Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/sipcc/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 73 kB image not shown  

Quelle  sdp_access.c   Sprache: C

 
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "sdp_os_defs.h"
#include "sipcc_sdp.h"
#include "sdp_private.h"

#include "sdp_log.h"

static const char* logTag = "sdp_access";

/* Pulled in from ccsip_sdp.h */
/* Possible encoding names of static payload types*/
#define SIPSDP_ATTR_ENCNAME_PCMU      "PCMU"
#define SIPSDP_ATTR_ENCNAME_PCMA      "PCMA"
#define SIPSDP_ATTR_ENCNAME_G729      "G729"
#define SIPSDP_ATTR_ENCNAME_G723      "G723"
#define SIPSDP_ATTR_ENCNAME_G726      "G726-32"
#define SIPSDP_ATTR_ENCNAME_G728      "G728"
#define SIPSDP_ATTR_ENCNAME_GSM       "GSM"
#define SIPSDP_ATTR_ENCNAME_CN        "CN"
#define SIPSDP_ATTR_ENCNAME_G722      "G722"
#define SIPSDP_ATTR_ENCNAME_ILBC      "iLBC"
#define SIPSDP_ATTR_ENCNAME_H263v2    "H263-1998"
#define SIPSDP_ATTR_ENCNAME_H264      "H264"
#define SIPSDP_ATTR_ENCNAME_AV1       "AV1"
#define SIPSDP_ATTR_ENCNAME_VP8       "VP8"
#define SIPSDP_ATTR_ENCNAME_VP9       "VP9"
#define SIPSDP_ATTR_ENCNAME_L16_256K  "L16"
#define SIPSDP_ATTR_ENCNAME_ISAC      "ISAC"
#define SIPSDP_ATTR_ENCNAME_OPUS      "opus"
#define SIPSDP_ATTR_ENCNAME_RED       "red"
#define SIPSDP_ATTR_ENCNAME_ULPFEC    "ulpfec"
#define SIPSDP_ATTR_ENCNAME_TELEPHONE_EVENT "telephone-event"
#define SIPSDP_ATTR_ENCNAME_RTX       "rtx"

/* Function:    sdp_find_media_level
 * Description: Find and return a pointer to the specified media level,
 *              if it exists.
 *              Note: This is not an API for the application but an internal
 *              routine used by the SDP library.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The media level to find.
 * Returns:     Pointer to the media level or NULL if not found.
 */

sdp_mca_t *sdp_find_media_level (sdp_t *sdp_p, uint16_t level)
{
    int i;
    sdp_mca_t *mca_p = NULL;

    if ((level >= 1) && (level <= sdp_p->mca_count)) {
        for (i=1, mca_p = sdp_p->mca_p;
             ((i < level) && (mca_p != NULL));
             mca_p = mca_p->next_p, i++) {

             /*sa_ignore EMPTYLOOP*/
             ; /* Do nothing. */
        }
    }

    return (mca_p);
}

/* Function:    sdp_version_valid
 * Description: Returns true or false depending on whether the version
 *              set for this SDP is valid.  Currently the only valid
 *              version is 0.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 * Returns:     TRUE or FALSE.
 */

tinybool sdp_version_valid (sdp_t *sdp_p)
{
    if (sdp_p->version == SDP_INVALID_VALUE) {
        return (FALSE);
    } else {
        return (TRUE);
    }
}

/* Function:    sdp_get_version
 * Description: Returns the version value set for the given SDP.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 * Returns:     Version value.
 */

int32_t sdp_get_version (sdp_t *sdp_p)
{
    return (sdp_p->version);
}

/* Function:    sdp_set_version
 * Description: Sets the value of the version parameter for the v= version
 *              token line.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              version     Version to set.
 * Returns:     SDP_SUCCESS
 */

sdp_result_e sdp_set_version (sdp_t *sdp_p, int32_t version)
{
    sdp_p->version = version;
    return (SDP_SUCCESS);
}

/* Function:    sdp_owner_valid
 * Description: Returns true or false depending on whether the owner
 *              token line has been defined for this SDP.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 * Returns:     TRUE or FALSE.
 */

tinybool sdp_owner_valid (sdp_t *sdp_p)
{
    if ((sdp_p->owner_name[0] == '\0') ||
        (sdp_p->owner_network_type == SDP_NT_INVALID) ||
        (sdp_p->owner_addr_type == SDP_AT_INVALID) ||
        (sdp_p->owner_addr[0] == '\0')) {
        return (FALSE);
    } else {
        return (TRUE);
    }
}

/* Function:    sdp_get_owner_username
 * Description: Returns a pointer to the value of the username parameter
 *              from the o= owner token line.  Value is returned as a
 *              const ptr and so cannot be modified by the application.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 * Returns:     Version value.
 */

const char *sdp_get_owner_username (sdp_t *sdp_p)
{
    return (sdp_p->owner_name);
}

/* Function:    sdp_get_owner_sessionid
 * Description: Returns the session id parameter from the o= owner token
 *              line.  Because the value may be larger than 32 bits, this
 *              parameter is returned as a string, though has been verified
 *              to be numeric.  Value is returned as a const ptr and so
 *              cannot be modified by the application.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 * Returns:     Ptr to owner session id or NULL.
 */

const char *sdp_get_owner_sessionid (sdp_t *sdp_p)
{
    return (sdp_p->owner_sessid);
}

/* Function:    sdp_get_owner_version
 * Description: Returns the version parameter from the o= owner token
 *              line.  Because the value may be larger than 32 bits, this
 *              parameter is returned as a string, though has been verified
 *              to be numeric.  Value is returned as a const ptr and so
 *              cannot be modified by the application.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 * Returns:     Ptr to owner version or NULL.
 */

const char *sdp_get_owner_version (sdp_t *sdp_p)
{
    return (sdp_p->owner_version);
}

/* Function:    sdp_get_owner_network_type
 * Description: Returns the network type parameter from the o= owner token
 *              line.  If network type has not been set SDP_NT_INVALID will
 *              be returned.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 * Returns:     Network type or SDP_NT_INVALID.
 */

sdp_nettype_e sdp_get_owner_network_type (sdp_t *sdp_p)
{
    return (sdp_p->owner_network_type);
}

/* Function:    sdp_get_owner_address_type
 * Description: Returns the address type parameter from the o= owner token
 *              line.  If address type has not been set SDP_AT_INVALID will
 *              be returned.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 * Returns:     Address type or SDP_AT_INVALID.
 */

sdp_addrtype_e sdp_get_owner_address_type (sdp_t *sdp_p)
{
    return (sdp_p->owner_addr_type);
}

/* Function:    sdp_get_owner_address
 * Description: Returns the address parameter from the o= owner token
 *              line.  Value is returned as a const ptr and so
 *              cannot be modified by the application.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 * Returns:     Ptr to address or NULL.
 */

const char *sdp_get_owner_address (sdp_t *sdp_p)
{
    return (sdp_p->owner_addr);
}

/* Function:    sdp_set_owner_username
 * Description: Sets the value of the username parameter for the o= owner
 *              token line.  The string is copied into the SDP structure
 *              so application memory will not be referenced by the SDP lib.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              username    Ptr to the username string.
 * Returns:     SDP_SUCCESS
 */

sdp_result_e sdp_set_owner_username (sdp_t *sdp_p, const char *username)
{
    sstrncpy(sdp_p->owner_name, username, sizeof(sdp_p->owner_name));
    return (SDP_SUCCESS);
}

/* Function:    sdp_set_owner_username
 * Description: Sets the value of the session id parameter for the o= owner
 *              token line.  The string is copied into the SDP structure
 *              so application memory will not be referenced by the SDP lib.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              sessionid   Ptr to the sessionid string.
 * Returns:     SDP_SUCCESS
 */

sdp_result_e sdp_set_owner_sessionid (sdp_t *sdp_p, const char *sessionid)
{
    sstrncpy(sdp_p->owner_sessid, sessionid, sizeof(sdp_p->owner_sessid));
    return (SDP_SUCCESS);
}

/* Function:    sdp_set_owner_version
 * Description: Sets the value of the version parameter for the o= owner
 *              token line.  The string is copied into the SDP structure
 *              so application memory will not be referenced by the SDP lib.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              version     Ptr to the version string.
 * Returns:     SDP_SUCCESS
 */

sdp_result_e sdp_set_owner_version (sdp_t *sdp_p, const char *version)
{
    sstrncpy(sdp_p->owner_version, version, sizeof(sdp_p->owner_version));
    return (SDP_SUCCESS);
}

/* Function:    sdp_set_owner_network_type
 * Description: Sets the value of the network type parameter for the o= owner
 *              token line.
 * Parameters:  sdp_p       The SDP handle returned by sdp_init_description.
 *              network_type  Network type for the owner line.
 * Returns:     SDP_SUCCESS
 */

sdp_result_e sdp_set_owner_network_type (sdp_t *sdp_p,
                                         sdp_nettype_e network_type)
{
    sdp_p->owner_network_type = network_type;
    return (SDP_SUCCESS);
}

/* Function:    sdp_set_owner_address_type
 * Description: Sets the value of the address type parameter for the o= owner
 *              token line.
 * Parameters:  sdp_p       The SDP handle returned by sdp_init_description.
 *              address_type  Address type for the owner line.
 * Returns:     SDP_SUCCESS
 */

sdp_result_e sdp_set_owner_address_type (sdp_t *sdp_p,
                                         sdp_addrtype_e address_type)
{
    sdp_p->owner_addr_type = address_type;
    return (SDP_SUCCESS);
}

/* Function:    sdp_set_owner_address
 * Description: Sets the value of the address parameter for the o= owner
 *              token line.  The string is copied into the SDP structure
 *              so application memory will not be referenced by the SDP lib.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              version     Ptr to the version string.
 * Returns:     SDP_SUCCESS
 */

sdp_result_e sdp_set_owner_address (sdp_t *sdp_p, const char *address)
{
    sstrncpy(sdp_p->owner_addr, address, sizeof(sdp_p->owner_addr));
    return (SDP_SUCCESS);
}

/* Function:    sdp_session_name_valid
 * Description: Returns true or false depending on whether the session name
 *              s= token line has been defined for this SDP.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 * Returns:     TRUE or FALSE.
 */

tinybool sdp_session_name_valid (sdp_t *sdp_p)
{
    if (sdp_p->sessname[0] == '\0') {
        return (FALSE);
    } else {
        return (TRUE);
    }
}

/* Function:    sdp_get_session_name
 * Description: Returns the session name parameter from the s= session
 *              name token line.  Value is returned as a const ptr and so
 *              cannot be modified by the application.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 * Returns:     Ptr to session name or NULL.
 */

const char *sdp_get_session_name (sdp_t *sdp_p)
{
    return (sdp_p->sessname);
}

/* Function:    sdp_set_session_name
 * Description: Sets the value of the session name parameter for the s=
 *              session name token line.  The string is copied into the
 *              SDP structure so application memory will not be
 *              referenced by the SDP lib.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              sessname    Ptr to the session name string.
 * Returns:     SDP_SUCCESS
 */

sdp_result_e sdp_set_session_name (sdp_t *sdp_p, const char *sessname)
{
    sstrncpy(sdp_p->sessname, sessname, sizeof(sdp_p->sessname));
    return (SDP_SUCCESS);
}

/* Function:    sdp_timespec_valid
 * Description: Returns true or false depending on whether the timespec t=
 *              token line has been defined for this SDP.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 * Returns:     TRUE or FALSE.
 */

tinybool sdp_timespec_valid (sdp_t *sdp_p)
{
    if ((sdp_p->timespec_p == NULL) ||
        (sdp_p->timespec_p->start_time[0] == '\0') ||
        (sdp_p->timespec_p->stop_time[0] == '\0')) {
        return (FALSE);
    } else {
        return (TRUE);
    }
}

/* Function:    sdp_get_time_start
 * Description: Returns the start time parameter from the t= timespec token
 *              line.  Because the value may be larger than 32 bits, this
 *              parameter is returned as a string, though has been verified
 *              to be numeric.  Value is returned as a const ptr and so
 *              cannot be modified by the application.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 * Returns:     Ptr to start time or NULL.
 */

const char *sdp_get_time_start (sdp_t *sdp_p)
{
    if (sdp_p->timespec_p != NULL) {
        return (sdp_p->timespec_p->start_time);
    } else {
        return (NULL);
    }
}

/* Function:    sdp_get_time_stop
 * Description: Returns the stop time parameter from the t= timespec token
 *              line.  Because the value may be larger than 32 bits, this
 *              parameter is returned as a string, though has been verified
 *              to be numeric.  Value is returned as a const ptr and so
 *              cannot be modified by the application.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 * Returns:     Ptr to stop time or NULL.
 */

const char *sdp_get_time_stop (sdp_t *sdp_p)
{
    if (sdp_p->timespec_p != NULL) {
        return (sdp_p->timespec_p->stop_time);
    } else {
        return (NULL);
    }
}

/* Function:    sdp_set_time_start
 * Description: Sets the value of the start time parameter for the t=
 *              timespec token line.  The string is copied into the
 *              SDP structure so application memory will not be
 *              referenced by the SDP lib.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              start_time  Ptr to the start time string.
 * Returns:     SDP_SUCCESS
 */

sdp_result_e sdp_set_time_start (sdp_t *sdp_p, const char *start_time)
{
    if (sdp_p->timespec_p == NULL) {
        sdp_p->timespec_p = (sdp_timespec_t *)SDP_MALLOC(sizeof(sdp_timespec_t));
        if (sdp_p->timespec_p == NULL) {
            sdp_p->conf_p->num_no_resource++;
            return (SDP_NO_RESOURCE);
        }
        sdp_p->timespec_p->start_time[0] = '\0';
        sdp_p->timespec_p->stop_time[0] = '\0';
    }
    sstrncpy(sdp_p->timespec_p->start_time, start_time,
             sizeof(sdp_p->timespec_p->start_time));
    return (SDP_SUCCESS);
}

/* Function:    sdp_set_time_stop
 * Description: Sets the value of the stop time parameter for the t=
 *              timespec token line.  The string is copied into the
 *              SDP structure so application memory will not be
 *              referenced by the SDP lib.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              stop_time  Ptr to the stop time string.
 * Returns:     SDP_SUCCESS
 */

sdp_result_e sdp_set_time_stop (sdp_t *sdp_p, const char *stop_time)
{
    if (sdp_p->timespec_p == NULL) {
        sdp_p->timespec_p = (sdp_timespec_t *)SDP_MALLOC(sizeof(sdp_timespec_t));
        if (sdp_p->timespec_p == NULL) {
            sdp_p->conf_p->num_no_resource++;
            return (SDP_NO_RESOURCE);
        }
        sdp_p->timespec_p->start_time[0] = '\0';
        sdp_p->timespec_p->stop_time[0] = '\0';
    }
    sstrncpy(sdp_p->timespec_p->stop_time, stop_time,
             sizeof(sdp_p->timespec_p->stop_time));
    return (SDP_SUCCESS);
}

/* Function:    sdp_encryption_valid
 * Description: Returns true or false depending on whether the encryption k=
 *              token line has been defined for this SDP at the given level.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to check for the k= line.  Will be
 *                          either SDP_SESSION_LEVEL or 1-n specifying a
 *                          media line level.
 * Returns:     TRUE or FALSE.
 */

tinybool sdp_encryption_valid (sdp_t *sdp_p, uint16_t level)
{
    sdp_encryptspec_t   *encrypt_p;
    sdp_mca_t           *mca_p;

    if (level == SDP_SESSION_LEVEL) {
        encrypt_p = &(sdp_p->encrypt);
    } else {
        mca_p = sdp_find_media_level(sdp_p, level);
        if (mca_p == NULL) {
            return (FALSE);
        }
        encrypt_p = &(mca_p->encrypt);
    }

    if ((encrypt_p->encrypt_type == SDP_ENCRYPT_INVALID) ||
        ((encrypt_p->encrypt_type != SDP_ENCRYPT_PROMPT) &&
         (encrypt_p->encrypt_key[0] == '\0'))) {
        return (FALSE);
    } else {
        return (TRUE);
    }
}

/* Function:    sdp_get_encryption_method
 * Description: Returns the encryption method parameter from the k=
 *              encryption token line.  If encryption method has not been
 *              set SDP_ENCRYPT_INVALID will be returned.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to check for the c= line.  Will be
 *                          either SDP_SESSION_LEVEL or 1-n specifying a
 *                          media line level.
 * Returns:     Encryption method or SDP_ENCRYPT_INVALID.
 */

sdp_encrypt_type_e sdp_get_encryption_method (sdp_t *sdp_p, uint16_t level)
{
    sdp_encryptspec_t   *encrypt_p;
    sdp_mca_t           *mca_p;

    if (level == SDP_SESSION_LEVEL) {
        encrypt_p = &(sdp_p->encrypt);
    } else {
        mca_p = sdp_find_media_level(sdp_p, level);
        if (mca_p == NULL) {
            return (SDP_ENCRYPT_INVALID);
        }
        encrypt_p = &(mca_p->encrypt);
    }

    return (encrypt_p->encrypt_type);
}

/* Function:    sdp_get_encryption_key
 * Description: Returns a pointer to the encryption key parameter
 *              from the k= encryption token line.  Value is returned as a
 *              const ptr and so cannot be modified by the application.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to check for the c= line.  Will be
 *                          either SDP_SESSION_LEVEL or 1-n specifying a
 *                          media line level.
 * Returns:     Ptr to encryption key or NULL.
 */

const char *sdp_get_encryption_key (sdp_t *sdp_p, uint16_t level)
{
    sdp_encryptspec_t   *encrypt_p;
    sdp_mca_t           *mca_p;

    if (level == SDP_SESSION_LEVEL) {
        encrypt_p = &(sdp_p->encrypt);
    } else {
        mca_p = sdp_find_media_level(sdp_p, level);
        if (mca_p == NULL) {
            return (NULL);
        }
        encrypt_p = &(mca_p->encrypt);
    }

    return (encrypt_p->encrypt_key);
}

/* Function:    sdp_connection_valid
 * Description: Returns true or false depending on whether the connection c=
 *              token line has been defined for this SDP at the given level.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to check for the c= line.  Will be
 *                          either SDP_SESSION_LEVEL or 1-n specifying a
 *                          media line level.
 * Returns:     TRUE or FALSE.
 */

tinybool sdp_connection_valid (sdp_t *sdp_p, uint16_t level)
{
    sdp_conn_t *conn_p;
    sdp_mca_t  *mca_p;

    if (level == SDP_SESSION_LEVEL) {
        conn_p = &(sdp_p->default_conn);
    } else {
        mca_p = sdp_find_media_level(sdp_p, level);
        if (mca_p == NULL) {
            return (FALSE);
        }
        conn_p = &(mca_p->conn);
    }

    /*if network type is ATM . then allow c= line without address type
     * and address . This is a special case to cover PVC
     */

    if (conn_p->nettype == SDP_NT_ATM &&
        conn_p->addrtype == SDP_AT_INVALID) {
        return TRUE;
    }

    if ((conn_p->nettype >= SDP_MAX_NETWORK_TYPES) ||
        (conn_p->addrtype >= SDP_MAX_ADDR_TYPES) ||
        (conn_p->conn_addr[0] == '\0')) {
        return (FALSE);
    } else {
        return (TRUE);
    }
}

/* Function:    sdp_bandwidth_valid
 * Description: Returns true or false depending on whether the bandwidth b=
 *              token line has been defined for this SDP at the given level.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to check for the c= line.  Will be
 *                          either SDP_SESSION_LEVEL or 1-n specifying a
 *                          media line level.
 *              inst_num    instance number of bw line at that level. The first
 *                          instance has a inst_num of 1 and so on.
 * Returns:     TRUE or FALSE.
 */

tinybool sdp_bandwidth_valid (sdp_t *sdp_p, uint16_t level, uint16_t inst_num)
{
    sdp_bw_data_t *bw_data_p;

    bw_data_p = sdp_find_bw_line(sdp_p, level, inst_num);
    if (bw_data_p != NULL) {
        if ((bw_data_p->bw_modifier < SDP_BW_MODIFIER_AS) ||
            (bw_data_p->bw_modifier >= SDP_MAX_BW_MODIFIER_VAL)) {
            return FALSE;
        } else {
            return TRUE;
        }
    } else {
        return FALSE;
    }
}

/*
 * sdp_bw_line_exists
 *
 * Description: This api retruns true if there exists a bw line at the
 *              instance and level specified.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to check for the c= line.  Will be
 *                          either SDP_SESSION_LEVEL or 1-n specifying a
 *                          media line level.
 *              inst_num    instance number of bw line at that level. The first
 *                          instance has a inst_num of 1 and so on.
 * Returns:     TRUE or FALSE
 */

tinybool sdp_bw_line_exists (sdp_t *sdp_p, uint16_t level, uint16_t inst_num)
{
    sdp_bw_data_t *bw_data_p;

    bw_data_p = sdp_find_bw_line(sdp_p, level, inst_num);
    if (bw_data_p != NULL) {
        return TRUE;
    } else {
        return FALSE;
    }
}

/* Function:    sdp_get_conn_nettype
 * Description: Returns the network type parameter from the c=
 *              connection token line.  If network type has not been
 *              set SDP_NT_INVALID will be returned.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to check for the c= line.  Will be
 *                          either SDP_SESSION_LEVEL or 1-n specifying a
 *                          media line level.
 * Returns:     Network type or SDP_NT_INVALID.
 */

sdp_nettype_e sdp_get_conn_nettype (sdp_t *sdp_p, uint16_t level)
{
    sdp_conn_t *conn_p;
    sdp_mca_t  *mca_p;

    if (level == SDP_SESSION_LEVEL) {
        conn_p = &(sdp_p->default_conn);
    } else {
        mca_p = sdp_find_media_level(sdp_p, level);
        if (mca_p == NULL) {
            return (SDP_NT_INVALID);
        }
        conn_p = &(mca_p->conn);
    }

    return (conn_p->nettype);
}

/* Function:    sdp_get_conn_addrtype
 * Description: Returns the address type parameter from the c=
 *              connection token line.  If address type has not been
 *              set SDP_AT_INVALID will be returned.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to check for the c= line.  Will be
 *                          either SDP_SESSION_LEVEL or 1-n specifying a
 *                          media line level.
 * Returns:     Address type or SDP_AT_INVALID.
 */

sdp_addrtype_e sdp_get_conn_addrtype (sdp_t *sdp_p, uint16_t level)
{
    sdp_conn_t *conn_p;
    sdp_mca_t  *mca_p;

    if (level == SDP_SESSION_LEVEL) {
        conn_p = &(sdp_p->default_conn);
    } else {
        mca_p = sdp_find_media_level(sdp_p, level);
        if (mca_p == NULL) {
            return (SDP_AT_INVALID);
        }
        conn_p = &(mca_p->conn);
    }

    return (conn_p->addrtype);
}

/* Function:    sdp_get_conn_address
 * Description: Returns a pointer to the address parameter
 *              from the c= connection token line.  Value is returned as a
 *              const ptr and so cannot be modified by the application.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to check for the c= line.  Will be
 *                          either SDP_SESSION_LEVEL or 1-n specifying a
 *                          media line level.
 * Returns:     Ptr to address or NULL.
 */

const char *sdp_get_conn_address (sdp_t *sdp_p, uint16_t level)
{
    sdp_conn_t *conn_p;
    sdp_mca_t  *mca_p;

    if (level == SDP_SESSION_LEVEL) {
        conn_p = &(sdp_p->default_conn);
    } else {
        mca_p = sdp_find_media_level(sdp_p, level);
        if (mca_p == NULL) {
            return (NULL);
        }
        conn_p = &(mca_p->conn);
    }

    return (conn_p->conn_addr);
}

/* Function:    sdp_is_mcast_addr
 * Description: Returns a boolean to indicate if the addr is multicast in
 *              the c=line.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to check for the c= line.  Will be
 *                          either SDP_SESSION_LEVEL or 1-n specifying a
 *                          media line level.
 * Returns:     TRUE if the addr is multicast, FALSE if not.
 */


tinybool sdp_is_mcast_addr (sdp_t *sdp_p, uint16_t level)
{
    sdp_conn_t *conn_p;
    sdp_mca_t  *mca_p;

    if (level == SDP_SESSION_LEVEL) {
        conn_p = &(sdp_p->default_conn);
    } else {
        mca_p = sdp_find_media_level(sdp_p, level);
        if (mca_p != NULL) {
            conn_p = &(mca_p->conn);
 } else {
            return (FALSE);
 }
    }

    if ((conn_p) && (conn_p->is_multicast)) {
        return (TRUE);
    } else {
        return (FALSE);
    }
}

/* Function:    sdp_get_mcast_ttl
 * Description: Get the time to live(ttl) value for the multicast address
 *              if present.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to check for the c= line.  Will be
 *                          either SDP_SESSION_LEVEL or 1-n specifying a
 *                          media line level.
 * Returns:     Multicast address - Time to live (ttl) value
 */


int32_t sdp_get_mcast_ttl (sdp_t *sdp_p, uint16_t level)
{
    sdp_conn_t *conn_p;
    sdp_mca_t  *mca_p;
    uint16_t ttl=0;

    if (level == SDP_SESSION_LEVEL) {
        conn_p = &(sdp_p->default_conn);
    } else {
        mca_p = sdp_find_media_level(sdp_p, level);
        if (mca_p != NULL) {
            conn_p = &(mca_p->conn);
        } else {
            return SDP_INVALID_VALUE;
        }
    }

    if (conn_p) {
 ttl = conn_p->ttl;
    }
    return ttl;
}

/* Function:    sdp_get_mcast_num_of_addresses
 * Description: Get the number of addresses value for the multicast address
 *              if present.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to check for the c= line.  Will be
 *                          either SDP_SESSION_LEVEL or 1-n specifying a
 *                          media line level.
 * Returns:     Multicast address - number of addresses value
 */


int32_t sdp_get_mcast_num_of_addresses (sdp_t *sdp_p, uint16_t level)
{
    sdp_conn_t *conn_p;
    sdp_mca_t  *mca_p;
    uint16_t num_addr = 0;

    if (level == SDP_SESSION_LEVEL) {
        conn_p = &(sdp_p->default_conn);
    } else {
        mca_p = sdp_find_media_level(sdp_p, level);
        if (mca_p != NULL) {
            conn_p = &(mca_p->conn);
        } else {
            return (SDP_INVALID_VALUE);
        }
    }

    if (conn_p) {
 num_addr = conn_p->num_of_addresses;
    }
    return num_addr;
}
/* Function:    sdp_set_conn_nettype
 * Description: Sets the value of the network type parameter for the c=
 *              connection token line.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              nettype     Network type for the connection line.
 *              level       The level to check for the c= line.  Will be
 *                          either SDP_SESSION_LEVEL or 1-n specifying a
 *                          media line level.
 * Returns:     SDP_SUCCESS or SDP_INVALID_PARAMETER
 */

sdp_result_e sdp_set_conn_nettype (sdp_t *sdp_p, uint16_t level,
                                   sdp_nettype_e nettype)
{
    sdp_conn_t *conn_p;
    sdp_mca_t  *mca_p;

    if (level == SDP_SESSION_LEVEL) {
        conn_p = &(sdp_p->default_conn);
    } else {
        mca_p = sdp_find_media_level(sdp_p, level);
        if (mca_p == NULL) {
            sdp_p->conf_p->num_invalid_param++;
            return (SDP_INVALID_PARAMETER);
        }
        conn_p = &(mca_p->conn);
    }

    conn_p->nettype = nettype;
    return (SDP_SUCCESS);
}

/* Function:    sdp_set_conn_addrtype
 * Description: Sets the value of the address type parameter for the c=
 *              connection token line.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              addrtype    Address type for the connection line.
 *              level       The level to check for the c= line.  Will be
 *                          either SDP_SESSION_LEVEL or 1-n specifying a
 *                          media line level.
 * Returns:     SDP_SUCCESS or SDP_INVALID_PARAMETER
 */

sdp_result_e sdp_set_conn_addrtype (sdp_t *sdp_p, uint16_t level,
                                    sdp_addrtype_e addrtype)
{
    sdp_conn_t *conn_p;
    sdp_mca_t  *mca_p;

    if (level == SDP_SESSION_LEVEL) {
        conn_p = &(sdp_p->default_conn);
    } else {
        mca_p = sdp_find_media_level(sdp_p, level);
        if (mca_p == NULL) {
            sdp_p->conf_p->num_invalid_param++;
            return (SDP_INVALID_PARAMETER);
        }
        conn_p = &(mca_p->conn);
    }

    conn_p->addrtype = addrtype;
    return (SDP_SUCCESS);
}

/* Function:    sdp_set_conn_address
 * Description: Sets the value of the address parameter for the c=
 *              connection token line.  The string is copied into the
 *              SDP structure so application memory will not be
 *              referenced by the SDP lib.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to check for the c= line.  Will be
 *                          either SDP_SESSION_LEVEL or 1-n specifying a
 *                          media line level.
 *              address     Ptr to the address string.
 * Returns:     SDP_SUCCESS
 */

sdp_result_e sdp_set_conn_address (sdp_t *sdp_p, uint16_t level,
                                   const char *address)
{
    sdp_conn_t *conn_p;
    sdp_mca_t  *mca_p;

    if (level == SDP_SESSION_LEVEL) {
        conn_p = &(sdp_p->default_conn);
    } else {
        mca_p = sdp_find_media_level(sdp_p, level);
        if (mca_p == NULL) {
            sdp_p->conf_p->num_invalid_param++;
            return (SDP_INVALID_PARAMETER);
        }
        conn_p = &(mca_p->conn);
    }

    sstrncpy(conn_p->conn_addr, address, sizeof(conn_p->conn_addr));
    return (SDP_SUCCESS);
}

/* Function:    sdp_media_line_valid
 * Description: Returns true or false depending on whether the specified
 *              media line m= has been defined for this SDP.  The
 *              SDP_SESSION_LEVEL level is not valid for this check since,
 *              by definition, this is a media level.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to check for the c= line.  Will be
 *                          1-n specifying a media line level.
 * Returns:     TRUE or FALSE.
 */

tinybool sdp_media_line_valid (sdp_t *sdp_p, uint16_t level)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return (FALSE);
    }

    /* Validate params for this media line */
    if ((mca_p->media >= SDP_MAX_MEDIA_TYPES) ||
        (mca_p->port_format >= SDP_MAX_PORT_FORMAT_TYPES) ||
        (mca_p->transport >= SDP_MAX_TRANSPORT_TYPES) ||
        (mca_p->num_payloads == 0)) {
        return (FALSE);
    } else {
        return (TRUE);
    }
}

/* Function:    sdp_get_num_media_lines
 * Description: Returns the number of media lines associated with the SDP.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 * Returns:     Number of media lines.
 */

uint16_t sdp_get_num_media_lines (sdp_t *sdp_p)
{
    return (sdp_p->mca_count);
}

/* Function:    sdp_get_media_type
 * Description: Returns the media type parameter from the m=
 *              media token line.  If media type has not been
 *              set SDP_MEDIA_INVALID will be returned.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to of the m= media line.  Will be 1-n.
 * Returns:     Media type or SDP_MEDIA_INVALID.
 */

sdp_media_e sdp_get_media_type (sdp_t *sdp_p, uint16_t level)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return (SDP_MEDIA_INVALID);
    }

    return (mca_p->media);
}

/* Function:    sdp_get_media_line_number
 * Description: Returns the line number in the SDP the media
 *              section starts on. Only set if SDP has been parsed
 *              (rather than built).
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to of the m= media line.  Will be 1-n.
 * Returns:     Line number (0 if not found or if locally built)
 */

uint32_t sdp_get_media_line_number (sdp_t *sdp_p, uint16_t level)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return 0;
    }

    return (mca_p->line_number);
}

/* Function:    sdp_get_media_port_format
 * Description: Returns the port format type associated with the m=
 *              media token line.  If port format type has not been
 *              set SDP_PORT_FORMAT_INVALID will be returned.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to of the m= media line.  Will be 1-n.
 * Returns:     Port format type or SDP_PORT_FORMAT_INVALID.
 */

sdp_port_format_e sdp_get_media_port_format (sdp_t *sdp_p, uint16_t level)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return (SDP_PORT_FORMAT_INVALID);
    }

    return (mca_p->port_format);
}

/* Function:    sdp_get_media_portnum
 * Description: Returns the port number associated with the m=
 *              media token line.  If port number has not been
 *              set SDP_INVALID_VALUE will be returned.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to of the m= media line.  Will be 1-n.
 * Returns:     Port number or SDP_INVALID_VALUE.
 */

int32_t sdp_get_media_portnum (sdp_t *sdp_p, uint16_t level)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return (SDP_INVALID_VALUE);
    }

    /* Make sure port number is valid for the specified format. */
    if ((mca_p->port_format != SDP_PORT_NUM_ONLY) &&
        (mca_p->port_format != SDP_PORT_NUM_COUNT) &&
        (mca_p->port_format != SDP_PORT_NUM_VPI_VCI) &&
        (mca_p->port_format != SDP_PORT_NUM_VPI_VCI_CID)) {
        if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
            SDPLogError(logTag, "%s Port num not valid for media line %u",
                      sdp_p->debug_str, (unsigned)level);
        }
        sdp_p->conf_p->num_invalid_param++;
        return (SDP_INVALID_VALUE);
    }

    return (mca_p->port);
}

/* Function:    sdp_get_media_portcount
 * Description: Returns the port count associated with the m=
 *              media token line.  If port count has not been
 *              set SDP_INVALID_VALUE will be returned.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to of the m= media line.  Will be 1-n.
 * Returns:     Port count or SDP_INVALID_VALUE.
 */

int32_t sdp_get_media_portcount (sdp_t *sdp_p, uint16_t level)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return (SDP_INVALID_VALUE);
    }

    /* Make sure port number is valid for the specified format. */
    if (mca_p->port_format != SDP_PORT_NUM_COUNT) {
        if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
            SDPLogError(logTag, "%s Port count not valid for media line %u",
                      sdp_p->debug_str, (unsigned)level);
        }
        sdp_p->conf_p->num_invalid_param++;
        return (SDP_INVALID_VALUE);
    }

    return (mca_p->num_ports);
}

/* Function:    sdp_get_media_vpi
 * Description: Returns the VPI parameter associated with the m=
 *              media token line.  If VPI has not been set
 *              SDP_INVALID_VALUE will be returned.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to of the m= media line.  Will be 1-n.
 * Returns:     VPI or SDP_INVALID_VALUE.
 */

int32_t sdp_get_media_vpi (sdp_t *sdp_p, uint16_t level)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return (SDP_INVALID_VALUE);
    }

    /* Make sure port number is valid for the specified format. */
    if ((mca_p->port_format != SDP_PORT_VPI_VCI) &&
        (mca_p->port_format != SDP_PORT_NUM_VPI_VCI) &&
        (mca_p->port_format != SDP_PORT_NUM_VPI_VCI_CID)) {
        if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
            SDPLogError(logTag, "%s VPI not valid for media line %u",
                      sdp_p->debug_str, (unsigned)level);
        }
        sdp_p->conf_p->num_invalid_param++;
        return (SDP_INVALID_VALUE);
    }

    return (mca_p->vpi);
}

/* Function:    sdp_get_media_vci
 * Description: Returns the VCI parameter associated with the m=
 *              media token line.  If VCI has not been set
 *              SDP_INVALID_VALUE will be returned.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to of the m= media line.  Will be 1-n.
 * Returns:     VCI or zero.
 */

uint32_t sdp_get_media_vci (sdp_t *sdp_p, uint16_t level)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return (0);
    }

    /* Make sure port number is valid for the specified format. */
    if ((mca_p->port_format != SDP_PORT_VPI_VCI) &&
        (mca_p->port_format != SDP_PORT_NUM_VPI_VCI) &&
        (mca_p->port_format != SDP_PORT_NUM_VPI_VCI_CID)) {
        if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
            SDPLogError(logTag, "%s VCI not valid for media line %u",
                      sdp_p->debug_str, (unsigned)level);
        }
        sdp_p->conf_p->num_invalid_param++;
        return (0);
    }

    return (mca_p->vci);
}

/* Function:    sdp_get_media_vcci
 * Description: Returns the VCCI parameter associated with the m=
 *              media token line.  If VCCI has not been set
 *              SDP_INVALID_VALUE will be returned.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to of the m= media line.  Will be 1-n.
 * Returns:     VCCI or SDP_INVALID_VALUE.
 */

int32_t sdp_get_media_vcci (sdp_t *sdp_p, uint16_t level)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return (SDP_INVALID_VALUE);
    }

    /* Make sure port number is valid for the specified format. */
    if ((mca_p->port_format != SDP_PORT_VCCI) &&
        (mca_p->port_format != SDP_PORT_VCCI_CID)) {
        if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
            SDPLogError(logTag, "%s VCCI not valid for media line %u",
                      sdp_p->debug_str, (unsigned)level);
        }
        sdp_p->conf_p->num_invalid_param++;
        return (SDP_INVALID_VALUE);
    }

    return (mca_p->vcci);
}

/* Function:    sdp_get_media_cid
 * Description: Returns the CID parameter associated with the m=
 *              media token line.  If CID has not been set
 *              SDP_INVALID_VALUE will be returned.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to of the m= media line.  Will be 1-n.
 * Returns:     CID or SDP_INVALID_VALUE.
 */

int32_t sdp_get_media_cid (sdp_t *sdp_p, uint16_t level)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return (SDP_INVALID_VALUE);
    }

    /* Make sure port number is valid for the specified format. */
    if ((mca_p->port_format != SDP_PORT_VCCI_CID) &&
        (mca_p->port_format != SDP_PORT_NUM_VPI_VCI_CID)) {
        if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
            SDPLogError(logTag, "%s CID not valid for media line %u",
                      sdp_p->debug_str, (unsigned)level);
        }
        sdp_p->conf_p->num_invalid_param++;
        return (SDP_INVALID_VALUE);
    }

    return (mca_p->cid);
}

/* Function:    sdp_get_media_transport
 * Description: Returns the transport type parameter associated with the m=
 *              media token line.  If transport type has not been set
 *              SDP_TRANSPORT_INVALID will be returned.  If the transport
 *              type is one of the AAL2 variants, the profile routines below
 *              should be used to access multiple profile types and payload
 *              lists per m= line.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to of the m= media line.  Will be 1-n.
 * Returns:     CID or SDP_TRANSPORT_INVALID.
 */

sdp_transport_e sdp_get_media_transport (sdp_t *sdp_p, uint16_t level)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return (SDP_TRANSPORT_INVALID);
    }

    return (mca_p->transport);
}

/* Function:    sdp_get_media_num_profiles
 * Description: Returns the number of profiles associated with the m=
 *              media token line.  If the media line is invalid, zero will
 *              be returned.  Application must validate the media line
 *              before using this routine.  Multiple profile types per
 *              media line is currently only used for AAL2.  If the appl
 *              detects that the transport type is one of the AAL2 types,
 *              it should use these profile access routines to access the
 *              profile types and payload list for each.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to of the m= media line.  Will be 1-n.
 * Returns:     Number of profiles or zero.
 */

uint16_t sdp_get_media_num_profiles (sdp_t *sdp_p, uint16_t level)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return (0);
    }

    if (mca_p->media_profiles_p == NULL) {
        return (0);
    } else {
        return (mca_p->media_profiles_p->num_profiles);
    }
}

/* Function:    sdp_get_media_profile
 * Description: Returns the specified profile type associated with the m=
 *              media token line.  If the media line or profile number is
 *              invalid, SDP_TRANSPORT_INVALID will be returned.
 *              Applications must validate the media line before using this
 *              routine.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to of the m= media line.  Will be 1-n.
 *              profile_num The specific profile type number to be retrieved.
 * Returns:     The profile type or SDP_TRANSPORT_INVALID.
 */

sdp_transport_e sdp_get_media_profile (sdp_t *sdp_p, uint16_t level,
                                       uint16_t profile_num)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return (SDP_TRANSPORT_INVALID);
    }

    if ((profile_num < 1) ||
        (profile_num > mca_p->media_profiles_p->num_profiles)) {
        return (SDP_TRANSPORT_INVALID);
    } else {
        return (mca_p->media_profiles_p->profile[profile_num-1]);
    }
}

/* Function:    sdp_get_media_num_payload_types
 * Description: Returns the number of payload types associated with the m=
 *              media token line.  If the media line is invalid, zero will
 *              be returned.  Application must validate the media line
 *              before using this routine.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to of the m= media line.  Will be 1-n.
 * Returns:     Number of payload types or zero.
 */

uint16_t sdp_get_media_num_payload_types (sdp_t *sdp_p, uint16_t level)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return (0);
    }

    return (mca_p->num_payloads);
}

/* Function:    sdp_get_media_profile_num_payload_types
 * Description: Returns the number of payload types associated with the
 *              specified profile on the m= media token line.  If the
 *              media line or profile number is invalid, zero will
 *              be returned.  Application must validate the media line
 *              and profile before using this routine.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to of the m= media line.  Will be 1-n.
 *              profile_num The specific profile number. Will be 1-n.
 * Returns:     Number of payload types or zero.
 */

uint16_t sdp_get_media_profile_num_payload_types (sdp_t *sdp_p, uint16_t level,
                                             uint16_t profile_num)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return (0);
    }

    if ((profile_num < 1) ||
        (profile_num > mca_p->media_profiles_p->num_profiles)) {
        return (0);
    } else {
        return (mca_p->media_profiles_p->num_payloads[profile_num-1]);
    }
}

rtp_ptype sdp_get_known_payload_type(sdp_t *sdp_p,
                                     uint16_t level,
                                     uint16_t payload_type_raw) {
  sdp_attr_t  *attr_p;
  sdp_transport_map_t *rtpmap;
  uint16_t    pack_mode = 0; /*default 0, if remote did not provide any */
  const char *encname = NULL;
  uint16_t    num_a_lines = 0;
  int         i;

  /*
   * Get number of RTPMAP attributes for the media line
   */

  (void) sdp_attr_num_instances(sdp_p, level, 0, SDP_ATTR_RTPMAP,
      &num_a_lines);

  /*
   * Loop through media line RTPMAP attributes.
   */

  for (i = 0; i < num_a_lines; i++) {
    attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_RTPMAP, (i + 1));
    if (attr_p == NULL) {
      if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
        SDPLogError(logTag, "%s rtpmap attribute, level %u instance %u "
                            "not found.",
                            sdp_p->debug_str,
                            (unsigned)level,
                            (unsigned)(i + 1));
      }
      sdp_p->conf_p->num_invalid_param++;
      return (RTP_NONE);
    }

    rtpmap = &(attr_p->attr.transport_map);

    if (rtpmap->payload_num == payload_type_raw) {
      encname = rtpmap->encname;
      if (encname) {
        if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_ILBC) == 0) {
          return (RTP_ILBC);
        }
        if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_L16_256K) == 0) {
          return (RTP_L16);
        }
        if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_ISAC) == 0) {
          return (RTP_ISAC);
        }
        if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_OPUS) == 0) {
          return (RTP_OPUS);
        }
        if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_PCMU) == 0) {
          return (RTP_PCMU);
        }
        if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_PCMA) == 0) {
          return (RTP_PCMA);
        }
        if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_G722) == 0) {
          return (RTP_G722);
        }
        if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_H264) == 0) {
          int fmtp_inst = sdp_find_fmtp_inst(sdp_p, level, rtpmap->payload_num);
          if (fmtp_inst < 0) {
            return (RTP_H264_P0);
          } else {
            sdp_attr_get_fmtp_pack_mode(sdp_p, level, 0, (uint16_t) fmtp_inst, &pack_mode);
            if (pack_mode == SDP_DEFAULT_PACKETIZATION_MODE_VALUE) {
              return (RTP_H264_P0);
            } else {
              return (RTP_H264_P1);
            }
          }
        }
        if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_AV1) == 0) {
          return (RTP_AV1);
        }
        if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_VP8) == 0) {
          return (RTP_VP8);
        }
        if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_VP9) == 0) {
          return (RTP_VP9);
        }
        if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_RED) == 0) {
          return (RTP_RED);
        }
        if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_ULPFEC) == 0) {
          return (RTP_ULPFEC);
        }
        if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_TELEPHONE_EVENT) == 0) {
          return (RTP_TELEPHONE_EVENT);
        }
        if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_RTX) == 0) {
          return (RTP_RTX);
        }
      }
    }
  }

  return (RTP_NONE);
}

/* Function:    sdp_get_media_payload_type
 * Description: Returns the payload type of the specified payload for the m=
 *              media token line.  If the media line or payload number is
 *              invalid, zero will be returned.  Application must validate
 *              the media line before using this routine.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to of the m= media line.  Will be 1-n.
 *              payload_num Number of the payload type to retrieve.  The
 *                          range is (1 - max num payloads).
 *              indicator   Returns the type of payload returned, either
 *                          NUMERIC or ENUM.
 * Returns:     Payload type or zero.
 */

uint32_t sdp_get_media_payload_type (sdp_t *sdp_p, uint16_t level, uint16_t payload_num,
                                sdp_payload_ind_e *indicator)
{
    sdp_mca_t  *mca_p;
    rtp_ptype   ptype;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return (0);
    }

    if ((payload_num < 1) || (payload_num > mca_p->num_payloads)) {
        return (0);
    }

    *indicator = mca_p->payload_indicator[payload_num-1];
    if ((mca_p->payload_type[payload_num-1] >= SDP_MIN_DYNAMIC_PAYLOAD) &&
        (mca_p->payload_type[payload_num-1] <= SDP_MAX_DYNAMIC_PAYLOAD)) {
        ptype = sdp_get_known_payload_type(sdp_p,
                                           level,
                                           mca_p->payload_type[payload_num-1]);
        if (ptype != RTP_NONE) {
          return (SET_PAYLOAD_TYPE_WITH_DYNAMIC(
                mca_p->payload_type[payload_num-1], ptype));
        }

    }
    return (mca_p->payload_type[payload_num-1]);
}

/* Function:    sdp_get_media_profile_payload_type
 * Description: Returns the payload type of the specified payload for the m=
 *              media token line.  If the media line or payload number is
 *              invalid, zero will be returned.  Application must validate
 *              the media line before using this routine.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The level to of the m= media line.  Will be 1-n.
 *              payload_num Number of the payload type to retrieve.  The
 *                          range is (1 - max num payloads).
 *              indicator   Returns the type of payload returned, either
 *                          NUMERIC or ENUM.
 * Returns:     Payload type or zero.
 */

uint32_t sdp_get_media_profile_payload_type (sdp_t *sdp_p, uint16_t level, uint16_t prof_num,
                                        uint16_t payload_num,
                                        sdp_payload_ind_e *indicator)
{
    sdp_mca_t            *mca_p;
    sdp_media_profiles_t *prof_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        return (0);
    }

    prof_p = mca_p->media_profiles_p;
    if ((prof_num < 1) ||
        (prof_num > prof_p->num_profiles)) {
        return (0);
    }

    if ((payload_num < 1) ||
        (payload_num > prof_p->num_payloads[prof_num-1])) {
        return (0);
    }

    *indicator = prof_p->payload_indicator[prof_num-1][payload_num-1];
    return (prof_p->payload_type[prof_num-1][payload_num-1]);
}

/* Function:    sdp_insert_media_line
 * Description: Insert a new media line at the level specified for the
 *              given SDP.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The new media level to insert.  Will be 1-n.
 * Returns:     SDP_SUCCESS, SDP_NO_RESOURCE, or SDP_INVALID_PARAMETER
 */

sdp_result_e sdp_insert_media_line (sdp_t *sdp_p, uint16_t level)
{
    sdp_mca_t  *mca_p;
    sdp_mca_t  *new_mca_p;

    if ((level < 1) || (level > (sdp_p->mca_count+1))) {
        if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
            SDPLogError(logTag, "%s Invalid media line (%u) to insert, max is "
                      "(%u).", sdp_p->debug_str, (unsigned)level, (unsigned)sdp_p->mca_count);
        }
        sdp_p->conf_p->num_invalid_param++;
        return (SDP_INVALID_PARAMETER);
    }

    /* Allocate resource for new media stream. */
    new_mca_p = sdp_alloc_mca(0);
    if (new_mca_p == NULL) {
        sdp_p->conf_p->num_no_resource++;
        return (SDP_NO_RESOURCE);
    }

    if (level == 1) {
        /* We're inserting the first media line */
        new_mca_p->next_p = sdp_p->mca_p;
        sdp_p->mca_p = new_mca_p;
    } else {
        /* Find the pointer to the media stream just prior to where
         * we want to insert the new stream.
         */

        mca_p = sdp_find_media_level(sdp_p, (uint16_t)(level-1));
        if (mca_p == NULL) {
            SDP_FREE(new_mca_p);
            sdp_p->conf_p->num_invalid_param++;
            return (SDP_INVALID_PARAMETER);
        }

        new_mca_p->next_p = mca_p->next_p;
        mca_p->next_p = new_mca_p;
    }

    sdp_p->mca_count++;
    return (SDP_SUCCESS);
}

/* Function:    sdp_set_media_type
 * Description: Sets the value of the media type parameter for the m=
 *              media token line.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The media level to set the param.  Will be 1-n.
 *              media       Media type for the media line.
 * Returns:     SDP_SUCCESS or SDP_INVALID_PARAMETER
 */

sdp_result_e sdp_set_media_type (sdp_t *sdp_p, uint16_t level, sdp_media_e media)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        sdp_p->conf_p->num_invalid_param++;
        return (SDP_INVALID_PARAMETER);
    }

    mca_p->media = media;
    return (SDP_SUCCESS);
}

/* Function:    sdp_set_media_portnum
 * Description: Sets the value of the port number parameter for the m=
 *              media token line.  If the port number is not valid with the
 *              port format specified for the media line, this call will
 *              fail.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The media level to set the param.  Will be 1-n.
 *              portnum     Port number to set.
 *              sctpport    sctp port for application m= line
 * Returns:     SDP_SUCCESS or SDP_INVALID_PARAMETER
 */

sdp_result_e sdp_set_media_portnum (sdp_t *sdp_p, uint16_t level, int32_t portnum, int32_t sctp_port)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        sdp_p->conf_p->num_invalid_param++;
        return (SDP_INVALID_PARAMETER);
    }

    mca_p->port = portnum;
    mca_p->sctpport = sctp_port;
    return (SDP_SUCCESS);
}

/* Function:    sdp_get_media_sctp_port
 * Description: Gets the value of the sctp port number parameter for the m=
 *              media token line.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The media level to set the param.  Will be 1-n.
 * Returns:     sctp_port or -1 on failure
 */

int32_t sdp_get_media_sctp_port(sdp_t *sdp_p, uint16_t level)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (!mca_p) {
        sdp_p->conf_p->num_invalid_param++;
        return -1;
    }

    return mca_p->sctpport;
}

sdp_sctp_media_fmt_type_e sdp_get_media_sctp_fmt(sdp_t *sdp_p, uint16_t level)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (!mca_p) {
        sdp_p->conf_p->num_invalid_param++;
        return -1;
    }

    return mca_p->sctp_fmt;
}

/* Function:    sdp_set_media_transport
 * Description: Sets the value of the transport type parameter for the m=
 *              media token line.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The media level to set the param.  Will be 1-n.
 *              transport   The transport type to set.
 * Returns:     SDP_SUCCESS or SDP_INVALID_PARAMETER
 */

sdp_result_e sdp_set_media_transport (sdp_t *sdp_p, uint16_t level,
                                      sdp_transport_e transport)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        sdp_p->conf_p->num_invalid_param++;
        return (SDP_INVALID_PARAMETER);
    }

    mca_p->transport = transport;
    return (SDP_SUCCESS);
}

/* Function:    sdp_add_media_profile
 * Description: Add a new profile type for the m= media token line.  This is
 *              used for AAL2 transport/profile types where more than one can
 *              be specified per media line.  All other transport types should
 *              use the other transport access routines rather than this.
 * Parameters:  sdp_p     The SDP handle returned by sdp_init_description.
 *              level       The media level to add the param.  Will be 1-n.
 *              profile     The profile type to add.
 * Returns:     SDP_SUCCESS or SDP_INVALID_PARAMETER
 */

sdp_result_e sdp_add_media_profile (sdp_t *sdp_p, uint16_t level,
                                    sdp_transport_e profile)
{
    uint16_t         prof_num;
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        sdp_p->conf_p->num_invalid_param++;
        return (SDP_INVALID_PARAMETER);
    }

    if (mca_p->media_profiles_p == NULL) {
        mca_p->media_profiles_p = (sdp_media_profiles_t *) \
            SDP_MALLOC(sizeof(sdp_media_profiles_t));
        if (mca_p->media_profiles_p == NULL) {
            sdp_p->conf_p->num_no_resource++;
            return (SDP_NO_RESOURCE);
        } else {
            mca_p->media_profiles_p->num_profiles = 0;
            /* Set the transport type to this first profile type. */
            mca_p->transport = profile;
        }
    }

    if (mca_p->media_profiles_p->num_profiles >= SDP_MAX_PROFILES) {
        if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
            SDPLogError(logTag, "%s Max number of media profiles already specified"
                      " for media level %u", sdp_p->debug_str, (unsigned)level);
        }
        sdp_p->conf_p->num_invalid_param++;
        return (SDP_INVALID_PARAMETER);
    }

    prof_num = mca_p->media_profiles_p->num_profiles++;
    mca_p->media_profiles_p->profile[prof_num] = profile;
    mca_p->media_profiles_p->num_payloads[prof_num] = 0;
    return (SDP_SUCCESS);
}

/* Function:    sdp_add_media_payload_type
 * Description: Add a new payload type for the media line at the level
 *              specified. The new payload type will be added at the end
 *              of the payload type list.
 * Parameters:  sdp_p      The SDP handle returned by sdp_init_description.
 *              level        The media level to add the payload.  Will be 1-n.
 *              payload_type The new payload type.
 *              indicator    Defines the type of payload returned, either
 *                           NUMERIC or ENUM.
 * Returns:     SDP_SUCCESS or SDP_INVALID_PARAMETER
 */

sdp_result_e sdp_add_media_payload_type (sdp_t *sdp_p, uint16_t level,
                                         uint16_t payload_type,
                                         sdp_payload_ind_e indicator)
{
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        sdp_p->conf_p->num_invalid_param++;
        return (SDP_INVALID_PARAMETER);
    }

    if (mca_p->num_payloads == SDP_MAX_PAYLOAD_TYPES) {
        if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
            SDPLogError(logTag, "%s Max number of payload types already defined "
                      "for media line %u", sdp_p->debug_str, (unsigned)level);
        }
        sdp_p->conf_p->num_invalid_param++;
        return (SDP_INVALID_PARAMETER);
    }

    mca_p->payload_indicator[mca_p->num_payloads] = indicator;
    mca_p->payload_type[mca_p->num_payloads++] = payload_type;
    return (SDP_SUCCESS);
}

/* Function:    sdp_add_media_profile_payload_type
 * Description: Add a new payload type for the media line at the level
 *              specified. The new payload type will be added at the end
 *              of the payload type list.
 * Parameters:  sdp_p      The SDP handle returned by sdp_init_description.
 *              level        The media level to add the payload.  Will be 1-n.
 *              prof_num     The profile number to add the payload type.
 *              payload_type The new payload type.
 *              indicator    Defines the type of payload returned, either
 *                           NUMERIC or ENUM.
 * Returns:     SDP_SUCCESS or SDP_INVALID_PARAMETER
 */

sdp_result_e sdp_add_media_profile_payload_type (sdp_t *sdp_p, uint16_t level,
                                                uint16_t prof_num, uint16_t payload_type,
                                                sdp_payload_ind_e indicator)
{
    uint16_t         num_payloads;
    sdp_mca_t  *mca_p;

    mca_p = sdp_find_media_level(sdp_p, level);
    if (mca_p == NULL) {
        sdp_p->conf_p->num_invalid_param++;
        return (SDP_INVALID_PARAMETER);
    }

    if ((prof_num < 1) ||
        (prof_num > mca_p->media_profiles_p->num_profiles)) {
        if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
            SDPLogError(logTag, "%s Invalid profile number (%u) for set profile "
                      " payload type", sdp_p->debug_str, (unsigned)level);
        }
        sdp_p->conf_p->num_invalid_param++;
        return (SDP_INVALID_PARAMETER);
    }

    if (mca_p->media_profiles_p->num_payloads[prof_num-1] ==
        SDP_MAX_PAYLOAD_TYPES) {
        if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
            SDPLogError(logTag, "%s Max number of profile payload types already "
                      "defined profile %u on media line %u",
                      sdp_p->debug_str, (unsigned)prof_num, (unsigned)level);
        }
        sdp_p->conf_p->num_invalid_param++;
        return (SDP_INVALID_PARAMETER);
    }

    /* Get the current num payloads for this profile, and inc the number
     * of payloads at the same time.  Then store the new payload type. */

    num_payloads = mca_p->media_profiles_p->num_payloads[prof_num-1]++;
    mca_p->media_profiles_p->payload_indicator[prof_num-1][num_payloads] =
                                                           indicator;
    mca_p->media_profiles_p->payload_type[prof_num-1][num_payloads] =
                                                           payload_type;
    return (SDP_SUCCESS);
}

/*
 * sdp_find_bw_line
 *
 * This helper function locates a specific bw line instance given the
 * sdp, the level and the instance number of the bw line.
 *
 * Returns: Pointer to the sdp_bw_data_t instance, or NULL.
 */

sdp_bw_data_t* sdp_find_bw_line (sdp_t *sdp_p, uint16_t level, uint16_t inst_num)
{
    sdp_bw_t            *bw_p;
    sdp_bw_data_t       *bw_data_p;
    sdp_mca_t           *mca_p;
    int                 bw_attr_count=0;

    if (level == SDP_SESSION_LEVEL) {
        bw_p = &(sdp_p->bw);
    } else {
        mca_p = sdp_find_media_level(sdp_p, level);
        if (mca_p == NULL) {
            sdp_p->conf_p->num_invalid_param++;
            return (NULL);
        }
        bw_p = &(mca_p->bw);
    }

    for (bw_data_p = bw_p->bw_data_list;
         bw_data_p != NULL;
         bw_data_p = bw_data_p->next_p) {
        bw_attr_count++;
        if (bw_attr_count == inst_num) {
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=96 H=93 G=94

¤ Dauer der Verarbeitung: 0.20 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.