From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- third_party/sipcc/sdp_access.c | 2100 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2100 insertions(+) create mode 100644 third_party/sipcc/sdp_access.c (limited to 'third_party/sipcc/sdp_access.c') diff --git a/third_party/sipcc/sdp_access.c b/third_party/sipcc/sdp_access.c new file mode 100644 index 0000000000..8a065e2a6a --- /dev/null +++ b/third_party/sipcc/sdp_access.c @@ -0,0 +1,2100 @@ +/* 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_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_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) { + return bw_data_p; + } + } + + return NULL; +} + +/* + * sdp_copy_all_bw_lines + * + * Appends all the bw lines from the specified level of the orig sdp to the + * specified level of the dst sdp. + * + * Parameters: src_sdp_p The source SDP handle. + * dst_sdp_p The dest SDP handle. + * src_level The level in the src sdp from where to get the + * attributes. + * dst_level The level in the dst sdp where to put the + * attributes. + * Returns: SDP_SUCCESS Attributes were successfully copied. + */ +sdp_result_e sdp_copy_all_bw_lines (sdp_t *src_sdp_p, sdp_t *dst_sdp_p, + uint16_t src_level, uint16_t dst_level) +{ + sdp_bw_data_t *orig_bw_data_p; + sdp_bw_data_t *new_bw_data_p; + sdp_bw_data_t *bw_data_p; + sdp_bw_t *src_bw_p; + sdp_bw_t *dst_bw_p; + sdp_mca_t *mca_p; + + /* Find src bw list */ + if (src_level == SDP_SESSION_LEVEL) { + src_bw_p = &(src_sdp_p->bw); + } else { + mca_p = sdp_find_media_level(src_sdp_p, src_level); + if (mca_p == NULL) { + if (src_sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { + SDPLogError(logTag, "%s Invalid src media level (%u) for copy all " + "attrs ", src_sdp_p->debug_str, (unsigned)src_level); + } + return (SDP_INVALID_PARAMETER); + } + src_bw_p = &(mca_p->bw); + } + + /* Find dst bw list */ + if (dst_level == SDP_SESSION_LEVEL) { + dst_bw_p = &(dst_sdp_p->bw); + } else { + mca_p = sdp_find_media_level(dst_sdp_p, dst_level); + if (mca_p == NULL) { + if (src_sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { + SDPLogError(logTag, "%s Invalid dst media level (%u) for copy all " + "attrs ", src_sdp_p->debug_str, (unsigned)dst_level); + } + return (SDP_INVALID_PARAMETER); + } + dst_bw_p = &(mca_p->bw); + } + + orig_bw_data_p = src_bw_p->bw_data_list; + while (orig_bw_data_p) { + /* For ever bw line in the src, allocate a new one for the dst */ + new_bw_data_p = (sdp_bw_data_t*)SDP_MALLOC(sizeof(sdp_bw_data_t)); + if (new_bw_data_p == NULL) { + return (SDP_NO_RESOURCE); + } + new_bw_data_p->next_p = NULL; + new_bw_data_p->bw_modifier = orig_bw_data_p->bw_modifier; + new_bw_data_p->bw_val = orig_bw_data_p->bw_val; + + /* + * Enqueue the sdp_bw_data_t instance at the end of the list of + * sdp_bw_data_t instances. + */ + if (dst_bw_p->bw_data_list == NULL) { + dst_bw_p->bw_data_list = new_bw_data_p; + } else { + for (bw_data_p = dst_bw_p->bw_data_list; + bw_data_p->next_p != NULL; + bw_data_p = bw_data_p->next_p) { + + /*sa_ignore EMPTYLOOP*/ + ; /* Do nothing. */ + } + + bw_data_p->next_p = new_bw_data_p; + } + dst_bw_p->bw_data_count++; + + orig_bw_data_p = orig_bw_data_p->next_p; + } + + return (SDP_SUCCESS); +} + +/* Function: sdp_get_bw_modifier + * Description: Returns the bandwidth modifier parameter from the b= + * line. If no bw modifier has been set , + * SDP_BW_MODIFIER_UNSUPPORTED will be returned. + * Parameters: sdp_p The SDP handle returned by sdp_init_description. + * level The level from which to get the bw modifier. + * inst_num instance number of bw line at that level. The first + * instance has a inst_num of 1 and so on. + * Returns: Valid modifer value or SDP_BW_MODIFIER_UNSUPPORTED. + */ +sdp_bw_modifier_e sdp_get_bw_modifier (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) { + return (bw_data_p->bw_modifier); + } else { + return (SDP_BW_MODIFIER_UNSUPPORTED); + } +} + +/* Function: sdp_get_bw_value + * Description: Returns the bandwidth value parameter from the b= + * line. + * Parameters: sdp_p The SDP handle returned by sdp_init_description. + * level The level from which to get the bw value. + * inst_num instance number of bw line at the level. The first + * instance has a inst_num of 1 and so on. + * Returns: A valid numerical bw value or SDP_INVALID_VALUE. + */ +int32_t sdp_get_bw_value (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) { + return (bw_data_p->bw_val); + } else { + return (SDP_INVALID_VALUE); + } +} + +/* + * sdp_get_num_bw_lines + * + * Returns the number of bw lines are present at a given level. + * + * Parameters: sdp_p The SDP handle returned by sdp_init_description. + * level The level at which the count of bw lines is required + * + * Returns: A valid count or SDP_INVALID_VALUE + */ +int32_t sdp_get_num_bw_lines (sdp_t *sdp_p, uint16_t level) +{ + sdp_bw_t *bw_p; + sdp_mca_t *mca_p; + + 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 (SDP_INVALID_VALUE); + } + bw_p = &(mca_p->bw); + } + + return (bw_p->bw_data_count); +} + +/* + * sdp_add_new_bw_line + * + * To specify bandwidth parameters at any level, a bw line must first be + * added at that level using this function. After this addition, you can set + * the properties of the added bw line by using sdp_set_bw(). + * + * Note carefully though, that since there can be multiple instances of bw + * lines at any level, you must specify the instance number when setting + * or getting the properties of a bw line at any level. + * + * This function returns within the inst_num variable, the instance number + * of the created bw_line at that level. The instance number is 1-based. + * For example: + * v=0 #Session Level + * o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4 + * s=SDP Seminar + * c=IN IP4 10.1.0.2 + * t=0 0 + * b=AS:60 # instance number 1 + * b=TIAS:50780 # instance number 2 + * m=audio 1234 RTP/AVP 0 101 102 # 1st Media level + * b=AS:12 # instance number 1 + * b=TIAS:8480 # instance number 2 + * m=audio 1234 RTP/AVP 0 101 102 # 2nd Media level + * b=AS:20 # instance number 1 + * + * Parameters: + * sdp_p The SDP handle returned by sdp_init_description. + * level The level to create the bw line. + * bw_modifier The Type of bandwidth, CT, AS or TIAS. + * *inst_num This memory is set with the instance number of the newly + * created bw line instance. + */ +sdp_result_e sdp_add_new_bw_line (sdp_t *sdp_p, uint16_t level, sdp_bw_modifier_e bw_modifier, uint16_t *inst_num) +{ + sdp_bw_t *bw_p; + sdp_mca_t *mca_p; + sdp_bw_data_t *new_bw_data_p; + sdp_bw_data_t *bw_data_p = NULL; + + *inst_num = 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 (SDP_INVALID_PARAMETER); + } + bw_p = &(mca_p->bw); + } + + //see if a bw line already exist for this bw_modifier. + for(bw_data_p = bw_p->bw_data_list; bw_data_p != NULL; bw_data_p = bw_data_p->next_p) { + ++(*inst_num); + if (bw_data_p->bw_modifier == bw_modifier) { + return (SDP_SUCCESS); + } + } + + /* + * Allocate a new sdp_bw_data_t instance and set it's values from the + * input parameters. + */ + new_bw_data_p = (sdp_bw_data_t*)SDP_MALLOC(sizeof(sdp_bw_data_t)); + if (new_bw_data_p == NULL) { + sdp_p->conf_p->num_no_resource++; + return (SDP_NO_RESOURCE); + } + new_bw_data_p->next_p = NULL; + new_bw_data_p->bw_modifier = SDP_BW_MODIFIER_UNSUPPORTED; + new_bw_data_p->bw_val = 0; + + /* + * Enqueue the sdp_bw_data_t instance at the end of the list of + * sdp_bw_data_t instances. + */ + if (bw_p->bw_data_list == NULL) { + bw_p->bw_data_list = new_bw_data_p; + } else { + for (bw_data_p = bw_p->bw_data_list; + bw_data_p->next_p != NULL; + bw_data_p = bw_data_p->next_p) { + + /*sa_ignore EMPTYLOOP*/ + ; /* Do nothing. */ + } + + bw_data_p->next_p = new_bw_data_p; + } + *inst_num = ++bw_p->bw_data_count; + + return (SDP_SUCCESS); +} + +/* Function: sdp_get_mid_value + * Description: Returns the mid value parameter from the a= mid: line. + * Parameters: sdp_p The SDP handle returned by sdp_init_description. + * level SDP_MEDIA_LEVEL + * Returns: mid value. + */ +int32_t sdp_get_mid_value (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) { + sdp_p->conf_p->num_invalid_param++; + return (SDP_INVALID_VALUE); + } + return (mca_p->mid); +} + -- cgit v1.2.3