📄 sdp_parse.c
字号:
post_session(p, sdp);}int sdp_connection_is_inaddr_any(sdp_connection_t const *c){ return c && c->c_nettype == sdp_net_in && ((c->c_addrtype == sdp_addr_ip4 && strcmp(c->c_address, "0.0.0.0")) || (c->c_addrtype == sdp_addr_ip6 && strcmp(c->c_address, "::")));}/**Postprocess session description. * * The function post_session() postprocesses the session description. The * postprocessing includes setting the session backpointer for each media. */static void post_session(sdp_parser_t *p, sdp_session_t *sdp){ sdp_media_t *m; sdp_connection_t const *c; if (!p->pr_ok) return; /* Set session back-pointer */ for (m = sdp->sdp_media; m; m = m->m_next) { m->m_session = sdp; } if (p->pr_config) { if (sdp->sdp_version[0] != 0) parsing_error(p, "Incorrect version"); return; } /* Go through all media and set mode */ for (m = sdp->sdp_media; m; m = m->m_next) { if (m->m_port == 0) { m->m_mode = sdp_inactive; m->m_rejected = 1; continue; } c = sdp_media_connections(m); if (p->pr_mode_0000 && c) { if (c->c_nettype == sdp_net_in && c->c_addrtype == sdp_addr_ip4 && strcmp(c->c_address, "0.0.0.0") == 0) /* Reset recvonly flag */ m->m_mode &= ~sdp_recvonly; } } if (p->pr_insane) return; /* Verify that all mandatory fields are present */ if (sdp_sanity_check(p) < 0) return;}/** Validates that all mandatory fields exist * * Checks that all necessary fields (v=, o=) exists in the parsed sdp. If * strict, check that all mandatory fields (c=, o=, s=, t=) are present. * This function also goes through all media, marks rejected media as such, * and updates the mode accordingly. * * @retval 0 if parsed SDP description is valid * @retval -1 if some SDP line is missing * @retval -2 if c= line is missing */int sdp_sanity_check(sdp_parser_t *p){ sdp_session_t *sdp = p->pr_session; sdp_media_t *m; if (!p || !p->pr_ok) return -1; else if (sdp->sdp_version[0] != 0) return parsing_error(p, "Incorrect version"); else if (!sdp->sdp_origin) return parsing_error(p, "No o= present"); else if (p->pr_strict && !sdp->sdp_subject) return parsing_error(p, "No s= present"); else if (p->pr_strict && !sdp->sdp_time) return parsing_error(p, "No t= present"); /* If there is no session level c= check that one exists for all media */ /* c= line may be missing if this is a RTSP description */ if (!p->pr_c_missing && !sdp->sdp_connection) { for (m = sdp->sdp_media ; m ; m = m->m_next) { if (!m->m_connections && !m->m_rejected) { parsing_error(p, "No c= on either session level or all mediums"); return -2; } } } return 0;}#if 0/** * Parse a "v=" field * * The function parser_version() parses the SDP version field. * * @param p pointer to SDP parser object * @param r pointer to record data * @param result pointer to which parsed record is assigned */static void parse_version(sdp_parser_t *p, char *r, sdp_version_t *result){ /* proto-version = "v=" 1*DIGIT CRLF ;[RFC2327] describes version 0 */ if (parse_ul(p, &r, result, 0)) parsing_error(p, "version \"%s\" is invalid", r); else if (*result > 0) parsing_error(p, "unknown version v=%s", r);}#endif/* ------------------------------------------------------------------------- * Function parse_origin() - parse an "o=" field * * Description: * This function parses an SDP origin field. * * Parameters: * p - pointer to SDP parser object * r - pointer to record data * result - pointer to which parsed record is assigned */static void parse_origin(sdp_parser_t *p, char *r, sdp_origin_t **result){ /* origin-field = "o=" username space sess-id space sess-version space nettype space addrtype space addr CRLF username = safe ;pretty wide definition, but doesn't include space sess-id = 1*(DIGIT) ;should be unique for this originating username/host sess-version = 1*(DIGIT) ;0 is a new session */ PARSE_ALLOC(p, sdp_origin_t, o); *result = o; o->o_username = token(&r, SPACE TAB, NULL, SPACE TAB); if (!o->o_username) { parsing_error(p, "invalid username"); return; } if (parse_ull(p, &r, &o->o_id, 0)) { parsing_error(p, "invalid session id"); return; } if (parse_ull(p, &r, &o->o_version, 0)) { parsing_error(p, "invalid session version"); return; } parse_connection(p, r, &o->o_address);}/* ------------------------------------------------------------------------- * Function parse_subject() - parse an "s=" field * * Description: * This function parses an SDP subject field. * * Parameters: * p - pointer to SDP parser object * r - pointer to record data * result - pointer to which parsed record is assigned */static void parse_subject(sdp_parser_t *p, char *r, sdp_text_t **result){ /* session-name-field = "s=" text CRLF text = byte-string */ *result = r;}/* ------------------------------------------------------------------------- * Function parse_information() - parse an "i=" field * * Description: * This function parses an SDP information field. * * Parameters: * p - pointer to SDP parser object * r - pointer to record data * result - pointer to which parsed record is assigned */static void parse_information(sdp_parser_t *p, char *r, sdp_text_t **result){ /* information-field = ["i=" text CRLF] */ *result = r;}/* ------------------------------------------------------------------------- * Function parse_uri() - parse an "u=" field * * Description: * This function parses an SDP URI field. * * Parameters: * p - pointer to SDP parser object * r - pointer to record data * result - pointer to which parsed record is assigned */static void parse_uri(sdp_parser_t *p, char *r, sdp_text_t **result){ /* uri-field = ["u=" uri CRLF] uri= ;defined in RFC1630 */ /* XXX - no syntax checking here */ *result = r;}/* ------------------------------------------------------------------------- * Function parse_email() - parse an "e=" field * * Description: * This function parses an SDP email field. * * Parameters: * p - pointer to SDP parser object * r - pointer to record data * result - pointer to which parsed record is assigned */static void parse_email(sdp_parser_t *p, char *r, sdp_list_t **result){ /* email-fields = *("e=" email-address CRLF) email-address = email | email "(" email-safe ")" | email-safe "<" email ">" email = ;defined in RFC822 */ parse_text_list(p, r, result);}/* ------------------------------------------------------------------------- * Function parse_phone() - parse an "p=" field * * Description: * This function parses an SDP phone field. * * Parameters: * p - pointer to SDP parser object * r - pointer to record data * result - pointer to which parsed record is assigned */static void parse_phone(sdp_parser_t *p, char *r, sdp_list_t **result){ /* phone-fields = *("p=" phone-number CRLF) phone-number = phone | phone "(" email-safe ")" | email-safe "<" phone ">" phone = "+" POS-DIGIT 1*(space | "-" | DIGIT) ;there must be a space or hyphen between the ;international code and the rest of the number. */ parse_text_list(p, r, result);}/* ------------------------------------------------------------------------- * Function parse_connection() - parse an "c=" field * * Description: * This function parses an SDP connection field. * * Parameters: * p - pointer to SDP parser object * r - pointer to record data * result - pointer to which parsed record is assigned */static void parse_connection(sdp_parser_t *p, char *r, sdp_connection_t **result){ /* connection-field = ["c=" nettype space addrtype space connection-address CRLF] ;a connection field must be present ;in every media description or at the ;session-level nettype = "IN" ;list to be extended addrtype = "IP4" | "IP6" ;list to be extended connection-address = multicast-address | addr multicast-address = 3*(decimal-uchar ".") decimal-uchar "/" ttl [ "/" integer ] ;multicast addresses may be in the range ;224.0.0.0 to 239.255.255.255 ttl = decimal-uchar addr = FQDN | unicast-address FQDN = 4*(alpha-numeric|"-"|".") ;fully qualified domain name as specified in RFC1035 unicast-address = IP4-address | IP6-address IP4-address = b1 "." decimal-uchar "." decimal-uchar "." b4 b1 = decimal-uchar ;less than "224"; not "0" or "127" b4 = decimal-uchar ;not "0" IP6-address = ;to be defined */ PARSE_ALLOC(p, sdp_connection_t, c); *result = c; if (strncasecmp(r, "IN", 2) == 0) { char *s; /* nettype is internet */ c->c_nettype = sdp_net_in; s = token(&r, SPACE TAB, NULL, NULL); /* addrtype */ s = token(&r, SPACE TAB, NULL, NULL); if (s && strcasecmp(s, "IP4") == 0) c->c_addrtype = sdp_addr_ip4; else if (s && strcasecmp(s, "IP6") == 0) c->c_addrtype = sdp_addr_ip6; else { parsing_error(p, "unknown IN address type: %s", s); return; } /* address */ s = next(&r, SPACE TAB, SPACE TAB); c->c_address = s; if (!s || !*s) { parsing_error(p, "invalid address"); return; } /* ttl */ s = strchr(s, '/'); if (s) { unsigned long value; *s++ = 0; if (parse_ul(p, &s, &value, 256) || (*s && *s != '/')) { parsing_error(p, "invalid ttl"); return; } c->c_ttl = value; c->c_mcast = 1; /* multiple groups */ value = 1; if (*s++ == '/') if (parse_ul(p, &s, &value, 0) || *s) { parsing_error(p, "invalid number of multicast groups"); return; } c->c_groups = value; } else c->c_groups = 1; } else if (p->pr_anynet) { c->c_nettype = sdp_net_x; c->c_addrtype = sdp_addr_x; c->c_address = r; c->c_ttl = 0; c->c_groups = 1; } else parsing_error(p, "invalid address");}/* ------------------------------------------------------------------------- * Function parse_bandwidth() - parse an "b=" field * * Description: * This function parses an SDP bandwidth field. * * Parameters: * p - pointer to SDP parser object * r - pointer to record data * result - pointer to which parsed record is assigned */static void parse_bandwidth(sdp_parser_t *p, char *r, sdp_bandwidth_t **result){ /* bandwidth-fields = *("b=" bwtype ":" bandwidth CRLF) bwtype = 1*(alpha-numeric) ; CT or AS bandwidth = 1*(DIGIT) */ /* NOTE: bwtype can also be like X-barf */ sdp_bandwidth_e modifier; char *name; unsigned long value; name = token(&r, ":", ALPHA DIGIT "-", SPACE TAB); if (name == NULL || parse_ul(p, &r, &value, 0)) { parsing_error(p, "invalid bandwidth"); return; } if (strcmp(name, "CT") == 0) modifier = sdp_bw_ct, name = NULL; else if (strcmp(name, "AS") == 0) modifier = sdp_bw_as, name = NULL; else modifier = sdp_bw_x; if (STRICT(p)) PARSE_CHECK_REST(p, r, "b"); { PARSE_ALLOC(p, sdp_bandwidth_t, b); *result = b; b->b_modifier = modifier; b->b_modifier_name = name; b->b_value = value; }}/* ------------------------------------------------------------------------- * Function parse_time() - parse an "t=" field * * Description: * This function parses an SDP time field. * * Parameters: * p - pointer to SDP parser object * r - pointer to record data * result - pointer to which parsed record is assigned */static void parse_time(sdp_parser_t *p, char *r, sdp_time_t **result){ /* time-fields = 1*( "t=" start-time space stop-time
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -