Source code

Revision control

Copy as Markdown

Other Tools

/* 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);
}