summaryrefslogtreecommitdiffstats
path: root/third_party/sipcc/sdp_attr_access.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/sipcc/sdp_attr_access.c6426
1 files changed, 6426 insertions, 0 deletions
diff --git a/third_party/sipcc/sdp_attr_access.c b/third_party/sipcc/sdp_attr_access.c
new file mode 100644
index 0000000000..b3efa3e6b6
--- /dev/null
+++ b/third_party/sipcc/sdp_attr_access.c
@@ -0,0 +1,6426 @@
+/* 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_attr_access";
+
+/* Attribute access routines are all defined by the following parameters.
+ *
+ * sdp_p The SDP handle returned by sdp_init_description.
+ * level The level the attribute is defined. Can be either
+ * SDP_SESSION_LEVEL or 0-n specifying a media line level.
+ * inst_num The instance number of the attribute. Multiple instances
+ * of a particular attribute may exist at each level and so
+ * the inst_num determines the particular attribute at that
+ * level that should be accessed. Note that this is the
+ * instance number of the specified type of attribute, not the
+ * overall attribute number at the level. Also note that the
+ * instance number is 1-based. For example:
+ * v=0
+ * o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4
+ * s=SDP Seminar
+ * c=IN IP4 10.1.0.2
+ * t=0 0
+ * m=audio 1234 RTP/AVP 0 101 102
+ * a=foo 1
+ * a=foo 2
+ * a=bar 1 # This is instance 1 of attribute bar.
+ * a=foo 3 # This is instance 3 of attribute foo.
+ * cap_num Almost all of the attributes may be defined as X-cpar
+ * parameters (with the exception of X-sqn, X-cap, and X-cpar).
+ * If the cap_num is set to zero, then the attribute is not
+ * an X-cpar parameter attribute. If the cap_num is any other
+ * value, it specifies the capability number that the X-cpar
+ * attribute is specified for.
+ */
+
+/* Attribute handling:
+ *
+ * There are two basic types of attributes handled by the SDP library,
+ * those defined by a= token lines, and those embedded with a=X-cpar lines.
+ * The handling for each of these is described here.
+ *
+ * Simple (non X-cpar attributes):
+ *
+ * Attributes not embedded in a=X-cpar lines are referenced by level and
+ * instance number. For these attributes the capability number is always
+ * set to zero.
+ *
+ * An application will typically process these attributes in one of two ways.
+ * With the first method, the application can determine the total number
+ * of attributes defined at a given level and process them one at a time.
+ * For each attribute, the application will query the library to find out
+ * what type of attribute it is and which instance within that type. The
+ * application can then process this particular attribute referencing it
+ * by level and instance number.
+ *
+ * A second method of processing attributes is for applications to determine
+ * each type of attribute they are interested in, query the SDP library to
+ * find out how many of that type of attribute exist at a given level, and
+ * process each one at a time.
+ *
+ * X-cpar attribute processing:
+ *
+ * X-cpar attributes can contain embedded attributes. They are associated
+ * with X-cap attribute lines. An example of X-cap and X-cpar attributes
+ * found in an SDP is as follows:
+ *
+ * v=0
+ * o=- 25678 753849 IN IP4 128.96.41.1
+ * s=-
+ * t=0 0
+ * c=IN IP4 10.1.0.2
+ * m=audio 3456 RTP/AVP 18 96
+ * a=rtpmap:96 telephone-event/8000
+ * a=fmtp:96 0-15,32-35
+ * a=X-sqn: 0
+ * a=X-cap: 1 audio RTP/AVP 0 18 96 97
+ * a=X-cpar: a=fmtp:96 0-16,32-35
+ * a=X-cpar: a=rtpmap:97 X-NSE/8000
+ * a=X-cpar: a=fmtp:97 195-197
+ * a=X-cap: 5 image udptl t38
+ * a=X-cap: 6 application udp X-tmr
+ * a=X-cap: 7 audio RTP/AVP 100 101
+ * a=X-cpar: a=rtpmap:100 g.711/8000
+ * a=X-cpar: a=rtpmap:101 g.729/8000
+ *
+ * X-cap attributes can be defined at the SESSION_LEVEL or any media level.
+ * An X-cap attr is defined by the level and instance number just like
+ * other attributes. In the example above, X-cap attrs are defined at
+ * media level 1 and there are four instances at that level.
+ *
+ * The X-cpar attributes can also be referenced by level and instance number.
+ * However, the embedded attribute within an X-cpar attribute must be
+ * referenced by level, instance number, and capability number. This is
+ * because the X-cpar attribute is associated with a particular X-cap/
+ * capability.
+ * For all attributes that are not embedded within an X-cpar attribute, the
+ * cap_num should be referenced as zero. But for X-cpar attributes, the
+ * cap_num is specified to be one of the capability numbers of the previous
+ * X-cap line. The number of capabilities specified in an X-cap line is
+ * equal to the number of payloads. Thus, in this example, the first X-cap
+ * attr instance specifies capabilities 1-4, the second specifies capability
+ * 5, the third capability 6, and the fourth capabilities 7-8.
+ *
+ * X-cpar attributes can be processed with methods similar to the two
+ * previously mentioned. For each X-cap attribute, the application can
+ * use one of two methods to process the X-cpar attributes. First, it
+ * can query the total number of X-cpar attributes associated with a
+ * given X-cap attribute. The X-cap attribute is here defined by a level
+ * and a capability number. In the example above, the total number of
+ * attributes defined is as follows:
+ * level 1, cap_num 1 - total attrs: 3
+ * level 1, cap_num 5 - total attrs: 0
+ * level 1, cap_num 6 - total attrs: 0
+ * level 1, cap_num 7 - total attrs: 2
+ *
+ * Note that if the application queried the number of attributes for
+ * cap_num 2, 3, or 4, it would also return 3 attrs, and for cap_num
+ * 8 the library would return 2.
+ *
+ * Once the application determines the total number of attributes for
+ * that capability, it can again query the embedded attribute type and
+ * instance. For example, sdp_get_attr_type would return the following:
+ * level 1, cap_num 1, attr 1 -> attr type fmtp, instance 1
+ * level 1, cap_num 1, attr 2 -> attr type rtpmap, instance 1
+ * level 1, cap_num 1, attr 3 -> attr type fmtp, instance 2
+ * level 1, cap_num 7, attr 1 -> attr type rtpmap, instance 1
+ * level 1, cap_num 7, attr 2 -> attr type rtpmap, instance 2
+ *
+ * The individual embedded attributes can then be accessed by level,
+ * cap_num, and instance number.
+ *
+ * With the second method for handling X-cpar attributes, the application
+ * determines the types of attributes it is interested in. It can then
+ * query the SDP library to determine the number of attributes of that
+ * type found for that level and cap_num, and then process each one at
+ * a time. e.g., calling sdp_attr_num_instances would give:
+ * level 1, cap_num 1, attr_type fmtp -> two instances
+ * level 1, cap_num 1, attr_type rtpmap -> one instance
+ * level 1, cap_num 7, attr_type fmtp -> zero instances
+ * level 1, cap_num 7, attr_type rtpmap -> two instances
+ */
+
+
+/* Function: sdp_add_new_attr
+ * Description: Add a new attribute of the specified type at the given
+ * level and capability level or base attribute if cap_num
+ * is zero.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * attr_type The type of attribute to add.
+ * inst_num Pointer to a uint16_t in which to return the instance
+ * number of the newly added attribute.
+ * Returns: SDP_SUCCESS Attribute was added successfully.
+ * SDP_NO_RESOURCE No memory avail for new attribute.
+ * SDP_INVALID_PARAMETER Specified media line is not defined.
+ */
+sdp_result_e sdp_add_new_attr (sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ sdp_attr_e attr_type, uint16_t *inst_num)
+{
+ uint16_t i;
+ sdp_mca_t *mca_p;
+ sdp_mca_t *cap_p;
+ sdp_attr_t *attr_p;
+ sdp_attr_t *new_attr_p;
+ sdp_attr_t *prev_attr_p=NULL;
+ sdp_fmtp_t *fmtp_p;
+ sdp_comediadir_t *comediadir_p;
+
+ *inst_num = 0;
+
+ if ((cap_num != 0) &&
+ ((attr_type == SDP_ATTR_X_CAP) || (attr_type == SDP_ATTR_X_CPAR) ||
+ (attr_type == SDP_ATTR_X_SQN) || (attr_type == SDP_ATTR_CDSC) ||
+ (attr_type == SDP_ATTR_CPAR) || (attr_type == SDP_ATTR_SQN))) {
+ if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) {
+ SDPLogDebug(logTag, "%s Warning: Invalid attribute type for X-cpar/cdsc "
+ "parameter.", sdp_p->debug_str);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+
+ /* Some attributes are valid only under media level */
+ if (level == SDP_SESSION_LEVEL) {
+ switch (attr_type) {
+ case SDP_ATTR_RTCP:
+ case SDP_ATTR_LABEL:
+ return (SDP_INVALID_MEDIA_LEVEL);
+
+ default:
+ break;
+ }
+ }
+
+ new_attr_p = (sdp_attr_t *)SDP_MALLOC(sizeof(sdp_attr_t));
+ if (new_attr_p == NULL) {
+ sdp_p->conf_p->num_no_resource++;
+ return (SDP_NO_RESOURCE);
+ }
+
+ new_attr_p->type = attr_type;
+ new_attr_p->next_p = NULL;
+
+ /* Initialize the new attribute structure */
+ if ((new_attr_p->type == SDP_ATTR_X_CAP) ||
+ (new_attr_p->type == SDP_ATTR_CDSC)) {
+ new_attr_p->attr.cap_p = (sdp_mca_t *)SDP_MALLOC(sizeof(sdp_mca_t));
+ if (new_attr_p->attr.cap_p == NULL) {
+ sdp_free_attr(new_attr_p);
+ sdp_p->conf_p->num_no_resource++;
+ return (SDP_NO_RESOURCE);
+ }
+ } else if (new_attr_p->type == SDP_ATTR_FMTP) {
+ fmtp_p = &(new_attr_p->attr.fmtp);
+ fmtp_p->fmtp_format = SDP_FMTP_UNKNOWN_TYPE;
+ // set to invalid value
+ fmtp_p->packetization_mode = SDP_INVALID_PACKETIZATION_MODE_VALUE;
+ fmtp_p->level_asymmetry_allowed = SDP_INVALID_LEVEL_ASYMMETRY_ALLOWED_VALUE;
+ fmtp_p->annexb_required = FALSE;
+ fmtp_p->annexa_required = FALSE;
+ fmtp_p->maxval = 0;
+ fmtp_p->bitrate = 0;
+ fmtp_p->cif = 0;
+ fmtp_p->qcif = 0;
+ fmtp_p->profile = SDP_INVALID_VALUE;
+ fmtp_p->level = SDP_INVALID_VALUE;
+ fmtp_p->parameter_add = SDP_FMTP_UNUSED;
+ fmtp_p->usedtx = SDP_FMTP_UNUSED;
+ fmtp_p->stereo = SDP_FMTP_UNUSED;
+ fmtp_p->useinbandfec = SDP_FMTP_UNUSED;
+ fmtp_p->cbr = SDP_FMTP_UNUSED;
+ for (i=0; i < SDP_NE_NUM_BMAP_WORDS; i++) {
+ fmtp_p->bmap[i] = 0;
+ }
+ } else if ((new_attr_p->type == SDP_ATTR_RTPMAP) ||
+ (new_attr_p->type == SDP_ATTR_SPRTMAP)) {
+ new_attr_p->attr.transport_map.num_chan = 1;
+ } else if (new_attr_p->type == SDP_ATTR_DIRECTION) {
+ comediadir_p = &(new_attr_p->attr.comediadir);
+ comediadir_p->role = SDP_MEDIADIR_ROLE_PASSIVE;
+ comediadir_p->conn_info_present = FALSE;
+ } else if (new_attr_p->type == SDP_ATTR_MPTIME) {
+ sdp_mptime_t *mptime = &(new_attr_p->attr.mptime);
+ mptime->num_intervals = 0;
+ }
+
+ if (cap_num == 0) {
+ /* Add a new attribute. */
+ if (level == SDP_SESSION_LEVEL) {
+ if (sdp_p->sess_attrs_p == NULL) {
+ sdp_p->sess_attrs_p = new_attr_p;
+ } else {
+ for (attr_p = sdp_p->sess_attrs_p;
+ attr_p != NULL;
+ prev_attr_p = attr_p, attr_p = attr_p->next_p) {
+ /* Count the num instances of this type. */
+ if (attr_p->type == attr_type) {
+ (*inst_num)++;
+ }
+ }
+ prev_attr_p->next_p = new_attr_p;
+ }
+ } else {
+ mca_p = sdp_find_media_level(sdp_p, level);
+ if (mca_p == NULL) {
+ sdp_free_attr(new_attr_p);
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+ if (mca_p->media_attrs_p == NULL) {
+ mca_p->media_attrs_p = new_attr_p;
+ } else {
+ for (attr_p = mca_p->media_attrs_p;
+ attr_p != NULL;
+ prev_attr_p = attr_p, attr_p = attr_p->next_p) {
+ /* Count the num instances of this type. */
+ if (attr_p->type == attr_type) {
+ (*inst_num)++;
+ }
+ }
+ prev_attr_p->next_p = new_attr_p;
+ }
+ }
+ } else {
+ /* Add a new capability attribute - find the capability attr. */
+ attr_p = sdp_find_capability(sdp_p, level, cap_num);
+ if (attr_p == NULL) {
+ sdp_free_attr(new_attr_p);
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+ cap_p = attr_p->attr.cap_p;
+ if (cap_p->media_attrs_p == NULL) {
+ cap_p->media_attrs_p = new_attr_p;
+ } else {
+ for (attr_p = cap_p->media_attrs_p;
+ attr_p != NULL;
+ prev_attr_p = attr_p, attr_p = attr_p->next_p) {
+ /* Count the num instances of this type. */
+ if (attr_p->type == attr_type) {
+ (*inst_num)++;
+ }
+ }
+ prev_attr_p->next_p = new_attr_p;
+ }
+ }
+
+ /* Increment the instance num for the attr just added. */
+ (*inst_num)++;
+ return (SDP_SUCCESS);
+}
+
+/* Function: sdp_attr_num_instances
+ * Description: Get the number of attributes of the specified type at
+ * the given level and capability level.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * attr_type The type of attribute to add.
+ * num_attr_inst Pointer to a uint16_t in which to return the
+ * number of attributes.
+ * Returns: SDP_SUCCESS Attribute was added successfully.
+ * SDP_INVALID_PARAMETER Specified media line is not defined.
+ */
+sdp_result_e sdp_attr_num_instances (sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ sdp_attr_e attr_type, uint16_t *num_attr_inst)
+{
+ sdp_attr_t *attr_p;
+ sdp_result_e rc;
+ static char fname[] = "attr_num_instances";
+
+ *num_attr_inst = 0;
+
+ rc = sdp_find_attr_list(sdp_p, level, cap_num, &attr_p, fname);
+ if (rc == SDP_SUCCESS) {
+ /* Found the attr list. Count the number of attrs of the given
+ * type at this level. */
+ for (; attr_p != NULL; attr_p = attr_p->next_p) {
+ if (attr_p->type == attr_type) {
+ (*num_attr_inst)++;
+ }
+ }
+
+ }
+
+ return (rc);
+}
+
+/* Forward declaration for use in sdp_free_attr */
+static boolean sdp_attr_is_long_string(sdp_attr_e attr_type);
+
+
+/* Internal routine to free the memory associated with an attribute.
+ * Certain attributes allocate additional memory. Free this and then
+ * free the attribute itself.
+ * Note that this routine may be called at any point (i.e., may be
+ * called due to a failure case) and so the additional memory
+ * associated with an attribute may or may not have been already
+ * allocated. This routine should check this carefully.
+ */
+void sdp_free_attr (sdp_attr_t *attr_p)
+{
+ sdp_mca_t *cap_p;
+ sdp_attr_t *cpar_p;
+ sdp_attr_t *next_cpar_p;
+ int i;
+
+ /* If this is an X-cap/cdsc attr, free the cap_p structure and
+ * all X-cpar/cpar attributes. */
+ if ((attr_p->type == SDP_ATTR_X_CAP) ||
+ (attr_p->type == SDP_ATTR_CDSC)) {
+ cap_p = attr_p->attr.cap_p;
+ if (cap_p != NULL) {
+ for (cpar_p = cap_p->media_attrs_p; cpar_p != NULL;) {
+ next_cpar_p = cpar_p->next_p;
+ sdp_free_attr(cpar_p);
+ cpar_p = next_cpar_p;
+ }
+ SDP_FREE(cap_p);
+ }
+ } else if ((attr_p->type == SDP_ATTR_SDESCRIPTIONS) ||
+ (attr_p->type == SDP_ATTR_SRTP_CONTEXT)) {
+ SDP_FREE(attr_p->attr.srtp_context.session_parameters);
+ } else if (sdp_attr_is_long_string(attr_p->type)) {
+ SDP_FREE(attr_p->attr.stringp);
+ }
+
+ if (attr_p->type == SDP_ATTR_GROUP) {
+ for (i = 0; i < attr_p->attr.stream_data.num_group_id; i++) {
+ SDP_FREE(attr_p->attr.stream_data.group_ids[i]);
+ }
+ } else if (attr_p->type == SDP_ATTR_MSID_SEMANTIC) {
+ for (i = 0; i < SDP_MAX_MEDIA_STREAMS; ++i) {
+ SDP_FREE(attr_p->attr.msid_semantic.msids[i]);
+ }
+ }
+
+ /* Now free the actual attribute memory. */
+ SDP_FREE(attr_p);
+
+}
+
+
+/* Function: sdp_find_attr_list
+ * Description: Find the attribute list for the specified level and cap_num.
+ * Note: This is not an API for the application but an internal
+ * routine used by the SDP library.
+ * Parameters: sdp_p Pointer to the SDP to search.
+ * level The level to check for the attribute list.
+ * cap_num The capability number associated with the
+ * attribute list. If none, should be zero.
+ * attr_p Pointer to the attr list pointer. Will be
+ * filled in on return if successful.
+ * fname String function name calling this routine.
+ * Use for printing debug.
+ * Returns: SDP_SUCCESS
+ * SDP_INVALID_MEDIA_LEVEL
+ * SDP_INVALID_CAPABILITY
+ * SDP_FAILURE
+ */
+sdp_result_e sdp_find_attr_list (sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ sdp_attr_t **attr_p, char *fname)
+{
+ sdp_mca_t *mca_p;
+ sdp_mca_t *cap_p;
+ sdp_attr_t *cap_attr_p;
+
+ /* Initialize the attr pointer. */
+ *attr_p = NULL;
+
+ if (cap_num == 0) {
+ /* Find attribute list at the specified level. */
+ if (level == SDP_SESSION_LEVEL) {
+ *attr_p = sdp_p->sess_attrs_p;
+ } 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);
+ }
+ *attr_p = mca_p->media_attrs_p;
+ }
+ } else {
+ /* Find the attr list for the capability specified. */
+ cap_attr_p = sdp_find_capability(sdp_p, level, cap_num);
+ if (cap_attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s %s, invalid capability %u at "
+ "level %u specified.", sdp_p->debug_str, fname,
+ (unsigned)cap_num, (unsigned)level);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_CAPABILITY);
+ }
+ cap_p = cap_attr_p->attr.cap_p;
+ *attr_p = cap_p->media_attrs_p;
+ }
+
+ return (SDP_SUCCESS);
+}
+
+/* Find fmtp inst_num with correct payload value or -1 for failure */
+int sdp_find_fmtp_inst (sdp_t *sdp_p, uint16_t level, uint16_t payload_num)
+{
+ uint16_t attr_count=0;
+ sdp_mca_t *mca_p;
+ sdp_attr_t *attr_p;
+
+ /* Attr is at a media level */
+ mca_p = sdp_find_media_level(sdp_p, level);
+ if (mca_p == NULL) {
+ return (-1);
+ }
+ for (attr_p = mca_p->media_attrs_p; attr_p != NULL;
+ attr_p = attr_p->next_p) {
+ if (attr_p->type == SDP_ATTR_FMTP) {
+ attr_count++;
+ if (attr_p->attr.fmtp.payload_num == payload_num) {
+ return (attr_count);
+ }
+ }
+ }
+
+ return (-1);
+
+}
+
+/* Function: sdp_find_attr
+ * Description: Find the specified attribute in an SDP structure.
+ * 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 level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * attr_type The type of attribute to find.
+ * inst_num The instance num of the attribute to find.
+ * Range should be (1 - max num insts of this
+ * particular type of attribute at this level).
+ * Returns: Pointer to the attribute or NULL if not found.
+ */
+sdp_attr_t *sdp_find_attr (sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ sdp_attr_e attr_type, uint16_t inst_num)
+{
+ uint16_t attr_count=0;
+ sdp_mca_t *mca_p;
+ sdp_mca_t *cap_p;
+ sdp_attr_t *attr_p;
+
+ if (inst_num < 1) {
+ return (NULL);
+ }
+
+ if (cap_num == 0) {
+ if (level == SDP_SESSION_LEVEL) {
+ for (attr_p = sdp_p->sess_attrs_p; attr_p != NULL;
+ attr_p = attr_p->next_p) {
+ if (attr_p->type == attr_type) {
+ attr_count++;
+ if (attr_count == inst_num) {
+ return (attr_p);
+ }
+ }
+ }
+ } else { /* Attr is at a media level */
+ mca_p = sdp_find_media_level(sdp_p, level);
+ if (mca_p == NULL) {
+ return (NULL);
+ }
+ for (attr_p = mca_p->media_attrs_p; attr_p != NULL;
+ attr_p = attr_p->next_p) {
+ if (attr_p->type == attr_type) {
+ attr_count++;
+ if (attr_count == inst_num) {
+ return (attr_p);
+ }
+ }
+ }
+ } /* Attr is at a media level */
+ } else {
+ /* Attr is a capability X-cpar/cpar attribute. */
+ attr_p = sdp_find_capability(sdp_p, level, cap_num);
+ if (attr_p == NULL) {
+ return (NULL);
+ }
+ cap_p = attr_p->attr.cap_p;
+ /* Now find the specific attribute. */
+ for (attr_p = cap_p->media_attrs_p; attr_p != NULL;
+ attr_p = attr_p->next_p) {
+ if (attr_p->type == attr_type) {
+ attr_count++;
+ if (attr_count == inst_num) {
+ return (attr_p);
+ }
+ }
+ }
+ }
+
+ return (NULL);
+}
+
+/* Function: sdp_find_capability
+ * Description: Find the specified capability attribute in an SDP structure.
+ * Note: This is not an API for the application but an internal
+ * routine used by the SDP library.
+ * Parameters: sdp_p The SDP handle.
+ * level The level to check for the capability.
+ * cap_num The capability number to locate.
+ * Returns: Pointer to the capability attribute or NULL if not found.
+ */
+sdp_attr_t *sdp_find_capability (sdp_t *sdp_p, uint16_t level, uint8_t cap_num)
+{
+ uint8_t cur_cap_num=0;
+ sdp_mca_t *mca_p;
+ sdp_mca_t *cap_p;
+ sdp_attr_t *attr_p;
+
+ if (level == SDP_SESSION_LEVEL) {
+ for (attr_p = sdp_p->sess_attrs_p; attr_p != NULL;
+ attr_p = attr_p->next_p) {
+ if ((attr_p->type == SDP_ATTR_X_CAP) ||
+ (attr_p->type == SDP_ATTR_CDSC)) {
+ cap_p = attr_p->attr.cap_p;
+ cur_cap_num += cap_p->num_payloads;
+ if (cap_num <= cur_cap_num) {
+ /* This is the right capability */
+ return (attr_p);
+ }
+ }
+ }
+ } else { /* Capability is at a media level */
+ mca_p = sdp_find_media_level(sdp_p, level);
+ if (mca_p == NULL) {
+ return (NULL);
+ }
+ for (attr_p = mca_p->media_attrs_p; attr_p != NULL;
+ attr_p = attr_p->next_p) {
+ if ((attr_p->type == SDP_ATTR_X_CAP) ||
+ (attr_p->type == SDP_ATTR_CDSC)) {
+ cap_p = attr_p->attr.cap_p;
+ cur_cap_num += cap_p->num_payloads;
+ if (cap_num <= cur_cap_num) {
+ /* This is the right capability */
+ return (attr_p);
+ }
+ }
+ }
+ }
+
+ /* We didn't find the specified capability. */
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Unable to find specified capability (level %u, "
+ "cap_num %u).", sdp_p->debug_str, (unsigned)level, (unsigned)cap_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (NULL);
+}
+
+/* Function: sdp_attr_valid(sdp_t *sdp_p)
+ * Description: Returns true or false depending on whether the specified
+ * instance of the given attribute has been defined at the
+ * given level.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * attr_type The attribute type to validate.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: TRUE or FALSE.
+ */
+tinybool sdp_attr_valid (sdp_t *sdp_p, sdp_attr_e attr_type, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ if (sdp_find_attr(sdp_p, level, cap_num, attr_type, inst_num) == NULL) {
+ return (FALSE);
+ } else {
+ return (TRUE);
+ }
+}
+
+/* Function: sdp_attr_line_number(sdp_t *sdp_p)
+ * Description: Returns the line number this attribute appears on.
+ * Only works if the SDP was parsed rather than created
+ * locally.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * attr_type The attribute type to validate.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: line number, or 0 if an error
+ */
+uint32_t sdp_attr_line_number (sdp_t *sdp_p, sdp_attr_e attr_type, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, attr_type, inst_num);
+ if (attr_p == NULL) {
+ return 0;
+ } else {
+ return attr_p->line_number;
+ }
+}
+
+static boolean sdp_attr_is_simple_string(sdp_attr_e attr_type) {
+ if ((attr_type != SDP_ATTR_BEARER) &&
+ (attr_type != SDP_ATTR_CALLED) &&
+ (attr_type != SDP_ATTR_CONN_TYPE) &&
+ (attr_type != SDP_ATTR_DIALED) &&
+ (attr_type != SDP_ATTR_DIALING) &&
+ (attr_type != SDP_ATTR_FRAMING) &&
+ (attr_type != SDP_ATTR_MID) &&
+ (attr_type != SDP_ATTR_X_SIDIN) &&
+ (attr_type != SDP_ATTR_X_SIDOUT)&&
+ (attr_type != SDP_ATTR_X_CONFID) &&
+ (attr_type != SDP_ATTR_LABEL) &&
+ (attr_type != SDP_ATTR_ICE_OPTIONS) &&
+ (attr_type != SDP_ATTR_IMAGEATTR) &&
+ (attr_type != SDP_ATTR_SIMULCAST) &&
+ (attr_type != SDP_ATTR_RID)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Function: sdp_attr_get_simple_string
+ * Description: Returns a pointer to a string attribute parameter. This
+ * routine can only be called for attributes that have just
+ * one string parameter. The value is returned as a const
+ * ptr and so cannot be modified by the application. If the
+ * given attribute is not defined, NULL will be returned.
+ * Attributes with a simple string parameter currently include:
+ * bearer, called, connection_type, dialed, dialing, direction
+ * and framing.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * attr_type The simple string attribute type.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Pointer to the parameter value.
+ */
+const char *sdp_attr_get_simple_string (sdp_t *sdp_p, sdp_attr_e attr_type,
+ uint16_t level, uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ if (!sdp_attr_is_simple_string(attr_type)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Attribute type is not a simple string (%s)",
+ sdp_p->debug_str, sdp_get_attr_name(attr_type));
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (NULL);
+ }
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, attr_type, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Attribute %s, level %u instance %u not found.",
+ sdp_p->debug_str, sdp_get_attr_name(attr_type),
+ (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (NULL);
+ } else {
+ return (attr_p->attr.string_val);
+ }
+}
+
+static boolean sdp_attr_is_long_string(sdp_attr_e attr_type) {
+ return (attr_type == SDP_ATTR_IDENTITY || attr_type == SDP_ATTR_DTLS_MESSAGE);
+}
+
+/* Identical in usage to sdp_attr_get_simple_string() */
+const char *sdp_attr_get_long_string (sdp_t *sdp_p, sdp_attr_e attr_type,
+ uint16_t level, uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ if (!sdp_attr_is_long_string(attr_type)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Attribute type is not a long string (%s)",
+ sdp_p->debug_str, sdp_get_attr_name(attr_type));
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (NULL);
+ }
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, attr_type, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Attribute %s, level %u instance %u not found.",
+ sdp_p->debug_str, sdp_get_attr_name(attr_type),
+ (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (NULL);
+ } else {
+ return (attr_p->attr.stringp);
+ }
+}
+
+static boolean sdp_attr_is_simple_u32(sdp_attr_e attr_type) {
+ if ((attr_type != SDP_ATTR_EECID) &&
+ (attr_type != SDP_ATTR_PTIME) &&
+ (attr_type != SDP_ATTR_MAXPTIME) &&
+ (attr_type != SDP_ATTR_SCTPPORT) &&
+ (attr_type != SDP_ATTR_MAXMESSAGESIZE) &&
+ (attr_type != SDP_ATTR_T38_VERSION) &&
+ (attr_type != SDP_ATTR_T38_MAXBITRATE) &&
+ (attr_type != SDP_ATTR_T38_MAXBUFFER) &&
+ (attr_type != SDP_ATTR_T38_MAXDGRAM) &&
+ (attr_type != SDP_ATTR_X_SQN) &&
+ (attr_type != SDP_ATTR_TC1_PAYLOAD_BYTES) &&
+ (attr_type != SDP_ATTR_TC1_WINDOW_SIZE) &&
+ (attr_type != SDP_ATTR_TC2_PAYLOAD_BYTES) &&
+ (attr_type != SDP_ATTR_TC2_WINDOW_SIZE) &&
+ (attr_type != SDP_ATTR_FRAMERATE)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Function: sdp_attr_get_simple_u32
+ * Description: Returns an unsigned 32-bit attribute parameter. This
+ * routine can only be called for attributes that have just
+ * one uint32_t parameter. If the given attribute is not defined,
+ * zero will be returned. There is no way for the application
+ * to determine if zero is the actual value or the attribute
+ * wasn't defined, so the application must use the
+ * sdp_attr_valid function to determine this.
+ * Attributes with a simple uint32_t parameter currently include:
+ * eecid, ptime, T38FaxVersion, T38maxBitRate, T38FaxMaxBuffer,
+ * T38FaxMaxDatagram, X-sqn, TC1PayloadBytes, TC1WindowSize,
+ * TC2PayloadBytes, TC2WindowSize, rtcp.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * attr_type The simple uint32_t attribute type.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: uint32_t parameter value.
+ */
+uint32_t sdp_attr_get_simple_u32 (sdp_t *sdp_p, sdp_attr_e attr_type, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ if (!sdp_attr_is_simple_u32(attr_type)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Attribute type is not a simple uint32_t (%s)",
+ sdp_p->debug_str, sdp_get_attr_name(attr_type));
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ }
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, attr_type, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Attribute %s, level %u instance %u not found.",
+ sdp_p->debug_str, sdp_get_attr_name(attr_type),
+ (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ return (attr_p->attr.u32_val);
+ }
+}
+
+/* Function: sdp_attr_get_simple_boolean
+ * Description: Returns a boolean attribute parameter. This
+ * routine can only be called for attributes that have just
+ * one boolean parameter. If the given attribute is not defined,
+ * FALSE will be returned. There is no way for the application
+ * to determine if FALSE is the actual value or the attribute
+ * wasn't defined, so the application must use the
+ * sdp_attr_valid function to determine this.
+ * Attributes with a simple boolean parameter currently include:
+ * T38FaxFillBitRemoval, T38FaxTranscodingMMR,
+ * T38FaxTranscodingJBIG, and TMRGwXid.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * attr_type The simple boolean attribute type.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Boolean value.
+ */
+tinybool sdp_attr_get_simple_boolean (sdp_t *sdp_p, sdp_attr_e attr_type,
+ uint16_t level, uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ if ((attr_type != SDP_ATTR_T38_FILLBITREMOVAL) &&
+ (attr_type != SDP_ATTR_T38_TRANSCODINGMMR) &&
+ (attr_type != SDP_ATTR_T38_TRANSCODINGJBIG) &&
+ (attr_type != SDP_ATTR_TMRGWXID)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Attribute type is not a simple boolean (%s)",
+ sdp_p->debug_str, sdp_get_attr_name(attr_type));
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (FALSE);
+ }
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, attr_type, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Attribute %s, level %u instance %u not found.",
+ sdp_p->debug_str, sdp_get_attr_name(attr_type),
+ (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (FALSE);
+ } else {
+ return (attr_p->attr.boolean_val);
+ }
+}
+
+/*
+ * sdp_attr_get_maxprate
+ *
+ * This function is used by the application layer to get the packet-rate
+ * within the maxprate attribute.
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * inst_num The attribute instance number to set.
+ *
+ * Returns a pointer to a constant char array that stores the packet-rate,
+ * OR null if the attribute does not exist.
+ */
+const char*
+sdp_attr_get_maxprate (sdp_t *sdp_p, uint16_t level, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_MAXPRATE, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Attribute %s, level %u instance %u not found.",
+ sdp_p->debug_str, sdp_get_attr_name(SDP_ATTR_MAXPRATE),
+ (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (NULL);
+ } else {
+ return (attr_p->attr.string_val);
+ }
+}
+
+/* Function: sdp_attr_get_t38ratemgmt
+ * Description: Returns the value of the t38ratemgmt attribute
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, SDP_T38_UNKNOWN_RATE is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Ratemgmt value.
+ */
+sdp_t38_ratemgmt_e sdp_attr_get_t38ratemgmt (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_T38_RATEMGMT, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s t38ratemgmt attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_T38_UNKNOWN_RATE);
+ } else {
+ return (attr_p->attr.t38ratemgmt);
+ }
+}
+
+/* Function: sdp_attr_get_t38udpec
+ * Description: Returns the value of the t38udpec attribute
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, SDP_T38_UDPEC_UNKNOWN is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: UDP EC value.
+ */
+sdp_t38_udpec_e sdp_attr_get_t38udpec (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_T38_UDPEC, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s t38udpec attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_T38_UDPEC_UNKNOWN);
+ } else {
+ return (attr_p->attr.t38udpec);
+ }
+}
+
+/* Function: sdp_get_media_direction
+ * Description: Determines the direction defined for a given level. The
+ * direction will be inactive, sendonly, recvonly, or sendrecv
+ * as determined by the last of these attributes specified at
+ * the given level. If none of these attributes are specified,
+ * the direction will be sendrecv by default.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * Returns: An SDP direction enum value.
+ */
+sdp_direction_e sdp_get_media_direction (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num)
+{
+ sdp_mca_t *mca_p;
+ sdp_attr_t *attr_p;
+ sdp_direction_e direction = SDP_DIRECTION_SENDRECV;
+
+ if (cap_num == 0) {
+ /* Find the pointer to the attr list for this level. */
+ if (level == SDP_SESSION_LEVEL) {
+ attr_p = sdp_p->sess_attrs_p;
+ } else { /* Attr is at a media level */
+ mca_p = sdp_find_media_level(sdp_p, level);
+ if (mca_p == NULL) {
+ return (direction);
+ }
+ attr_p = mca_p->media_attrs_p;
+ }
+
+ /* Scan for direction oriented attributes. Last one wins. */
+ for (; attr_p != NULL; attr_p = attr_p->next_p) {
+ if (attr_p->type == SDP_ATTR_INACTIVE) {
+ direction = SDP_DIRECTION_INACTIVE;
+ } else if (attr_p->type == SDP_ATTR_SENDONLY) {
+ direction = SDP_DIRECTION_SENDONLY;
+ } else if (attr_p->type == SDP_ATTR_RECVONLY) {
+ direction = SDP_DIRECTION_RECVONLY;
+ } else if (attr_p->type == SDP_ATTR_SENDRECV) {
+ direction = SDP_DIRECTION_SENDRECV;
+ }
+ }
+ } else {
+ if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) {
+ SDPLogDebug(logTag, "%s Warning: Invalid cap_num for media direction.",
+ sdp_p->debug_str);
+ }
+ }
+
+ return (direction);
+}
+
+/* Since there are four different attribute names which all have the same
+ * qos parameters, all of these attributes are accessed through this same
+ * set of APIs. To distinguish between specific attributes, the application
+ * must also pass the attribute type. The attribute must be one of:
+ * SDP_ATTR_QOS, SDP_ATTR_SECURE, SDP_ATTR_X_PC_QOS, and SDP_ATTR_X_QOS.
+ */
+tinybool sdp_validate_qos_attr (sdp_attr_e qos_attr)
+{
+ if ((qos_attr == SDP_ATTR_QOS) ||
+ (qos_attr == SDP_ATTR_SECURE) ||
+ (qos_attr == SDP_ATTR_X_PC_QOS) ||
+ (qos_attr == SDP_ATTR_X_QOS) ||
+ (qos_attr == SDP_ATTR_CURR) ||
+ (qos_attr == SDP_ATTR_DES) ||
+ (qos_attr == SDP_ATTR_CONF)){
+ return (TRUE);
+ } else {
+ return (FALSE);
+ }
+}
+
+/* Function: sdp_attr_get_qos_strength
+ * Description: Returns the value of the qos attribute strength
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, SDP_QOS_STRENGTH_UNKNOWN is
+ * returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * qos_attr The specific type of qos attribute. May be
+ * qos, secure, X-pc-qos, or X-qos.
+ * inst_num The attribute instance number to check.
+ * Returns: Qos strength value.
+ */
+sdp_qos_strength_e sdp_attr_get_qos_strength (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ if (sdp_validate_qos_attr(qos_attr) == FALSE) {
+ if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) {
+ SDPLogDebug(logTag, "%s Warning: Invalid QOS attribute specified for"
+ "get qos strength.", sdp_p->debug_str);
+ }
+ return (SDP_QOS_STRENGTH_UNKNOWN);
+ }
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s %s attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str,
+ sdp_get_attr_name(qos_attr), (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_QOS_STRENGTH_UNKNOWN);
+ } else {
+ switch (qos_attr) {
+ case SDP_ATTR_QOS:
+ return (attr_p->attr.qos.strength);
+ case SDP_ATTR_DES:
+ return (attr_p->attr.des.strength);
+ default:
+ return SDP_QOS_STRENGTH_UNKNOWN;
+
+ }
+ }
+}
+
+/* Function: sdp_attr_get_qos_direction
+ * Description: Returns the value of the qos attribute direction
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, SDP_QOS_DIR_UNKNOWN is
+ * returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * qos_attr The specific type of qos attribute. May be
+ * qos, secure, X-pc-qos, or X-qos.
+ * inst_num The attribute instance number to check.
+ * Returns: Qos direction value.
+ */
+sdp_qos_dir_e sdp_attr_get_qos_direction (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ if (sdp_validate_qos_attr(qos_attr) == FALSE) {
+ if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) {
+ SDPLogDebug(logTag, "%s Warning: Invalid QOS attribute specified "
+ "for get qos direction.", sdp_p->debug_str);
+ }
+ return (SDP_QOS_DIR_UNKNOWN);
+ }
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s %s attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str,
+ sdp_get_attr_name(qos_attr), (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_QOS_DIR_UNKNOWN);
+ } else {
+ switch (qos_attr) {
+ case SDP_ATTR_QOS:
+ return (attr_p->attr.qos.direction);
+ case SDP_ATTR_CURR:
+ return (attr_p->attr.curr.direction);
+ case SDP_ATTR_DES:
+ return (attr_p->attr.des.direction);
+ case SDP_ATTR_CONF:
+ return (attr_p->attr.conf.direction);
+ default:
+ return SDP_QOS_DIR_UNKNOWN;
+
+ }
+ }
+}
+
+/* Function: sdp_attr_get_qos_status_type
+ * Description: Returns the value of the qos attribute status_type
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, SDP_QOS_STATUS_TYPE_UNKNOWN is
+ * returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * qos_attr The specific type of qos attribute. May be
+ * qos, secure, X-pc-qos, or X-qos.
+ * inst_num The attribute instance number to check.
+ * Returns: Qos direction value.
+ */
+sdp_qos_status_types_e sdp_attr_get_qos_status_type (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ if (sdp_validate_qos_attr(qos_attr) == FALSE) {
+ if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) {
+ SDPLogDebug(logTag, "%s Warning: Invalid QOS attribute specified "
+ "for get qos status_type.", sdp_p->debug_str);
+ }
+ return (SDP_QOS_STATUS_TYPE_UNKNOWN);
+ }
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s %s attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str,
+ sdp_get_attr_name(qos_attr), (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_QOS_STATUS_TYPE_UNKNOWN);
+ } else {
+ switch (qos_attr) {
+ case SDP_ATTR_CURR:
+ return (attr_p->attr.curr.status_type);
+ case SDP_ATTR_DES:
+ return (attr_p->attr.des.status_type);
+ case SDP_ATTR_CONF:
+ return (attr_p->attr.conf.status_type);
+ default:
+ return SDP_QOS_STATUS_TYPE_UNKNOWN;
+
+ }
+ }
+}
+
+/* Function: sdp_attr_get_qos_confirm
+ * Description: Returns the value of the qos attribute confirm
+ * parameter specified for the given attribute. Returns TRUE if
+ * the confirm parameter is specified.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * qos_attr The specific type of qos attribute. May be
+ * qos, secure, X-pc-qos, or X-qos.
+ * inst_num The attribute instance number to check.
+ * Returns: Boolean value.
+ */
+tinybool sdp_attr_get_qos_confirm (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ if (sdp_validate_qos_attr(qos_attr) == FALSE) {
+ if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) {
+ SDPLogDebug(logTag, "%s Warning: Invalid QOS attribute specified "
+ "for get qos confirm.", sdp_p->debug_str);
+ }
+ return (FALSE);
+ }
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s %s attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str,
+ sdp_get_attr_name(qos_attr), (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (FALSE);
+ } else {
+ return (attr_p->attr.qos.confirm);
+ }
+}
+
+/* Function: sdp_attr_get_curr_type
+ * Description: Returns the value of the curr attribute status_type
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, SDP_CURR_UNKNOWN_TYPE is
+ * returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * qos_attr The specific type of qos attribute. May be
+ * qos, secure, X-pc-qos, or X-qos.
+ * inst_num The attribute instance number to check.
+ * Returns: Curr type value.
+ */
+sdp_curr_type_e sdp_attr_get_curr_type (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s %s attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str,
+ sdp_get_attr_name(qos_attr), (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_CURR_UNKNOWN_TYPE);
+ } else {
+ return (attr_p->attr.curr.type);
+ }
+}
+
+/* Function: sdp_attr_get_des_type
+ * Description: Returns the value of the des attribute status_type
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, SDP_DES_UNKNOWN_TYPE is
+ * returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * qos_attr The specific type of qos attribute. May be
+ * qos, secure, X-pc-qos, or X-qos.
+ * inst_num The attribute instance number to check.
+ * Returns: DES type value.
+ */
+sdp_des_type_e sdp_attr_get_des_type (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s %s attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str,
+ sdp_get_attr_name(qos_attr), (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_DES_UNKNOWN_TYPE);
+ } else {
+ return (attr_p->attr.des.type);
+ }
+}
+
+/* Function: sdp_attr_get_conf_type
+ * Description: Returns the value of the des attribute status_type
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, SDP_CONF_UNKNOWN_TYPE is
+ * returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * qos_attr The specific type of qos attribute. May be
+ * qos, secure, X-pc-qos, or X-qos.
+ * inst_num The attribute instance number to check.
+ * Returns: CONF type value.
+ */
+sdp_conf_type_e sdp_attr_get_conf_type (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s %s attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str,
+ sdp_get_attr_name(qos_attr), (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_CONF_UNKNOWN_TYPE);
+ } else {
+ return (attr_p->attr.conf.type);
+ }
+}
+
+/* Function: sdp_attr_get_subnet_nettype
+ * Description: Returns the value of the subnet attribute network type
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, SDP_NT_INVALID is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Nettype value.
+ */
+sdp_nettype_e sdp_attr_get_subnet_nettype (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SUBNET, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Subnet attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_NT_INVALID);
+ } else {
+ return (attr_p->attr.subnet.nettype);
+ }
+}
+
+/* Function: sdp_attr_get_subnet_addrtype
+ * Description: Returns the value of the subnet attribute address type
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, SDP_AT_INVALID is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Addrtype value.
+ */
+sdp_addrtype_e sdp_attr_get_subnet_addrtype (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SUBNET, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Subnet attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_AT_INVALID);
+ } else {
+ return (attr_p->attr.subnet.addrtype);
+ }
+}
+
+/* Function: sdp_attr_get_subnet_addr
+ * Description: Returns the value of the subnet attribute address
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, NULL is returned. 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 attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Pointer to address or NULL.
+ */
+const char *sdp_attr_get_subnet_addr (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SUBNET, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Subnet attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (NULL);
+ } else {
+ return (attr_p->attr.subnet.addr);
+ }
+}
+
+/* Function: sdp_attr_get_subnet_prefix
+ * Description: Returns the value of the subnet attribute prefix
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, SDP_INVALID_PARAM is returned.
+ * Note that this is value is defined to be (-2) and is
+ * different from the return code SDP_INVALID_PARAMETER.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Prefix value or SDP_INVALID_PARAM.
+ */
+int32_t sdp_attr_get_subnet_prefix (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SUBNET, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Subnet attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.subnet.prefix);
+ }
+}
+
+/* Function: sdp_attr_rtpmap_payload_valid
+ * Description: Returns true or false depending on whether an rtpmap
+ * attribute was specified with the given payload value
+ * at the given level. If it was, the instance number of
+ * that attribute is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number of the attribute
+ * found is returned via this param.
+ * Returns: TRUE or FALSE.
+ */
+tinybool sdp_attr_rtpmap_payload_valid (sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ uint16_t *inst_num, uint16_t payload_type)
+{
+ uint16_t i;
+ sdp_attr_t *attr_p;
+ uint16_t num_instances;
+
+ *inst_num = 0;
+
+ if (sdp_attr_num_instances(sdp_p, level, cap_num,
+ SDP_ATTR_RTPMAP, &num_instances) != SDP_SUCCESS) {
+ return (FALSE);
+ }
+
+ for (i=1; i <= num_instances; i++) {
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTPMAP, i);
+ if ((attr_p != NULL) &&
+ (attr_p->attr.transport_map.payload_num == payload_type)) {
+ *inst_num = i;
+ return (TRUE);
+ }
+ }
+
+ return (FALSE);
+}
+
+/* Function: sdp_attr_get_rtpmap_payload_type
+ * Description: Returns the value of the rtpmap attribute payload type
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, zero is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Payload type value.
+ */
+uint16_t sdp_attr_get_rtpmap_payload_type (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTPMAP, inst_num);
+ 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)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ return (attr_p->attr.transport_map.payload_num);
+ }
+}
+
+/* Function: sdp_attr_get_rtpmap_encname
+ * Description: Returns a pointer to the value of the encoding name
+ * parameter specified for the given attribute. Value is
+ * returned as a const ptr and so cannot be modified by the
+ * application. If the given attribute is not defined, NULL
+ * will be returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Codec value or SDP_CODEC_INVALID.
+ */
+const char *sdp_attr_get_rtpmap_encname (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTPMAP, inst_num);
+ 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)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (NULL);
+ } else {
+ return (attr_p->attr.transport_map.encname);
+ }
+}
+
+/* Function: sdp_attr_get_rtpmap_clockrate
+ * Description: Returns the value of the rtpmap attribute clockrate
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, zero is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Clockrate value.
+ */
+uint32_t sdp_attr_get_rtpmap_clockrate (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTPMAP, inst_num);
+ 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)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ return (attr_p->attr.transport_map.clockrate);
+ }
+}
+
+/* Function: sdp_attr_get_rtpmap_num_chan
+ * Description: Returns the value of the rtpmap attribute num_chan
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, zero is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Number of channels param or zero.
+ */
+uint16_t sdp_attr_get_rtpmap_num_chan (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTPMAP, inst_num);
+ 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)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ return (attr_p->attr.transport_map.num_chan);
+ }
+}
+
+/* Function: sdp_attr_get_ice_attribute
+ * Description: Returns the value of an ice attribute at a given level
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * ice_attrib Returns an ice attrib string
+ * Returns:
+ * SDP_SUCCESS Attribute param was set successfully.
+ * SDP_INVALID_SDP_PTR SDP pointer invalid
+ * SDP_INVALID_PARAMETER Specified attribute is not defined.
+ */
+
+sdp_result_e sdp_attr_get_ice_attribute (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, sdp_attr_e sdp_attr, uint16_t inst_num,
+ char **out)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, sdp_attr, inst_num);
+ if (attr_p != NULL) {
+ *out = attr_p->attr.ice_attr;
+ return (SDP_SUCCESS);
+ } else {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s ice attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+}
+
+/* Function: sdp_attr_is_present
+ * Description: Returns a boolean value based on attribute being present or
+ * not
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * attr_type The attribute type.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * Returns:
+ * Boolean value.
+ */
+
+tinybool sdp_attr_is_present (sdp_t *sdp_p, sdp_attr_e attr_type, uint16_t level,
+ uint8_t cap_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, attr_type, 1);
+ if (attr_p != NULL) {
+ return (TRUE);
+ }
+ if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) {
+ SDPLogDebug(logTag, "%s Attribute %s, level %u not found.",
+ sdp_p->debug_str, sdp_get_attr_name(attr_type), level);
+ }
+
+ return (FALSE);
+}
+
+
+
+/* Function: sdp_attr_get_rtcp_mux_attribute
+ * Description: Returns the value of an rtcp-mux attribute at a given level
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * rtcp_mux Returns an rtcp-mux attrib bool
+ * Returns:
+ * SDP_SUCCESS Attribute param was set successfully.
+ * SDP_INVALID_SDP_PTR SDP pointer invalid
+ * SDP_INVALID_PARAMETER Specified attribute is not defined.
+ */
+sdp_result_e sdp_attr_get_rtcp_mux_attribute (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, sdp_attr_e sdp_attr, uint16_t inst_num,
+ tinybool *rtcp_mux)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, sdp_attr, inst_num);
+ if (attr_p != NULL) {
+ *rtcp_mux = attr_p->attr.boolean_val;
+ return (SDP_SUCCESS);
+ } else {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s rtcp-mux attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+}
+
+/* Function: sdp_attr_get_setup_attribute
+ * Description: Returns the value of a setup attribute at a given level
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * setup_type Returns sdp_setup_type_e enum
+ * Returns:
+ * SDP_SUCCESS Attribute param was set successfully.
+ * SDP_INVALID_SDP_PTR SDP pointer invalid
+ * SDP_INVALID_PARAMETER Specified attribute is not defined.
+ */
+sdp_result_e sdp_attr_get_setup_attribute (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, sdp_setup_type_e *setup_type)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SETUP, inst_num);
+ if (!attr_p) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag,
+ "%s setup attribute, level %u instance %u not found.",
+ sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return SDP_INVALID_PARAMETER;
+ }
+
+ *setup_type = attr_p->attr.setup;
+ return SDP_SUCCESS;
+}
+
+/* Function: sdp_attr_get_connection_attribute
+ * Description: Returns the value of a connection attribute at a given level
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * connection_type Returns sdp_connection_type_e enum
+ * Returns:
+ * SDP_SUCCESS Attribute param was set successfully.
+ * SDP_INVALID_SDP_PTR SDP pointer invalid
+ * SDP_INVALID_PARAMETER Specified attribute is not defined.
+ */
+sdp_result_e sdp_attr_get_connection_attribute (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, sdp_connection_type_e *connection_type)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_CONNECTION,
+ inst_num);
+ if (!attr_p) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag,
+ "%s setup attribute, level %u instance %u not found.",
+ sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return SDP_INVALID_PARAMETER;
+ }
+
+ *connection_type = attr_p->attr.connection;
+ return SDP_SUCCESS;
+}
+
+/* Function: sdp_attr_get_dtls_fingerprint_attribute
+ * Description: Returns the value of dtls fingerprint attribute at a given level
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * dtls_fingerprint Returns an dtls fingerprint attrib string
+ * Returns:
+ * SDP_SUCCESS Attribute param was set successfully.
+ * SDP_INVALID_SDP_PTR SDP pointer invalid
+ * SDP_INVALID_PARAMETER Specified attribute is not defined.
+ */
+sdp_result_e sdp_attr_get_dtls_fingerprint_attribute (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, sdp_attr_e sdp_attr, uint16_t inst_num,
+ char **out)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, sdp_attr, inst_num);
+ if (attr_p != NULL) {
+ *out = attr_p->attr.string_val;
+ return (SDP_SUCCESS);
+ } else {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s dtls fingerprint attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+}
+
+/* Function: sdp_attr_sprtmap_payload_valid
+ * Description: Returns true or false depending on whether an sprtmap
+ * attribute was specified with the given payload value
+ * at the given level. If it was, the instance number of
+ * that attribute is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number of the attribute
+ * found is returned via this param.
+ * Returns: TRUE or FALSE.
+ */
+tinybool sdp_attr_sprtmap_payload_valid (sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ uint16_t *inst_num, uint16_t payload_type)
+{
+ uint16_t i;
+ sdp_attr_t *attr_p;
+ uint16_t num_instances;
+
+ *inst_num = 0;
+
+ if (sdp_attr_num_instances(sdp_p, level, cap_num,
+ SDP_ATTR_SPRTMAP, &num_instances) != SDP_SUCCESS) {
+ return (FALSE);
+ }
+
+ for (i=1; i <= num_instances; i++) {
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SPRTMAP, i);
+ if ((attr_p != NULL) &&
+ (attr_p->attr.transport_map.payload_num == payload_type)) {
+ *inst_num = i;
+ return (TRUE);
+ }
+ }
+
+ return (FALSE);
+}
+
+/* Function: sdp_attr_get_sprtmap_payload_type
+ * Description: Returns the value of the sprtmap attribute payload type
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, zero is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Payload type value.
+ */
+uint16_t sdp_attr_get_sprtmap_payload_type (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SPRTMAP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s sprtmap attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ return (attr_p->attr.transport_map.payload_num);
+ }
+}
+
+/* Function: sdp_attr_get_sprtmap_encname
+ * Description: Returns a pointer to the value of the encoding name
+ * parameter specified for the given attribute. Value is
+ * returned as a const ptr and so cannot be modified by the
+ * application. If the given attribute is not defined, NULL
+ * will be returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Codec value or SDP_CODEC_INVALID.
+ */
+const char *sdp_attr_get_sprtmap_encname (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SPRTMAP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s sprtmap attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (NULL);
+ } else {
+ return (attr_p->attr.transport_map.encname);
+ }
+}
+
+/* Function: sdp_attr_get_sprtmap_clockrate
+ * Description: Returns the value of the sprtmap attribute clockrate
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, zero is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Clockrate value.
+ */
+uint32_t sdp_attr_get_sprtmap_clockrate (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SPRTMAP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s sprtmap attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ return (attr_p->attr.transport_map.clockrate);
+ }
+}
+
+/* Function: sdp_attr_get_sprtmap_num_chan
+ * Description: Returns the value of the sprtmap attribute num_chan
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, zero is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Number of channels param or zero.
+ */
+uint16_t sdp_attr_get_sprtmap_num_chan (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SPRTMAP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s sprtmap attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ return (attr_p->attr.transport_map.num_chan);
+ }
+}
+
+/* Note: The fmtp attribute formats currently handled are:
+ * fmtp:<payload type> <event>,<event>...
+ * fmtp:<payload_type> [annexa=yes/no] [annexb=yes/no] [bitrate=<value>]
+ * where "value" is a numeric value > 0
+ * where each event is a single number or a range separated
+ * by a '-'.
+ * Example: fmtp:101 1,3-15,20
+ */
+
+/* Function: tinybool sdp_attr_fmtp_valid(sdp_t *sdp_p)
+ * Description: Returns true or false depending on whether an fmtp
+ * attribute was specified with the given payload value
+ * at the given level. If it was, the instance number of
+ * that attribute is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: TRUE or FALSE.
+ */
+tinybool sdp_attr_fmtp_payload_valid (sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ uint16_t *inst_num, uint16_t payload_type)
+{
+ uint16_t i;
+ sdp_attr_t *attr_p;
+ uint16_t num_instances;
+
+ if (sdp_attr_num_instances(sdp_p, level, cap_num,
+ SDP_ATTR_FMTP, &num_instances) != SDP_SUCCESS) {
+ return (FALSE);
+ }
+
+ for (i=1; i <= num_instances; i++) {
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, i);
+ if ((attr_p != NULL) &&
+ (attr_p->attr.fmtp.payload_num == payload_type)) {
+ *inst_num = i;
+ return (TRUE);
+ }
+ }
+
+ return (FALSE);
+}
+
+/* Function: sdp_attr_get_fmtp_payload_type
+ * Description: Returns the value of the fmtp attribute payload type
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, zero is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Payload type value.
+ */
+uint16_t sdp_attr_get_fmtp_payload_type (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ return (attr_p->attr.fmtp.payload_num);
+ }
+}
+
+
+/* Function: sdp_attr_fmtp_is_range_set
+ * Description: Determines if a range of events is set in an fmtp attribute.
+ * The overall range for events is 0-255.
+ * This will return either FULL_MATCH, PARTIAL_MATCH, or NO_MATCH
+ * depending on whether all, some, or none of the specified
+ * events are defined. If the given attribute is not defined,
+ * NO_MATCH will be returned. It is up to the appl to verify
+ * the validity of the attribute before calling this routine.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * low_val Low value of the range. Range is 0-255.
+ * high_val High value of the range.
+ * Returns: SDP_FULL_MATCH, SDP_PARTIAL_MATCH, SDP_NO_MATCH
+ */
+sdp_ne_res_e sdp_attr_fmtp_is_range_set (sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ uint16_t inst_num, uint8_t low_val, uint8_t high_val)
+{
+ uint16_t i;
+ uint32_t mapword;
+ uint32_t bmap;
+ uint32_t num_vals = 0;
+ uint32_t num_vals_set = 0;
+ sdp_attr_t *attr_p;
+ sdp_fmtp_t *fmtp_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_NO_MATCH);
+ }
+
+ fmtp_p = &(attr_p->attr.fmtp);
+ for (i = low_val; i <= high_val; i++) {
+ num_vals++;
+ mapword = i/SDP_NE_BITS_PER_WORD;
+ bmap = SDP_NE_BIT_0 << (i%32);
+ if (fmtp_p->bmap[ mapword ] & bmap) {
+ num_vals_set++;
+ }
+ }
+
+ if (num_vals == num_vals_set) {
+ return (SDP_FULL_MATCH);
+ } else if (num_vals_set == 0) {
+ return (SDP_NO_MATCH);
+ } else {
+ return (SDP_PARTIAL_MATCH);
+ }
+}
+
+/* Function: sdp_attr_fmtp_valid
+ * Description: Determines the validity of the events in the fmtp.
+ * The overall range for events is 0-255.
+ * The user passes an event list with valid events supported by Appl.
+ * This routine will do a simple AND comparison and report the result.
+ *
+ * This will return TRUE if ftmp events are valid, and FALSE otherwise.
+ * It is up to the appl to verify the validity of the attribute
+ * before calling this routine.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * appl_maxval Max event value supported by Appl. Range is 0-255.
+ * evt_array Bitmap containing events supported by application.
+ * Returns: TRUE, FALSE
+ */
+tinybool
+sdp_attr_fmtp_valid(sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ uint16_t inst_num, uint16_t appl_maxval, uint32_t* evt_array)
+{
+ uint16_t i;
+ uint32_t mapword;
+ sdp_attr_t *attr_p;
+ sdp_fmtp_t *fmtp_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return FALSE;
+ }
+
+ fmtp_p = &(attr_p->attr.fmtp);
+
+ /* Do quick test. If application max value is lower than fmtp's then error */
+ if (fmtp_p->maxval > appl_maxval)
+ return FALSE;
+
+ /* Ok, events are within range. Now check that only
+ * allowed events have been received
+ */
+ mapword = appl_maxval/SDP_NE_BITS_PER_WORD;
+ for (i=0; i<mapword; i++) {
+ if (fmtp_p->bmap[i] & ~(evt_array[i])) {
+ /* Remote SDP is requesting events not supported by Application */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Function: sdp_attr_set_fmtp_payload_type
+ * Description: Sets the value of the fmtp attribute payload type parameter
+ * for the given attribute.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * payload_type New payload type value.
+ * Returns: SDP_SUCCESS Attribute param was set successfully.
+ * SDP_INVALID_PARAMETER Specified attribute is not defined.
+ */
+sdp_result_e sdp_attr_set_fmtp_payload_type (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num,
+ uint16_t payload_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ attr_p->attr.fmtp.payload_num = payload_num;
+ return (SDP_SUCCESS);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_range
+ * Description: Get a range of named events for an fmtp attribute.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * bmap The 8 word data array holding the bitmap
+ * Returns: SDP_SUCCESS
+ */
+sdp_result_e sdp_attr_get_fmtp_range (sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ uint16_t inst_num, uint32_t *bmap)
+{
+ sdp_attr_t *attr_p;
+ sdp_fmtp_t *fmtp_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+
+ fmtp_p = &(attr_p->attr.fmtp);
+ memcpy(bmap, fmtp_p->bmap, SDP_NE_NUM_BMAP_WORDS * sizeof(uint32_t) );
+
+ return (SDP_SUCCESS);
+}
+
+/* Function: sdp_attr_clear_fmtp_range
+ * Description: Clear a range of named events for an fmtp attribute. The low
+ * value specified must be <= the high value.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * low_val The low value of the range. Range is 0-255
+ * high_val The high value of the range. May be == low.
+ * Returns: SDP_SUCCESS
+ */
+sdp_result_e sdp_attr_clear_fmtp_range (sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ uint16_t inst_num, uint8_t low_val, uint8_t high_val)
+{
+ uint16_t i;
+ uint32_t mapword;
+ uint32_t bmap;
+ sdp_attr_t *attr_p;
+ sdp_fmtp_t *fmtp_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+
+ fmtp_p = &(attr_p->attr.fmtp);
+ for (i = low_val; i <= high_val; i++) {
+ mapword = i/SDP_NE_BITS_PER_WORD;
+ bmap = SDP_NE_BIT_0 << (i%32);
+ fmtp_p->bmap[ mapword ] &= ~bmap;
+ }
+ if (high_val > fmtp_p->maxval) {
+ fmtp_p->maxval = high_val;
+ }
+ return (SDP_SUCCESS);
+}
+
+/* Function: sdp_attr_compare_fmtp_ranges
+ * Description: Compare the named events set of two fmtp attributes. If all
+ * events are the same (either set or not), FULL_MATCH will be
+ * returned. If no events match, NO_MATCH will be returned.
+ * Otherwise PARTIAL_MATCH will be returned. If either attr is
+ * invalid, NO_MATCH will be returned.
+ * Parameters: src_sdp_p The SDP handle returned by sdp_init_description.
+ * dst_sdp_p The SDP handle returned by sdp_init_description.
+ * src_level The level of the src fmtp attribute.
+ * dst_level The level to the dst fmtp attribute.
+ * src_cap_num The capability number of the src attr.
+ * dst_cap_num The capability number of the dst attr.
+ * src_inst_numh The attribute instance of the src attr.
+ * dst_inst_numh The attribute instance of the dst attr.
+ * Returns: SDP_FULL_MATCH, SDP_PARTIAL_MATCH, SDP_NO_MATCH.
+ */
+sdp_ne_res_e sdp_attr_compare_fmtp_ranges (sdp_t *src_sdp_p,sdp_t *dst_sdp_p,
+ uint16_t src_level, uint16_t dst_level,
+ uint8_t src_cap_num, uint8_t dst_cap_num,
+ uint16_t src_inst_num, uint16_t dst_inst_num)
+{
+ uint16_t i,j;
+ uint32_t bmap;
+ uint32_t num_vals_match = 0;
+ sdp_attr_t *src_attr_p;
+ sdp_attr_t *dst_attr_p;
+ sdp_fmtp_t *src_fmtp_p;
+ sdp_fmtp_t *dst_fmtp_p;
+
+ src_attr_p = sdp_find_attr(src_sdp_p, src_level, src_cap_num,
+ SDP_ATTR_FMTP, src_inst_num);
+ dst_attr_p = sdp_find_attr(dst_sdp_p, dst_level, dst_cap_num,
+ SDP_ATTR_FMTP, dst_inst_num);
+ if ((src_attr_p == NULL) || (dst_attr_p == NULL)) {
+ if (src_sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s source or destination fmtp attribute for "
+ "compare not found.", src_sdp_p->debug_str);
+ }
+ src_sdp_p->conf_p->num_invalid_param++;
+ return (SDP_NO_MATCH);
+ }
+
+ src_fmtp_p = &(src_attr_p->attr.fmtp);
+ dst_fmtp_p = &(dst_attr_p->attr.fmtp);
+ for (i = 0; i < SDP_NE_NUM_BMAP_WORDS; i++) {
+ for (j = 0; j < SDP_NE_BITS_PER_WORD; j++) {
+ bmap = SDP_NE_BIT_0 << j;
+ if ((src_fmtp_p->bmap[i] & bmap) && (dst_fmtp_p->bmap[i] & bmap)) {
+ num_vals_match++;
+ } else if ((!(src_fmtp_p->bmap[i] & bmap)) &&
+ (!(dst_fmtp_p->bmap[i] & bmap))) {
+ num_vals_match++;
+ }
+ }
+ }
+
+ if (num_vals_match == (SDP_NE_NUM_BMAP_WORDS * SDP_NE_BITS_PER_WORD)) {
+ return (SDP_FULL_MATCH);
+ } else if (num_vals_match == 0) {
+ return (SDP_NO_MATCH);
+ } else {
+ return (SDP_PARTIAL_MATCH);
+ }
+}
+
+/* Function: sdp_attr_copy_fmtp_ranges
+ * Description: Copy the named events set for one fmtp attribute to another.
+ * Parameters: src_sdp_p The SDP handle returned by sdp_init_description.
+ * dst_sdp_p The SDP handle returned by sdp_init_description.
+ * src_level The level of the src fmtp attribute.
+ * dst_level The level to the dst fmtp attribute.
+ * src_cap_num The capability number of the src attr.
+ * dst_cap_num The capability number of the dst attr.
+ * src_inst_numh The attribute instance of the src attr.
+ * dst_inst_numh The attribute instance of the dst attr.
+ * Returns: SDP_SUCCESS
+ */
+sdp_result_e sdp_attr_copy_fmtp_ranges (sdp_t *src_sdp_p, sdp_t *dst_sdp_p,
+ uint16_t src_level, uint16_t dst_level,
+ uint8_t src_cap_num, uint8_t dst_cap_num,
+ uint16_t src_inst_num, uint16_t dst_inst_num)
+{
+ uint16_t i;
+ sdp_attr_t *src_attr_p;
+ sdp_attr_t *dst_attr_p;
+ sdp_fmtp_t *src_fmtp_p;
+ sdp_fmtp_t *dst_fmtp_p;
+
+ if (!src_sdp_p || !dst_sdp_p) {
+ return (SDP_INVALID_SDP_PTR);
+ }
+
+ src_attr_p = sdp_find_attr(src_sdp_p, src_level, src_cap_num,
+ SDP_ATTR_FMTP, src_inst_num);
+ dst_attr_p = sdp_find_attr(dst_sdp_p, dst_level, dst_cap_num,
+ SDP_ATTR_FMTP, dst_inst_num);
+ if ((src_attr_p == NULL) || (dst_attr_p == NULL)) {
+ if (src_sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s source or destination fmtp attribute for "
+ "copy not found.", src_sdp_p->debug_str);
+ }
+ src_sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+
+ src_fmtp_p = &(src_attr_p->attr.fmtp);
+ dst_fmtp_p = &(dst_attr_p->attr.fmtp);
+ dst_fmtp_p->maxval = src_fmtp_p->maxval;
+ for (i = 0; i < SDP_NE_NUM_BMAP_WORDS; i++) {
+ dst_fmtp_p->bmap[i] = src_fmtp_p->bmap[i];
+ }
+ return (SDP_SUCCESS);
+}
+
+/* Function: sdp_attr_get_fmtp_mode
+ * Description: Gets the value of the fmtp attribute mode parameter
+ * for the given attribute.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * payload_type payload type.
+ * Returns: mode value or zero if mode attribute not found
+ */
+uint32_t sdp_attr_get_fmtp_mode_for_payload_type (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint32_t payload_type)
+{
+ uint16_t num_a_lines = 0;
+ int i;
+ sdp_attr_t *attr_p;
+
+ /*
+ * Get number of FMTP attributes for the AUDIO line
+ */
+ (void) sdp_attr_num_instances(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ &num_a_lines);
+ for (i = 0; i < num_a_lines; i++) {
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, (uint16_t) (i + 1));
+ if ((attr_p != NULL) &&
+ (attr_p->attr.fmtp.payload_num == (uint16_t)payload_type)) {
+ if (attr_p->attr.fmtp.fmtp_format == SDP_FMTP_MODE) {
+ return attr_p->attr.fmtp.mode;
+ }
+ }
+ }
+ return 0;
+}
+
+sdp_result_e sdp_attr_set_fmtp_max_fs (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num,
+ uint32_t max_fs)
+{
+ sdp_attr_t *attr_p;
+ sdp_fmtp_t *fmtp_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+
+ fmtp_p = &(attr_p->attr.fmtp);
+ fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO;
+
+ if (max_fs > 0) {
+ fmtp_p->max_fs = max_fs;
+ return (SDP_SUCCESS);
+ } else {
+ return (SDP_FAILURE);
+ }
+}
+
+sdp_result_e sdp_attr_set_fmtp_max_fr (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num,
+ uint32_t max_fr)
+{
+ sdp_attr_t *attr_p;
+ sdp_fmtp_t *fmtp_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+
+ fmtp_p = &(attr_p->attr.fmtp);
+ fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO;
+
+ if (max_fr > 0) {
+ fmtp_p->max_fr = max_fr;
+ return (SDP_SUCCESS);
+ } else {
+ return (SDP_FAILURE);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_max_average_bitrate
+ * Description: Gets the value of the fmtp attribute- maxaveragebitrate parameter for the OPUS codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: max-br value.
+ */
+
+sdp_result_e sdp_attr_get_fmtp_max_average_bitrate (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, uint32_t* val)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, 1);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ *val = attr_p->attr.fmtp.maxaveragebitrate;
+ return (SDP_SUCCESS);
+ }
+}
+
+
+/* Function: sdp_attr_get_fmtp_usedtx
+ * Description: Gets the value of the fmtp attribute- usedtx parameter for the OPUS codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: usedtx value.
+ */
+
+sdp_result_e sdp_attr_get_fmtp_usedtx (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, tinybool* val)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ *val = (tinybool)attr_p->attr.fmtp.usedtx;
+ return (SDP_SUCCESS);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_usedtx
+ * Description: Gets the value of the fmtp attribute- usedtx parameter for the OPUS codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: stereo value.
+ */
+
+sdp_result_e sdp_attr_get_fmtp_stereo (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, tinybool* val)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ *val = (tinybool)attr_p->attr.fmtp.stereo;
+ return (SDP_SUCCESS);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_useinbandfec
+ * Description: Gets the value of the fmtp attribute useinbandfec parameter for the OPUS codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: useinbandfec value.
+ */
+
+sdp_result_e sdp_attr_get_fmtp_useinbandfec (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, tinybool* val)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ *val = (tinybool)attr_p->attr.fmtp.useinbandfec;
+ return (SDP_SUCCESS);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_maxcodedaudiobandwidth
+ * Description: Gets the value of the fmtp attribute maxcodedaudiobandwidth parameter for OPUS codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: maxcodedaudiobandwidth value.
+ */
+char* sdp_attr_get_fmtp_maxcodedaudiobandwidth (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ return (attr_p->attr.fmtp.maxcodedaudiobandwidth);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_cbr
+ * Description: Gets the value of the fmtp attribute cbr parameter for the OPUS codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: cbr value.
+ */
+
+sdp_result_e sdp_attr_get_fmtp_cbr (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, tinybool* val)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ *val = (tinybool)attr_p->attr.fmtp.cbr;
+ return (SDP_SUCCESS);
+ }
+}
+
+uint16_t sdp_attr_get_sctpmap_port(sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SCTPMAP, inst_num);
+ if (!attr_p) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s sctpmap port, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return 0;
+ } else {
+ return attr_p->attr.sctpmap.port;
+ }
+}
+
+sdp_result_e sdp_attr_get_sctpmap_streams (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, uint32_t* val)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SCTPMAP, inst_num);
+ if (!attr_p) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s sctpmap streams, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ *val = attr_p->attr.sctpmap.streams;
+ return (SDP_SUCCESS);
+ }
+}
+
+sdp_result_e sdp_attr_get_sctpmap_protocol (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num,
+ char* protocol)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SCTPMAP,
+ inst_num);
+ if (!attr_p) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s sctpmap, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ sstrncpy(protocol, attr_p->attr.sctpmap.protocol, SDP_MAX_STRING_LEN+1);
+ }
+ return (SDP_SUCCESS);
+}
+
+/* Function: sdp_attr_fmtp_is_annexb_set
+ * Description: Gives the value of the fmtp attribute annexb type parameter
+ * for the given attribute.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ *
+ *
+ * Returns: TRUE or FALSE.
+ */
+tinybool sdp_attr_fmtp_is_annexb_set (sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (FALSE);
+ } else {
+ return (attr_p->attr.fmtp.annexb);
+ }
+}
+
+/* Function: sdp_attr_fmtp_is_annexa_set
+ * Description: Gives the value of the fmtp attribute annexa type parameter
+ * for the given attribute.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ *
+ *
+ * Returns: TRUE or FALSE.
+ */
+tinybool sdp_attr_fmtp_is_annexa_set (sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (FALSE);
+ } else {
+ return (attr_p->attr.fmtp.annexa);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_bitrate_type
+ * Description: Gets the value of the fmtp attribute bitrate type parameter
+ * for the given attribute.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Bitrate type value.
+ */
+int32_t sdp_attr_get_fmtp_bitrate_type (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.bitrate);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_qcif
+ * Description: Gets the value of the fmtp attribute QCIF type parameter
+ * for a given Video codec.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: QCIF value.
+ */
+int32_t sdp_attr_get_fmtp_qcif (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.qcif);
+ }
+}
+/* Function: sdp_attr_get_fmtp_cif
+ * Description: Gets the value of the fmtp attribute CIF type parameter
+ * for a given Video codec.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: CIF value.
+ */
+int32_t sdp_attr_get_fmtp_cif (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.cif);
+ }
+}
+
+
+/* Function: sdp_attr_get_fmtp_sqcif
+ * Description: Gets the value of the fmtp attribute sqcif type parameter
+ * for a given Video codec.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: sqcif value.
+ */
+int32_t sdp_attr_get_fmtp_sqcif (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.sqcif);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_cif4
+ * Description: Gets the value of the fmtp attribute CIF4 type parameter
+ * for a given Video codec.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: CIF4 value.
+ */
+int32_t sdp_attr_get_fmtp_cif4 (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.cif4);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_cif16
+ * Description: Gets the value of the fmtp attribute CIF16 type parameter
+ * for a given Video codec.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: CIF16 value.
+ */
+
+int32_t sdp_attr_get_fmtp_cif16 (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.cif16);
+ }
+}
+
+
+/* Function: sdp_attr_get_fmtp_maxbr
+ * Description: Gets the value of the fmtp attribute MAXBR type parameter
+ * for a given Video codec.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: MAXBR value.
+ */
+int32_t sdp_attr_get_fmtp_maxbr (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.maxbr);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_custom_x
+ * Description: Gets the value of the fmtp attribute CUSTOM type parameter
+ * for a given Video codec.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: CUSTOM x value.
+ */
+
+int32_t sdp_attr_get_fmtp_custom_x (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.custom_x);
+ }
+}
+/* Function: sdp_attr_get_fmtp_custom_y
+ * Description: Gets the value of the fmtp attribute custom_y type parameter
+ * for a given Video codec.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: CUSTOM Y-AXIS value.
+ */
+
+int32_t sdp_attr_get_fmtp_custom_y (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.custom_y);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_custom_mpi
+ * Description: Gets the value of the fmtp attribute CUSTOM type parameter
+ * for a given Video codec.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: CUSTOM MPI value.
+ */
+
+int32_t sdp_attr_get_fmtp_custom_mpi (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.custom_mpi);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_par_width
+ * Description: Gets the value of the fmtp attribute PAR (width) parameter
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: PAR - width value.
+ */
+int32_t sdp_attr_get_fmtp_par_width (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.par_width);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_par_height
+ * Description: Gets the value of the fmtp attribute PAR (height) parameter
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: PAR - height value.
+ */
+int32_t sdp_attr_get_fmtp_par_height (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.par_height);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_cpcf
+ * Description: Gets the value of the fmtp attribute- CPCF parameter
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: CPCF value.
+ */
+int32_t sdp_attr_get_fmtp_cpcf (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.cpcf);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_bpp
+ * Description: Gets the value of the fmtp attribute- BPP parameter
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: BPP value.
+ */
+int32_t sdp_attr_get_fmtp_bpp (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.bpp);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_hrd
+ * Description: Gets the value of the fmtp attribute- HRD parameter
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: HRD value.
+ */
+int32_t sdp_attr_get_fmtp_hrd (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.hrd);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_profile
+ * Description: Gets the value of the fmtp attribute- PROFILE parameter
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: PROFILE value.
+ */
+int32_t sdp_attr_get_fmtp_profile (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.profile);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_level
+ * Description: Gets the value of the fmtp attribute- LEVEL parameter
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: LEVEL value.
+ */
+int32_t sdp_attr_get_fmtp_level (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.level);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_interlace
+ * Description: Checks if INTERLACE parameter is set.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: TRUE if INTERLACE is present and FALSE if INTERLACE is absent.
+ */
+tinybool sdp_attr_get_fmtp_interlace (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return FALSE;
+ } else {
+ return (attr_p->attr.fmtp.is_interlace);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_pack_mode
+ * Description: Gets the value of the fmtp attribute- packetization-mode parameter for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: packetization-mode value in the range 0 - 2.
+ */
+
+sdp_result_e sdp_attr_get_fmtp_pack_mode (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, uint16_t *val)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ if (SDP_INVALID_PACKETIZATION_MODE_VALUE == attr_p->attr.fmtp.packetization_mode) {
+ /* packetization mode unspecified (optional) */
+ *val = SDP_DEFAULT_PACKETIZATION_MODE_VALUE;
+ } else {
+ *val = attr_p->attr.fmtp.packetization_mode;
+ }
+ return (SDP_SUCCESS);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_level_asymmetry_allowed
+ * Description: Gets the value of the fmtp attribute- level-asymmetry-allowed parameter for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: level asymmetry allowed value (0 or 1).
+ */
+
+sdp_result_e sdp_attr_get_fmtp_level_asymmetry_allowed (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, uint16_t *val)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ *val = attr_p->attr.fmtp.level_asymmetry_allowed;
+ return (SDP_SUCCESS);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_profile_id
+ * Description: Gets the value of the fmtp attribute- profile-level-id parameter for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: profile-level-id value.
+ */
+const char* sdp_attr_get_fmtp_profile_id (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ return (attr_p->attr.fmtp.profile_level_id);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_param_sets
+ * Description: Gets the value of the fmtp attribute- parameter-sets parameter for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: parameter-sets value.
+ */
+const char* sdp_attr_get_fmtp_param_sets (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ return (attr_p->attr.fmtp.parameter_sets);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_interleaving_depth
+ * Description: Gets the value of the fmtp attribute- interleaving_depth parameter for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: interleaving_depth value
+ */
+
+sdp_result_e sdp_attr_get_fmtp_interleaving_depth (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, uint16_t* val)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ *val = attr_p->attr.fmtp.interleaving_depth;
+ return (SDP_SUCCESS);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_deint_buf_req
+ * Description: Gets the value of the fmtp attribute- deint-buf-req parameter for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: deint-buf-req value.
+ */
+
+sdp_result_e sdp_attr_get_fmtp_deint_buf_req (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num,
+ uint32_t *val)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ if (attr_p->attr.fmtp.flag & SDP_DEINT_BUF_REQ_FLAG) {
+ *val = attr_p->attr.fmtp.deint_buf_req;
+ return (SDP_SUCCESS);
+ } else {
+ return (SDP_FAILURE);
+ }
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_max_don_diff
+ * Description: Gets the value of the fmtp attribute- max-don-diff parameter for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: max-don-diff value.
+ */
+sdp_result_e sdp_attr_get_fmtp_max_don_diff (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num,
+ uint32_t *val)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ *val = attr_p->attr.fmtp.max_don_diff;
+ return (SDP_SUCCESS);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_init_buf_time
+ * Description: Gets the value of the fmtp attribute- init-buf-time parameter for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: init-buf-time value.
+ */
+sdp_result_e sdp_attr_get_fmtp_init_buf_time (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num,
+ uint32_t *val)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ if (attr_p->attr.fmtp.flag & SDP_INIT_BUF_TIME_FLAG) {
+ *val = attr_p->attr.fmtp.init_buf_time;
+ return (SDP_SUCCESS);
+ } else {
+ return (SDP_FAILURE);
+ }
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_max_mbps
+ * Description: Gets the value of the fmtp attribute- max-mbps parameter for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: max-mbps value.
+ */
+
+sdp_result_e sdp_attr_get_fmtp_max_mbps (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num,
+ uint32_t *val)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ *val = attr_p->attr.fmtp.max_mbps;
+ return (SDP_SUCCESS);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_max_fs
+ * Description: Gets the value of the fmtp attribute- max-fs parameter for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: max-fs value.
+ */
+
+sdp_result_e sdp_attr_get_fmtp_max_fs (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, uint32_t *val)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ *val = attr_p->attr.fmtp.max_fs;
+ return (SDP_SUCCESS);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_max_fr
+ * Description: Gets the value of the fmtp attribute- max-fr parameter
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: max-fr value.
+ */
+
+sdp_result_e sdp_attr_get_fmtp_max_fr (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, uint32_t *val)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ *val = attr_p->attr.fmtp.max_fr;
+ return (SDP_SUCCESS);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_max_cpb
+ * Description: Gets the value of the fmtp attribute- max-cpb parameter for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: max-cpb value.
+ */
+
+sdp_result_e sdp_attr_get_fmtp_max_cpb (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, uint32_t *val)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ *val = attr_p->attr.fmtp.max_cpb;
+ return (SDP_SUCCESS);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_max_dpb
+ * Description: Gets the value of the fmtp attribute- max-dpb parameter for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: max-dpb value.
+ */
+
+sdp_result_e sdp_attr_get_fmtp_max_dpb (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, uint32_t *val)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ *val = attr_p->attr.fmtp.max_dpb;
+ return (SDP_SUCCESS);
+ }
+}
+
+
+/* Function: sdp_attr_get_fmtp_max_br
+ * Description: Gets the value of the fmtp attribute- max-br parameter for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: max-br value.
+ */
+
+sdp_result_e sdp_attr_get_fmtp_max_br (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, uint32_t* val)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ *val = attr_p->attr.fmtp.max_br;
+ return (SDP_SUCCESS);
+ }
+}
+
+/* Function: sdp_attr_fmtp_is_redundant_pic_cap
+ * Description: Gets the value of the fmtp attribute- redundant_pic_cap parameter for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: redundant-pic-cap value.
+ */
+tinybool sdp_attr_fmtp_is_redundant_pic_cap (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (FALSE);
+ } else {
+ return (attr_p->attr.fmtp.redundant_pic_cap);
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_deint_buf_cap
+ * Description: Gets the value of the fmtp attribute- deint-buf-cap parameter for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: deint-buf-cap value.
+ */
+
+sdp_result_e sdp_attr_get_fmtp_deint_buf_cap (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num,
+ uint32_t *val)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ if (attr_p->attr.fmtp.flag & SDP_DEINT_BUF_CAP_FLAG) {
+ *val = attr_p->attr.fmtp.deint_buf_cap;
+ return (SDP_SUCCESS);
+ } else {
+ return (SDP_FAILURE);
+ }
+ }
+}
+
+/* Function: sdp_attr_get_fmtp_max_rcmd_nalu_size
+ * Description: Gets the value of the fmtp attribute- max-rcmd-nalu-size parameter for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: max-rcmd-nalu-size value.
+ */
+sdp_result_e sdp_attr_get_fmtp_max_rcmd_nalu_size (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num,
+ uint32_t *val)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ if (attr_p->attr.fmtp.flag & SDP_MAX_RCMD_NALU_SIZE_FLAG) {
+ *val = attr_p->attr.fmtp.max_rcmd_nalu_size;
+ return (SDP_SUCCESS);
+ } else {
+ return (SDP_FAILURE);
+ }
+ }
+}
+
+/* Function: sdp_attr_fmtp_is_parameter_add
+ * Description: Gets the value of the fmtp attribute- parameter-add for H.264 codec
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: TRUE/FALSE ( parameter-add is boolean)
+ */
+tinybool sdp_attr_fmtp_is_parameter_add (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (FALSE);
+ } else {
+ /* Both 1 and SDP_FMTP_UNUSED (parameter not present) should be
+ * treated as TRUE, per RFC 3984, page 45 */
+ return (attr_p->attr.fmtp.parameter_add != 0);
+ }
+}
+
+/****** Following functions are get routines for Annex values
+ * For each Annex support, the get routine will return the boolean TRUE/FALSE
+ * Some Annexures for Video codecs have values defined . In those cases,
+ * (e.g Annex K, P ) , the return values are not boolean.
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Annex value
+ */
+
+tinybool sdp_attr_get_fmtp_annex_d (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (FALSE);
+ } else {
+ return (attr_p->attr.fmtp.annex_d);
+ }
+}
+
+tinybool sdp_attr_get_fmtp_annex_f (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (FALSE);
+ } else {
+ return (attr_p->attr.fmtp.annex_f);
+ }
+}
+
+tinybool sdp_attr_get_fmtp_annex_i (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (FALSE);
+ } else {
+ return (attr_p->attr.fmtp.annex_i);
+ }
+}
+
+tinybool sdp_attr_get_fmtp_annex_j (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (FALSE);
+ } else {
+ return (attr_p->attr.fmtp.annex_j);
+ }
+}
+
+tinybool sdp_attr_get_fmtp_annex_t (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (FALSE);
+ } else {
+ return (attr_p->attr.fmtp.annex_t);
+ }
+}
+
+int32_t sdp_attr_get_fmtp_annex_k_val (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.annex_k_val);
+ }
+}
+
+int32_t sdp_attr_get_fmtp_annex_n_val (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.annex_n_val);
+ }
+}
+
+int32_t sdp_attr_get_fmtp_annex_p_picture_resize (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.annex_p_val_picture_resize);
+ }
+}
+
+int32_t sdp_attr_get_fmtp_annex_p_warp (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ } else {
+ return (attr_p->attr.fmtp.annex_p_val_warp);
+ }
+}
+
+/* Function: sdp_attr_fmtp_get_fmtp_format
+ * Description: Gives the value of the fmtp attribute fmtp_format
+ * type parameter
+ * for the given attribute.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ *
+ *
+ * Returns: Enum type sdp_fmtp_format_type_e
+ */
+sdp_fmtp_format_type_e sdp_attr_fmtp_get_fmtp_format (sdp_t *sdp_p,
+ uint16_t level, uint8_t cap_num,
+ uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s fmtp attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_FMTP_UNKNOWN_TYPE);
+ } else {
+ return (attr_p->attr.fmtp.fmtp_format);
+ }
+}
+
+/* Function: sdp_attr_get_pccodec_num_payload_types
+ * Description: Returns the number of payload types specified for the
+ * given X-pc-codec attribute. If the given attribute is not
+ * defined, zero is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Number of payload types.
+ */
+uint16_t sdp_attr_get_pccodec_num_payload_types (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_X_PC_CODEC,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s X-pc-codec attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ return (attr_p->attr.pccodec.num_payloads);
+ }
+}
+
+/* Function: sdp_attr_get_pccodec_payload_type
+ * Description: Returns the value of the specified payload type for the
+ * given X-pc-codec attribute. If the given attribute is not
+ * defined, zero is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * payload_num The payload number to get. Range is (1 -
+ * max num payloads).
+ * Returns: Payload type.
+ */
+uint16_t sdp_attr_get_pccodec_payload_type (sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ uint16_t inst_num, uint16_t payload_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_X_PC_CODEC,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s X-pc-codec attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ if ((payload_num < 1) ||
+ (payload_num > attr_p->attr.pccodec.num_payloads)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s X-pc-codec attribute, level %u instance %u, "
+ "invalid payload number %u requested.",
+ sdp_p->debug_str, (unsigned)level, (unsigned)inst_num, (unsigned)payload_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ return (attr_p->attr.pccodec.payload_type[payload_num-1]);
+ }
+ }
+}
+
+/* Function: sdp_attr_add_pccodec_payload_type
+ * Description: Add a new value to the list of payload types specified for
+ * the given X-pc-codec attribute. The payload type will be
+ * added to the end of the list so these values should be added
+ * in the order they will be displayed within the attribute.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * payload_type The payload type to add.
+ * Returns: SDP_SUCCESS Payload type was added successfully.
+ * SDP_INVALID_PARAMETER Specified attribute is not defined.
+ */
+sdp_result_e sdp_attr_add_pccodec_payload_type (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num,
+ uint16_t payload_type)
+{
+ uint16_t payload_num;
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_X_PC_CODEC,
+ inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s X-pc-codec attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ } else {
+ payload_num = attr_p->attr.pccodec.num_payloads++;
+ attr_p->attr.pccodec.payload_type[payload_num] = payload_type;
+ return (SDP_SUCCESS);
+ }
+}
+
+/* Function: sdp_attr_get_xcap_first_cap_num
+ * Description: Gets the first capability number valid for the specified
+ * X-cap attribute instance. If the capability is not
+ * defined, zero is returned.
+ * Note: cap_num is not specified. It must be zero.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the capability.
+ * inst_num The X-cap instance number to check.
+ * Returns: Capability number or zero.
+ */
+uint16_t sdp_attr_get_xcap_first_cap_num (sdp_t *sdp_p, uint16_t level, uint16_t inst_num)
+{
+ uint16_t cap_num=1;
+ uint16_t attr_count=0;
+ sdp_attr_t *attr_p;
+ sdp_mca_t *mca_p;
+
+ if (level == SDP_SESSION_LEVEL) {
+ for (attr_p = sdp_p->sess_attrs_p; attr_p != NULL;
+ attr_p = attr_p->next_p) {
+ if (attr_p->type == SDP_ATTR_X_CAP) {
+ attr_count++;
+ if (attr_count == inst_num) {
+ return (cap_num);
+ } else {
+ cap_num += attr_p->attr.cap_p->num_payloads;
+ }
+ }
+ }
+ } else { /* Capability is at a media level */
+ mca_p = sdp_find_media_level(sdp_p, level);
+ if (mca_p == NULL) {
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ }
+ for (attr_p = mca_p->media_attrs_p; attr_p != NULL;
+ attr_p = attr_p->next_p) {
+ if (attr_p->type == SDP_ATTR_X_CAP) {
+ attr_count++;
+ if (attr_count == inst_num) {
+ return (cap_num);
+ } else {
+ cap_num += attr_p->attr.cap_p->num_payloads;
+ }
+ }
+ }
+ } /* Attr is at a media level */
+
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s X-cap attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+}
+
+/* Function: sdp_attr_get_xcap_media_type
+ * Description: Returns the media type specified for the given X-cap
+ * attribute. If the given attribute is not defined,
+ * SDP_MEDIA_INVALID is returned.
+ * Note: cap_num is not specified. It must be zero.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * inst_num The attribute instance number to check.
+ * Returns: Media type or SDP_MEDIA_INVALID.
+ */
+sdp_media_e sdp_attr_get_xcap_media_type (sdp_t *sdp_p, uint16_t level,
+ uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+ sdp_mca_t *cap_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_X_CAP, inst_num);
+ if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s X-cap attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_MEDIA_INVALID);
+ } else {
+ cap_p = attr_p->attr.cap_p;
+ return (cap_p->media);
+ }
+}
+
+/* Function: sdp_attr_get_xcap_transport_type
+ * Description: Returns the transport type specified for the given X-cap
+ * attribute. If the given attribute is not defined,
+ * SDP_TRANSPORT_INVALID is returned.
+ * Note: cap_num is not specified. It must be zero.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * inst_num The attribute instance number to check.
+ * Returns: Media type or SDP_TRANSPORT_INVALID.
+ */
+sdp_transport_e sdp_attr_get_xcap_transport_type (sdp_t *sdp_p, uint16_t level,
+ uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+ sdp_mca_t *cap_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_X_CAP,
+ inst_num);
+ if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s X-cap attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_TRANSPORT_INVALID);
+ } else {
+ cap_p = attr_p->attr.cap_p;
+ return (cap_p->transport);
+ }
+}
+
+/* Function: sdp_attr_get_xcap_num_payload_types
+ * Description: Returns the number of payload types associated with the
+ * specified X-cap attribute. If the attribute is invalid,
+ * zero will be returned. Application must validate the
+ * attribute line before using this routine.
+ * Note: cap_num is not specified. It must be zero.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Number of payload types or zero.
+ */
+uint16_t sdp_attr_get_xcap_num_payload_types (sdp_t *sdp_p, uint16_t level,
+ uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+ sdp_mca_t *cap_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_X_CAP, inst_num);
+ if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s X-cap attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ cap_p = attr_p->attr.cap_p;
+ return (cap_p->num_payloads);
+ }
+}
+
+/* Function: sdp_attr_get_xcap_payload_type
+ * Description: Returns the payload type of the specified payload for the
+ * X-cap attribute line. If the attr line or payload number is
+ * invalid, zero will be returned. Application must validate
+ * the X-cap attr before using this routine.
+ * Note: cap_num is not specified. It must be zero.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * inst_num The attribute instance number to check.
+ * payload_num The payload number to retrieve. Range is
+ * (1 - max num payloads).
+ * Returns: Payload type or zero.
+ */
+uint16_t sdp_attr_get_xcap_payload_type (sdp_t *sdp_p, uint16_t level,
+ uint16_t inst_num, uint16_t payload_num,
+ sdp_payload_ind_e *indicator)
+{
+ sdp_attr_t *attr_p;
+ sdp_mca_t *cap_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_X_CAP, inst_num);
+ if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s X-cap attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ cap_p = attr_p->attr.cap_p;
+ if ((payload_num < 1) ||
+ (payload_num > cap_p->num_payloads)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s X-cap attribute, level %u instance %u, "
+ "payload num %u invalid.", sdp_p->debug_str,
+ (unsigned)level, (unsigned)inst_num, (unsigned)payload_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ *indicator = cap_p->payload_indicator[payload_num-1];
+ return (cap_p->payload_type[payload_num-1]);
+ }
+ }
+}
+
+
+/* Function: sdp_attr_add_xcap_payload_type
+ * Description: Add a new payload type for the X-cap attribute line
+ * specified. The new payload type will be added at the end
+ * of the payload type list.
+ * Note: cap_num is not specified. It must be zero.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * inst_num The attribute instance number to check.
+ * payload_type The new payload type.
+ * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER
+ */
+sdp_result_e sdp_attr_add_xcap_payload_type(sdp_t *sdp_p, uint16_t level,
+ uint16_t inst_num, uint16_t payload_type,
+ sdp_payload_ind_e indicator)
+{
+ sdp_attr_t *attr_p;
+ sdp_mca_t *cap_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_X_CAP, inst_num);
+ if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s X-cap attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+
+ cap_p = attr_p->attr.cap_p;
+ cap_p->payload_indicator[cap_p->num_payloads] = indicator;
+ cap_p->payload_type[cap_p->num_payloads++] = payload_type;
+ return (SDP_SUCCESS);
+}
+
+/* Function: sdp_attr_get_cdsc_first_cap_num
+ * Description: Gets the first capability number valid for the specified
+ * CDSC attribute instance. If the capability is not
+ * defined, zero is returned.
+ * Note: cap_num is not specified. It must be zero.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the capability.
+ * inst_num The CDSC instance number to check.
+ * Returns: Capability number or zero.
+ */
+uint16_t sdp_attr_get_cdsc_first_cap_num(sdp_t *sdp_p, uint16_t level, uint16_t inst_num)
+{
+ uint16_t cap_num=1;
+ uint16_t attr_count=0;
+ sdp_attr_t *attr_p;
+ sdp_mca_t *mca_p;
+
+ if (level == SDP_SESSION_LEVEL) {
+ for (attr_p = sdp_p->sess_attrs_p; attr_p != NULL;
+ attr_p = attr_p->next_p) {
+ if (attr_p->type == SDP_ATTR_CDSC) {
+ attr_count++;
+ if (attr_count == inst_num) {
+ return (cap_num);
+ } else {
+ cap_num += attr_p->attr.cap_p->num_payloads;
+ }
+ }
+ }
+ } else { /* Capability is at a media level */
+ mca_p = sdp_find_media_level(sdp_p, level);
+ if (mca_p == NULL) {
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ }
+ for (attr_p = mca_p->media_attrs_p; attr_p != NULL;
+ attr_p = attr_p->next_p) {
+ if (attr_p->type == SDP_ATTR_CDSC) {
+ attr_count++;
+ if (attr_count == inst_num) {
+ return (cap_num);
+ } else {
+ cap_num += attr_p->attr.cap_p->num_payloads;
+ }
+ }
+ }
+ } /* Attr is at a media level */
+
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s CDSC attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+}
+
+/* Function: sdp_attr_get_cdsc_media_type
+ * Description: Returns the media type specified for the given CDSC
+ * attribute. If the given attribute is not defined,
+ * SDP_MEDIA_INVALID is returned.
+ * Note: cap_num is not specified. It must be zero.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * inst_num The attribute instance number to check.
+ * Returns: Media type or SDP_MEDIA_INVALID.
+ */
+sdp_media_e sdp_attr_get_cdsc_media_type(sdp_t *sdp_p, uint16_t level,
+ uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+ sdp_mca_t *cdsc_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_CDSC, inst_num);
+ if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s CDSC attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_MEDIA_INVALID);
+ } else {
+ cdsc_p = attr_p->attr.cap_p;
+ return (cdsc_p->media);
+ }
+}
+
+/* Function: sdp_attr_get_cdsc_transport_type
+ * Description: Returns the transport type specified for the given CDSC
+ * attribute. If the given attribute is not defined,
+ * SDP_TRANSPORT_INVALID is returned.
+ * Note: cap_num is not specified. It must be zero.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * inst_num The attribute instance number to check.
+ * Returns: Media type or SDP_TRANSPORT_INVALID.
+ */
+sdp_transport_e sdp_attr_get_cdsc_transport_type(sdp_t *sdp_p, uint16_t level,
+ uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+ sdp_mca_t *cdsc_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_CDSC,
+ inst_num);
+ if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s CDSC attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_TRANSPORT_INVALID);
+ } else {
+ cdsc_p = attr_p->attr.cap_p;
+ return (cdsc_p->transport);
+ }
+}
+
+/* Function: sdp_attr_get_cdsc_num_payload_types
+ * Description: Returns the number of payload types associated with the
+ * specified CDSC attribute. If the attribute is invalid,
+ * zero will be returned. Application must validate the
+ * attribute line before using this routine.
+ * Note: cap_num is not specified. It must be zero.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Number of payload types or zero.
+ */
+uint16_t sdp_attr_get_cdsc_num_payload_types (sdp_t *sdp_p, uint16_t level,
+ uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+ sdp_mca_t *cdsc_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_CDSC, inst_num);
+ if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s CDSC attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ cdsc_p = attr_p->attr.cap_p;
+ return (cdsc_p->num_payloads);
+ }
+}
+
+/* Function: sdp_attr_get_cdsc_payload_type
+ * Description: Returns the payload type of the specified payload for the
+ * CDSC attribute line. If the attr line or payload number is
+ * invalid, zero will be returned. Application must validate
+ * the CDSC attr before using this routine.
+ * Note: cap_num is not specified. It must be zero.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * inst_num The attribute instance number to check.
+ * payload_num The payload number to retrieve. Range is
+ * (1 - max num payloads).
+ * Returns: Payload type or zero.
+ */
+uint16_t sdp_attr_get_cdsc_payload_type (sdp_t *sdp_p, uint16_t level,
+ uint16_t inst_num, uint16_t payload_num,
+ sdp_payload_ind_e *indicator)
+{
+ sdp_attr_t *attr_p;
+ sdp_mca_t *cdsc_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_CDSC, inst_num);
+ if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s CDSC attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ cdsc_p = attr_p->attr.cap_p;
+ if ((payload_num < 1) ||
+ (payload_num > cdsc_p->num_payloads)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s CDSC attribute, level %u instance %u, "
+ "payload num %u invalid.", sdp_p->debug_str,
+ (unsigned)level, (unsigned)inst_num, (unsigned)payload_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ *indicator = cdsc_p->payload_indicator[payload_num-1];
+ return (cdsc_p->payload_type[payload_num-1]);
+ }
+ }
+}
+
+/* Function: sdp_attr_add_cdsc_payload_type
+ * Description: Add a new payload type for the CDSC attribute line
+ * specified. The new payload type will be added at the end
+ * of the payload type list.
+ * Note: cap_num is not specified. It must be zero.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * inst_num The attribute instance number to check.
+ * payload_type The new payload type.
+ * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER
+ */
+sdp_result_e sdp_attr_add_cdsc_payload_type (sdp_t *sdp_p, uint16_t level,
+ uint16_t inst_num, uint16_t payload_type,
+ sdp_payload_ind_e indicator)
+{
+ sdp_attr_t *attr_p;
+ sdp_mca_t *cdsc_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_CDSC, inst_num);
+ if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s CDSC attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+
+ cdsc_p = attr_p->attr.cap_p;
+ cdsc_p->payload_indicator[cdsc_p->num_payloads] = indicator;
+ cdsc_p->payload_type[cdsc_p->num_payloads++] = payload_type;
+ return (SDP_SUCCESS);
+}
+
+/* Function: sdp_media_dynamic_payload_valid
+ * Description: Checks if the dynamic payload type passed in is defined
+ * on the media line m_line
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * payload_type Payload type to be checked
+ *
+ * Returns: TRUE or FALSE. Returns TRUE if payload type is defined on the
+ * media line, else returns FALSE
+ */
+
+tinybool sdp_media_dynamic_payload_valid (sdp_t *sdp_p, uint16_t payload_type,
+ uint16_t m_line)
+{
+ uint16_t p_type,m_ptype;
+ ushort num_payload_types;
+ sdp_payload_ind_e ind;
+ tinybool payload_matches = FALSE;
+ tinybool result = TRUE;
+
+ if ((payload_type < SDP_MIN_DYNAMIC_PAYLOAD) ||
+ (payload_type > SDP_MAX_DYNAMIC_PAYLOAD)) {
+ return FALSE;
+ }
+
+ num_payload_types =
+ sdp_get_media_num_payload_types(sdp_p, m_line);
+
+ for(p_type=1; p_type <=num_payload_types;p_type++){
+
+ m_ptype = (uint16_t)sdp_get_media_payload_type(sdp_p,
+ m_line, p_type, &ind);
+ if (payload_type == m_ptype) {
+ payload_matches = TRUE;
+ break;
+ }
+
+ }
+
+ if (!payload_matches) {
+ return FALSE;
+ }
+
+ return (result);
+
+}
+
+/* Function: sdp_attr_get_rtr_confirm
+ * Description: Returns the value of the rtr attribute confirm
+ * parameter specified for the given attribute. Returns TRUE if
+ * the confirm parameter is specified.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Boolean value.
+ */
+tinybool sdp_attr_get_rtr_confirm (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTR, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s %s attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str,
+ sdp_get_attr_name(SDP_ATTR_RTR), (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (FALSE);
+ } else {
+ return (attr_p->attr.rtr.confirm);
+ }
+}
+
+
+
+sdp_mediadir_role_e sdp_attr_get_comediadir_role (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_DIRECTION, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Comediadir role attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_MEDIADIR_ROLE_UNKNOWN);
+ } else {
+ return (attr_p->attr.comediadir.role);
+ }
+}
+
+/* Function: sdp_attr_get_silencesupp_enabled
+ * Description: Returns the value of the silencesupp attribute enable
+ * parameter specified for the given attribute. Returns TRUE if
+ * the confirm parameter is specified.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Boolean value.
+ */
+tinybool sdp_attr_get_silencesupp_enabled (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SILENCESUPP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s silenceSuppEnable attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (FALSE);
+ } else {
+ return (attr_p->attr.silencesupp.enabled);
+ }
+}
+
+/* Function: sdp_attr_get_silencesupp_timer
+ * Description: Returns the value of the silencesupp attribute timer
+ * parameter specified for the given attribute. null_ind
+ * is set to TRUE if no value was specified, but instead the
+ * null "-" value was specified.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: 16-bit timer value
+ * boolean null_ind
+ */
+uint16_t sdp_attr_get_silencesupp_timer (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num,
+ tinybool *null_ind)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SILENCESUPP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s silenceTimer attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ *null_ind = attr_p->attr.silencesupp.timer_null;
+ return (attr_p->attr.silencesupp.timer);
+ }
+}
+
+/* Function: sdp_attr_get_silencesupp_pref
+ * Description: Sets the silencesupp supppref value
+ * If this parameter is TRUE, the confirm parameter will be
+ * specified when the SDP description is built.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * confirm New qos confirm parameter.
+ * Returns: SDP_SUCCESS Attribute param was set successfully.
+ * SDP_INVALID_PARAMETER Specified attribute is not defined.
+ */
+sdp_silencesupp_pref_e sdp_attr_get_silencesupp_pref (sdp_t *sdp_p,
+ uint16_t level, uint8_t cap_num,
+ uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SILENCESUPP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s silence suppPref attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_SILENCESUPP_PREF_UNKNOWN);
+ } else {
+ return (attr_p->attr.silencesupp.pref);
+ }
+}
+
+/* Function: sdp_attr_get_silencesupp_siduse
+ * Description: Returns the value of the silencesupp attribute siduse
+ * parameter specified for the given attribute. If the given
+ * attribute is not defined, SDP_QOS_STRENGTH_UNKNOWN is
+ * returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: silencesupp siduse enum.
+ */
+sdp_silencesupp_siduse_e sdp_attr_get_silencesupp_siduse (sdp_t *sdp_p,
+ uint16_t level,
+ uint8_t cap_num,
+ uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SILENCESUPP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s silence sidUse attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_SILENCESUPP_SIDUSE_UNKNOWN);
+ } else {
+ return (attr_p->attr.silencesupp.siduse);
+ }
+}
+
+/* Function: sdp_attr_get_silencesupp_fxnslevel
+ * Description: Returns the value of the silencesupp attribute fxns
+ * (fixed noise) parameter specified for the given attribute.
+ * null_ind is set to TRUE if no value was specified,
+ * but instead the null "-" value was specified.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: 7-bit fxns value
+ * boolean null_ind
+ */
+uint8_t sdp_attr_get_silencesupp_fxnslevel (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num,
+ tinybool *null_ind)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SILENCESUPP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s silence fxnslevel attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ *null_ind = attr_p->attr.silencesupp.fxnslevel_null;
+ return (attr_p->attr.silencesupp.fxnslevel);
+ }
+}
+
+/* Function: sdp_attr_get_mptime_num_intervals
+ * Description: Returns the number of intervals specified for the
+ * given mptime attribute. If the given attribute is not
+ * defined, zero is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Number of intervals.
+ */
+uint16_t sdp_attr_get_mptime_num_intervals (
+ sdp_t *sdp_p,
+ uint16_t level,
+ uint8_t cap_num,
+ uint16_t inst_num) {
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_MPTIME, inst_num);
+ if (attr_p != NULL) {
+ return attr_p->attr.mptime.num_intervals;
+ }
+
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s mptime attribute, level %u instance %u not found.",
+ sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return 0;
+}
+
+/* Function: sdp_attr_get_mptime_interval
+ * Description: Returns the value of the specified interval for the
+ * given mptime attribute. If the given attribute is not
+ * defined, zero is returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * interval_num The interval number to get. Range is (1 -
+ * max num payloads).
+ * Returns: Interval.
+ */
+uint16_t sdp_attr_get_mptime_interval (
+ sdp_t *sdp_p,
+ uint16_t level,
+ uint8_t cap_num,
+ uint16_t inst_num,
+ uint16_t interval_num) {
+
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_MPTIME, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s mptime attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return 0;
+ }
+
+ if ((interval_num<1) || (interval_num>attr_p->attr.mptime.num_intervals)) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s mptime attribute, level %u instance %u, "
+ "invalid interval number %u requested.",
+ sdp_p->debug_str, (unsigned)level, (unsigned)inst_num, (unsigned)interval_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return 0;
+ }
+
+ return attr_p->attr.mptime.intervals[interval_num-1];
+}
+
+/* Function: sdp_attr_add_mptime_interval
+ * Description: Add a new value to the list of intervals specified for
+ * the given mptime attribute. The interval will be
+ * added to the end of the list so these values should be added
+ * in the order they will be displayed within the attribute.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * mp_interval The interval to add.
+ * Returns: SDP_SUCCESS Interval was added successfully.
+ * SDP_INVALID_PARAMETER Specified attribute is not defined.
+ * SDP_INVALID_SDP_PTR Supplied SDP pointer is invalid
+ */
+sdp_result_e sdp_attr_add_mptime_interval (
+ sdp_t *sdp_p,
+ uint16_t level,
+ uint8_t cap_num,
+ uint16_t inst_num,
+ uint16_t mp_interval) {
+
+ uint16_t interval_num;
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_MPTIME, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s mptime attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return SDP_INVALID_PARAMETER;
+ }
+
+ interval_num = attr_p->attr.mptime.num_intervals;
+ if (interval_num>=SDP_MAX_PAYLOAD_TYPES) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s mptime attribute, level %u instance %u "
+ "exceeds maximum length.",
+ sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return SDP_INVALID_PARAMETER;
+ }
+
+ attr_p->attr.mptime.intervals[interval_num] = mp_interval;
+ ++attr_p->attr.mptime.num_intervals;
+ return SDP_SUCCESS;
+}
+
+
+
+/* Function: sdp_get_group_attr
+ * Description: Returns the attribute parameter from the a=group:<>
+ * line. If no attrib has been set ,
+ * SDP_GROUP_ATTR_UNSUPPORTED will be returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level SDP_SESSION_LEVEL
+ * Returns: Valid attrib value or SDP_GROUP_ATTR_UNSUPPORTED.
+ */
+sdp_group_attr_e sdp_get_group_attr (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_GROUP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Group (a= group line) attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_GROUP_ATTR_UNSUPPORTED);
+ } else {
+ if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) {
+ SDP_PRINT("%s Stream data group attr field is :%s ",
+ sdp_p->debug_str,
+ sdp_get_group_attr_name(attr_p->attr.stream_data.group_attr) );
+ }
+ return (attr_p->attr.stream_data.group_attr);
+ }
+}
+
+/* Function: sdp_get_group_num_id
+ * Description: Returns the number of ids from the a=group:<> line.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level SDP_SESSION_LEVEL
+ * Returns: Num of group ids present or 0 if there is an error.
+ */
+uint16_t sdp_get_group_num_id (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_GROUP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s a=group level attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (0);
+ } else {
+ if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) {
+ SDP_PRINT("%s Stream data group attr - num of ids is :%u ",
+ sdp_p->debug_str,
+ (unsigned)attr_p->attr.stream_data.num_group_id);
+ }
+ }
+ return (attr_p->attr.stream_data.num_group_id);
+}
+
+/* Function: sdp_get_group_id
+ * Description: Returns the group id from the a=group:<> line.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level SDP_SESSION_LEVEL
+ * id_num Number of the id to retrieve. The range is (1 -
+ * SDP_MAX_GROUP_STREAM_ID)
+ * Returns: Value of the group id at the index specified or
+ * NULL if an error
+ */
+const char* sdp_get_group_id (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num, uint16_t id_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_GROUP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s a=group level attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (NULL);
+ } else {
+ if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) {
+ SDP_PRINT("%s Stream data group attr - num of ids is :%u ",
+ sdp_p->debug_str,
+ (unsigned)attr_p->attr.stream_data.num_group_id);
+ }
+ if ((id_num < 1) || (id_num > attr_p->attr.stream_data.num_group_id)) {
+ return (NULL);
+ }
+ }
+ return (attr_p->attr.stream_data.group_ids[id_num-1]);
+}
+
+/* Function: sdp_attr_get_x_sidin
+ * Description: Returns the attribute parameter from the a=X-sidin:<>
+ * line. If no attrib has been set NULL will be returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level media level index
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Pointer to sidin or NULL.
+ */
+const char* sdp_attr_get_x_sidin (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_X_SIDIN, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s X-sidin attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (NULL);
+ } else {
+ if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) {
+ SDP_PRINT("%s Stream X-sidin attr field is :%s ",
+ sdp_p->debug_str,
+ attr_p->attr.stream_data.x_sidin);
+ }
+ return (attr_p->attr.stream_data.x_sidin);
+ }
+}
+
+/* Function: sdp_attr_get_x_sidout
+ * Description: Returns the attribute parameter from the a=X-sidout:<>
+ * line. If no attrib has been set NULL will be returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level media level index
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Pointer to sidout or NULL.
+ */
+const char* sdp_attr_get_x_sidout (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_X_SIDOUT, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s X-sidout attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (NULL);
+ } else {
+ if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) {
+ SDP_PRINT("%s Stream X-sidout attr field is :%s ",
+ sdp_p->debug_str,
+ attr_p->attr.stream_data.x_sidout);
+ }
+ return (attr_p->attr.stream_data.x_sidout);
+ }
+}
+
+/* Function: sdp_attr_get_x_confid
+ * Description: Returns the attribute parameter from the a=X-confid:<>
+ * line. If no attrib has been set NULL will be returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level media level index
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Pointer to confid or NULL.
+ */
+const char* sdp_attr_get_x_confid (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_X_CONFID, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s X-confid attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (NULL);
+ } else {
+ if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) {
+ SDP_PRINT("%s Stream X-confid attr field is :%s ",
+ sdp_p->debug_str,
+ attr_p->attr.stream_data.x_confid);
+ }
+ return (attr_p->attr.stream_data.x_confid);
+ }
+}
+
+/* Function: sdp_get_source_filter_mode
+ * Description: Gets the filter mode in internal representation
+ * Parameters: sdp_p The SDP handle which contains the attributes
+ * level SDP_SESSION_LEVEL/m-line number
+ * inst_num The attribute instance number
+ * Returns: Filter mode (incl/excl/not present)
+ */
+sdp_src_filter_mode_e
+sdp_get_source_filter_mode (sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SOURCE_FILTER, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Source filter attribute, level %u, "
+ "instance %u not found", sdp_p->debug_str,
+ (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_FILTER_MODE_NOT_PRESENT);
+ }
+ return (attr_p->attr.source_filter.mode);
+}
+
+/* Function: sdp_get_filter_destination_attributes
+ * Description: Gets the destination address parameters
+ * Parameters: Network type (optional), destination address type
+ * (optional), and destination address (mandatory) variables
+ * which gets updated.
+ * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER/SDP_INVALID_SDP_PTR
+ */
+sdp_result_e
+sdp_get_filter_destination_attributes (sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ uint16_t inst_num, sdp_nettype_e *nettype,
+ sdp_addrtype_e *addrtype,
+ char *dest_addr)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SOURCE_FILTER, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Source filter attribute, level %u instance %u "
+ "not found", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+ if (nettype) {
+ *nettype = attr_p->attr.source_filter.nettype;
+ }
+ if (addrtype) {
+ *addrtype = attr_p->attr.source_filter.addrtype;
+ }
+ sstrncpy(dest_addr, attr_p->attr.source_filter.dest_addr,
+ SDP_MAX_STRING_LEN+1);
+
+ return (SDP_SUCCESS);
+}
+
+/* Function: sdp_get_filter_source_address_count
+ * Description: Gets the number of source addresses in the list
+ * Parameters: sdp_p The SDP handle which contains the attributes
+ * level SDP_SESSION_LEVEL/m-line number
+ * inst_num The attribute instance number
+ * Returns: Source-list count
+ */
+
+int32_t
+sdp_get_filter_source_address_count (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SOURCE_FILTER, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Source filter attribute, level %u instance %u "
+ "not found", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_VALUE);
+ }
+ return (attr_p->attr.source_filter.num_src_addr);
+}
+
+/* Function: sdp_get_filter_source_address
+ * Description: Gets one of the source address that is indexed by the user
+ * Parameters: sdp_p The SDP handle which contains the attributes
+ * level SDP_SESSION_LEVEL/m-line number
+ * inst_num The attribute instance number
+ * src_addr_id User provided index (value in range between
+ * 0 to (SDP_MAX_SRC_ADDR_LIST-1) which obtains
+ * the source addr corresponding to it.
+ * src_addr The user provided variable which gets updated
+ * with source address corresponding to the index
+ */
+sdp_result_e
+sdp_get_filter_source_address (sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ uint16_t inst_num, uint16_t src_addr_id,
+ char *src_addr)
+{
+ sdp_attr_t *attr_p;
+
+ src_addr[0] = '\0';
+
+ if (src_addr_id >= SDP_MAX_SRC_ADDR_LIST) {
+ return (SDP_INVALID_PARAMETER);
+ }
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SOURCE_FILTER, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s Source filter attribute, level %u instance %u "
+ "not found", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+ if (src_addr_id >= attr_p->attr.source_filter.num_src_addr) {
+ return (SDP_INVALID_PARAMETER);
+ }
+ sstrncpy(src_addr, attr_p->attr.source_filter.src_list[src_addr_id],
+ SDP_MAX_STRING_LEN+1);
+
+ return (SDP_SUCCESS);
+}
+
+sdp_rtcp_unicast_mode_e
+sdp_get_rtcp_unicast_mode(sdp_t *sdp_p, uint16_t level, uint8_t cap_num,
+ uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_RTCP_UNICAST, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s RTCP Unicast attribute, level %u, "
+ "instance %u not found", sdp_p->debug_str,
+ (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_RTCP_UNICAST_MODE_NOT_PRESENT);
+ }
+ return ((sdp_rtcp_unicast_mode_e)attr_p->attr.u32_val);
+}
+
+
+/* Function: sdp_attr_get_sdescriptions_tag
+ * Description: Returns the value of the sdescriptions tag
+ * parameter specified for the given attribute.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: Tag value or SDP_INVALID_VALUE (-2) if error encountered.
+ */
+
+int32_t
+sdp_attr_get_sdescriptions_tag (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SDESCRIPTIONS, inst_num);
+
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s srtp attribute tag, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return SDP_INVALID_VALUE;
+ } else {
+ return attr_p->attr.srtp_context.tag;
+ }
+}
+
+/* Function: sdp_attr_get_sdescriptions_crypto_suite
+ * Description: Returns the value of the sdescriptions crypto suite
+ * parameter specified for the given attribute. Note that
+ * this is a common api for both version 2 and version 9
+ * sdescriptions. It has no knowledge which version is being
+ * used so it will first try to find if a version 2 sdescriptions
+ * attribute is present. If it is, return the suite. If it's not,
+ * try to find the version 9. This assumes you cannot have both
+ * versions in the same SDP.
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: SDP_SRTP_UNKNOWN_CRYPTO_SUITE is returned if an error was
+ * encountered otherwise the crypto suite is returned.
+ */
+
+sdp_srtp_crypto_suite_t
+sdp_attr_get_sdescriptions_crypto_suite (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+
+ /* Try version 2 first */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SRTP_CONTEXT, inst_num);
+
+ if (attr_p == NULL) {
+ /* There's no version 2 so now try version 9 */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SDESCRIPTIONS, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s srtp attribute suite, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return SDP_SRTP_UNKNOWN_CRYPTO_SUITE;
+ }
+ }
+
+ return attr_p->attr.srtp_context.suite;
+
+}
+
+/* Function: sdp_attr_get_sdescriptions_key
+ * Description: Returns the value of the sdescriptions master key
+ * parameter specified for the given attribute. Note that
+ * this is a common api for both version 2 and version 9
+ * sdescriptions. It has no knowledge which version is being
+ * used so it will first try to find if a version 2 sdescriptions
+ * attribute is present. If it is, return the key. If it's not,
+ * try to find the version 9. This assumes you cannot have both
+ * versions in the same SDP.
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: NULL if error encountered or master key salt string
+ */
+
+const char*
+sdp_attr_get_sdescriptions_key (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ /* Try version 2 first */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SRTP_CONTEXT, inst_num);
+
+ if (attr_p == NULL) {
+ /* Couldn't find version 2 now try version 9 */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SDESCRIPTIONS, inst_num);
+
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s srtp attribute key, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return NULL;
+ }
+ }
+
+ return (char*)attr_p->attr.srtp_context.master_key;
+}
+
+
+/* Function: sdp_attr_get_sdescriptions_salt
+ * Description: Returns the value of the sdescriptions master salt
+ * parameter specified for the given attribute. Note that
+ * this is a common api for both version 2 and version 9
+ * sdescriptions. It has no knowledge which version is being
+ * used so it will first try to find if a version 2 sdescriptions
+ * attribute is present. If it is, return the salt. If it's not,
+ * try to find the version 9. This assumes you cannot have both
+ * versions in the same SDP.
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: NULL if error encountered or master key salt string
+ */
+
+const char*
+sdp_attr_get_sdescriptions_salt (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ /* Try version 2 first */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SRTP_CONTEXT, inst_num);
+
+ if (attr_p == NULL) {
+ /* Couldn't find version 2 now try version 9 */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SDESCRIPTIONS, inst_num);
+
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s srtp attribute salt, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return NULL;
+ }
+ }
+
+ return (char*) attr_p->attr.srtp_context.master_salt;
+
+}
+
+
+
+/* Function: sdp_attr_get_sdescriptions_lifetime
+ * Description: Returns the value of the sdescriptions lifetime
+ * parameter specified for the given attribute.Note that
+ * this is a common api for both version 2 and version 9
+ * sdescriptions. It has no knowledge which version is being
+ * used so it will first try to find if a version 2 sdescriptions
+ * attribute is present. If it is, return the lifetime. If it's
+ * not, try to find the version 9. This assumes you cannot have
+ * both versions in the same SDP.
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: NULL if error encountered or lifetime string
+ */
+
+const char*
+sdp_attr_get_sdescriptions_lifetime (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ /* Try version 2 first. */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SRTP_CONTEXT, inst_num);
+
+ if (attr_p == NULL) {
+ /* Couldn't find version 2 now try version 9 */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SDESCRIPTIONS, inst_num);
+
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s srtp attribute lifetime, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return NULL;
+ }
+ }
+
+ return (char*)attr_p->attr.srtp_context.master_key_lifetime;
+
+}
+
+/* Function: sdp_attr_get_sdescriptions_mki
+ * Description: Returns the value of the sdescriptions MKI value and length
+ * parameter of the specified attribute instance. Note that
+ * this is a common api for both version 2 and version 9
+ * sdescriptions. It has no knowledge which version is being
+ * used so it will first try to find if a version 2 sdescriptions
+ * attribute is present. If it is, return the MKI. If it's
+ * not, try to find version 9. This assumes you cannot have
+ * both versions in the same SDP.
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * mki_value application provided pointer that on exit
+ * is set to the MKI value string if one exists.
+ * mki_length application provided pointer that on exit
+ * is set to the MKI length if one exists.
+ * Returns: SDP_SUCCESS no errors encountered otherwise sdp error
+ * based upon the specific error.
+ */
+
+sdp_result_e
+sdp_attr_get_sdescriptions_mki (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num,
+ const char **mki_value,
+ uint16_t *mki_length)
+{
+ sdp_attr_t *attr_p;
+
+ *mki_value = NULL;
+ *mki_length = 0;
+
+ /* Try version 2 first */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SRTP_CONTEXT, inst_num);
+
+ if (attr_p == NULL) {
+ /* Couldn't find version 2 now try version 9 */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SDESCRIPTIONS, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s srtp attribute MKI, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return SDP_INVALID_PARAMETER;
+ }
+ }
+
+ *mki_value = (char*)attr_p->attr.srtp_context.mki;
+ *mki_length = attr_p->attr.srtp_context.mki_size_bytes;
+ return SDP_SUCCESS;
+
+}
+
+
+/* Function: sdp_attr_get_sdescriptions_session_params
+ * Description: Returns the unparsed session parameters string. Note that
+ * this is a common api for both version 2 and version 9
+ * sdescriptions. It has no knowledge which version is being
+ * used so it will first try to find if a version 2 sdescriptions
+ * attribute is present. If it is, return session parameters. If
+ * it's not, try to find version 9. This assumes you cannot have
+ * both versions in the same SDP.
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: NULL if no session parameters were received in the sdp,
+ * otherwise returns a pointer to the start of the session
+ * parameters string. Note that the calling function should
+ * not free the returned pointer.
+ */
+
+const char*
+sdp_attr_get_sdescriptions_session_params (sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ /* Try version 2 first */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SRTP_CONTEXT, inst_num);
+
+ if (attr_p == NULL) {
+ /* Couldn't find version 2 try version 9 */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SDESCRIPTIONS, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s srtp attribute session params, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return NULL;
+ }
+ }
+
+ return attr_p->attr.srtp_context.session_parameters;
+}
+
+
+/* Function: sdp_attr_get_sdescriptions_key_size
+ * Description: Returns the master key size. Note that
+ * this is a common api for both version 2 and version 9
+ * sdescriptions. It has no knowledge which version is being
+ * used so it will first try to find if a version 2 sdescriptions
+ * attribute is present. If it is, return key size. If
+ * it's not, try to find version 9. This assumes you cannot have
+ * both versions in the same SDP.
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: 0 (SDP_SDESCRIPTIONS_KEY_SIZE_UNKNOWN) if error was
+ * encountered, otherwise key size.
+ */
+
+unsigned char
+sdp_attr_get_sdescriptions_key_size (sdp_t *sdp_p,
+ uint16_t level,
+ uint8_t cap_num,
+ uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ /* Try version 2 first */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SRTP_CONTEXT, inst_num);
+
+ if (attr_p == NULL) {
+ /* Couldn't find version 2 now try version 9 */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SDESCRIPTIONS, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s srtp attribute MKI, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return SDP_SDESCRIPTIONS_KEY_SIZE_UNKNOWN;
+ }
+ }
+
+ return attr_p->attr.srtp_context.master_key_size_bytes;
+
+}
+
+
+/* Function: sdp_attr_get_sdescriptions_salt_size
+ * Description: Returns the salt key size. Note that
+ * this is a common api for both version 2 and version 9
+ * sdescriptions. It has no knowledge which version is being
+ * used so it will first try to find if a version 2 sdescriptions
+ * attribute is present. If it is, return salt size. If
+ * it's not, try to find version 9. This assumes you cannot have
+ * both versions in the same SDP.
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: 0 (SDP_SDESCRIPTIONS_KEY_SIZE_UNKNOWN) if error was
+ * encountered, otherwise salt size.
+ */
+
+unsigned char
+sdp_attr_get_sdescriptions_salt_size (sdp_t *sdp_p,
+ uint16_t level,
+ uint8_t cap_num,
+ uint16_t inst_num)
+{
+
+ sdp_attr_t *attr_p;
+
+ /* Try version 2 first */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SRTP_CONTEXT, inst_num);
+
+ if (attr_p == NULL) {
+ /* Couldn't find version 2 now try version 9 */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SDESCRIPTIONS, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s srtp attribute MKI, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return SDP_SDESCRIPTIONS_KEY_SIZE_UNKNOWN;
+ }
+ }
+
+ return attr_p->attr.srtp_context.master_salt_size_bytes;
+
+}
+
+
+/* Function: sdp_attr_get_srtp_crypto_selection_flags
+ * Description: Returns the selection flags. Note that
+ * this is a common api for both version 2 and version 9
+ * sdescriptions. It has no knowledge which version is being
+ * used so it will first try to find if a version 2 sdescriptions
+ * attribute is present. If it is, return selection flags. If
+ * it's not, try to find version 9. This assumes you cannot have
+ * both versions in the same SDP.
+ * Currently only necessary for MGCP.
+ *
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * cap_num The capability number associated with the
+ * attribute if any. If none, should be zero.
+ * inst_num The attribute instance number to check.
+ * Returns: 0 (SDP_SRTP_CRYPTO_SELECTION_FLAGS_UNKNOWN) if error was
+ * encountered, otherwise selection flags.
+ */
+
+unsigned long
+sdp_attr_get_srtp_crypto_selection_flags (sdp_t *sdp_p,
+ uint16_t level,
+ uint8_t cap_num,
+ uint16_t inst_num)
+{
+
+
+ sdp_attr_t *attr_p;
+
+ /* Try version 2 first */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SRTP_CONTEXT, inst_num);
+
+ if (attr_p == NULL) {
+ /* Couldn't find version 2 now try version 9 */
+ attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_SDESCRIPTIONS, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s srtp attribute MKI, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return SDP_SRTP_CRYPTO_SELECTION_FLAGS_UNKNOWN;
+ }
+ }
+
+ return attr_p->attr.srtp_context.selection_flags;
+
+}
+
+
+
+/* Function: sdp_find_rtcp_fb_attr
+ * Description: Helper to find the nth instance of a rtcp-fb attribute of
+ * the specified feedback type.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * payload_type The payload to get the attribute for
+ * fb_type The feedback type to look for.
+ * inst_num The attribute instance number to check.
+ * Returns: Pointer to the attribute, or NULL if not found.
+ */
+
+sdp_attr_t *
+sdp_find_rtcp_fb_attr (sdp_t *sdp_p,
+ uint16_t level,
+ uint16_t payload_type,
+ sdp_rtcp_fb_type_e fb_type,
+ uint16_t inst_num)
+{
+ uint16_t attr_count=0;
+ sdp_mca_t *mca_p;
+ sdp_attr_t *attr_p;
+
+ mca_p = sdp_find_media_level(sdp_p, level);
+ if (!mca_p) {
+ return (NULL);
+ }
+ for (attr_p = mca_p->media_attrs_p; attr_p; attr_p = attr_p->next_p) {
+ if (attr_p->type == SDP_ATTR_RTCP_FB &&
+ (attr_p->attr.rtcp_fb.payload_num == payload_type ||
+ attr_p->attr.rtcp_fb.payload_num == SDP_ALL_PAYLOADS) &&
+ attr_p->attr.rtcp_fb.feedback_type == fb_type) {
+ attr_count++;
+ if (attr_count == inst_num) {
+ return (attr_p);
+ }
+ }
+ }
+ return NULL;
+}
+
+/* Function: sdp_attr_get_rtcp_fb_ack
+ * Description: Returns the value of the rtcp-fb:...ack attribute
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * payload_type The payload to get the attribute for
+ * inst_num The attribute instance number to check.
+ * Returns: ACK type (SDP_RTCP_FB_ACK_NOT_FOUND if not present)
+ */
+sdp_rtcp_fb_ack_type_e
+sdp_attr_get_rtcp_fb_ack(sdp_t *sdp_p, uint16_t level, uint16_t payload_type, uint16_t inst)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_rtcp_fb_attr(sdp_p, level, payload_type,
+ SDP_RTCP_FB_ACK, inst);
+ if (!attr_p) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s rtcp-fb attribute, level %u, pt %u, "
+ "instance %u not found.", sdp_p->debug_str, (unsigned)level,
+ (unsigned)payload_type, (unsigned)inst);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return SDP_RTCP_FB_ACK_NOT_FOUND;
+ }
+ return (attr_p->attr.rtcp_fb.param.ack);
+}
+
+/* Function: sdp_attr_get_rtcp_fb_nack
+ * Description: Returns the value of the rtcp-fb:...nack attribute
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * payload_type The payload to get the attribute for
+ * inst_num The attribute instance number to check.
+ * Returns: NACK type (SDP_RTCP_FB_NACK_NOT_FOUND if not present)
+ */
+sdp_rtcp_fb_nack_type_e
+sdp_attr_get_rtcp_fb_nack(sdp_t *sdp_p, uint16_t level, uint16_t payload_type, uint16_t inst)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_rtcp_fb_attr(sdp_p, level, payload_type,
+ SDP_RTCP_FB_NACK, inst);
+ if (!attr_p) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s rtcp-fb attribute, level %u, pt %u, "
+ "instance %u not found.", sdp_p->debug_str, (unsigned)level,
+ (unsigned)payload_type, (unsigned)inst);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return SDP_RTCP_FB_NACK_NOT_FOUND;
+ }
+ return (attr_p->attr.rtcp_fb.param.nack);
+}
+
+/* Function: sdp_attr_get_rtcp_fb_trr_int
+ * Description: Returns the value of the rtcp-fb:...trr-int attribute
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * payload_type The payload to get the attribute for
+ * inst_num The attribute instance number to check.
+ * Returns: trr-int interval (0xFFFFFFFF if not found)
+ */
+uint32_t
+sdp_attr_get_rtcp_fb_trr_int(sdp_t *sdp_p, uint16_t level,
+ uint16_t payload_type, uint16_t inst)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_rtcp_fb_attr(sdp_p, level, payload_type,
+ SDP_RTCP_FB_TRR_INT, inst);
+ if (!attr_p) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s rtcp-fb attribute, level %u, pt %u, "
+ "instance %u not found.", sdp_p->debug_str, (unsigned)level,
+ (unsigned)payload_type, (unsigned)inst);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return 0xFFFFFFFF;
+ }
+ return (attr_p->attr.rtcp_fb.param.trr_int);
+}
+
+/* Function: sdp_attr_get_rtcp_fb_remb_enabled
+ * Description: Returns true if rtcp-fb:...goog-remb attribute exists
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * payload_type The payload to get the attribute for
+ * Returns: true if rtcp-fb:...goog-remb exists
+ */
+tinybool
+sdp_attr_get_rtcp_fb_remb_enabled(sdp_t *sdp_p,
+ uint16_t level,
+ uint16_t payload_type)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_rtcp_fb_attr(sdp_p, level, payload_type,
+ SDP_RTCP_FB_REMB,
+ 1); // always check for 1st instance
+ return (attr_p? TRUE : FALSE); // either exists or not
+}
+
+/* Function: sdp_attr_get_rtcp_fb_transport_cc_enabled
+ * Description: Returns true if rtcp-fb:...transport-cc attribute exists
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * payload_type The payload to get the attribute for
+ * Returns: true if rtcp-fb:...transport-cc exists
+ */
+tinybool
+sdp_attr_get_rtcp_fb_transport_cc_enabled(sdp_t *sdp_p,
+ uint16_t level,
+ uint16_t payload_type)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_rtcp_fb_attr(sdp_p, level, payload_type,
+ SDP_RTCP_FB_TRANSPORT_CC,
+ 1); // always check for 1st instance
+ return (attr_p? TRUE : FALSE); // either exists or not
+}
+
+/* Function: sdp_attr_get_rtcp_fb_ccm
+ * Description: Returns the value of the rtcp-fb:...ccm attribute
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * payload_type The payload to get the attribute for
+ * inst_num The attribute instance number to check.
+ * Returns: CCM type (SDP_RTCP_FB_CCM_NOT_FOUND if not present)
+ */
+sdp_rtcp_fb_ccm_type_e
+sdp_attr_get_rtcp_fb_ccm(sdp_t *sdp_p, uint16_t level, uint16_t payload_type, uint16_t inst)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_rtcp_fb_attr(sdp_p, level, payload_type,
+ SDP_RTCP_FB_CCM, inst);
+ if (!attr_p) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s rtcp-fb attribute, level %u, pt %u, "
+ "instance %u not found.", sdp_p->debug_str, (unsigned)level,
+ (unsigned)payload_type, (unsigned)inst);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return SDP_RTCP_FB_CCM_NOT_FOUND;
+ }
+ return (attr_p->attr.rtcp_fb.param.ccm);
+}
+
+/* Function: sdp_attr_set_rtcp_fb_ack
+ * Description: Sets the value of an rtcp-fb:...ack attribute
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to set the attribute.
+ * payload_type The value to set the payload type to for
+ * this attribute. Can be SDP_ALL_PAYLOADS.
+ * inst_num The attribute instance number to check.
+ * type The ack type to indicate
+ * Returns: SDP_SUCCESS Attribute param was set successfully.
+ * SDP_INVALID_PARAMETER Specified attribute is not defined.
+ */
+sdp_result_e
+sdp_attr_set_rtcp_fb_ack(sdp_t *sdp_p, uint16_t level, uint16_t payload_type, uint16_t inst,
+ sdp_rtcp_fb_ack_type_e type)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, inst);
+ if (!attr_p) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s rtcp_fb ack attribute, level %u "
+ "instance %u not found.", sdp_p->debug_str, (unsigned)level,
+ (unsigned)inst);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+
+ attr_p->attr.rtcp_fb.payload_num = payload_type;
+ attr_p->attr.rtcp_fb.feedback_type = SDP_RTCP_FB_ACK;
+ attr_p->attr.rtcp_fb.param.ack = type;
+ attr_p->attr.rtcp_fb.extra[0] = '\0';
+ return (SDP_SUCCESS);
+}
+
+
+/* Function: sdp_attr_set_rtcp_fb_nack
+ * Description: Sets the value of an rtcp-fb:...nack attribute
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to set the attribute.
+ * payload_type The value to set the payload type to for
+ * this attribute. Can be SDP_ALL_PAYLOADS.
+ * inst_num The attribute instance number to check.
+ * type The nack type to indicate
+ * Returns: SDP_SUCCESS Attribute param was set successfully.
+ * SDP_INVALID_PARAMETER Specified attribute is not defined.
+ */
+sdp_result_e
+sdp_attr_set_rtcp_fb_nack(sdp_t *sdp_p, uint16_t level, uint16_t payload_type, uint16_t inst,
+ sdp_rtcp_fb_nack_type_e type)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, inst);
+ if (!attr_p) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s rtcp_fb nack attribute, level %u "
+ "instance %u not found.", sdp_p->debug_str, (unsigned)level,
+ (unsigned)inst);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+
+ attr_p->attr.rtcp_fb.payload_num = payload_type;
+ attr_p->attr.rtcp_fb.feedback_type = SDP_RTCP_FB_NACK;
+ attr_p->attr.rtcp_fb.param.nack = type;
+ attr_p->attr.rtcp_fb.extra[0] = '\0';
+ return (SDP_SUCCESS);
+}
+
+/* Function: sdp_attr_set_rtcp_fb_trr_int
+ * Description: Sets the value of an rtcp-fb:...trr-int attribute
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to set the attribute.
+ * payload_type The value to set the payload type to for
+ * this attribute. Can be SDP_ALL_PAYLOADS.
+ * inst_num The attribute instance number to check.
+ * interval The interval time to indicate
+ * Returns: SDP_SUCCESS Attribute param was set successfully.
+ * SDP_INVALID_PARAMETER Specified attribute is not defined.
+ */
+sdp_result_e
+sdp_attr_set_rtcp_fb_trr_int(sdp_t *sdp_p, uint16_t level, uint16_t payload_type,
+ uint16_t inst, uint32_t interval)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, inst);
+ if (!attr_p) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s rtcp_fb trr-int attribute, level %u "
+ "instance %u not found.", sdp_p->debug_str, (unsigned)level,
+ (unsigned)inst);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+
+ attr_p->attr.rtcp_fb.payload_num = payload_type;
+ attr_p->attr.rtcp_fb.feedback_type = SDP_RTCP_FB_TRR_INT;
+ attr_p->attr.rtcp_fb.param.trr_int = interval;
+ attr_p->attr.rtcp_fb.extra[0] = '\0';
+ return (SDP_SUCCESS);
+}
+
+/* Function: sdp_attr_set_rtcp_fb_remb
+ * Description: Sets the value of an rtcp-fb:...goog-remb attribute
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to set the attribute.
+ * payload_type The value to set the payload type to for
+ * this attribute. Can be SDP_ALL_PAYLOADS.
+ * inst_num The attribute instance number to check.
+ * Returns: SDP_SUCCESS Attribute param was set successfully.
+ * SDP_INVALID_PARAMETER Specified attribute is not defined.
+ */
+sdp_result_e
+sdp_attr_set_rtcp_fb_remb(sdp_t *sdp_p, uint16_t level, uint16_t payload_type,
+ uint16_t inst)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, inst);
+ if (!attr_p) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s rtcp_fb goog-remb attribute, level %u "
+ "instance %u not found.", sdp_p->debug_str, (unsigned)level,
+ (unsigned)inst);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+
+ attr_p->attr.rtcp_fb.payload_num = payload_type;
+ attr_p->attr.rtcp_fb.feedback_type = SDP_RTCP_FB_REMB;
+ return (SDP_SUCCESS);
+}
+
+/* Function: sdp_attr_set_rtcp_fb_transport_cc
+ * Description: Sets the value of an rtcp-fb:...transport-cc attribute
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to set the attribute.
+ * payload_type The value to set the payload type to for
+ * this attribute. Can be SDP_ALL_PAYLOADS.
+ * inst_num The attribute instance number to check.
+ * Returns: SDP_SUCCESS Attribute param was set successfully.
+ * SDP_INVALID_PARAMETER Specified attribute is not defined.
+ */
+sdp_result_e
+sdp_attr_set_rtcp_fb_transport_cc(sdp_t *sdp_p, uint16_t level, uint16_t payload_type,
+ uint16_t inst)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, inst);
+ if (!attr_p) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s rtcp_fb transport-cc attribute, level %u "
+ "instance %u not found.", sdp_p->debug_str, (unsigned)level,
+ (unsigned)inst);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+
+ attr_p->attr.rtcp_fb.payload_num = payload_type;
+ attr_p->attr.rtcp_fb.feedback_type = SDP_RTCP_FB_TRANSPORT_CC;
+ return (SDP_SUCCESS);
+}
+
+/* Function: sdp_attr_set_rtcp_fb_ccm
+ * Description: Sets the value of an rtcp-fb:...ccm attribute
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to set the attribute.
+ * payload_type The value to set the payload type to for
+ * this attribute. Can be SDP_ALL_PAYLOADS.
+ * inst_num The attribute instance number to check.
+ * type The ccm type to indicate
+ * Returns: SDP_SUCCESS Attribute param was set successfully.
+ * SDP_INVALID_PARAMETER Specified attribute is not defined.
+ */
+sdp_result_e
+sdp_attr_set_rtcp_fb_ccm(sdp_t *sdp_p, uint16_t level, uint16_t payload_type, uint16_t inst,
+ sdp_rtcp_fb_ccm_type_e type)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, inst);
+ if (!attr_p) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s rtcp_fb ccm attribute, level %u "
+ "instance %u not found.", sdp_p->debug_str, (unsigned)level,
+ (unsigned)inst);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+ attr_p->attr.rtcp_fb.payload_num = payload_type;
+ attr_p->attr.rtcp_fb.feedback_type = SDP_RTCP_FB_CCM;
+ attr_p->attr.rtcp_fb.param.ccm = type;
+ attr_p->attr.rtcp_fb.extra[0] = '\0';
+ return (SDP_SUCCESS);
+}
+
+/* Function: sdp_attr_get_extmap_uri
+ * Description: Returns a pointer to the value of the encoding name
+ * parameter specified for the given attribute. Value is
+ * returned as a const ptr and so cannot be modified by the
+ * application. If the given attribute is not defined, NULL
+ * will be returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * inst_num The attribute instance number to check.
+ * Returns: Codec value or SDP_CODEC_INVALID.
+ */
+const char *sdp_attr_get_extmap_uri(sdp_t *sdp_p, uint16_t level,
+ uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_EXTMAP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s extmap attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (NULL);
+ } else {
+ return (attr_p->attr.extmap.uri);
+ }
+}
+
+/* Function: sdp_attr_get_extmap_id
+ * Description: Returns the id of the extmap specified for the given
+ * attribute. If the given attribute is not defined, 0xFFFF
+ * will be returned.
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to check for the attribute.
+ * inst_num The attribute instance number to check.
+ * Returns: The id of the extmap attribute.
+ */
+uint16_t sdp_attr_get_extmap_id(sdp_t *sdp_p, uint16_t level,
+ uint16_t inst_num)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_EXTMAP, inst_num);
+ if (attr_p == NULL) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s extmap attribute, level %u instance %u "
+ "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return 0xFFFF;
+ } else {
+ return (attr_p->attr.extmap.id);
+ }
+}
+
+/* Function: sdp_attr_set_extmap
+ * Description: Sets the value of an rtcp-fb:...ccm attribute
+ * Parameters: sdp_p The SDP handle returned by sdp_init_description.
+ * level The level to set the attribute.
+ * id The id to set the attribute.
+ * uri The uri to set the attribute.
+ * inst The attribute instance number to check.
+ * Returns: SDP_SUCCESS Attribute param was set successfully.
+ * SDP_INVALID_PARAMETER Specified attribute is not defined.
+ */
+sdp_result_e
+sdp_attr_set_extmap(sdp_t *sdp_p, uint16_t level, uint16_t id, const char* uri, uint16_t inst)
+{
+ sdp_attr_t *attr_p;
+
+ attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_EXTMAP, inst);
+ if (!attr_p) {
+ if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
+ SDPLogError(logTag, "%s extmap attribute, level %u "
+ "instance %u not found.", sdp_p->debug_str, (unsigned)level,
+ (unsigned)inst);
+ }
+ sdp_p->conf_p->num_invalid_param++;
+ return (SDP_INVALID_PARAMETER);
+ }
+
+ attr_p->attr.extmap.id = id;
+ sstrncpy(attr_p->attr.extmap.uri, uri, SDP_MAX_STRING_LEN+1);
+ return (SDP_SUCCESS);
+}
+
+const char *sdp_attr_get_msid_identifier(sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst)
+{
+ sdp_attr_t *attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_MSID, inst);
+ if (!attr_p) {
+ return NULL;
+ }
+ return attr_p->attr.msid.identifier;
+}
+
+const char *sdp_attr_get_msid_appdata(sdp_t *sdp_p, uint16_t level,
+ uint8_t cap_num, uint16_t inst)
+{
+ sdp_attr_t *attr_p = sdp_find_attr(sdp_p, level, cap_num,
+ SDP_ATTR_MSID, inst);
+ if (!attr_p) {
+ return NULL;
+ }
+ return attr_p->attr.msid.appdata;
+}