📄 sdp_decode.c
字号:
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 ? ¤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: 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 + -