LCOV - code coverage report
Current view: top level - media/webrtc/signaling/src/sdp/sipcc - sdp_main.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 355 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 31 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* This Source Code Form is subject to the terms of the Mozilla Public
       2             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       3             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       4             : 
       5             : #include "sdp_os_defs.h"
       6             : #include "sdp.h"
       7             : #include "sdp_private.h"
       8             : 
       9             : #include "CSFLog.h"
      10             : 
      11             : static const char* logTag = "sdp_main";
      12             : 
      13             : /* Note: These *must* be in the same order as the enum types. */
      14             : const sdp_tokenarray_t sdp_token[SDP_MAX_TOKENS] =
      15             : {
      16             :     {"v=", sdp_parse_version,      sdp_build_version },
      17             :     {"o=", sdp_parse_owner,        sdp_build_owner },
      18             :     {"s=", sdp_parse_sessname,     sdp_build_sessname },
      19             :     {"i=", sdp_parse_sessinfo,     sdp_build_sessinfo },
      20             :     {"u=", sdp_parse_uri,          sdp_build_uri },
      21             :     {"e=", sdp_parse_email,        sdp_build_email },
      22             :     {"p=", sdp_parse_phonenum,     sdp_build_phonenum },
      23             :     {"c=", sdp_parse_connection,   sdp_build_connection },
      24             :     {"b=", sdp_parse_bandwidth,    sdp_build_bandwidth },
      25             :     {"t=", sdp_parse_timespec,     sdp_build_timespec },
      26             :     {"r=", sdp_parse_repeat_time,  sdp_build_repeat_time },
      27             :     {"z=", sdp_parse_timezone_adj, sdp_build_timezone_adj },
      28             :     {"k=", sdp_parse_encryption,   sdp_build_encryption },
      29             :     {"a=", sdp_parse_attribute,    sdp_build_attribute },
      30             :     {"m=", sdp_parse_media,        sdp_build_media }
      31             : };
      32             : 
      33             : 
      34             : /* Note: These *must* be in the same order as the enum types. */
      35             : const sdp_attrarray_t sdp_attr[SDP_MAX_ATTR_TYPES] =
      36             : {
      37             :     {"bearer", sizeof("bearer"),
      38             :      sdp_parse_attr_simple_string, sdp_build_attr_simple_string },
      39             :     {"called", sizeof("called"),
      40             :      sdp_parse_attr_simple_string, sdp_build_attr_simple_string },
      41             :     {"connection_type", sizeof("connection_type"),
      42             :      sdp_parse_attr_simple_string, sdp_build_attr_simple_string },
      43             :     {"dialed", sizeof("dialed"),
      44             :      sdp_parse_attr_simple_string, sdp_build_attr_simple_string },
      45             :     {"dialing", sizeof("dialing"),
      46             :      sdp_parse_attr_simple_string, sdp_build_attr_simple_string },
      47             :     {"direction", sizeof("direction"),
      48             :      sdp_parse_attr_comediadir, sdp_build_attr_comediadir },
      49             :     {"eecid", sizeof("eecid"),
      50             :      sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
      51             :     {"fmtp", sizeof("fmtp"),
      52             :      sdp_parse_attr_fmtp, sdp_build_attr_fmtp },
      53             :     {"sctpmap", sizeof("sctpmap"),
      54             :      sdp_parse_attr_sctpmap, sdp_build_attr_sctpmap },
      55             :     {"framing", sizeof("framing"),
      56             :      sdp_parse_attr_simple_string, sdp_build_attr_simple_string },
      57             :     {"inactive", sizeof("inactive"),
      58             :      sdp_parse_attr_direction, sdp_build_attr_direction },
      59             :     {"ptime", sizeof("ptime"),
      60             :      sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
      61             :     {"qos", sizeof("qos"),
      62             :      sdp_parse_attr_qos, sdp_build_attr_qos },
      63             :     {"curr", sizeof("curr"),
      64             :      sdp_parse_attr_curr, sdp_build_attr_curr },
      65             :     {"des", sizeof("des"),
      66             :      sdp_parse_attr_des, sdp_build_attr_des},
      67             :     {"conf", sizeof("conf"),
      68             :      sdp_parse_attr_conf, sdp_build_attr_conf},
      69             :     {"recvonly", sizeof("recvonly"),
      70             :      sdp_parse_attr_direction, sdp_build_attr_direction },
      71             :     {"rtpmap", sizeof("rtpmap"),
      72             :      sdp_parse_attr_transport_map, sdp_build_attr_transport_map },
      73             :     {"secure", sizeof("secure"),
      74             :      sdp_parse_attr_qos, sdp_build_attr_qos },
      75             :     {"sendonly", sizeof("sendonly"),
      76             :      sdp_parse_attr_direction, sdp_build_attr_direction },
      77             :     {"sendrecv", sizeof("sendrecv"),
      78             :      sdp_parse_attr_direction, sdp_build_attr_direction },
      79             :     {"subnet", sizeof("subnet"),
      80             :      sdp_parse_attr_subnet, sdp_build_attr_subnet },
      81             :     {"T38FaxVersion", sizeof("T38FaxVersion"),
      82             :      sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
      83             :     {"T38MaxBitRate", sizeof("T38MaxBitRate"),
      84             :      sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
      85             :     {"T38FaxFillBitRemoval", sizeof("T38FaxFillBitRemoval"),
      86             :      sdp_parse_attr_simple_bool, sdp_build_attr_simple_bool },
      87             :     {"T38FaxTranscodingMMR", sizeof("T38FaxTranscodingMMR"),
      88             :      sdp_parse_attr_simple_bool, sdp_build_attr_simple_bool },
      89             :     {"T38FaxTranscodingJBIG", sizeof("T38FaxTranscodingJBIG"),
      90             :      sdp_parse_attr_simple_bool, sdp_build_attr_simple_bool },
      91             :     {"T38FaxRateManagement", sizeof("T38FaxRateManagement"),
      92             :      sdp_parse_attr_t38_ratemgmt, sdp_build_attr_t38_ratemgmt },
      93             :     {"T38FaxMaxBuffer", sizeof("T38FaxMaxBuffer"),
      94             :      sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
      95             :     {"T38FaxMaxDatagram", sizeof("T38FaxMaxDatagram"),
      96             :      sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
      97             :     {"T38FaxUdpEC", sizeof("T38FaxUdpEC"),
      98             :      sdp_parse_attr_t38_udpec, sdp_build_attr_t38_udpec },
      99             :     {"X-cap", sizeof("X-cap"),
     100             :      sdp_parse_attr_cap, sdp_build_attr_cap },
     101             :     {"X-cpar", sizeof("X-cpar"),
     102             :      sdp_parse_attr_cpar, sdp_build_attr_cpar },
     103             :     {"X-pc-codec", sizeof("X-pc-codec"),
     104             :      sdp_parse_attr_pc_codec, sdp_build_attr_pc_codec },
     105             :     {"X-pc-qos", sizeof("X-pc-qos"),
     106             :      sdp_parse_attr_qos, sdp_build_attr_qos },
     107             :     {"X-qos", sizeof("X-qos"),
     108             :      sdp_parse_attr_qos, sdp_build_attr_qos },
     109             :     {"X-sqn", sizeof("X-sqn"),
     110             :      sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
     111             :     {"TMRGwXid", sizeof("TMRGwXid"),
     112             :      sdp_parse_attr_simple_bool, sdp_build_attr_simple_bool },
     113             :     {"TC1PayloadBytes", sizeof("TC1PayloadBytes"),
     114             :      sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
     115             :     {"TC1WindowSize", sizeof("TC1WindowSize"),
     116             :      sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
     117             :     {"TC2PayloadBytes", sizeof("TC2PayloadBytes"),
     118             :      sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
     119             :     {"TC2WindowSize", sizeof("TC2WindowSize"),
     120             :      sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
     121             :     {"rtcp", sizeof("rtcp"),
     122             :      sdp_parse_attr_rtcp, sdp_build_attr_rtcp },
     123             :     {"rtr", sizeof("rtr"),
     124             :      sdp_parse_attr_rtr, sdp_build_attr_rtr},
     125             :     {"silenceSupp", sizeof("silenceSupp"),
     126             :      sdp_parse_attr_silencesupp, sdp_build_attr_silencesupp },
     127             :     {"X-crypto", sizeof("X-crypto"),
     128             :      sdp_parse_attr_srtpcontext, sdp_build_attr_srtpcontext },
     129             :     {"mptime", sizeof("mptime"),
     130             :       sdp_parse_attr_mptime, sdp_build_attr_mptime },
     131             :     {"X-sidin", sizeof("X-sidin"),
     132             :       sdp_parse_attr_x_sidin, sdp_build_attr_x_sidin },
     133             :     {"X-sidout", sizeof("X-sidout"),
     134             :       sdp_parse_attr_x_sidout, sdp_build_attr_x_sidout },
     135             :     {"X-confid", sizeof("X-confid"),
     136             :       sdp_parse_attr_x_confid, sdp_build_attr_x_confid },
     137             :     {"group", sizeof("group"),
     138             :       sdp_parse_attr_group, sdp_build_attr_group },
     139             :     {"mid", sizeof("mid"),
     140             :       sdp_parse_attr_simple_string, sdp_build_attr_simple_string },
     141             :     {"source-filter", sizeof("source-filter"),
     142             :       sdp_parse_attr_source_filter, sdp_build_source_filter},
     143             :     {"rtcp-unicast", sizeof("rtcp-unicast"),
     144             :       sdp_parse_attr_rtcp_unicast, sdp_build_attr_rtcp_unicast},
     145             :     {"maxprate", sizeof("maxprate"),
     146             :       sdp_parse_attr_maxprate, sdp_build_attr_simple_string},
     147             :     {"sqn", sizeof("sqn"),
     148             :      sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
     149             :     {"cdsc", sizeof("cdsc"),
     150             :      sdp_parse_attr_cap, sdp_build_attr_cap },
     151             :     {"cpar", sizeof("cpar"),
     152             :      sdp_parse_attr_cpar, sdp_build_attr_cpar },
     153             :     {"sprtmap", sizeof("sprtmap"),
     154             :      sdp_parse_attr_transport_map, sdp_build_attr_transport_map },
     155             :     {"crypto", sizeof("crypto"),
     156             :      sdp_parse_attr_sdescriptions, sdp_build_attr_sdescriptions },
     157             :     {"label", sizeof("label"),
     158             :       sdp_parse_attr_simple_string, sdp_build_attr_simple_string },
     159             :     {"framerate", sizeof("framerate"),
     160             :       sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 },
     161             :     {"candidate", sizeof("candidate"),
     162             :       sdp_parse_attr_ice_attr, sdp_build_attr_ice_attr },
     163             :     {"ice-ufrag", sizeof("ice-ufrag"),
     164             :       sdp_parse_attr_ice_attr, sdp_build_attr_ice_attr },
     165             :     {"ice-pwd", sizeof("ice-pwd"),
     166             :       sdp_parse_attr_ice_attr, sdp_build_attr_ice_attr},
     167             :     {"ice-lite", sizeof("ice-lite"),
     168             :       sdp_parse_attr_simple_flag, sdp_build_attr_simple_flag},
     169             :     {"rtcp-mux", sizeof("rtcp-mux"),
     170             :       sdp_parse_attr_simple_flag, sdp_build_attr_simple_flag},
     171             :     {"fingerprint", sizeof("fingerprint"),
     172             :       sdp_parse_attr_complete_line, sdp_build_attr_simple_string},
     173             :     {"maxptime", sizeof("maxptime"),
     174             :       sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32},
     175             :     {"rtcp-fb", sizeof("rtcp-fb"),
     176             :       sdp_parse_attr_rtcp_fb, sdp_build_attr_rtcp_fb},
     177             :     {"setup", sizeof("setup"),
     178             :       sdp_parse_attr_setup, sdp_build_attr_setup},
     179             :     {"connection", sizeof("connection"),
     180             :       sdp_parse_attr_connection, sdp_build_attr_connection},
     181             :     {"extmap", sizeof("extmap"),
     182             :       sdp_parse_attr_extmap, sdp_build_attr_extmap},
     183             :     {"identity", sizeof("identity"),
     184             :       sdp_parse_attr_long_line, sdp_build_attr_long_line},
     185             :     {"msid", sizeof("msid"),
     186             :       sdp_parse_attr_msid, sdp_build_attr_msid},
     187             :     {"msid-semantic", sizeof("msid-semantic"),
     188             :       sdp_parse_attr_msid_semantic, sdp_build_attr_msid_semantic},
     189             :     {"bundle-only", sizeof("bundle-only"),
     190             :       sdp_parse_attr_simple_flag, sdp_build_attr_simple_flag},
     191             :     {"end-of-candidates", sizeof("end-of-candidates"),
     192             :       sdp_parse_attr_simple_flag, sdp_build_attr_simple_flag},
     193             :     {"ice-options", sizeof("ice-options"),
     194             :       sdp_parse_attr_complete_line, sdp_build_attr_simple_string},
     195             :     {"ssrc", sizeof("ssrc"),
     196             :       sdp_parse_attr_ssrc, sdp_build_attr_ssrc},
     197             :     {"imageattr", sizeof("imageattr"),
     198             :       sdp_parse_attr_complete_line, sdp_build_attr_simple_string},
     199             :     {"simulcast", sizeof("simulcast"),
     200             :       sdp_parse_attr_complete_line, sdp_build_attr_simple_string},
     201             :     {"rid", sizeof("rid"),
     202             :       sdp_parse_attr_complete_line, sdp_build_attr_simple_string},
     203             :     {"dtls-message", sizeof("dtls-message"),
     204             :       sdp_parse_attr_long_line, sdp_build_attr_long_line},
     205             :     {"sctp-port", sizeof("sctp-port"),
     206             :       sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32},
     207             :     {"max-message-size", sizeof("max-message-size"),
     208             :       sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32},
     209             : };
     210             : 
     211             : /* Note: These *must* be in the same order as the enum types. */
     212             : const sdp_namearray_t sdp_media[SDP_MAX_MEDIA_TYPES] =
     213             : {
     214             :     {"audio",        sizeof("audio")},
     215             :     {"video",        sizeof("video")},
     216             :     {"application",  sizeof("application")},
     217             :     {"data",         sizeof("data")},
     218             :     {"control",      sizeof("control")},
     219             :     {"nas/radius",   sizeof("nas/radius")},
     220             :     {"nas/tacacs",   sizeof("nas/tacacs")},
     221             :     {"nas/diameter", sizeof("nas/diameter")},
     222             :     {"nas/l2tp",     sizeof("nas/l2tp")},
     223             :     {"nas/login",    sizeof("nas/login")},
     224             :     {"nas/none",     sizeof("nas/none")},
     225             :     {"image",        sizeof("image")},
     226             :     {"text",         sizeof("text")}
     227             : };
     228             : 
     229             : 
     230             : /* Note: These *must* be in the same order as the enum types. */
     231             : const sdp_namearray_t sdp_nettype[SDP_MAX_NETWORK_TYPES] =
     232             : {
     233             :     {"IN",           sizeof("IN")},
     234             :     {"ATM",          sizeof("ATM")},
     235             :     {"FR",           sizeof("FR")},
     236             :     {"LOCAL",        sizeof("LOCAL")}
     237             : };
     238             : 
     239             : 
     240             : /* Note: These *must* be in the same order as the enum types. */
     241             : const sdp_namearray_t sdp_addrtype[SDP_MAX_ADDR_TYPES] =
     242             : {
     243             :     {"IP4",          sizeof("IP4")},
     244             :     {"IP6",          sizeof("IP6")},
     245             :     {"NSAP",         sizeof("NSAP")},
     246             :     {"EPN",          sizeof("EPN")},
     247             :     {"E164",         sizeof("E164")},
     248             :     {"GWID",         sizeof("GWID")}
     249             : };
     250             : 
     251             : 
     252             : /* Note: These *must* be in the same order as the enum type. */
     253             : const sdp_namearray_t sdp_transport[SDP_MAX_TRANSPORT_TYPES] =
     254             : {
     255             :     {"RTP/AVP",      sizeof("RTP/AVP")},
     256             :     {"udp",          sizeof("udp")},
     257             :     {"udptl",        sizeof("udptl")},
     258             :     {"ces10",        sizeof("ces10")},
     259             :     {"LOCAL",        sizeof("LOCAL")},
     260             :     {"AAL2/ITU",     sizeof("AAL2/ITU")},
     261             :     {"AAL2/ATMF",    sizeof("AAL2/ATMF")},
     262             :     {"AAL2/custom",  sizeof("AAL2/custom")},
     263             :     {"AAL1/AVP",     sizeof("AAL1/AVP")},
     264             :     {"udpsprt",      sizeof("udpsprt")},
     265             :     {"RTP/SAVP",     sizeof("RTP/SAVP")},
     266             :     {"tcp",          sizeof("tcp")},
     267             :     {"RTP/SAVPF",    sizeof("RTP/SAVPF")},
     268             :     {"DTLS/SCTP",    sizeof("DTLS/SCTP")},
     269             :     {"RTP/AVPF",     sizeof("RTP/AVPF")},
     270             :     {"UDP/TLS/RTP/SAVP", sizeof("UDP/TLS/RTP/SAVP")},
     271             :     {"UDP/TLS/RTP/SAVPF", sizeof("UDP/TLS/RTP/SAVPF")},
     272             :     {"TCP/TLS/RTP/SAVP", sizeof("TCP/TLS/RTP/SAVP")},
     273             :     {"TCP/TLS/RTP/SAVPF", sizeof("TCP/TLS/RTP/SAVPF")},
     274             :     {"UDP/DTLS/SCTP",    sizeof("UDP/DTLS/SCTP")},
     275             :     {"TCP/DTLS/SCTP",    sizeof("TCP/DTLS/SCTP")},
     276             : };
     277             : 
     278             : /* Note: These *must* be in the same order as the enum type. */
     279             : const sdp_namearray_t sdp_encrypt[SDP_MAX_ENCRYPT_TYPES] =
     280             : {
     281             :     {"clear",        sizeof("clear")},
     282             :     {"base64",       sizeof("base64")},
     283             :     {"uri",          sizeof("uri")},
     284             :     {"prompt",       sizeof("prompt")}
     285             : };
     286             : 
     287             : /* Note: These *must* be in the same order as the enum type. */
     288             : const sdp_namearray_t sdp_payload[SDP_MAX_STRING_PAYLOAD_TYPES] =
     289             : {
     290             :     {"t38",          sizeof("t38")},
     291             :     {"X-tmr",        sizeof("X-tmr")},
     292             :     {"T120",         sizeof("T120")}
     293             : };
     294             : 
     295             : /* Note: These *must* be in the same order as the enum type. */
     296             : const sdp_namearray_t sdp_t38_rate[SDP_T38_MAX_RATES] =
     297             : {
     298             :     {"localTCF",        sizeof("localTCF")},
     299             :     {"transferredTCF",  sizeof("transferredTCF")},
     300             :     {"unknown",         sizeof("unknown")}
     301             : };
     302             : 
     303             : /* Note: These *must* be in the same order as the enum type. */
     304             : const sdp_namearray_t sdp_t38_udpec[SDP_T38_MAX_UDPEC] =
     305             : {
     306             :     {"t38UDPRedundancy",  sizeof("t38UDPRedundancy")},
     307             :     {"t38UDPFEC",         sizeof("t38UDPFEC")},
     308             :     {"unknown",           sizeof("unknown")}
     309             : };
     310             : 
     311             : /* Note: These *must* be in the same order as the enum type. */
     312             : const sdp_namearray_t sdp_qos_strength[SDP_MAX_QOS_STRENGTH] =
     313             : {
     314             :     {"optional",          sizeof("optional")},
     315             :     {"mandatory",         sizeof("mandatory")},
     316             :     {"success",           sizeof("success")},
     317             :     {"failure",           sizeof("failure")},
     318             :     {"none",              sizeof("none")}
     319             : };
     320             : 
     321             : /* Note: These *must* be in the same order as the enum type. */
     322             : const sdp_namearray_t sdp_qos_status_type[SDP_MAX_QOS_STATUS_TYPES] =
     323             : {
     324             :     {"local",          sizeof("local")},
     325             :     {"remote",         sizeof("remote")},
     326             :     {"e2e",            sizeof("e2e")}
     327             : };
     328             : 
     329             : /* Note: These *must* be in the same order as the enum type. */
     330             : const sdp_namearray_t sdp_curr_type[SDP_MAX_CURR_TYPES] =
     331             : {
     332             :     {"qos",            sizeof("qos")},
     333             :     {"unknown",         sizeof("unknown")}
     334             : };
     335             : 
     336             : /* Note: These *must* be in the same order as the enum type. */
     337             : const sdp_namearray_t sdp_des_type[SDP_MAX_DES_TYPES] =
     338             : {
     339             :     {"qos",            sizeof("qos")},
     340             :     {"unknown",         sizeof("unknown")}
     341             : };
     342             : 
     343             : /* Note: These *must* be in the same order as the enum type. */
     344             : const sdp_namearray_t sdp_conf_type[SDP_MAX_CONF_TYPES] =
     345             : {
     346             :     {"qos",            sizeof("qos")},
     347             :     {"unknown",         sizeof("unknown")}
     348             : };
     349             : /* Note: These *must* be in the same order as the enum type. */
     350             : const sdp_namearray_t sdp_qos_direction[SDP_MAX_QOS_DIR] =
     351             : {
     352             :     {"send",              sizeof("send")},
     353             :     {"recv",              sizeof("recv")},
     354             :     {"sendrecv",          sizeof("sendrecv")},
     355             :     {"none",              sizeof("none")}
     356             : };
     357             : 
     358             : /* Note: These *must* be in the same order as the enum type. */
     359             : const sdp_namearray_t sdp_silencesupp_pref[SDP_MAX_SILENCESUPP_PREF] = {
     360             :     {"standard",          sizeof("standard")},
     361             :     {"custom",            sizeof("custom")},
     362             :     {"-",                 sizeof("-")}
     363             : };
     364             : 
     365             : /* Note: These *must* be in the same order as the enum type. */
     366             : const sdp_namearray_t sdp_silencesupp_siduse[SDP_MAX_SILENCESUPP_SIDUSE] = {
     367             :     {"No SID",            sizeof("No SID")},
     368             :     {"Fixed Noise",       sizeof("Fixed Noise")},
     369             :     {"Sampled Noise",     sizeof("Sampled Noise")},
     370             :     {"-",                 sizeof("-")}
     371             : };
     372             : 
     373             : /* Note: These *must* be in the same order as the enum type. */
     374             : const sdp_namearray_t sdp_mediadir_role[SDP_MAX_MEDIADIR_ROLES] =
     375             : {
     376             :     {"passive",       sizeof("passive")},
     377             :     {"active",        sizeof("active")},
     378             :     {"both",          sizeof("both")},
     379             :     {"reuse",         sizeof("reuse")},
     380             :     {"unknown",       sizeof("unknown")}
     381             : };
     382             : 
     383             : /* Note: These *must* be in the same order as the enum type. */
     384             : const sdp_namearray_t sdp_fmtp_codec_param[SDP_MAX_FMTP_PARAM] =
     385             : {
     386             :     {"annexa",              sizeof("annexa")}, /* 0 */
     387             :     {"annexb",              sizeof("annexb")}, /* 1 */
     388             :     {"bitrate",             sizeof("bitrate")}, /* 2 */
     389             :     {"QCIF",                sizeof("QCIF")}, /* 3 */
     390             :     {"CIF",                 sizeof("CIF")},  /* 4 */
     391             :     {"MAXBR",               sizeof("MAXBR")}, /* 5 */
     392             :     {"SQCIF",               sizeof("SQCIF")}, /* 6 */
     393             :     {"CIF4",                sizeof("CIF4")}, /* 7 */
     394             :     {"CIF16",               sizeof("CIF16")}, /* 8 */
     395             :     {"CUSTOM",              sizeof("CUSTOM")}, /* 9 */
     396             :     {"PAR",                 sizeof("PAR")}, /* 10 */
     397             :     {"CPCF",                sizeof("CPCF")}, /* 11 */
     398             :     {"BPP",                 sizeof("BPP")}, /* 12 */
     399             :     {"HRD",                 sizeof("HRD")}, /* 13 */
     400             :     {"PROFILE",             sizeof("PROFILE")}, /* 14 */
     401             :     {"LEVEL",               sizeof("LEVEL")}, /* 15 */
     402             :     {"INTERLACE",           sizeof("INTERLACE")}, /* 16 */
     403             : 
     404             :     /* H.264 related */
     405             :     {"profile-level-id",      sizeof("profile-level-id")}, /* 17 */
     406             :     {"sprop-parameter-sets",  sizeof("sprop-parameter-sets")}, /* 18 */
     407             :     {"packetization-mode",    sizeof("packetization-mode")}, /* 19 */
     408             :     {"sprop-interleaving-depth",    sizeof("sprop-interleaving-depth")}, /* 20 */
     409             :     {"sprop-deint-buf-req",   sizeof("sprop-deint-buf-req")}, /* 21 */
     410             :     {"sprop-max-don-diff",    sizeof("sprop-max-don-diff")}, /* 22 */
     411             :     {"sprop-init-buf-time",   sizeof("sprop-init-buf-time")}, /* 23 */
     412             : 
     413             :     {"max-mbps",              sizeof("max-mbps")}, /* 24 */
     414             :     {"max-fs",                sizeof("max-fs")}, /* 25 */
     415             :     {"max-cpb",               sizeof("max-cpb")}, /* 26 */
     416             :     {"max-dpb",               sizeof("max-dpb")}, /* 27 */
     417             :     {"max-br",                sizeof("max-br")}, /* 28 */
     418             :     {"redundant-pic-cap",     sizeof("redundant-pic-cap")}, /* 29 */
     419             :     {"deint-buf-cap",         sizeof("deint-buf-cap")}, /* 30 */
     420             :     {"max-rcmd-nalu-size",    sizeof("max-rcmd_nali-size")}, /* 31 */
     421             :     {"parameter-add",         sizeof("parameter-add")}, /* 32 */
     422             : 
     423             :     /* Annexes - require special handling */
     424             :      {"D", sizeof("D")}, /* 33 */
     425             :      {"F", sizeof("F")}, /* 34 */
     426             :      {"I", sizeof("I")}, /* 35 */
     427             :      {"J", sizeof("J")}, /* 36 */
     428             :      {"T", sizeof("T")}, /* 37 */
     429             :      {"K", sizeof("K")}, /* 38 */
     430             :      {"N", sizeof("N")}, /* 39 */
     431             :      {"P", sizeof("P")}, /* 40 */
     432             : 
     433             :      {"mode",                sizeof("mode")},  /* 41 */
     434             :     {"level-asymmetry-allowed",         sizeof("level-asymmetry-allowed")}, /* 42 */
     435             :     {"maxaveragebitrate",               sizeof("maxaveragebitrate")}, /* 43 */
     436             :     {"usedtx",                          sizeof("usedtx")}, /* 44 */
     437             :     {"stereo",                          sizeof("stereo")}, /* 45 */
     438             :     {"useinbandfec",                    sizeof("useinbandfec")}, /* 46 */
     439             :     {"maxcodedaudiobandwidth",          sizeof("maxcodedaudiobandwidth")}, /* 47 */
     440             :     {"cbr",                             sizeof("cbr")}, /* 48 */
     441             :     {"max-fr",                          sizeof("max-fr")}, /* 49 */
     442             :     {"maxplaybackrate",                 sizeof("maxplaybackrate")} /* 50 */
     443             : } ;
     444             : 
     445             : /* Note: These *must* be in the same order as the enum type. */
     446             : const sdp_namearray_t sdp_fmtp_codec_param_val[SDP_MAX_FMTP_PARAM_VAL] =
     447             : {
     448             :     {"yes",                 sizeof("yes")},
     449             :     {"no",                  sizeof("no")}
     450             : };
     451             : 
     452             : const sdp_namearray_t sdp_bw_modifier_val[SDP_MAX_BW_MODIFIER_VAL] =
     453             : {
     454             :     {"AS",                  sizeof("AS")},
     455             :     {"CT",                  sizeof("CT")},
     456             :     {"TIAS",                sizeof("TIAS")}
     457             : };
     458             : 
     459             : const sdp_namearray_t sdp_group_attr_val[SDP_MAX_GROUP_ATTR_VAL] =
     460             : {
     461             :     {"FID",                 sizeof("FID")},
     462             :     {"LS",                  sizeof("LS")},
     463             :     {"ANAT",                sizeof("ANAT")},
     464             :     {"BUNDLE",              sizeof("BUNDLE")}
     465             : };
     466             : 
     467             : const sdp_namearray_t sdp_srtp_context_crypto_suite[SDP_SRTP_MAX_NUM_CRYPTO_SUITES] =
     468             : {
     469             :   {"UNKNOWN_CRYPTO_SUITE",    sizeof("UNKNOWN_CRYPTO_SUITE")},
     470             :   {"AES_CM_128_HMAC_SHA1_32", sizeof("AES_CM_128_HMAC_SHA1_32")},
     471             :   {"AES_CM_128_HMAC_SHA1_80", sizeof("AES_CM_128_HMAC_SHA1_80")},
     472             :   {"F8_128_HMAC_SHA1_80", sizeof("F8_128_HMAC_SHA1_80")}
     473             : };
     474             : 
     475             : /* Maintain the same order as defined in typedef sdp_src_filter_mode_e */
     476             : const sdp_namearray_t sdp_src_filter_mode_val[SDP_MAX_FILTER_MODE] =
     477             : {
     478             :     {"incl", sizeof("incl")},
     479             :     {"excl", sizeof("excl")}
     480             : };
     481             : 
     482             : /* Maintain the same order as defined in typdef sdp_rtcp_unicast_mode_e */
     483             : const sdp_namearray_t sdp_rtcp_unicast_mode_val[SDP_RTCP_MAX_UNICAST_MODE] =
     484             : {
     485             :     {"reflection", sizeof("reflection")},
     486             :     {"rsi",        sizeof("rsi")}
     487             : };
     488             : 
     489             : #define SDP_NAME(x) {x, sizeof(x)}
     490             : /* Maintain the same order as defined in typdef sdp_rtcp_fb_type_e */
     491             : const sdp_namearray_t sdp_rtcp_fb_type_val[SDP_MAX_RTCP_FB] =
     492             : {
     493             :     SDP_NAME("ack"),
     494             :     SDP_NAME("ccm"),
     495             :     SDP_NAME("nack"),
     496             :     SDP_NAME("trr-int"),
     497             :     SDP_NAME("goog-remb")
     498             : };
     499             : 
     500             : /* Maintain the same order as defined in typdef sdp_rtcp_fb_nack_type_e */
     501             : const sdp_namearray_t sdp_rtcp_fb_nack_type_val[SDP_MAX_RTCP_FB_NACK] =
     502             : {
     503             :     SDP_NAME(""),
     504             :     SDP_NAME("sli"),
     505             :     SDP_NAME("pli"),
     506             :     SDP_NAME("rpsi"),
     507             :     SDP_NAME("app"),
     508             :     SDP_NAME("rai"),
     509             :     SDP_NAME("tllei"),
     510             :     SDP_NAME("pslei"),
     511             :     SDP_NAME("ecn")
     512             : };
     513             : 
     514             : /* Maintain the same order as defined in typdef sdp_rtcp_fb_ack_type_e */
     515             : const sdp_namearray_t sdp_rtcp_fb_ack_type_val[SDP_MAX_RTCP_FB_ACK] =
     516             : {
     517             :     SDP_NAME("rpsi"),
     518             :     SDP_NAME("app")
     519             : };
     520             : 
     521             : /* Maintain the same order as defined in typdef sdp_rtcp_fb_ccm_type_e */
     522             : const sdp_namearray_t sdp_rtcp_fb_ccm_type_val[SDP_MAX_RTCP_FB_CCM] =
     523             : {
     524             :     SDP_NAME("fir"),
     525             :     SDP_NAME("tmmbr"),
     526             :     SDP_NAME("tstr"),
     527             :     SDP_NAME("vbcm")
     528             : };
     529             : 
     530             : /* Maintain the same order as defined in typedef sdp_setup_type_e */
     531             : const sdp_namearray_t sdp_setup_type_val[SDP_MAX_SETUP] =
     532             : {
     533             :     SDP_NAME("active"),
     534             :     SDP_NAME("passive"),
     535             :     SDP_NAME("actpass"),
     536             :     SDP_NAME("holdconn")
     537             : };
     538             : 
     539             : /* Maintain the same order as defined in typedef sdp_connection_type_e */
     540             : const sdp_namearray_t sdp_connection_type_val[SDP_MAX_CONNECTION] =
     541             : {
     542             :     SDP_NAME("new"),
     543             :     SDP_NAME("existing")
     544             : };
     545             : 
     546             : /*  Maintain same order as defined in typedef sdp_srtp_crypto_suite_t */
     547             : const sdp_srtp_crypto_suite_list sdp_srtp_crypto_suite_array[SDP_SRTP_MAX_NUM_CRYPTO_SUITES] =
     548             : {
     549             :   {SDP_SRTP_UNKNOWN_CRYPTO_SUITE, UNKNOWN_CRYPTO_SUITE, 0, 0},
     550             :   {SDP_SRTP_AES_CM_128_HMAC_SHA1_32, AES_CM_128_HMAC_SHA1_32,
     551             :       SDP_SRTP_AES_CM_128_HMAC_SHA1_32_KEY_BYTES,
     552             :       SDP_SRTP_AES_CM_128_HMAC_SHA1_32_SALT_BYTES},
     553             :   {SDP_SRTP_AES_CM_128_HMAC_SHA1_80, AES_CM_128_HMAC_SHA1_80,
     554             :       SDP_SRTP_AES_CM_128_HMAC_SHA1_80_KEY_BYTES,
     555             :       SDP_SRTP_AES_CM_128_HMAC_SHA1_80_SALT_BYTES},
     556             :   {SDP_SRTP_F8_128_HMAC_SHA1_80, F8_128_HMAC_SHA1_80,
     557             :       SDP_SRTP_F8_128_HMAC_SHA1_80_KEY_BYTES,
     558             :       SDP_SRTP_F8_128_HMAC_SHA1_80_SALT_BYTES}
     559             : };
     560             : 
     561             : const char* sdp_result_name[SDP_MAX_RC] =
     562             :     {"SDP_SUCCESS",
     563             :      "SDP_FAILURE",
     564             :      "SDP_INVALID_SDP_PTR",
     565             :      "SDP_NOT_SDP_DESCRIPTION",
     566             :      "SDP_INVALID_TOKEN_ORDERING",
     567             :      "SDP_INVALID_PARAMETER",
     568             :      "SDP_INVALID_MEDIA_LEVEL",
     569             :      "SDP_INVALID_CAPABILITY",
     570             :      "SDP_NO_RESOURCE",
     571             :      "SDP_UNRECOGNIZED_TOKEN",
     572             :      "SDP_NULL_BUF_PTR",
     573             :      "SDP_POTENTIAL_SDP_OVERFLOW",
     574             :      "SDP_EMPTY_TOKEN"};
     575             : 
     576           0 : const char *sdp_get_result_name ( sdp_result_e rc )
     577             : {
     578           0 :     if (rc >= SDP_MAX_RC) {
     579           0 :         return ("Invalid SDP result code");
     580             :     } else {
     581           0 :         return (sdp_result_name[rc]);
     582             :     }
     583             : }
     584             : 
     585           0 : const char *sdp_get_attr_name ( sdp_attr_e attr_type )
     586             : {
     587           0 :     if (attr_type >= SDP_MAX_ATTR_TYPES) {
     588           0 :         return ("Invalid attribute type");
     589             :     } else {
     590           0 :         return (sdp_attr[attr_type].name);
     591             :     }
     592             : }
     593             : 
     594           0 : const char *sdp_get_media_name ( sdp_media_e media_type )
     595             : {
     596           0 :     if (media_type == SDP_MEDIA_UNSUPPORTED) {
     597           0 :         return (SDP_UNSUPPORTED);
     598           0 :     } else if (media_type >= SDP_MAX_MEDIA_TYPES) {
     599           0 :         return ("Invalid media type");
     600             :     } else {
     601           0 :         return (sdp_media[media_type].name);
     602             :     }
     603             : }
     604             : 
     605           0 : const char *sdp_get_network_name ( sdp_nettype_e network_type )
     606             : {
     607           0 :     if (network_type == SDP_NT_UNSUPPORTED) {
     608           0 :         return (SDP_UNSUPPORTED);
     609           0 :     } else if (network_type >= SDP_MAX_NETWORK_TYPES) {
     610           0 :         return ("Invalid network type");
     611             :     } else {
     612           0 :         return (sdp_nettype[network_type].name);
     613             :     }
     614             : }
     615             : 
     616           0 : const char *sdp_get_address_name ( sdp_addrtype_e addr_type )
     617             : {
     618           0 :     if (addr_type == SDP_AT_UNSUPPORTED) {
     619           0 :         return (SDP_UNSUPPORTED);
     620           0 :     } else if (addr_type >= SDP_MAX_ADDR_TYPES) {
     621           0 :         if (addr_type == SDP_AT_FQDN) {
     622           0 :             return ("*");
     623             :         } else {
     624           0 :             return ("Invalid address type");
     625             :         }
     626             :     } else {
     627           0 :         return (sdp_addrtype[addr_type].name);
     628             :     }
     629             : }
     630             : 
     631           0 : const char *sdp_get_transport_name ( sdp_transport_e transport_type )
     632             : {
     633           0 :     if (transport_type == SDP_TRANSPORT_UNSUPPORTED) {
     634           0 :         return (SDP_UNSUPPORTED);
     635           0 :     } else if (transport_type >= SDP_MAX_TRANSPORT_TYPES) {
     636           0 :         return ("Invalid transport type");
     637             :     } else {
     638           0 :         return (sdp_transport[transport_type].name);
     639             :     }
     640             : }
     641             : 
     642           0 : const char *sdp_get_encrypt_name ( sdp_encrypt_type_e encrypt_type )
     643             : {
     644           0 :     if (encrypt_type == SDP_ENCRYPT_UNSUPPORTED) {
     645           0 :         return (SDP_UNSUPPORTED);
     646           0 :     } else if (encrypt_type >= SDP_MAX_ENCRYPT_TYPES) {
     647           0 :         return ("Invalid encryption type");
     648             :     } else {
     649           0 :         return (sdp_encrypt[encrypt_type].name);
     650             :     }
     651             : }
     652             : 
     653           0 : const char *sdp_get_payload_name ( sdp_payload_e payload )
     654             : {
     655           0 :     if (payload == SDP_PAYLOAD_UNSUPPORTED) {
     656           0 :         return (SDP_UNSUPPORTED);
     657           0 :     } else if (payload >= SDP_MAX_STRING_PAYLOAD_TYPES) {
     658           0 :         return ("Invalid payload type");
     659             :     } else {
     660           0 :         return (sdp_payload[payload].name);
     661             :     }
     662             : }
     663             : 
     664           0 : const char *sdp_get_t38_ratemgmt_name ( sdp_t38_ratemgmt_e rate )
     665             : {
     666           0 :     if (rate >= SDP_T38_MAX_RATES) {
     667           0 :         return ("Invalid rate");
     668             :     } else {
     669           0 :         return (sdp_t38_rate[rate].name);
     670             :     }
     671             : }
     672             : 
     673           0 : const char *sdp_get_t38_udpec_name ( sdp_t38_udpec_e udpec )
     674             : {
     675           0 :     if (udpec >= SDP_T38_MAX_UDPEC) {
     676           0 :         return ("Invalid udpec");
     677             :     } else {
     678           0 :         return (sdp_t38_udpec[udpec].name);
     679             :     }
     680             : }
     681             : 
     682           0 : const char *sdp_get_qos_strength_name ( sdp_qos_strength_e strength )
     683             : {
     684           0 :     if (strength >= SDP_MAX_QOS_STRENGTH) {
     685           0 :         return ("Invalid qos strength");
     686             :     } else {
     687           0 :         return (sdp_qos_strength[strength].name);
     688             :     }
     689             : }
     690             : 
     691           0 : const char *sdp_get_qos_direction_name ( sdp_qos_dir_e direction )
     692             : {
     693           0 :     if (direction >= SDP_MAX_QOS_DIR) {
     694           0 :         return ("Invalid qos direction");
     695             :     } else {
     696           0 :         return (sdp_qos_direction[direction].name);
     697             :     }
     698             : }
     699             : 
     700           0 : const char *sdp_get_qos_status_type_name ( sdp_qos_status_types_e status_type )
     701             : {
     702           0 :     if (status_type >= SDP_MAX_QOS_STATUS_TYPES) {
     703           0 :         return ("Invalid qos status type");
     704             :     } else {
     705           0 :         return (sdp_qos_status_type[status_type].name);
     706             :     }
     707             : }
     708             : 
     709           0 : const char *sdp_get_curr_type_name (sdp_curr_type_e curr_type )
     710             : {
     711           0 :     if (curr_type >= SDP_MAX_CURR_TYPES) {
     712           0 :         return ("Invalid curr type");
     713             :     } else {
     714           0 :         return (sdp_curr_type[curr_type].name);
     715             :     }
     716             : }
     717             : 
     718           0 : const char *sdp_get_des_type_name (sdp_des_type_e des_type )
     719             : {
     720           0 :     if (des_type >= SDP_MAX_DES_TYPES) {
     721           0 :         return ("Invalid des type");
     722             :     } else {
     723           0 :         return (sdp_des_type[des_type].name);
     724             :     }
     725             : }
     726             : 
     727           0 : const char *sdp_get_conf_type_name (sdp_conf_type_e conf_type )
     728             : {
     729           0 :     if (conf_type >= SDP_MAX_CONF_TYPES) {
     730           0 :         return ("Invalid conf type");
     731             :     } else {
     732           0 :         return (sdp_conf_type[conf_type].name);
     733             :     }
     734             : }
     735             : 
     736           0 : const char *sdp_get_silencesupp_pref_name (sdp_silencesupp_pref_e pref)
     737             : {
     738           0 :     if (pref >= SDP_MAX_SILENCESUPP_PREF) {
     739           0 :         return ("Invalid silencesupp pref");
     740             :     } else {
     741           0 :         return (sdp_silencesupp_pref[pref].name);
     742             :     }
     743             : }
     744             : 
     745           0 : const char *sdp_get_silencesupp_siduse_name (sdp_silencesupp_siduse_e siduse)
     746             : {
     747           0 :     if (siduse >= SDP_MAX_SILENCESUPP_SIDUSE) {
     748           0 :         return ("Invalid silencesupp siduse");
     749             :     } else {
     750           0 :         return (sdp_silencesupp_siduse[siduse].name);
     751             :     }
     752             : }
     753             : 
     754           0 : const char *sdp_get_mediadir_role_name (sdp_mediadir_role_e role)
     755             : {
     756           0 :     if (role >= SDP_MEDIADIR_ROLE_UNKNOWN) {
     757           0 :         return ("Invalid media direction role");
     758             :     } else {
     759           0 :         return (sdp_mediadir_role[role].name);
     760             :     }
     761             : }
     762             : 
     763             : 
     764           0 : const char *sdp_get_bw_modifier_name (sdp_bw_modifier_e bw_modifier_type)
     765             : {
     766           0 :     if (bw_modifier_type == SDP_BW_MODIFIER_UNSUPPORTED) {
     767           0 :         return (SDP_UNSUPPORTED);
     768           0 :     } else if (bw_modifier_type < SDP_BW_MODIFIER_AS ||
     769             :             bw_modifier_type >= SDP_MAX_BW_MODIFIER_VAL) {
     770           0 :         return ("Invalid bw modifier type");
     771             :     } else {
     772           0 :         return (sdp_bw_modifier_val[bw_modifier_type].name);
     773             :     }
     774             : }
     775             : 
     776           0 : const char *sdp_get_group_attr_name (sdp_group_attr_e group_attr_type)
     777             : {
     778           0 :     if (group_attr_type == SDP_GROUP_ATTR_UNSUPPORTED) {
     779           0 :         return (SDP_UNSUPPORTED);
     780           0 :     } else if (group_attr_type >= SDP_MAX_GROUP_ATTR_VAL) {
     781           0 :         return ("Invalid a=group: attribute type");
     782             :     } else {
     783           0 :         return (sdp_group_attr_val[group_attr_type].name);
     784             :     }
     785             : }
     786             : 
     787           0 : const char *sdp_get_src_filter_mode_name (sdp_src_filter_mode_e type)
     788             : {
     789           0 :     if (type >= SDP_MAX_FILTER_MODE) {
     790           0 :         return ("Invalid source filter mode");
     791             :     } else {
     792           0 :         return (sdp_src_filter_mode_val[type].name);
     793             :     }
     794             : }
     795             : 
     796           0 : const char *sdp_get_rtcp_unicast_mode_name (sdp_rtcp_unicast_mode_e type)
     797             : {
     798           0 :     if (type >= SDP_RTCP_MAX_UNICAST_MODE) {
     799           0 :         return ("Invalid rtcp unicast mode");
     800             :     } else {
     801           0 :         return (sdp_rtcp_unicast_mode_val[type].name);
     802             :     }
     803             : }
     804             : 
     805             : /* Function:    sdp_init_description
     806             :  * Description: Allocates a new SDP structure that can be used for either
     807             :  *              parsing or building an SDP description.  This routine
     808             :  *              saves the config pointer passed in the SDP structure so
     809             :  *              SDP will know how to parse/build based on the options defined.
     810             :  *              An SDP structure must be allocated before parsing or building
     811             :  *              since the handle must be passed to these routines.
     812             :  * Parameters:  config_p     The config handle returned by sdp_init_config
     813             :  * Returns:     A handle for a new SDP structure as a void ptr.
     814             : */
     815           0 : sdp_t *sdp_init_description (sdp_conf_options_t *conf_p)
     816             : {
     817             :     int i;
     818             :     sdp_t *sdp_p;
     819             : 
     820           0 :     if (!conf_p) {
     821           0 :         return (NULL);
     822             :     }
     823             : 
     824           0 :     sdp_p = (sdp_t *)SDP_MALLOC(sizeof(sdp_t));
     825           0 :     if (sdp_p == NULL) {
     826           0 :         return (NULL);
     827             :     }
     828             : 
     829           0 :     sdp_p->conf_p             = conf_p;
     830           0 :     sdp_p->version            = SDP_CURRENT_VERSION;
     831           0 :     sdp_p->owner_name[0]      = '\0';
     832           0 :     sdp_p->owner_sessid[0]    = '\0';
     833           0 :     sdp_p->owner_version[0]   = '\0';
     834           0 :     sdp_p->owner_network_type = SDP_NT_INVALID;
     835           0 :     sdp_p->owner_addr_type    = SDP_AT_INVALID;
     836           0 :     sdp_p->owner_addr[0]      = '\0';
     837           0 :     sdp_p->sessname[0]        = '\0';
     838           0 :     sdp_p->sessinfo_found     = FALSE;
     839           0 :     sdp_p->uri_found          = FALSE;
     840             : 
     841           0 :     sdp_p->default_conn.nettype      = SDP_NT_INVALID;
     842           0 :     sdp_p->default_conn.addrtype     = SDP_AT_INVALID;
     843           0 :     sdp_p->default_conn.conn_addr[0] = '\0';
     844           0 :     sdp_p->default_conn.is_multicast = FALSE;
     845           0 :     sdp_p->default_conn.ttl          = 0;
     846           0 :     sdp_p->default_conn.num_of_addresses = 0;
     847             : 
     848           0 :     sdp_p->bw.bw_data_count   = 0;
     849           0 :     sdp_p->bw.bw_data_list    = NULL;
     850             : 
     851           0 :     sdp_p->timespec_p         = NULL;
     852           0 :     sdp_p->sess_attrs_p       = NULL;
     853           0 :     sdp_p->mca_p              = NULL;
     854           0 :     sdp_p->mca_count          = 0;
     855             : 
     856             :     /* Set default debug flags from application config. */
     857           0 :     for (i=0; i < SDP_MAX_DEBUG_TYPES; i++) {
     858           0 :         sdp_p->debug_flag[i] = conf_p->debug_flag[i];
     859             :     }
     860             : 
     861           0 :     return (sdp_p);
     862             : }
     863             : 
     864             : 
     865             : /* Function:    void sdp_debug(sdp_t *sdp_p, sdp_debug_e debug_type,
     866             :  *                             tinybool my_bool);
     867             :  * Description: Define the type of debug for this particular SDP structure.
     868             :  *              By default, each SDP description has the settings that are
     869             :  *              set for the application.
     870             :  *              Valid debug types are ERRORS, WARNINGS, and TRACE.  Each
     871             :  *              debug type can be turned on/off individually.  The
     872             :  *              debug level can be redefined at any time.
     873             :  * Parameters:  sdp_ptr    The SDP handle returned by sdp_init_description.
     874             :  *              debug_type Specifies the debug type being enabled/disabled.
     875             :  *              my_bool    Defines whether the debug should be enabled or not.
     876             :  * Returns:     Nothing.
     877             :  */
     878           0 : void sdp_debug (sdp_t *sdp_p, sdp_debug_e debug_type, tinybool debug_flag)
     879             : {
     880           0 :     if (!sdp_p) {
     881           0 :         return;
     882             :     }
     883             : 
     884           0 :     if (debug_type < SDP_MAX_DEBUG_TYPES)  {
     885           0 :         sdp_p->debug_flag[debug_type] = debug_flag;
     886             :     }
     887             : }
     888             : 
     889             : 
     890             : /* Function:    void sdp_set_string_debug(sdp_t *sdp_p, char *debug_str)
     891             :  * Description: Define a string to be associated with all debug output
     892             :  *              for this SDP. The string will be copied into the SDP
     893             :  *              structure and so the library will not be dependent on
     894             :  *              the application's memory for this string.
     895             :  * Parameters:  sdp_p      The SDP handle returned by sdp_init_description.
     896             :  *              debug_str  Pointer to a string that should be printed out
     897             :  *                         with every debug msg.
     898             :  * Returns:     Nothing.
     899             :  */
     900           0 : void sdp_set_string_debug (sdp_t *sdp_p, const char *debug_str)
     901             : {
     902           0 :     if (!sdp_p) {
     903           0 :         return;
     904             :     }
     905             : 
     906           0 :     sstrncpy(sdp_p->debug_str, debug_str, sizeof(sdp_p->debug_str));
     907             : }
     908             : 
     909             : 
     910             : /* Function:    sdp_validate_sdp
     911             :  * Description: Validate an SDP structure.
     912             :  * Parameters:  sdp_p    The SDP handle of the struct to validate.
     913             :  * Returns:     A result value indicating if the validation was successful.
     914             :  *              If not, what type of error was encountered.
     915             :  */
     916           0 : sdp_result_e sdp_validate_sdp (sdp_t *sdp_p)
     917             : {
     918             :     int i;
     919             :     uint16_t num_media_levels;
     920             : 
     921             :     /* Need to validate c= info is specified at session level or
     922             :      * at all m= levels.
     923             :      */
     924           0 :     if (sdp_connection_valid((void *)sdp_p, SDP_SESSION_LEVEL) == FALSE) {
     925           0 :         num_media_levels = sdp_get_num_media_lines((void *)sdp_p);
     926           0 :         for (i=1; i <= num_media_levels; i++) {
     927           0 :             if (sdp_connection_valid((void *)sdp_p, (unsigned short)i) == FALSE) {
     928           0 :                 sdp_parse_error(sdp_p,
     929             :                     "%s c= connection line not specified for "
     930             :                     "every media level, validation failed.",
     931           0 :                     sdp_p->debug_str);
     932           0 :                 return (SDP_FAILURE);
     933             :             }
     934             :         }
     935             :     }
     936             : 
     937             :     /* Validate required lines were specified */
     938           0 :     if ((sdp_owner_valid((void *)sdp_p) == FALSE) &&
     939           0 :         (sdp_p->conf_p->owner_reqd == TRUE)) {
     940           0 :         sdp_parse_error(sdp_p,
     941             :             "%s o= owner line not specified, validation failed.",
     942           0 :             sdp_p->debug_str);
     943           0 :         return (SDP_FAILURE);
     944             :     }
     945             : 
     946           0 :     if ((sdp_session_name_valid((void *)sdp_p) == FALSE) &&
     947           0 :         (sdp_p->conf_p->session_name_reqd == TRUE)) {
     948           0 :         sdp_parse_error(sdp_p,
     949             :             "%s s= session name line not specified, validation failed.",
     950           0 :             sdp_p->debug_str);
     951           0 :         return (SDP_FAILURE);
     952             :     }
     953             : 
     954           0 :     if ((sdp_timespec_valid((void *)sdp_p) == FALSE) &&
     955           0 :         (sdp_p->conf_p->timespec_reqd == TRUE)) {
     956           0 :         sdp_parse_error(sdp_p,
     957             :             "%s t= timespec line not specified, validation failed.",
     958           0 :             sdp_p->debug_str);
     959           0 :         return (SDP_FAILURE);
     960             :     }
     961             : 
     962           0 :     return (SDP_SUCCESS);
     963             : }
     964             : 
     965             : /* Function:    sdp_parse
     966             :  * Description: Parse an SDP description in the specified buffer.
     967             :  * Parameters:  sdp_p    The SDP handle returned by sdp_init_description
     968             :  *              bufp     Pointer to the buffer containing the SDP
     969             :  *                       description to parse.
     970             :  *              len      The length of the buffer.
     971             :  * Returns:     A result value indicating if the parse was successful and
     972             :  *              if not, what type of error was encountered.  The
     973             :  *              information from the parse is stored in the sdp_p structure.
     974             :  */
     975           0 : sdp_result_e sdp_parse (sdp_t *sdp_p, const char *buf, size_t len)
     976             : {
     977             :     uint8_t           i;
     978           0 :     uint16_t          cur_level = SDP_SESSION_LEVEL;
     979             :     const char  *ptr;
     980           0 :     const char  *next_ptr = NULL;
     981             :     char        *line_end;
     982           0 :     sdp_token_e  last_token = SDP_TOKEN_V;
     983           0 :     sdp_result_e result = SDP_SUCCESS;
     984           0 :     tinybool     parse_done = FALSE;
     985           0 :     tinybool     end_found = FALSE;
     986           0 :     tinybool     first_line = TRUE;
     987           0 :     tinybool     unrec_token = FALSE;
     988           0 :     const char   **bufp = &buf;
     989             : 
     990           0 :     if (!sdp_p) {
     991           0 :         return (SDP_INVALID_SDP_PTR);
     992             :     }
     993             : 
     994           0 :     if ((bufp == NULL) || (*bufp == NULL)) {
     995           0 :         return (SDP_NULL_BUF_PTR);
     996             :     }
     997             : 
     998           0 :     if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) {
     999           0 :         SDP_PRINT("%s Trace SDP Parse:", sdp_p->debug_str);
    1000             :     }
    1001             : 
    1002           0 :     next_ptr = *bufp;
    1003           0 :     sdp_p->conf_p->num_parses++;
    1004             : 
    1005             :     /* Initialize the last valid capability instance to zero.  Used
    1006             :      * to help in parsing X-cpar attrs. */
    1007           0 :     sdp_p->cap_valid = FALSE;
    1008           0 :     sdp_p->last_cap_inst = 0;
    1009             : 
    1010           0 :     sdp_p->parse_line = 0;
    1011             : 
    1012             :     /* We want to try to find the end of the SDP description, even if
    1013             :      * we find a parsing error.
    1014             :      */
    1015           0 :     while (!end_found) {
    1016             :         /* If the last char of this line goes beyond the end of the buffer,
    1017             :          * we don't parse it.
    1018             :          */
    1019           0 :         ptr = next_ptr;
    1020           0 :         sdp_p->parse_line++;
    1021           0 :         line_end = sdp_findchar(ptr, "\n");
    1022           0 :         if ((line_end >= (*bufp + len)) ||
    1023           0 :            (*line_end == '\0')) {
    1024             :             /* As this does not update the result value the SDP up to this point
    1025             :              * is still accept as valid. So encountering this is not treated as
    1026             :              * an error.
    1027             :              */
    1028           0 :             sdp_parse_error(sdp_p,
    1029             :                 "%s End of line beyond end of buffer.",
    1030           0 :                 sdp_p->debug_str);
    1031           0 :             CSFLogError(logTag, "SDP: Invalid SDP, no \\n (len %u): %*s",
    1032             :                         (unsigned)len, (int)len, *bufp);
    1033           0 :             end_found = TRUE;
    1034           0 :             break;
    1035             :         }
    1036             : 
    1037             :         /* Print the line if we're tracing. */
    1038           0 :         if ((parse_done == FALSE) &&
    1039           0 :           (sdp_p->debug_flag[SDP_DEBUG_TRACE])) {
    1040           0 :             SDP_PRINT("%s ", sdp_p->debug_str);
    1041             : 
    1042           0 :             SDP_PRINT("%*s", (int)(line_end - ptr), ptr);
    1043             : 
    1044             :         }
    1045             : 
    1046             :         /* Find out which token this line has, if any. */
    1047           0 :         for (i=0; i < SDP_MAX_TOKENS; i++) {
    1048           0 :             if (strncmp(ptr, sdp_token[i].name, SDP_TOKEN_LEN) == 0) {
    1049           0 :                 break;
    1050             :             }
    1051             :         }
    1052           0 :         if (i == SDP_MAX_TOKENS) {
    1053             :             /* See if the second char on the next line is an '=' char.
    1054             :              * If so, we note this as an unrecognized token line. */
    1055           0 :             if (ptr[1] == '=') {
    1056           0 :                 unrec_token = TRUE;
    1057             :             }
    1058           0 :             if (first_line == TRUE) {
    1059           0 :                 sdp_parse_error(sdp_p,
    1060             :                     "%s Attempt to parse text not recognized as "
    1061           0 :                     "SDP text, parse fails.", sdp_p->debug_str);
    1062             :                     /* If we haven't already printed out the line we
    1063             :                      * were trying to parse, do it now.
    1064             :                      */
    1065           0 :                 if (!sdp_p->debug_flag[SDP_DEBUG_TRACE]) {
    1066           0 :                     SDP_PRINT("%s ", sdp_p->debug_str);
    1067           0 :                     SDP_PRINT("%*s", (int)(line_end - ptr), ptr);
    1068             :                 }
    1069           0 :                 sdp_p->conf_p->num_not_sdp_desc++;
    1070           0 :                 return (SDP_NOT_SDP_DESCRIPTION);
    1071             :             } else {
    1072           0 :                 end_found = TRUE;
    1073           0 :                 break;
    1074             :             }
    1075             :         }
    1076             : 
    1077             :         /* This is the beginning of a new SDP description. */
    1078           0 :         if ((first_line != TRUE) && (i == SDP_TOKEN_V)) {
    1079           0 :             end_found = TRUE;
    1080           0 :             break;
    1081             :         }
    1082             : 
    1083             :         /* Advance the next ptr to one char beyond the end of the line. */
    1084           0 :         next_ptr = line_end + 1;
    1085           0 :         if (next_ptr >= (*bufp + len)) {
    1086           0 :             end_found = TRUE;
    1087             :         }
    1088             : 
    1089             :         /* If we've finished parsing and are just looking for the end of
    1090             :          * the SDP description, we don't need to do anything else here.
    1091             :          */
    1092           0 :         if (parse_done == TRUE) {
    1093           0 :             continue;
    1094             :         }
    1095             : 
    1096             :         /* Only certain tokens are valid at the media level. */
    1097           0 :         if (cur_level != SDP_SESSION_LEVEL) {
    1098           0 :             if ((i != SDP_TOKEN_I) && (i != SDP_TOKEN_C) &&
    1099           0 :                 (i != SDP_TOKEN_B) && (i != SDP_TOKEN_K) &&
    1100           0 :                 (i != SDP_TOKEN_A) && (i != SDP_TOKEN_M)) {
    1101           0 :                 sdp_p->conf_p->num_invalid_token_order++;
    1102           0 :                 sdp_parse_error(sdp_p,
    1103             :                     "%s Warning: Invalid token %s found at media level",
    1104           0 :                     sdp_p->debug_str, sdp_token[i].name);
    1105           0 :                 continue;
    1106             :             }
    1107             :         }
    1108             : 
    1109             :         /* Verify the token ordering. */
    1110           0 :         if (first_line == TRUE) {
    1111           0 :             if (i != SDP_TOKEN_V) {
    1112           0 :                 if (sdp_p->conf_p->version_reqd == TRUE) {
    1113           0 :                     sdp_parse_error(sdp_p,
    1114             :                         "%s First line not v=, parse fails",
    1115           0 :                         sdp_p->debug_str);
    1116           0 :                     sdp_p->conf_p->num_invalid_token_order++;
    1117           0 :                     result = SDP_INVALID_TOKEN_ORDERING;
    1118           0 :                     parse_done = TRUE;
    1119             :                 } else {
    1120           0 :                     last_token = (sdp_token_e)i;
    1121             :                 }
    1122             :             } else {
    1123           0 :                 last_token = (sdp_token_e)i;
    1124             :             }
    1125           0 :             first_line = FALSE;
    1126             :         } else {
    1127           0 :             if (i < last_token) {
    1128           0 :                 sdp_p->conf_p->num_invalid_token_order++;
    1129           0 :                 sdp_parse_error(sdp_p,
    1130             :                     "%s Warning: Invalid token ordering detected, "
    1131           0 :                     "token %s found after token %s", sdp_p->debug_str,
    1132             :                     sdp_token[i].name, sdp_token[last_token].name);
    1133             :             }
    1134             :         }
    1135             : 
    1136             :         /* Finally parse the line. */
    1137           0 :         ptr += SDP_TOKEN_LEN;
    1138           0 :         result = sdp_token[i].parse_func(sdp_p, cur_level, (const char *)ptr);
    1139           0 :         last_token = (sdp_token_e)i;
    1140           0 :         if (last_token == SDP_TOKEN_M) {
    1141           0 :             if (cur_level == SDP_SESSION_LEVEL) {
    1142           0 :                 cur_level = 1;
    1143             :             } else {
    1144           0 :                 cur_level++;
    1145             :             }
    1146             :             /* The token ordering can start again at i= */
    1147           0 :             last_token = (sdp_token_e)(SDP_TOKEN_I - 1);
    1148             :         }
    1149           0 :         if (result != SDP_SUCCESS) {
    1150           0 :             parse_done = TRUE;
    1151             :         }
    1152             : 
    1153             :         /* Skip the new line char at the end of this line and see if
    1154             :          * this is the end of the buffer.
    1155             :          */
    1156           0 :         if ((line_end + 1) == (*bufp + len)) {
    1157           0 :             end_found = TRUE;
    1158             :         }
    1159             :     }
    1160             : 
    1161             :     /* If we found no valid lines, return an error. */
    1162           0 :     if (first_line == TRUE) {
    1163           0 :         sdp_p->conf_p->num_not_sdp_desc++;
    1164           0 :         return (SDP_NOT_SDP_DESCRIPTION);
    1165             :     }
    1166             : 
    1167             :     /* If no errors were found yet, validate the overall sdp. */
    1168           0 :     if (result == SDP_SUCCESS) {
    1169           0 :         result = sdp_validate_sdp(sdp_p);
    1170             :     }
    1171             :     /* Return the pointer where we left off. */
    1172           0 :     *bufp = next_ptr;
    1173             :     /* If the SDP is valid, but the next line following was an
    1174             :      * unrecognized <token>= line, indicate this on the return. */
    1175           0 :     if ((result == SDP_SUCCESS) && (unrec_token == TRUE)) {
    1176           0 :         return (SDP_UNRECOGNIZED_TOKEN);
    1177             :     } else {
    1178           0 :         return (result);
    1179             :     }
    1180             : }
    1181             : 
    1182             : 
    1183             : /* Function:    sdp_build
    1184             :  * Description: Build an SDP description in the specified buffer based
    1185             :  *              on the information in the given SDP structure.
    1186             :  * Parameters:  sdp_p    The SDP handle returned by sdp_init_description
    1187             :  *              fs A flex_string where the SDP description should be built.
    1188             :  * Returns:     A result value indicating if the build was successful and
    1189             :  *              if not, what type of error was encountered - e.g.,
    1190             :  *              description was too long for the given buffer.
    1191             :  */
    1192           0 : sdp_result_e sdp_build (sdp_t *sdp_p, flex_string *fs)
    1193             : {
    1194             :     int i, j;
    1195           0 :     sdp_result_e        result = SDP_SUCCESS;
    1196             : 
    1197           0 :     if (!sdp_p) {
    1198           0 :         return (SDP_INVALID_SDP_PTR);
    1199             :     }
    1200             : 
    1201           0 :     if (!fs) {
    1202           0 :         return (SDP_NULL_BUF_PTR);
    1203             :     }
    1204             : 
    1205           0 :     if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) {
    1206           0 :         SDP_PRINT("%s Trace SDP Build:", sdp_p->debug_str);
    1207             :     }
    1208             : 
    1209           0 :     sdp_p->conf_p->num_builds++;
    1210             : 
    1211           0 :     for (i=0; ((i < SDP_TOKEN_M) &&
    1212           0 :                (result == SDP_SUCCESS)); i++) {
    1213           0 :         result = sdp_token[i].build_func(sdp_p, SDP_SESSION_LEVEL, fs);
    1214             :         /* ok not to check buffer space (yet) as the if() checks it */
    1215             :     }
    1216             :     /* If the session level was ok, build the media lines. */
    1217           0 :     if (result == SDP_SUCCESS) {
    1218           0 :         for (i=1; ((i <= sdp_p->mca_count) &&
    1219           0 :                    (result == SDP_SUCCESS)); i++) {
    1220           0 :             result = sdp_token[SDP_TOKEN_M].build_func(sdp_p, (uint16_t)i, fs);
    1221             : 
    1222             :             /* ok not to check buffer space (yet) as the for() checks it */
    1223           0 :             for (j=SDP_TOKEN_I;
    1224           0 :                  ((j < SDP_TOKEN_M) && (result == SDP_SUCCESS));
    1225           0 :                  j++) {
    1226           0 :                 if ((j == SDP_TOKEN_U) || (j == SDP_TOKEN_E) ||
    1227           0 :                     (j == SDP_TOKEN_P) || (j == SDP_TOKEN_T) ||
    1228           0 :                     (j == SDP_TOKEN_R) || (j == SDP_TOKEN_Z)) {
    1229             :                     /* These tokens not valid at media level. */
    1230           0 :                     continue;
    1231             :                 }
    1232           0 :                 result = sdp_token[j].build_func(sdp_p, (uint16_t)i, fs);
    1233             :                 /* ok not to check buffer space (yet) as the for() checks it */
    1234             :             }
    1235             :         }
    1236             :     }
    1237             : 
    1238           0 :     return (result);
    1239             : }
    1240             : 
    1241             : /* Function:    sdp_free_description
    1242             :  * Description: Free an SDP description and all memory associated with it.
    1243             :  * Parameters:  sdp_p  The SDP handle returned by sdp_init_description
    1244             :  * Returns:     A result value indicating if the free was successful and
    1245             :  *              if not, what type of error was encountered - e.g., sdp_p
    1246             :  *              was invalid and didn't point to an SDP structure.
    1247             : */
    1248           0 : sdp_result_e sdp_free_description (sdp_t *sdp_p)
    1249             : {
    1250             :     sdp_timespec_t  *time_p, *next_time_p;
    1251             :     sdp_attr_t      *attr_p, *next_attr_p;
    1252             :     sdp_mca_t       *mca_p, *next_mca_p;
    1253             :     sdp_bw_t        *bw_p;
    1254             :     sdp_bw_data_t   *bw_data_p;
    1255             : 
    1256           0 :     if (!sdp_p) {
    1257           0 :         return (SDP_INVALID_SDP_PTR);
    1258             :     }
    1259             : 
    1260             :     /* Free the config structure */
    1261           0 :     sdp_free_config(sdp_p->conf_p);
    1262             : 
    1263             :     /* Free any timespec structures - should be only one since
    1264             :      * this is all we currently support.
    1265             :      */
    1266           0 :     time_p = sdp_p->timespec_p;
    1267           0 :     while (time_p != NULL) {
    1268           0 :         next_time_p = time_p->next_p;
    1269           0 :         SDP_FREE(time_p);
    1270           0 :         time_p = next_time_p;
    1271             :     }
    1272             : 
    1273           0 :     bw_p = &(sdp_p->bw);
    1274           0 :     bw_data_p = bw_p->bw_data_list;
    1275           0 :     while (bw_data_p != NULL) {
    1276           0 :         bw_p->bw_data_list = bw_data_p->next_p;
    1277           0 :         SDP_FREE(bw_data_p);
    1278           0 :         bw_data_p = bw_p->bw_data_list;
    1279             :     }
    1280             : 
    1281             :     /* Free any session attr structures */
    1282           0 :     attr_p = sdp_p->sess_attrs_p;
    1283           0 :     while (attr_p != NULL) {
    1284           0 :         next_attr_p = attr_p->next_p;
    1285           0 :         sdp_free_attr(attr_p);
    1286           0 :         attr_p = next_attr_p;
    1287             :     }
    1288             : 
    1289             :     /* Free any mca structures */
    1290           0 :     mca_p = sdp_p->mca_p;
    1291           0 :     while (mca_p != NULL) {
    1292           0 :         next_mca_p = mca_p->next_p;
    1293             : 
    1294             :         /* Free any media attr structures */
    1295           0 :         attr_p = mca_p->media_attrs_p;
    1296           0 :         while (attr_p != NULL) {
    1297           0 :             next_attr_p = attr_p->next_p;
    1298           0 :             sdp_free_attr(attr_p);
    1299           0 :             attr_p = next_attr_p;
    1300             :         }
    1301             : 
    1302             :         /* Free the media profiles struct if allocated. */
    1303           0 :         if (mca_p->media_profiles_p != NULL) {
    1304           0 :             SDP_FREE(mca_p->media_profiles_p);
    1305             :         }
    1306             : 
    1307           0 :         bw_p = &(mca_p->bw);
    1308           0 :         bw_data_p = bw_p->bw_data_list;
    1309           0 :         while (bw_data_p != NULL) {
    1310           0 :             bw_p->bw_data_list = bw_data_p->next_p;
    1311           0 :             SDP_FREE(bw_data_p);
    1312           0 :             bw_data_p = bw_p->bw_data_list;
    1313             :         }
    1314             : 
    1315           0 :         SDP_FREE(mca_p);
    1316           0 :         mca_p = next_mca_p;
    1317             :     }
    1318             : 
    1319           0 :     SDP_FREE(sdp_p);
    1320             : 
    1321           0 :     return (SDP_SUCCESS);
    1322             : }
    1323             : 
    1324             : /*
    1325             :  * sdp_parse_error
    1326             :  * Send SDP parsing errors to log and up to peerconnection
    1327             :  */
    1328           0 : void sdp_parse_error(sdp_t* sdp, const char *format, ...) {
    1329             :     flex_string fs;
    1330             :     va_list ap;
    1331             : 
    1332           0 :     flex_string_init(&fs);
    1333             : 
    1334           0 :     va_start(ap, format);
    1335           0 :     flex_string_vsprintf(&fs, format, ap);
    1336           0 :     va_end(ap);
    1337             : 
    1338           0 :     CSFLogError("SDP Parse", "SDP Parse Error %s, line %u", fs.buffer,
    1339             :                 sdp->parse_line);
    1340             : 
    1341           0 :     if (sdp->conf_p->error_handler) {
    1342           0 :         sdp->conf_p->error_handler(sdp->conf_p->error_handler_context,
    1343             :                                    sdp->parse_line,
    1344           0 :                                    fs.buffer);
    1345             :     }
    1346             : 
    1347           0 :     flex_string_free(&fs);
    1348           0 : }

Generated by: LCOV version 1.13