summaryrefslogtreecommitdiffstats
path: root/third_party/sipcc/sdp_access.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/sipcc/sdp_access.c')
-rw-r--r--third_party/sipcc/sdp_access.c2100
1 files changed, 2100 insertions, 0 deletions
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);
+}
+