Bug Summary

File:root/firefox-clang/third_party/sipcc/sdp_main.c
Warning:line 1156, column 17
Value stored to 'last_token' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name sdp_main.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/third_party/sipcc -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/third_party/sipcc -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D SIP_OS_LINUX -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/third_party/sipcc -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/third_party/sipcc -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-character-conversion -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c /root/firefox-clang/third_party/sipcc/sdp_main.c
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
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#include "sdp_os_defs.h"
6#include "sipcc_sdp.h"
7#include "sdp_private.h"
8
9#include "sdp_log.h"
10
11static const char* logTag = "sdp_main";
12
13/* Note: These *must* be in the same order as the enum types. */
14const sdp_tokenarray_t sdp_token[SDP_MAX_TOKENS] =
15{
16 {"v=", sdp_parse_version, sdp_build_version },
17 {"o=", sdp_parse_owner, sdp_build_owner },
18 {"s=", sdp_parse_sessname, sdp_build_sessname },
19 {"i=", sdp_parse_sessinfo, sdp_build_sessinfo },
20 {"u=", sdp_parse_uri, sdp_build_uri },
21 {"e=", sdp_parse_email, sdp_build_email },
22 {"p=", sdp_parse_phonenum, sdp_build_phonenum },
23 {"c=", sdp_parse_connection, sdp_build_connection },
24 {"b=", sdp_parse_bandwidth, sdp_build_bandwidth },
25 {"t=", sdp_parse_timespec, sdp_build_timespec },
26 {"r=", sdp_parse_repeat_time, sdp_build_repeat_time },
27 {"z=", sdp_parse_timezone_adj, sdp_build_timezone_adj },
28 {"k=", sdp_parse_encryption, sdp_build_encryption },
29 {"a=", sdp_parse_attribute, sdp_build_attribute },
30 {"m=", sdp_parse_media, sdp_build_media }
31};
32
33
34/* Note: These *must* be in the same order as the enum types. */
35const sdp_attrarray_t sdp_attr[SDP_MAX_ATTR_TYPES] =
36{
37 {"bearer", sizeof("bearer"),
38 sdp_parse_attr_simple_string, sdp_build_attr_simple_string },
39 {"called", sizeof("called"),
40 sdp_parse_attr_simple_string, sdp_build_attr_simple_string },
41 {"connection_type", sizeof("connection_type"),
42 sdp_parse_attr_simple_string, sdp_build_attr_simple_string },
43 {"dialed", sizeof("dialed"),
44 sdp_parse_attr_simple_string, sdp_build_attr_simple_string },
45 {"dialing", sizeof("dialing"),
46 sdp_parse_attr_simple_string, sdp_build_attr_simple_string },
47 {"direction", sizeof("direction"),
48 sdp_parse_attr_comediadir, sdp_build_attr_comediadir },
49 {"eecid", sizeof("eecid"),
50 sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
51 {"fmtp", sizeof("fmtp"),
52 sdp_parse_attr_fmtp, sdp_build_attr_fmtp },
53 {"sctpmap", sizeof("sctpmap"),
54 sdp_parse_attr_sctpmap, sdp_build_attr_sctpmap },
55 {"framing", sizeof("framing"),
56 sdp_parse_attr_simple_string, sdp_build_attr_simple_string },
57 {"inactive", sizeof("inactive"),
58 sdp_parse_attr_direction, sdp_build_attr_direction },
59 {"ptime", sizeof("ptime"),
60 sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
61 {"qos", sizeof("qos"),
62 sdp_parse_attr_qos, sdp_build_attr_qos },
63 {"curr", sizeof("curr"),
64 sdp_parse_attr_curr, sdp_build_attr_curr },
65 {"des", sizeof("des"),
66 sdp_parse_attr_des, sdp_build_attr_des},
67 {"conf", sizeof("conf"),
68 sdp_parse_attr_conf, sdp_build_attr_conf},
69 {"recvonly", sizeof("recvonly"),
70 sdp_parse_attr_direction, sdp_build_attr_direction },
71 {"rtpmap", sizeof("rtpmap"),
72 sdp_parse_attr_transport_map, sdp_build_attr_transport_map },
73 {"secure", sizeof("secure"),
74 sdp_parse_attr_qos, sdp_build_attr_qos },
75 {"sendonly", sizeof("sendonly"),
76 sdp_parse_attr_direction, sdp_build_attr_direction },
77 {"sendrecv", sizeof("sendrecv"),
78 sdp_parse_attr_direction, sdp_build_attr_direction },
79 {"subnet", sizeof("subnet"),
80 sdp_parse_attr_subnet, sdp_build_attr_subnet },
81 {"T38FaxVersion", sizeof("T38FaxVersion"),
82 sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
83 {"T38MaxBitRate", sizeof("T38MaxBitRate"),
84 sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
85 {"T38FaxFillBitRemoval", sizeof("T38FaxFillBitRemoval"),
86 sdp_parse_attr_simple_bool, sdp_build_attr_simple_bool },
87 {"T38FaxTranscodingMMR", sizeof("T38FaxTranscodingMMR"),
88 sdp_parse_attr_simple_bool, sdp_build_attr_simple_bool },
89 {"T38FaxTranscodingJBIG", sizeof("T38FaxTranscodingJBIG"),
90 sdp_parse_attr_simple_bool, sdp_build_attr_simple_bool },
91 {"T38FaxRateManagement", sizeof("T38FaxRateManagement"),
92 sdp_parse_attr_t38_ratemgmt, sdp_build_attr_t38_ratemgmt },
93 {"T38FaxMaxBuffer", sizeof("T38FaxMaxBuffer"),
94 sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
95 {"T38FaxMaxDatagram", sizeof("T38FaxMaxDatagram"),
96 sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
97 {"T38FaxUdpEC", sizeof("T38FaxUdpEC"),
98 sdp_parse_attr_t38_udpec, sdp_build_attr_t38_udpec },
99 {"X-cap", sizeof("X-cap"),
100 sdp_parse_attr_cap, sdp_build_attr_cap },
101 {"X-cpar", sizeof("X-cpar"),
102 sdp_parse_attr_cpar, sdp_build_attr_cpar },
103 {"X-pc-codec", sizeof("X-pc-codec"),
104 sdp_parse_attr_pc_codec, sdp_build_attr_pc_codec },
105 {"X-pc-qos", sizeof("X-pc-qos"),
106 sdp_parse_attr_qos, sdp_build_attr_qos },
107 {"X-qos", sizeof("X-qos"),
108 sdp_parse_attr_qos, sdp_build_attr_qos },
109 {"X-sqn", sizeof("X-sqn"),
110 sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
111 {"TMRGwXid", sizeof("TMRGwXid"),
112 sdp_parse_attr_simple_bool, sdp_build_attr_simple_bool },
113 {"TC1PayloadBytes", sizeof("TC1PayloadBytes"),
114 sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
115 {"TC1WindowSize", sizeof("TC1WindowSize"),
116 sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
117 {"TC2PayloadBytes", sizeof("TC2PayloadBytes"),
118 sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
119 {"TC2WindowSize", sizeof("TC2WindowSize"),
120 sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
121 {"rtcp", sizeof("rtcp"),
122 sdp_parse_attr_rtcp, sdp_build_attr_rtcp },
123 {"rtr", sizeof("rtr"),
124 sdp_parse_attr_rtr, sdp_build_attr_rtr},
125 {"silenceSupp", sizeof("silenceSupp"),
126 sdp_parse_attr_silencesupp, sdp_build_attr_silencesupp },
127 {"X-crypto", sizeof("X-crypto"),
128 sdp_parse_attr_srtpcontext, sdp_build_attr_srtpcontext },
129 {"mptime", sizeof("mptime"),
130 sdp_parse_attr_mptime, sdp_build_attr_mptime },
131 {"X-sidin", sizeof("X-sidin"),
132 sdp_parse_attr_x_sidin, sdp_build_attr_x_sidin },
133 {"X-sidout", sizeof("X-sidout"),
134 sdp_parse_attr_x_sidout, sdp_build_attr_x_sidout },
135 {"X-confid", sizeof("X-confid"),
136 sdp_parse_attr_x_confid, sdp_build_attr_x_confid },
137 {"group", sizeof("group"),
138 sdp_parse_attr_group, sdp_build_attr_group },
139 {"mid", sizeof("mid"),
140 sdp_parse_attr_simple_string, sdp_build_attr_simple_string },
141 {"source-filter", sizeof("source-filter"),
142 sdp_parse_attr_source_filter, sdp_build_source_filter},
143 {"rtcp-unicast", sizeof("rtcp-unicast"),
144 sdp_parse_attr_rtcp_unicast, sdp_build_attr_rtcp_unicast},
145 {"maxprate", sizeof("maxprate"),
146 sdp_parse_attr_maxprate, sdp_build_attr_simple_string},
147 {"sqn", sizeof("sqn"),
148 sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
149 {"cdsc", sizeof("cdsc"),
150 sdp_parse_attr_cap, sdp_build_attr_cap },
151 {"cpar", sizeof("cpar"),
152 sdp_parse_attr_cpar, sdp_build_attr_cpar },
153 {"sprtmap", sizeof("sprtmap"),
154 sdp_parse_attr_transport_map, sdp_build_attr_transport_map },
155 {"crypto", sizeof("crypto"),
156 sdp_parse_attr_sdescriptions, sdp_build_attr_sdescriptions },
157 {"label", sizeof("label"),
158 sdp_parse_attr_simple_string, sdp_build_attr_simple_string },
159 {"framerate", sizeof("framerate"),
160 sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
161 {"candidate", sizeof("candidate"),
162 sdp_parse_attr_ice_attr, sdp_build_attr_ice_attr },
163 {"ice-ufrag", sizeof("ice-ufrag"),
164 sdp_parse_attr_ice_attr, sdp_build_attr_ice_attr },
165 {"ice-pwd", sizeof("ice-pwd"),
166 sdp_parse_attr_ice_attr, sdp_build_attr_ice_attr},
167 {"ice-lite", sizeof("ice-lite"),
168 sdp_parse_attr_simple_flag, sdp_build_attr_simple_flag},
169 {"rtcp-mux", sizeof("rtcp-mux"),
170 sdp_parse_attr_simple_flag, sdp_build_attr_simple_flag},
171 {"fingerprint", sizeof("fingerprint"),
172 sdp_parse_attr_complete_line, sdp_build_attr_simple_string},
173 {"maxptime", sizeof("maxptime"),
174 sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32},
175 {"rtcp-fb", sizeof("rtcp-fb"),
176 sdp_parse_attr_rtcp_fb, sdp_build_attr_rtcp_fb},
177 {"setup", sizeof("setup"),
178 sdp_parse_attr_setup, sdp_build_attr_setup},
179 {"connection", sizeof("connection"),
180 sdp_parse_attr_connection, sdp_build_attr_connection},
181 {"extmap", sizeof("extmap"),
182 sdp_parse_attr_extmap, sdp_build_attr_extmap},
183 {"identity", sizeof("identity"),
184 sdp_parse_attr_long_line, sdp_build_attr_long_line},
185 {"msid", sizeof("msid"),
186 sdp_parse_attr_msid, sdp_build_attr_msid},
187 {"msid-semantic", sizeof("msid-semantic"),
188 sdp_parse_attr_msid_semantic, sdp_build_attr_msid_semantic},
189 {"bundle-only", sizeof("bundle-only"),
190 sdp_parse_attr_simple_flag, sdp_build_attr_simple_flag},
191 {"end-of-candidates", sizeof("end-of-candidates"),
192 sdp_parse_attr_simple_flag, sdp_build_attr_simple_flag},
193 {"ice-options", sizeof("ice-options"),
194 sdp_parse_attr_complete_line, sdp_build_attr_simple_string},
195 {"ssrc", sizeof("ssrc"),
196 sdp_parse_attr_ssrc, sdp_build_attr_ssrc},
197 {"imageattr", sizeof("imageattr"),
198 sdp_parse_attr_complete_line, sdp_build_attr_simple_string},
199 {"simulcast", sizeof("simulcast"),
200 sdp_parse_attr_complete_line, sdp_build_attr_simple_string},
201 {"rid", sizeof("rid"),
202 sdp_parse_attr_complete_line, sdp_build_attr_simple_string},
203 {"dtls-message", sizeof("dtls-message"),
204 sdp_parse_attr_long_line, sdp_build_attr_long_line},
205 {"sctp-port", sizeof("sctp-port"),
206 sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32},
207 {"max-message-size", sizeof("max-message-size"),
208 sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32},
209 {"ssrc-group", sizeof("ssrc-group"), sdp_parse_attr_ssrc_group,
210 sdp_build_attr_ssrc_group},
211 {"rtcp-rsize", sizeof("rtcp-rsize"),
212 sdp_parse_attr_simple_flag, sdp_build_attr_simple_flag},
213 {"extmap-allow-mixed", sizeof("extmap-allow-mixed"),
214 sdp_parse_attr_simple_flag, sdp_build_attr_simple_flag},
215};
216
217/* Note: These *must* be in the same order as the enum types. */
218const sdp_namearray_t sdp_media[SDP_MAX_MEDIA_TYPES] =
219{
220 {"audio", sizeof("audio")},
221 {"video", sizeof("video")},
222 {"application", sizeof("application")},
223 {"data", sizeof("data")},
224 {"control", sizeof("control")},
225 {"nas/radius", sizeof("nas/radius")},
226 {"nas/tacacs", sizeof("nas/tacacs")},
227 {"nas/diameter", sizeof("nas/diameter")},
228 {"nas/l2tp", sizeof("nas/l2tp")},
229 {"nas/login", sizeof("nas/login")},
230 {"nas/none", sizeof("nas/none")},
231 {"image", sizeof("image")},
232 {"text", sizeof("text")}
233};
234
235
236/* Note: These *must* be in the same order as the enum types. */
237const sdp_namearray_t sdp_nettype[SDP_MAX_NETWORK_TYPES] =
238{
239 {"IN", sizeof("IN")},
240 {"ATM", sizeof("ATM")},
241 {"FR", sizeof("FR")},
242 {"LOCAL", sizeof("LOCAL")}
243};
244
245
246/* Note: These *must* be in the same order as the enum types. */
247const sdp_namearray_t sdp_addrtype[SDP_MAX_ADDR_TYPES] =
248{
249 {"IP4", sizeof("IP4")},
250 {"IP6", sizeof("IP6")},
251 {"NSAP", sizeof("NSAP")},
252 {"EPN", sizeof("EPN")},
253 {"E164", sizeof("E164")},
254 {"GWID", sizeof("GWID")}
255};
256
257
258/* Note: These *must* be in the same order as the enum type. */
259const sdp_namearray_t sdp_transport[SDP_MAX_TRANSPORT_TYPES] =
260{
261 {"RTP/AVP", sizeof("RTP/AVP")},
262 {"udp", sizeof("udp")},
263 {"udptl", sizeof("udptl")},
264 {"ces10", sizeof("ces10")},
265 {"LOCAL", sizeof("LOCAL")},
266 {"AAL2/ITU", sizeof("AAL2/ITU")},
267 {"AAL2/ATMF", sizeof("AAL2/ATMF")},
268 {"AAL2/custom", sizeof("AAL2/custom")},
269 {"AAL1/AVP", sizeof("AAL1/AVP")},
270 {"udpsprt", sizeof("udpsprt")},
271 {"RTP/SAVP", sizeof("RTP/SAVP")},
272 {"tcp", sizeof("tcp")},
273 {"RTP/SAVPF", sizeof("RTP/SAVPF")},
274 {"DTLS/SCTP", sizeof("DTLS/SCTP")},
275 {"RTP/AVPF", sizeof("RTP/AVPF")},
276 {"UDP/TLS/RTP/SAVP", sizeof("UDP/TLS/RTP/SAVP")},
277 {"UDP/TLS/RTP/SAVPF", sizeof("UDP/TLS/RTP/SAVPF")},
278 {"TCP/DTLS/RTP/SAVP", sizeof("TCP/DTLS/RTP/SAVP")},
279 {"TCP/DTLS/RTP/SAVPF", sizeof("TCP/DTLS/RTP/SAVPF")},
280 {"UDP/DTLS/SCTP", sizeof("UDP/DTLS/SCTP")},
281 {"TCP/DTLS/SCTP", sizeof("TCP/DTLS/SCTP")},
282};
283
284/* Note: These *must* be in the same order as the enum type. */
285const sdp_namearray_t sdp_encrypt[SDP_MAX_ENCRYPT_TYPES] =
286{
287 {"clear", sizeof("clear")},
288 {"base64", sizeof("base64")},
289 {"uri", sizeof("uri")},
290 {"prompt", sizeof("prompt")}
291};
292
293/* Note: These *must* be in the same order as the enum type. */
294const sdp_namearray_t sdp_payload[SDP_MAX_STRING_PAYLOAD_TYPES] =
295{
296 {"t38", sizeof("t38")},
297 {"X-tmr", sizeof("X-tmr")},
298 {"T120", sizeof("T120")}
299};
300
301/* Note: These *must* be in the same order as the enum type. */
302const sdp_namearray_t sdp_t38_rate[SDP_T38_MAX_RATES] =
303{
304 {"localTCF", sizeof("localTCF")},
305 {"transferredTCF", sizeof("transferredTCF")},
306 {"unknown", sizeof("unknown")}
307};
308
309/* Note: These *must* be in the same order as the enum type. */
310const sdp_namearray_t sdp_t38_udpec[SDP_T38_MAX_UDPEC] =
311{
312 {"t38UDPRedundancy", sizeof("t38UDPRedundancy")},
313 {"t38UDPFEC", sizeof("t38UDPFEC")},
314 {"unknown", sizeof("unknown")}
315};
316
317/* Note: These *must* be in the same order as the enum type. */
318const sdp_namearray_t sdp_qos_strength[SDP_MAX_QOS_STRENGTH] =
319{
320 {"optional", sizeof("optional")},
321 {"mandatory", sizeof("mandatory")},
322 {"success", sizeof("success")},
323 {"failure", sizeof("failure")},
324 {"none", sizeof("none")}
325};
326
327/* Note: These *must* be in the same order as the enum type. */
328const sdp_namearray_t sdp_qos_status_type[SDP_MAX_QOS_STATUS_TYPES] =
329{
330 {"local", sizeof("local")},
331 {"remote", sizeof("remote")},
332 {"e2e", sizeof("e2e")}
333};
334
335/* Note: These *must* be in the same order as the enum type. */
336const sdp_namearray_t sdp_curr_type[SDP_MAX_CURR_TYPES] =
337{
338 {"qos", sizeof("qos")},
339 {"unknown", sizeof("unknown")}
340};
341
342/* Note: These *must* be in the same order as the enum type. */
343const sdp_namearray_t sdp_des_type[SDP_MAX_DES_TYPES] =
344{
345 {"qos", sizeof("qos")},
346 {"unknown", sizeof("unknown")}
347};
348
349/* Note: These *must* be in the same order as the enum type. */
350const sdp_namearray_t sdp_conf_type[SDP_MAX_CONF_TYPES] =
351{
352 {"qos", sizeof("qos")},
353 {"unknown", sizeof("unknown")}
354};
355/* Note: These *must* be in the same order as the enum type. */
356const sdp_namearray_t sdp_qos_direction[SDP_MAX_QOS_DIR] =
357{
358 {"send", sizeof("send")},
359 {"recv", sizeof("recv")},
360 {"sendrecv", sizeof("sendrecv")},
361 {"none", sizeof("none")}
362};
363
364/* Note: These *must* be in the same order as the enum type. */
365const sdp_namearray_t sdp_silencesupp_pref[SDP_MAX_SILENCESUPP_PREF] = {
366 {"standard", sizeof("standard")},
367 {"custom", sizeof("custom")},
368 {"-", sizeof("-")}
369};
370
371/* Note: These *must* be in the same order as the enum type. */
372const sdp_namearray_t sdp_silencesupp_siduse[SDP_MAX_SILENCESUPP_SIDUSE] = {
373 {"No SID", sizeof("No SID")},
374 {"Fixed Noise", sizeof("Fixed Noise")},
375 {"Sampled Noise", sizeof("Sampled Noise")},
376 {"-", sizeof("-")}
377};
378
379/* Note: These *must* be in the same order as the enum type. */
380const sdp_namearray_t sdp_mediadir_role[SDP_MAX_MEDIADIR_ROLES] =
381{
382 {"passive", sizeof("passive")},
383 {"active", sizeof("active")},
384 {"both", sizeof("both")},
385 {"reuse", sizeof("reuse")},
386 {"unknown", sizeof("unknown")}
387};
388
389/* Note: These *must* be in the same order as the enum type. */
390const sdp_namearray_t sdp_fmtp_codec_param[SDP_MAX_FMTP_PARAM] =
391{
392 {"annexa", sizeof("annexa")}, /* 0 */
393 {"annexb", sizeof("annexb")}, /* 1 */
394 {"bitrate", sizeof("bitrate")}, /* 2 */
395 {"QCIF", sizeof("QCIF")}, /* 3 */
396 {"CIF", sizeof("CIF")}, /* 4 */
397 {"MAXBR", sizeof("MAXBR")}, /* 5 */
398 {"SQCIF", sizeof("SQCIF")}, /* 6 */
399 {"CIF4", sizeof("CIF4")}, /* 7 */
400 {"CIF16", sizeof("CIF16")}, /* 8 */
401 {"CUSTOM", sizeof("CUSTOM")}, /* 9 */
402 {"PAR", sizeof("PAR")}, /* 10 */
403 {"CPCF", sizeof("CPCF")}, /* 11 */
404 {"BPP", sizeof("BPP")}, /* 12 */
405 {"HRD", sizeof("HRD")}, /* 13 */
406 {"PROFILE", sizeof("PROFILE")}, /* 14 */
407 {"LEVEL", sizeof("LEVEL")}, /* 15 */
408 {"INTERLACE", sizeof("INTERLACE")}, /* 16 */
409
410 /* H.264 related */
411 {"profile-level-id", sizeof("profile-level-id")}, /* 17 */
412 {"sprop-parameter-sets", sizeof("sprop-parameter-sets")}, /* 18 */
413 {"packetization-mode", sizeof("packetization-mode")}, /* 19 */
414 {"sprop-interleaving-depth", sizeof("sprop-interleaving-depth")}, /* 20 */
415 {"sprop-deint-buf-req", sizeof("sprop-deint-buf-req")}, /* 21 */
416 {"sprop-max-don-diff", sizeof("sprop-max-don-diff")}, /* 22 */
417 {"sprop-init-buf-time", sizeof("sprop-init-buf-time")}, /* 23 */
418
419 {"max-mbps", sizeof("max-mbps")}, /* 24 */
420 {"max-fs", sizeof("max-fs")}, /* 25 */
421 {"max-cpb", sizeof("max-cpb")}, /* 26 */
422 {"max-dpb", sizeof("max-dpb")}, /* 27 */
423 {"max-br", sizeof("max-br")}, /* 28 */
424 {"redundant-pic-cap", sizeof("redundant-pic-cap")}, /* 29 */
425 {"deint-buf-cap", sizeof("deint-buf-cap")}, /* 30 */
426 {"max-rcmd-nalu-size", sizeof("max-rcmd_nali-size")}, /* 31 */
427 {"parameter-add", sizeof("parameter-add")}, /* 32 */
428
429 /* Annexes - require special handling */
430 {"D", sizeof("D")}, /* 33 */
431 {"F", sizeof("F")}, /* 34 */
432 {"I", sizeof("I")}, /* 35 */
433 {"J", sizeof("J")}, /* 36 */
434 {"T", sizeof("T")}, /* 37 */
435 {"K", sizeof("K")}, /* 38 */
436 {"N", sizeof("N")}, /* 39 */
437 {"P", sizeof("P")}, /* 40 */
438
439 {"mode", sizeof("mode")}, /* 41 */
440 {"level-asymmetry-allowed", sizeof("level-asymmetry-allowed")}, /* 42 */
441 {"maxaveragebitrate", sizeof("maxaveragebitrate")}, /* 43 */
442 {"usedtx", sizeof("usedtx")}, /* 44 */
443 {"stereo", sizeof("stereo")}, /* 45 */
444 {"useinbandfec", sizeof("useinbandfec")}, /* 46 */
445 {"maxcodedaudiobandwidth", sizeof("maxcodedaudiobandwidth")}, /* 47 */
446 {"cbr", sizeof("cbr")}, /* 48 */
447 {"max-fr", sizeof("max-fr")}, /* 49 */
448 {"maxplaybackrate", sizeof("maxplaybackrate")}, /* 50 */
449 {"apt", sizeof("apt")}, /* 51 */
450 {"rtx-time", sizeof("rtx-time")}, /* 52 */
451 {"level-idx", sizeof("level-idx")}, /* 53 */
452 {"tier", sizeof("tier")}, /* 54 */
453 {"ptime", sizeof("ptime")}, /* 55 */
454 {"minptime", sizeof("minptime")}, /* 56 */
455 {"maxptime", sizeof("maxptime")}, /* 57 */
456} ;
457
458/* Note: These *must* be in the same order as the enum type. */
459const sdp_namearray_t sdp_fmtp_codec_param_val[SDP_MAX_FMTP_PARAM_VAL] =
460{
461 {"yes", sizeof("yes")},
462 {"no", sizeof("no")}
463};
464
465const sdp_namearray_t sdp_bw_modifier_val[SDP_MAX_BW_MODIFIER_VAL] =
466{
467 {"AS", sizeof("AS")},
468 {"CT", sizeof("CT")},
469 {"TIAS", sizeof("TIAS")}
470};
471
472const sdp_namearray_t sdp_group_attr_val[SDP_MAX_GROUP_ATTR_VAL] =
473{
474 {"FID", sizeof("FID")},
475 {"LS", sizeof("LS")},
476 {"ANAT", sizeof("ANAT")},
477 {"BUNDLE", sizeof("BUNDLE")}
478};
479
480const sdp_namearray_t sdp_ssrc_group_attr_val[SDP_MAX_SSRC_GROUP_ATTR_VAL] = {
481 {"DUP", sizeof("DUP")},
482 {"FEC", sizeof("FEC")},
483 {"FEC-FR", sizeof("FEC-FR")},
484 {"FID", sizeof("FID")},
485 {"SIM", sizeof("SIM")}
486};
487
488const sdp_namearray_t sdp_srtp_context_crypto_suite[SDP_SRTP_MAX_NUM_CRYPTO_SUITES] =
489{
490 {"UNKNOWN_CRYPTO_SUITE", sizeof("UNKNOWN_CRYPTO_SUITE")},
491 {"AES_CM_128_HMAC_SHA1_32", sizeof("AES_CM_128_HMAC_SHA1_32")},
492 {"AES_CM_128_HMAC_SHA1_80", sizeof("AES_CM_128_HMAC_SHA1_80")},
493 {"F8_128_HMAC_SHA1_80", sizeof("F8_128_HMAC_SHA1_80")}
494};
495
496/* Maintain the same order as defined in typedef sdp_src_filter_mode_e */
497const sdp_namearray_t sdp_src_filter_mode_val[SDP_MAX_FILTER_MODE] =
498{
499 {"incl", sizeof("incl")},
500 {"excl", sizeof("excl")}
501};
502
503/* Maintain the same order as defined in typdef sdp_rtcp_unicast_mode_e */
504const sdp_namearray_t sdp_rtcp_unicast_mode_val[SDP_RTCP_MAX_UNICAST_MODE] =
505{
506 {"reflection", sizeof("reflection")},
507 {"rsi", sizeof("rsi")}
508};
509
510#define SDP_NAME(x){x, sizeof(x)} {x, sizeof(x)}
511/* Maintain the same order as defined in typdef sdp_rtcp_fb_type_e */
512const sdp_namearray_t sdp_rtcp_fb_type_val[SDP_MAX_RTCP_FB] =
513{
514 SDP_NAME("ack"){"ack", sizeof("ack")},
515 SDP_NAME("ccm"){"ccm", sizeof("ccm")},
516 SDP_NAME("nack"){"nack", sizeof("nack")},
517 SDP_NAME("trr-int"){"trr-int", sizeof("trr-int")},
518 SDP_NAME("goog-remb"){"goog-remb", sizeof("goog-remb")},
519 SDP_NAME("transport-cc"){"transport-cc", sizeof("transport-cc")}
520};
521
522/* Maintain the same order as defined in typdef sdp_rtcp_fb_nack_type_e */
523const sdp_namearray_t sdp_rtcp_fb_nack_type_val[SDP_MAX_RTCP_FB_NACK] =
524{
525 SDP_NAME(""){"", sizeof("")},
526 SDP_NAME("sli"){"sli", sizeof("sli")},
527 SDP_NAME("pli"){"pli", sizeof("pli")},
528 SDP_NAME("rpsi"){"rpsi", sizeof("rpsi")},
529 SDP_NAME("app"){"app", sizeof("app")},
530 SDP_NAME("rai"){"rai", sizeof("rai")},
531 SDP_NAME("tllei"){"tllei", sizeof("tllei")},
532 SDP_NAME("pslei"){"pslei", sizeof("pslei")},
533 SDP_NAME("ecn"){"ecn", sizeof("ecn")}
534};
535
536/* Maintain the same order as defined in typdef sdp_rtcp_fb_ack_type_e */
537const sdp_namearray_t sdp_rtcp_fb_ack_type_val[SDP_MAX_RTCP_FB_ACK] =
538{
539 SDP_NAME("rpsi"){"rpsi", sizeof("rpsi")},
540 SDP_NAME("app"){"app", sizeof("app")}
541};
542
543/* Maintain the same order as defined in typdef sdp_rtcp_fb_ccm_type_e */
544const sdp_namearray_t sdp_rtcp_fb_ccm_type_val[SDP_MAX_RTCP_FB_CCM] =
545{
546 SDP_NAME("fir"){"fir", sizeof("fir")},
547 SDP_NAME("tmmbr"){"tmmbr", sizeof("tmmbr")},
548 SDP_NAME("tstr"){"tstr", sizeof("tstr")},
549 SDP_NAME("vbcm"){"vbcm", sizeof("vbcm")}
550};
551
552/* Maintain the same order as defined in typedef sdp_setup_type_e */
553const sdp_namearray_t sdp_setup_type_val[SDP_MAX_SETUP] =
554{
555 SDP_NAME("active"){"active", sizeof("active")},
556 SDP_NAME("passive"){"passive", sizeof("passive")},
557 SDP_NAME("actpass"){"actpass", sizeof("actpass")},
558 SDP_NAME("holdconn"){"holdconn", sizeof("holdconn")}
559};
560
561/* Maintain the same order as defined in typedef sdp_connection_type_e */
562const sdp_namearray_t sdp_connection_type_val[SDP_MAX_CONNECTION] =
563{
564 SDP_NAME("new"){"new", sizeof("new")},
565 SDP_NAME("existing"){"existing", sizeof("existing")}
566};
567
568/* Maintain same order as defined in typedef sdp_srtp_crypto_suite_t */
569const sdp_srtp_crypto_suite_list sdp_srtp_crypto_suite_array[SDP_SRTP_MAX_NUM_CRYPTO_SUITES] =
570{
571 {SDP_SRTP_UNKNOWN_CRYPTO_SUITE, UNKNOWN_CRYPTO_SUITE"UNKNOWN_CRYPTO_SUITE", 0, 0},
572 {SDP_SRTP_AES_CM_128_HMAC_SHA1_32, AES_CM_128_HMAC_SHA1_32"AES_CM_128_HMAC_SHA1_32",
573 SDP_SRTP_AES_CM_128_HMAC_SHA1_32_KEY_BYTES16,
574 SDP_SRTP_AES_CM_128_HMAC_SHA1_32_SALT_BYTES14},
575 {SDP_SRTP_AES_CM_128_HMAC_SHA1_80, AES_CM_128_HMAC_SHA1_80"AES_CM_128_HMAC_SHA1_80",
576 SDP_SRTP_AES_CM_128_HMAC_SHA1_80_KEY_BYTES16,
577 SDP_SRTP_AES_CM_128_HMAC_SHA1_80_SALT_BYTES14},
578 {SDP_SRTP_F8_128_HMAC_SHA1_80, F8_128_HMAC_SHA1_80"F8_128_HMAC_SHA1_80",
579 SDP_SRTP_F8_128_HMAC_SHA1_80_KEY_BYTES16,
580 SDP_SRTP_F8_128_HMAC_SHA1_80_SALT_BYTES14}
581};
582
583const char* sdp_result_name[SDP_MAX_RC] =
584 {"SDP_SUCCESS",
585 "SDP_FAILURE",
586 "SDP_INVALID_SDP_PTR",
587 "SDP_NOT_SDP_DESCRIPTION",
588 "SDP_INVALID_TOKEN_ORDERING",
589 "SDP_INVALID_PARAMETER",
590 "SDP_INVALID_MEDIA_LEVEL",
591 "SDP_INVALID_CAPABILITY",
592 "SDP_NO_RESOURCE",
593 "SDP_UNRECOGNIZED_TOKEN",
594 "SDP_NULL_BUF_PTR",
595 "SDP_POTENTIAL_SDP_OVERFLOW",
596 "SDP_EMPTY_TOKEN"};
597
598const char *sdp_get_result_name ( sdp_result_e rc )
599{
600 if (rc >= SDP_MAX_RC) {
601 return ("Invalid SDP result code");
602 } else {
603 return (sdp_result_name[rc]);
604 }
605}
606
607const char *sdp_get_attr_name ( sdp_attr_e attr_type )
608{
609 if (attr_type >= SDP_MAX_ATTR_TYPES) {
610 return ("Invalid attribute type");
611 } else {
612 return (sdp_attr[attr_type].name);
613 }
614}
615
616const char *sdp_get_media_name ( sdp_media_e media_type )
617{
618 if (media_type == SDP_MEDIA_UNSUPPORTED) {
619 return (SDP_UNSUPPORTED"Unsupported");
620 } else if (media_type >= SDP_MAX_MEDIA_TYPES) {
621 return ("Invalid media type");
622 } else {
623 return (sdp_media[media_type].name);
624 }
625}
626
627const char *sdp_get_network_name ( sdp_nettype_e network_type )
628{
629 if (network_type == SDP_NT_UNSUPPORTED) {
630 return (SDP_UNSUPPORTED"Unsupported");
631 } else if (network_type >= SDP_MAX_NETWORK_TYPES) {
632 return ("Invalid network type");
633 } else {
634 return (sdp_nettype[network_type].name);
635 }
636}
637
638const char *sdp_get_address_name ( sdp_addrtype_e addr_type )
639{
640 if (addr_type == SDP_AT_UNSUPPORTED) {
641 return (SDP_UNSUPPORTED"Unsupported");
642 } else if (addr_type >= SDP_MAX_ADDR_TYPES) {
643 if (addr_type == SDP_AT_FQDN) {
644 return ("*");
645 } else {
646 return ("Invalid address type");
647 }
648 } else {
649 return (sdp_addrtype[addr_type].name);
650 }
651}
652
653const char *sdp_get_transport_name ( sdp_transport_e transport_type )
654{
655 if (transport_type == SDP_TRANSPORT_UNSUPPORTED) {
656 return (SDP_UNSUPPORTED"Unsupported");
657 } else if (transport_type >= SDP_MAX_TRANSPORT_TYPES) {
658 return ("Invalid transport type");
659 } else {
660 return (sdp_transport[transport_type].name);
661 }
662}
663
664const char *sdp_get_encrypt_name ( sdp_encrypt_type_e encrypt_type )
665{
666 if (encrypt_type == SDP_ENCRYPT_UNSUPPORTED) {
667 return (SDP_UNSUPPORTED"Unsupported");
668 } else if (encrypt_type >= SDP_MAX_ENCRYPT_TYPES) {
669 return ("Invalid encryption type");
670 } else {
671 return (sdp_encrypt[encrypt_type].name);
672 }
673}
674
675const char *sdp_get_payload_name ( sdp_payload_e payload )
676{
677 if (payload == SDP_PAYLOAD_UNSUPPORTED) {
678 return (SDP_UNSUPPORTED"Unsupported");
679 } else if (payload >= SDP_MAX_STRING_PAYLOAD_TYPES) {
680 return ("Invalid payload type");
681 } else {
682 return (sdp_payload[payload].name);
683 }
684}
685
686const char *sdp_get_t38_ratemgmt_name ( sdp_t38_ratemgmt_e rate )
687{
688 if (rate >= SDP_T38_MAX_RATES) {
689 return ("Invalid rate");
690 } else {
691 return (sdp_t38_rate[rate].name);
692 }
693}
694
695const char *sdp_get_t38_udpec_name ( sdp_t38_udpec_e udpec )
696{
697 if (udpec >= SDP_T38_MAX_UDPEC) {
698 return ("Invalid udpec");
699 } else {
700 return (sdp_t38_udpec[udpec].name);
701 }
702}
703
704const char *sdp_get_qos_strength_name ( sdp_qos_strength_e strength )
705{
706 if (strength >= SDP_MAX_QOS_STRENGTH) {
707 return ("Invalid qos strength");
708 } else {
709 return (sdp_qos_strength[strength].name);
710 }
711}
712
713const char *sdp_get_qos_direction_name ( sdp_qos_dir_e direction )
714{
715 if (direction >= SDP_MAX_QOS_DIR) {
716 return ("Invalid qos direction");
717 } else {
718 return (sdp_qos_direction[direction].name);
719 }
720}
721
722const char *sdp_get_qos_status_type_name ( sdp_qos_status_types_e status_type )
723{
724 if (status_type >= SDP_MAX_QOS_STATUS_TYPES) {
725 return ("Invalid qos status type");
726 } else {
727 return (sdp_qos_status_type[status_type].name);
728 }
729}
730
731const char *sdp_get_curr_type_name (sdp_curr_type_e curr_type )
732{
733 if (curr_type >= SDP_MAX_CURR_TYPES) {
734 return ("Invalid curr type");
735 } else {
736 return (sdp_curr_type[curr_type].name);
737 }
738}
739
740const char *sdp_get_des_type_name (sdp_des_type_e des_type )
741{
742 if (des_type >= SDP_MAX_DES_TYPES) {
743 return ("Invalid des type");
744 } else {
745 return (sdp_des_type[des_type].name);
746 }
747}
748
749const char *sdp_get_conf_type_name (sdp_conf_type_e conf_type )
750{
751 if (conf_type >= SDP_MAX_CONF_TYPES) {
752 return ("Invalid conf type");
753 } else {
754 return (sdp_conf_type[conf_type].name);
755 }
756}
757
758const char *sdp_get_silencesupp_pref_name (sdp_silencesupp_pref_e pref)
759{
760 if (pref >= SDP_MAX_SILENCESUPP_PREF) {
761 return ("Invalid silencesupp pref");
762 } else {
763 return (sdp_silencesupp_pref[pref].name);
764 }
765}
766
767const char *sdp_get_silencesupp_siduse_name (sdp_silencesupp_siduse_e siduse)
768{
769 if (siduse >= SDP_MAX_SILENCESUPP_SIDUSE) {
770 return ("Invalid silencesupp siduse");
771 } else {
772 return (sdp_silencesupp_siduse[siduse].name);
773 }
774}
775
776const char *sdp_get_mediadir_role_name (sdp_mediadir_role_e role)
777{
778 if (role >= SDP_MEDIADIR_ROLE_UNKNOWN) {
779 return ("Invalid media direction role");
780 } else {
781 return (sdp_mediadir_role[role].name);
782 }
783}
784
785
786const char *sdp_get_bw_modifier_name (sdp_bw_modifier_e bw_modifier_type)
787{
788 if (bw_modifier_type == SDP_BW_MODIFIER_UNSUPPORTED) {
789 return (SDP_UNSUPPORTED"Unsupported");
790 } else if (bw_modifier_type < SDP_BW_MODIFIER_AS ||
791 bw_modifier_type >= SDP_MAX_BW_MODIFIER_VAL) {
792 return ("Invalid bw modifier type");
793 } else {
794 return (sdp_bw_modifier_val[bw_modifier_type].name);
795 }
796}
797
798const char *sdp_get_group_attr_name (sdp_group_attr_e group_attr_type)
799{
800 if (group_attr_type == SDP_GROUP_ATTR_UNSUPPORTED) {
801 return (SDP_UNSUPPORTED"Unsupported");
802 } else if (group_attr_type >= SDP_MAX_GROUP_ATTR_VAL) {
803 return ("Invalid a=group: attribute type");
804 } else {
805 return (sdp_group_attr_val[group_attr_type].name);
806 }
807}
808
809const char *sdp_get_ssrc_group_attr_name(
810 sdp_ssrc_group_attr_e ssrc_group_attr_type) {
811 if (ssrc_group_attr_type == SDP_SSRC_GROUP_ATTR_UNSUPPORTED) {
812 return (SDP_UNSUPPORTED"Unsupported");
813 } else if (ssrc_group_attr_type >= SDP_MAX_SSRC_GROUP_ATTR_VAL) {
814 return ("Invalid a=ssrc-group: attribute type");
815 } else {
816 return (sdp_ssrc_group_attr_val[ssrc_group_attr_type].name);
817 }
818}
819
820const char *sdp_get_src_filter_mode_name (sdp_src_filter_mode_e type)
821{
822 if (type >= SDP_MAX_FILTER_MODE) {
823 return ("Invalid source filter mode");
824 } else {
825 return (sdp_src_filter_mode_val[type].name);
826 }
827}
828
829const char *sdp_get_rtcp_unicast_mode_name (sdp_rtcp_unicast_mode_e type)
830{
831 if (type >= SDP_RTCP_MAX_UNICAST_MODE) {
832 return ("Invalid rtcp unicast mode");
833 } else {
834 return (sdp_rtcp_unicast_mode_val[type].name);
835 }
836}
837
838/* Function: sdp_init_description
839 * Description: Allocates a new SDP structure that can be used for either
840 * parsing or building an SDP description. This routine
841 * saves the config pointer passed in the SDP structure so
842 * SDP will know how to parse/build based on the options defined.
843 * An SDP structure must be allocated before parsing or building
844 * since the handle must be passed to these routines.
845 * Parameters: config_p The config handle returned by sdp_init_config
846 * Returns: A handle for a new SDP structure as a void ptr.
847*/
848sdp_t *sdp_init_description (sdp_conf_options_t *conf_p)
849{
850 int i;
851 sdp_t *sdp_p;
852
853 if (!conf_p) {
854 return (NULL((void*)0));
855 }
856
857 sdp_p = (sdp_t *)SDP_MALLOC(sizeof(sdp_t))calloc(1, (sizeof(sdp_t)));
858 if (sdp_p == NULL((void*)0)) {
859 return (NULL((void*)0));
860 }
861
862 sdp_p->conf_p = conf_p;
863 sdp_p->version = SDP_CURRENT_VERSION0;
864 sdp_p->owner_name[0] = '\0';
865 sdp_p->owner_sessid[0] = '\0';
866 sdp_p->owner_version[0] = '\0';
867 sdp_p->owner_network_type = SDP_NT_INVALID;
868 sdp_p->owner_addr_type = SDP_AT_INVALID;
869 sdp_p->owner_addr[0] = '\0';
870 sdp_p->sessname[0] = '\0';
871 sdp_p->sessinfo_found = FALSE0;
872 sdp_p->uri_found = FALSE0;
873
874 sdp_p->default_conn.nettype = SDP_NT_INVALID;
875 sdp_p->default_conn.addrtype = SDP_AT_INVALID;
876 sdp_p->default_conn.conn_addr[0] = '\0';
877 sdp_p->default_conn.is_multicast = FALSE0;
878 sdp_p->default_conn.ttl = 0;
879 sdp_p->default_conn.num_of_addresses = 0;
880
881 sdp_p->bw.bw_data_count = 0;
882 sdp_p->bw.bw_data_list = NULL((void*)0);
883
884 sdp_p->timespec_p = NULL((void*)0);
885 sdp_p->sess_attrs_p = NULL((void*)0);
886 sdp_p->mca_p = NULL((void*)0);
887 sdp_p->mca_count = 0;
888
889 /* Set default debug flags from application config. */
890 for (i=0; i < SDP_MAX_DEBUG_TYPES; i++) {
891 sdp_p->debug_flag[i] = conf_p->debug_flag[i];
892 }
893
894 return (sdp_p);
895}
896
897
898/* Function: void sdp_debug(sdp_t *sdp_p, sdp_debug_e debug_type,
899 * tinybool my_bool);
900 * Description: Define the type of debug for this particular SDP structure.
901 * By default, each SDP description has the settings that are
902 * set for the application.
903 * Valid debug types are ERRORS, WARNINGS, and TRACE. Each
904 * debug type can be turned on/off individually. The
905 * debug level can be redefined at any time.
906 * Parameters: sdp_ptr The SDP handle returned by sdp_init_description.
907 * debug_type Specifies the debug type being enabled/disabled.
908 * my_bool Defines whether the debug should be enabled or not.
909 * Returns: Nothing.
910 */
911void sdp_debug (sdp_t *sdp_p, sdp_debug_e debug_type, tinybool debug_flag)
912{
913 if (!sdp_p) {
914 return;
915 }
916
917 if (debug_type < SDP_MAX_DEBUG_TYPES) {
918 sdp_p->debug_flag[debug_type] = debug_flag;
919 }
920}
921
922
923/* Function: void sdp_set_string_debug(sdp_t *sdp_p, char *debug_str)
924 * Description: Define a string to be associated with all debug output
925 * for this SDP. The string will be copied into the SDP
926 * structure and so the library will not be dependent on
927 * the application's memory for this string.
928 * Parameters: sdp_p The SDP handle returned by sdp_init_description.
929 * debug_str Pointer to a string that should be printed out
930 * with every debug msg.
931 * Returns: Nothing.
932 */
933void sdp_set_string_debug (sdp_t *sdp_p, const char *debug_str)
934{
935 if (!sdp_p) {
936 return;
937 }
938
939 sstrncpy(sdp_p->debug_str, debug_str, sizeof(sdp_p->debug_str));
940}
941
942
943/* Function: sdp_validate_sdp
944 * Description: Validate an SDP structure.
945 * Parameters: sdp_p The SDP handle of the struct to validate.
946 * Returns: A result value indicating if the validation was successful.
947 * If not, what type of error was encountered.
948 */
949sdp_result_e sdp_validate_sdp (sdp_t *sdp_p)
950{
951 int i;
952 uint16_t num_media_levels;
953
954 /* Need to validate c= info is specified at session level or
955 * at all m= levels.
956 */
957 if (sdp_connection_valid((void *)sdp_p, SDP_SESSION_LEVEL0xFFFF) == FALSE0) {
958 num_media_levels = sdp_get_num_media_lines((void *)sdp_p);
959 for (i=1; i <= num_media_levels; i++) {
960 if (sdp_connection_valid((void *)sdp_p, (unsigned short)i) == FALSE0) {
961 sdp_parse_error(sdp_p,
962 "%s c= connection line not specified for "
963 "every media level, validation failed.",
964 sdp_p->debug_str);
965 return (SDP_FAILURE);
966 }
967 }
968 }
969
970 /* Validate required lines were specified */
971 if ((sdp_owner_valid((void *)sdp_p) == FALSE0) &&
972 (sdp_p->conf_p->owner_reqd == TRUE1)) {
973 sdp_parse_error(sdp_p,
974 "%s o= owner line not specified, validation failed.",
975 sdp_p->debug_str);
976 return (SDP_FAILURE);
977 }
978
979 if ((sdp_session_name_valid((void *)sdp_p) == FALSE0) &&
980 (sdp_p->conf_p->session_name_reqd == TRUE1)) {
981 sdp_parse_error(sdp_p,
982 "%s s= session name line not specified, validation failed.",
983 sdp_p->debug_str);
984 return (SDP_FAILURE);
985 }
986
987 if ((sdp_timespec_valid((void *)sdp_p) == FALSE0) &&
988 (sdp_p->conf_p->timespec_reqd == TRUE1)) {
989 sdp_parse_error(sdp_p,
990 "%s t= timespec line not specified, validation failed.",
991 sdp_p->debug_str);
992 return (SDP_FAILURE);
993 }
994
995 return (SDP_SUCCESS);
996}
997
998/* Function: sdp_parse
999 * Description: Parse an SDP description in the specified buffer.
1000 * Parameters: sdp_p The SDP handle returned by sdp_init_description
1001 * bufp Pointer to the buffer containing the SDP
1002 * description to parse.
1003 * len The length of the buffer.
1004 * Returns: A result value indicating if the parse was successful and
1005 * if not, what type of error was encountered. The
1006 * information from the parse is stored in the sdp_p structure.
1007 */
1008sdp_result_e sdp_parse (sdp_t *sdp_p, const char *buf, size_t len)
1009{
1010 uint8_t i;
1011 uint16_t cur_level = SDP_SESSION_LEVEL0xFFFF;
1012 const char *ptr;
1013 const char *next_ptr = NULL((void*)0);
1014 char *line_end;
1015 sdp_token_e last_token = SDP_TOKEN_V;
1016 sdp_result_e result = SDP_SUCCESS;
1017 tinybool parse_done = FALSE0;
1018 tinybool end_found = FALSE0;
1019 tinybool first_line = TRUE1;
1020 tinybool unrec_token = FALSE0;
1021 const char **bufp = &buf;
1022
1023 if (!sdp_p) {
1024 return (SDP_INVALID_SDP_PTR);
1025 }
1026
1027 if ((bufp == NULL((void*)0)) || (*bufp == NULL((void*)0))) {
1028 return (SDP_NULL_BUF_PTR);
1029 }
1030
1031 if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) {
1032 SDP_PRINT("%s Trace SDP Parse:", sdp_p->debug_str)SDPLog(SDP_LOG_ERROR, "/root/firefox-clang/third_party/sipcc/sdp_main.c"
, 1032, "sdp", "%s Trace SDP Parse:", sdp_p->debug_str)
;
1033 }
1034
1035 next_ptr = *bufp;
1036 sdp_p->conf_p->num_parses++;
1037
1038 /* Initialize the last valid capability instance to zero. Used
1039 * to help in parsing X-cpar attrs. */
1040 sdp_p->cap_valid = FALSE0;
1041 sdp_p->last_cap_inst = 0;
1042
1043 sdp_p->parse_line = 0;
1044
1045 /* We want to try to find the end of the SDP description, even if
1046 * we find a parsing error.
1047 */
1048 while (!end_found) {
1049 /* If the last char of this line goes beyond the end of the buffer,
1050 * we don't parse it.
1051 */
1052 ptr = next_ptr;
1053 sdp_p->parse_line++;
1054 line_end = sdp_findchar(ptr, "\n");
1055 if ((line_end >= (*bufp + len)) ||
1056 (*line_end == '\0')) {
1057 /* As this does not update the result value the SDP up to this point
1058 * is still accept as valid. So encountering this is not treated as
1059 * an error.
1060 */
1061 sdp_parse_error(sdp_p,
1062 "%s End of line beyond end of buffer.",
1063 sdp_p->debug_str);
1064 SDPLogError(logTag, "SDP: Invalid SDP, no \\n (len %u): %*s",SDPLog(SDP_LOG_ERROR, "/root/firefox-clang/third_party/sipcc/sdp_main.c"
, 1065, logTag, "SDP: Invalid SDP, no \\n (len %u): %*s", (unsigned
)len, (int)len, *bufp)
1065 (unsigned)len, (int)len, *bufp)SDPLog(SDP_LOG_ERROR, "/root/firefox-clang/third_party/sipcc/sdp_main.c"
, 1065, logTag, "SDP: Invalid SDP, no \\n (len %u): %*s", (unsigned
)len, (int)len, *bufp)
;
1066 end_found = TRUE1;
1067 break;
1068 }
1069
1070 /* Print the line if we're tracing. */
1071 if ((parse_done == FALSE0) &&
1072 (sdp_p->debug_flag[SDP_DEBUG_TRACE])) {
1073 SDP_PRINT("%s ", sdp_p->debug_str)SDPLog(SDP_LOG_ERROR, "/root/firefox-clang/third_party/sipcc/sdp_main.c"
, 1073, "sdp", "%s ", sdp_p->debug_str)
;
1074
1075 SDP_PRINT("%*s", (int)(line_end - ptr), ptr)SDPLog(SDP_LOG_ERROR, "/root/firefox-clang/third_party/sipcc/sdp_main.c"
, 1075, "sdp", "%*s", (int)(line_end - ptr), ptr)
;
1076
1077 }
1078
1079 /* Find out which token this line has, if any. */
1080 for (i=0; i < SDP_MAX_TOKENS; i++) {
1081 if (strncmp(ptr, sdp_token[i].name, SDP_TOKEN_LEN2) == 0) {
1082 break;
1083 }
1084 }
1085 if (i == SDP_MAX_TOKENS) {
1086 /* See if the second char on the next line is an '=' char.
1087 * If so, we note this as an unrecognized token line. */
1088 if (ptr[1] == '=') {
1089 unrec_token = TRUE1;
1090 }
1091 if (first_line == TRUE1) {
1092 sdp_parse_error(sdp_p,
1093 "%s Attempt to parse text not recognized as "
1094 "SDP text, parse fails.", sdp_p->debug_str);
1095 /* If we haven't already printed out the line we
1096 * were trying to parse, do it now.
1097 */
1098 if (!sdp_p->debug_flag[SDP_DEBUG_TRACE]) {
1099 SDP_PRINT("%s ", sdp_p->debug_str)SDPLog(SDP_LOG_ERROR, "/root/firefox-clang/third_party/sipcc/sdp_main.c"
, 1099, "sdp", "%s ", sdp_p->debug_str)
;
1100 SDP_PRINT("%*s", (int)(line_end - ptr), ptr)SDPLog(SDP_LOG_ERROR, "/root/firefox-clang/third_party/sipcc/sdp_main.c"
, 1100, "sdp", "%*s", (int)(line_end - ptr), ptr)
;
1101 }
1102 sdp_p->conf_p->num_not_sdp_desc++;
1103 return (SDP_NOT_SDP_DESCRIPTION);
1104 } else {
1105 end_found = TRUE1;
1106 break;
1107 }
1108 }
1109
1110 /* This is the beginning of a new SDP description. */
1111 if ((first_line != TRUE1) && (i == SDP_TOKEN_V)) {
1112 end_found = TRUE1;
1113 break;
1114 }
1115
1116 /* Advance the next ptr to one char beyond the end of the line. */
1117 next_ptr = line_end + 1;
1118 if (next_ptr >= (*bufp + len)) {
1119 end_found = TRUE1;
1120 }
1121
1122 /* If we've finished parsing and are just looking for the end of
1123 * the SDP description, we don't need to do anything else here.
1124 */
1125 if (parse_done == TRUE1) {
1126 continue;
1127 }
1128
1129 /* Only certain tokens are valid at the media level. */
1130 if (cur_level != SDP_SESSION_LEVEL0xFFFF) {
1131 if ((i != SDP_TOKEN_I) && (i != SDP_TOKEN_C) &&
1132 (i != SDP_TOKEN_B) && (i != SDP_TOKEN_K) &&
1133 (i != SDP_TOKEN_A) && (i != SDP_TOKEN_M)) {
1134 sdp_p->conf_p->num_invalid_token_order++;
1135 sdp_parse_error(sdp_p,
1136 "%s Warning: Invalid token %s found at media level",
1137 sdp_p->debug_str, sdp_token[i].name);
1138 continue;
1139 }
1140 }
1141
1142 /* Verify the token ordering. */
1143 if (first_line == TRUE1) {
1144 if (i != SDP_TOKEN_V) {
1145 if (sdp_p->conf_p->version_reqd == TRUE1) {
1146 sdp_parse_error(sdp_p,
1147 "%s First line not v=, parse fails",
1148 sdp_p->debug_str);
1149 sdp_p->conf_p->num_invalid_token_order++;
1150 result = SDP_INVALID_TOKEN_ORDERING;
1151 parse_done = TRUE1;
1152 } else {
1153 last_token = (sdp_token_e)i;
1154 }
1155 } else {
1156 last_token = (sdp_token_e)i;
Value stored to 'last_token' is never read
1157 }
1158 first_line = FALSE0;
1159 } else {
1160 if (i < last_token) {
1161 sdp_p->conf_p->num_invalid_token_order++;
1162 sdp_parse_error(sdp_p,
1163 "%s Warning: Invalid token ordering detected, "
1164 "token %s found after token %s", sdp_p->debug_str,
1165 sdp_token[i].name, sdp_token[last_token].name);
1166 }
1167 }
1168
1169 /* Finally parse the line. */
1170 ptr += SDP_TOKEN_LEN2;
1171 result = sdp_token[i].parse_func(sdp_p, cur_level, (const char *)ptr);
1172 last_token = (sdp_token_e)i;
1173 if (last_token == SDP_TOKEN_M) {
1174 if (cur_level == SDP_SESSION_LEVEL0xFFFF) {
1175 cur_level = 1;
1176 } else {
1177 cur_level++;
1178 }
1179 /* The token ordering can start again at i= */
1180 last_token = (sdp_token_e)(SDP_TOKEN_I - 1);
1181 }
1182 if (result != SDP_SUCCESS) {
1183 parse_done = TRUE1;
1184 }
1185
1186 /* Skip the new line char at the end of this line and see if
1187 * this is the end of the buffer.
1188 */
1189 if ((line_end + 1) == (*bufp + len)) {
1190 end_found = TRUE1;
1191 }
1192 }
1193
1194 /* If we found no valid lines, return an error. */
1195 if (first_line == TRUE1) {
1196 sdp_p->conf_p->num_not_sdp_desc++;
1197 return (SDP_NOT_SDP_DESCRIPTION);
1198 }
1199
1200 /* If no errors were found yet, validate the overall sdp. */
1201 if (result == SDP_SUCCESS) {
1202 result = sdp_validate_sdp(sdp_p);
1203 }
1204 /* Return the pointer where we left off. */
1205 *bufp = next_ptr;
1206 /* If the SDP is valid, but the next line following was an
1207 * unrecognized <token>= line, indicate this on the return. */
1208 if ((result == SDP_SUCCESS) && (unrec_token == TRUE1)) {
1209 return (SDP_UNRECOGNIZED_TOKEN);
1210 } else {
1211 return (result);
1212 }
1213}
1214
1215
1216/* Function: sdp_build
1217 * Description: Build an SDP description in the specified buffer based
1218 * on the information in the given SDP structure.
1219 * Parameters: sdp_p The SDP handle returned by sdp_init_description
1220 * fs A flex_string where the SDP description should be built.
1221 * Returns: A result value indicating if the build was successful and
1222 * if not, what type of error was encountered - e.g.,
1223 * description was too long for the given buffer.
1224 */
1225sdp_result_e sdp_build (sdp_t *sdp_p, flex_string *fs)
1226{
1227 int i, j;
1228 sdp_result_e result = SDP_SUCCESS;
1229
1230 if (!sdp_p) {
1231 return (SDP_INVALID_SDP_PTR);
1232 }
1233
1234 if (!fs) {
1235 return (SDP_NULL_BUF_PTR);
1236 }
1237
1238 if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) {
1239 SDP_PRINT("%s Trace SDP Build:", sdp_p->debug_str)SDPLog(SDP_LOG_ERROR, "/root/firefox-clang/third_party/sipcc/sdp_main.c"
, 1239, "sdp", "%s Trace SDP Build:", sdp_p->debug_str)
;
1240 }
1241
1242 sdp_p->conf_p->num_builds++;
1243
1244 for (i=0; ((i < SDP_TOKEN_M) &&
1245 (result == SDP_SUCCESS)); i++) {
1246 result = sdp_token[i].build_func(sdp_p, SDP_SESSION_LEVEL0xFFFF, fs);
1247 /* ok not to check buffer space (yet) as the if() checks it */
1248 }
1249 /* If the session level was ok, build the media lines. */
1250 if (result == SDP_SUCCESS) {
1251 for (i=1; ((i <= sdp_p->mca_count) &&
1252 (result == SDP_SUCCESS)); i++) {
1253 result = sdp_token[SDP_TOKEN_M].build_func(sdp_p, (uint16_t)i, fs);
1254
1255 /* ok not to check buffer space (yet) as the for() checks it */
1256 for (j=SDP_TOKEN_I;
1257 ((j < SDP_TOKEN_M) && (result == SDP_SUCCESS));
1258 j++) {
1259 if ((j == SDP_TOKEN_U) || (j == SDP_TOKEN_E) ||
1260 (j == SDP_TOKEN_P) || (j == SDP_TOKEN_T) ||
1261 (j == SDP_TOKEN_R) || (j == SDP_TOKEN_Z)) {
1262 /* These tokens not valid at media level. */
1263 continue;
1264 }
1265 result = sdp_token[j].build_func(sdp_p, (uint16_t)i, fs);
1266 /* ok not to check buffer space (yet) as the for() checks it */
1267 }
1268 }
1269 }
1270
1271 return (result);
1272}
1273
1274/* Function: sdp_free_description
1275 * Description: Free an SDP description and all memory associated with it.
1276 * Parameters: sdp_p The SDP handle returned by sdp_init_description
1277 * Returns: A result value indicating if the free was successful and
1278 * if not, what type of error was encountered - e.g., sdp_p
1279 * was invalid and didn't point to an SDP structure.
1280*/
1281sdp_result_e sdp_free_description (sdp_t *sdp_p)
1282{
1283 sdp_timespec_t *time_p, *next_time_p;
1284 sdp_attr_t *attr_p, *next_attr_p;
1285 sdp_mca_t *mca_p, *next_mca_p;
1286 sdp_bw_t *bw_p;
1287 sdp_bw_data_t *bw_data_p;
1288
1289 if (!sdp_p) {
1290 return (SDP_INVALID_SDP_PTR);
1291 }
1292
1293 /* Free the config structure */
1294 sdp_free_config(sdp_p->conf_p);
1295
1296 /* Free any timespec structures - should be only one since
1297 * this is all we currently support.
1298 */
1299 time_p = sdp_p->timespec_p;
1300 while (time_p != NULL((void*)0)) {
1301 next_time_p = time_p->next_p;
1302 SDP_FREEfree(time_p);
1303 time_p = next_time_p;
1304 }
1305
1306 bw_p = &(sdp_p->bw);
1307 bw_data_p = bw_p->bw_data_list;
1308 while (bw_data_p != NULL((void*)0)) {
1309 bw_p->bw_data_list = bw_data_p->next_p;
1310 SDP_FREEfree(bw_data_p);
1311 bw_data_p = bw_p->bw_data_list;
1312 }
1313
1314 /* Free any session attr structures */
1315 attr_p = sdp_p->sess_attrs_p;
1316 while (attr_p != NULL((void*)0)) {
1317 next_attr_p = attr_p->next_p;
1318 sdp_free_attr(attr_p);
1319 attr_p = next_attr_p;
1320 }
1321
1322 /* Free any mca structures */
1323 mca_p = sdp_p->mca_p;
1324 while (mca_p != NULL((void*)0)) {
1325 next_mca_p = mca_p->next_p;
1326
1327 /* Free any media attr structures */
1328 attr_p = mca_p->media_attrs_p;
1329 while (attr_p != NULL((void*)0)) {
1330 next_attr_p = attr_p->next_p;
1331 sdp_free_attr(attr_p);
1332 attr_p = next_attr_p;
1333 }
1334
1335 /* Free the media profiles struct if allocated. */
1336 if (mca_p->media_profiles_p != NULL((void*)0)) {
1337 SDP_FREEfree(mca_p->media_profiles_p);
1338 }
1339
1340 bw_p = &(mca_p->bw);
1341 bw_data_p = bw_p->bw_data_list;
1342 while (bw_data_p != NULL((void*)0)) {
1343 bw_p->bw_data_list = bw_data_p->next_p;
1344 SDP_FREEfree(bw_data_p);
1345 bw_data_p = bw_p->bw_data_list;
1346 }
1347
1348 SDP_FREEfree(mca_p);
1349 mca_p = next_mca_p;
1350 }
1351
1352 SDP_FREEfree(sdp_p);
1353
1354 return (SDP_SUCCESS);
1355}
1356
1357/*
1358 * sdp_parse_error
1359 * Send SDP parsing errors to log and up to peerconnection
1360 */
1361void sdp_parse_error(sdp_t* sdp, const char *format, ...) {
1362 flex_string fs;
1363 va_list ap;
1364
1365 flex_string_init(&fs);
1366
1367 va_start(ap, format)__builtin_va_start(ap, format);
1368 flex_string_vsprintf(&fs, format, ap);
1369 va_end(ap)__builtin_va_end(ap);
1370
1371 SDPLogError("SDP Parse", "SDP Parse Error %s, line %u", fs.buffer,SDPLog(SDP_LOG_ERROR, "/root/firefox-clang/third_party/sipcc/sdp_main.c"
, 1372, "SDP Parse", "SDP Parse Error %s, line %u", fs.buffer
, sdp->parse_line)
1372 sdp->parse_line)SDPLog(SDP_LOG_ERROR, "/root/firefox-clang/third_party/sipcc/sdp_main.c"
, 1372, "SDP Parse", "SDP Parse Error %s, line %u", fs.buffer
, sdp->parse_line)
;
1373
1374 if (sdp->conf_p->error_handler) {
1375 sdp->conf_p->error_handler(sdp->conf_p->error_handler_context,
1376 sdp->parse_line,
1377 fs.buffer);
1378 }
1379
1380 flex_string_free(&fs);
1381}