int sdp_message_a_attribute_del_at_index (sdp_message_t * sdp, int pos_media, char *att_field, int pos_attr) { int i; sdp_media_t *med; sdp_attribute_t *attr; if (sdp == NULL) return -1; if ((pos_media != -1) && (osip_list_size (&sdp->m_medias) < pos_media + 1)) return -1; if (pos_media == -1) { if (pos_attr == -1) { for (i = 0; i < osip_list_size (&sdp->a_attributes);) { attr = osip_list_get (&sdp->a_attributes, i); if (strcmp (attr->a_att_field, att_field) == 0) { osip_list_remove (&sdp->a_attributes, i); sdp_attribute_free (attr); } else i++; } } else if ((attr = osip_list_get (&sdp->a_attributes, pos_attr)) != NULL) { osip_list_remove (&sdp->a_attributes, pos_attr); sdp_attribute_free (attr); } return 0; } med = (sdp_media_t *) osip_list_get (&sdp->m_medias, pos_media); if (med == NULL) return -1; for (i = 0; i < osip_list_size (&med->a_attributes);) { if (pos_attr == -1) { attr = osip_list_get (&med->a_attributes, i); if (strcmp (attr->a_att_field, att_field) == 0) { osip_list_remove (&med->a_attributes, i); sdp_attribute_free (attr); } else i++; } else if ((attr = osip_list_get (&med->a_attributes, pos_attr)) != NULL) { osip_list_remove (&med->a_attributes, pos_attr); sdp_attribute_free (attr); } } return 0; }
int sdp_message_a_attribute_del (sdp_message_t * sdp, int pos_media, char *att_field) { int i; sdp_media_t *med; sdp_attribute_t *attr; if (sdp == NULL) return OSIP_BADPARAMETER; if ((pos_media != -1) && (osip_list_size (&sdp->m_medias) < pos_media + 1)) return OSIP_UNDEFINED_ERROR; if (pos_media == -1) { for (i = 0; i < osip_list_size (&sdp->a_attributes);) { attr = osip_list_get (&sdp->a_attributes, i); if (strcmp (attr->a_att_field, att_field) == 0) { osip_list_remove (&sdp->a_attributes, i); sdp_attribute_free (attr); } else i++; } return OSIP_SUCCESS; } med = (sdp_media_t *) osip_list_get (&sdp->m_medias, pos_media); if (med == NULL) return OSIP_UNDEFINED_ERROR; for (i = 0; i < osip_list_size (&med->a_attributes);) { attr = osip_list_get (&med->a_attributes, i); if (strcmp (attr->a_att_field, att_field) == 0) { osip_list_remove (&med->a_attributes, i); sdp_attribute_free (attr); } else i++; } return OSIP_SUCCESS; }
static int sdp_message_parse_a (sdp_message_t * sdp, char *buf, char **next) { char *equal; char *crlf; char *tmp; char *tmp_next; int i; sdp_attribute_t *a_attribute; char *colon; *next = buf; equal = buf; while ((*equal != '=') && (*equal != '\0')) equal++; if (*equal == '\0') return ERR_ERROR; /* check if header is "a" */ if (equal[-1] != 'a') return ERR_DISCARD; crlf = equal + 1; while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) crlf++; if (*crlf == '\0') return ERR_ERROR; if (crlf == equal + 1) return ERR_ERROR; /* a=\r ?? bad header */ tmp = equal + 1; i = sdp_attribute_init (&a_attribute); if (i != 0) return ERR_ERROR; /* a=att-field[:att-value] */ /* is there any att-value? */ colon = strchr (equal + 1, ':'); if ((colon != NULL) && (colon < crlf)) { /* att-field is alpha-numeric */ i = __osip_set_next_token (&(a_attribute->a_att_field), tmp, ':', &tmp_next); if (i != 0) { sdp_attribute_free (a_attribute); return -1; } tmp = tmp_next; i = __osip_set_next_token (&(a_attribute->a_att_value), tmp, '\r', &tmp_next); if (i != 0) { i = __osip_set_next_token (&(a_attribute->a_att_value), tmp, '\n', &tmp_next); if (i != 0) { sdp_attribute_free (a_attribute); return -1; } } } else { i = __osip_set_next_token (&(a_attribute->a_att_field), tmp, '\r', &tmp_next); if (i != 0) { i = __osip_set_next_token (&(a_attribute->a_att_field), tmp, '\n', &tmp_next); if (i != 0) { sdp_attribute_free (a_attribute); return -1; } } } /* add the attribute at the correct place: if there is no media line yet, then the "a=" is the global one. */ i = osip_list_size (sdp->m_medias); if (i == 0) osip_list_add (sdp->a_attributes, a_attribute, -1); else { sdp_media_t *last_sdp_media = (sdp_media_t *) osip_list_get (sdp->m_medias, i - 1); osip_list_add (last_sdp_media->a_attributes, a_attribute, -1); } if (crlf[1] == '\n') *next = crlf + 2; else *next = crlf + 1; return WF; }
/*--------------------------------------------------------------------*/ static int sdp_filter_codec(sdp_message_t *sdp) { int sts; int i; char *sdp_media; int media_stream_no; // SDP payload list processing char *payload; int payload_mediatype; int payload_no; // SDP attribute list processing sdp_attribute_t *sdp_attr; int attr_mediatype; int media_attr_no; int skip_media_attr_inc=0; // // loop through all media descriptions (normal phone call has 1 stream, a video call // may have multiple streams) // media_stream_no=0; while ((sdp_media=sdp_message_m_media_get(sdp, media_stream_no))) { // // loop through all media attributes of this media stream // media_attr_no=0; while ((sdp_attr=sdp_message_attribute_get(sdp, media_stream_no, media_attr_no))) { DEBUGC(DBCLASS_PLUGIN, " +--Attr m:%i, a=%i", media_stream_no, media_attr_no); // check if attribute field and value exist if (sdp_attr->a_att_field && sdp_attr->a_att_value) { // fetch the media type value (first number field in value) attr_mediatype=0; sts=sscanf(sdp_attr->a_att_value, "%i", &attr_mediatype); DEBUGC(DBCLASS_PLUGIN, " +--Attr field=%s, val=%s [MT=%i]", sdp_attr->a_att_field, sdp_attr->a_att_value, attr_mediatype); // // loop through all configured "blacklisted" media strings // and look for a match // for (i=0; i<plugin_cfg.codec_blacklist.used; i++) { // do an *case-insensitive* *substring* match if (strcasestr(sdp_attr->a_att_value, plugin_cfg.codec_blacklist.string[i])) { // match, need to remove this codec DEBUGC(DBCLASS_PLUGIN, "%s: blacklisted - removing media attr [%s] at attrpos=%i", name, sdp_attr->a_att_value, media_attr_no); // // remove media attribute (a) // // libosip bug?? -> the following coda causes an infinite loop inside libosip2. //if (sdp_message_a_attribute_del_at_index(sdp, media_stream_no, sdp_attr->a_att_field, media_attr_no) != OSIP_SUCCESS) { // ERROR("%s: sdp_message_a_attribute_del() failed", name); //} // #&%+!@ -> So it manually... { sdp_media_t *med; sdp_attribute_t *attr; med = (sdp_media_t *) osip_list_get(&sdp->m_medias, media_stream_no); if ((attr = osip_list_get(&med->a_attributes, media_attr_no)) != NULL) { osip_list_remove(&med->a_attributes, media_attr_no); sdp_attribute_free(attr); attr=NULL; // as I have removed the current attribute, all other // attributes are shifted one down, so for the next iteration // I must not increment the index or I will skip one attribute skip_media_attr_inc=1; } } // // find corresponding (m) payload and remove it as well$ // // loop through all payloads of the current media description payload_no=0; while ((payload=sdp_message_m_payload_get(sdp, media_stream_no, payload_no))) { // extract the media type from the payload payload_mediatype=0; sts=sscanf(payload, "%i", &payload_mediatype); DEBUGC(DBCLASS_PLUGIN, " +-- payload:%s MT=%i", payload, payload_mediatype); // medfia type matches? if (payload_mediatype == attr_mediatype) { DEBUGC(DBCLASS_PLUGIN, "%s: blacklisted - removing media format %i at stream=%i, pos=%i", name, payload_mediatype, media_stream_no, payload_no); // remove (m) playload in media description if (sdp_message_m_payload_del(sdp, media_stream_no, payload_no) != OSIP_SUCCESS) { ERROR("%s: sdp_message_a_attribute_del() failed", name); } } else { // increment index only if the current payload has not been removed // as all other medias would have shifted down. payload_no++; } } /* while playload */ } /* if match with config blacklist */ } /* for codec_blacklist */ } /* if attribute field and value exist */ // increment index only of the current media attribute has not been deleted if (skip_media_attr_inc == 0) { media_attr_no++; } else { skip_media_attr_inc=0; } } /* while sdp_message_attribute_get */ media_stream_no++; } /* while sdp_message_m_media_get */ return STS_SUCCESS; }