RsdparsaSdp.cpp (4003B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "sdp/RsdparsaSdp.h" 8 9 #include "mozilla/Assertions.h" 10 #include "nsError.h" 11 #include "sdp/RsdparsaSdpInc.h" 12 #include "sdp/RsdparsaSdpMediaSection.h" 13 14 #ifdef CRLF 15 # undef CRLF 16 #endif 17 #define CRLF "\r\n" 18 19 namespace mozilla { 20 21 RsdparsaSdp::RsdparsaSdp(RsdparsaSessionHandle session, const SdpOrigin& origin) 22 : mSession(std::move(session)), mOrigin(origin) { 23 RsdparsaSessionHandle attributeSession(sdp_new_reference(mSession.get())); 24 mAttributeList.reset( 25 new RsdparsaSdpAttributeList(std::move(attributeSession))); 26 27 size_t section_count = sdp_media_section_count(mSession.get()); 28 for (size_t level = 0; level < section_count; level++) { 29 RustMediaSection* mediaSection = 30 sdp_get_media_section(mSession.get(), level); 31 if (!mediaSection) { 32 MOZ_ASSERT(false, 33 "sdp_get_media_section failed because level was out of" 34 " bounds, but we did a bounds check!"); 35 break; 36 } 37 RsdparsaSessionHandle newSession(sdp_new_reference(mSession.get())); 38 RsdparsaSdpMediaSection* sdpMediaSection; 39 sdpMediaSection = new RsdparsaSdpMediaSection( 40 level, std::move(newSession), mediaSection, mAttributeList.get()); 41 mMediaSections.emplace_back(sdpMediaSection); 42 } 43 } 44 45 RsdparsaSdp::RsdparsaSdp(const RsdparsaSdp& aOrig) 46 : RsdparsaSdp(RsdparsaSessionHandle(create_sdp_clone(aOrig.mSession.get())), 47 aOrig.mOrigin) {} 48 49 Sdp* RsdparsaSdp::Clone() const { return new RsdparsaSdp(*this); } 50 51 const SdpOrigin& RsdparsaSdp::GetOrigin() const { return mOrigin; } 52 53 uint32_t RsdparsaSdp::GetBandwidth(const std::string& type) const { 54 return get_sdp_bandwidth(mSession.get(), type.c_str()); 55 } 56 57 const SdpMediaSection& RsdparsaSdp::GetMediaSection(size_t level) const { 58 if (level > mMediaSections.size()) { 59 MOZ_CRASH(); 60 } 61 return *mMediaSections[level]; 62 } 63 64 SdpMediaSection& RsdparsaSdp::GetMediaSection(size_t level) { 65 if (level > mMediaSections.size()) { 66 MOZ_CRASH(); 67 } 68 return *mMediaSections[level]; 69 } 70 71 SdpMediaSection& RsdparsaSdp::AddMediaSection( 72 SdpMediaSection::MediaType mediaType, SdpDirectionAttribute::Direction dir, 73 uint16_t port, SdpMediaSection::Protocol protocol, sdp::AddrType addrType, 74 const std::string& addr) { 75 StringView rustAddr{addr.c_str(), addr.size()}; 76 auto nr = sdp_add_media_section(mSession.get(), mediaType, dir, port, 77 protocol, addrType, rustAddr); 78 79 if (NS_SUCCEEDED(nr)) { 80 size_t level = mMediaSections.size(); 81 RsdparsaSessionHandle newSessHandle(sdp_new_reference(mSession.get())); 82 83 auto rustMediaSection = sdp_get_media_section(mSession.get(), level); 84 auto mediaSection = 85 new RsdparsaSdpMediaSection(level, std::move(newSessHandle), 86 rustMediaSection, mAttributeList.get()); 87 mMediaSections.emplace_back(mediaSection); 88 89 return *mediaSection; 90 } else { 91 // Return the last media section if the construction of this one fails 92 return GetMediaSection(mMediaSections.size() - 1); 93 } 94 } 95 96 void RsdparsaSdp::Serialize(std::ostream& os) const { 97 os << "v=0" << CRLF << mOrigin << "s=-" << CRLF; 98 99 // We don't support creating i=, u=, e=, p= 100 // We don't generate c= at the session level (only in media) 101 102 BandwidthVec* bwVec = sdp_get_session_bandwidth_vec(mSession.get()); 103 char* bwString = sdp_serialize_bandwidth(bwVec); 104 if (bwString) { 105 os << bwString; 106 sdp_free_string(bwString); 107 } 108 109 os << "t=0 0" << CRLF; 110 111 // We don't support r= or z= 112 113 // attributes 114 os << *mAttributeList; 115 116 // media sections 117 for (const auto& msection : mMediaSections) { 118 os << *msection; 119 } 120 } 121 122 } // namespace mozilla