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

📄 sdp_decode.c

📁 完整的RTP RTSP代码库
💻 C
📖 第 1 页 / 共 4 页
字号:
  session_time_desc_t *tptr;  uint32_t start, end;  *err = 0;  if (!isdigit(*lptr)) {    *err = ESDP_TIME;    sdp_debug(LOG_ERR, "t= statement has illegal first character %c", *lptr);    return (NULL);  }  start = end = 0;    while (isdigit(*lptr)) {    start *= 10;    start += *lptr - '0';    lptr++;  }  ADV_SPACE(lptr);  if (!isdigit(*lptr)) {    sdp_debug(LOG_ERR,	      "t= statement has illegal character after 1st number %c",	      *lptr);    *err = ESDP_TIME;    return (NULL);  }    while (isdigit(*lptr)) {    end *= 10;    end += *lptr - '0';    lptr++;  }    tptr = malloc(sizeof(session_time_desc_t));  if (tptr == NULL) {    *err = ENOMEM;    return (NULL);  }  tptr->next = NULL;  tptr->repeat = NULL;  // Convert from NTP time to Unix time (unless time is 0)  tptr->start_time = (start == 0) ? 0 : (start - NTP_TO_UNIX_TIME);  tptr->end_time = (end == 0) ? 0 : (end - NTP_TO_UNIX_TIME);  // Add to end of linked list of time descriptions  if (sptr->time_desc == NULL) {    sptr->time_desc = tptr;  } else {    session_time_desc_t *q;    q = sptr->time_desc;    while (q->next != NULL) q = q->next;    q->next = tptr;  }    return (tptr);  }/* * sdp_decode_parse_time_adj() * decode z= fields. * Inputs: lptr - pointer to line to decode *   session - pointer to session_descriptor to add * Returns: *   TRUE - valid line *   FALSE - invalid line */static int sdp_decode_parse_time_adj (char *lptr,				      session_desc_t *session){  char *sep;  int valid;  time_adj_desc_t *start_aptr, *aptr;  time_t adj_time;  int32_t offset;   uint32_t off;  int possign;  int err;    if (!isdigit(*lptr)) {    sdp_debug(LOG_ERR, "Illegal character for z= field %s", lptr);    return (ESDP_TIME_ADJ);  }  start_aptr = NULL;  valid = TRUE;  /*   * parse pairs of <adjustment time> <offset>   */  err = ESDP_TIME_ADJ;    while ((sep = strsep(&lptr, SPACES)) && valid == TRUE) {    if (lptr == NULL) {      valid = FALSE;      continue;    }    // process <adjustment time> - adjust it from NTP to unix time    if (sscanf(sep, "%ld", &adj_time) != 1) return -1;    // Check for negative sign for offset.    ADV_SPACE(lptr);    if (*lptr == '-') {      possign = FALSE;      lptr++;    } else possign = TRUE;    ADV_SPACE(lptr);        sep = strsep(&lptr, SPACES);    if (adj_time == 0 || sep == NULL) {      valid = FALSE;      continue;    }    adj_time -= NTP_TO_UNIX_TIME;    // Process offset - could be positive or negative.    if (str_to_time_offset(sep, &off) == FALSE) {      valid = FALSE;      continue;    }    offset = off;    if (possign == FALSE) offset = 0 - offset;    /*     * create a time structure - order the link list by value     * of adj_times     */    aptr = malloc(sizeof(time_adj_desc_t));    if (aptr == NULL) {      valid = FALSE;      err = ENOMEM;      continue;    }        aptr->next = NULL;    aptr->adj_time = adj_time;    aptr->offset = offset;    if (lptr != NULL) {      ADV_SPACE(lptr);    }    start_aptr = time_adj_order_in_list(start_aptr, aptr);      }  if (valid == FALSE) {    while (start_aptr != NULL) {      aptr = start_aptr;      start_aptr = aptr->next;      free(aptr);    }    return (err);  }  if (start_aptr == NULL) return (err);  while (start_aptr != NULL) {    aptr = start_aptr->next;    start_aptr = aptr->next;    aptr->next = NULL;    session->time_adj_desc = time_adj_order_in_list(session->time_adj_desc,						    aptr);  }  return (0);}/* * sdp_decode_parse_time_repeat * parse "r=" field in SDP description, store info off of current time * pointer * * Inputs : lptr - pointer to decode buffer *    current_time - current time pointer returned by sdp_decode_parse_time() * * Outputs - TRUE - decoded successfully - FALSE - error */static int sdp_decode_parse_time_repeat (char *lptr,					 session_time_desc_t *current_time){  time_repeat_desc_t *rptr;  char *sep;  uint32_t interval, duration;    if (current_time == NULL) {    sdp_debug(LOG_ERR, "r= before or without time");    return (ESDP_REPEAT_NOTIME);  }  sep = strsep(&lptr, SPACES);  if (sep == NULL || lptr == NULL) {    sdp_debug(LOG_ERR, "Interval not found in repeat statment");    return (ESDP_REPEAT);  }  if (str_to_time_offset(sep, &interval) == FALSE) {    sdp_debug(LOG_ERR, "Illegal string conversion in repeat");    return (ESDP_REPEAT);  }    ADV_SPACE(lptr);  sep = strsep(&lptr, SPACES);  if (sep == NULL || lptr == NULL) {    sdp_debug(LOG_ERR, "No duration in repeat statement");    return (ESDP_REPEAT);  }  if (str_to_time_offset(sep, &duration) == FALSE) {    return (ESDP_REPEAT);  }    if (duration == 0 || interval == 0) {    sdp_debug(LOG_ERR, "duration or interval are 0 in repeat");    return (ESDP_REPEAT);  }  ADV_SPACE(lptr);    rptr = malloc(sizeof(time_repeat_desc_t));  if (rptr == NULL)    return (ENOMEM);  rptr->next = NULL;  rptr->offset_cnt = 0;  rptr->repeat_interval = interval;  rptr->active_duration = duration;  // Read offset fields - we set a maximum of 16 here.  while ((sep = strsep(&lptr, SPACES)) &&	 rptr->offset_cnt < MAX_REPEAT_OFFSETS) {    if (str_to_time_offset(sep, &rptr->offsets[rptr->offset_cnt]) == FALSE) {      sdp_debug(LOG_ERR, "Illegal repeat offset - number %d", rptr->offset_cnt);      free(rptr);      return (ESDP_REPEAT);    }    rptr->offset_cnt++;    if (lptr != NULL) {      ADV_SPACE(lptr);    }  }  if (rptr->offset_cnt == 0 || sep != NULL) {    sdp_debug(LOG_ERR, "No listed offset in repeat");    free(rptr);    return (ESDP_REPEAT);  }    if (current_time->repeat == NULL) {    current_time->repeat = rptr;  } else {    time_repeat_desc_t *q;    q = current_time->repeat;    while (q->next != NULL) q = q->next;    q->next = rptr;  }  return (0);}/***************************************************************************** * Main library routines *****************************************************************************//* * sdp_decode() * main routine * Inputs: *   decode - pointer to sdp_decode_info_t set before calling. *   retlist - pointer to pointer of list head *   translated - pointer to return number translated * Outputs: *   error code or 0.  Negative error codes are local, positive are errorno. *   retlist - pointer to list of session_desc_t. *   translated - number translated. */int sdp_decode (sdp_decode_info_t *decode,		session_desc_t **retlist,		int *translated){  char *line, *lptr;  char code;  int errret;  uint32_t linelen;  session_desc_t *first_session,*sptr;  media_desc_t *current_media;  session_time_desc_t *current_time;  if ((decode == NULL) || (decode->isSet != TRUE)) {    return -EINVAL;  }  *retlist = first_session = NULL;  sptr = NULL;  current_media = NULL;  current_time = NULL;  *translated = 0;  errret = 0;  line = NULL;  linelen = 0;  while (errret == 0 && get_next_line(&line, decode, &linelen) != FALSE) {    lptr = line;    ADV_SPACE(lptr);    /*     * All spaces ?  Just go to next line.     */    if (*lptr == '\0')      continue;    sdp_debug(LOG_DEBUG, "\'%s\'",  lptr);    /*     * Let's be strict about 1 character code     */    code = *lptr++;    ADV_SPACE(lptr);    if (*lptr == '=') {      lptr++;      ADV_SPACE(lptr);      if ((sptr == NULL) && (tolower(code) != 'v')) {	sdp_debug(LOG_ERR, "Version not 1st statement");	errret = ESDP_INVVER;	break;      }      switch (tolower(code)) {      case 'v': {	int ver;	if ((sscanf(lptr, "%u", &ver) != 1) ||	    (ver != 0)) {	  errret = ESDP_INVVER;	  sdp_debug(LOG_ERR, "SDP Version not correct, %s", line);	  break;	}	/*	 * Next session...	 */	sptr = malloc(sizeof(session_desc_t));	if (sptr == NULL) {	  errret = ENOMEM;	  break;	}	memset(sptr, 0, sizeof(session_desc_t));	if (first_session == NULL) {	  *retlist = first_session = sptr;	} else {	  session_desc_t *p;	  p = first_session;	  while (p->next != NULL) p = p->next;	  p->next = sptr;	}	*translated = *translated + 1;	current_media = NULL;	current_time = NULL;	break;      }      case 'o':	errret = sdp_decode_parse_origin(lptr, sptr);	break;      case 's':	if (sptr->session_name == NULL)	  sptr->session_name = strdup(lptr);	if (sptr->session_name == NULL) {	  errret = ENOMEM;	}	break;      case 'i':	if (current_media != NULL) {	  if (current_media->media_desc == NULL)	    current_media->media_desc = strdup(lptr);	  if (current_media->media_desc == NULL) {	    errret = ENOMEM;	  }	} else {	  if (sptr->session_desc == NULL) 	    sptr->session_desc = strdup(lptr);	  if (sptr->session_desc == NULL) {	    errret = ENOMEM;	  }	}	break;      case 'u':	if (sptr->uri == NULL)	  sptr->uri = strdup(lptr);	if (sptr->uri == NULL) {	  errret = ENOMEM;	}	break;      case 'e':	if (sdp_add_string_to_list(&sptr->admin_email, lptr) == FALSE) {	  errret = ENOMEM;	}	break;      case 'p':	if (sdp_add_string_to_list(&sptr->admin_phone, lptr) == FALSE) {	  errret = ENOMEM;	}	break;      case 'c':	errret = sdp_decode_parse_connect(lptr,					  current_media ?					  &current_media->media_connect :					  &sptr->session_connect);	break;      case 'b':	errret= sdp_decode_parse_bandwidth(lptr,					   current_media != NULL ?					   &current_media->media_bandwidth :					   &sptr->session_bandwidth);	break;      case 't':	current_time = sdp_decode_parse_time(lptr, sptr, &errret);	if (current_time == NULL) {	  errret = ESDP_TIME;	}	break;      case 'r':	if (current_time != NULL) {	  errret = sdp_decode_parse_time_repeat(lptr, current_time);	}	break;      case 'z':	errret = sdp_decode_parse_time_adj(lptr, sptr);	break;      case 'k':	errret = sdp_decode_parse_key(lptr,				      current_media == NULL ? &sptr->key :				      &current_media->key);	break;      case 'a':	errret = sdp_decode_parse_a(lptr, line, sptr, current_media);	break;      case 'm':	current_media = sdp_decode_parse_media(lptr, sptr, &errret);	break;      default:	sdp_debug(LOG_ERR, "unknown code - %s", line);	errret = ESDP_UNKNOWN_LINE;      }    } else {      // bigger than 1 character code      sdp_debug(LOG_ERR, "More than 1 character code - %s", line);      errret = ESDP_UNKNOWN_LINE;    }  }  if (line != NULL) {    free(line);  }  if (errret != 0) {    if (sptr != NULL) {      if (first_session == sptr) {	*retlist = NULL;      } else {	session_desc_t *p;	p = first_session;	while (p->next != sptr) {	  p = p->next;	}	p->next = NULL;      }      sdp_free_session_desc(sptr);    }    sdp_debug(LOG_ALERT, "SDP decode failure %d", errret);    return (errret);  }  return (0);}/* * set_sdp_decode_from_memory() * Allows sdp decode to be run from a memory block. * * Inputs: memptr - pointer to memory.  Won't be touched. * Outputs: pointer to sdp_decode_info_t to be used. */sdp_decode_info_t *set_sdp_decode_from_memory (const char *memptr){  sdp_decode_info_t *decode_ptr;  decode_ptr = malloc(sizeof(sdp_decode_info_t));  if (decode_ptr == NULL)    return (NULL);    memset(decode_ptr, 0, sizeof(sdp_decode_info_t));  decode_ptr->isSet = TRUE;  decode_ptr->isMem = TRUE;  decode_ptr->memptr = memptr;  decode_ptr->filename = NULL;  decode_ptr->ifile = NULL;  return (decode_ptr);}/* * set_sdp_decode_from_filename() * Allows sdp decode to be run on a file * * Inputs: filename - name of file to open * Outputs: pointer to sdp_decode_info_t to be used. */sdp_decode_info_t *set_sdp_decode_from_filename (const char *filename){  sdp_decode_info_t *decode_ptr;  decode_ptr = malloc(sizeof(sdp_decode_info_t));  if (decode_ptr == NULL)    return (NULL);    memset(decode_ptr, 0, sizeof(sdp_decode_info_t));  decode_ptr->isSet = TRUE;  decode_ptr->isMem = FALSE;  decode_ptr->memptr = NULL;  decode_ptr->filename = filename;  decode_ptr->ifile = fopen(filename, "r");  if (decode_ptr->ifile == NULL) {    free(decode_ptr);    return (NULL);  }  return (decode_ptr);}void sdp_decode_info_free (sdp_decode_info_t *decode){  if (decode->isMem == FALSE) {    fclose(decode->ifile);  }  free(decode);}

⌨️ 快捷键说明

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