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