2 This file is part of FreeSDP
3 Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp@altern.org>
5 FreeSDP is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 Benjamin Zores, (C) 2006
20 added support in parser for the a=control: lines.
21 added support in parser for the a=range: lines.
27 * @short Parsing module implementation.
29 * This file implements the parsing routine <code>fsdp_parse</code>
30 * and the <code>fsdp_get_xxxx</code> routines that allow to get the
31 * session properties from a session description object build through
32 * the application of <code>fsdp_parse</code> to a textual SDP session
36 #include "parserpriv.h"
39 * \brief find the start of the next line
40 * \param c pointer to current position in string
41 * \return pointer to start of next line or NULL if illegal (i.e.
42 * a '\r' is not followed by a '\n'
44 static const char *next_line(const char *c
) {
45 c
+= strcspn(c
, "\n\r");
46 if (*c
== 0) return c
;
54 * Moves the <code>c<code> pointer up to the beginning of the next
57 * @param c char pointer to pointer
58 * @retval FSDPE_ILLEGAL_CHARACTER, when an illegal '\r' character
59 * (not followed by a '\n') is found, returns
61 #define NEXT_LINE(c) do { if (!(c = next_line(c))) return FSDPE_ILLEGAL_CHARACTER; } while (0);
64 fsdp_parse (const char *text_description
, fsdp_description_t
* dsc
)
67 const char *p
= text_description
, *p2
;
68 unsigned int index
, j
;
69 /* temps for sscanf */
70 const unsigned int TEMPCHARS
= 6;
71 char fsdp_buf
[TEMPCHARS
][MAXSHORTFIELDLEN
];
72 char longfsdp_buf
[MAXLONGFIELDLEN
];
73 const unsigned int TEMPINTS
= 2;
74 unsigned long int wuint
[TEMPINTS
];
76 if ((NULL
== text_description
) || (NULL
== dsc
))
77 return FSDPE_INVALID_PARAMETER
;
79 /***************************************************************************/
80 /* A) parse session-level description */
81 /***************************************************************************/
83 /* `v=' line (protocol version) */
84 /* according to the RFC, only `v=0' is valid */
85 if (sscanf (p
, "v=%1lu", &wuint
[0]))
88 return FSDPE_INVALID_VERSION
;
92 return FSDPE_MISSING_VERSION
;
96 /* `o=' line (owner/creator and session identifier) */
97 /* o=<username> <session id> <version> <network type> <address type>
99 if (!strncmp (p
, "o=", 2))
102 /* note that the following max lengths may vary in the future and
103 are quite arbitary */
106 "%" MSFLENS
"[\x21-\xFF] %" MSFLENS
"[0-9] %" MSFLENS
107 "[0-9] %2s %3s %" MSFLENS
"s", fsdp_buf
[0], fsdp_buf
[1],
108 fsdp_buf
[2], fsdp_buf
[3], fsdp_buf
[4], fsdp_buf
[5]) != 6)
109 return FSDPE_INVALID_OWNER
;
110 dsc
->o_username
= strdup (fsdp_buf
[0]);
111 dsc
->o_session_id
= strdup (fsdp_buf
[1]);
112 dsc
->o_announcement_version
= strdup (fsdp_buf
[2]);
113 if (!strncmp (fsdp_buf
[3], "IN", 2))
115 dsc
->o_network_type
= FSDP_NETWORK_TYPE_INET
;
116 if (!strncmp (fsdp_buf
[4], "IP4", 3))
117 dsc
->o_address_type
= FSDP_ADDRESS_TYPE_IPV4
;
118 else if (!strncmp (fsdp_buf
[4], "IP6", 3))
119 dsc
->o_address_type
= FSDP_ADDRESS_TYPE_IPV6
;
121 return FSDPE_INVALID_OWNER
;
125 return FSDPE_INVALID_OWNER
;
127 /* TODO? check valid unicast address/FQDN */
128 dsc
->o_address
= strdup (fsdp_buf
[5]);
132 return FSDPE_MISSING_OWNER
;
136 /* `s=' line (session name) -note that the name string cannot be empty */
137 /* s=<session name> */
138 if (!strncmp (p
, "s=", 2))
140 if (sscanf (p
, "s=%" MLFLENS
"[^\r\n]", longfsdp_buf
) < 1)
141 return FSDPE_EMPTY_NAME
;
142 dsc
->s_name
= strdup (longfsdp_buf
);
146 return FSDPE_MISSING_NAME
;
150 /* `i=' line (session information) [optional] */
151 /* i=<session description> */
152 if (!strncmp (p
, "i=", 2)
153 && sscanf (p
, "i=%" MLFLENS
"[^\r\n]", longfsdp_buf
))
155 dsc
->i_information
= strdup (longfsdp_buf
);
160 /* (optional) information absent */
163 /* `u=' line (URI of description) [optional] */
165 if (!strncmp (p
, "u=", 2)
166 && sscanf (p
, "u=%" MLFLENS
"[^\r\n]", longfsdp_buf
))
168 /* TODO? check valid uri */
169 dsc
->u_uri
= strdup (longfsdp_buf
);
174 /* (optional) uri absent */
177 /* `e=' lines (email address) [zero or more] */
178 /* e=<email address> */
181 while (!strncmp (p2
, "e=", 2))
183 /* First, count how many emails are there */
187 dsc
->emails_count
= j
;
188 if (dsc
->emails_count
> 0)
190 /* Then, build the array of emails */
191 dsc
->emails
= calloc (j
, sizeof (const char *));
192 for (j
= 0; j
< dsc
->emails_count
; j
++)
194 sscanf (p
, "e=%" MLFLENS
"[^\r\n]", longfsdp_buf
);
195 /* TODO? check valid email-address. */
196 dsc
->emails
[j
] = strdup (longfsdp_buf
);
201 /* `p=' lines (phone number) [zero or more] */
202 /* p=<phone number> */
204 /* assert ( p2 == p ); */
205 while (!strncmp (p2
, "p=", 2))
210 dsc
->phones_count
= j
;
211 if (dsc
->phones_count
> 0)
213 dsc
->phones
= calloc (j
, sizeof (const char *));
214 for (j
= 0; j
< dsc
->phones_count
; j
++)
216 sscanf (p
, "p=%" MLFLENS
"[^\r\n]", longfsdp_buf
);
217 /* TODO? check valid phone-number. */
218 dsc
->phones
[j
] = strdup (longfsdp_buf
);
223 /* `c=' line (connection information - not required if included in all media) [optional] */
224 /* c=<network type> <address type> <connection address> */
225 result
= fsdp_parse_c (&p
, &(dsc
->c_network_type
), &(dsc
->c_address_type
),
227 if (FSDPE_OK
!= result
)
230 /* `b=' lines (bandwidth information) [optional] */
231 /* b=<modifier>:<bandwidth-value> */
233 fsdp_parse_b (&p
, &(dsc
->bw_modifiers
), &(dsc
->bw_modifiers_count
));
234 if (FSDPE_OK
!= result
)
237 /* A.1) Time descriptions: */
239 /* `t=' lines (time the session is active) [1 or more] */
240 /* t=<start time> <stop time> */
243 while (!strncmp (p2
, "t=", 2))
247 while (!strncmp (p2
, "r=", 2))
250 dsc
->time_periods_count
= j
;
251 if (dsc
->time_periods_count
== 0)
252 return FSDPE_MISSING_TIME
;
253 dsc
->time_periods
= calloc (dsc
->time_periods_count
,
254 sizeof (fsdp_time_period_t
*));
256 for (j
= 0; j
< dsc
->time_periods_count
; j
++)
259 if (sscanf (p
, "t=%10lu %10lu", &wuint
[0], &wuint
[1]) != 2)
261 /* not all periods have been successfully parsed */
262 dsc
->time_periods_count
= j
;
263 return FSDPE_INVALID_TIME
;
265 dsc
->time_periods
[j
] = calloc (1, sizeof (fsdp_time_period_t
));
267 /* convert from NTP to time_t time */
269 wuint
[0] -= NTP_EPOCH_OFFSET
;
271 wuint
[1] -= NTP_EPOCH_OFFSET
;
272 dsc
->time_periods
[j
]->start
= wuint
[0];
273 dsc
->time_periods
[j
]->stop
= wuint
[1];
276 /* `r' lines [zero or more repeat times for each t=] */
277 /*r=<repeat interval> <active duration> <list of offsets from
280 while (!strncmp (p2
, "r=", 2))
285 dsc
->time_periods
[j
]->repeats_count
= h
;
288 unsigned int index2
= 0;
289 dsc
->time_periods
[j
]->repeats
=
290 calloc (h
, sizeof (fsdp_repeat_t
*));
291 for (h
= 0; h
< dsc
->time_periods
[j
]->repeats_count
; h
++)
294 get_repeat_values(p,&(dsc->time_periods[index].repeats[index2]));
295 fsdp_error_t get_repeat_values (const char *r, fsdp_repeat_t
298 if (sscanf (p
, "r=%10s %10s %" MLFLENS
"[^\r\n]",
299 fsdp_buf
[0], fsdp_buf
[1], longfsdp_buf
) == 3)
301 fsdp_repeat_t
*repeat
;
302 dsc
->time_periods
[j
]->repeats
[h
] =
303 calloc (1, sizeof (fsdp_repeat_t
));
304 repeat
= dsc
->time_periods
[j
]->repeats
[h
];
305 /* get interval, duration and list of offsets */
307 fsdp_repeat_time_to_uint (fsdp_buf
[0],
308 &(repeat
->interval
));
309 if (result
== FSDPE_OK
)
312 fsdp_repeat_time_to_uint (fsdp_buf
[1],
313 &(repeat
->duration
));
314 if (result
== FSDPE_OK
)
317 const char *i
= longfsdp_buf
;
318 while (NULL
!= (i
= strchr (i
, ' ')))
324 repeat
->offsets_count
= k
;
325 repeat
->offsets
= calloc (k
, sizeof (time_t));
328 (k
< repeat
->offsets_count
)
329 && (result
== FSDPE_OK
); k
++)
332 fsdp_repeat_time_to_uint (i
,
339 if (k
< repeat
->offsets_count
)
341 /* there where invalid repeat offsets */
342 dsc
->time_periods
[j
]->repeats_count
= k
;
343 return FSDPE_INVALID_REPEAT
;
347 if (result
!= FSDPE_OK
)
349 /* not all repeats have been succesfully parsed */
350 dsc
->time_periods
[j
]->repeats_count
= h
;
351 return FSDPE_INVALID_REPEAT
;
357 /* not all repeats have been succesfully parsed */
358 dsc
->time_periods
[j
]->repeats_count
= h
;
359 return FSDPE_INVALID_REPEAT
;
366 /* `z=' line (time zone adjustments) [zero or more] */
367 /* z=<adjustment time> <offset> <adjustment time> <offset> .... */
368 if (!strncmp (p
, "z=", 2))
370 if (sscanf (p
, "z=%" MLFLENS
"[^\r\n]", longfsdp_buf
))
372 /* TODO: guess how many pairs are there and process them */
373 dsc
->timezone_adj
= strdup (longfsdp_buf
);
378 return FSDPE_INVALID_TIMEZONE
;
382 /* `k=' line (encryption key) [optional] */
384 k=<method>:<encryption key> */
385 result
= fsdp_parse_k (&p
, &(dsc
->k_encryption_method
),
386 &(dsc
->k_encryption_content
));
387 if (result
!= FSDPE_OK
)
390 /* A.2) Attributes */
391 /* `a=' lines (session attribute) [0 or more] */
393 a=<attribute>:<value> */
394 while (!strncmp (p
, "a=", 2))
396 /* The "9" length specifier of the first string is subject to
399 (p
, "a=%9[^:\r\n]:%" MSFLENS
"[^\r\n]", fsdp_buf
[0],
402 /* session-level value attributes */
403 if (!strncmp (fsdp_buf
[0], "cat", 3))
404 dsc
->a_category
= strdup (fsdp_buf
[1]);
405 else if (!strncmp (fsdp_buf
[0], "keywds", 6))
406 dsc
->a_keywords
= strdup (fsdp_buf
[1]);
407 else if (!strncmp (fsdp_buf
[0], "tool", 4))
408 dsc
->a_keywords
= strdup (fsdp_buf
[1]);
409 else if (!strncmp (fsdp_buf
[0], "rtpmap", 6))
410 fsdp_parse_rtpmap (&(dsc
->a_rtpmaps
),
411 &(dsc
->a_rtpmaps_count
), fsdp_buf
[1]);
412 else if (!strncmp (fsdp_buf
[0], "type", 4))
414 if (!strncmp (fsdp_buf
[1], "broadcast", 9))
415 dsc
->a_type
= FSDP_SESSION_TYPE_BROADCAST
;
416 else if (!strncmp (fsdp_buf
[1], "meeting", 7))
417 dsc
->a_type
= FSDP_SESSION_TYPE_MEETING
;
418 else if (!strncmp (fsdp_buf
[1], "moderated", 9))
419 dsc
->a_type
= FSDP_SESSION_TYPE_MODERATED
;
420 else if (!strncmp (fsdp_buf
[1], "test", 4))
421 dsc
->a_type
= FSDP_SESSION_TYPE_TEST
;
422 else if (!strncmp (fsdp_buf
[1], "H332", 4))
423 dsc
->a_type
= FSDP_SESSION_TYPE_H332
;
425 return FSDPE_INVALID_SESSION_TYPE
;
427 else if (!strncmp (fsdp_buf
[0], "charset", 7))
428 dsc
->a_charset
= strdup (fsdp_buf
[1]);
429 else if (!strncmp (fsdp_buf
[0], "sdplang", 7))
431 if (NULL
== dsc
->a_sdplangs
)
433 dsc
->a_sdplangs_count
= 0;
435 calloc (SDPLANGS_MAX_COUNT
, sizeof (char *));
437 if (dsc
->a_sdplangs_count
< SDPLANGS_MAX_COUNT
)
439 dsc
->a_sdplangs
[dsc
->a_sdplangs_count
] =
440 strdup (fsdp_buf
[1]);
441 dsc
->a_sdplangs_count
++;
444 else if (!strncmp (fsdp_buf
[0], "lang", 4))
446 if (NULL
== dsc
->a_langs
)
448 dsc
->a_langs_count
= 0;
449 dsc
->a_langs
= calloc (SDPLANGS_MAX_COUNT
, sizeof (char *));
451 if (dsc
->a_langs_count
< SDPLANGS_MAX_COUNT
)
453 dsc
->a_langs
[dsc
->a_langs_count
] = strdup (fsdp_buf
[1]);
454 dsc
->a_langs_count
++;
457 else if (!strncmp (fsdp_buf
[0], "control", 7))
459 if (NULL
== dsc
->a_controls
)
461 dsc
->a_controls_count
= 0;
463 calloc (SDPCONTROLS_MAX_COUNT
, sizeof (char *));
465 if (dsc
->a_controls_count
< SDPCONTROLS_MAX_COUNT
)
467 dsc
->a_controls
[dsc
->a_controls_count
] =
468 strdup (fsdp_buf
[1]);
469 dsc
->a_controls_count
++;
472 else if (!strncmp (fsdp_buf
[0], "range", 5))
476 dsc
->a_range
= strdup (fsdp_buf
[1]);
480 /* ignore unknown attributes, but provide access to them */
481 *longfsdp_buf
= '\0';
482 strncat (longfsdp_buf
, fsdp_buf
[0], MAXLONGFIELDLEN
-1);
483 strncat (longfsdp_buf
, ":", MAXLONGFIELDLEN
-strlen(longfsdp_buf
)-1);
484 strncat (longfsdp_buf
, fsdp_buf
[1], MAXLONGFIELDLEN
-strlen(longfsdp_buf
)-1);
485 if (NULL
== dsc
->unidentified_attributes
)
487 dsc
->unidentified_attributes_count
= 0;
488 dsc
->unidentified_attributes
=
489 calloc (UNIDENTIFIED_ATTRIBUTES_MAX_COUNT
,
492 if (dsc
->unidentified_attributes_count
<
493 UNIDENTIFIED_ATTRIBUTES_MAX_COUNT
)
495 dsc
->unidentified_attributes
496 [dsc
->unidentified_attributes_count
] =
497 strdup (longfsdp_buf
);
498 dsc
->unidentified_attributes_count
++;
503 else if (sscanf (p
, "a=%20s", fsdp_buf
[0]) == 1)
505 /* session-level property attributes */
506 if (!strncmp (fsdp_buf
[0], "recvonly", 8))
507 dsc
->a_sendrecv_mode
= FSDP_SENDRECV_RECVONLY
;
508 else if (!strncmp (fsdp_buf
[0], "sendonly", 8))
509 dsc
->a_sendrecv_mode
= FSDP_SENDRECV_SENDONLY
;
510 else if (!strncmp (fsdp_buf
[0], "inactive", 8))
511 dsc
->a_sendrecv_mode
= FSDP_SENDRECV_INACTIVE
;
512 else if (!strncmp (fsdp_buf
[0], "sendrecv", 8))
513 dsc
->a_sendrecv_mode
= FSDP_SENDRECV_SENDRECV
;
516 /* ignore unknown attributes, but provide access to them */
517 *longfsdp_buf
= '\0';
518 strncat (longfsdp_buf
, fsdp_buf
[0], MAXLONGFIELDLEN
-1);
519 if (NULL
== dsc
->unidentified_attributes
)
521 dsc
->unidentified_attributes_count
= 0;
522 dsc
->unidentified_attributes
=
523 calloc (UNIDENTIFIED_ATTRIBUTES_MAX_COUNT
,
526 if (dsc
->unidentified_attributes_count
<
527 UNIDENTIFIED_ATTRIBUTES_MAX_COUNT
)
529 dsc
->unidentified_attributes
530 [dsc
->unidentified_attributes_count
] =
531 strdup (longfsdp_buf
);
532 dsc
->unidentified_attributes_count
++;
538 return FSDPE_INVALID_ATTRIBUTE
;
541 /***************************************************************************/
542 /* B) parse media-level descriptions */
543 /***************************************************************************/
546 while ((*p2
!= '\0') && !strncmp (p2
, "m=", 2))
551 while (sscanf (p2
, "%c=", &c
) == 1)
553 if (c
== 'i' || c
== 'c' || c
== 'b' || c
== 'k' || c
== 'a')
563 return FSDPE_INVALID_LINE
;
567 dsc
->media_announcements_count
= j
;
568 if (dsc
->media_announcements_count
== 0)
571 /*return FSDPE_MISSING_MEDIA; */
574 { /* dsc->media_announcements_count > 0 */
575 dsc
->media_announcements
=
576 calloc (j
, sizeof (fsdp_media_announcement_t
*));
577 for (j
= 0; j
< dsc
->media_announcements_count
; j
++)
579 fsdp_media_announcement_t
*media
= NULL
;
580 /* `m=' line (media name, transport address and format list) */
581 /* m=<media> <port> <transport> <fmt list> */
582 /* The max. string lengths are subject to change */
583 if (sscanf (p
, "m=%11s %8s %7s %" MLFLENS
"[^\r\n]",
584 fsdp_buf
[0], fsdp_buf
[1], fsdp_buf
[2],
587 return FSDPE_INVALID_MEDIA
;
591 dsc
->media_announcements
[j
] =
592 calloc (1, sizeof (fsdp_media_announcement_t
));
593 media
= dsc
->media_announcements
[j
];
594 if (!strncmp (fsdp_buf
[0], "audio", 5))
595 media
->media_type
= FSDP_MEDIA_AUDIO
;
596 else if (!strncmp (fsdp_buf
[0], "video", 5))
597 media
->media_type
= FSDP_MEDIA_VIDEO
;
598 else if (!strncmp (fsdp_buf
[0], "application", 11))
599 media
->media_type
= FSDP_MEDIA_APPLICATION
;
600 else if (!strncmp (fsdp_buf
[0], "data", 4))
601 media
->media_type
= FSDP_MEDIA_DATA
;
602 else if (!strncmp (fsdp_buf
[0], "control", 7))
603 media
->media_type
= FSDP_MEDIA_CONTROL
;
605 return FSDPE_UNKNOWN_MEDIA_TYPE
;
606 { /* try to get port specification as port/number */
608 if ((slash
= strchr (fsdp_buf
[1], '/')))
612 media
->port
= strtol (fsdp_buf
[1], NULL
, 10);
613 media
->port_count
= strtol (slash
, NULL
, 10);
617 media
->port
= strtol (fsdp_buf
[1], NULL
, 10);
618 media
->port_count
= 0;
621 if (!strncmp (fsdp_buf
[2], "RTP/AVP", 7))
622 media
->transport
= FSDP_TP_RTP_AVP
;
623 else if (!strncmp (fsdp_buf
[2], "udp", 3))
624 media
->transport
= FSDP_TP_UDP
;
625 else if (!strncmp (fsdp_buf
[2], "TCP", 3))
626 media
->transport
= FSDP_TP_TCP
;
627 else if (!strncmp (fsdp_buf
[2], "UDPTL", 5))
628 media
->transport
= FSDP_TP_UDPTL
;
629 else if (!strncmp (fsdp_buf
[2], "vat", 3))
630 media
->transport
= FSDP_TP_VAT
;
631 else if (!strncmp (fsdp_buf
[2], "rtp", 3))
632 media
->transport
= FSDP_TP_OLD_RTP
;
634 return FSDPE_UNKNOWN_MEDIA_TRANSPORT
;
637 char *s
= longfsdp_buf
;
638 while (NULL
!= (s
= strchr (s
, ' ')))
644 k
++; /* when there is no space left, count the last format */
645 media
->formats_count
= k
;
646 media
->formats
= calloc (k
, sizeof (char *));
648 for (k
= 0; k
< media
->formats_count
; k
++)
650 char *space
= strchr (s
, ' ');
653 media
->formats
[k
] = strdup (s
);
660 /* `i=' line (media title) [optional] */
661 /* i=<media title> */
662 if (!strncmp (p
, "i=", 2)
663 && sscanf (p
, "i=%" MLFLENS
"[^\r\n]", longfsdp_buf
))
665 media
->i_title
= strdup (longfsdp_buf
);
670 /* (optional) information absent */
673 /* `c=' line (connection information - overrides session-level
674 line) [optional if provided at session-level] */
675 /* c=<network type> <address type> <connection address> */
676 result
= fsdp_parse_c (&p
, &(media
->c_network_type
),
677 &(media
->c_address_type
),
678 &(media
->c_address
));
679 if (result
!= FSDPE_OK
)
682 /* `b=' lines (bandwidth information) [optional] */
683 /* b=<modifier>:<bandwidth-value> */
684 result
= fsdp_parse_b (&p
, &(media
->bw_modifiers
),
685 &(media
->bw_modifiers_count
));
686 if (FSDPE_OK
!= result
)
689 /* `k=' line (encryption key) [optional] */
691 k=<method>:<encryption key> */
692 result
= fsdp_parse_k (&p
, &(media
->k_encryption_method
),
693 &(media
->k_encryption_content
));
694 if (result
!= FSDPE_OK
)
697 /* B.1) Attributes */
699 /* `a=' lines (zero or more media attribute lines) [optional] */
701 a=<attribute>:<value> */
702 while (!strncmp (p
, "a=", 2))
705 (p
, "a=%9[^:\r\n]:%" MLFLENS
"[^\r\n]", fsdp_buf
[0],
708 /* media-level value attributes */
709 if (!strncmp (fsdp_buf
[0], "ptime", 5))
710 media
->a_ptime
= strtoul (longfsdp_buf
, NULL
, 10);
711 else if (!strncmp (fsdp_buf
[0], "maxptime", 8))
712 media
->a_maxptime
= strtoul (longfsdp_buf
, NULL
, 10);
713 else if (!strncmp (fsdp_buf
[0], "rtpmap", 6))
714 fsdp_parse_rtpmap (&(media
->a_rtpmaps
),
715 &(media
->a_rtpmaps_count
),
717 else if (!strncmp (fsdp_buf
[0], "orient", 6))
719 if (!strncmp (longfsdp_buf
, "portrait", 8))
720 media
->a_orient
= FSDP_ORIENT_PORTRAIT
;
721 else if (!strncmp (longfsdp_buf
, "landscape", 9))
722 media
->a_orient
= FSDP_ORIENT_LANDSCAPE
;
723 else if (!strncmp (longfsdp_buf
, "seascape", 9))
724 media
->a_orient
= FSDP_ORIENT_SEASCAPE
;
726 else if (!strncmp (fsdp_buf
[0], "sdplang", 7))
728 if (NULL
== dsc
->a_sdplangs
)
730 media
->a_sdplangs_count
= 0;
732 calloc (SDPLANGS_MAX_COUNT
, sizeof (char *));
734 if (media
->a_sdplangs_count
< SDPLANGS_MAX_COUNT
)
736 media
->a_sdplangs
[dsc
->a_sdplangs_count
] =
737 strdup (longfsdp_buf
);
738 media
->a_sdplangs_count
++;
741 else if (!strncmp (fsdp_buf
[0], "lang", 4))
743 if (NULL
== dsc
->a_langs
)
745 media
->a_langs_count
= 0;
747 calloc (SDPLANGS_MAX_COUNT
, sizeof (char *));
749 if (media
->a_langs_count
< SDPLANGS_MAX_COUNT
)
751 media
->a_langs
[dsc
->a_langs_count
] =
752 strdup (longfsdp_buf
);
753 media
->a_langs_count
++;
756 else if (!strncmp (fsdp_buf
[0], "control", 7))
758 if (NULL
== media
->a_controls
)
760 media
->a_controls_count
= 0;
762 calloc (SDPCONTROLS_MAX_COUNT
, sizeof (char *));
764 if (media
->a_controls_count
< SDPCONTROLS_MAX_COUNT
)
766 media
->a_controls
[media
->a_controls_count
] =
767 strdup (longfsdp_buf
);
768 media
->a_controls_count
++;
771 else if (!strncmp (fsdp_buf
[0], "range", 5))
774 free (media
->a_range
);
775 media
->a_range
= strdup (fsdp_buf
[1]);
777 else if (!strncmp (fsdp_buf
[0], "framerate", 9))
778 media
->a_framerate
= strtod (longfsdp_buf
, NULL
);
779 else if (!strncmp (fsdp_buf
[0], "fmtp", 4))
781 if (NULL
== media
->a_fmtps
)
783 media
->a_fmtps_count
= 0;
785 calloc (SDPLANGS_MAX_COUNT
, sizeof (char *));
787 if (media
->a_fmtps_count
< SDPLANGS_MAX_COUNT
)
789 media
->a_fmtps
[media
->a_fmtps_count
] =
790 strdup (longfsdp_buf
);
791 media
->a_fmtps_count
++;
794 else if (!strncmp (fsdp_buf
[0], "rtcp", 4))
797 /* rtcp attribute: a=rtcp:<port> <nettype> <addrtype> <address> */
799 sscanf (longfsdp_buf
, "%lu %2s %3s %" MSFLENS
"s",
800 &wuint
[0], fsdp_buf
[0], fsdp_buf
[1],
804 media
->a_rtcp_port
= wuint
[0];
807 if (!strncmp (fsdp_buf
[0], "IN", 2))
809 media
->a_rtcp_network_type
=
810 FSDP_NETWORK_TYPE_INET
;
812 ; TODO: define error code? */
815 if (!strncmp (fsdp_buf
[1], "IP4", 3))
816 media
->a_rtcp_address_type
=
817 FSDP_ADDRESS_TYPE_IPV4
;
818 else if (!strncmp (fsdp_buf
[1], "IP6", 3))
819 media
->a_rtcp_address_type
=
820 FSDP_ADDRESS_TYPE_IPV6
;
822 return FSDPE_INVALID_CONNECTION_NETTYPE
;
823 /*add specific code? */
825 media
->a_rtcp_address
=
826 strdup (fsdp_buf
[2]);
833 /* ignore unknown attributes, but provide access to them */
835 strncat (fsdp_buf
[1], fsdp_buf
[0], MAXSHORTFIELDLEN
-1);
836 strncat (fsdp_buf
[1], ":", MAXSHORTFIELDLEN
-strlen(fsdp_buf
[1])-1);
837 strncat (fsdp_buf
[1], longfsdp_buf
, MAXSHORTFIELDLEN
-strlen(fsdp_buf
[1])-1);
838 if (NULL
== media
->unidentified_attributes
)
840 media
->unidentified_attributes_count
= 0;
841 media
->unidentified_attributes
=
842 calloc (UNIDENTIFIED_ATTRIBUTES_MAX_COUNT
,
845 if (media
->unidentified_attributes_count
<
846 UNIDENTIFIED_ATTRIBUTES_MAX_COUNT
)
848 media
->unidentified_attributes
849 [media
->unidentified_attributes_count
] =
850 strdup (fsdp_buf
[1]);
851 media
->unidentified_attributes_count
++;
856 else if (sscanf (p
, "a=%8s", fsdp_buf
[0]) == 1)
858 /* media-level property attributes */
859 if (!strncmp (fsdp_buf
[0], "recvonly", 8))
860 media
->a_sendrecv_mode
= FSDP_SENDRECV_RECVONLY
;
861 else if (!strncmp (fsdp_buf
[0], "sendonly", 8))
862 media
->a_sendrecv_mode
= FSDP_SENDRECV_SENDONLY
;
863 else if (!strncmp (fsdp_buf
[0], "inactive", 8))
864 media
->a_sendrecv_mode
= FSDP_SENDRECV_INACTIVE
;
865 else if (!strncmp (fsdp_buf
[0], "sendrecv", 8))
866 media
->a_sendrecv_mode
= FSDP_SENDRECV_SENDRECV
;
869 /* ignore unknown attributes, but provide access to them */
870 *longfsdp_buf
= '\0';
871 strncat (longfsdp_buf
, fsdp_buf
[0], MAXLONGFIELDLEN
-1);
872 if (NULL
== media
->unidentified_attributes
)
874 media
->unidentified_attributes_count
= 0;
875 media
->unidentified_attributes
=
876 calloc (UNIDENTIFIED_ATTRIBUTES_MAX_COUNT
,
879 if (media
->unidentified_attributes_count
<
880 UNIDENTIFIED_ATTRIBUTES_MAX_COUNT
)
882 media
->unidentified_attributes
883 [media
->unidentified_attributes_count
] =
884 strdup (longfsdp_buf
);
885 media
->unidentified_attributes_count
++;
891 return FSDPE_INVALID_ATTRIBUTE
;
896 /* Check c= has been given at session level or at media level for
898 if (NULL
== dsc
->c_address
.address
)
901 for (c
= 0; c
< dsc
->media_announcements_count
; c
++)
902 if (NULL
== dsc
->media_announcements
[c
]->c_address
.address
)
903 return FSDPE_MISSING_CONNECTION_INFO
;
910 return FSDPE_OVERFILLED
;
914 fsdp_parse_c (const char **p
, fsdp_network_type_t
* ntype
,
915 fsdp_address_type_t
* atype
,
916 fsdp_connection_address_t
* address
)
918 const unsigned int TEMPCHARS
= 3;
919 char fsdp_buf
[TEMPCHARS
][MAXSHORTFIELDLEN
];
921 if (!strncmp (*p
, "c=", 2))
923 if (sscanf (*p
, "c=%2s %3s %" MSFLENS
"s",
924 fsdp_buf
[0], fsdp_buf
[1], fsdp_buf
[2]))
926 if (!strncmp (fsdp_buf
[0], "IN", 2))
928 *ntype
= FSDP_NETWORK_TYPE_INET
;
929 if (!strncmp (fsdp_buf
[1], "IP4", 3))
930 *atype
= FSDP_ADDRESS_TYPE_IPV4
;
931 else if (!strncmp (fsdp_buf
[1], "IP6", 3))
932 *atype
= FSDP_ADDRESS_TYPE_IPV6
;
934 return FSDPE_INVALID_CONNECTION_NETTYPE
;
938 return FSDPE_INVALID_CONNECTION_ADDRTYPE
;
941 char *slash
= strchr (fsdp_buf
[2], '/');
944 address
->address
= strdup (fsdp_buf
[2]);
945 address
->address_ttl
= 0;
946 address
->address_count
= 0;
950 /* address is IP4 multicast */
954 address
->address
= strdup (fsdp_buf
[2]);
955 slash2
= strchr (slash
+ 1, '/');
958 address
->address_ttl
= strtol (slash
, NULL
, 10);
959 address
->address_count
= 0;
965 address
->address_ttl
= strtol (slash
, NULL
, 10);
966 address
->address_count
= strtol (slash2
, NULL
, 10);
974 return FSDPE_INVALID_CONNECTION
;
981 fsdp_parse_b (const char **p
, fsdp_bw_modifier_t
** bw_modifiers
,
982 unsigned int *bw_modifiers_count
)
984 char fsdp_buf
[MAXSHORTFIELDLEN
];
985 unsigned long int wuint
;
990 while (!strncmp (lp
, "b=", 2))
995 *bw_modifiers
= calloc (i
, sizeof (fsdp_bw_modifier_t
));
996 *bw_modifiers_count
= i
;
1000 unsigned int index
= *bw_modifiers_count
- i
;
1001 if (2 == sscanf (*p
, "b=%20[^:\r\n]:%lu", fsdp_buf
, &wuint
))
1003 if (!strncmp (fsdp_buf
, "CT", 2))
1004 (*bw_modifiers
)[index
].b_mod_type
=
1005 FSDP_BW_MOD_TYPE_CONFERENCE_TOTAL
;
1006 else if (!strncmp (fsdp_buf
, "AS", 2))
1007 (*bw_modifiers
)[index
].b_mod_type
=
1008 FSDP_BW_MOD_TYPE_APPLICATION_SPECIFIC
;
1009 else if (!strncmp (fsdp_buf
, "RS", 2))
1010 (*bw_modifiers
)[index
].b_mod_type
= FSDP_BW_MOD_TYPE_RTCP_SENDERS
;
1011 else if (!strncmp (fsdp_buf
, "RR", 2))
1012 (*bw_modifiers
)[index
].b_mod_type
=
1013 FSDP_BW_MOD_TYPE_RTCP_RECEIVERS
;
1016 (*bw_modifiers
)[index
].b_mod_type
= FSDP_BW_MOD_TYPE_UNKNOWN
;
1017 (*bw_modifiers
)[index
].b_unknown_bw_modt
=
1018 (char *) strdup (fsdp_buf
);
1020 (*bw_modifiers
)[index
].b_value
= wuint
;
1025 *bw_modifiers_count
-= i
;
1026 return FSDPE_INVALID_BANDWIDTH
;
1034 fsdp_parse_k (const char **p
, fsdp_encryption_method_t
* method
,
1037 char fsdp_buf
[MAXSHORTFIELDLEN
];
1038 char longfsdp_buf
[MAXLONGFIELDLEN
];
1040 if (!strncmp (*p
, "k=", 2))
1042 if (sscanf (*p
, "k=prompt"))
1044 *method
= FSDP_ENCRYPTION_METHOD_PROMPT
;
1051 (*p
, "k=%6[^:\r\n]:%" MLFLENS
"s", fsdp_buf
, longfsdp_buf
))
1053 if (!strncmp (fsdp_buf
, "clear", 5))
1054 *method
= FSDP_ENCRYPTION_METHOD_CLEAR
;
1055 else if (!strncmp (fsdp_buf
, "base64", 6))
1056 *method
= FSDP_ENCRYPTION_METHOD_BASE64
;
1057 else if (!strncmp (fsdp_buf
, "uri", 3))
1058 *method
= FSDP_ENCRYPTION_METHOD_URI
;
1060 return FSDPE_INVALID_ENCRYPTION_METHOD
;
1061 *content
= strdup (longfsdp_buf
);
1070 fsdp_parse_rtpmap (fsdp_rtpmap_t
*** rtpmap
, unsigned int *counter
,
1073 fsdp_error_t result
= FSDPE_OK
;
1078 *rtpmap
= calloc (MEDIA_RTPMAPS_MAX_COUNT
, sizeof (fsdp_rtpmap_t
*));
1080 if (*counter
< MEDIA_RTPMAPS_MAX_COUNT
)
1082 unsigned int c
= *counter
;
1083 fsdp_rtpmap_t
**map
= *rtpmap
;
1084 char fsdp_buf
[MAXSHORTFIELDLEN
];
1085 char longfsdp_buf
[MAXLONGFIELDLEN
];
1086 map
[c
] = calloc (1, sizeof (fsdp_rtpmap_t
));
1088 /* a=rtpmap:<payload type> <encoding name>/<clock rate>[/<encoding
1090 if (2 == sscanf (value
, "%s %s", fsdp_buf
, longfsdp_buf
))
1093 map
[c
]->pt
= strdup (fsdp_buf
);
1094 /* parse <encoding name>/<clock rate>[/<encoding parameters>] */
1095 slash1
= strchr (longfsdp_buf
, '/');
1098 result
= FSDPE_INVALID_ATTRIBUTE_RTPMAP
;
1105 map
[c
]->encoding_name
= strdup (longfsdp_buf
);
1106 slash2
= strchr (slash1
, '/');
1111 map
[c
]->parameters
= strdup (slash2
);
1113 map
[c
]->clock_rate
= strtol (slash1
, NULL
, 10);
1122 fsdp_repeat_time_to_uint (const char *time
, unsigned long int *seconds
)
1124 const unsigned long SECONDS_PER_DAY
= 86400;
1125 const unsigned long SECONDS_PER_HOUR
= 3600;
1126 const unsigned long SECONDS_PER_MINUTE
= 60;
1128 unsigned long int wuint
;
1130 if (sscanf (time
, "%lu%c", &wuint
, &c
) == 2)
1132 /* time with unit specification character */
1136 *seconds
= wuint
* SECONDS_PER_DAY
;
1139 *seconds
= wuint
* SECONDS_PER_HOUR
;
1142 *seconds
= wuint
* SECONDS_PER_MINUTE
;
1148 return FSDPE_INVALID_REPEAT
;
1152 else if (sscanf (time
, "%lu", &wuint
) == 1)
1154 /* time without unit specification character */
1159 return FSDPE_INVALID_REPEAT
;
1165 fsdp_get_version (const fsdp_description_t
* dsc
)
1169 return dsc
->version
;
1173 fsdp_get_owner_username (const fsdp_description_t
* dsc
)
1177 return dsc
->o_username
;
1181 fsdp_get_session_id (const fsdp_description_t
* dsc
)
1185 return dsc
->o_session_id
;
1189 fsdp_get_announcement_version (const fsdp_description_t
* dsc
)
1193 return dsc
->o_announcement_version
;
1197 fsdp_get_owner_network_type (const fsdp_description_t
* dsc
)
1200 return FSDP_NETWORK_TYPE_UNDEFINED
;
1201 return dsc
->o_network_type
;
1205 fsdp_get_owner_address_type (const fsdp_description_t
* dsc
)
1208 return FSDP_ADDRESS_TYPE_UNDEFINED
;
1209 return dsc
->o_address_type
;
1213 fsdp_get_owner_address (const fsdp_description_t
* dsc
)
1217 return dsc
->o_address
;
1221 fsdp_get_name (const fsdp_description_t
* dsc
)
1229 fsdp_get_information (const fsdp_description_t
* dsc
)
1233 return dsc
->i_information
;
1237 fsdp_get_uri (const fsdp_description_t
* dsc
)
1245 fsdp_get_emails_count (const fsdp_description_t
* dsc
)
1249 return dsc
->emails_count
;
1253 fsdp_get_email (const fsdp_description_t
* dsc
, unsigned int index
)
1255 if ((!dsc
) || (index
>= dsc
->emails_count
))
1257 return dsc
->emails
[index
];
1261 fsdp_get_phones_count (const fsdp_description_t
* dsc
)
1265 return dsc
->phones_count
;
1269 fsdp_get_phone (const fsdp_description_t
* dsc
, unsigned int index
)
1271 if ((!dsc
) || (index
>= dsc
->phones_count
))
1273 return dsc
->phones
[index
];
1277 fsdp_get_global_conn_network_type (const fsdp_description_t
* dsc
)
1280 return FSDP_NETWORK_TYPE_UNDEFINED
;
1281 return dsc
->c_network_type
;
1285 fsdp_get_global_conn_address_type (const fsdp_description_t
* dsc
)
1288 return FSDP_ADDRESS_TYPE_UNDEFINED
;
1289 return dsc
->c_address_type
;
1293 fsdp_get_global_conn_address (const fsdp_description_t
* dsc
)
1297 return dsc
->c_address
.address
;
1301 fsdp_get_global_conn_address_ttl (const fsdp_description_t
* dsc
)
1305 return dsc
->c_address
.address_ttl
;
1309 fsdp_get_global_conn_address_count (const fsdp_description_t
* dsc
)
1313 return dsc
->c_address
.address_count
;
1317 fsdp_get_bw_modifier_count (const fsdp_description_t
* dsc
)
1321 return dsc
->bw_modifiers_count
;
1324 fsdp_bw_modifier_type_t
1325 fsdp_get_bw_modifier_type (const fsdp_description_t
* dsc
, unsigned int index
)
1327 if ((!dsc
) || (index
>= dsc
->bw_modifiers_count
))
1328 return FSDP_BW_MOD_TYPE_UNDEFINED
;
1329 return dsc
->bw_modifiers
[index
].b_mod_type
;
1333 fsdp_get_bw_modifier_type_unknown (const fsdp_description_t
* dsc
,
1336 if ((!dsc
) || (index
>= dsc
->bw_modifiers_count
) ||
1337 (dsc
->bw_modifiers
[index
].b_mod_type
!= FSDP_BW_MOD_TYPE_UNKNOWN
))
1339 return dsc
->bw_modifiers
[index
].b_unknown_bw_modt
;
1343 fsdp_get_bw_value (const fsdp_description_t
* dsc
, unsigned int index
)
1345 if ((!dsc
) || (index
>= dsc
->bw_modifiers_count
))
1347 return dsc
->bw_modifiers
[index
].b_value
;
1351 fsdp_get_period_start (const fsdp_description_t
* dsc
, unsigned int index
)
1353 if ((!dsc
) || (index
>= dsc
->time_periods_count
))
1355 return dsc
->time_periods
[index
]->start
;
1359 fsdp_get_period_stop (const fsdp_description_t
* dsc
, unsigned int index
)
1361 if ((!dsc
) || (index
>= dsc
->time_periods_count
))
1363 return dsc
->time_periods
[index
]->stop
;
1367 fsdp_get_period_repeats_count (const fsdp_description_t
* dsc
,
1370 if ((!dsc
) || (index
>= dsc
->time_periods_count
))
1372 return dsc
->time_periods
[index
]->repeats_count
;
1376 fsdp_get_period_repeat_interval (const fsdp_description_t
* dsc
,
1377 unsigned int index
, unsigned int rindex
)
1379 if ((!dsc
) || (index
>= dsc
->time_periods_count
))
1381 return dsc
->time_periods
[index
]->repeats
[rindex
]->interval
;
1385 fsdp_get_period_repeat_duration (const fsdp_description_t
* dsc
,
1386 unsigned int index
, unsigned int rindex
)
1388 if ((!dsc
) || (index
>= dsc
->time_periods_count
))
1390 return dsc
->time_periods
[index
]->repeats
[rindex
]->duration
;
1393 const unsigned long int *
1394 fsdp_get_period_repeat_offsets (const fsdp_description_t
* dsc
,
1395 unsigned int index
, unsigned int rindex
)
1397 if ((!dsc
) || (index
>= dsc
->time_periods_count
))
1399 return dsc
->time_periods
[index
]->repeats
[rindex
]->offsets
;
1403 fsdp_get_timezone_adj (const fsdp_description_t
* dsc
)
1407 return dsc
->timezone_adj
;
1411 fsdp_get_unidentified_attribute_count (const fsdp_description_t
* dsc
)
1415 return dsc
->unidentified_attributes_count
;
1419 fsdp_get_unidentified_attribute (const fsdp_description_t
* dsc
,
1422 if (!dsc
|| (index
< dsc
->unidentified_attributes_count
))
1424 return dsc
->unidentified_attributes
[index
];
1427 fsdp_encryption_method_t
1428 fsdp_get_encryption_method (const fsdp_description_t
* dsc
)
1431 return FSDP_ENCRYPTION_METHOD_UNDEFINED
;
1432 return dsc
->k_encryption_method
;
1436 fsdp_get_encryption_content (const fsdp_description_t
* dsc
)
1438 if (!dsc
|| (dsc
->k_encryption_method
== FSDP_ENCRYPTION_METHOD_UNDEFINED
))
1440 return dsc
->k_encryption_content
;
1444 fsdp_get_str_att (const fsdp_description_t
* dsc
, fsdp_session_str_att_t att
)
1446 /*TODO: change these individual attributes with a table, thus
1447 avoiding this slow switch */
1455 case FSDP_SESSION_STR_ATT_CATEGORY
:
1456 result
= dsc
->a_category
;
1458 case FSDP_SESSION_STR_ATT_KEYWORDS
:
1459 result
= dsc
->a_keywords
;
1461 case FSDP_SESSION_STR_ATT_TOOL
:
1462 result
= dsc
->a_tool
;
1464 case FSDP_SESSION_STR_ATT_CHARSET
:
1465 result
= dsc
->a_charset
;
1474 fsdp_get_sdplang_count (const fsdp_description_t
* dsc
)
1478 return dsc
->a_sdplangs_count
;
1482 fsdp_get_sdplang (const fsdp_description_t
* dsc
, unsigned int index
)
1484 if ((!dsc
) || (index
>= dsc
->a_sdplangs_count
))
1486 return dsc
->a_sdplangs
[index
];
1490 fsdp_get_control_count (const fsdp_description_t
* dsc
)
1494 return dsc
->a_controls_count
;
1498 fsdp_get_control (const fsdp_description_t
* dsc
, unsigned int index
)
1500 if ((!dsc
) || (index
>= dsc
->a_controls_count
))
1502 return dsc
->a_controls
[index
];
1506 fsdp_get_range (const fsdp_description_t
* dsc
)
1508 return dsc
->a_range
;
1511 fsdp_sendrecv_mode_t
1512 fsdp_get_sendrecv_mode (const fsdp_description_t
* dsc
)
1515 return FSDP_SENDRECV_UNDEFINED
;
1516 return dsc
->a_sendrecv_mode
;
1520 fsdp_get_session_type (const fsdp_description_t
* dsc
)
1523 return FSDP_SESSION_TYPE_UNDEFINED
;
1528 fsdp_get_media_count (const fsdp_description_t
* dsc
)
1532 return dsc
->media_announcements_count
;
1535 const fsdp_media_description_t
*
1536 fsdp_get_media (const fsdp_description_t
* dsc
, unsigned int index
)
1538 if ((index
>= dsc
->media_announcements_count
))
1540 return dsc
->media_announcements
[index
];
1544 fsdp_get_media_type (const fsdp_media_description_t
* dsc
)
1547 return FSDP_MEDIA_UNDEFINED
;
1548 return dsc
->media_type
;
1552 fsdp_get_media_port (const fsdp_media_description_t
* dsc
)
1560 fsdp_get_media_port_count (const fsdp_media_description_t
* dsc
)
1564 return dsc
->port_count
;
1567 fsdp_transport_protocol_t
1568 fsdp_get_media_transport_protocol (const fsdp_media_description_t
* dsc
)
1571 return FSDP_TP_UNDEFINED
;
1572 return dsc
->transport
;
1576 fsdp_get_media_formats_count (const fsdp_media_description_t
* dsc
)
1580 return dsc
->formats_count
;
1584 fsdp_get_media_format (const fsdp_media_description_t
* dsc
,
1587 if (!dsc
|| (index
< dsc
->formats_count
- 1))
1589 return dsc
->formats
[index
];
1593 fsdp_get_media_title (const fsdp_media_description_t
* dsc
)
1597 return dsc
->i_title
;
1601 fsdp_get_media_network_type (const fsdp_media_description_t
* dsc
)
1604 return FSDP_NETWORK_TYPE_UNDEFINED
;
1605 return dsc
->c_network_type
;
1609 fsdp_get_media_address_type (const fsdp_media_description_t
* dsc
)
1612 return FSDP_ADDRESS_TYPE_UNDEFINED
;
1613 return dsc
->c_address_type
;
1617 fsdp_get_media_address (const fsdp_media_description_t
* dsc
)
1621 return dsc
->c_address
.address
;
1625 fsdp_get_media_address_ttl (const fsdp_media_description_t
* mdsc
)
1629 return mdsc
->c_address
.address_ttl
;
1633 fsdp_get_media_address_count (const fsdp_media_description_t
* mdsc
)
1637 return mdsc
->c_address
.address_count
;
1640 fsdp_bw_modifier_type_t
1641 fsdp_get_media_bw_modifier_type (const fsdp_media_description_t
* dsc
,
1644 if (!dsc
|| (index
>= dsc
->bw_modifiers_count
))
1645 return FSDP_BW_MOD_TYPE_UNDEFINED
;
1646 return dsc
->bw_modifiers
[index
].b_mod_type
;
1650 fsdp_get_media_bw_modifier_type_unknown (const fsdp_media_description_t
* dsc
,
1653 if (!dsc
|| (index
>= dsc
->bw_modifiers_count
) ||
1654 (FSDP_BW_MOD_TYPE_UNKNOWN
!= dsc
->bw_modifiers
[index
].b_mod_type
))
1656 return dsc
->bw_modifiers
[index
].b_unknown_bw_modt
;
1660 fsdp_get_media_bw_value (const fsdp_media_description_t
* dsc
,
1663 if (!dsc
|| (index
>= dsc
->bw_modifiers_count
))
1665 return dsc
->bw_modifiers
[index
].b_value
;
1668 fsdp_encryption_method_t
1669 fsdp_get_media_encryption_method (const fsdp_media_description_t
* dsc
)
1672 return FSDP_ENCRYPTION_METHOD_UNDEFINED
;
1673 return dsc
->k_encryption_method
;
1677 fsdp_get_media_encryption_content (const fsdp_media_description_t
* dsc
)
1681 return dsc
->k_encryption_content
;
1685 fsdp_get_media_ptime (const fsdp_media_description_t
* dsc
)
1689 return dsc
->a_ptime
;
1693 fsdp_get_media_maxptime (const fsdp_media_description_t
* dsc
)
1697 return dsc
->a_maxptime
;
1701 fsdp_get_media_rtpmap_count (const fsdp_media_description_t
* mdsc
)
1705 return mdsc
->a_rtpmaps_count
;
1709 fsdp_get_media_rtpmap_payload_type (const fsdp_media_description_t
* mdsc
,
1712 if (!mdsc
|| (index
>= mdsc
->a_rtpmaps_count
))
1714 return mdsc
->a_rtpmaps
[index
]->pt
;
1718 fsdp_get_media_rtpmap_encoding_name (const fsdp_media_description_t
* mdsc
,
1721 if (!mdsc
|| (index
>= mdsc
->a_rtpmaps_count
))
1723 return mdsc
->a_rtpmaps
[index
]->encoding_name
;
1727 fsdp_get_media_rtpmap_clock_rate (const fsdp_media_description_t
* mdsc
,
1730 if (!mdsc
|| (index
>= mdsc
->a_rtpmaps_count
))
1732 return mdsc
->a_rtpmaps
[index
]->clock_rate
;
1736 fsdp_get_media_rtpmap_encoding_parameters (const fsdp_description_t
* mdsc
,
1739 if (!mdsc
|| (index
>= mdsc
->a_rtpmaps_count
))
1741 return mdsc
->a_rtpmaps
[index
]->parameters
;
1745 fsdp_get_media_sdplang_count (const fsdp_media_description_t
* mdsc
)
1749 return mdsc
->a_sdplangs_count
;
1753 fsdp_get_media_sdplang (const fsdp_media_description_t
* mdsc
,
1756 if (!mdsc
|| (index
>= mdsc
->a_sdplangs_count
))
1758 return mdsc
->a_sdplangs
[index
];
1762 fsdp_get_media_lang_count (const fsdp_media_description_t
* mdsc
)
1766 return mdsc
->a_langs_count
;
1770 fsdp_get_media_lang (const fsdp_media_description_t
* mdsc
,
1773 if (!mdsc
|| (index
>= mdsc
->a_langs_count
))
1775 return mdsc
->a_langs
[index
];
1779 fsdp_get_media_control_count (const fsdp_media_description_t
* mdsc
)
1783 return mdsc
->a_controls_count
;
1787 fsdp_get_media_control (const fsdp_media_description_t
* mdsc
,
1790 if (!mdsc
|| (index
>= mdsc
->a_controls_count
))
1792 return mdsc
->a_controls
[index
];
1796 fsdp_get_media_range (const fsdp_media_description_t
* mdsc
)
1798 return mdsc
->a_range
;
1802 fsdp_get_media_fmtp_count (const fsdp_media_description_t
* mdsc
)
1806 return mdsc
->a_fmtps_count
;
1810 fsdp_get_media_fmtp (const fsdp_media_description_t
* mdsc
,
1813 if (!mdsc
|| (index
>= mdsc
->a_fmtps_count
))
1815 return mdsc
->a_fmtps
[index
];
1819 fsdp_get_media_orient (const fsdp_media_description_t
* dsc
)
1822 return FSDP_ORIENT_UNDEFINED
;
1823 return dsc
->a_orient
;
1826 fsdp_sendrecv_mode_t
1827 fsdp_get_media_sendrecv (const fsdp_media_description_t
* dsc
)
1830 return FSDP_SENDRECV_UNDEFINED
;
1831 return dsc
->a_sendrecv_mode
;
1835 fsdp_get_media_framerate (const fsdp_media_description_t
* dsc
)
1839 return dsc
->a_framerate
;
1843 fsdp_get_media_quality (const fsdp_media_description_t
* dsc
)
1847 return dsc
->a_quality
;
1851 fsdp_get_media_rtcp_port (const fsdp_media_description_t
* dsc
)
1855 return dsc
->a_rtcp_port
;
1859 fsdp_get_media_rtcp_network_type (const fsdp_media_description_t
* dsc
)
1862 return FSDP_NETWORK_TYPE_UNDEFINED
;
1863 return dsc
->a_rtcp_network_type
;
1867 fsdp_get_media_rtcp_address_type (const fsdp_media_description_t
* dsc
)
1870 return FSDP_ADDRESS_TYPE_UNDEFINED
;
1871 return dsc
->a_rtcp_address_type
;
1875 fsdp_get_media_rtcp_address (const fsdp_media_description_t
* dsc
)
1879 return dsc
->a_rtcp_address
;
1883 fsdp_get_media_unidentified_attribute_count (const fsdp_media_description_t
1888 return mdsc
->unidentified_attributes_count
;
1892 fsdp_get_media_unidentified_attribute (const fsdp_media_description_t
* mdsc
,
1895 if (!mdsc
|| (index
< mdsc
->unidentified_attributes_count
))
1897 return mdsc
->unidentified_attributes
[index
];