⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdp_decode.c

📁 完整的RTP RTSP代码库
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is MPEG4IP. *  * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved. *  * Contributor(s):  *              Bill May        wmay@cisco.com *//* * sdp_decode.c * * decode SDP format from file into session description structures * defined in sdp.h * * October, 2000 * Bill May (wmay@cisco.com) * Cisco Systems, Inc. */#include "sdp.h"#include "sdp_decode_private.h"static const char *SPACES=" \t";#define FREE_CHECK(a,b) if (a->b != NULL) { free((void*)a->b); a->b = NULL;}/***************************************************************************** * Memory free routines - frees memory associated with various structures *****************************************************************************/static void free_bandwidth_desc (bandwidth_t *bptr){  bandwidth_t *q;  while (bptr != NULL) {    q = bptr;    bptr = q->next;    FREE_CHECK(q, user_band);    free(q);  }}static void free_category_list (category_list_t **cptr){  category_list_t *p;  if (*cptr == NULL) return;    while (*cptr != NULL) {    p = *cptr;    *cptr = p->next;    free(p);  }}static void free_connect_desc (connect_desc_t *cptr){  FREE_CHECK(cptr, conn_type);  FREE_CHECK(cptr, conn_addr);}/* * sdp_free_media_desc() * Frees all memory associated with a media descriptor(mptr) */void sdp_free_media_desc (media_desc_t *mptr){  free_bandwidth_desc(mptr->media_bandwidth);  mptr->media_bandwidth = NULL;  free_connect_desc(&mptr->media_connect);  free_connect_desc(&mptr->rtcp_connect);  sdp_free_format_list(&mptr->fmt_list);  sdp_free_string_list(&mptr->unparsed_a_lines);  FREE_CHECK(mptr, media);  FREE_CHECK(mptr, media_desc);  FREE_CHECK(mptr, proto);  FREE_CHECK(mptr, sdplang);  FREE_CHECK(mptr, lang);  FREE_CHECK(mptr, orient_user_type);  FREE_CHECK(mptr, control_string);  FREE_CHECK(mptr, key.key);  mptr->parent = NULL;  free(mptr);}static void free_time_desc (session_time_desc_t *ptime){  time_repeat_desc_t *rptr;    if (ptime->next != NULL) {    free_time_desc(ptime->next);    ptime->next = NULL;  }  while (ptime->repeat != NULL) {    rptr = ptime->repeat;    ptime->repeat = rptr->next;    free (rptr);  }  free(ptime);}/* * sdp_free_session_desc() * Inputs - sptr - pointer to session_description list to free */void sdp_free_session_desc (session_desc_t *sptr){  session_desc_t *p;  media_desc_t *mptr, *q;  p = sptr;  while (p != NULL) {    sptr = p;    p = p->next;        sptr->next = NULL;    mptr = sptr->media;    sptr->media = NULL;    while (mptr != NULL) {      q = mptr;      mptr = q->next;      sdp_free_media_desc(q);    }    FREE_CHECK(sptr, etag);    FREE_CHECK(sptr, orig_username);    FREE_CHECK(sptr, control_string);    FREE_CHECK(sptr, create_addr_type);    FREE_CHECK(sptr, create_addr);    FREE_CHECK(sptr, session_name);    FREE_CHECK(sptr, session_desc);    FREE_CHECK(sptr, uri);    FREE_CHECK(sptr, key.key);    FREE_CHECK(sptr, keywds);    FREE_CHECK(sptr, lang);    FREE_CHECK(sptr, tool);    FREE_CHECK(sptr, charset);    FREE_CHECK(sptr, sdplang);    FREE_CHECK(sptr, conf_type_user);    if (sptr->time_desc != NULL) {      free_time_desc(sptr->time_desc);      sptr->time_desc = NULL;    }    free_bandwidth_desc(sptr->session_bandwidth);    sptr->session_bandwidth = NULL;    free_category_list(&sptr->category_list);    free_connect_desc(&sptr->session_connect);    sdp_free_string_list(&sptr->admin_phone);    sdp_free_string_list(&sptr->admin_email);    sdp_free_string_list(&sptr->unparsed_a_lines);        while (sptr->time_adj_desc != NULL) {      time_adj_desc_t *aptr;      aptr = sptr->time_adj_desc;      sptr->time_adj_desc = aptr->next;      free(aptr);    }      free(sptr);  }}/***************************************************************************** * Utility routines - string manipulation, etc *****************************************************************************//* * get_next_line will get the next line to process, and stick it in * lptr. * * Inputs: *    lptr - buffer to store into *    decode - pointer to where to get next line *    buflen - max length of buffer * * Outputs: *    TRUE - have a new line. *    FALSE - all done. */static int get_next_line (char **polptr,			  sdp_decode_info_t *decode,			  uint32_t *buflen){  char *fret;  uint32_t len;  uint32_t buflen_left;  const char *cptr;  if (decode->isMem) {    cptr = decode->memptr;    if (*cptr == '\0') return FALSE;    while (*cptr != '\0' && *cptr != '\n' && *cptr != '\r') cptr++;    len = cptr - decode->memptr;    if (*polptr == NULL || *buflen <= len + 1) {      if (len > 65535) {	sdp_debug(LOG_CRIT, "Max line length of 65535 exceeded %u", 		  len);	return (FALSE);      }      *polptr = realloc(*polptr, len + 1);      if (*polptr == NULL) return FALSE;      *buflen = len + 1;    }    memcpy(*polptr, decode->memptr, len);    (*polptr)[len] = '\0';    decode->memptr += len;    while (*decode->memptr == '\n' || *decode->memptr == '\r')      decode->memptr++;  } else {    char *ptr;    // File reads...    if (decode->ifile == NULL)      return FALSE;    if (*buflen == 0) {      *polptr = (char *)malloc(1024);      if (*polptr == NULL) return FALSE;      *buflen = 1024;    }    // Read file until we hit the end, or a non-blank line read    ptr = *polptr;    buflen_left = *buflen;    len = 0;    while (1) {      fret = fgets(ptr, buflen_left, decode->ifile);      if (fret == NULL) {	if (len > 0) {	  sdp_debug(LOG_WARNING, "Unterminated last line");	  (*polptr)[len] = '\0'; // make sure	  return (TRUE);	}	return (FALSE);      }      len = strlen(ptr);      if (len == 0) return FALSE;      if (ptr[len - 1] == '\n' || ptr[len - 1] == '\r') {	// we have an end of line	len--;	while (len >= 0 &&	       (ptr[len] == '\n' || ptr[len] == '\r')) {	  ptr[len] = '\0';	  len--;	}	return (TRUE);      }            // too long...      buflen_left -= len;      if (*buflen + 1024 > 65535) {	sdp_debug(LOG_CRIT, "Max line length of 65535 exceeded %u", 		  *buflen);	return (FALSE);      }      *buflen += 1024;      buflen_left += 1024;      *polptr = realloc(*polptr, *buflen);      if (*polptr == NULL) return FALSE;      ptr = *polptr + *buflen - buflen_left;    }  }  return TRUE;}/* * strtou64() * Converts string to uint64_t number up to next space, with error checking. * Inputs: *    lptr - pointer to pointer to string.  *lptr will be modified *    num - return value * Outputs - TRUE - sucess, FALSE, failure */static int strtou64 (char **lptr, uint64_t *num){  char *sep;    *num = 0;  ADV_SPACE((*lptr));  sep = strsep(lptr, SPACES);  if (sep == NULL || *lptr == NULL) {    return (FALSE);  }  *num = 0;  while (*sep != '\0') {    if (isdigit(*sep)) {      *num *= 10;      *num += *sep - '0';      sep++;    } else {      return (FALSE);    }  }  return (TRUE);}/* * str_to_time_offset() * converts typed-time field (number or [#d][#h][#m][#s]) * * Inputs - *   str - \0 terminated string to translate *   retval - pointer to return value * Returns - *   TRUE - valid string processed; *   FALSE - invalid string */static int str_to_time_offset (const char *str, uint32_t *retval){  uint32_t value;  uint32_t accum;  char temp;    value = 0;  accum = 0;  if (!isdigit(*str)) return (FALSE);    while (*str != '\0') {    if (isdigit(*str)) {      accum *= 10;      accum += (*str - '0');    } else {      temp = tolower(*str);      if (temp == 'd') {	value += accum * SEC_PER_DAY;	accum = 0;      } else if (temp == 'h') {	value += accum * SEC_PER_HOUR;	accum = 0;      } else if (temp == 'm') {	value += accum * SEC_PER_MINUTE;	accum = 0;      } else if (temp == 's') {	value += accum;	accum = 0;      } else {	sdp_debug(LOG_ERR, "Illegal character %c in time offset", temp);	return (FALSE);      }    }    str++;  }  value += accum;  *retval = value;  return (TRUE);}/* * time_adj_order_in_list() * order linked list by adj_time values.  We don't allow 2 items in the * list - "new" value might be free'd at end * Inputs: *   start - pointer to start of list *   new - pointer to new value * Returns: *   pointer to head of list - new value might be free'd. */static time_adj_desc_t *time_adj_order_in_list (time_adj_desc_t *start,						time_adj_desc_t *new){  time_adj_desc_t *p, *q;  if (start == NULL)    return (new);  p = start;  q = NULL;  while (p != NULL) {    if (new->adj_time == p->adj_time) {      sdp_debug(LOG_NOTICE, "Duplicate time %ld in adj description", p->adj_time);      free(new);      return (start);    }    if (new->adj_time < p->adj_time) {      new->next = p;      if (q == NULL) {	return (new);      } else {	q->next = new;	return (start);      }    }    q = p;    p = p->next;  }  q->next = new;  return (start);}/***************************************************************************** * Line parsing routines *****************************************************************************//* * sdp_decode_parse_a_bool() * parses a boolean field. */static int sdp_decode_parse_a_bool (int arg,				    char *lptr,				    session_desc_t *sptr,				    media_desc_t *mptr){  switch (arg) {  case 0:    if (mptr != NULL) mptr->recvonly = TRUE;    else sptr->recvonly = TRUE;    break;  case 1:    if (mptr != NULL) mptr->sendrecv = TRUE;    else sptr->sendrecv = TRUE;    break;  case 2:    if (mptr != NULL) mptr->sendonly = TRUE;    else sptr->sendonly = TRUE;    break;  }  return (0);}/* * sdp_decode_parse_a_rtpmap() * parses a=rtpmap:<fmt> <name>/<clockrate>[/<enc_param>] */static int sdp_decode_parse_a_fmtp (int arg,				    char *lptr,				    session_desc_t *sptr,				    media_desc_t *mptr){  format_list_t *fptr;  int len;    if (mptr == NULL)    return (-1);  /*   * See our format matches a value in the media's format list.   */  fptr = sdp_find_format_in_line(mptr->fmt_list, lptr) ;  if (fptr == NULL) {    sdp_debug(LOG_ALERT, "Can't find fmtp format %s in media format list", lptr);    return (-1);  }  if (fptr->fmt_param != NULL) {    sdp_debug(LOG_ALERT, "Duplicate fmpt line %s", lptr);    return -1;  }  len = strlen(fptr->fmt);  lptr += len;  lptr++;  ADV_SPACE(lptr);  fptr->fmt_param = strdup(lptr);  if (fptr->fmt_param == NULL) {    return (-1);  }  return (0);}/* * sdp_decode_parse_a_rtpmap() * parses a=rtpmap:<fmt> <name>/<clockrate>[/<enc_param>] */static int sdp_decode_parse_a_rtpmap (int arg,				      char *lptr,				      session_desc_t *sptr,				      media_desc_t *mptr){  char *enc, *slash, *temp;  format_list_t *fptr;  int len;  uint32_t a, b;    if (mptr == NULL)    return (-1);  /*   * See our format matches a value in the media's format list.   */  fptr = sdp_find_format_in_line(mptr->fmt_list, lptr);  if (fptr == NULL) {    sdp_debug(LOG_ALERT, "Can't find rtpmap format %s in media list", lptr);    return (-1);  }  if (fptr->rtpmap_name != NULL) {    sdp_debug(LOG_ALERT, "rtpmap already loaded in fmt %s", fptr->fmt);    return -1;  }  len = strlen(fptr->fmt);  /*   * Matches entry left in fptr.  Decode rest of line   */  enc = lptr + len;  ADV_SPACE(enc);  slash = strchr(enc, '/');    if (slash != NULL) {    *slash++ = '\0';    temp = enc;    while ((!(isspace(*temp))) && *temp != '\0') temp++;    *temp = '\0';      // enc points to encode name    ADV_SPACE(slash);    temp = strsep(&slash, " \t/");    if (temp == NULL) {      sdp_debug(LOG_ERR, "Can't find seperator after encode name in rtpmap");      return (-1);    }    if (sscanf(temp, "%u", &a) == 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -