diff options
Diffstat (limited to 'stream/freesdp/parser.c')
-rw-r--r-- | stream/freesdp/parser.c | 1890 |
1 files changed, 0 insertions, 1890 deletions
diff --git a/stream/freesdp/parser.c b/stream/freesdp/parser.c deleted file mode 100644 index cb093c2bae..0000000000 --- a/stream/freesdp/parser.c +++ /dev/null @@ -1,1890 +0,0 @@ -/* - This file is part of FreeSDP - Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp@altern.org> - - FreeSDP is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Benjamin Zores, (C) 2006 - added support in parser for the a=control: lines. - added support in parser for the a=range: lines. -*/ - -/** - * @file parser.c - * - * @short Parsing module implementation. - * - * This file implements the parsing routine <code>fsdp_parse</code> - * and the <code>fsdp_get_xxxx</code> routines that allow to get the - * session properties from a session description object build through - * the application of <code>fsdp_parse</code> to a textual SDP session - * description. - **/ - -#include "parserpriv.h" - -/** - * \brief find the start of the next line - * \param c pointer to current position in string - * \return pointer to start of next line or NULL if illegal (i.e. - * a '\r' is not followed by a '\n' - */ -static const char *next_line(const char *c) { - c += strcspn(c, "\n\r"); - if (*c == 0) return c; - if (*c == '\r') c++; - if (*c == '\n') - return c + 1; - return NULL; -} - -/** - * Moves the <code>c<code> pointer up to the beginning of the next - * line. - * - * @param c char pointer to pointer - * @retval FSDPE_ILLEGAL_CHARACTER, when an illegal '\r' character - * (not followed by a '\n') is found, returns - */ -#define NEXT_LINE(c) do { if (!(c = next_line(c))) return FSDPE_ILLEGAL_CHARACTER; } while (0); - -fsdp_error_t -fsdp_parse (const char *text_description, fsdp_description_t * dsc) -{ - fsdp_error_t result; - const char *p = text_description, *p2; - unsigned int j; - /* temps for sscanf */ - const unsigned int TEMPCHARS = 6; - char fsdp_buf[TEMPCHARS][MAXSHORTFIELDLEN]; - char longfsdp_buf[MAXLONGFIELDLEN]; - const unsigned int TEMPINTS = 2; - unsigned long int wuint[TEMPINTS]; - - if ((NULL == text_description) || (NULL == dsc)) - return FSDPE_INVALID_PARAMETER; - - /***************************************************************************/ - /* A) parse session-level description */ - /***************************************************************************/ - - /* `v=' line (protocol version) */ - /* according to the RFC, only `v=0' is valid */ - if (sscanf (p, "v=%1lu", &wuint[0])) - { - if (wuint[0] != 0) - return FSDPE_INVALID_VERSION; - } - else - { - return FSDPE_MISSING_VERSION; - } - NEXT_LINE (p); - - /* `o=' line (owner/creator and session identifier) */ - /* o=<username> <session id> <version> <network type> <address type> - <address> */ - if (!strncmp (p, "o=", 2)) - { - p += 2; - /* note that the following max lengths may vary in the future and - are quite arbitary */ - if (sscanf - (p, - "%" MSFLENS "[\x21-\xFF] %" MSFLENS "[0-9] %" MSFLENS - "[0-9] %2s %3s %" MSFLENS "s", fsdp_buf[0], fsdp_buf[1], - fsdp_buf[2], fsdp_buf[3], fsdp_buf[4], fsdp_buf[5]) != 6) - return FSDPE_INVALID_OWNER; - dsc->o_username = strdup (fsdp_buf[0]); - dsc->o_session_id = strdup (fsdp_buf[1]); - dsc->o_announcement_version = strdup (fsdp_buf[2]); - if (!strncmp (fsdp_buf[3], "IN", 2)) - { - dsc->o_network_type = FSDP_NETWORK_TYPE_INET; - if (!strncmp (fsdp_buf[4], "IP4", 3)) - dsc->o_address_type = FSDP_ADDRESS_TYPE_IPV4; - else if (!strncmp (fsdp_buf[4], "IP6", 3)) - dsc->o_address_type = FSDP_ADDRESS_TYPE_IPV6; - else - return FSDPE_INVALID_OWNER; - } - else - { - return FSDPE_INVALID_OWNER; - } - /* TODO? check valid unicast address/FQDN */ - dsc->o_address = strdup (fsdp_buf[5]); - } - else - { - return FSDPE_MISSING_OWNER; - } - NEXT_LINE (p); - - /* `s=' line (session name) -note that the name string cannot be empty */ - /* s=<session name> */ - if (!strncmp (p, "s=", 2)) - { - if (sscanf (p, "s=%" MLFLENS "[^\r\n]", longfsdp_buf) < 1) - return FSDPE_EMPTY_NAME; - dsc->s_name = strdup (longfsdp_buf); - } - else - { - return FSDPE_MISSING_NAME; - } - NEXT_LINE (p); - - /* `i=' line (session information) [optional] */ - /* i=<session description> */ - if (!strncmp (p, "i=", 2) - && sscanf (p, "i=%" MLFLENS "[^\r\n]", longfsdp_buf)) - { - dsc->i_information = strdup (longfsdp_buf); - NEXT_LINE (p); - } - else - { - /* (optional) information absent */ - } - - /* `u=' line (URI of description) [optional] */ - /* u=<URI> */ - if (!strncmp (p, "u=", 2) - && sscanf (p, "u=%" MLFLENS "[^\r\n]", longfsdp_buf)) - { - /* TODO? check valid uri */ - dsc->u_uri = strdup (longfsdp_buf); - NEXT_LINE (p); - } - else - { - /* (optional) uri absent */ - } - - /* `e=' lines (email address) [zero or more] */ - /* e=<email address> */ - p2 = p; - j = 0; - while (!strncmp (p2, "e=", 2)) - { - /* First, count how many emails are there */ - j++; - NEXT_LINE (p2); - } - dsc->emails_count = j; - if (dsc->emails_count > 0) - { - /* Then, build the array of emails */ - dsc->emails = calloc (j, sizeof (const char *)); - for (j = 0; j < dsc->emails_count; j++) - { - sscanf (p, "e=%" MLFLENS "[^\r\n]", longfsdp_buf); - /* TODO? check valid email-address. */ - dsc->emails[j] = strdup (longfsdp_buf); - NEXT_LINE (p); - } - } - - /* `p=' lines (phone number) [zero or more] */ - /* p=<phone number> */ - j = 0; - /* assert ( p2 == p ); */ - while (!strncmp (p2, "p=", 2)) - { - j++; - NEXT_LINE (p2); - } - dsc->phones_count = j; - if (dsc->phones_count > 0) - { - dsc->phones = calloc (j, sizeof (const char *)); - for (j = 0; j < dsc->phones_count; j++) - { - sscanf (p, "p=%" MLFLENS "[^\r\n]", longfsdp_buf); - /* TODO? check valid phone-number. */ - dsc->phones[j] = strdup (longfsdp_buf); - NEXT_LINE (p); - } - } - - /* `c=' line (connection information - not required if included in all media) [optional] */ - /* c=<network type> <address type> <connection address> */ - result = fsdp_parse_c (&p, &(dsc->c_network_type), &(dsc->c_address_type), - &(dsc->c_address)); - if (FSDPE_OK != result) - return result; - - /* `b=' lines (bandwidth information) [optional] */ - /* b=<modifier>:<bandwidth-value> */ - result = - fsdp_parse_b (&p, &(dsc->bw_modifiers), &(dsc->bw_modifiers_count)); - if (FSDPE_OK != result) - return result; - - /* A.1) Time descriptions: */ - - /* `t=' lines (time the session is active) [1 or more] */ - /* t=<start time> <stop time> */ - j = 0; - p2 = p; - while (!strncmp (p2, "t=", 2)) - { - j++; - NEXT_LINE (p2); - while (!strncmp (p2, "r=", 2)) - NEXT_LINE (p2); - } - dsc->time_periods_count = j; - if (dsc->time_periods_count == 0) - return FSDPE_MISSING_TIME; - dsc->time_periods = calloc (dsc->time_periods_count, - sizeof (fsdp_time_period_t *)); - for (j = 0; j < dsc->time_periods_count; j++) - { - unsigned int h = 0; - if (sscanf (p, "t=%10lu %10lu", &wuint[0], &wuint[1]) != 2) - { - /* not all periods have been successfully parsed */ - dsc->time_periods_count = j; - return FSDPE_INVALID_TIME; - } - dsc->time_periods[j] = calloc (1, sizeof (fsdp_time_period_t)); - - /* convert from NTP to time_t time */ - if (wuint[0] != 0) - wuint[0] -= NTP_EPOCH_OFFSET; - if (wuint[1] != 0) - wuint[1] -= NTP_EPOCH_OFFSET; - dsc->time_periods[j]->start = wuint[0]; - dsc->time_periods[j]->stop = wuint[1]; - NEXT_LINE (p); - - /* `r' lines [zero or more repeat times for each t=] */ - /*r=<repeat interval> <active duration> <list of offsets from - start-time> */ - p2 = p; - while (!strncmp (p2, "r=", 2)) - { - h++; - NEXT_LINE (p2); - } - dsc->time_periods[j]->repeats_count = h; - if (h > 0) - { - unsigned int index2 = 0; - dsc->time_periods[j]->repeats = - calloc (h, sizeof (fsdp_repeat_t *)); - for (h = 0; h < dsc->time_periods[j]->repeats_count; h++) - { - if (sscanf (p, "r=%10s %10s %" MLFLENS "[^\r\n]", - fsdp_buf[0], fsdp_buf[1], longfsdp_buf) == 3) - { - fsdp_repeat_t *repeat; - dsc->time_periods[j]->repeats[h] = - calloc (1, sizeof (fsdp_repeat_t)); - repeat = dsc->time_periods[j]->repeats[h]; - /* get interval, duration and list of offsets */ - result = - fsdp_repeat_time_to_uint (fsdp_buf[0], - &(repeat->interval)); - if (result == FSDPE_OK) - { - result = - fsdp_repeat_time_to_uint (fsdp_buf[1], - &(repeat->duration)); - if (result == FSDPE_OK) - { - unsigned int k = 1; - const char *i = longfsdp_buf; - while (NULL != (i = strchr (i, ' '))) - { - k++; - if (NULL != i) - i++; - } - repeat->offsets_count = k; - repeat->offsets = calloc (k, sizeof (time_t)); - i = longfsdp_buf; - for (k = 0; - (k < repeat->offsets_count) - && (result == FSDPE_OK); k++) - { - result = - fsdp_repeat_time_to_uint (i, - &(repeat-> - offsets[k])); - i = strchr (i, ' '); - if (NULL != i) - i++; - } - if (k < repeat->offsets_count) - { - /* there where invalid repeat offsets */ - dsc->time_periods[j]->repeats_count = k; - return FSDPE_INVALID_REPEAT; - } - } - } - if (result != FSDPE_OK) - { - /* not all repeats have been succesfully parsed */ - dsc->time_periods[j]->repeats_count = h; - return FSDPE_INVALID_REPEAT; - } - NEXT_LINE (p); - } - else - { - /* not all repeats have been succesfully parsed */ - dsc->time_periods[j]->repeats_count = h; - return FSDPE_INVALID_REPEAT; - } - index2++; - } - } - } - - /* `z=' line (time zone adjustments) [zero or more] */ - /* z=<adjustment time> <offset> <adjustment time> <offset> .... */ - if (!strncmp (p, "z=", 2)) - { - if (sscanf (p, "z=%" MLFLENS "[^\r\n]", longfsdp_buf)) - { - /* TODO: guess how many pairs are there and process them */ - dsc->timezone_adj = strdup (longfsdp_buf); - NEXT_LINE (p); - } - else - { - return FSDPE_INVALID_TIMEZONE; - } - } - - /* `k=' line (encryption key) [optional] */ - /* k=<method> - k=<method>:<encryption key> */ - result = fsdp_parse_k (&p, &(dsc->k_encryption_method), - &(dsc->k_encryption_content)); - if (result != FSDPE_OK) - return result; - - /* A.2) Attributes */ - /* `a=' lines (session attribute) [0 or more] */ - /* a=<attribute> - a=<attribute>:<value> */ - while (!strncmp (p, "a=", 2)) - { - /* The "9" length specifier of the first string is subject to - changes */ - if (sscanf - (p, "a=%9[^:\r\n]:%" MSFLENS "[^\r\n]", fsdp_buf[0], - fsdp_buf[1]) == 2) - { - /* session-level value attributes */ - if (!strncmp (fsdp_buf[0], "cat", 3)) - dsc->a_category = strdup (fsdp_buf[1]); - else if (!strncmp (fsdp_buf[0], "keywds", 6)) - dsc->a_keywords = strdup (fsdp_buf[1]); - else if (!strncmp (fsdp_buf[0], "tool", 4)) - dsc->a_keywords = strdup (fsdp_buf[1]); - else if (!strncmp (fsdp_buf[0], "rtpmap", 6)) - fsdp_parse_rtpmap (&(dsc->a_rtpmaps), - &(dsc->a_rtpmaps_count), fsdp_buf[1]); - else if (!strncmp (fsdp_buf[0], "type", 4)) - { - if (!strncmp (fsdp_buf[1], "broadcast", 9)) - dsc->a_type = FSDP_SESSION_TYPE_BROADCAST; - else if (!strncmp (fsdp_buf[1], "meeting", 7)) - dsc->a_type = FSDP_SESSION_TYPE_MEETING; - else if (!strncmp (fsdp_buf[1], "moderated", 9)) - dsc->a_type = FSDP_SESSION_TYPE_MODERATED; - else if (!strncmp (fsdp_buf[1], "test", 4)) - dsc->a_type = FSDP_SESSION_TYPE_TEST; - else if (!strncmp (fsdp_buf[1], "H332", 4)) - dsc->a_type = FSDP_SESSION_TYPE_H332; - else - return FSDPE_INVALID_SESSION_TYPE; - } - else if (!strncmp (fsdp_buf[0], "charset", 7)) - dsc->a_charset = strdup (fsdp_buf[1]); - else if (!strncmp (fsdp_buf[0], "sdplang", 7)) - { - if (NULL == dsc->a_sdplangs) - { - dsc->a_sdplangs_count = 0; - dsc->a_sdplangs = - calloc (SDPLANGS_MAX_COUNT, sizeof (char *)); - } - if (dsc->a_sdplangs_count < SDPLANGS_MAX_COUNT) - { - dsc->a_sdplangs[dsc->a_sdplangs_count] = - strdup (fsdp_buf[1]); - dsc->a_sdplangs_count++; - } - } - else if (!strncmp (fsdp_buf[0], "lang", 4)) - { - if (NULL == dsc->a_langs) - { - dsc->a_langs_count = 0; - dsc->a_langs = calloc (SDPLANGS_MAX_COUNT, sizeof (char *)); - } - if (dsc->a_langs_count < SDPLANGS_MAX_COUNT) - { - dsc->a_langs[dsc->a_langs_count] = strdup (fsdp_buf[1]); - dsc->a_langs_count++; - } - } - else if (!strncmp (fsdp_buf[0], "control", 7)) - { - if (NULL == dsc->a_controls) - { - dsc->a_controls_count = 0; - dsc->a_controls = - calloc (SDPCONTROLS_MAX_COUNT, sizeof (char *)); - } - if (dsc->a_controls_count < SDPCONTROLS_MAX_COUNT) - { - dsc->a_controls[dsc->a_controls_count] = - strdup (fsdp_buf[1]); - dsc->a_controls_count++; - } - } - else if (!strncmp (fsdp_buf[0], "range", 5)) - { - free (dsc->a_range); - dsc->a_range = strdup (fsdp_buf[1]); - } - else - { - /* ignore unknown attributes, but provide access to them */ - *longfsdp_buf = '\0'; - strncat (longfsdp_buf, fsdp_buf[0], MAXLONGFIELDLEN-1); - strncat (longfsdp_buf, ":", MAXLONGFIELDLEN-strlen(longfsdp_buf)-1); - strncat (longfsdp_buf, fsdp_buf[1], MAXLONGFIELDLEN-strlen(longfsdp_buf)-1); - if (NULL == dsc->unidentified_attributes) - { - dsc->unidentified_attributes_count = 0; - dsc->unidentified_attributes = - calloc (UNIDENTIFIED_ATTRIBUTES_MAX_COUNT, - sizeof (char *)); - } - if (dsc->unidentified_attributes_count < - UNIDENTIFIED_ATTRIBUTES_MAX_COUNT) - { - dsc->unidentified_attributes - [dsc->unidentified_attributes_count] = - strdup (longfsdp_buf); - dsc->unidentified_attributes_count++; - } - } - NEXT_LINE (p); - } - else if (sscanf (p, "a=%20s", fsdp_buf[0]) == 1) - { - /* session-level property attributes */ - if (!strncmp (fsdp_buf[0], "recvonly", 8)) - dsc->a_sendrecv_mode = FSDP_SENDRECV_RECVONLY; - else if (!strncmp (fsdp_buf[0], "sendonly", 8)) - dsc->a_sendrecv_mode = FSDP_SENDRECV_SENDONLY; - else if (!strncmp (fsdp_buf[0], "inactive", 8)) - dsc->a_sendrecv_mode = FSDP_SENDRECV_INACTIVE; - else if (!strncmp (fsdp_buf[0], "sendrecv", 8)) - dsc->a_sendrecv_mode = FSDP_SENDRECV_SENDRECV; - else - { - /* ignore unknown attributes, but provide access to them */ - *longfsdp_buf = '\0'; - strncat (longfsdp_buf, fsdp_buf[0], MAXLONGFIELDLEN-1); - if (NULL == dsc->unidentified_attributes) - { - dsc->unidentified_attributes_count = 0; - dsc->unidentified_attributes = - calloc (UNIDENTIFIED_ATTRIBUTES_MAX_COUNT, - sizeof (char *)); - } - if (dsc->unidentified_attributes_count < - UNIDENTIFIED_ATTRIBUTES_MAX_COUNT) - { - dsc->unidentified_attributes - [dsc->unidentified_attributes_count] = - strdup (longfsdp_buf); - dsc->unidentified_attributes_count++; - } - } - NEXT_LINE (p); - } - else - return FSDPE_INVALID_ATTRIBUTE; - } - - /***************************************************************************/ - /* B) parse media-level descriptions */ - /***************************************************************************/ - p2 = p; - j = 0; - while ((*p2 != '\0') && !strncmp (p2, "m=", 2)) - { - char c; - j++; - NEXT_LINE (p2); - while (sscanf (p2, "%c=", &c) == 1) - { - if (c == 'i' || c == 'c' || c == 'b' || c == 'k' || c == 'a') - { - NEXT_LINE (p2); - } - else if (c == 'm') - { - break; - } - else - { - return FSDPE_INVALID_LINE; - } - } - } - dsc->media_announcements_count = j; - if (dsc->media_announcements_count == 0) - { - ; - /*return FSDPE_MISSING_MEDIA; */ - } - else - { /* dsc->media_announcements_count > 0 */ - dsc->media_announcements = - calloc (j, sizeof (fsdp_media_announcement_t *)); - for (j = 0; j < dsc->media_announcements_count; j++) - { - fsdp_media_announcement_t *media = NULL; - /* `m=' line (media name, transport address and format list) */ - /* m=<media> <port> <transport> <fmt list> */ - /* The max. string lengths are subject to change */ - if (sscanf (p, "m=%11s %8s %7s %" MLFLENS "[^\r\n]", - fsdp_buf[0], fsdp_buf[1], fsdp_buf[2], - longfsdp_buf) != 4) - { - return FSDPE_INVALID_MEDIA; - } - else - { - dsc->media_announcements[j] = - calloc (1, sizeof (fsdp_media_announcement_t)); - media = dsc->media_announcements[j]; - if (!strncmp (fsdp_buf[0], "audio", 5)) - media->media_type = FSDP_MEDIA_AUDIO; - else if (!strncmp (fsdp_buf[0], "video", 5)) - media->media_type = FSDP_MEDIA_VIDEO; - else if (!strncmp (fsdp_buf[0], "application", 11)) - media->media_type = FSDP_MEDIA_APPLICATION; - else if (!strncmp (fsdp_buf[0], "data", 4)) - media->media_type = FSDP_MEDIA_DATA; - else if (!strncmp (fsdp_buf[0], "control", 7)) - media->media_type = FSDP_MEDIA_CONTROL; - else - return FSDPE_UNKNOWN_MEDIA_TYPE; - { /* try to get port specification as port/number */ - char *slash; - if ((slash = strchr (fsdp_buf[1], '/'))) - { - *slash = '\0'; - slash++; - media->port = strtol (fsdp_buf[1], NULL, 10); - media->port_count = strtol (slash, NULL, 10); - } - else - { - media->port = strtol (fsdp_buf[1], NULL, 10); - media->port_count = 0; - } - } - if (!strncmp (fsdp_buf[2], "RTP/AVP", 7)) - media->transport = FSDP_TP_RTP_AVP; - else if (!strncmp (fsdp_buf[2], "udp", 3)) - media->transport = FSDP_TP_UDP; - else if (!strncmp (fsdp_buf[2], "TCP", 3)) - media->transport = FSDP_TP_TCP; - else if (!strncmp (fsdp_buf[2], "UDPTL", 5)) - media->transport = FSDP_TP_UDPTL; - else if (!strncmp (fsdp_buf[2], "vat", 3)) - media->transport = FSDP_TP_VAT; - else if (!strncmp (fsdp_buf[2], "rtp", 3)) - media->transport = FSDP_TP_OLD_RTP; - else - return FSDPE_UNKNOWN_MEDIA_TRANSPORT; - { - unsigned int k = 0; - char *s = longfsdp_buf; - while (NULL != (s = strchr (s, ' '))) - { - k++; - if (NULL != s) - s++; - } - k++; /* when there is no space left, count the last format */ - media->formats_count = k; - media->formats = calloc (k, sizeof (char *)); - s = longfsdp_buf; - for (k = 0; k < media->formats_count; k++) - { - char *space = strchr (s, ' '); - if (NULL != space) - *space = '\0'; - media->formats[k] = strdup (s); - s = space + 1; - } - } - NEXT_LINE (p); - } - - /* `i=' line (media title) [optional] */ - /* i=<media title> */ - if (!strncmp (p, "i=", 2) - && sscanf (p, "i=%" MLFLENS "[^\r\n]", longfsdp_buf)) - { - media->i_title = strdup (longfsdp_buf); - NEXT_LINE (p); - } - else - { - /* (optional) information absent */ - } - - /* `c=' line (connection information - overrides session-level - line) [optional if provided at session-level] */ - /* c=<network type> <address type> <connection address> */ - result = fsdp_parse_c (&p, &(media->c_network_type), - &(media->c_address_type), - &(media->c_address)); - if (result != FSDPE_OK) - return result; - - /* `b=' lines (bandwidth information) [optional] */ - /* b=<modifier>:<bandwidth-value> */ - result = fsdp_parse_b (&p, &(media->bw_modifiers), - &(media->bw_modifiers_count)); - if (FSDPE_OK != result) - return result; - - /* `k=' line (encryption key) [optional] */ - /* k=<method> - k=<method>:<encryption key> */ - result = fsdp_parse_k (&p, &(media->k_encryption_method), - &(media->k_encryption_content)); - if (result != FSDPE_OK) - return result; - - /* B.1) Attributes */ - - /* `a=' lines (zero or more media attribute lines) [optional] */ - /* a=<attribute> - a=<attribute>:<value> */ - while (!strncmp (p, "a=", 2)) - { - if (sscanf - (p, "a=%9[^:\r\n]:%" MLFLENS "[^\r\n]", fsdp_buf[0], - longfsdp_buf) == 2) - { - /* media-level value attributes */ - if (!strncmp (fsdp_buf[0], "ptime", 5)) - media->a_ptime = strtoul (longfsdp_buf, NULL, 10); - else if (!strncmp (fsdp_buf[0], "maxptime", 8)) - media->a_maxptime = strtoul (longfsdp_buf, NULL, 10); - else if (!strncmp (fsdp_buf[0], "rtpmap", 6)) - fsdp_parse_rtpmap (&(media->a_rtpmaps), - &(media->a_rtpmaps_count), - longfsdp_buf); - else if (!strncmp (fsdp_buf[0], "orient", 6)) - { - if (!strncmp (longfsdp_buf, "portrait", 8)) - media->a_orient = FSDP_ORIENT_PORTRAIT; - else if (!strncmp (longfsdp_buf, "landscape", 9)) - media->a_orient = FSDP_ORIENT_LANDSCAPE; - else if (!strncmp (longfsdp_buf, "seascape", 9)) - media->a_orient = FSDP_ORIENT_SEASCAPE; - } - else if (!strncmp (fsdp_buf[0], "sdplang", 7)) - { - if (NULL == dsc->a_sdplangs) - { - media->a_sdplangs_count = 0; - media->a_sdplangs = - calloc (SDPLANGS_MAX_COUNT, sizeof (char *)); - } - if (media->a_sdplangs_count < SDPLANGS_MAX_COUNT) - { - media->a_sdplangs[dsc->a_sdplangs_count] = - strdup (longfsdp_buf); - media->a_sdplangs_count++; - } - } - else if (!strncmp (fsdp_buf[0], "lang", 4)) - { - if (NULL == dsc->a_langs) - { - media->a_langs_count = 0; - media->a_langs = - calloc (SDPLANGS_MAX_COUNT, sizeof (char *)); - } - if (media->a_langs_count < SDPLANGS_MAX_COUNT) - { - media->a_langs[dsc->a_langs_count] = - strdup (longfsdp_buf); - media->a_langs_count++; - } - } - else if (!strncmp (fsdp_buf[0], "control", 7)) - { - if (NULL == media->a_controls) - { - media->a_controls_count = 0; - media->a_controls = - calloc (SDPCONTROLS_MAX_COUNT, sizeof (char *)); - } - if (media->a_controls_count < SDPCONTROLS_MAX_COUNT) - { - media->a_controls[media->a_controls_count] = - strdup (longfsdp_buf); - media->a_controls_count++; - } - } - else if (!strncmp (fsdp_buf[0], "range", 5)) - { - free (media->a_range); - media->a_range = strdup (fsdp_buf[1]); - } - else if (!strncmp (fsdp_buf[0], "framerate", 9)) - media->a_framerate = strtod (longfsdp_buf, NULL); - else if (!strncmp (fsdp_buf[0], "fmtp", 4)) - { - if (NULL == media->a_fmtps) - { - media->a_fmtps_count = 0; - media->a_fmtps = - calloc (SDPLANGS_MAX_COUNT, sizeof (char *)); - } - if (media->a_fmtps_count < SDPLANGS_MAX_COUNT) - { - media->a_fmtps[media->a_fmtps_count] = - strdup (longfsdp_buf); - media->a_fmtps_count++; - } - } - else if (!strncmp (fsdp_buf[0], "rtcp", 4)) - { - int opts = 0; - /* rtcp attribute: a=rtcp:<port> <nettype> <addrtype> <address> */ - opts = - sscanf (longfsdp_buf, "%lu %2s %3s %" MSFLENS "s", - &wuint[0], fsdp_buf[0], fsdp_buf[1], - fsdp_buf[2]); - if (opts >= 1) - { - media->a_rtcp_port = wuint[0]; - if (opts >= 2) - { - if (!strncmp (fsdp_buf[0], "IN", 2)) - { - media->a_rtcp_network_type = - FSDP_NETWORK_TYPE_INET; - } /* else - ; TODO: define error code? */ - if (opts >= 3) - { - if (!strncmp (fsdp_buf[1], "IP4", 3)) - media->a_rtcp_address_type = - FSDP_ADDRESS_TYPE_IPV4; - else if (!strncmp (fsdp_buf[1], "IP6", 3)) - media->a_rtcp_address_type = - FSDP_ADDRESS_TYPE_IPV6; - else - return FSDPE_INVALID_CONNECTION_NETTYPE; - /*add specific code? */ - if (opts >= 4) - media->a_rtcp_address = - strdup (fsdp_buf[2]); - } - } - } - } - else - { - /* ignore unknown attributes, but provide access to them */ - *fsdp_buf[1] = '\0'; - strncat (fsdp_buf[1], fsdp_buf[0], MAXSHORTFIELDLEN-1); - strncat (fsdp_buf[1], ":", MAXSHORTFIELDLEN-strlen(fsdp_buf[1])-1); - strncat (fsdp_buf[1], longfsdp_buf, MAXSHORTFIELDLEN-strlen(fsdp_buf[1])-1); - if (NULL == media->unidentified_attributes) - { - media->unidentified_attributes_count = 0; - media->unidentified_attributes = - calloc (UNIDENTIFIED_ATTRIBUTES_MAX_COUNT, - sizeof (char *)); - } - if (media->unidentified_attributes_count < - UNIDENTIFIED_ATTRIBUTES_MAX_COUNT) - { - media->unidentified_attributes - [media->unidentified_attributes_count] = - strdup (fsdp_buf[1]); - media->unidentified_attributes_count++; - } - } - NEXT_LINE (p); - } - else if (sscanf (p, "a=%8s", fsdp_buf[0]) == 1) - { - /* media-level property attributes */ - if (!strncmp (fsdp_buf[0], "recvonly", 8)) - media->a_sendrecv_mode = FSDP_SENDRECV_RECVONLY; - else if (!strncmp (fsdp_buf[0], "sendonly", 8)) - media->a_sendrecv_mode = FSDP_SENDRECV_SENDONLY; - else if (!strncmp (fsdp_buf[0], "inactive", 8)) - media->a_sendrecv_mode = FSDP_SENDRECV_INACTIVE; - else if (!strncmp (fsdp_buf[0], "sendrecv", 8)) - media->a_sendrecv_mode = FSDP_SENDRECV_SENDRECV; - else - { - /* ignore unknown attributes, but provide access to them */ - *longfsdp_buf = '\0'; - strncat (longfsdp_buf, fsdp_buf[0], MAXLONGFIELDLEN-1); - if (NULL == media->unidentified_attributes) - { - media->unidentified_attributes_count = 0; - media->unidentified_attributes = - calloc (UNIDENTIFIED_ATTRIBUTES_MAX_COUNT, - sizeof (char *)); - } - if (media->unidentified_attributes_count < - UNIDENTIFIED_ATTRIBUTES_MAX_COUNT) - { - media->unidentified_attributes - [media->unidentified_attributes_count] = - strdup (longfsdp_buf); - media->unidentified_attributes_count++; - } - } - NEXT_LINE (p); - } - else - return FSDPE_INVALID_ATTRIBUTE; - } - } /* end of for */ - } - - /* Check c= has been given at session level or at media level for - all media */ - if (NULL == dsc->c_address.address) - { - unsigned int c; - for (c = 0; c < dsc->media_announcements_count; c++) - if (NULL == dsc->media_announcements[c]->c_address.address) - return FSDPE_MISSING_CONNECTION_INFO; - } - - /* finish */ - if (*p == '\0') - return FSDPE_OK; - else - return FSDPE_OVERFILLED; -} - -static fsdp_error_t -fsdp_parse_c (const char **p, fsdp_network_type_t * ntype, - fsdp_address_type_t * atype, - fsdp_connection_address_t * address) -{ - const unsigned int TEMPCHARS = 3; - char fsdp_buf[TEMPCHARS][MAXSHORTFIELDLEN]; - - if (!strncmp (*p, "c=", 2)) - { - if (sscanf (*p, "c=%2s %3s %" MSFLENS "s", - fsdp_buf[0], fsdp_buf[1], fsdp_buf[2])) - { - if (!strncmp (fsdp_buf[0], "IN", 2)) - { - *ntype = FSDP_NETWORK_TYPE_INET; - if (!strncmp (fsdp_buf[1], "IP4", 3)) - *atype = FSDP_ADDRESS_TYPE_IPV4; - else if (!strncmp (fsdp_buf[1], "IP6", 3)) - *atype = FSDP_ADDRESS_TYPE_IPV6; - else - return FSDPE_INVALID_CONNECTION_NETTYPE; - } - else - { - return FSDPE_INVALID_CONNECTION_ADDRTYPE; - } - { - char *slash = strchr (fsdp_buf[2], '/'); - if (NULL == slash) - { - address->address = strdup (fsdp_buf[2]); - address->address_ttl = 0; - address->address_count = 0; - } - else - { - /* address is IP4 multicast */ - char *slash2; - *slash = '\0'; - slash++; - address->address = strdup (fsdp_buf[2]); - slash2 = strchr (slash + 1, '/'); - if (NULL == slash2) - { - address->address_ttl = strtol (slash, NULL, 10); - address->address_count = 0; - } - else - { - *slash2 = '\0'; - slash2++; - address->address_ttl = strtol (slash, NULL, 10); - address->address_count = strtol (slash2, NULL, 10); - } - } - } - NEXT_LINE (*p); - } - else - { - return FSDPE_INVALID_CONNECTION; - } - } - return FSDPE_OK; -} - -static fsdp_error_t -fsdp_parse_b (const char **p, fsdp_bw_modifier_t ** bw_modifiers, - unsigned int *bw_modifiers_count) -{ - char fsdp_buf[MAXSHORTFIELDLEN]; - unsigned long int wuint; - unsigned int i = 0; - const char *lp = *p; - - /* count b= lines */ - while (!strncmp (lp, "b=", 2)) - { - NEXT_LINE (lp); - i++; - } - *bw_modifiers = calloc (i, sizeof (fsdp_bw_modifier_t)); - *bw_modifiers_count = i; - - while (i > 0) - { - unsigned int index = *bw_modifiers_count - i; - if (2 == sscanf (*p, "b=%20[^:\r\n]:%lu", fsdp_buf, &wuint)) - { - if (!strncmp (fsdp_buf, "CT", 2)) - (*bw_modifiers)[index].b_mod_type = - FSDP_BW_MOD_TYPE_CONFERENCE_TOTAL; - else if (!strncmp (fsdp_buf, "AS", 2)) - (*bw_modifiers)[index].b_mod_type = - FSDP_BW_MOD_TYPE_APPLICATION_SPECIFIC; - else if (!strncmp (fsdp_buf, "RS", 2)) - (*bw_modifiers)[index].b_mod_type = FSDP_BW_MOD_TYPE_RTCP_SENDERS; - else if (!strncmp (fsdp_buf, "RR", 2)) - (*bw_modifiers)[index].b_mod_type = - FSDP_BW_MOD_TYPE_RTCP_RECEIVERS; - else - { - (*bw_modifiers)[index].b_mod_type = FSDP_BW_MOD_TYPE_UNKNOWN; - (*bw_modifiers)[index].b_unknown_bw_modt = - (char *) strdup (fsdp_buf); - } - (*bw_modifiers)[index].b_value = wuint; - NEXT_LINE (*p); - } - else - { - *bw_modifiers_count -= i; - return FSDPE_INVALID_BANDWIDTH; - } - i--; - } - return FSDPE_OK; -} - -static fsdp_error_t -fsdp_parse_k ( |