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 "signaling/src/sdp/SdpMediaSection.h"
8 
9 namespace mozilla
10 {
11 const SdpFmtpAttributeList::Parameters*
FindFmtp(const std::string & pt) const12 SdpMediaSection::FindFmtp(const std::string& pt) const
13 {
14   const SdpAttributeList& attrs = GetAttributeList();
15 
16   if (attrs.HasAttribute(SdpAttribute::kFmtpAttribute)) {
17     for (auto& fmtpAttr : attrs.GetFmtp().mFmtps) {
18       if (fmtpAttr.format == pt && fmtpAttr.parameters) {
19         return fmtpAttr.parameters.get();
20       }
21     }
22   }
23   return nullptr;
24 }
25 
26 void
SetFmtp(const SdpFmtpAttributeList::Fmtp & fmtpToSet)27 SdpMediaSection::SetFmtp(const SdpFmtpAttributeList::Fmtp& fmtpToSet)
28 {
29   UniquePtr<SdpFmtpAttributeList> fmtps(new SdpFmtpAttributeList);
30 
31   if (GetAttributeList().HasAttribute(SdpAttribute::kFmtpAttribute)) {
32     *fmtps = GetAttributeList().GetFmtp();
33   }
34 
35   bool found = false;
36   for (SdpFmtpAttributeList::Fmtp& fmtp : fmtps->mFmtps) {
37     if (fmtp.format == fmtpToSet.format) {
38       fmtp = fmtpToSet;
39       found = true;
40     }
41   }
42 
43   if (!found) {
44     fmtps->mFmtps.push_back(fmtpToSet);
45   }
46 
47   GetAttributeList().SetAttribute(fmtps.release());
48 }
49 
50 void
RemoveFmtp(const std::string & pt)51 SdpMediaSection::RemoveFmtp(const std::string& pt)
52 {
53   UniquePtr<SdpFmtpAttributeList> fmtps(new SdpFmtpAttributeList);
54 
55   SdpAttributeList& attrList = GetAttributeList();
56   if (attrList.HasAttribute(SdpAttribute::kFmtpAttribute)) {
57     *fmtps = attrList.GetFmtp();
58   }
59 
60   for (size_t i = 0; i < fmtps->mFmtps.size(); ++i) {
61     if (pt == fmtps->mFmtps[i].format) {
62       fmtps->mFmtps.erase(fmtps->mFmtps.begin() + i);
63       break;
64     }
65   }
66 
67   attrList.SetAttribute(fmtps.release());
68 }
69 
70 const SdpRtpmapAttributeList::Rtpmap*
FindRtpmap(const std::string & pt) const71 SdpMediaSection::FindRtpmap(const std::string& pt) const
72 {
73   auto& attrs = GetAttributeList();
74   if (!attrs.HasAttribute(SdpAttribute::kRtpmapAttribute)) {
75     return nullptr;
76   }
77 
78   const SdpRtpmapAttributeList& rtpmap = attrs.GetRtpmap();
79   if (!rtpmap.HasEntry(pt)) {
80     return nullptr;
81   }
82 
83   return &rtpmap.GetEntry(pt);
84 }
85 
86 const SdpSctpmapAttributeList::Sctpmap*
FindSctpmap(const std::string & pt) const87 SdpMediaSection::FindSctpmap(const std::string& pt) const
88 {
89   auto& attrs = GetAttributeList();
90   if (!attrs.HasAttribute(SdpAttribute::kSctpmapAttribute)) {
91     return nullptr;
92   }
93 
94   const SdpSctpmapAttributeList& sctpmap = attrs.GetSctpmap();
95   if (!sctpmap.HasEntry(pt)) {
96     return nullptr;
97   }
98 
99   return &sctpmap.GetEntry(pt);
100 }
101 
102 bool
HasRtcpFb(const std::string & pt,SdpRtcpFbAttributeList::Type type,const std::string & subType) const103 SdpMediaSection::HasRtcpFb(const std::string& pt,
104                            SdpRtcpFbAttributeList::Type type,
105                            const std::string& subType) const
106 {
107   const SdpAttributeList& attrs(GetAttributeList());
108 
109   if (!attrs.HasAttribute(SdpAttribute::kRtcpFbAttribute)) {
110     return false;
111   }
112 
113   for (auto& rtcpfb : attrs.GetRtcpFb().mFeedbacks) {
114     if (rtcpfb.type == type) {
115       if (rtcpfb.pt == "*" || rtcpfb.pt == pt) {
116         if (rtcpfb.parameter == subType) {
117           return true;
118         }
119       }
120     }
121   }
122 
123   return false;
124 }
125 
126 SdpRtcpFbAttributeList
GetRtcpFbs() const127 SdpMediaSection::GetRtcpFbs() const
128 {
129   SdpRtcpFbAttributeList result;
130   if (GetAttributeList().HasAttribute(SdpAttribute::kRtcpFbAttribute)) {
131     result = GetAttributeList().GetRtcpFb();
132   }
133   return result;
134 }
135 
136 void
SetRtcpFbs(const SdpRtcpFbAttributeList & rtcpfbs)137 SdpMediaSection::SetRtcpFbs(const SdpRtcpFbAttributeList& rtcpfbs)
138 {
139   if (rtcpfbs.mFeedbacks.empty()) {
140     GetAttributeList().RemoveAttribute(SdpAttribute::kRtcpFbAttribute);
141     return;
142   }
143 
144   GetAttributeList().SetAttribute(new SdpRtcpFbAttributeList(rtcpfbs));
145 }
146 
147 void
SetSsrcs(const std::vector<uint32_t> & ssrcs,const std::string & cname)148 SdpMediaSection::SetSsrcs(const std::vector<uint32_t>& ssrcs,
149                           const std::string& cname)
150 {
151   if (ssrcs.empty()) {
152     GetAttributeList().RemoveAttribute(SdpAttribute::kSsrcAttribute);
153     return;
154   }
155 
156   UniquePtr<SdpSsrcAttributeList> ssrcAttr(new SdpSsrcAttributeList);
157   for (auto ssrc : ssrcs) {
158     // When using ssrc attributes, we are required to at least have a cname.
159     // (See https://tools.ietf.org/html/rfc5576#section-6.1)
160     std::string cnameAttr("cname:");
161     cnameAttr += cname;
162     ssrcAttr->PushEntry(ssrc, cnameAttr);
163   }
164 
165   GetAttributeList().SetAttribute(ssrcAttr.release());
166 }
167 
168 void
AddMsid(const std::string & id,const std::string & appdata)169 SdpMediaSection::AddMsid(const std::string& id, const std::string& appdata)
170 {
171   UniquePtr<SdpMsidAttributeList> msids(new SdpMsidAttributeList);
172   if (GetAttributeList().HasAttribute(SdpAttribute::kMsidAttribute)) {
173     msids->mMsids = GetAttributeList().GetMsid().mMsids;
174   }
175   msids->PushEntry(id, appdata);
176   GetAttributeList().SetAttribute(msids.release());
177 }
178 
179 const SdpRidAttributeList::Rid*
FindRid(const std::string & id) const180 SdpMediaSection::FindRid(const std::string& id) const
181 {
182   if (!GetAttributeList().HasAttribute(SdpAttribute::kRidAttribute)) {
183     return nullptr;
184   }
185 
186   for (const auto& rid : GetAttributeList().GetRid().mRids) {
187     if (rid.id == id) {
188       return &rid;
189     }
190   }
191 
192   return nullptr;
193 }
194 
195 } // namespace mozilla
196 
197