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
3 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 :
5 : #include "sdp_os_defs.h"
6 : #include "sdp.h"
7 : #include "sdp_private.h"
8 :
9 : #include "CSFLog.h"
10 :
11 : static const char* logTag = "sdp_access";
12 :
13 : /* Pulled in from ccsip_sdp.h */
14 : /* Possible encoding names of static payload types*/
15 : #define SIPSDP_ATTR_ENCNAME_PCMU "PCMU"
16 : #define SIPSDP_ATTR_ENCNAME_PCMA "PCMA"
17 : #define SIPSDP_ATTR_ENCNAME_G729 "G729"
18 : #define SIPSDP_ATTR_ENCNAME_G723 "G723"
19 : #define SIPSDP_ATTR_ENCNAME_G726 "G726-32"
20 : #define SIPSDP_ATTR_ENCNAME_G728 "G728"
21 : #define SIPSDP_ATTR_ENCNAME_GSM "GSM"
22 : #define SIPSDP_ATTR_ENCNAME_CN "CN"
23 : #define SIPSDP_ATTR_ENCNAME_G722 "G722"
24 : #define SIPSDP_ATTR_ENCNAME_ILBC "iLBC"
25 : #define SIPSDP_ATTR_ENCNAME_H263v2 "H263-1998"
26 : #define SIPSDP_ATTR_ENCNAME_H264 "H264"
27 : #define SIPSDP_ATTR_ENCNAME_VP8 "VP8"
28 : #define SIPSDP_ATTR_ENCNAME_VP9 "VP9"
29 : #define SIPSDP_ATTR_ENCNAME_L16_256K "L16"
30 : #define SIPSDP_ATTR_ENCNAME_ISAC "ISAC"
31 : #define SIPSDP_ATTR_ENCNAME_OPUS "opus"
32 : #define SIPSDP_ATTR_ENCNAME_RED "red"
33 : #define SIPSDP_ATTR_ENCNAME_ULPFEC "ulpfec"
34 : #define SIPSDP_ATTR_ENCNAME_TELEPHONE_EVENT "telephone-event"
35 :
36 : /* Function: sdp_find_media_level
37 : * Description: Find and return a pointer to the specified media level,
38 : * if it exists.
39 : * Note: This is not an API for the application but an internal
40 : * routine used by the SDP library.
41 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
42 : * level The media level to find.
43 : * Returns: Pointer to the media level or NULL if not found.
44 : */
45 0 : sdp_mca_t *sdp_find_media_level (sdp_t *sdp_p, uint16_t level)
46 : {
47 : int i;
48 0 : sdp_mca_t *mca_p = NULL;
49 :
50 0 : if ((level >= 1) && (level <= sdp_p->mca_count)) {
51 0 : for (i=1, mca_p = sdp_p->mca_p;
52 0 : ((i < level) && (mca_p != NULL));
53 0 : mca_p = mca_p->next_p, i++) {
54 :
55 : /*sa_ignore EMPTYLOOP*/
56 : ; /* Do nothing. */
57 : }
58 : }
59 :
60 0 : return (mca_p);
61 : }
62 :
63 : /* Function: sdp_version_valid
64 : * Description: Returns true or false depending on whether the version
65 : * set for this SDP is valid. Currently the only valid
66 : * version is 0.
67 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
68 : * Returns: TRUE or FALSE.
69 : */
70 0 : tinybool sdp_version_valid (sdp_t *sdp_p)
71 : {
72 0 : if (sdp_p->version == SDP_INVALID_VALUE) {
73 0 : return (FALSE);
74 : } else {
75 0 : return (TRUE);
76 : }
77 : }
78 :
79 : /* Function: sdp_get_version
80 : * Description: Returns the version value set for the given SDP.
81 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
82 : * Returns: Version value.
83 : */
84 0 : int32_t sdp_get_version (sdp_t *sdp_p)
85 : {
86 0 : return (sdp_p->version);
87 : }
88 :
89 : /* Function: sdp_set_version
90 : * Description: Sets the value of the version parameter for the v= version
91 : * token line.
92 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
93 : * version Version to set.
94 : * Returns: SDP_SUCCESS
95 : */
96 0 : sdp_result_e sdp_set_version (sdp_t *sdp_p, int32_t version)
97 : {
98 0 : sdp_p->version = version;
99 0 : return (SDP_SUCCESS);
100 : }
101 :
102 : /* Function: sdp_owner_valid
103 : * Description: Returns true or false depending on whether the owner
104 : * token line has been defined for this SDP.
105 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
106 : * Returns: TRUE or FALSE.
107 : */
108 0 : tinybool sdp_owner_valid (sdp_t *sdp_p)
109 : {
110 0 : if ((sdp_p->owner_name[0] == '\0') ||
111 0 : (sdp_p->owner_network_type == SDP_NT_INVALID) ||
112 0 : (sdp_p->owner_addr_type == SDP_AT_INVALID) ||
113 0 : (sdp_p->owner_addr[0] == '\0')) {
114 0 : return (FALSE);
115 : } else {
116 0 : return (TRUE);
117 : }
118 : }
119 :
120 : /* Function: sdp_get_owner_username
121 : * Description: Returns a pointer to the value of the username parameter
122 : * from the o= owner token line. Value is returned as a
123 : * const ptr and so cannot be modified by the application.
124 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
125 : * Returns: Version value.
126 : */
127 0 : const char *sdp_get_owner_username (sdp_t *sdp_p)
128 : {
129 0 : return (sdp_p->owner_name);
130 : }
131 :
132 : /* Function: sdp_get_owner_sessionid
133 : * Description: Returns the session id parameter from the o= owner token
134 : * line. Because the value may be larger than 32 bits, this
135 : * parameter is returned as a string, though has been verified
136 : * to be numeric. Value is returned as a const ptr and so
137 : * cannot be modified by the application.
138 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
139 : * Returns: Ptr to owner session id or NULL.
140 : */
141 0 : const char *sdp_get_owner_sessionid (sdp_t *sdp_p)
142 : {
143 0 : return (sdp_p->owner_sessid);
144 : }
145 :
146 : /* Function: sdp_get_owner_version
147 : * Description: Returns the version parameter from the o= owner token
148 : * line. Because the value may be larger than 32 bits, this
149 : * parameter is returned as a string, though has been verified
150 : * to be numeric. Value is returned as a const ptr and so
151 : * cannot be modified by the application.
152 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
153 : * Returns: Ptr to owner version or NULL.
154 : */
155 0 : const char *sdp_get_owner_version (sdp_t *sdp_p)
156 : {
157 0 : return (sdp_p->owner_version);
158 : }
159 :
160 : /* Function: sdp_get_owner_network_type
161 : * Description: Returns the network type parameter from the o= owner token
162 : * line. If network type has not been set SDP_NT_INVALID will
163 : * be returned.
164 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
165 : * Returns: Network type or SDP_NT_INVALID.
166 : */
167 0 : sdp_nettype_e sdp_get_owner_network_type (sdp_t *sdp_p)
168 : {
169 0 : return (sdp_p->owner_network_type);
170 : }
171 :
172 : /* Function: sdp_get_owner_address_type
173 : * Description: Returns the address type parameter from the o= owner token
174 : * line. If address type has not been set SDP_AT_INVALID will
175 : * be returned.
176 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
177 : * Returns: Address type or SDP_AT_INVALID.
178 : */
179 0 : sdp_addrtype_e sdp_get_owner_address_type (sdp_t *sdp_p)
180 : {
181 0 : return (sdp_p->owner_addr_type);
182 : }
183 :
184 : /* Function: sdp_get_owner_address
185 : * Description: Returns the address parameter from the o= owner token
186 : * line. Value is returned as a const ptr and so
187 : * cannot be modified by the application.
188 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
189 : * Returns: Ptr to address or NULL.
190 : */
191 0 : const char *sdp_get_owner_address (sdp_t *sdp_p)
192 : {
193 0 : return (sdp_p->owner_addr);
194 : }
195 :
196 : /* Function: sdp_set_owner_username
197 : * Description: Sets the value of the username parameter for the o= owner
198 : * token line. The string is copied into the SDP structure
199 : * so application memory will not be referenced by the SDP lib.
200 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
201 : * username Ptr to the username string.
202 : * Returns: SDP_SUCCESS
203 : */
204 0 : sdp_result_e sdp_set_owner_username (sdp_t *sdp_p, const char *username)
205 : {
206 0 : sstrncpy(sdp_p->owner_name, username, sizeof(sdp_p->owner_name));
207 0 : return (SDP_SUCCESS);
208 : }
209 :
210 : /* Function: sdp_set_owner_username
211 : * Description: Sets the value of the session id parameter for the o= owner
212 : * token line. The string is copied into the SDP structure
213 : * so application memory will not be referenced by the SDP lib.
214 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
215 : * sessionid Ptr to the sessionid string.
216 : * Returns: SDP_SUCCESS
217 : */
218 0 : sdp_result_e sdp_set_owner_sessionid (sdp_t *sdp_p, const char *sessionid)
219 : {
220 0 : sstrncpy(sdp_p->owner_sessid, sessionid, sizeof(sdp_p->owner_sessid));
221 0 : return (SDP_SUCCESS);
222 : }
223 :
224 : /* Function: sdp_set_owner_version
225 : * Description: Sets the value of the version parameter for the o= owner
226 : * token line. The string is copied into the SDP structure
227 : * so application memory will not be referenced by the SDP lib.
228 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
229 : * version Ptr to the version string.
230 : * Returns: SDP_SUCCESS
231 : */
232 0 : sdp_result_e sdp_set_owner_version (sdp_t *sdp_p, const char *version)
233 : {
234 0 : sstrncpy(sdp_p->owner_version, version, sizeof(sdp_p->owner_version));
235 0 : return (SDP_SUCCESS);
236 : }
237 :
238 : /* Function: sdp_set_owner_network_type
239 : * Description: Sets the value of the network type parameter for the o= owner
240 : * token line.
241 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
242 : * network_type Network type for the owner line.
243 : * Returns: SDP_SUCCESS
244 : */
245 0 : sdp_result_e sdp_set_owner_network_type (sdp_t *sdp_p,
246 : sdp_nettype_e network_type)
247 : {
248 0 : sdp_p->owner_network_type = network_type;
249 0 : return (SDP_SUCCESS);
250 : }
251 :
252 : /* Function: sdp_set_owner_address_type
253 : * Description: Sets the value of the address type parameter for the o= owner
254 : * token line.
255 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
256 : * address_type Address type for the owner line.
257 : * Returns: SDP_SUCCESS
258 : */
259 0 : sdp_result_e sdp_set_owner_address_type (sdp_t *sdp_p,
260 : sdp_addrtype_e address_type)
261 : {
262 0 : sdp_p->owner_addr_type = address_type;
263 0 : return (SDP_SUCCESS);
264 : }
265 :
266 : /* Function: sdp_set_owner_address
267 : * Description: Sets the value of the address parameter for the o= owner
268 : * token line. The string is copied into the SDP structure
269 : * so application memory will not be referenced by the SDP lib.
270 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
271 : * version Ptr to the version string.
272 : * Returns: SDP_SUCCESS
273 : */
274 0 : sdp_result_e sdp_set_owner_address (sdp_t *sdp_p, const char *address)
275 : {
276 0 : sstrncpy(sdp_p->owner_addr, address, sizeof(sdp_p->owner_addr));
277 0 : return (SDP_SUCCESS);
278 : }
279 :
280 : /* Function: sdp_session_name_valid
281 : * Description: Returns true or false depending on whether the session name
282 : * s= token line has been defined for this SDP.
283 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
284 : * Returns: TRUE or FALSE.
285 : */
286 0 : tinybool sdp_session_name_valid (sdp_t *sdp_p)
287 : {
288 0 : if (sdp_p->sessname[0] == '\0') {
289 0 : return (FALSE);
290 : } else {
291 0 : return (TRUE);
292 : }
293 : }
294 :
295 : /* Function: sdp_get_session_name
296 : * Description: Returns the session name parameter from the s= session
297 : * name token line. Value is returned as a const ptr and so
298 : * cannot be modified by the application.
299 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
300 : * Returns: Ptr to session name or NULL.
301 : */
302 0 : const char *sdp_get_session_name (sdp_t *sdp_p)
303 : {
304 0 : return (sdp_p->sessname);
305 : }
306 :
307 : /* Function: sdp_set_session_name
308 : * Description: Sets the value of the session name parameter for the s=
309 : * session name token line. The string is copied into the
310 : * SDP structure so application memory will not be
311 : * referenced by the SDP lib.
312 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
313 : * sessname Ptr to the session name string.
314 : * Returns: SDP_SUCCESS
315 : */
316 0 : sdp_result_e sdp_set_session_name (sdp_t *sdp_p, const char *sessname)
317 : {
318 0 : sstrncpy(sdp_p->sessname, sessname, sizeof(sdp_p->sessname));
319 0 : return (SDP_SUCCESS);
320 : }
321 :
322 : /* Function: sdp_timespec_valid
323 : * Description: Returns true or false depending on whether the timespec t=
324 : * token line has been defined for this SDP.
325 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
326 : * Returns: TRUE or FALSE.
327 : */
328 0 : tinybool sdp_timespec_valid (sdp_t *sdp_p)
329 : {
330 0 : if ((sdp_p->timespec_p == NULL) ||
331 0 : (sdp_p->timespec_p->start_time[0] == '\0') ||
332 0 : (sdp_p->timespec_p->stop_time[0] == '\0')) {
333 0 : return (FALSE);
334 : } else {
335 0 : return (TRUE);
336 : }
337 : }
338 :
339 : /* Function: sdp_get_time_start
340 : * Description: Returns the start time parameter from the t= timespec token
341 : * line. Because the value may be larger than 32 bits, this
342 : * parameter is returned as a string, though has been verified
343 : * to be numeric. Value is returned as a const ptr and so
344 : * cannot be modified by the application.
345 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
346 : * Returns: Ptr to start time or NULL.
347 : */
348 0 : const char *sdp_get_time_start (sdp_t *sdp_p)
349 : {
350 0 : if (sdp_p->timespec_p != NULL) {
351 0 : return (sdp_p->timespec_p->start_time);
352 : } else {
353 0 : return (NULL);
354 : }
355 : }
356 :
357 : /* Function: sdp_get_time_stop
358 : * Description: Returns the stop time parameter from the t= timespec token
359 : * line. Because the value may be larger than 32 bits, this
360 : * parameter is returned as a string, though has been verified
361 : * to be numeric. Value is returned as a const ptr and so
362 : * cannot be modified by the application.
363 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
364 : * Returns: Ptr to stop time or NULL.
365 : */
366 0 : const char *sdp_get_time_stop (sdp_t *sdp_p)
367 : {
368 0 : if (sdp_p->timespec_p != NULL) {
369 0 : return (sdp_p->timespec_p->stop_time);
370 : } else {
371 0 : return (NULL);
372 : }
373 : }
374 :
375 : /* Function: sdp_set_time_start
376 : * Description: Sets the value of the start time parameter for the t=
377 : * timespec token line. The string is copied into the
378 : * SDP structure so application memory will not be
379 : * referenced by the SDP lib.
380 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
381 : * start_time Ptr to the start time string.
382 : * Returns: SDP_SUCCESS
383 : */
384 0 : sdp_result_e sdp_set_time_start (sdp_t *sdp_p, const char *start_time)
385 : {
386 0 : if (sdp_p->timespec_p == NULL) {
387 0 : sdp_p->timespec_p = (sdp_timespec_t *)SDP_MALLOC(sizeof(sdp_timespec_t));
388 0 : if (sdp_p->timespec_p == NULL) {
389 0 : sdp_p->conf_p->num_no_resource++;
390 0 : return (SDP_NO_RESOURCE);
391 : }
392 0 : sdp_p->timespec_p->start_time[0] = '\0';
393 0 : sdp_p->timespec_p->stop_time[0] = '\0';
394 : }
395 0 : sstrncpy(sdp_p->timespec_p->start_time, start_time,
396 : sizeof(sdp_p->timespec_p->start_time));
397 0 : return (SDP_SUCCESS);
398 : }
399 :
400 : /* Function: sdp_set_time_stop
401 : * Description: Sets the value of the stop time parameter for the t=
402 : * timespec token line. The string is copied into the
403 : * SDP structure so application memory will not be
404 : * referenced by the SDP lib.
405 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
406 : * stop_time Ptr to the stop time string.
407 : * Returns: SDP_SUCCESS
408 : */
409 0 : sdp_result_e sdp_set_time_stop (sdp_t *sdp_p, const char *stop_time)
410 : {
411 0 : if (sdp_p->timespec_p == NULL) {
412 0 : sdp_p->timespec_p = (sdp_timespec_t *)SDP_MALLOC(sizeof(sdp_timespec_t));
413 0 : if (sdp_p->timespec_p == NULL) {
414 0 : sdp_p->conf_p->num_no_resource++;
415 0 : return (SDP_NO_RESOURCE);
416 : }
417 0 : sdp_p->timespec_p->start_time[0] = '\0';
418 0 : sdp_p->timespec_p->stop_time[0] = '\0';
419 : }
420 0 : sstrncpy(sdp_p->timespec_p->stop_time, stop_time,
421 : sizeof(sdp_p->timespec_p->stop_time));
422 0 : return (SDP_SUCCESS);
423 : }
424 :
425 : /* Function: sdp_encryption_valid
426 : * Description: Returns true or false depending on whether the encryption k=
427 : * token line has been defined for this SDP at the given level.
428 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
429 : * level The level to check for the k= line. Will be
430 : * either SDP_SESSION_LEVEL or 1-n specifying a
431 : * media line level.
432 : * Returns: TRUE or FALSE.
433 : */
434 0 : tinybool sdp_encryption_valid (sdp_t *sdp_p, uint16_t level)
435 : {
436 : sdp_encryptspec_t *encrypt_p;
437 : sdp_mca_t *mca_p;
438 :
439 0 : if (level == SDP_SESSION_LEVEL) {
440 0 : encrypt_p = &(sdp_p->encrypt);
441 : } else {
442 0 : mca_p = sdp_find_media_level(sdp_p, level);
443 0 : if (mca_p == NULL) {
444 0 : return (FALSE);
445 : }
446 0 : encrypt_p = &(mca_p->encrypt);
447 : }
448 :
449 0 : if ((encrypt_p->encrypt_type == SDP_ENCRYPT_INVALID) ||
450 0 : ((encrypt_p->encrypt_type != SDP_ENCRYPT_PROMPT) &&
451 0 : (encrypt_p->encrypt_key[0] == '\0'))) {
452 0 : return (FALSE);
453 : } else {
454 0 : return (TRUE);
455 : }
456 : }
457 :
458 : /* Function: sdp_get_encryption_method
459 : * Description: Returns the encryption method parameter from the k=
460 : * encryption token line. If encryption method has not been
461 : * set SDP_ENCRYPT_INVALID will be returned.
462 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
463 : * level The level to check for the c= line. Will be
464 : * either SDP_SESSION_LEVEL or 1-n specifying a
465 : * media line level.
466 : * Returns: Encryption method or SDP_ENCRYPT_INVALID.
467 : */
468 0 : sdp_encrypt_type_e sdp_get_encryption_method (sdp_t *sdp_p, uint16_t level)
469 : {
470 : sdp_encryptspec_t *encrypt_p;
471 : sdp_mca_t *mca_p;
472 :
473 0 : if (level == SDP_SESSION_LEVEL) {
474 0 : encrypt_p = &(sdp_p->encrypt);
475 : } else {
476 0 : mca_p = sdp_find_media_level(sdp_p, level);
477 0 : if (mca_p == NULL) {
478 0 : return (SDP_ENCRYPT_INVALID);
479 : }
480 0 : encrypt_p = &(mca_p->encrypt);
481 : }
482 :
483 0 : return (encrypt_p->encrypt_type);
484 : }
485 :
486 : /* Function: sdp_get_encryption_key
487 : * Description: Returns a pointer to the encryption key parameter
488 : * from the k= encryption token line. Value is returned as a
489 : * const ptr and so cannot be modified by the application.
490 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
491 : * level The level to check for the c= line. Will be
492 : * either SDP_SESSION_LEVEL or 1-n specifying a
493 : * media line level.
494 : * Returns: Ptr to encryption key or NULL.
495 : */
496 0 : const char *sdp_get_encryption_key (sdp_t *sdp_p, uint16_t level)
497 : {
498 : sdp_encryptspec_t *encrypt_p;
499 : sdp_mca_t *mca_p;
500 :
501 0 : if (level == SDP_SESSION_LEVEL) {
502 0 : encrypt_p = &(sdp_p->encrypt);
503 : } else {
504 0 : mca_p = sdp_find_media_level(sdp_p, level);
505 0 : if (mca_p == NULL) {
506 0 : return (NULL);
507 : }
508 0 : encrypt_p = &(mca_p->encrypt);
509 : }
510 :
511 0 : return (encrypt_p->encrypt_key);
512 : }
513 :
514 : /* Function: sdp_connection_valid
515 : * Description: Returns true or false depending on whether the connection c=
516 : * token line has been defined for this SDP at the given level.
517 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
518 : * level The level to check for the c= line. Will be
519 : * either SDP_SESSION_LEVEL or 1-n specifying a
520 : * media line level.
521 : * Returns: TRUE or FALSE.
522 : */
523 0 : tinybool sdp_connection_valid (sdp_t *sdp_p, uint16_t level)
524 : {
525 : sdp_conn_t *conn_p;
526 : sdp_mca_t *mca_p;
527 :
528 0 : if (level == SDP_SESSION_LEVEL) {
529 0 : conn_p = &(sdp_p->default_conn);
530 : } else {
531 0 : mca_p = sdp_find_media_level(sdp_p, level);
532 0 : if (mca_p == NULL) {
533 0 : return (FALSE);
534 : }
535 0 : conn_p = &(mca_p->conn);
536 : }
537 :
538 : /*if network type is ATM . then allow c= line without address type
539 : * and address . This is a special case to cover PVC
540 : */
541 0 : if (conn_p->nettype == SDP_NT_ATM &&
542 0 : conn_p->addrtype == SDP_AT_INVALID) {
543 0 : return TRUE;
544 : }
545 :
546 0 : if ((conn_p->nettype >= SDP_MAX_NETWORK_TYPES) ||
547 0 : (conn_p->addrtype >= SDP_MAX_ADDR_TYPES) ||
548 0 : (conn_p->conn_addr[0] == '\0')) {
549 0 : return (FALSE);
550 : } else {
551 0 : return (TRUE);
552 : }
553 : }
554 :
555 : /* Function: sdp_bandwidth_valid
556 : * Description: Returns true or false depending on whether the bandwidth b=
557 : * token line has been defined for this SDP at the given level.
558 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
559 : * level The level to check for the c= line. Will be
560 : * either SDP_SESSION_LEVEL or 1-n specifying a
561 : * media line level.
562 : * inst_num instance number of bw line at that level. The first
563 : * instance has a inst_num of 1 and so on.
564 : * Returns: TRUE or FALSE.
565 : */
566 0 : tinybool sdp_bandwidth_valid (sdp_t *sdp_p, uint16_t level, uint16_t inst_num)
567 : {
568 : sdp_bw_data_t *bw_data_p;
569 :
570 0 : bw_data_p = sdp_find_bw_line(sdp_p, level, inst_num);
571 0 : if (bw_data_p != NULL) {
572 0 : if ((bw_data_p->bw_modifier < SDP_BW_MODIFIER_AS) ||
573 0 : (bw_data_p->bw_modifier >= SDP_MAX_BW_MODIFIER_VAL)) {
574 0 : return FALSE;
575 : } else {
576 0 : return TRUE;
577 : }
578 : } else {
579 0 : return FALSE;
580 : }
581 : }
582 :
583 : /*
584 : * sdp_bw_line_exists
585 : *
586 : * Description: This api retruns true if there exists a bw line at the
587 : * instance and level specified.
588 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
589 : * level The level to check for the c= line. Will be
590 : * either SDP_SESSION_LEVEL or 1-n specifying a
591 : * media line level.
592 : * inst_num instance number of bw line at that level. The first
593 : * instance has a inst_num of 1 and so on.
594 : * Returns: TRUE or FALSE
595 : */
596 0 : tinybool sdp_bw_line_exists (sdp_t *sdp_p, uint16_t level, uint16_t inst_num)
597 : {
598 : sdp_bw_data_t *bw_data_p;
599 :
600 0 : bw_data_p = sdp_find_bw_line(sdp_p, level, inst_num);
601 0 : if (bw_data_p != NULL) {
602 0 : return TRUE;
603 : } else {
604 0 : return FALSE;
605 : }
606 : }
607 :
608 : /* Function: sdp_get_conn_nettype
609 : * Description: Returns the network type parameter from the c=
610 : * connection token line. If network type has not been
611 : * set SDP_NT_INVALID will be returned.
612 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
613 : * level The level to check for the c= line. Will be
614 : * either SDP_SESSION_LEVEL or 1-n specifying a
615 : * media line level.
616 : * Returns: Network type or SDP_NT_INVALID.
617 : */
618 0 : sdp_nettype_e sdp_get_conn_nettype (sdp_t *sdp_p, uint16_t level)
619 : {
620 : sdp_conn_t *conn_p;
621 : sdp_mca_t *mca_p;
622 :
623 0 : if (level == SDP_SESSION_LEVEL) {
624 0 : conn_p = &(sdp_p->default_conn);
625 : } else {
626 0 : mca_p = sdp_find_media_level(sdp_p, level);
627 0 : if (mca_p == NULL) {
628 0 : return (SDP_NT_INVALID);
629 : }
630 0 : conn_p = &(mca_p->conn);
631 : }
632 :
633 0 : return (conn_p->nettype);
634 : }
635 :
636 : /* Function: sdp_get_conn_addrtype
637 : * Description: Returns the address type parameter from the c=
638 : * connection token line. If address type has not been
639 : * set SDP_AT_INVALID will be returned.
640 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
641 : * level The level to check for the c= line. Will be
642 : * either SDP_SESSION_LEVEL or 1-n specifying a
643 : * media line level.
644 : * Returns: Address type or SDP_AT_INVALID.
645 : */
646 0 : sdp_addrtype_e sdp_get_conn_addrtype (sdp_t *sdp_p, uint16_t level)
647 : {
648 : sdp_conn_t *conn_p;
649 : sdp_mca_t *mca_p;
650 :
651 0 : if (level == SDP_SESSION_LEVEL) {
652 0 : conn_p = &(sdp_p->default_conn);
653 : } else {
654 0 : mca_p = sdp_find_media_level(sdp_p, level);
655 0 : if (mca_p == NULL) {
656 0 : return (SDP_AT_INVALID);
657 : }
658 0 : conn_p = &(mca_p->conn);
659 : }
660 :
661 0 : return (conn_p->addrtype);
662 : }
663 :
664 : /* Function: sdp_get_conn_address
665 : * Description: Returns a pointer to the address parameter
666 : * from the c= connection token line. Value is returned as a
667 : * const ptr and so cannot be modified by the application.
668 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
669 : * level The level to check for the c= line. Will be
670 : * either SDP_SESSION_LEVEL or 1-n specifying a
671 : * media line level.
672 : * Returns: Ptr to address or NULL.
673 : */
674 0 : const char *sdp_get_conn_address (sdp_t *sdp_p, uint16_t level)
675 : {
676 : sdp_conn_t *conn_p;
677 : sdp_mca_t *mca_p;
678 :
679 0 : if (level == SDP_SESSION_LEVEL) {
680 0 : conn_p = &(sdp_p->default_conn);
681 : } else {
682 0 : mca_p = sdp_find_media_level(sdp_p, level);
683 0 : if (mca_p == NULL) {
684 0 : return (NULL);
685 : }
686 0 : conn_p = &(mca_p->conn);
687 : }
688 :
689 0 : return (conn_p->conn_addr);
690 : }
691 :
692 : /* Function: sdp_is_mcast_addr
693 : * Description: Returns a boolean to indicate if the addr is multicast in
694 : * the c=line.
695 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
696 : * level The level to check for the c= line. Will be
697 : * either SDP_SESSION_LEVEL or 1-n specifying a
698 : * media line level.
699 : * Returns: TRUE if the addr is multicast, FALSE if not.
700 : */
701 :
702 0 : tinybool sdp_is_mcast_addr (sdp_t *sdp_p, uint16_t level)
703 : {
704 : sdp_conn_t *conn_p;
705 : sdp_mca_t *mca_p;
706 :
707 0 : if (level == SDP_SESSION_LEVEL) {
708 0 : conn_p = &(sdp_p->default_conn);
709 : } else {
710 0 : mca_p = sdp_find_media_level(sdp_p, level);
711 0 : if (mca_p != NULL) {
712 0 : conn_p = &(mca_p->conn);
713 : } else {
714 0 : return (FALSE);
715 : }
716 : }
717 :
718 0 : if ((conn_p) && (conn_p->is_multicast)) {
719 0 : return (TRUE);
720 : } else {
721 0 : return (FALSE);
722 : }
723 : }
724 :
725 : /* Function: sdp_get_mcast_ttl
726 : * Description: Get the time to live(ttl) value for the multicast address
727 : * if present.
728 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
729 : * level The level to check for the c= line. Will be
730 : * either SDP_SESSION_LEVEL or 1-n specifying a
731 : * media line level.
732 : * Returns: Multicast address - Time to live (ttl) value
733 : */
734 :
735 0 : int32_t sdp_get_mcast_ttl (sdp_t *sdp_p, uint16_t level)
736 : {
737 : sdp_conn_t *conn_p;
738 : sdp_mca_t *mca_p;
739 0 : uint16_t ttl=0;
740 :
741 0 : if (level == SDP_SESSION_LEVEL) {
742 0 : conn_p = &(sdp_p->default_conn);
743 : } else {
744 0 : mca_p = sdp_find_media_level(sdp_p, level);
745 0 : if (mca_p != NULL) {
746 0 : conn_p = &(mca_p->conn);
747 : } else {
748 0 : return SDP_INVALID_VALUE;
749 : }
750 : }
751 :
752 0 : if (conn_p) {
753 0 : ttl = conn_p->ttl;
754 : }
755 0 : return ttl;
756 : }
757 :
758 : /* Function: sdp_get_mcast_num_of_addresses
759 : * Description: Get the number of addresses value for the multicast address
760 : * if present.
761 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
762 : * level The level to check for the c= line. Will be
763 : * either SDP_SESSION_LEVEL or 1-n specifying a
764 : * media line level.
765 : * Returns: Multicast address - number of addresses value
766 : */
767 :
768 0 : int32_t sdp_get_mcast_num_of_addresses (sdp_t *sdp_p, uint16_t level)
769 : {
770 : sdp_conn_t *conn_p;
771 : sdp_mca_t *mca_p;
772 0 : uint16_t num_addr = 0;
773 :
774 0 : if (level == SDP_SESSION_LEVEL) {
775 0 : conn_p = &(sdp_p->default_conn);
776 : } else {
777 0 : mca_p = sdp_find_media_level(sdp_p, level);
778 0 : if (mca_p != NULL) {
779 0 : conn_p = &(mca_p->conn);
780 : } else {
781 0 : return (SDP_INVALID_VALUE);
782 : }
783 : }
784 :
785 0 : if (conn_p) {
786 0 : num_addr = conn_p->num_of_addresses;
787 : }
788 0 : return num_addr;
789 : }
790 : /* Function: sdp_set_conn_nettype
791 : * Description: Sets the value of the network type parameter for the c=
792 : * connection token line.
793 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
794 : * nettype Network type for the connection line.
795 : * level The level to check for the c= line. Will be
796 : * either SDP_SESSION_LEVEL or 1-n specifying a
797 : * media line level.
798 : * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER
799 : */
800 0 : sdp_result_e sdp_set_conn_nettype (sdp_t *sdp_p, uint16_t level,
801 : sdp_nettype_e nettype)
802 : {
803 : sdp_conn_t *conn_p;
804 : sdp_mca_t *mca_p;
805 :
806 0 : if (level == SDP_SESSION_LEVEL) {
807 0 : conn_p = &(sdp_p->default_conn);
808 : } else {
809 0 : mca_p = sdp_find_media_level(sdp_p, level);
810 0 : if (mca_p == NULL) {
811 0 : sdp_p->conf_p->num_invalid_param++;
812 0 : return (SDP_INVALID_PARAMETER);
813 : }
814 0 : conn_p = &(mca_p->conn);
815 : }
816 :
817 0 : conn_p->nettype = nettype;
818 0 : return (SDP_SUCCESS);
819 : }
820 :
821 : /* Function: sdp_set_conn_addrtype
822 : * Description: Sets the value of the address type parameter for the c=
823 : * connection token line.
824 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
825 : * addrtype Address type for the connection line.
826 : * level The level to check for the c= line. Will be
827 : * either SDP_SESSION_LEVEL or 1-n specifying a
828 : * media line level.
829 : * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER
830 : */
831 0 : sdp_result_e sdp_set_conn_addrtype (sdp_t *sdp_p, uint16_t level,
832 : sdp_addrtype_e addrtype)
833 : {
834 : sdp_conn_t *conn_p;
835 : sdp_mca_t *mca_p;
836 :
837 0 : if (level == SDP_SESSION_LEVEL) {
838 0 : conn_p = &(sdp_p->default_conn);
839 : } else {
840 0 : mca_p = sdp_find_media_level(sdp_p, level);
841 0 : if (mca_p == NULL) {
842 0 : sdp_p->conf_p->num_invalid_param++;
843 0 : return (SDP_INVALID_PARAMETER);
844 : }
845 0 : conn_p = &(mca_p->conn);
846 : }
847 :
848 0 : conn_p->addrtype = addrtype;
849 0 : return (SDP_SUCCESS);
850 : }
851 :
852 : /* Function: sdp_set_conn_address
853 : * Description: Sets the value of the address parameter for the c=
854 : * connection token line. The string is copied into the
855 : * SDP structure so application memory will not be
856 : * referenced by the SDP lib.
857 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
858 : * level The level to check for the c= line. Will be
859 : * either SDP_SESSION_LEVEL or 1-n specifying a
860 : * media line level.
861 : * address Ptr to the address string.
862 : * Returns: SDP_SUCCESS
863 : */
864 0 : sdp_result_e sdp_set_conn_address (sdp_t *sdp_p, uint16_t level,
865 : const char *address)
866 : {
867 : sdp_conn_t *conn_p;
868 : sdp_mca_t *mca_p;
869 :
870 0 : if (level == SDP_SESSION_LEVEL) {
871 0 : conn_p = &(sdp_p->default_conn);
872 : } else {
873 0 : mca_p = sdp_find_media_level(sdp_p, level);
874 0 : if (mca_p == NULL) {
875 0 : sdp_p->conf_p->num_invalid_param++;
876 0 : return (SDP_INVALID_PARAMETER);
877 : }
878 0 : conn_p = &(mca_p->conn);
879 : }
880 :
881 0 : sstrncpy(conn_p->conn_addr, address, sizeof(conn_p->conn_addr));
882 0 : return (SDP_SUCCESS);
883 : }
884 :
885 : /* Function: sdp_media_line_valid
886 : * Description: Returns true or false depending on whether the specified
887 : * media line m= has been defined for this SDP. The
888 : * SDP_SESSION_LEVEL level is not valid for this check since,
889 : * by definition, this is a media level.
890 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
891 : * level The level to check for the c= line. Will be
892 : * 1-n specifying a media line level.
893 : * Returns: TRUE or FALSE.
894 : */
895 0 : tinybool sdp_media_line_valid (sdp_t *sdp_p, uint16_t level)
896 : {
897 : sdp_mca_t *mca_p;
898 :
899 0 : mca_p = sdp_find_media_level(sdp_p, level);
900 0 : if (mca_p == NULL) {
901 0 : return (FALSE);
902 : }
903 :
904 : /* Validate params for this media line */
905 0 : if ((mca_p->media >= SDP_MAX_MEDIA_TYPES) ||
906 0 : (mca_p->port_format >= SDP_MAX_PORT_FORMAT_TYPES) ||
907 0 : (mca_p->transport >= SDP_MAX_TRANSPORT_TYPES) ||
908 0 : (mca_p->num_payloads == 0)) {
909 0 : return (FALSE);
910 : } else {
911 0 : return (TRUE);
912 : }
913 : }
914 :
915 : /* Function: sdp_get_num_media_lines
916 : * Description: Returns the number of media lines associated with the SDP.
917 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
918 : * Returns: Number of media lines.
919 : */
920 0 : uint16_t sdp_get_num_media_lines (sdp_t *sdp_p)
921 : {
922 0 : return (sdp_p->mca_count);
923 : }
924 :
925 : /* Function: sdp_get_media_type
926 : * Description: Returns the media type parameter from the m=
927 : * media token line. If media type has not been
928 : * set SDP_MEDIA_INVALID will be returned.
929 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
930 : * level The level to of the m= media line. Will be 1-n.
931 : * Returns: Media type or SDP_MEDIA_INVALID.
932 : */
933 0 : sdp_media_e sdp_get_media_type (sdp_t *sdp_p, uint16_t level)
934 : {
935 : sdp_mca_t *mca_p;
936 :
937 0 : mca_p = sdp_find_media_level(sdp_p, level);
938 0 : if (mca_p == NULL) {
939 0 : return (SDP_MEDIA_INVALID);
940 : }
941 :
942 0 : return (mca_p->media);
943 : }
944 :
945 : /* Function: sdp_get_media_line_number
946 : * Description: Returns the line number in the SDP the media
947 : * section starts on. Only set if SDP has been parsed
948 : * (rather than built).
949 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
950 : * level The level to of the m= media line. Will be 1-n.
951 : * Returns: Line number (0 if not found or if locally built)
952 : */
953 0 : uint32_t sdp_get_media_line_number (sdp_t *sdp_p, uint16_t level)
954 : {
955 : sdp_mca_t *mca_p;
956 :
957 0 : mca_p = sdp_find_media_level(sdp_p, level);
958 0 : if (mca_p == NULL) {
959 0 : return 0;
960 : }
961 :
962 0 : return (mca_p->line_number);
963 : }
964 :
965 : /* Function: sdp_get_media_port_format
966 : * Description: Returns the port format type associated with the m=
967 : * media token line. If port format type has not been
968 : * set SDP_PORT_FORMAT_INVALID will be returned.
969 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
970 : * level The level to of the m= media line. Will be 1-n.
971 : * Returns: Port format type or SDP_PORT_FORMAT_INVALID.
972 : */
973 0 : sdp_port_format_e sdp_get_media_port_format (sdp_t *sdp_p, uint16_t level)
974 : {
975 : sdp_mca_t *mca_p;
976 :
977 0 : mca_p = sdp_find_media_level(sdp_p, level);
978 0 : if (mca_p == NULL) {
979 0 : return (SDP_PORT_FORMAT_INVALID);
980 : }
981 :
982 0 : return (mca_p->port_format);
983 : }
984 :
985 : /* Function: sdp_get_media_portnum
986 : * Description: Returns the port number associated with the m=
987 : * media token line. If port number has not been
988 : * set SDP_INVALID_VALUE will be returned.
989 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
990 : * level The level to of the m= media line. Will be 1-n.
991 : * Returns: Port number or SDP_INVALID_VALUE.
992 : */
993 0 : int32_t sdp_get_media_portnum (sdp_t *sdp_p, uint16_t level)
994 : {
995 : sdp_mca_t *mca_p;
996 :
997 0 : mca_p = sdp_find_media_level(sdp_p, level);
998 0 : if (mca_p == NULL) {
999 0 : return (SDP_INVALID_VALUE);
1000 : }
1001 :
1002 : /* Make sure port number is valid for the specified format. */
1003 0 : if ((mca_p->port_format != SDP_PORT_NUM_ONLY) &&
1004 0 : (mca_p->port_format != SDP_PORT_NUM_COUNT) &&
1005 0 : (mca_p->port_format != SDP_PORT_NUM_VPI_VCI) &&
1006 0 : (mca_p->port_format != SDP_PORT_NUM_VPI_VCI_CID)) {
1007 0 : if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
1008 0 : CSFLogError(logTag, "%s Port num not valid for media line %u",
1009 : sdp_p->debug_str, (unsigned)level);
1010 : }
1011 0 : sdp_p->conf_p->num_invalid_param++;
1012 0 : return (SDP_INVALID_VALUE);
1013 : }
1014 :
1015 0 : return (mca_p->port);
1016 : }
1017 :
1018 : /* Function: sdp_get_media_portcount
1019 : * Description: Returns the port count associated with the m=
1020 : * media token line. If port count has not been
1021 : * set SDP_INVALID_VALUE will be returned.
1022 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1023 : * level The level to of the m= media line. Will be 1-n.
1024 : * Returns: Port count or SDP_INVALID_VALUE.
1025 : */
1026 0 : int32_t sdp_get_media_portcount (sdp_t *sdp_p, uint16_t level)
1027 : {
1028 : sdp_mca_t *mca_p;
1029 :
1030 0 : mca_p = sdp_find_media_level(sdp_p, level);
1031 0 : if (mca_p == NULL) {
1032 0 : return (SDP_INVALID_VALUE);
1033 : }
1034 :
1035 : /* Make sure port number is valid for the specified format. */
1036 0 : if (mca_p->port_format != SDP_PORT_NUM_COUNT) {
1037 0 : if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
1038 0 : CSFLogError(logTag, "%s Port count not valid for media line %u",
1039 : sdp_p->debug_str, (unsigned)level);
1040 : }
1041 0 : sdp_p->conf_p->num_invalid_param++;
1042 0 : return (SDP_INVALID_VALUE);
1043 : }
1044 :
1045 0 : return (mca_p->num_ports);
1046 : }
1047 :
1048 : /* Function: sdp_get_media_vpi
1049 : * Description: Returns the VPI parameter associated with the m=
1050 : * media token line. If VPI has not been set
1051 : * SDP_INVALID_VALUE will be returned.
1052 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1053 : * level The level to of the m= media line. Will be 1-n.
1054 : * Returns: VPI or SDP_INVALID_VALUE.
1055 : */
1056 0 : int32_t sdp_get_media_vpi (sdp_t *sdp_p, uint16_t level)
1057 : {
1058 : sdp_mca_t *mca_p;
1059 :
1060 0 : mca_p = sdp_find_media_level(sdp_p, level);
1061 0 : if (mca_p == NULL) {
1062 0 : return (SDP_INVALID_VALUE);
1063 : }
1064 :
1065 : /* Make sure port number is valid for the specified format. */
1066 0 : if ((mca_p->port_format != SDP_PORT_VPI_VCI) &&
1067 0 : (mca_p->port_format != SDP_PORT_NUM_VPI_VCI) &&
1068 0 : (mca_p->port_format != SDP_PORT_NUM_VPI_VCI_CID)) {
1069 0 : if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
1070 0 : CSFLogError(logTag, "%s VPI not valid for media line %u",
1071 : sdp_p->debug_str, (unsigned)level);
1072 : }
1073 0 : sdp_p->conf_p->num_invalid_param++;
1074 0 : return (SDP_INVALID_VALUE);
1075 : }
1076 :
1077 0 : return (mca_p->vpi);
1078 : }
1079 :
1080 : /* Function: sdp_get_media_vci
1081 : * Description: Returns the VCI parameter associated with the m=
1082 : * media token line. If VCI has not been set
1083 : * SDP_INVALID_VALUE will be returned.
1084 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1085 : * level The level to of the m= media line. Will be 1-n.
1086 : * Returns: VCI or zero.
1087 : */
1088 0 : uint32_t sdp_get_media_vci (sdp_t *sdp_p, uint16_t level)
1089 : {
1090 : sdp_mca_t *mca_p;
1091 :
1092 0 : mca_p = sdp_find_media_level(sdp_p, level);
1093 0 : if (mca_p == NULL) {
1094 0 : return (0);
1095 : }
1096 :
1097 : /* Make sure port number is valid for the specified format. */
1098 0 : if ((mca_p->port_format != SDP_PORT_VPI_VCI) &&
1099 0 : (mca_p->port_format != SDP_PORT_NUM_VPI_VCI) &&
1100 0 : (mca_p->port_format != SDP_PORT_NUM_VPI_VCI_CID)) {
1101 0 : if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
1102 0 : CSFLogError(logTag, "%s VCI not valid for media line %u",
1103 : sdp_p->debug_str, (unsigned)level);
1104 : }
1105 0 : sdp_p->conf_p->num_invalid_param++;
1106 0 : return (0);
1107 : }
1108 :
1109 0 : return (mca_p->vci);
1110 : }
1111 :
1112 : /* Function: sdp_get_media_vcci
1113 : * Description: Returns the VCCI parameter associated with the m=
1114 : * media token line. If VCCI has not been set
1115 : * SDP_INVALID_VALUE will be returned.
1116 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1117 : * level The level to of the m= media line. Will be 1-n.
1118 : * Returns: VCCI or SDP_INVALID_VALUE.
1119 : */
1120 0 : int32_t sdp_get_media_vcci (sdp_t *sdp_p, uint16_t level)
1121 : {
1122 : sdp_mca_t *mca_p;
1123 :
1124 0 : mca_p = sdp_find_media_level(sdp_p, level);
1125 0 : if (mca_p == NULL) {
1126 0 : return (SDP_INVALID_VALUE);
1127 : }
1128 :
1129 : /* Make sure port number is valid for the specified format. */
1130 0 : if ((mca_p->port_format != SDP_PORT_VCCI) &&
1131 0 : (mca_p->port_format != SDP_PORT_VCCI_CID)) {
1132 0 : if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
1133 0 : CSFLogError(logTag, "%s VCCI not valid for media line %u",
1134 : sdp_p->debug_str, (unsigned)level);
1135 : }
1136 0 : sdp_p->conf_p->num_invalid_param++;
1137 0 : return (SDP_INVALID_VALUE);
1138 : }
1139 :
1140 0 : return (mca_p->vcci);
1141 : }
1142 :
1143 : /* Function: sdp_get_media_cid
1144 : * Description: Returns the CID parameter associated with the m=
1145 : * media token line. If CID has not been set
1146 : * SDP_INVALID_VALUE will be returned.
1147 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1148 : * level The level to of the m= media line. Will be 1-n.
1149 : * Returns: CID or SDP_INVALID_VALUE.
1150 : */
1151 0 : int32_t sdp_get_media_cid (sdp_t *sdp_p, uint16_t level)
1152 : {
1153 : sdp_mca_t *mca_p;
1154 :
1155 0 : mca_p = sdp_find_media_level(sdp_p, level);
1156 0 : if (mca_p == NULL) {
1157 0 : return (SDP_INVALID_VALUE);
1158 : }
1159 :
1160 : /* Make sure port number is valid for the specified format. */
1161 0 : if ((mca_p->port_format != SDP_PORT_VCCI_CID) &&
1162 0 : (mca_p->port_format != SDP_PORT_NUM_VPI_VCI_CID)) {
1163 0 : if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
1164 0 : CSFLogError(logTag, "%s CID not valid for media line %u",
1165 : sdp_p->debug_str, (unsigned)level);
1166 : }
1167 0 : sdp_p->conf_p->num_invalid_param++;
1168 0 : return (SDP_INVALID_VALUE);
1169 : }
1170 :
1171 0 : return (mca_p->cid);
1172 : }
1173 :
1174 : /* Function: sdp_get_media_transport
1175 : * Description: Returns the transport type parameter associated with the m=
1176 : * media token line. If transport type has not been set
1177 : * SDP_TRANSPORT_INVALID will be returned. If the transport
1178 : * type is one of the AAL2 variants, the profile routines below
1179 : * should be used to access multiple profile types and payload
1180 : * lists per m= line.
1181 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1182 : * level The level to of the m= media line. Will be 1-n.
1183 : * Returns: CID or SDP_TRANSPORT_INVALID.
1184 : */
1185 0 : sdp_transport_e sdp_get_media_transport (sdp_t *sdp_p, uint16_t level)
1186 : {
1187 : sdp_mca_t *mca_p;
1188 :
1189 0 : mca_p = sdp_find_media_level(sdp_p, level);
1190 0 : if (mca_p == NULL) {
1191 0 : return (SDP_TRANSPORT_INVALID);
1192 : }
1193 :
1194 0 : return (mca_p->transport);
1195 : }
1196 :
1197 : /* Function: sdp_get_media_num_profiles
1198 : * Description: Returns the number of profiles associated with the m=
1199 : * media token line. If the media line is invalid, zero will
1200 : * be returned. Application must validate the media line
1201 : * before using this routine. Multiple profile types per
1202 : * media line is currently only used for AAL2. If the appl
1203 : * detects that the transport type is one of the AAL2 types,
1204 : * it should use these profile access routines to access the
1205 : * profile types and payload list for each.
1206 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1207 : * level The level to of the m= media line. Will be 1-n.
1208 : * Returns: Number of profiles or zero.
1209 : */
1210 0 : uint16_t sdp_get_media_num_profiles (sdp_t *sdp_p, uint16_t level)
1211 : {
1212 : sdp_mca_t *mca_p;
1213 :
1214 0 : mca_p = sdp_find_media_level(sdp_p, level);
1215 0 : if (mca_p == NULL) {
1216 0 : return (0);
1217 : }
1218 :
1219 0 : if (mca_p->media_profiles_p == NULL) {
1220 0 : return (0);
1221 : } else {
1222 0 : return (mca_p->media_profiles_p->num_profiles);
1223 : }
1224 : }
1225 :
1226 : /* Function: sdp_get_media_profile
1227 : * Description: Returns the specified profile type associated with the m=
1228 : * media token line. If the media line or profile number is
1229 : * invalid, SDP_TRANSPORT_INVALID will be returned.
1230 : * Applications must validate the media line before using this
1231 : * routine.
1232 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1233 : * level The level to of the m= media line. Will be 1-n.
1234 : * profile_num The specific profile type number to be retrieved.
1235 : * Returns: The profile type or SDP_TRANSPORT_INVALID.
1236 : */
1237 0 : sdp_transport_e sdp_get_media_profile (sdp_t *sdp_p, uint16_t level,
1238 : uint16_t profile_num)
1239 : {
1240 : sdp_mca_t *mca_p;
1241 :
1242 0 : mca_p = sdp_find_media_level(sdp_p, level);
1243 0 : if (mca_p == NULL) {
1244 0 : return (SDP_TRANSPORT_INVALID);
1245 : }
1246 :
1247 0 : if ((profile_num < 1) ||
1248 0 : (profile_num > mca_p->media_profiles_p->num_profiles)) {
1249 0 : return (SDP_TRANSPORT_INVALID);
1250 : } else {
1251 0 : return (mca_p->media_profiles_p->profile[profile_num-1]);
1252 : }
1253 : }
1254 :
1255 : /* Function: sdp_get_media_num_payload_types
1256 : * Description: Returns the number of payload types associated with the m=
1257 : * media token line. If the media line is invalid, zero will
1258 : * be returned. Application must validate the media line
1259 : * before using this routine.
1260 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1261 : * level The level to of the m= media line. Will be 1-n.
1262 : * Returns: Number of payload types or zero.
1263 : */
1264 0 : uint16_t sdp_get_media_num_payload_types (sdp_t *sdp_p, uint16_t level)
1265 : {
1266 : sdp_mca_t *mca_p;
1267 :
1268 0 : mca_p = sdp_find_media_level(sdp_p, level);
1269 0 : if (mca_p == NULL) {
1270 0 : return (0);
1271 : }
1272 :
1273 0 : return (mca_p->num_payloads);
1274 : }
1275 :
1276 : /* Function: sdp_get_media_profile_num_payload_types
1277 : * Description: Returns the number of payload types associated with the
1278 : * specified profile on the m= media token line. If the
1279 : * media line or profile number is invalid, zero will
1280 : * be returned. Application must validate the media line
1281 : * and profile before using this routine.
1282 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1283 : * level The level to of the m= media line. Will be 1-n.
1284 : * profile_num The specific profile number. Will be 1-n.
1285 : * Returns: Number of payload types or zero.
1286 : */
1287 0 : uint16_t sdp_get_media_profile_num_payload_types (sdp_t *sdp_p, uint16_t level,
1288 : uint16_t profile_num)
1289 : {
1290 : sdp_mca_t *mca_p;
1291 :
1292 0 : mca_p = sdp_find_media_level(sdp_p, level);
1293 0 : if (mca_p == NULL) {
1294 0 : return (0);
1295 : }
1296 :
1297 0 : if ((profile_num < 1) ||
1298 0 : (profile_num > mca_p->media_profiles_p->num_profiles)) {
1299 0 : return (0);
1300 : } else {
1301 0 : return (mca_p->media_profiles_p->num_payloads[profile_num-1]);
1302 : }
1303 : }
1304 :
1305 0 : rtp_ptype sdp_get_known_payload_type(sdp_t *sdp_p,
1306 : uint16_t level,
1307 : uint16_t payload_type_raw) {
1308 : sdp_attr_t *attr_p;
1309 : sdp_transport_map_t *rtpmap;
1310 0 : uint16_t pack_mode = 0; /*default 0, if remote did not provide any */
1311 0 : const char *encname = NULL;
1312 0 : uint16_t num_a_lines = 0;
1313 : int i;
1314 :
1315 : /*
1316 : * Get number of RTPMAP attributes for the media line
1317 : */
1318 0 : (void) sdp_attr_num_instances(sdp_p, level, 0, SDP_ATTR_RTPMAP,
1319 : &num_a_lines);
1320 :
1321 : /*
1322 : * Loop through media line RTPMAP attributes.
1323 : */
1324 0 : for (i = 0; i < num_a_lines; i++) {
1325 0 : attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_RTPMAP, (i + 1));
1326 0 : if (attr_p == NULL) {
1327 0 : if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
1328 0 : CSFLogError(logTag, "%s rtpmap attribute, level %u instance %u "
1329 : "not found.",
1330 : sdp_p->debug_str,
1331 : (unsigned)level,
1332 : (unsigned)(i + 1));
1333 : }
1334 0 : sdp_p->conf_p->num_invalid_param++;
1335 0 : return (RTP_NONE);
1336 : }
1337 :
1338 0 : rtpmap = &(attr_p->attr.transport_map);
1339 :
1340 0 : if (rtpmap->payload_num == payload_type_raw) {
1341 0 : encname = rtpmap->encname;
1342 0 : if (encname) {
1343 0 : if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_ILBC) == 0) {
1344 0 : return (RTP_ILBC);
1345 : }
1346 0 : if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_L16_256K) == 0) {
1347 0 : return (RTP_L16);
1348 : }
1349 0 : if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_ISAC) == 0) {
1350 0 : return (RTP_ISAC);
1351 : }
1352 0 : if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_OPUS) == 0) {
1353 0 : return (RTP_OPUS);
1354 : }
1355 0 : if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_PCMU) == 0) {
1356 0 : return (RTP_PCMU);
1357 : }
1358 0 : if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_PCMA) == 0) {
1359 0 : return (RTP_PCMA);
1360 : }
1361 0 : if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_G722) == 0) {
1362 0 : return (RTP_G722);
1363 : }
1364 0 : if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_H264) == 0) {
1365 0 : int fmtp_inst = sdp_find_fmtp_inst(sdp_p, level, rtpmap->payload_num);
1366 0 : if (fmtp_inst < 0) {
1367 0 : return (RTP_H264_P0);
1368 : } else {
1369 0 : sdp_attr_get_fmtp_pack_mode(sdp_p, level, 0, (uint16_t) fmtp_inst, &pack_mode);
1370 0 : if (pack_mode == SDP_DEFAULT_PACKETIZATION_MODE_VALUE) {
1371 0 : return (RTP_H264_P0);
1372 : } else {
1373 0 : return (RTP_H264_P1);
1374 : }
1375 : }
1376 : }
1377 0 : if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_VP8) == 0) {
1378 0 : return (RTP_VP8);
1379 : }
1380 0 : if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_VP9) == 0) {
1381 0 : return (RTP_VP9);
1382 : }
1383 0 : if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_RED) == 0) {
1384 0 : return (RTP_RED);
1385 : }
1386 0 : if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_ULPFEC) == 0) {
1387 0 : return (RTP_ULPFEC);
1388 : }
1389 0 : if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_TELEPHONE_EVENT) == 0) {
1390 0 : return (RTP_TELEPHONE_EVENT);
1391 : }
1392 : }
1393 : }
1394 : }
1395 :
1396 0 : return (RTP_NONE);
1397 : }
1398 :
1399 : /* Function: sdp_get_media_payload_type
1400 : * Description: Returns the payload type of the specified payload for the m=
1401 : * media token line. If the media line or payload number is
1402 : * invalid, zero will be returned. Application must validate
1403 : * the media line before using this routine.
1404 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1405 : * level The level to of the m= media line. Will be 1-n.
1406 : * payload_num Number of the payload type to retrieve. The
1407 : * range is (1 - max num payloads).
1408 : * indicator Returns the type of payload returned, either
1409 : * NUMERIC or ENUM.
1410 : * Returns: Payload type or zero.
1411 : */
1412 0 : uint32_t sdp_get_media_payload_type (sdp_t *sdp_p, uint16_t level, uint16_t payload_num,
1413 : sdp_payload_ind_e *indicator)
1414 : {
1415 : sdp_mca_t *mca_p;
1416 : rtp_ptype ptype;
1417 :
1418 0 : mca_p = sdp_find_media_level(sdp_p, level);
1419 0 : if (mca_p == NULL) {
1420 0 : return (0);
1421 : }
1422 :
1423 0 : if ((payload_num < 1) || (payload_num > mca_p->num_payloads)) {
1424 0 : return (0);
1425 : }
1426 :
1427 0 : *indicator = mca_p->payload_indicator[payload_num-1];
1428 0 : if ((mca_p->payload_type[payload_num-1] >= SDP_MIN_DYNAMIC_PAYLOAD) &&
1429 0 : (mca_p->payload_type[payload_num-1] <= SDP_MAX_DYNAMIC_PAYLOAD)) {
1430 0 : ptype = sdp_get_known_payload_type(sdp_p,
1431 : level,
1432 0 : mca_p->payload_type[payload_num-1]);
1433 0 : if (ptype != RTP_NONE) {
1434 0 : return (SET_PAYLOAD_TYPE_WITH_DYNAMIC(
1435 : mca_p->payload_type[payload_num-1], ptype));
1436 : }
1437 :
1438 : }
1439 0 : return (mca_p->payload_type[payload_num-1]);
1440 : }
1441 :
1442 : /* Function: sdp_get_media_profile_payload_type
1443 : * Description: Returns the payload type of the specified payload for the m=
1444 : * media token line. If the media line or payload number is
1445 : * invalid, zero will be returned. Application must validate
1446 : * the media line before using this routine.
1447 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1448 : * level The level to of the m= media line. Will be 1-n.
1449 : * payload_num Number of the payload type to retrieve. The
1450 : * range is (1 - max num payloads).
1451 : * indicator Returns the type of payload returned, either
1452 : * NUMERIC or ENUM.
1453 : * Returns: Payload type or zero.
1454 : */
1455 0 : uint32_t sdp_get_media_profile_payload_type (sdp_t *sdp_p, uint16_t level, uint16_t prof_num,
1456 : uint16_t payload_num,
1457 : sdp_payload_ind_e *indicator)
1458 : {
1459 : sdp_mca_t *mca_p;
1460 : sdp_media_profiles_t *prof_p;
1461 :
1462 0 : mca_p = sdp_find_media_level(sdp_p, level);
1463 0 : if (mca_p == NULL) {
1464 0 : return (0);
1465 : }
1466 :
1467 0 : prof_p = mca_p->media_profiles_p;
1468 0 : if ((prof_num < 1) ||
1469 0 : (prof_num > prof_p->num_profiles)) {
1470 0 : return (0);
1471 : }
1472 :
1473 0 : if ((payload_num < 1) ||
1474 0 : (payload_num > prof_p->num_payloads[prof_num-1])) {
1475 0 : return (0);
1476 : }
1477 :
1478 0 : *indicator = prof_p->payload_indicator[prof_num-1][payload_num-1];
1479 0 : return (prof_p->payload_type[prof_num-1][payload_num-1]);
1480 : }
1481 :
1482 : /* Function: sdp_insert_media_line
1483 : * Description: Insert a new media line at the level specified for the
1484 : * given SDP.
1485 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1486 : * level The new media level to insert. Will be 1-n.
1487 : * Returns: SDP_SUCCESS, SDP_NO_RESOURCE, or SDP_INVALID_PARAMETER
1488 : */
1489 0 : sdp_result_e sdp_insert_media_line (sdp_t *sdp_p, uint16_t level)
1490 : {
1491 : sdp_mca_t *mca_p;
1492 : sdp_mca_t *new_mca_p;
1493 :
1494 0 : if ((level < 1) || (level > (sdp_p->mca_count+1))) {
1495 0 : if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
1496 0 : CSFLogError(logTag, "%s Invalid media line (%u) to insert, max is "
1497 : "(%u).", sdp_p->debug_str, (unsigned)level, (unsigned)sdp_p->mca_count);
1498 : }
1499 0 : sdp_p->conf_p->num_invalid_param++;
1500 0 : return (SDP_INVALID_PARAMETER);
1501 : }
1502 :
1503 : /* Allocate resource for new media stream. */
1504 0 : new_mca_p = sdp_alloc_mca(0);
1505 0 : if (new_mca_p == NULL) {
1506 0 : sdp_p->conf_p->num_no_resource++;
1507 0 : return (SDP_NO_RESOURCE);
1508 : }
1509 :
1510 0 : if (level == 1) {
1511 : /* We're inserting the first media line */
1512 0 : new_mca_p->next_p = sdp_p->mca_p;
1513 0 : sdp_p->mca_p = new_mca_p;
1514 : } else {
1515 : /* Find the pointer to the media stream just prior to where
1516 : * we want to insert the new stream.
1517 : */
1518 0 : mca_p = sdp_find_media_level(sdp_p, (uint16_t)(level-1));
1519 0 : if (mca_p == NULL) {
1520 0 : SDP_FREE(new_mca_p);
1521 0 : sdp_p->conf_p->num_invalid_param++;
1522 0 : return (SDP_INVALID_PARAMETER);
1523 : }
1524 :
1525 0 : new_mca_p->next_p = mca_p->next_p;
1526 0 : mca_p->next_p = new_mca_p;
1527 : }
1528 :
1529 0 : sdp_p->mca_count++;
1530 0 : return (SDP_SUCCESS);
1531 : }
1532 :
1533 : /* Function: sdp_set_media_type
1534 : * Description: Sets the value of the media type parameter for the m=
1535 : * media token line.
1536 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1537 : * level The media level to set the param. Will be 1-n.
1538 : * media Media type for the media line.
1539 : * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER
1540 : */
1541 0 : sdp_result_e sdp_set_media_type (sdp_t *sdp_p, uint16_t level, sdp_media_e media)
1542 : {
1543 : sdp_mca_t *mca_p;
1544 :
1545 0 : mca_p = sdp_find_media_level(sdp_p, level);
1546 0 : if (mca_p == NULL) {
1547 0 : sdp_p->conf_p->num_invalid_param++;
1548 0 : return (SDP_INVALID_PARAMETER);
1549 : }
1550 :
1551 0 : mca_p->media = media;
1552 0 : return (SDP_SUCCESS);
1553 : }
1554 :
1555 : /* Function: sdp_set_media_portnum
1556 : * Description: Sets the value of the port number parameter for the m=
1557 : * media token line. If the port number is not valid with the
1558 : * port format specified for the media line, this call will
1559 : * fail.
1560 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1561 : * level The media level to set the param. Will be 1-n.
1562 : * portnum Port number to set.
1563 : * sctpport sctp port for application m= line
1564 : * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER
1565 : */
1566 0 : sdp_result_e sdp_set_media_portnum (sdp_t *sdp_p, uint16_t level, int32_t portnum, int32_t sctp_port)
1567 : {
1568 : sdp_mca_t *mca_p;
1569 :
1570 0 : mca_p = sdp_find_media_level(sdp_p, level);
1571 0 : if (mca_p == NULL) {
1572 0 : sdp_p->conf_p->num_invalid_param++;
1573 0 : return (SDP_INVALID_PARAMETER);
1574 : }
1575 :
1576 0 : mca_p->port = portnum;
1577 0 : mca_p->sctpport = sctp_port;
1578 0 : return (SDP_SUCCESS);
1579 : }
1580 :
1581 : /* Function: sdp_get_media_sctp_port
1582 : * Description: Gets the value of the sctp port number parameter for the m=
1583 : * media token line.
1584 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1585 : * level The media level to set the param. Will be 1-n.
1586 : * Returns: sctp_port or -1 on failure
1587 : */
1588 0 : int32_t sdp_get_media_sctp_port(sdp_t *sdp_p, uint16_t level)
1589 : {
1590 : sdp_mca_t *mca_p;
1591 :
1592 0 : mca_p = sdp_find_media_level(sdp_p, level);
1593 0 : if (!mca_p) {
1594 0 : sdp_p->conf_p->num_invalid_param++;
1595 0 : return -1;
1596 : }
1597 :
1598 0 : return mca_p->sctpport;
1599 : }
1600 :
1601 0 : sdp_sctp_media_fmt_type_e sdp_get_media_sctp_fmt(sdp_t *sdp_p, uint16_t level)
1602 : {
1603 : sdp_mca_t *mca_p;
1604 :
1605 0 : mca_p = sdp_find_media_level(sdp_p, level);
1606 0 : if (!mca_p) {
1607 0 : sdp_p->conf_p->num_invalid_param++;
1608 0 : return -1;
1609 : }
1610 :
1611 0 : return mca_p->sctp_fmt;
1612 : }
1613 :
1614 : /* Function: sdp_set_media_transport
1615 : * Description: Sets the value of the transport type parameter for the m=
1616 : * media token line.
1617 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1618 : * level The media level to set the param. Will be 1-n.
1619 : * transport The transport type to set.
1620 : * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER
1621 : */
1622 0 : sdp_result_e sdp_set_media_transport (sdp_t *sdp_p, uint16_t level,
1623 : sdp_transport_e transport)
1624 : {
1625 : sdp_mca_t *mca_p;
1626 :
1627 0 : mca_p = sdp_find_media_level(sdp_p, level);
1628 0 : if (mca_p == NULL) {
1629 0 : sdp_p->conf_p->num_invalid_param++;
1630 0 : return (SDP_INVALID_PARAMETER);
1631 : }
1632 :
1633 0 : mca_p->transport = transport;
1634 0 : return (SDP_SUCCESS);
1635 : }
1636 :
1637 : /* Function: sdp_add_media_profile
1638 : * Description: Add a new profile type for the m= media token line. This is
1639 : * used for AAL2 transport/profile types where more than one can
1640 : * be specified per media line. All other transport types should
1641 : * use the other transport access routines rather than this.
1642 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1643 : * level The media level to add the param. Will be 1-n.
1644 : * profile The profile type to add.
1645 : * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER
1646 : */
1647 0 : sdp_result_e sdp_add_media_profile (sdp_t *sdp_p, uint16_t level,
1648 : sdp_transport_e profile)
1649 : {
1650 : uint16_t prof_num;
1651 : sdp_mca_t *mca_p;
1652 :
1653 0 : mca_p = sdp_find_media_level(sdp_p, level);
1654 0 : if (mca_p == NULL) {
1655 0 : sdp_p->conf_p->num_invalid_param++;
1656 0 : return (SDP_INVALID_PARAMETER);
1657 : }
1658 :
1659 0 : if (mca_p->media_profiles_p == NULL) {
1660 0 : mca_p->media_profiles_p = (sdp_media_profiles_t *) \
1661 0 : SDP_MALLOC(sizeof(sdp_media_profiles_t));
1662 0 : if (mca_p->media_profiles_p == NULL) {
1663 0 : sdp_p->conf_p->num_no_resource++;
1664 0 : return (SDP_NO_RESOURCE);
1665 : } else {
1666 0 : mca_p->media_profiles_p->num_profiles = 0;
1667 : /* Set the transport type to this first profile type. */
1668 0 : mca_p->transport = profile;
1669 : }
1670 : }
1671 :
1672 0 : if (mca_p->media_profiles_p->num_profiles >= SDP_MAX_PROFILES) {
1673 0 : if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
1674 0 : CSFLogError(logTag, "%s Max number of media profiles already specified"
1675 : " for media level %u", sdp_p->debug_str, (unsigned)level);
1676 : }
1677 0 : sdp_p->conf_p->num_invalid_param++;
1678 0 : return (SDP_INVALID_PARAMETER);
1679 : }
1680 :
1681 0 : prof_num = mca_p->media_profiles_p->num_profiles++;
1682 0 : mca_p->media_profiles_p->profile[prof_num] = profile;
1683 0 : mca_p->media_profiles_p->num_payloads[prof_num] = 0;
1684 0 : return (SDP_SUCCESS);
1685 : }
1686 :
1687 : /* Function: sdp_add_media_payload_type
1688 : * Description: Add a new payload type for the media line at the level
1689 : * specified. The new payload type will be added at the end
1690 : * of the payload type list.
1691 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1692 : * level The media level to add the payload. Will be 1-n.
1693 : * payload_type The new payload type.
1694 : * indicator Defines the type of payload returned, either
1695 : * NUMERIC or ENUM.
1696 : * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER
1697 : */
1698 0 : sdp_result_e sdp_add_media_payload_type (sdp_t *sdp_p, uint16_t level,
1699 : uint16_t payload_type,
1700 : sdp_payload_ind_e indicator)
1701 : {
1702 : sdp_mca_t *mca_p;
1703 :
1704 0 : mca_p = sdp_find_media_level(sdp_p, level);
1705 0 : if (mca_p == NULL) {
1706 0 : sdp_p->conf_p->num_invalid_param++;
1707 0 : return (SDP_INVALID_PARAMETER);
1708 : }
1709 :
1710 0 : if (mca_p->num_payloads == SDP_MAX_PAYLOAD_TYPES) {
1711 0 : if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
1712 0 : CSFLogError(logTag, "%s Max number of payload types already defined "
1713 : "for media line %u", sdp_p->debug_str, (unsigned)level);
1714 : }
1715 0 : sdp_p->conf_p->num_invalid_param++;
1716 0 : return (SDP_INVALID_PARAMETER);
1717 : }
1718 :
1719 0 : mca_p->payload_indicator[mca_p->num_payloads] = indicator;
1720 0 : mca_p->payload_type[mca_p->num_payloads++] = payload_type;
1721 0 : return (SDP_SUCCESS);
1722 : }
1723 :
1724 : /* Function: sdp_add_media_profile_payload_type
1725 : * Description: Add a new payload type for the media line at the level
1726 : * specified. The new payload type will be added at the end
1727 : * of the payload type list.
1728 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1729 : * level The media level to add the payload. Will be 1-n.
1730 : * prof_num The profile number to add the payload type.
1731 : * payload_type The new payload type.
1732 : * indicator Defines the type of payload returned, either
1733 : * NUMERIC or ENUM.
1734 : * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER
1735 : */
1736 0 : sdp_result_e sdp_add_media_profile_payload_type (sdp_t *sdp_p, uint16_t level,
1737 : uint16_t prof_num, uint16_t payload_type,
1738 : sdp_payload_ind_e indicator)
1739 : {
1740 : uint16_t num_payloads;
1741 : sdp_mca_t *mca_p;
1742 :
1743 0 : mca_p = sdp_find_media_level(sdp_p, level);
1744 0 : if (mca_p == NULL) {
1745 0 : sdp_p->conf_p->num_invalid_param++;
1746 0 : return (SDP_INVALID_PARAMETER);
1747 : }
1748 :
1749 0 : if ((prof_num < 1) ||
1750 0 : (prof_num > mca_p->media_profiles_p->num_profiles)) {
1751 0 : if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
1752 0 : CSFLogError(logTag, "%s Invalid profile number (%u) for set profile "
1753 : " payload type", sdp_p->debug_str, (unsigned)level);
1754 : }
1755 0 : sdp_p->conf_p->num_invalid_param++;
1756 0 : return (SDP_INVALID_PARAMETER);
1757 : }
1758 :
1759 0 : if (mca_p->media_profiles_p->num_payloads[prof_num-1] ==
1760 : SDP_MAX_PAYLOAD_TYPES) {
1761 0 : if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
1762 0 : CSFLogError(logTag, "%s Max number of profile payload types already "
1763 : "defined profile %u on media line %u",
1764 : sdp_p->debug_str, (unsigned)prof_num, (unsigned)level);
1765 : }
1766 0 : sdp_p->conf_p->num_invalid_param++;
1767 0 : return (SDP_INVALID_PARAMETER);
1768 : }
1769 :
1770 : /* Get the current num payloads for this profile, and inc the number
1771 : * of payloads at the same time. Then store the new payload type. */
1772 0 : num_payloads = mca_p->media_profiles_p->num_payloads[prof_num-1]++;
1773 0 : mca_p->media_profiles_p->payload_indicator[prof_num-1][num_payloads] =
1774 : indicator;
1775 0 : mca_p->media_profiles_p->payload_type[prof_num-1][num_payloads] =
1776 : payload_type;
1777 0 : return (SDP_SUCCESS);
1778 : }
1779 :
1780 : /*
1781 : * sdp_find_bw_line
1782 : *
1783 : * This helper function locates a specific bw line instance given the
1784 : * sdp, the level and the instance number of the bw line.
1785 : *
1786 : * Returns: Pointer to the sdp_bw_data_t instance, or NULL.
1787 : */
1788 0 : sdp_bw_data_t* sdp_find_bw_line (sdp_t *sdp_p, uint16_t level, uint16_t inst_num)
1789 : {
1790 : sdp_bw_t *bw_p;
1791 : sdp_bw_data_t *bw_data_p;
1792 : sdp_mca_t *mca_p;
1793 0 : int bw_attr_count=0;
1794 :
1795 0 : if (level == SDP_SESSION_LEVEL) {
1796 0 : bw_p = &(sdp_p->bw);
1797 : } else {
1798 0 : mca_p = sdp_find_media_level(sdp_p, level);
1799 0 : if (mca_p == NULL) {
1800 0 : sdp_p->conf_p->num_invalid_param++;
1801 0 : return (NULL);
1802 : }
1803 0 : bw_p = &(mca_p->bw);
1804 : }
1805 :
1806 0 : for (bw_data_p = bw_p->bw_data_list;
1807 : bw_data_p != NULL;
1808 0 : bw_data_p = bw_data_p->next_p) {
1809 0 : bw_attr_count++;
1810 0 : if (bw_attr_count == inst_num) {
1811 0 : return bw_data_p;
1812 : }
1813 : }
1814 :
1815 0 : return NULL;
1816 : }
1817 :
1818 : /*
1819 : * sdp_copy_all_bw_lines
1820 : *
1821 : * Appends all the bw lines from the specified level of the orig sdp to the
1822 : * specified level of the dst sdp.
1823 : *
1824 : * Parameters: src_sdp_p The source SDP handle.
1825 : * dst_sdp_p The dest SDP handle.
1826 : * src_level The level in the src sdp from where to get the
1827 : * attributes.
1828 : * dst_level The level in the dst sdp where to put the
1829 : * attributes.
1830 : * Returns: SDP_SUCCESS Attributes were successfully copied.
1831 : */
1832 0 : sdp_result_e sdp_copy_all_bw_lines (sdp_t *src_sdp_p, sdp_t *dst_sdp_p,
1833 : uint16_t src_level, uint16_t dst_level)
1834 : {
1835 : sdp_bw_data_t *orig_bw_data_p;
1836 : sdp_bw_data_t *new_bw_data_p;
1837 : sdp_bw_data_t *bw_data_p;
1838 : sdp_bw_t *src_bw_p;
1839 : sdp_bw_t *dst_bw_p;
1840 : sdp_mca_t *mca_p;
1841 :
1842 : /* Find src bw list */
1843 0 : if (src_level == SDP_SESSION_LEVEL) {
1844 0 : src_bw_p = &(src_sdp_p->bw);
1845 : } else {
1846 0 : mca_p = sdp_find_media_level(src_sdp_p, src_level);
1847 0 : if (mca_p == NULL) {
1848 0 : if (src_sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
1849 0 : CSFLogError(logTag, "%s Invalid src media level (%u) for copy all "
1850 : "attrs ", src_sdp_p->debug_str, (unsigned)src_level);
1851 : }
1852 0 : return (SDP_INVALID_PARAMETER);
1853 : }
1854 0 : src_bw_p = &(mca_p->bw);
1855 : }
1856 :
1857 : /* Find dst bw list */
1858 0 : if (dst_level == SDP_SESSION_LEVEL) {
1859 0 : dst_bw_p = &(dst_sdp_p->bw);
1860 : } else {
1861 0 : mca_p = sdp_find_media_level(dst_sdp_p, dst_level);
1862 0 : if (mca_p == NULL) {
1863 0 : if (src_sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
1864 0 : CSFLogError(logTag, "%s Invalid dst media level (%u) for copy all "
1865 : "attrs ", src_sdp_p->debug_str, (unsigned)dst_level);
1866 : }
1867 0 : return (SDP_INVALID_PARAMETER);
1868 : }
1869 0 : dst_bw_p = &(mca_p->bw);
1870 : }
1871 :
1872 0 : orig_bw_data_p = src_bw_p->bw_data_list;
1873 0 : while (orig_bw_data_p) {
1874 : /* For ever bw line in the src, allocate a new one for the dst */
1875 0 : new_bw_data_p = (sdp_bw_data_t*)SDP_MALLOC(sizeof(sdp_bw_data_t));
1876 0 : if (new_bw_data_p == NULL) {
1877 0 : return (SDP_NO_RESOURCE);
1878 : }
1879 0 : new_bw_data_p->next_p = NULL;
1880 0 : new_bw_data_p->bw_modifier = orig_bw_data_p->bw_modifier;
1881 0 : new_bw_data_p->bw_val = orig_bw_data_p->bw_val;
1882 :
1883 : /*
1884 : * Enqueue the sdp_bw_data_t instance at the end of the list of
1885 : * sdp_bw_data_t instances.
1886 : */
1887 0 : if (dst_bw_p->bw_data_list == NULL) {
1888 0 : dst_bw_p->bw_data_list = new_bw_data_p;
1889 : } else {
1890 0 : for (bw_data_p = dst_bw_p->bw_data_list;
1891 0 : bw_data_p->next_p != NULL;
1892 0 : bw_data_p = bw_data_p->next_p) {
1893 :
1894 : /*sa_ignore EMPTYLOOP*/
1895 : ; /* Do nothing. */
1896 : }
1897 :
1898 0 : bw_data_p->next_p = new_bw_data_p;
1899 : }
1900 0 : dst_bw_p->bw_data_count++;
1901 :
1902 0 : orig_bw_data_p = orig_bw_data_p->next_p;
1903 : }
1904 :
1905 0 : return (SDP_SUCCESS);
1906 : }
1907 :
1908 : /* Function: sdp_get_bw_modifier
1909 : * Description: Returns the bandwidth modifier parameter from the b=
1910 : * line. If no bw modifier has been set ,
1911 : * SDP_BW_MODIFIER_UNSUPPORTED will be returned.
1912 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1913 : * level The level from which to get the bw modifier.
1914 : * inst_num instance number of bw line at that level. The first
1915 : * instance has a inst_num of 1 and so on.
1916 : * Returns: Valid modifer value or SDP_BW_MODIFIER_UNSUPPORTED.
1917 : */
1918 0 : sdp_bw_modifier_e sdp_get_bw_modifier (sdp_t *sdp_p, uint16_t level, uint16_t inst_num)
1919 : {
1920 : sdp_bw_data_t *bw_data_p;
1921 :
1922 0 : bw_data_p = sdp_find_bw_line(sdp_p, level, inst_num);
1923 :
1924 0 : if (bw_data_p) {
1925 0 : return (bw_data_p->bw_modifier);
1926 : } else {
1927 0 : return (SDP_BW_MODIFIER_UNSUPPORTED);
1928 : }
1929 : }
1930 :
1931 : /* Function: sdp_get_bw_value
1932 : * Description: Returns the bandwidth value parameter from the b=
1933 : * line.
1934 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1935 : * level The level from which to get the bw value.
1936 : * inst_num instance number of bw line at the level. The first
1937 : * instance has a inst_num of 1 and so on.
1938 : * Returns: A valid numerical bw value or SDP_INVALID_VALUE.
1939 : */
1940 0 : int32_t sdp_get_bw_value (sdp_t *sdp_p, uint16_t level, uint16_t inst_num)
1941 : {
1942 : sdp_bw_data_t *bw_data_p;
1943 :
1944 0 : bw_data_p = sdp_find_bw_line(sdp_p, level, inst_num);
1945 :
1946 0 : if (bw_data_p) {
1947 0 : return (bw_data_p->bw_val);
1948 : } else {
1949 0 : return (SDP_INVALID_VALUE);
1950 : }
1951 : }
1952 :
1953 : /*
1954 : * sdp_get_num_bw_lines
1955 : *
1956 : * Returns the number of bw lines are present at a given level.
1957 : *
1958 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
1959 : * level The level at which the count of bw lines is required
1960 : *
1961 : * Returns: A valid count or SDP_INVALID_VALUE
1962 : */
1963 0 : int32_t sdp_get_num_bw_lines (sdp_t *sdp_p, uint16_t level)
1964 : {
1965 : sdp_bw_t *bw_p;
1966 : sdp_mca_t *mca_p;
1967 :
1968 0 : if (level == SDP_SESSION_LEVEL) {
1969 0 : bw_p = &(sdp_p->bw);
1970 : } else {
1971 0 : mca_p = sdp_find_media_level(sdp_p, level);
1972 0 : if (mca_p == NULL) {
1973 0 : sdp_p->conf_p->num_invalid_param++;
1974 0 : return (SDP_INVALID_VALUE);
1975 : }
1976 0 : bw_p = &(mca_p->bw);
1977 : }
1978 :
1979 0 : return (bw_p->bw_data_count);
1980 : }
1981 :
1982 : /*
1983 : * sdp_add_new_bw_line
1984 : *
1985 : * To specify bandwidth parameters at any level, a bw line must first be
1986 : * added at that level using this function. After this addition, you can set
1987 : * the properties of the added bw line by using sdp_set_bw().
1988 : *
1989 : * Note carefully though, that since there can be multiple instances of bw
1990 : * lines at any level, you must specify the instance number when setting
1991 : * or getting the properties of a bw line at any level.
1992 : *
1993 : * This function returns within the inst_num variable, the instance number
1994 : * of the created bw_line at that level. The instance number is 1-based.
1995 : * For example:
1996 : * v=0 #Session Level
1997 : * o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4
1998 : * s=SDP Seminar
1999 : * c=IN IP4 10.1.0.2
2000 : * t=0 0
2001 : * b=AS:60 # instance number 1
2002 : * b=TIAS:50780 # instance number 2
2003 : * m=audio 1234 RTP/AVP 0 101 102 # 1st Media level
2004 : * b=AS:12 # instance number 1
2005 : * b=TIAS:8480 # instance number 2
2006 : * m=audio 1234 RTP/AVP 0 101 102 # 2nd Media level
2007 : * b=AS:20 # instance number 1
2008 : *
2009 : * Parameters:
2010 : * sdp_p The SDP handle returned by sdp_init_description.
2011 : * level The level to create the bw line.
2012 : * bw_modifier The Type of bandwidth, CT, AS or TIAS.
2013 : * *inst_num This memory is set with the instance number of the newly
2014 : * created bw line instance.
2015 : */
2016 0 : sdp_result_e sdp_add_new_bw_line (sdp_t *sdp_p, uint16_t level, sdp_bw_modifier_e bw_modifier, uint16_t *inst_num)
2017 : {
2018 : sdp_bw_t *bw_p;
2019 : sdp_mca_t *mca_p;
2020 : sdp_bw_data_t *new_bw_data_p;
2021 0 : sdp_bw_data_t *bw_data_p = NULL;
2022 :
2023 0 : *inst_num = 0;
2024 :
2025 0 : if (level == SDP_SESSION_LEVEL) {
2026 0 : bw_p = &(sdp_p->bw);
2027 : } else {
2028 0 : mca_p = sdp_find_media_level(sdp_p, level);
2029 0 : if (mca_p == NULL) {
2030 0 : sdp_p->conf_p->num_invalid_param++;
2031 0 : return (SDP_INVALID_PARAMETER);
2032 : }
2033 0 : bw_p = &(mca_p->bw);
2034 : }
2035 :
2036 : //see if a bw line already exist for this bw_modifier.
2037 0 : for(bw_data_p = bw_p->bw_data_list; bw_data_p != NULL; bw_data_p = bw_data_p->next_p) {
2038 0 : ++(*inst_num);
2039 0 : if (bw_data_p->bw_modifier == bw_modifier) {
2040 0 : return (SDP_SUCCESS);
2041 : }
2042 : }
2043 :
2044 : /*
2045 : * Allocate a new sdp_bw_data_t instance and set it's values from the
2046 : * input parameters.
2047 : */
2048 0 : new_bw_data_p = (sdp_bw_data_t*)SDP_MALLOC(sizeof(sdp_bw_data_t));
2049 0 : if (new_bw_data_p == NULL) {
2050 0 : sdp_p->conf_p->num_no_resource++;
2051 0 : return (SDP_NO_RESOURCE);
2052 : }
2053 0 : new_bw_data_p->next_p = NULL;
2054 0 : new_bw_data_p->bw_modifier = SDP_BW_MODIFIER_UNSUPPORTED;
2055 0 : new_bw_data_p->bw_val = 0;
2056 :
2057 : /*
2058 : * Enqueue the sdp_bw_data_t instance at the end of the list of
2059 : * sdp_bw_data_t instances.
2060 : */
2061 0 : if (bw_p->bw_data_list == NULL) {
2062 0 : bw_p->bw_data_list = new_bw_data_p;
2063 : } else {
2064 0 : for (bw_data_p = bw_p->bw_data_list;
2065 0 : bw_data_p->next_p != NULL;
2066 0 : bw_data_p = bw_data_p->next_p) {
2067 :
2068 : /*sa_ignore EMPTYLOOP*/
2069 : ; /* Do nothing. */
2070 : }
2071 :
2072 0 : bw_data_p->next_p = new_bw_data_p;
2073 : }
2074 0 : *inst_num = ++bw_p->bw_data_count;
2075 :
2076 0 : return (SDP_SUCCESS);
2077 : }
2078 :
2079 : /* Function: sdp_get_mid_value
2080 : * Description: Returns the mid value parameter from the a= mid: line.
2081 : * Parameters: sdp_p The SDP handle returned by sdp_init_description.
2082 : * level SDP_MEDIA_LEVEL
2083 : * Returns: mid value.
2084 : */
2085 0 : int32_t sdp_get_mid_value (sdp_t *sdp_p, uint16_t level)
2086 : {
2087 : sdp_mca_t *mca_p;
2088 :
2089 0 : mca_p = sdp_find_media_level(sdp_p, level);
2090 0 : if (mca_p == NULL) {
2091 0 : sdp_p->conf_p->num_invalid_param++;
2092 0 : return (SDP_INVALID_VALUE);
2093 : }
2094 0 : return (mca_p->mid);
2095 : }
2096 :
|