📄 parser.c
字号:
} if (dsc->unidentified_attributes_count < UNIDENTIFIED_ATTRIBUTES_MAX_COUNT) { dsc->unidentified_attributes [dsc->unidentified_attributes_count] = strdup (longfsdp_buf); dsc->unidentified_attributes_count++; } } NEXT_LINE (p); } else if (sscanf (p, "a=%20s", fsdp_buf[0]) == 1) { /* session-level property attributes */ if (!strncmp (fsdp_buf[0], "recvonly", 8)) dsc->a_sendrecv_mode = FSDP_SENDRECV_RECVONLY; else if (!strncmp (fsdp_buf[0], "sendonly", 8)) dsc->a_sendrecv_mode = FSDP_SENDRECV_SENDONLY; else if (!strncmp (fsdp_buf[0], "inactive", 8)) dsc->a_sendrecv_mode = FSDP_SENDRECV_INACTIVE; else if (!strncmp (fsdp_buf[0], "sendrecv", 8)) dsc->a_sendrecv_mode = FSDP_SENDRECV_SENDRECV; else { /* ignore unknown attributes, but provide access to them */ *longfsdp_buf = '\0'; strncat (longfsdp_buf, fsdp_buf[0], MAXLONGFIELDLEN-1); if (NULL == dsc->unidentified_attributes) { dsc->unidentified_attributes_count = 0; dsc->unidentified_attributes = calloc (UNIDENTIFIED_ATTRIBUTES_MAX_COUNT, sizeof (char *)); } if (dsc->unidentified_attributes_count < UNIDENTIFIED_ATTRIBUTES_MAX_COUNT) { dsc->unidentified_attributes [dsc->unidentified_attributes_count] = strdup (longfsdp_buf); dsc->unidentified_attributes_count++; } } NEXT_LINE (p); } else return FSDPE_INVALID_ATTRIBUTE; } /***************************************************************************/ /* B) parse media-level descriptions */ /***************************************************************************/ p2 = p; j = 0; while ((*p2 != '\0') && !strncmp (p2, "m=", 2)) { char c; j++; NEXT_LINE (p2); while (sscanf (p2, "%c=", &c) == 1) { if (c == 'i' || c == 'c' || c == 'b' || c == 'k' || c == 'a') { NEXT_LINE (p2); } else if (c == 'm') { break; } else { return FSDPE_INVALID_LINE; } } } dsc->media_announcements_count = j; if (dsc->media_announcements_count == 0) { ; /*return FSDPE_MISSING_MEDIA; */ } else { /* dsc->media_announcements_count > 0 */ dsc->media_announcements = calloc (j, sizeof (fsdp_media_announcement_t *)); for (j = 0; j < dsc->media_announcements_count; j++) { fsdp_media_announcement_t *media = NULL; /* `m=' line (media name, transport address and format list) */ /* m=<media> <port> <transport> <fmt list> */ /* The max. string lengths are subject to change */ if (sscanf (p, "m=%11s %8s %7s %" MLFLENS "[^\r\n]", fsdp_buf[0], fsdp_buf[1], fsdp_buf[2], longfsdp_buf) != 4) { return FSDPE_INVALID_MEDIA; } else { dsc->media_announcements[j] = calloc (1, sizeof (fsdp_media_announcement_t)); media = dsc->media_announcements[j]; if (!strncmp (fsdp_buf[0], "audio", 5)) media->media_type = FSDP_MEDIA_AUDIO; else if (!strncmp (fsdp_buf[0], "video", 5)) media->media_type = FSDP_MEDIA_VIDEO; else if (!strncmp (fsdp_buf[0], "application", 11)) media->media_type = FSDP_MEDIA_APPLICATION; else if (!strncmp (fsdp_buf[0], "data", 4)) media->media_type = FSDP_MEDIA_DATA; else if (!strncmp (fsdp_buf[0], "control", 7)) media->media_type = FSDP_MEDIA_CONTROL; else return FSDPE_UNKNOWN_MEDIA_TYPE; { /* try to get port specification as port/number */ char *slash; if ((slash = strchr (fsdp_buf[1], '/'))) { *slash = '\0'; slash++; media->port = strtol (fsdp_buf[1], NULL, 10); media->port_count = strtol (slash, NULL, 10); } else { media->port = strtol (fsdp_buf[1], NULL, 10); media->port_count = 0; } } if (!strncmp (fsdp_buf[2], "RTP/AVP", 7)) media->transport = FSDP_TP_RTP_AVP; else if (!strncmp (fsdp_buf[2], "udp", 3)) media->transport = FSDP_TP_UDP; else if (!strncmp (fsdp_buf[2], "TCP", 3)) media->transport = FSDP_TP_TCP; else if (!strncmp (fsdp_buf[2], "UDPTL", 5)) media->transport = FSDP_TP_UDPTL; else if (!strncmp (fsdp_buf[2], "vat", 3)) media->transport = FSDP_TP_VAT; else if (!strncmp (fsdp_buf[2], "rtp", 3)) media->transport = FSDP_TP_OLD_RTP; else return FSDPE_UNKNOWN_MEDIA_TRANSPORT; { unsigned int k = 0; char *s = longfsdp_buf; while (NULL != (s = strchr (s, ' '))) { k++; if (NULL != s) s++; } k++; /* when there is no space left, count the last format */ media->formats_count = k; media->formats = calloc (k, sizeof (char *)); s = longfsdp_buf; for (k = 0; k < media->formats_count; k++) { char *space = strchr (s, ' '); if (NULL != space) *space = '\0'; media->formats[k] = strdup (s); s = space + 1; } } NEXT_LINE (p); } /* `i=' line (media title) [optional] */ /* i=<media title> */ if (!strncmp (p, "i=", 2) && sscanf (p, "i=%" MLFLENS "[^\r\n]", longfsdp_buf)) { media->i_title = strdup (longfsdp_buf); NEXT_LINE (p); } else { /* (optional) information absent */ } /* `c=' line (connection information - overrides session-level line) [optional if provided at session-level] */ /* c=<network type> <address type> <connection address> */ result = fsdp_parse_c (&p, &(media->c_network_type), &(media->c_address_type), &(media->c_address)); if (result != FSDPE_OK) return result; /* `b=' lines (bandwidth information) [optional] */ /* b=<modifier>:<bandwidth-value> */ result = fsdp_parse_b (&p, &(media->bw_modifiers), &(media->bw_modifiers_count)); if (FSDPE_OK != result) return result; /* `k=' line (encryption key) [optional] */ /* k=<method> k=<method>:<encryption key> */ result = fsdp_parse_k (&p, &(media->k_encryption_method), &(media->k_encryption_content)); if (result != FSDPE_OK) return result; /* B.1) Attributes */ /* `a=' lines (zero or more media attribute lines) [optional] */ /* a=<attribute> a=<attribute>:<value> */ while (!strncmp (p, "a=", 2)) { if (sscanf (p, "a=%9[^:\r\n]:%" MLFLENS "[^\r\n]", fsdp_buf[0], longfsdp_buf) == 2) { /* media-level value attributes */ if (!strncmp (fsdp_buf[0], "ptime", 5)) media->a_ptime = strtoul (longfsdp_buf, NULL, 10); else if (!strncmp (fsdp_buf[0], "maxptime", 8)) media->a_maxptime = strtoul (longfsdp_buf, NULL, 10); else if (!strncmp (fsdp_buf[0], "rtpmap", 6)) fsdp_parse_rtpmap (&(media->a_rtpmaps), &(media->a_rtpmaps_count), longfsdp_buf); else if (!strncmp (fsdp_buf[0], "orient", 6)) { if (!strncmp (longfsdp_buf, "portrait", 8)) media->a_orient = FSDP_ORIENT_PORTRAIT; else if (!strncmp (longfsdp_buf, "landscape", 9)) media->a_orient = FSDP_ORIENT_LANDSCAPE; else if (!strncmp (longfsdp_buf, "seascape", 9)) media->a_orient = FSDP_ORIENT_SEASCAPE; } else if (!strncmp (fsdp_buf[0], "sdplang", 7)) { if (NULL == dsc->a_sdplangs) { media->a_sdplangs_count = 0; media->a_sdplangs = calloc (SDPLANGS_MAX_COUNT, sizeof (char *)); } if (media->a_sdplangs_count < SDPLANGS_MAX_COUNT) { media->a_sdplangs[dsc->a_sdplangs_count] = strdup (longfsdp_buf); media->a_sdplangs_count++; } } else if (!strncmp (fsdp_buf[0], "lang", 4)) { if (NULL == dsc->a_langs) { media->a_langs_count = 0; media->a_langs = calloc (SDPLANGS_MAX_COUNT, sizeof (char *)); } if (media->a_langs_count < SDPLANGS_MAX_COUNT) { media->a_langs[dsc->a_langs_count] = strdup (longfsdp_buf); media->a_langs_count++; } } else if (!strncmp (fsdp_buf[0], "control", 7)) { if (NULL == media->a_controls) { media->a_controls_count = 0; media->a_controls = calloc (SDPCONTROLS_MAX_COUNT, sizeof (char *)); } if (media->a_controls_count < SDPCONTROLS_MAX_COUNT) { media->a_controls[media->a_controls_count] = strdup (longfsdp_buf); media->a_controls_count++; } } else if (!strncmp (fsdp_buf[0], "range", 5)) { if (media->a_range) free (media->a_range); media->a_range = strdup (fsdp_buf[1]); } else if (!strncmp (fsdp_buf[0], "framerate", 9)) media->a_framerate = strtod (longfsdp_buf, NULL); else if (!strncmp (fsdp_buf[0], "fmtp", 4)) { if (NULL == media->a_fmtps) { media->a_fmtps_count = 0; media->a_fmtps = calloc (SDPLANGS_MAX_COUNT, sizeof (char *)); } if (media->a_fmtps_count < SDPLANGS_MAX_COUNT) { media->a_fmtps[media->a_fmtps_count] = strdup (longfsdp_buf); media->a_fmtps_count++; } } else if (!strncmp (fsdp_buf[0], "rtcp", 4)) { int opts = 0; /* rtcp attribute: a=rtcp:<port> <nettype> <addrtype> <address> */ opts = sscanf (longfsdp_buf, "%lu %2s %3s %" MSFLENS "s", &wuint[0], fsdp_buf[0], fsdp_buf[1], fsdp_buf[2]); if (opts >= 1) { media->a_rtcp_port = wuint[0]; if (opts >= 2) { if (!strncmp (fsdp_buf[0], "IN", 2)) { media->a_rtcp_network_type = FSDP_NETWORK_TYPE_INET; } /* else ; TODO: define error code? */ if (opts >= 3) { if (!strncmp (fsdp_buf[1], "IP4", 3)) media->a_rtcp_address_type = FSDP_ADDRESS_TYPE_IPV4; else if (!strncmp (fsdp_buf[1], "IP6", 3)) media->a_rtcp_address_type = FSDP_ADDRESS_TYPE_IPV6; else return FSDPE_INVALID_CONNECTION_NETTYPE; /*add specific code? */ if (opts >= 4) media->a_rtcp_address = strdup (fsdp_buf[2]); } } } } else { /* ignore unknown attributes, but provide access to them */ *fsdp_buf[1] = '\0'; strncat (fsdp_buf[1], fsdp_buf[0], MAXSHORTFIELDLEN-1); strncat (fsdp_buf[1], ":", MAXSHORTFIELDLEN-strlen(fsdp_buf[1])-1); strncat (fsdp_buf[1], longfsdp_buf, MAXSHORTFIELDLEN-strlen(fsdp_buf[1])-1); if (NULL == media->unidentified_attributes) { media->unidentified_attributes_count = 0; media->unidentified_attributes = calloc (UNIDENTIFIED_ATTRIBUTES_MAX_COUNT, sizeof (char *)); } if (media->unidentified_attributes_count < UNIDENTIFIED_ATTRIBUTES_MAX_COUNT) { media->unidentified_attributes [media->unidentified_attributes_count] = strdup (fsdp_buf[1]); media->unidentified_attributes_count++; } } NEXT_LINE (p); } else if (sscanf (p, "a=%8s", fsdp_buf[0]) == 1) { /* media-level property attributes */ if (!strncmp (fsdp_buf[0], "recvonly", 8)) media->a_sendrecv_mode = FSDP_SENDRECV_RECVONLY; else if (!strncmp (fsdp_buf[0], "sendonly", 8)) media->a_sendrecv_mode = FSDP_SENDRECV_SENDONLY; else if (!strncmp (fsdp_buf[0], "inactive", 8)) media->a_sendrecv_mode = FSDP_SENDRECV_INACTIVE; else if (!strncmp (fsdp_buf[0], "sendrecv", 8)) media->a_sendrecv_mode = FSDP_SENDRECV_SENDRECV; else { /* ignore unknown attributes, but provide access to them */ *longfsdp_buf = '\0'; strncat (longfsdp_buf, fsdp_buf[0], MAXLONGFIELDLEN-1); if (NULL == media->unidentified_attributes) { media->unidentified_attributes_count = 0; media->unidentified_attributes = calloc (UNIDENTIFIED_ATTRIBUTES_MAX_COUNT, sizeof (char *)); } if (media->unidentified_attributes_count < UNIDENTIFIED_ATTRIBUTES_MAX_COUNT) { media->unidentified_attributes [media->unidentified_attributes_count] = strdup (longfsdp_buf); media->unidentified_attributes_count++; } } NEXT_LINE (p); } else return FSDPE_INVALID_ATTRIBUTE; } } /* end of for */ } /* Check c= has been given at session level or at media level for all media */ if (NULL == dsc->c_address.address) { unsigned int c; for (c = 0; c < dsc->media_announcements_count; c++) if (NULL == dsc->media_announcements[c]->c_address.address) return FSDPE_MISSING_CONNECTION_INFO; } /* finish */ if (*p == '\0') return FSDPE_OK; else return FSDPE_OVERFILLED;}static fsdp_error_tfsdp_parse_c (const char **p, fsdp_network_type_t * ntype, fsdp_address_type_t * atype, fsdp_connection_address_t * address){ const unsigned int TEMPCHARS = 3; char fsdp_buf[TEMPCHARS][MAXSHORTFIELDLEN]; if (!strncmp (*p, "c=", 2)) { if (sscanf (*p, "c=%2s %3s %" MSFLENS "s", fsdp_buf[0], fsdp_buf[1], fsdp_buf[2])) { if (!strncmp (fsdp_buf[0], "IN", 2)) { *ntype = FSDP_NETWORK_TYPE_INET; if (!strncmp (fsdp_buf[1], "IP4", 3)) *atype = FSDP_ADDRESS_TYPE_IPV4; else if (!strncmp (fsdp_buf[1], "IP6", 3)) *atype = FSDP_ADDRESS_TYPE_IPV6; else return FSDPE_INVALID_CONNECTION_NETTYPE; } else { return FSDPE_INVALID_CONNECTION_ADDRTYPE; } { char *slash = strchr (fsdp_buf[2], '/'); if (NULL == slash) { address->address = strdup (fsdp_buf[2]); address->address_ttl = 0; address->address_count = 0; } else { /* address is IP4 multicast */ char *slash2; *slash = '\0'; slash++; address->address = strdup (fsdp_buf[2]); slash2 = strchr (slash + 1, '/'); if (NULL == slash2) { address->address_ttl = strtol (slash, NULL, 10); address->address_count = 0; } else { *slash2 = '\0'; slash2++; address->address_ttl = strtol (slash, NULL, 10); address->address_count = strtol (slash2, NULL, 10); } } } NEXT_LINE (*p); } else { return FSDPE_INVALID_CONNECTION; } } return FSDPE_OK;}static fsdp_error_t
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -