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

📄 sdp_parse.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 4 页
字号:
  sdp_rtpmap_celb = RTPMAP(25, "CelB", 90000, 0),  sdp_rtpmap_jpeg = RTPMAP(26, "JPEG", 90000, 0),  sdp_rtpmap_nv = RTPMAP(28, "nv",   90000, 0),  sdp_rtpmap_h261 = RTPMAP(31, "H261", 90000, 0),  sdp_rtpmap_mpv = RTPMAP(32, "MPV",  90000, 0),  sdp_rtpmap_mp2t = RTPMAP(33, "MP2T", 90000, 0),  sdp_rtpmap_h263 = RTPMAP(34, "H263", 90000, 0);/** Table of rtpmap structures by payload type numbers. * * The table of reserved payload numbers is constructed from @RFC3551 * and @RFC1890. Note the clock rate of G722. * * Use sdp_rtpmap_dup() to copy these structures. */sdp_rtpmap_t const * const sdp_rtpmap_well_known[128] ={  &sdp_rtpmap_pcmu,		/* 0 */  &sdp_rtpmap_1016,		/* 1 */  &sdp_rtpmap_g721,		/* 2 */  &sdp_rtpmap_gsm,		/* 3 */  &sdp_rtpmap_g723,		/* 4 */  &sdp_rtpmap_dvi4_8000,	/* 5 */  &sdp_rtpmap_dvi4_16000,	/* 6 */  &sdp_rtpmap_lpc,		/* 7 */  &sdp_rtpmap_pcma,		/* 8 */  &sdp_rtpmap_g722,		/* 9 */  &sdp_rtpmap_l16_2,		/* 10 */  &sdp_rtpmap_l16,		/* 11 */  &sdp_rtpmap_qcelp,		/* 12 */  &sdp_rtpmap_cn,		/* 13 */  &sdp_rtpmap_mpa,		/* 14 */  &sdp_rtpmap_g728,		/* 15 */  &sdp_rtpmap_dvi4_11025,	/* 16 */  &sdp_rtpmap_dvi4_22050,	/* 17 */  &sdp_rtpmap_g729,		/* 18 */  &sdp_rtpmap_reserved_cn,	/* 19 */  NULL,				/* 20 */  NULL,				/* 21 */  NULL,				/* 22 */  NULL,				/* 23 */  NULL,				/* 24 */  &sdp_rtpmap_celb,		/* 25 */  &sdp_rtpmap_jpeg,		/* 26 */  NULL,				/* 27 */  &sdp_rtpmap_nv,		/* 28 */  NULL,				/* 29 */  NULL,				/* 30 */  &sdp_rtpmap_h261,		/* 31 */  &sdp_rtpmap_mpv,		/* 32 */  &sdp_rtpmap_mp2t,		/* 33 */  &sdp_rtpmap_h263,		/* 34 */  NULL,};/** * The function parse_payload() parses an RTP payload type list, and * creates an rtpmap structure for each payload type. * * @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_payload(sdp_parser_t *p, char *r, sdp_rtpmap_t **result){  while (*r) {    unsigned long value;    if (parse_ul(p, &r, &value, 128) == 0) {      PARSE_ALLOC(p, sdp_rtpmap_t, rm);      assert(0 <= value && value < 128);      *result = rm; result = &rm->rm_next;      if (sdp_rtpmap_well_known[value]) {	*rm = *sdp_rtpmap_well_known[value];      }      else {	rm->rm_predef = 1;	rm->rm_pt = value;	rm->rm_encoding = "";	rm->rm_rate = 0;      }    }    else if (p->pr_config && r[0] == '*' && (r[1] == ' ' || r[1] == '\0')) {      PARSE_ALLOC(p, sdp_rtpmap_t, rm);      *result = rm; result = &rm->rm_next;      rm->rm_predef = 1;      rm->rm_any = 1;      rm->rm_encoding = "*";      rm->rm_rate = 0;      return;    }    else {      parsing_error(p, "m= invalid format for RTP/AVT");      return;    }  }}/* ------------------------------------------------------------------------- * Function parse_media_attr() - parse a media-specific "a=" field * * Description: *   This function parses a media-specific attribute field. * * Parameters: *   p      - pointer to SDP parser object *   r      - pointer to record data *   result - pointer to which parsed record is assigned */static void parse_media_attr(sdp_parser_t *p, char *r, sdp_media_t *m,			     sdp_attribute_t **result){  /*   attribute-fields =    *("a=" attribute CRLF)   attribute =           (att-field ":" att-value) | att-field   att-field =           1*(alpha-numeric)    att-value =           byte-string   a=rtpmap:<payload type> <encoding name>/<clock rate>[/<encoding parameters>]   a=fmtp:<payload type> <parameters>   */  int rtp = sdp_media_has_rtp(m);  char *name = NULL, *value = NULL;  int n;  if (!(name = token(&r, ":", ALPHA DIGIT "-", SPACE TAB))) {    parsing_error(p,"invalid attribute name");    return;  }  if (*r)    value = r;  else     PARSE_CHECK_REST(p, r, "a");  if (p->pr_mode_manual)     ;  else if (strcasecmp(name, "inactive") == 0) {    m->m_mode = sdp_inactive;    return;  }  else if (strcasecmp(name, "sendonly") == 0) {    m->m_mode = sdp_sendonly;    return;  }  else if (strcasecmp(name, "recvonly") == 0) {    m->m_mode = sdp_recvonly;    return;  }  else if (strcasecmp(name, "sendrecv") == 0) {    m->m_mode = sdp_sendrecv;    return;  }  if (rtp && strcasecmp(name, "rtpmap") == 0) {    if ((n = parse_rtpmap(p, r, m)) == 0 || n < -1)      return;  }  else if (rtp && strcasecmp(name, "fmtp") == 0) {    if ((n = parse_fmtp(p, r, m)) == 0 || n < -1)      return;  }  else {    PARSE_ALLOC(p, sdp_attribute_t, a);    *result = a;    a->a_name  = name;    a->a_value = value;  }}/** Parse rtpmap attribute. * * a=rtpmap:<payload type> <encoding name>/<clock rate>[/<encoding parameters>] */static int parse_rtpmap(sdp_parser_t *p, char *r, sdp_media_t *m){  unsigned long pt, rate;  char *encoding, *params;  sdp_rtpmap_t *rm;  int strict = STRICT(p);  if (parse_ul(p, &r, &pt, 128)) {    if (strict)      parsing_error(p, "a=rtpmap: invalid payload type");    return -1;  }  for (rm = m->m_rtpmaps; rm; rm = rm->rm_next)    if (rm->rm_pt == pt)      break;  if (!rm) {    if (strict)      parsing_error(p, "a=rtpmap:%lu: unknown payload type", pt);    return -1;  }  encoding = token(&r, "/", ALPHA DIGIT "-", NULL);  if (!r) {    parsing_error(p, "a=rtpmap:%lu: missing <clock rate>", pt);    return -2;  }  if (parse_ul(p, &r, &rate, 0)) {    parsing_error(p, "a=rtpmap:%lu %s: invalid <clock rate>", pt, encoding);    return -2;  }  if (*r == '/')     params = ++r;  else    params = 0;      rm->rm_predef = 0;  rm->rm_encoding = encoding;  rm->rm_rate = rate;  rm->rm_params = params;  return 0;}/** Parse fmtp attribute. * * a=fmtp:<payload type> <parameters> */static int parse_fmtp(sdp_parser_t *p, char *r, sdp_media_t *m){  unsigned long pt;  sdp_rtpmap_t *rm;  int strict = STRICT(p);  if (parse_ul(p, &r, &pt, 128)) {    if (strict)      parsing_error(p, "a=rtpmap: invalid payload type");    return -1;  }  for (rm = m->m_rtpmaps; rm; rm = rm->rm_next)    if (rm->rm_pt == pt)      break;  if (!rm) {    if (strict)      parsing_error(p, "a=fmtp:%lu: unknown payload type", pt);    return -1;  }  rm->rm_fmtp = r;  return 0;}/* ------------------------------------------------------------------------- * Function parse_descs() - parse media descriptors * * Description: *   This function parses media descriptors at the end of SDP message. * * Parameters: *   p      - pointer to SDP parser object *   record - pointer to first media field *   message - pointer to rest  *   medias - pointer to which parsed media structures are assigned */static void parse_descs(sdp_parser_t *p, 			char *record, 			char *message, 			sdp_media_t **medias){  char *rest;  const char *strip;  sdp_media_t *m = NULL;  sdp_connection_t **connections = NULL;  sdp_bandwidth_t **bandwidths = NULL;  sdp_attribute_t **attributes = NULL;  if (!STRICT(p))    strip = SPACE TAB;		/* skip initial whitespace */  else    strip = "";    for (;       record && p->pr_ok;       record = next(&message, CRLF, strip)) {    char field = record[0];    rest = record + 2; rest += strspn(rest, strip);    if (record[1] == '=') switch (field) {    case 'c':      assert(connections);      parse_connection(p, rest, connections);      connections = &(*connections)->c_next;      break;    case 'b':      assert(bandwidths);      parse_bandwidth(p, rest, bandwidths);      bandwidths = &(*bandwidths)->b_next;      break;    case 'k':      parse_key(p, rest, &m->m_key);      break;    case 'a':      assert(attributes);      parse_media_attr(p, rest, m, attributes);      if (*attributes)	attributes = &(*attributes)->a_next;      break;    case 'm':      parse_media(p, rest, medias);      m = *medias;      if (m) {	m->m_mode = p->pr_session_mode;	medias = &m->m_next;	connections = &m->m_connections;	bandwidths = &m->m_bandwidths;	attributes = &m->m_attributes;      }    }  }}static void parse_text_list(sdp_parser_t *p, char *r, sdp_list_t **result){  PARSE_ALLOC(p, sdp_list_t, l);  *result = l;  l->l_text = r;}/* * parse_ul: parse an unsigned long */static int parse_ul(sdp_parser_t *p, char **r, 		    unsigned long *result, unsigned long max){  char *ul = *r;   ul += strspn(ul, SPACE TAB);  *result = strtoul(ul, r, 10);  if (ul != *r && !(max && max <= *result)) {    *r += strspn(*r, SPACE TAB);    return 0;  }  return -1;}#if !HAVE_STRTOULLunsigned longlong strtoull(char const *string, char **return_end, int base);#endif/* * parse_ull: parse an unsigned long long */static int parse_ull(sdp_parser_t *p, char **r, 		     uint64_t *result, uint64_t max){  unsigned longlong ull;  char *s = *r;   s += strspn(s, SPACE TAB);  ull = strtoull(s, r, 10);  if (s != *r && !(max && max <= ull)) {    *result = (uint64_t)ull;    *r += strspn(*r, SPACE TAB);    return 0;  }  return -1;}static char *token(char **message, 		   const char *sep, 		   const char *legal, 		   const char *strip){  size_t n;  char *retval = *message;  if (strip)    retval += strspn(retval, strip);  if (legal)    n = strspn(retval, legal);  else     n = strcspn(retval, sep);  if (n == 0)    return NULL;  if (retval[n]) {    retval[n++] = '\0';    n += strspn(retval + n, sep);  }  *message = retval + n;  if (*retval == '\0')    return NULL;  return retval;}static char *next(char **message, const char *sep, const char *strip){  size_t n;  char *retval = *message;  if (strip[0])    retval += strspn(retval, strip);  n = strcspn(retval, sep);  if (n == 0)    return NULL;  if (retval[n]) {    retval[n++] = '\0';    n += strspn(retval + n, sep);  }  *message = retval + n;  if (*retval == '\0')    return NULL;  return retval;}static int parsing_error(sdp_parser_t *p, char const *fmt, ...){  int n;  va_list ap;  va_start(ap, fmt);     memset(p->pr_error, 0, sizeof(p->pr_error));  n = vsnprintf(p->pr_error, sizeof(p->pr_error), fmt, ap);  va_end(ap);  p->pr_ok = 0;  return -1;}static void parse_alloc_error(sdp_parser_t *p, const char *typename){  parsing_error(p, "memory exhausted (while allocating memory for %s)", 		typename);}

⌨️ 快捷键说明

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