Line data Source code
1 : /* This Source Code Form is subject to the terms of the Mozilla Public
2 : * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
4 :
5 : #include "signaling/src/sdp/SipccSdp.h"
6 :
7 : #include <cstdlib>
8 : #include "mozilla/UniquePtr.h"
9 : #include "mozilla/Assertions.h"
10 : #include "signaling/src/sdp/SdpErrorHolder.h"
11 :
12 : #ifdef CRLF
13 : #undef CRLF
14 : #endif
15 : #define CRLF "\r\n"
16 :
17 : namespace mozilla
18 : {
19 :
20 : const SdpOrigin&
21 0 : SipccSdp::GetOrigin() const
22 : {
23 0 : return mOrigin;
24 : }
25 :
26 : uint32_t
27 0 : SipccSdp::GetBandwidth(const std::string& type) const
28 : {
29 0 : auto found = mBandwidths.find(type);
30 0 : if (found == mBandwidths.end()) {
31 0 : return 0;
32 : }
33 0 : return found->second;
34 : }
35 :
36 : const SdpMediaSection&
37 0 : SipccSdp::GetMediaSection(size_t level) const
38 : {
39 0 : if (level > mMediaSections.values.size()) {
40 0 : MOZ_CRASH();
41 : }
42 0 : return *mMediaSections.values[level];
43 : }
44 :
45 : SdpMediaSection&
46 0 : SipccSdp::GetMediaSection(size_t level)
47 : {
48 0 : if (level > mMediaSections.values.size()) {
49 0 : MOZ_CRASH();
50 : }
51 0 : return *mMediaSections.values[level];
52 : }
53 :
54 : SdpMediaSection&
55 0 : SipccSdp::AddMediaSection(SdpMediaSection::MediaType mediaType,
56 : SdpDirectionAttribute::Direction dir, uint16_t port,
57 : SdpMediaSection::Protocol protocol,
58 : sdp::AddrType addrType, const std::string& addr)
59 : {
60 0 : size_t level = mMediaSections.values.size();
61 : SipccSdpMediaSection* media =
62 0 : new SipccSdpMediaSection(level, &mAttributeList);
63 0 : media->mMediaType = mediaType;
64 0 : media->mPort = port;
65 0 : media->mPortCount = 0;
66 0 : media->mProtocol = protocol;
67 0 : media->mConnection = MakeUnique<SdpConnection>(addrType, addr);
68 0 : media->GetAttributeList().SetAttribute(new SdpDirectionAttribute(dir));
69 0 : mMediaSections.values.push_back(media);
70 0 : return *media;
71 : }
72 :
73 : bool
74 0 : SipccSdp::LoadOrigin(sdp_t* sdp, SdpErrorHolder& errorHolder)
75 : {
76 0 : std::string username = sdp_get_owner_username(sdp);
77 0 : uint64_t sessId = strtoull(sdp_get_owner_sessionid(sdp), nullptr, 10);
78 0 : uint64_t sessVer = strtoull(sdp_get_owner_version(sdp), nullptr, 10);
79 :
80 0 : sdp_nettype_e type = sdp_get_owner_network_type(sdp);
81 0 : if (type != SDP_NT_INTERNET) {
82 0 : errorHolder.AddParseError(2, "Unsupported network type");
83 0 : return false;
84 : }
85 :
86 : sdp::AddrType addrType;
87 0 : switch (sdp_get_owner_address_type(sdp)) {
88 : case SDP_AT_IP4:
89 0 : addrType = sdp::kIPv4;
90 0 : break;
91 : case SDP_AT_IP6:
92 0 : addrType = sdp::kIPv6;
93 0 : break;
94 : default:
95 0 : errorHolder.AddParseError(2, "Unsupported address type");
96 0 : return false;
97 : }
98 :
99 0 : std::string address = sdp_get_owner_address(sdp);
100 0 : mOrigin = SdpOrigin(username, sessId, sessVer, addrType, address);
101 0 : return true;
102 : }
103 :
104 : bool
105 0 : SipccSdp::Load(sdp_t* sdp, SdpErrorHolder& errorHolder)
106 : {
107 : // Believe it or not, SDP_SESSION_LEVEL is 0xFFFF
108 0 : if (!mAttributeList.Load(sdp, SDP_SESSION_LEVEL, errorHolder)) {
109 0 : return false;
110 : }
111 :
112 0 : if (!LoadOrigin(sdp, errorHolder)) {
113 0 : return false;
114 : }
115 :
116 0 : if (!mBandwidths.Load(sdp, SDP_SESSION_LEVEL, errorHolder)) {
117 0 : return false;
118 : }
119 :
120 0 : for (int i = 0; i < sdp_get_num_media_lines(sdp); ++i) {
121 : // note that we pass a "level" here that is one higher
122 : // sipcc counts media sections from 1, using 0xFFFF as the "session"
123 : UniquePtr<SipccSdpMediaSection> section(
124 0 : new SipccSdpMediaSection(i, &mAttributeList));
125 0 : if (!section->Load(sdp, i + 1, errorHolder)) {
126 0 : return false;
127 : }
128 0 : mMediaSections.values.push_back(section.release());
129 : }
130 0 : return true;
131 : }
132 :
133 : void
134 0 : SipccSdp::Serialize(std::ostream& os) const
135 : {
136 0 : os << "v=0" << CRLF << mOrigin << "s=-" << CRLF;
137 :
138 : // We don't support creating i=, u=, e=, p=
139 : // We don't generate c= at the session level (only in media)
140 :
141 0 : mBandwidths.Serialize(os);
142 0 : os << "t=0 0" << CRLF;
143 :
144 : // We don't support r= or z=
145 :
146 : // attributes
147 0 : os << mAttributeList;
148 :
149 : // media sections
150 0 : for (const SdpMediaSection* msection : mMediaSections.values) {
151 0 : os << *msection;
152 : }
153 0 : }
154 :
155 : bool
156 0 : SipccSdpBandwidths::Load(sdp_t* sdp, uint16_t level,
157 : SdpErrorHolder& errorHolder)
158 : {
159 0 : size_t count = sdp_get_num_bw_lines(sdp, level);
160 0 : for (size_t i = 1; i <= count; ++i) {
161 0 : sdp_bw_modifier_e bwtype = sdp_get_bw_modifier(sdp, level, i);
162 0 : uint32_t bandwidth = sdp_get_bw_value(sdp, level, i);
163 0 : if (bwtype != SDP_BW_MODIFIER_UNSUPPORTED) {
164 0 : const char* typeName = sdp_get_bw_modifier_name(bwtype);
165 0 : (*this)[typeName] = bandwidth;
166 : }
167 : }
168 :
169 0 : return true;
170 : }
171 :
172 : void
173 0 : SipccSdpBandwidths::Serialize(std::ostream& os) const
174 : {
175 0 : for (auto i = begin(); i != end(); ++i) {
176 0 : os << "b=" << i->first << ":" << i->second << CRLF;
177 : }
178 0 : }
179 :
180 : } // namespace mozilla
|