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

📄 sdp_decode.c

📁 嵌入式系统中c程序实现了rtsp协议的基本内容
💻 C
📖 第 1 页 / 共 4 页
字号:
    *err = ESDP_TIME;
    Rtsp_Printf( "t= statement has illegal first character %c\n", *lptr);
    return (NULL);
  }

  start = end = 0;
  
  while (isdigit(*lptr)) {
    start *= 10;
    start += *lptr - '0';
    lptr++;
  }

  ADV_SPACE(lptr);

  if (!isdigit(*lptr)) {
    Rtsp_Printf(
	      "t= statement has illegal character after 1st number %c\n",
	      *lptr);
    *err = ESDP_TIME;
    return (NULL);
  }
  
  while (isdigit(*lptr)) {
    end *= 10;
    end += *lptr - '0';
    lptr++;
  }
  
  tptr = Rtsp_Malloc(sizeof(session_time_desc_t),__LINE__,__FILE__);
  if (tptr == NULL) {
    *err = ST_ERROR_NO_MEMORY;
    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;
  unsigned int offset;
  int possign;
  int err;
  
  if (!isdigit(*lptr)) {
    Rtsp_Printf( "Illegal character for z= field %s\n", lptr);
    return (ESDP_TIME_ADJ);
  }

  start_aptr = NULL;
  valid = TRUE;
  /*
   * parse pairs of <adjustment time> <offset>
   */
  err = ESDP_TIME_ADJ;
  
  while (NULL!=(sep = (char*)strsep(&lptr, SPACES)) && valid == TRUE) {
    if (lptr == NULL) {
      valid = FALSE;
      continue;
    }
    /* process <adjustment time> - adjust it from NTP to unix time*/
    sscanf(sep, "%ld", &adj_time);

    /* Check for negative sign for offset.*/
    ADV_SPACE(lptr);
    if (*lptr == '-') {
      possign = FALSE;
      lptr++;
    } else possign = TRUE;
    ADV_SPACE(lptr);
    
    sep = (char*)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, &offset) == FALSE) {
      valid = FALSE;
      continue;
    }

    if (possign == FALSE) offset = 0 - offset;

    /*
     * create a time structure - order the link list by value
     * of adj_times
     */
    aptr = Rtsp_Malloc(sizeof(time_adj_desc_t),__LINE__,__FILE__);
    if (aptr == NULL) {
      valid = FALSE;
      err = ST_ERROR_NO_MEMORY;
      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;
      Rtsp_Free(aptr,__LINE__,__FILE__);
    }
    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) {
    Rtsp_Printf( "r= before or without time\n");
    return (ESDP_REPEAT_NOTIME);
  }

  sep =(char*) strsep(&lptr, SPACES);
  if (sep == NULL || lptr == NULL) {
    Rtsp_Printf( "Interval not found in repeat statment\n");
    return (ESDP_REPEAT);
  }

  if (str_to_time_offset(sep, &interval) == FALSE) {
    Rtsp_Printf( "Illegal string conversion in repeat\n");
    return (ESDP_REPEAT);
  }
  
  ADV_SPACE(lptr);
  sep = (char*)strsep(&lptr, SPACES);
  if (sep == NULL || lptr == NULL) {
    Rtsp_Printf( "No duration in repeat statement\n");
    return (ESDP_REPEAT);
  }

  if (str_to_time_offset(sep, &duration) == FALSE) {
    return (ESDP_REPEAT);
  }
  
  if (duration == 0 || interval == 0) {
    Rtsp_Printf( "duration or interval are 0 in repeat\n");
    return (ESDP_REPEAT);
  }

  ADV_SPACE(lptr);
  
  rptr = Rtsp_Malloc(sizeof(time_repeat_desc_t),__LINE__,__FILE__);
  if (rptr == NULL)
    return (ST_ERROR_NO_MEMORY);

  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 (NULL!=(sep = (char*)strsep(&lptr, SPACES)) &&
	 rptr->offset_cnt < MAX_REPEAT_OFFSETS) {
    if (str_to_time_offset(sep, &rptr->offsets[rptr->offset_cnt]) == FALSE) {
      Rtsp_Printf( "Illegal repeat offset - number %d\n", rptr->offset_cnt);
      Rtsp_Free(rptr,__LINE__,__FILE__);
      return (ESDP_REPEAT);
    }
    rptr->offset_cnt++;
    if (lptr != NULL) {
      ADV_SPACE(lptr);
    }
  }

  if (rptr->offset_cnt == 0 || sep != NULL) {
    Rtsp_Printf( "No listed offset in repeat\n");
    Rtsp_Free(rptr,__LINE__,__FILE__);
    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 ST_ERROR_BAD_PARAMETER;
  }

  *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;
    
            
    /*
     * 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')) {
	Rtsp_Printf( "Version not 1st statement\n");
	errret = ESDP_INVVER;
	break;
      }
      switch (tolower(code)) {
      case 'v': {
	int ver;
	if ((sscanf(lptr, "%u", &ver) != 1) ||
	    (ver != 0)) {
	  errret = ESDP_INVVER;
	  Rtsp_Printf( "SDP Version not correct, %s\n", line);
	  break;
	}
	/*
	 * Next session...
	 */
	sptr = Rtsp_Malloc(sizeof(session_desc_t),__LINE__,__FILE__);
	
	if (sptr == NULL) {
	  errret = ST_ERROR_NO_MEMORY;
	  break;
	}
	memset(sptr, 0, sizeof(session_desc_t));
#if 0 //wxf add it
	sptr->control_string=Rtsp_Malloc(10,__LINE__,__FILE__);
	if (sptr->control_string == NULL) {
	  errret = ST_ERROR_NO_MEMORY;
	  break;
	}
#endif
	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':
	sptr->session_name = strdup(lptr);
	if (sptr->session_name == NULL) {
	  errret = ST_ERROR_NO_MEMORY;
	}
	break;
      case 'i':
	if (current_media != NULL) {
	  current_media->media_desc = strdup(lptr);
	  if (current_media->media_desc == NULL) {
	    errret = ST_ERROR_NO_MEMORY;
	  }
	} else {
	  sptr->session_desc = strdup(lptr);
	  if (sptr->session_desc == NULL) {
	    errret = ST_ERROR_NO_MEMORY;
	  }
	}
	break;
      case 'u':
	sptr->uri = strdup(lptr);
	if (sptr->uri == NULL) {
	  errret = ST_ERROR_NO_MEMORY;
	}
	break;
      case 'e':
	if (sdp_add_string_to_list(&sptr->admin_email, lptr) == FALSE) {
	  errret = ST_ERROR_NO_MEMORY;
	}
	break;
      case 'p':
	if (sdp_add_string_to_list(&sptr->admin_phone, lptr) == FALSE) {
	  errret = ST_ERROR_NO_MEMORY;
	}
	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:
	Rtsp_Printf( "unknown code - %s\n", line);
	errret = ESDP_UNKNOWN_LINE;
      }
    } else {
      /* bigger than 1 character code*/
      Rtsp_Printf( "More than 1 character code - %s\n", line);
      errret = ESDP_UNKNOWN_LINE;
    }
  }


  if (line != NULL) {
    Rtsp_Free(line,__LINE__,__FILE__);
  }

  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);
    }
    Rtsp_Printf( "SDP decode failure %d\n", 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 = Rtsp_Malloc(sizeof(sdp_decode_info_t),__LINE__,__FILE__);
  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 = Rtsp_Malloc(sizeof(sdp_decode_info_t),__LINE__,__FILE__);
  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) {
    Rtsp_Free(decode_ptr,__LINE__,__FILE__);
    return (NULL);
  }

  return (decode_ptr);
}

void sdp_decode_info_free (sdp_decode_info_t *decode)
{
  if (decode->isMem == FALSE) {
    fclose(decode->ifile);
  }
  Rtsp_Free(decode,__LINE__,__FILE__);
}
#if 0
char* strdup(const char* s) {
    char* temp  ;
    temp=malloc(file_partition,strlen(s)+1);
    strcpy(temp,s);
    return temp;
}
#endif

⌨️ 快捷键说明

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