diff --git a/include/rtc/description.hpp b/include/rtc/description.hpp index bfad86a..70ed5cd 100644 --- a/include/rtc/description.hpp +++ b/include/rtc/description.hpp @@ -63,25 +63,27 @@ public: class Entry { public: - Entry(string mline, string mid = "", Direction dir = Direction::Unknown); virtual ~Entry() = default; virtual string type() const { return mType; } virtual string description() const { return mDescription; } virtual string mid() const { return mMid; } - Direction direction() const; + Direction direction() const { return mDirection; } + void setDirection(Direction dir); virtual void parseSdpLine(string_view line); virtual string generateSdp(string_view eol) const; protected: + Entry(string mline, string mid = "", Direction dir = Direction::Unknown); + std::vector mAttributes; - Direction mDirection; private: string mType; string mDescription; string mMid; + Direction mDirection; }; struct Application : public Entry { @@ -119,7 +121,6 @@ public: string description() const override; Media reciprocate() const; - void setDirection(Direction dir); void removeFormat(const string &fmt); void addVideoCodec(int payloadType, const string &codec); diff --git a/include/rtc/peerconnection.hpp b/include/rtc/peerconnection.hpp index 86b3731..0437114 100644 --- a/include/rtc/peerconnection.hpp +++ b/include/rtc/peerconnection.hpp @@ -129,6 +129,7 @@ private: void closeDataChannels(); void remoteCloseDataChannels(); + void incomingTrack(Description::Media description); void openTracks(); void processLocalDescription(Description description); diff --git a/src/description.cpp b/src/description.cpp index 0dff959..6288d80 100644 --- a/src/description.cpp +++ b/src/description.cpp @@ -366,7 +366,7 @@ Description::media(int index) const { int Description::mediaCount() const { return int(mEntries.size()); } Description::Entry::Entry(string mline, string mid, Direction dir) - : mDirection(dir), mMid(std::move(mid)) { + : mMid(std::move(mid)), mDirection(dir) { size_t p = mline.find(' '); mType = mline.substr(0, p); if (p != string::npos) @@ -374,6 +374,8 @@ Description::Entry::Entry(string mline, string mid, Direction dir) mDescription = mline.substr(q + 1, mline.find(' ', q + 1) - (q + 1)); } +void Description::Entry::setDirection(Direction dir) { mDirection = dir; } + string Description::Entry::generateSdp(string_view eol) const { std::ostringstream sdp; // Port 9 is the discard protocol @@ -490,12 +492,12 @@ Description::Media Description::Media::reciprocate() const { Media reciprocated(*this); // Invert direction - switch (reciprocated.mDirection) { + switch (direction()) { case Direction::RecvOnly: - reciprocated.mDirection = Direction::SendOnly; + reciprocated.setDirection(Direction::SendOnly); break; case Direction::SendOnly: - reciprocated.mDirection = Direction::RecvOnly; + reciprocated.setDirection(Direction::RecvOnly); break; default: // We are good @@ -521,8 +523,6 @@ Description::Media::RTPMap &Description::Media::getFormat(const string &fmt) { throw std::invalid_argument("format was not found"); } -void Description::Media::setDirection(Direction dir) { mDirection = dir; } - void Description::Media::removeFormat(const string &fmt) { auto it = mRtpMap.begin(); std::vector remed; diff --git a/src/peerconnection.cpp b/src/peerconnection.cpp index d18de4e..857e631 100644 --- a/src/peerconnection.cpp +++ b/src/peerconnection.cpp @@ -240,6 +240,10 @@ std::shared_ptr PeerConnection::createTrack(Description::Media descriptio if (localDescription()) throw std::logic_error("Tracks must be created before local description"); + if (auto it = mTracks.find(description.mid()); it != mTracks.end()) + if (auto track = it->second.lock()) + return track; + auto track = std::make_shared(std::move(description)); mTracks.emplace(std::make_pair(track->mid(), track)); return track; @@ -638,6 +642,22 @@ void PeerConnection::openDataChannels() { iterateDataChannels([&](shared_ptr channel) { channel->open(transport); }); } +void PeerConnection::closeDataChannels() { + iterateDataChannels([&](shared_ptr channel) { channel->close(); }); +} + +void PeerConnection::remoteCloseDataChannels() { + iterateDataChannels([&](shared_ptr channel) { channel->remoteClose(); }); +} + +void PeerConnection::incomingTrack(Description::Media description) { + std::unique_lock lock(mTracksMutex); // we are going to emplace + if (mTracks.find(description.mid()) == mTracks.end()) { + auto track = std::make_shared(std::move(description)); + mTracks.emplace(std::make_pair(track->mid(), track)); + } +} + void PeerConnection::openTracks() { #if RTC_ENABLE_MEDIA if (!hasMedia()) @@ -653,13 +673,6 @@ void PeerConnection::openTracks() { #endif } -void PeerConnection::closeDataChannels() { - iterateDataChannels([&](shared_ptr channel) { channel->close(); }); -} - -void PeerConnection::remoteCloseDataChannels() { - iterateDataChannels([&](shared_ptr channel) { channel->remoteClose(); }); -} void PeerConnection::processLocalDescription(Description description) { if (auto remote = remoteDescription()) { @@ -680,7 +693,10 @@ void PeerConnection::processLocalDescription(Description description) { << media->mid() << "\""; auto reciprocated = media->reciprocate(); -#if !RTC_ENABLE_MEDIA +#if RTC_ENABLE_MEDIA + if (reciprocated.direction() != Description::Direction::Inactive) + incomingTrack(reciprocated); +#else // No media support, mark as inactive reciprocated.setDirection(Description::Direction::Inactive); #endif diff --git a/src/track.cpp b/src/track.cpp index 683b534..bdc54af 100644 --- a/src/track.cpp +++ b/src/track.cpp @@ -74,6 +74,11 @@ void Track::open(shared_ptr transport) { mDtlsSrtpTransport = #endif bool Track::outgoing(message_ptr message) { + auto direction = mMediaDescription.direction(); + if (direction == Description::Direction::RecvOnly || + direction == Description::Direction::Inactive) + throw std::runtime_error("Track media direction does not allow sending"); + if (mIsClosed) throw std::runtime_error("Track is closed"); @@ -104,6 +109,13 @@ void Track::incoming(message_ptr message) { message = *opt; } + auto direction = mMediaDescription.direction(); + if ((direction == Description::Direction::SendOnly || + direction == Description::Direction::Inactive) && + message->type != Message::Control) { + PLOG_WARNING << "Track media direction does not allow reception, dropping"; + } + // Tail drop if queue is full if (mRecvQueue.full()) return;