示例#1
0
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;
}
示例#2
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;
}
示例#3
0
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;
}