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

📄 parser.c

📁 SDP文件解析代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        }        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 + -