📄 sdp_decode.c
字号:
*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 ?
¤t_media->media_connect :
&sptr->session_connect);
break;
case 'b':
errret= sdp_decode_parse_bandwidth(lptr,
current_media != NULL ?
¤t_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 :
¤t_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 + -