void
osip_negotiation_ctx_free (osip_negotiation_ctx_t * con)
{
  if (con == NULL)
    return;
  sdp_message_free (con->remote);
  sdp_message_free (con->local);
  osip_free (con);
}
Exemple #2
0
void sdp_context_free(sdp_context_t *ctx){
	osip_free(ctx->localip);
	osip_free(ctx->username);
	if (ctx->offer!=NULL) sdp_message_free(ctx->offer);
	if (ctx->answer!=NULL) sdp_message_free(ctx->answer);
	if (ctx->offerstr!=NULL) osip_free(ctx->offerstr);
	if (ctx->answerstr!=NULL) osip_free(ctx->answerstr);
	if (ctx->relay!=NULL) osip_free(ctx->relay);
	if (ctx->relay_session_id!=NULL) osip_free(ctx->relay_session_id);
	osip_free(ctx);
}
int
sdp_message_clone (sdp_message_t * sdp, sdp_message_t ** dest)
{
  int i;
  char *body;

  i = sdp_message_init (dest);
  if (i != 0)
    return -1;

  i = sdp_message_to_str (sdp, &body);
  if (i != 0)
    goto error_sc1;

  i = sdp_message_parse (*dest, body);
  osip_free (body);
  if (i != 0)
    goto error_sc1;

  return 0;

error_sc1:
  sdp_message_free (*dest);
  return -1;
}
Exemple #4
0
static __inline__ void
rtsp_method_do_desc(rtsp_client *rc, rtsp_message *req, media *media)
{
	RTSP_STATUS_CODE rsc;
	rtsp_message *res;
	int32_t err, sdp_size;
	media_info mi;
	sdp_message *sdp = NULL;
	char *content_base = NULL;
	uint8_t *sdp_buf;
	uint32_t cb_size;

	err = media_info_get(media, &mi);
	if (!err)
	{
		content_base = rtsp_method_get_content_base(req, &cb_size);
		if (!content_base)
		{
			LOG_W(
				"rtsp_method_do_desc()->rtsp_method_get_content_base() failed."
			);
			err = -EINVAL;
			goto desc_err;
		}

		sdp = rtsp_method_mi_to_sdp(&mi);
		sdp_buf = (uint8_t*)rtsp_mem_alloc(MAX_RTSP_BUF_SIZE);
		sdp_size = sdp_message_as_text(sdp, (char*)sdp_buf, MAX_RTSP_BUF_SIZE);
		sdp_message_free(sdp);
		if (sdp_size < 0 || sdp_size >= MAX_RTSP_BUF_SIZE)
		{
			LOG_W(
				"rtsp_method_do_desc()->sdp_message_as_text() failed."
			);
			tr_free(content_base, cb_size);
			err = -EINVAL;
			goto desc_err;
		}

		media_info_clear(&mi);
		res = rtsp_impl_new_generic_response(req, RTSP_STS_OK);
		rtsp_message_take_body(res, sdp_buf, sdp_size);
		rtsp_message_add_header(res, RTSP_HDR_CONTENT_TYPE, "application/sdp");
		rtsp_message_add_header(res, RTSP_HDR_CONTENT_BASE, content_base);
		tr_free(content_base, cb_size);
		rtsp_impl_send_message(rc, res);
		return;
	}

desc_err:
	media_info_clear(&mi);
	rsc = rtsp_impl_trans_status_code(TR_RTSP_DESC, err);
	res = rtsp_impl_new_generic_response(req, rsc);
	rtsp_impl_send_message(rc, res);
}
Exemple #5
0
static int		sip_get_address(osip_message_t *msg, u_int *host, u_short *port)
{
  osip_content_type_t	*ctt;
  sdp_message_t		*sdp;
  char			*tmp;
  int			i;
  int			j;

  if (NULL == (ctt = osip_message_get_content_type(msg)))
    return 0;
  if ((NULL == ctt->type) || (NULL == ctt->subtype))
    return 0;
  if (osip_strcasecmp(ctt->type, "application"))
    return 0;
  if (osip_strcasecmp(ctt->subtype, "sdp"))
    return 0;
  for (i = 0; !osip_list_eol(msg->bodies, i); ++i) {
    sdp = NULL;
    sdp_message_init(&sdp);
    tmp = ((osip_body_t *)osip_list_get(msg->bodies, i))->body;
    if (sdp_message_parse(sdp, tmp)) {
      sdp_message_free(sdp);
      continue;
    }
    for (j = 0; NULL != sdp_message_m_media_get(sdp, j); ++j) {
      if (NULL == (tmp = sdp_message_m_port_get(sdp, j)))
	continue;
      *port = atoi(tmp);
      if (NULL == (tmp = sdp_message_c_addr_get(sdp, -1, 0)))
	if (NULL == (tmp = sdp_message_c_addr_get(sdp, j, 0)))
	  continue;
      *host = (u_int)inet_addr(tmp);
      sdp_message_free(sdp);
      return 1;
    }
    sdp_message_free(sdp);
  }
  return 0;
}
Exemple #6
0
void free_args(arguments_t *a) {

  if(a == NULL) {
    return;
  }

  if(a->log_fd != -1) {
    close(a->log_fd);
  }

  if(strcmp(a->sdp_file, "") != 0) {
    sf_free(a->src_filt);
    free(a->src_filt);
    sdp_message_free(a->sdp);
  }
}
sdp_message_t *
eXosip_get_sdp_info (osip_message_t * message)
{
  osip_content_type_t *ctt;
  sdp_message_t *sdp;
  osip_body_t *oldbody;
  int pos;

  if (message == NULL)
    return NULL;

  /* get content-type info */
  ctt = osip_message_get_content_type (message);
  if (ctt == NULL)
    return NULL;                /* previous message was not correct or empty */

  if (ctt->type == NULL || ctt->subtype == NULL)
    return NULL;
  if (osip_strcasecmp (ctt->type, "multipart") == 0)
    {
      /* probably within the multipart attachement */
  } else if (osip_strcasecmp (ctt->type, "application") != 0 ||
             osip_strcasecmp (ctt->subtype, "sdp") != 0)
    return NULL;

  pos = 0;
  while (!osip_list_eol (&message->bodies, pos))
    {
      int i;

      oldbody = (osip_body_t *) osip_list_get (&message->bodies, pos);
      pos++;
      sdp_message_init (&sdp);
      i = sdp_message_parse (sdp, oldbody->body);
      if (i == 0)
        return sdp;
      sdp_message_free (sdp);
      sdp = NULL;
    }
  return NULL;
}
Exemple #8
0
/* Get SIP message of the call leg */
sdp_message_t *eXosipua_extract_sdp_message(eXosipua_t *jua, eXosip_event_t *je)
{
   sdp_message_t *sdp;

   if(!je->sdp_body || !je->sdp_body[0] || sdp_message_init(&sdp) != 0)
   {
      jua_debug(("eXosipua_extract_message: no sdp body\n"));
      return NULL;
   }

   jua_debug(("eXosipua_extract_message: sdp body\n"));
   jua_debug(("%s", je->sdp_body));

   if(sdp_message_parse(sdp, je->sdp_body) != 0)
   {
      sdp_message_free(sdp);
      return NULL;
   }

   return sdp;
}
int client_sipua_event(void* lisener, sipua_event_t* e)
{
	sipua_t *sipua = (sipua_t*)lisener;

	ogmp_client_t *client = (ogmp_client_t*)lisener;

	sipua_set_t *call_info = e->call_info;

	switch(e->type)
	{
		case(SIPUA_EVENT_REGISTRATION_SUCCEEDED):
		case(SIPUA_EVENT_UNREGISTRATION_SUCCEEDED):
		{
			sipua_reg_event_t *reg_e = (sipua_reg_event_t*)e;
			user_profile_t* user_prof = client->reg_profile;

            if(user_prof == NULL)
                break;
                
            if(user_prof->reg_reason_phrase)
            {
                xfree(user_prof->reg_reason_phrase);
                user_prof->reg_reason_phrase = NULL;
            }
            
            if(reg_e->server_info)
                user_prof->reg_reason_phrase = xstr_clone(reg_e->server_info);

            if(user_prof->reg_status == SIPUA_STATUS_REG_DOING)
			{
				user_prof->reg_server = xstr_clone(reg_e->server);

				client->user_prof = client->reg_profile;

				user_prof->reg_status = SIPUA_STATUS_REG_OK;
			}

			if(user_prof->reg_status == SIPUA_STATUS_UNREG_DOING)
            {
                xstr_done_string(user_prof->reg_server);
                user_prof->reg_server = NULL;

				user_prof->reg_status = SIPUA_STATUS_NORMAL;
            }

			/* registering transaction completed */
            client->reg_profile = NULL;

            client->ui->beep(client->ui);

			break;
		}
		case(SIPUA_EVENT_REGISTRATION_FAILURE):
		case(SIPUA_EVENT_UNREGISTRATION_FAILURE):
		{
			char buf[100];

			sipua_reg_event_t *reg_e = (sipua_reg_event_t*)e;
			user_profile_t* user_prof = client->reg_profile;

            if(!user_prof)
                break;
                
            snprintf(buf, 99, "Register %s Error[%i]: %s",
					reg_e->server, reg_e->status_code, reg_e->server_info);

			clie_log(("client_sipua_event: %s\n", buf));

			user_prof->reg_status = SIPUA_STATUS_REG_FAIL;

			if(user_prof->reg_reason_phrase) 
				xfree(user_prof->reg_reason_phrase);
                
			user_prof->reg_reason_phrase = xstr_clone(reg_e->server_info);

			/* registering transaction completed */
			client->reg_profile = NULL;

			break;

		}
		case(SIPUA_EVENT_NEW_CALL):
		{
			/* Callee receive a new call, now in negotiation stage */
			int i;
			sipua_call_event_t *call_e = (sipua_call_event_t*)e;
			sipua_set_t *call;

			int lineno = e->lineno;

			rtpcap_set_t* rtpcapset;

			sdp_message_t *sdp_message;
			char* sdp_body = (char*)e->content;

			sdp_message_init(&sdp_message);

			if (sdp_message_parse(sdp_message, sdp_body) != 0)
			{
				clie_log(("\nsipua_event: fail to parse sdp\n"));
				sdp_message_free(sdp_message);
				
				return UA_FAIL;
			}

			rtpcapset = rtp_capable_from_sdp(sdp_message);

			/* now to negotiate call, which will generate call structure with sdp message for reply
			 * still no rtp session created !
			 */
			call = sipua_negotiate_call(sipua, client->user_prof, rtpcapset,
							client->mediatypes, client->default_rtp_ports, 
							client->default_rtcp_ports, client->nmedia,
							client->control);
			
			if(!call)
			{
				/* Fail to receive the call, miss it */
				break;
			}

			call_info->cid = call_e->cid;
			call_info->did = call_e->did;
			call_info->rtpcapset = rtpcapset;

			for(i=0; i<MAX_SIPUA_LINES; i++)
			{
				if(client->lines[i] == NULL)
				{
					client->lines[i] = call;
					sipua->uas->accept(sipua->uas, lineno);

					break;
				}
			}

			sdp_message_free(sdp_message);

			break;
		}
		case(SIPUA_EVENT_PROCEEDING):
		{
			break;
		}
		case(SIPUA_EVENT_RINGING):
		{	
			break;
		}
		case(SIPUA_EVENT_ANSWERED):
		{
			/* Caller establishs call when callee is answered */
			sipua_set_t *call = e->call_info; 
            /*
            sipua_call_event_t *call_e = (sipua_call_event_t*)e;
            */
			rtpcap_set_t* rtpcapset;

			sdp_message_t *sdp_message;
			char* sdp_body = (char*)e->content;

			sdp_message_init(&sdp_message);

			if (sdp_message_parse(sdp_message, sdp_body) != 0)
			{
				clie_log(("\nsipua_event: fail to parse sdp\n"));
				sdp_message_free(sdp_message);
				
				break;
			}

			rtpcapset = rtp_capable_from_sdp(sdp_message);

			/* rtp sessions created */
			sipua_establish_call(sipua, call, "playback", rtpcapset, client->format_handlers, client->control, client->pt);

			rtp_capable_done_set(rtpcapset);
			sdp_message_free(sdp_message);

			break;
		}
		case(SIPUA_EVENT_ACK):
		{
			/* Callee establishs call after its answer is acked
			sipua_set_t *call = e->call_info; */

			/* rtp sessions created */
			sipua_establish_call(sipua, e->call_info, "playback", e->call_info->rtpcapset, client->format_handlers, client->control, client->pt);

			rtp_capable_done_set(e->call_info->rtpcapset);
			e->call_info->rtpcapset = NULL;

			break;
		}
	}

	return UA_OK;
}
int
osip_negotiation_ctx_execute_negotiation (osip_negotiation_t * config,
					  osip_negotiation_ctx_t * context)
{
  int m_lines_that_match = 0;
  sdp_message_t *remote;
  sdp_message_t *local;
  int i;

  if (context == NULL)
    return -1;
  remote = context->remote;
  if (remote == NULL)
    return -1;

  i = sdp_message_init (&local);
  if (i != 0)
    return -1;

  if (0 != strncmp (remote->v_version, "0", 1))
    {
      sdp_message_free (local);
      /*      sdp_context->fcn_wrong_version(context); */
      return 406;		/* Not Acceptable */
    }

  i = sdp_partial_clone (config, context, remote, &local);
  if (i != 0)
    {
      sdp_message_free (local);
      return -1;
    }
  i = sdp_confirm_media (config, context, remote, &local);
  if (i != 0)
    {
      sdp_message_free (local);
      return i;
    }

  i = 0;
  while (!sdp_message_endof_media (local, i))
    {
      /* this is to refuse each line with no codec that matches! */
      if (NULL == sdp_message_m_payload_get (local, i, 0))
	{
	  sdp_media_t *med = osip_list_get ((local)->m_medias, i);
	  char *str = sdp_message_m_payload_get (remote, i, 0);

	  sdp_message_m_payload_add (local, i, osip_strdup (str));
	  osip_free (med->m_port);
	  med->m_port = osip_strdup ("0");	/* refuse this line */
	}
      else
	{			/* number of "m" lines that match */
	  sdp_media_t *med = osip_list_get (local->m_medias, i);

	  m_lines_that_match++;
	  osip_free (med->m_port);
	  /* AMD: use the correct fcn_get_xxx_port method: */
	  if (0 == strcmp (med->m_media, "audio"))
	    {
	      if (config->fcn_get_audio_port != NULL)
		med->m_port = config->fcn_get_audio_port (context, i);
	      else
		med->m_port = osip_strdup ("0");	/* should never happen */
	    }
	  else if (0 == strcmp (med->m_media, "video"))
	    {
	      if (config->fcn_get_video_port != NULL)
		med->m_port = config->fcn_get_video_port (context, i);
	      else
		med->m_port = osip_strdup ("0");	/* should never happen */
	    }
	  else
	    {
	      if (config->fcn_get_other_port != NULL)
		med->m_port = config->fcn_get_other_port (context, i);
	      else
		med->m_port = osip_strdup ("0");	/* should never happen */
	    }
	}
      i++;
    }
  if (m_lines_that_match > 0)
    {
      context->local = local;
      return 200;
    }
  else
    {
      sdp_message_free (local);
      return 415;
    }

}
Exemple #11
0
char *
sdp_context_get_answer ( sdp_context_t *ctx,sdp_message_t *remote)
{
	sdp_message_t *answer=NULL;
	char *mtype=NULL, *tmp=NULL;
	char *proto=NULL, *port=NULL, *pt=NULL;
	int i, j, ncodec, m_lines_accepted = 0;
	int err;
	sdp_payload_t payload;
	sdp_handler_t *sdph=ctx->handler;
	sdp_bandwidth_t *sbw=NULL;
	char *relay;

	tmp = sdp_message_c_addr_get (remote, 0, 0);
	if (tmp == NULL)
	  tmp = sdp_message_c_addr_get (remote, -1, 0);
	if (ctx->localip==NULL) {
		/* NULL means guess, otherwise we use the address given as localip */
		ctx->localip=osip_malloc(128);
		eXosip_guess_localip(strchr(tmp,':') ?  AF_INET6 : AF_INET,ctx->localip,128);
	}
	else eXosip_trace(OSIP_INFO1,("Using firewall address in sdp."));

	answer = sdp_context_generate_template (ctx);
	
	/* for each m= line */
	for (i = 0; !sdp_message_endof_media (remote, i); i++)
	{
		sdp_payload_init(&payload);
		mtype = sdp_message_m_media_get (remote, i);
		proto = sdp_message_m_proto_get (remote, i);
		port = sdp_message_m_port_get (remote, i);
		payload.remoteport = osip_atoi (port);
		payload.proto = proto;
		payload.line = i;
		payload.c_addr = sdp_message_c_addr_get (remote, i, 0);
		if (payload.c_addr == NULL)
			payload.c_addr = sdp_message_c_addr_get (remote, -1, 0);
		/*parse relay address if given*/
		relay=sdp_message_a_attr_value_get(remote,i,"relay-addr");
		if (relay){
			payload.relay_host=parse_relay_addr(relay,&payload.relay_port);
		}
		payload.relay_session_id=sdp_message_a_attr_value_get(remote,i,"relay-session-id");
		/* get application specific bandwidth, if any */
		for(j=0;(sbw=sdp_message_bandwidth_get(remote,i,j))!=NULL;j++){
			if (strcasecmp(sbw->b_bwtype,"AS")==0) payload.b_as_bandwidth=atoi(sbw->b_bandwidth);
		}
		payload.a_ptime=_sdp_message_get_a_ptime(remote,i);
		if (keywordcmp ("audio", mtype) == 0)
		{
			if (sdph->accept_audio_codecs != NULL)
			{
				ncodec = 0;
				/* for each payload type */
				for (j = 0;
				     ((pt =
				       sdp_message_m_payload_get (remote, i,
							  j)) != NULL); j++)
				{
					payload.pt = osip_atoi (pt);
					/* get the rtpmap associated to this codec, if any */
					payload.a_rtpmap =
						sdp_message_a_attr_value_get_with_pt
						(remote, i, payload.pt,
						 "rtpmap");
					/* get the fmtp, if any */
					payload.a_fmtp =
						sdp_message_a_attr_value_get_with_pt
						(remote, i, payload.pt,
						 "fmtp");
					
					/* ask the application if this codec is supported */
					err = sdph->accept_audio_codecs (ctx,
									 &payload);
					if (err == 0 && payload.localport > 0)
					{
						ncodec++;
						/* codec accepted */
						if (ncodec == 1)
						{
							/* first codec accepted, setup the line  */
							sdp_message_m_media_add
								(answer,
								 osip_strdup
								 (mtype),
								 int_2char
								 (payload.
								  localport),
								 NULL,
								 osip_strdup
								 (proto));
							/* and accept the remote relay addr if we planned to use our own */
							if (ctx->relay!=NULL && relay){
								add_relay_info(answer,i,relay,payload.relay_session_id);
							}
						}
						/* add the payload, rtpmap, fmtp */
						sdp_message_m_payload_add (answer, i,
								   int_2char
								   (payload.
								    pt));
						if (payload.a_rtpmap != NULL)
						{
							sdp_message_a_attribute_add
								(answer, i,
								 osip_strdup
								 ("rtpmap"),
								 sstrdup_sprintf
								 ("%i %s",
								  payload.pt,
								  payload.
								  a_rtpmap));
						}
						if (payload.a_fmtp != NULL)
						{
							sdp_message_a_attribute_add
								(answer, i,
								 osip_strdup
								 ("fmtp"),
								 sstrdup_sprintf
								 ("%i %s",
								  payload.pt,
								  payload.
								  a_fmtp));
						}
						if (payload.b_as_bandwidth !=
						    0)
						{
							if (sdp_message_bandwidth_get(answer,i,0)==NULL)
								sdp_message_b_bandwidth_add
								(answer, i,
								 osip_strdup
								 ("AS"),
								 sstrdup_sprintf
								 ("%i",
								  payload.
								  b_as_bandwidth));
						}
					}
				}
				if (ncodec == 0)
				{
					/* refuse the line */
					refuse_mline(answer,mtype,proto,i);
					
				}
				else
					m_lines_accepted++;
			}
			else
			{
				/* refuse this line (leave port to 0) */
				refuse_mline(answer,mtype,proto,i);
			}

		}
		else if (keywordcmp ("video", mtype) == 0)
		{
			if (sdph->accept_video_codecs != NULL)
			{
				ncodec = 0;
				/* for each payload type */
				for (j = 0;
				     ((pt =
				       sdp_message_m_payload_get (remote, i,
							  j)) != NULL); j++)
				{
					payload.pt = osip_atoi (pt);
					/* get the rtpmap associated to this codec, if any */
					payload.a_rtpmap =
						sdp_message_a_attr_value_get_with_pt
						(remote, i, payload.pt,
						 "rtpmap");
					/* get the fmtp, if any */
					payload.a_fmtp =
						sdp_message_a_attr_value_get_with_pt
						(remote, i, payload.pt,
						 "fmtp");
					/* ask the application if this codec is supported */
					err = sdph->accept_video_codecs (ctx,
									 &payload);
					if (err == 0 && payload.localport > 0)
					{
						ncodec++;
						/* codec accepted */
						if (ncodec == 1)
						{
							/* first codec accepted, setup the line  */
							sdp_message_m_media_add
								(answer,
								 osip_strdup
								 (mtype),
								 int_2char
								 (payload.localport), NULL,
								 osip_strdup
								 (proto));
							/* and accept the remote relay addr if we planned to use our own */
							if (ctx->relay!=NULL && relay){
								add_relay_info(answer,i,relay,payload.relay_session_id);
							}
						}
						/* add the payload, rtpmap, fmtp */
						sdp_message_m_payload_add (answer, i,
								   int_2char
								   (payload.
								    pt));
						if (payload.a_rtpmap != NULL)
						{
							sdp_message_a_attribute_add
								(answer, i,
								 osip_strdup
								 ("rtpmap"),
								 sstrdup_sprintf
								 ("%i %s",
								  payload.pt,
								  payload.
								  a_rtpmap));
						}
						if (payload.a_fmtp != NULL)
						{
							sdp_message_a_attribute_add
								(answer, i,
								 osip_strdup
								 ("fmtp"),
								 sstrdup_sprintf
								 ("%i %s",
								  payload.pt,
								  payload.
								  a_fmtp));
						}
						if (payload.b_as_bandwidth !=0)
						{
							if (sdp_message_bandwidth_get(answer,i,0)==NULL)
								sdp_message_b_bandwidth_add
								(answer, i,
								 osip_strdup
								 ("AS"),
								 sstrdup_sprintf
								 ("%i",
								  payload.
								  b_as_bandwidth));
						}
					}
				}
				if (ncodec == 0)
				{
					/* refuse the line */
					refuse_mline(answer,mtype,proto,i);
				}
				else
					m_lines_accepted++;
			}
			else
			{
				/* refuse the line */
				refuse_mline(answer,mtype,proto,i);
			}
		}
	}
	if (ctx->answer!=NULL)
		sdp_message_free(ctx->answer);
	ctx->answer = answer;
	if (m_lines_accepted > 0){
		ctx->negoc_status = 200;
		sdp_message_to_str(answer,&tmp);
		if (ctx->answerstr!=NULL)
			osip_free(ctx->answerstr);
		ctx->answerstr=tmp;
		return tmp;
	}else{
		ctx->negoc_status = 415;
		return NULL;
	}
}
Exemple #12
0
int
test_message (char *msg, size_t len, int verbose, int clone)
{
  osip_message_t *sip;

  {
    char *result;

    /* int j=10000; */
    int j = 1;

    if (verbose)
      fprintf (stdout, "Trying %i sequentials calls to osip_message_init(), osip_message_parse() and osip_message_free()\n", j);
    while (j != 0) {
      j--;
      osip_message_init (&sip);
      if (osip_message_parse (sip, msg, len) != 0) {
        fprintf (stdout, "ERROR: failed while parsing!\n");
        osip_message_free (sip);
        return -1;
      }
      osip_message_free (sip);
    }

    osip_message_init (&sip);
    if (osip_message_parse (sip, msg, len) != 0) {
      fprintf (stdout, "ERROR: failed while parsing!\n");
      osip_message_free (sip);
      return -1;
    }
    else {
      int i;
      size_t length;

#if 0
      sdp_message_t *sdp;
      osip_body_t *oldbody;
      int pos;

      pos = 0;
      while (!osip_list_eol (&sip->bodies, pos)) {
        oldbody = (osip_body_t *) osip_list_get (&sip->bodies, pos);
        pos++;
        sdp_message_init (&sdp);
        i = sdp_message_parse (sdp, oldbody->body);
        if (i != 0) {
          fprintf (stdout, "ERROR: Bad SDP!\n");
        }
        else
          fprintf (stdout, "SUCCESS: Correct SDP!\n");
        sdp_message_free (sdp);
        sdp = NULL;
      }
#endif

      osip_message_force_update (sip);
      i = osip_message_to_str (sip, &result, &length);
      if (i == -1) {
        fprintf (stdout, "ERROR: failed while printing message!\n");
        osip_message_free (sip);
        return -1;
      }
      else {
        if (verbose)
          fwrite (result, 1, length, stdout);
        if (clone) {
          /* create a clone of message */
          /* int j = 10000; */
          int j = 1;

          if (verbose)
            fprintf (stdout, "Trying %i sequentials calls to osip_message_clone() and osip_message_free()\n", j);
          while (j != 0) {
            osip_message_t *copy;

            j--;
            i = osip_message_clone (sip, &copy);
            if (i != 0) {
              fprintf (stdout, "ERROR: failed while creating copy of message!\n");
            }
            else {
              char *tmp;
              size_t length;

              osip_message_force_update (copy);
              i = osip_message_to_str (copy, &tmp, &length);
              if (i != 0) {
                fprintf (stdout, "ERROR: failed while printing message!\n");
              }
              else {
                if (0 == strcmp (result, tmp)) {
                  if (verbose)
                    printf ("The osip_message_clone method works perfectly\n");
                }
                else
                  printf ("ERROR: The osip_message_clone method DOES NOT works\n");
                if (verbose) {
                  printf ("Here is the copy: \n");
                  fwrite (tmp, 1, length, stdout);
                  printf ("\n");
                }

                osip_free (tmp);
              }
              osip_message_free (copy);
            }
          }
          if (verbose)
            fprintf (stdout, "sequentials calls: done\n");
        }
        osip_free (result);
      }
      osip_message_free (sip);
    }
  }
  return 0;
}
int
test_sdp_message (char *msg, int verbose)
{
  sdp_message_t *sdp;

  {
    char *result;

    sdp_message_init (&sdp);
    if (sdp_message_parse (sdp, msg) != 0)
      {
	fprintf (stdout, "ERROR: failed while parsing!\n");
	sdp_message_free (sdp);	/* try to free msg, even if it failed! */
	/* this seems dangerous..... */
	return -1;
      }
    else
      {
	int i;

	i = sdp_message_to_str (sdp, &result);
	test_accessor_get_api (sdp);
	if (i == -1)
	  {
	    fprintf (stdout, "ERROR: failed while printing message!\n");
	    sdp_message_free (sdp);
	    return -1;
	  }
	else
	  {
	    if (verbose)
	      fprintf (stdout, "%s", result);
	    if (strlen (result) != strlen (msg))
	      fprintf (stdout, "length differ from original message!\n");
	    if (0 == strncmp (result, msg, strlen (result)))
	      fprintf (stdout, "result equals msg!!\n");
	    osip_free (result);
	    {
	      osip_negotiation_ctx_t *context;

	      sdp_message_t *dest;

	      i = osip_negotiation_ctx_init (&context);
	      i =
		osip_negotiation_ctx_set_mycontext (context,
						    (void *) ua_context);

	      {
		sdp_message_t *sdp;

		osip_negotiation_sdp_build_offer (osip_negotiation,
						  context, &sdp,
						  ua_context->m_audio_port,
						  ua_context->m_video_port);
		sdp_message_to_str (sdp, &result);
		fprintf (stdout, "Here is the offer:\n%s\n", result);
		osip_free (result);
		osip_negotiation_sdp_message_put_on_hold (sdp);
		sdp_message_to_str (sdp, &result);
		fprintf (stdout, "Here is the offer on hold:\n%s\n", result);
		osip_free (result);
		sdp_message_free (sdp);
	      }



	      i = osip_negotiation_ctx_set_remote_sdp (context, sdp);
	      if (i != 0)
		{
		  fprintf (stdout,
			   "Initialisation of context failed. Could not negociate\n");
		}
	      else
		{
		  fprintf (stdout, "Trying to execute a SIP negotiation:\n");
		  i =
		    osip_negotiation_ctx_execute_negotiation
		    (osip_negotiation, context);
		  fprintf (stdout, "return code: %i\n", i);
		  if (i == 200)
		    {
		      dest = osip_negotiation_ctx_get_local_sdp (context);
		      fprintf (stdout, "SDP answer:\n");
		      i = sdp_message_to_str (dest, &result);
		      if (i != 0)
			fprintf (stdout,
				 "Error found in SDP answer while printing\n");
		      else
			fprintf (stdout, "%s\n", result);
		      osip_free (result);
		    }
		  osip_negotiation_ctx_free (context);
		  return 0;
		}
	    }
	  }
	sdp_message_free (sdp);
      }
  }
  return 0;
}
int
sdp_complete_200ok (int did, osip_message_t * answer)
{
  sdp_message_t *remote_sdp;
  sdp_media_t *remote_med;
  char *tmp = NULL;
  char buf[4096];
  int pos;

  char localip[128];


  remote_sdp = eXosip_get_remote_sdp (did);
  if (remote_sdp == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_WARNING, NULL,
                   "No remote SDP body found for call\n"));
      return -1;                /* no existing body? */
    }

  eXosip_guess_localip (AF_INET, localip, 128);
  snprintf (buf, 4096,
            "v=0\r\n"
            "o=josua 0 0 IN IP4 %s\r\n"
            "s=conversation\r\n" "c=IN IP4 %s\r\n" "t=0 0\r\n", localip, localip);

  pos = 0;
  while (!osip_list_eol (remote_sdp->m_medias, pos))
    {
      char payloads[128];
      int pos2;

      memset (payloads, '\0', sizeof (payloads));
      remote_med = (sdp_media_t *) osip_list_get (remote_sdp->m_medias, pos);

      if (0 == osip_strcasecmp (remote_med->m_media, "audio"))
        {
          pos2 = 0;
          while (!osip_list_eol (remote_med->m_payloads, pos2))
            {
              tmp = (char *) osip_list_get (remote_med->m_payloads, pos2);
              if (tmp != NULL &&
                  (0 == osip_strcasecmp (tmp, "0")
                   || 0 == osip_strcasecmp (tmp, "8")))
                {
                  strcat (payloads, tmp);
                  strcat (payloads, " ");
                }
              pos2++;
            }
          strcat (buf, "m=");
          strcat (buf, remote_med->m_media);
          if (pos2 == 0 || payloads[0] == '\0')
            {
              strcat (buf, " 0 RTP/AVP \r\n");
              sdp_message_free (remote_sdp);
              return -1;        /* refuse anyway */
          } else
            {
              strcat (buf, " 10500 RTP/AVP ");
              strcat (buf, payloads);
              strcat (buf, "\r\n");

#if 0
              if (NULL != strstr (payloads, " 0 ")
                  || (payloads[0] == '0' && payloads[1] == ' '))
                strcat (buf, "a=rtpmap:0 PCMU/8000/1\r\n");
              if (NULL != strstr (payloads, " 8 ")
                  || (payloads[0] == '8' && payloads[1] == ' '))
                strcat (buf, "a=rtpmap:8 PCMA/8000/1\r\n");
#else
              if (NULL != strstr (payloads, " 0 ")
                  || (payloads[0] == '0' && payloads[1] == ' '))
                strcat (buf, "a=rtpmap:0 PCMU/8000\r\n");
              if (NULL != strstr (payloads, " 8 ")
                  || (payloads[0] == '8' && payloads[1] == ' '))
                strcat (buf, "a=rtpmap:8 PCMA/8000\r\n");
#endif
            }
      } else
        {
          strcat (buf, "m=");
          strcat (buf, remote_med->m_media);
          strcat (buf, " 0 ");
          strcat (buf, remote_med->m_proto);
          strcat (buf, " \r\n");
        }
      pos++;
    }

  osip_message_set_body (answer, buf, strlen (buf));
  osip_message_set_content_type (answer, "application/sdp");
  sdp_message_free (remote_sdp);
  return 0;
}
Exemple #15
0
int
eXosip_answer_options_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code)
{
  osip_event_t *evt_answer;
  osip_transaction_t *tr;
  osip_message_t *response;
  sdp_message_t *sdp;
  char *body;
  char size[10];
  int i;

  tr = eXosip_find_last_inc_options(jc, jd);
  if (tr==NULL)
    {
      OSIP_TRACE (osip_trace
		  (__FILE__, __LINE__, OSIP_ERROR, NULL,
         "eXosip: cannot find transaction to answer"));
      return -1;
    }
  osip_negotiation_sdp_build_offer(eXosip.osip_negotiation, NULL, &sdp, "10400", NULL);
  if (sdp==NULL)
    {
      return -1;
    }
  if (jd!=NULL)
    {
      i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
    }
  else
    {
      i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
    }
  if (i!=0)
    {
      OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for options\n"));
      sdp_message_free(sdp); /* not used */
      return -1;
    }
  i = sdp_message_to_str(sdp, &body);
  sdp_message_free(sdp);
  if ( ( i!=0 ) || ( ! body ) ) {
    osip_message_free(response);
    return -1;
  }
  
  i = osip_message_set_body(response, body, strlen(body));
  if (i!=0) {
    osip_message_free(response);
    return -1;
  }
#ifdef __APPLE_CC__
  snprintf(size, 9,"%li",strlen(body));
#else
  snprintf(size, 9,"%i",strlen(body));
#endif
  i = osip_message_set_content_length(response, size);
  if (i!=0) {
    osip_free(body);
    osip_message_free(response);
    return -1;
  }
  osip_free(body);
  i = osip_message_set_content_type(response, "application/sdp");
  if (i!=0) {
    osip_message_free(response);
    return -1;
  }

  evt_answer = osip_new_outgoing_sipmessage(response);
  evt_answer->transactionid = tr->transactionid;

  osip_transaction_add_event(tr, evt_answer);
  __eXosip_wakeup();
  return 0;
}
Exemple #16
0
char *
generating_sdp_answer(osip_message_t *request, osip_negotiation_ctx_t *context)
{
  sdp_message_t *remote_sdp;
  sdp_message_t *local_sdp = NULL;
  int i;
  char *local_body;
  if (context==NULL)
    return NULL;

  local_body = NULL;
  if (MSG_IS_INVITE(request)||MSG_IS_OPTIONS(request)||MSG_IS_RESPONSE_FOR(request, "INVITE"))
    {
      osip_body_t *body;
      body = (osip_body_t *)osip_list_get(&request->bodies,0);
      if(body == NULL)
	return NULL;
      
      /* remote_sdp = (sdp_message_t *) osip_malloc(sizeof(sdp_message_t)); */
      i = sdp_message_init(&remote_sdp);
      if (i!=0) return NULL;
      
      /* WE ASSUME IT IS A SDP BODY AND THAT    */
      /* IT IS THE ONLY ONE, OF COURSE, THIS IS */
      /* NOT TRUE */
      i = sdp_message_parse(remote_sdp,body->body);
      if (i!=0) return NULL;

      i = osip_negotiation_ctx_set_remote_sdp(context, remote_sdp);

      i = osip_negotiation_ctx_execute_negotiation(eXosip.osip_negotiation, context);
      if (i==200)
	{
	  local_sdp = osip_negotiation_ctx_get_local_sdp(context);

	  i = sdp_message_to_str(local_sdp, &local_body);

	  remote_sdp = osip_negotiation_ctx_get_remote_sdp(context);
	  sdp_message_free(remote_sdp);
	  osip_negotiation_ctx_set_remote_sdp(context, NULL);

	  if (i!=0) {
	    OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not parse local SDP answer %i\n",i));
	    return NULL;
	  }
	  return local_body;
	}
      else if (i==415)
	{
	  OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"WARNING: Unsupported media %i\n",i));
	}
      else
	{
	  OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: while building answer to SDP (%i)\n",i));
	}
      remote_sdp = osip_negotiation_ctx_get_remote_sdp(context);
      sdp_message_free(remote_sdp);
      osip_negotiation_ctx_set_remote_sdp(context, NULL);
    }
  return NULL;
}
/*
 * Processing.
 * 
 */
int  PLUGIN_PROCESS(int stage, sip_ticket_t *ticket){
   /* stage contains the PLUGIN_* value - the stage of SIP processing. */
   int sts;
   char *buff;
   size_t buflen;
   osip_body_t *body;
   sdp_message_t  *sdp;
   int content_length;
   osip_content_type_t *content_type;
   char clen[8]; /* content length: probably never more than 7 digits !*/

   //
   // check that we have the expected payload "application/sdp"
   //

   // get content length
   content_length=0;
   if (ticket->sipmsg && ticket->sipmsg->content_length 
       && ticket->sipmsg->content_length->value) {
      sts=sscanf(ticket->sipmsg->content_length->value, "%i", &content_length);
   }

   // check if we have a content type defined and that payload length >0
   content_type=osip_message_get_content_type(ticket->sipmsg);
   if ((content_length == 0) || (content_type == NULL) 
       || (content_type->type == NULL) || (content_type->subtype == NULL)) {
      DEBUGC(DBCLASS_PLUGIN, "%s: no content", name);
      return STS_SUCCESS;
   }

   // check content type: must be "application/sdp"
   if ((strncmp(content_type->type, "application", sizeof("application")) != 0)
       || (strncmp(content_type->subtype, "sdp", sizeof("sdp")) != 0)) {
      DEBUGC(DBCLASS_PLUGIN, "%s: unsupported content-type %s/%s", name,
             content_type->type, content_type->subtype);
      return STS_SUCCESS;
   }

   DEBUGC(DBCLASS_PLUGIN, "%s: content-type %s/%s, size=%i", name, 
          content_type->type, content_type->subtype, content_length);

   //
   // parse the payload
   //

   // get a pointer to the payload of the SIP packet
   sts = osip_message_get_body(ticket->sipmsg, 0, &body);
   if (sts != 0) {
      DEBUGC(DBCLASS_PLUGIN, "%s: no body found in message", name);
      return STS_SUCCESS;
   }
   // dump it into a buffer
   sts = sip_body_to_str(body, &buff, &buflen);
   if (sts != 0) {
      WARN("%s: unable to sip_body_to_str", name);
      return STS_SUCCESS;
   }
   // and parse it into an SDP structure
   sts = sdp_message_init(&sdp);
   sts = sdp_message_parse (sdp, buff);
   if (sts != 0) {
      WARN("%s: unable to sdp_message_parse() body", name);
      DUMP_BUFFER(-1, buff, buflen);
      osip_free(buff);
      buff=NULL;
      sdp_message_free(sdp);
      return STS_SUCCESS;
   }
   osip_free(buff);
   buff=NULL;

   //
   // now do the codec filtering magic...
   sdp_filter_codec(sdp);

   //
   // replace the original payload with the new modified payload
   //
   
   // remove old body from SIP packet
   sts = osip_list_remove(&(ticket->sipmsg->bodies), 0);
   osip_body_free(body);
   body=NULL;

   // dump new body to buffer
   sdp_message_to_str(sdp, &buff);
   buflen=strlen(buff);

   // free sdp structure (no longer needed)
   sdp_message_free(sdp);
   sdp=NULL;

   // put new body into SIP message
   sts=sip_message_set_body(ticket->sipmsg, buff, buflen);
   if (sts != 0) {
      ERROR("%s: unable to sip_message_set_body body", name);
      DUMP_BUFFER(-1, buff, buflen);
      buflen=0;
   }
   // free buffer
   osip_free(buff);
   buff=NULL;

   //
   // set new content length
   //

   // remove old content leght field
   osip_content_length_free(ticket->sipmsg->content_length);
   ticket->sipmsg->content_length=NULL;

   // set new content length
   sprintf(clen,"%ld",(long)buflen);
   sts = osip_message_set_content_length(ticket->sipmsg, clen);

   return STS_SUCCESS;
}
Exemple #18
0
/*
 * PROXY_REWRITE_INVITATION_BODY
 *
 * rewrites the outgoing INVITATION request or response packet
 * 
 * RETURNS
 *	STS_SUCCESS on success
 *	STS_FAILURE on error
 */
int proxy_rewrite_invitation_body(osip_message_t *mymsg, int direction){
   osip_body_t *body;
   sdp_message_t  *sdp;
   struct in_addr map_addr, addr_sess, addr_media, outside_addr, inside_addr;
   int sts;
   char *bodybuff;
   int bodybuflen;
   char clen[8]; /* content length: probably never more than 7 digits !*/
   int map_port, msg_port;
   int media_stream_no;
   sdp_connection_t *sdp_conn;
   sdp_media_t *sdp_med;
   int rtp_direction=0;
   int have_c_media=0;

   if (configuration.rtp_proxy_enable == 0) return STS_SUCCESS;

   /*
    * get SDP structure
    */
   sts = osip_message_get_body(mymsg, 0, &body);
   if (sts != 0) {
#if 0
      if ((MSG_IS_RESPONSE_FOR(mymsg,"INVITE")) &&
          (MSG_IS_STATUS_1XX(mymsg))) {
         /* 1xx responses *MAY* contain SDP data */
         DEBUGC(DBCLASS_PROXY, "rewrite_invitation_body: "
                "no body found in message");
         return STS_SUCCESS;
      } else {
         /* INVITE request and 200 response *MUST* contain SDP data */
         ERROR("rewrite_invitation_body: no body found in message");
         return STS_FAILURE;
      }
#else
      DEBUGC(DBCLASS_PROXY, "rewrite_invitation_body: "
                            "no body found in message");
      return STS_SUCCESS;
#endif
   }

   sts = sip_body_to_str(body, &bodybuff, &bodybuflen);
   if (sts != 0) {
      ERROR("rewrite_invitation_body: unable to sip_body_to_str");
   }
   sts = sdp_message_init(&sdp);
   sts = sdp_message_parse (sdp, bodybuff);
   if (sts != 0) {
      ERROR("rewrite_invitation_body: unable to sdp_message_parse body");
      DUMP_BUFFER(-1, bodybuff, bodybuflen);
      osip_free(bodybuff);
      sdp_message_free(sdp);
      return STS_FAILURE;
   }
   osip_free(bodybuff);


if (configuration.debuglevel)
{ /* just dump the buffer */
   char *tmp, *tmp2;
   int tmplen;
   sts = osip_message_get_body(mymsg, 0, &body);
   sts = sip_body_to_str(body, &tmp, &tmplen);
   osip_content_length_to_str(mymsg->content_length, &tmp2);
   DEBUG("Body before rewrite (clen=%s, strlen=%i):\n%s\n----",
         tmp2, tmplen, tmp);
   osip_free(tmp);
   osip_free(tmp2);
}

   /*
    * RTP proxy: get ready and start forwarding
    * start forwarding for each media stream ('m=' item in SIP message)
    */

   /* get outbound address */
   if (get_interface_ip(IF_OUTBOUND, &outside_addr) != STS_SUCCESS) {
      sdp_message_free(sdp);
      return STS_FAILURE;
   }

   /* get inbound address */
   if (get_interface_ip(IF_INBOUND, &inside_addr) != STS_SUCCESS) {
      sdp_message_free(sdp);
      return STS_FAILURE;
   }

   /* figure out what address to use for RTP masquerading */
   if (MSG_IS_REQUEST(mymsg)) {
      if (direction == DIR_INCOMING) {
         memcpy(&map_addr, &inside_addr, sizeof (map_addr));
         rtp_direction = DIR_OUTGOING;
      } else {
         memcpy(&map_addr, &outside_addr, sizeof (map_addr));
         rtp_direction = DIR_INCOMING;
      }
   } else /* MSG_IS_REPONSE(mymsg) */ {
      if (direction == DIR_INCOMING) {
         memcpy(&map_addr, &inside_addr, sizeof (map_addr));
         rtp_direction = DIR_OUTGOING;
      } else {
         memcpy(&map_addr, &outside_addr, sizeof (map_addr));
         rtp_direction = DIR_INCOMING;
      }
   }

   DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: SIP[%s %s] RTP[%s %s]",
          MSG_IS_REQUEST(mymsg)? "RQ" : "RS",
          (direction==DIR_INCOMING)? "IN" : "OUT",
          (rtp_direction==DIR_INCOMING)? "IN" : "OUT",
          utils_inet_ntoa(map_addr));


   /*
    * first, check presence of a 'c=' item on session level
    */
   if (sdp->c_connection==NULL || sdp->c_connection->c_addr==NULL) {
      /*
       * No 'c=' on session level, search on media level now
       *
       * According to RFC2327, ALL media description must
       * include a 'c=' item now:
       */
      media_stream_no=0;
      while (!sdp_message_endof_media(sdp, media_stream_no)) {
         /* check if n'th media stream is present */
         if (sdp_message_c_addr_get(sdp, media_stream_no, 0) == NULL) {
            ERROR("SDP: have no 'c=' on session level and neither "
                  "on media level (media=%i)",media_stream_no);
            sdp_message_free(sdp);
            return STS_FAILURE;
         }
         media_stream_no++;
      } /* while */
   }

   /* Required 'c=' items ARE present */


   /*
    * rewrite 'c=' item on session level if present and not yet done.
    * remember the original address in addr_sess
    */
   memset(&addr_sess, 0, sizeof(addr_sess));
   if (sdp->c_connection && sdp->c_connection->c_addr) {
      sts = get_ip_by_host(sdp->c_connection->c_addr, &addr_sess);
      if (sts == STS_FAILURE) {
         ERROR("SDP: cannot resolve session 'c=' host [%s]",
               sdp->c_connection->c_addr);
         sdp_message_free(sdp);
         return STS_FAILURE;
      }
      /*
       * Rewrite
       * an IP address of 0.0.0.0 means *MUTE*, don't rewrite such
       */
      if (strcmp(sdp->c_connection->c_addr, "0.0.0.0") != 0) {
         osip_free(sdp->c_connection->c_addr);
         sdp->c_connection->c_addr=osip_malloc(HOSTNAME_SIZE);
         sprintf(sdp->c_connection->c_addr, "%s", utils_inet_ntoa(map_addr));
      } else {
         /* 0.0.0.0 - don't rewrite */
         DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: "
                "got a MUTE c= record (on session level - legal?)");
      }
   }


   /*
    * rewrite 'o=' item (originator) on session level if present.
    */
   if (sdp->o_addrtype && sdp->o_addr) {
      if (strcmp(sdp->o_addrtype, "IP4") != 0) {
         ERROR("got IP6 in SDP originator - not yet suported by siproxd");
         sdp_message_free(sdp);
         return STS_FAILURE;
      }

      osip_free(sdp->o_addr);
      sdp->o_addr=osip_malloc(HOSTNAME_SIZE);
      sprintf(sdp->o_addr, "%s", utils_inet_ntoa(map_addr));
   }


   /*
    * loop through all media descritions,
    * start RTP proxy and rewrite them
    */
   for (media_stream_no=0;;media_stream_no++) {
      /* check if n'th media stream is present */
      if (sdp_message_m_port_get(sdp, media_stream_no) == NULL) break;

      /*
       * check if a 'c=' item is present in this media description,
       * if so -> rewrite it
       */
      memset(&addr_media, 0, sizeof(addr_media));
      have_c_media=0;
      sdp_conn=sdp_message_connection_get(sdp, media_stream_no, 0);
      if (sdp_conn && sdp_conn->c_addr) {
         if (strcmp(sdp_conn->c_addr, "0.0.0.0") != 0) {
            sts = get_ip_by_host(sdp_conn->c_addr, &addr_media);
            have_c_media=1;
            /* have a valid address */
            osip_free(sdp_conn->c_addr);
            sdp_conn->c_addr=osip_malloc(HOSTNAME_SIZE);
            sprintf(sdp_conn->c_addr, "%s", utils_inet_ntoa(map_addr));
         } else {
            /* 0.0.0.0 - don't rewrite */
            DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: got a "
                   "MUTE c= record (media level)");
         }
      }

      /* start an RTP proxying stream */
      if (sdp_message_m_port_get(sdp, media_stream_no)) {
         msg_port=atoi(sdp_message_m_port_get(sdp, media_stream_no));

         if (msg_port > 0) {
            osip_uri_t *cont_url = NULL;
            char *client_id=NULL;
            /* try to get some additional UA specific unique ID.
             * Try:
             * 1) User part of Contact header
             * 2) Host part of Contact header (will be different
             *    between internal UA and external UA)
             */
            if (!osip_list_eol(mymsg->contacts, 0))
               cont_url = ((osip_contact_t*)(mymsg->contacts->node->element))->url;
            if (cont_url) {
               client_id=cont_url->username;
               if (client_id == NULL) client_id=cont_url->host;
            }


            /*
             * do we have a 'c=' item on media level?
             * if not, use the same as on session level
             */
            if (have_c_media == 0) {
               memcpy(&addr_media, &addr_sess, sizeof(addr_sess));
            }

            /*
             * Am I running in front of the routing device? Then I cannot
             * use the external IP to bind a listen socket to, so force
             * the use of my inbound IP for listening.
             */
            if ((rtp_direction == DIR_INCOMING) &&
                (configuration.outbound_host) &&
                (strcmp(configuration.outbound_host, "")!=0)) {
               DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: "
                      "in-front-of-NAT-Router");
               memcpy(&map_addr, &inside_addr, sizeof (map_addr));
            }

            sts = rtp_start_fwd(osip_message_get_call_id(mymsg),
                                client_id,
                                rtp_direction,
                                media_stream_no,
                                map_addr, &map_port,
                                addr_media, msg_port);

            if (sts == STS_SUCCESS) {
               /* and rewrite the port */
               sdp_med=osip_list_get(sdp->m_medias, media_stream_no);
               if (sdp_med && sdp_med->m_port) {
                  osip_free(sdp_med->m_port);
                  sdp_med->m_port=osip_malloc(8); /* 5 digits, \0 + align */
                  sprintf(sdp_med->m_port, "%i", map_port);
                  DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: "
                         "m= rewrote port to [%i]",map_port);
               } else {
                  ERROR("rewriting port in m= failed sdp_med=%p, "
                        "m_number_of_port=%p", sdp_med, sdp_med->m_port);
               }
            } /* sts == success */
         } /* if msg_port > 0 */
      } else {
         /* no port defined - skip entry */
         WARN("no port defined in m=(media) stream_no=%i", media_stream_no);
         continue;
      }
   } /* for media_stream_no */

   /* remove old body */
   sts = osip_list_remove(mymsg->bodies, 0);
   osip_body_free(body);

   /* dump new body */
   sdp_message_to_str(sdp, &bodybuff);
   bodybuflen=strlen(bodybuff);

   /* free sdp structure */
   sdp_message_free(sdp);

   /* include new body */
   sip_message_set_body(mymsg, bodybuff, bodybuflen);
   if (sts != 0) {
      ERROR("rewrite_invitation_body: unable to sip_message_set_body body");
   }

   /* free content length resource and include new one*/
   osip_content_length_free(mymsg->content_length);
   mymsg->content_length=NULL;
   sprintf(clen,"%i",bodybuflen);
   sts = osip_message_set_content_length(mymsg, clen);

   /* free old body */
   osip_free(bodybuff);

if (configuration.debuglevel)
{ /* just dump the buffer */
   char *tmp, *tmp2;
   int tmplen;
   sts = osip_message_get_body(mymsg, 0, &body);
   sts = sip_body_to_str(body, &tmp, &tmplen);
   osip_content_length_to_str(mymsg->content_length, &tmp2);
   DEBUG("Body after rewrite (clen=%s, strlen=%i):\n%s\n----",
         tmp2, tmplen, tmp);
   osip_free(tmp);
   osip_free(tmp2);
}
   return STS_SUCCESS;
}
int main(int argc, char **argv)
{
  struct osip_rfc3264 *cnf;
  int i;
  int verbose = 0;		/* 0: verbose, 1 (or nothing: not verbose) */
  FILE *torture_file;

  if (argc > 3)
    {
      if (0 == strncmp (argv[3], "-v", 2))
	verbose = 1;
      if (0 == strcmp (argv[3], "-vv"))
	verbose = 2;
    }

  fprintf (stdout, "test %i : ============================ \n", atoi(argv[2]));

  torture_file = fopen (argv[1], "r");
  if (torture_file == NULL)
    {
      fprintf (stderr,
	       "Failed to open \"torture_sdps\" file.\nUsage: %s torture_file [-v]\n",
	       argv[0]);
      fprintf (stdout, "test %s : ============================ FAILED\n", argv[2]);
      exit (1);
    }






  i = osip_rfc3264_init(&cnf);
  if (i!=0)
    {
      fprintf(stderr, "Cannot Initialize Negotiator feature.\n");
      osip_rfc3264_free(cnf);
      fclose (torture_file);
      fprintf (stdout, "test %s : ============================ FAILED\n", argv[2]);
      return -1;
    }

  test_add_codec(cnf, AUDIO_CODEC, 0,  "0 PCMU/8000");
  test_add_codec(cnf, AUDIO_CODEC, 8,  "8 PCMA/8000");
  test_add_codec(cnf, AUDIO_CODEC, 18, "18 G729/8000");

  test_add_codec(cnf, VIDEO_CODEC, 97, "97 XXX/11111");
  test_add_codec(cnf, VIDEO_CODEC, 31, "31 H261/90000");

#if 0
  osip_rfc3264_del_video_media(cnf, 0);
  osip_rfc3264_del_audio_media(cnf, 1);
  osip_rfc3264_del_audio_media(cnf, 2);

  test_add_codec(cnf, AUDIO_CODEC, 8,  "0 PCMA/8000");
  test_add_codec(cnf, AUDIO_CODEC, 18, "18 G729/8000");
#endif

  if (verbose==2)
    __osip_rfc3264_print_codecs(cnf);

  {
    sdp_message_t *remote_sdp;
    sdp_media_t *audio_tab[10];
    sdp_media_t *video_tab[10];
    sdp_media_t *t38_tab[10];
    sdp_media_t *app_tab[10];
    int res_audio = 0;
    int res_video = 0;
    int res_t38   = 0;
    int res_app   = 0;

    char str_local_sdp[8192];
    sdp_message_t *local_sdp;
    int mline;
    char *tmp = NULL;

    remote_sdp = get_test_remote_message(atoi(argv[2]), torture_file, verbose);
    if (!remote_sdp)
      {
	fprintf(stderr, "Cannot Get remote SDP message for testing.\n");
	osip_rfc3264_free(cnf);
	fclose (torture_file);
	fprintf (stdout, "test %s : ============================ FAILED\n", argv[2]);
	return -1;
      }

    i=osip_rfc3264_prepare_answer(cnf, remote_sdp, str_local_sdp, 8192);
    if (i!=0)
      {
	fprintf(stderr, "Cannot Prepare local SDP answer from offer.\n");
	osip_rfc3264_free(cnf);
	fclose (torture_file);
	fprintf (stdout, "test %s : ============================ FAILED\n", argv[2]);
	return -1;
      }
    sdp_message_init(&local_sdp);
    i=sdp_message_parse(local_sdp, str_local_sdp);
    if (i!=0)
      {
	fprintf(stderr, "Cannot Parse uncomplete SDP answer from offer.\n");
	sdp_message_free(local_sdp);
	osip_rfc3264_free(cnf);
	fclose (torture_file);
	fprintf (stdout, "test %s : ============================ FAILED\n", argv[2]);
	return -1;
      }

    mline=0;
    while (0==osip_rfc3264_match(cnf, remote_sdp,
				 audio_tab, video_tab, t38_tab, app_tab, mline))
      {
	int pos;

	if (audio_tab[0]==NULL && video_tab[0]==NULL && t38_tab[0]==NULL && app_tab[0]==NULL)
	  {
	    if (verbose)
	      fprintf(stdout, "The remote SDP does not match any local payloads.\n");
	  }
	else
	  {
	    for (pos=0;audio_tab[pos]!=NULL;pos++)
	      {
		int pos2 = 0;
		sdp_media_t *med = audio_tab[pos];
		char *str = (char *) osip_list_get (med->m_payloads, 0);
		if (verbose==2)
		  fprintf(stdout, "\tm=%s %s %s %s\n",
			  med->m_media,
			  med->m_port,
			  med->m_proto,
			  str);
		while (!osip_list_eol (med->a_attributes, pos2))
		  {
		    sdp_attribute_t *attr =
		      (sdp_attribute_t *) osip_list_get (med->a_attributes, pos2);
		    if (verbose==2)
		      fprintf(stdout, "\ta=%s:%s\n",
			      attr->a_att_field,
			      attr->a_att_value);
		    pos2++;
		  }
		if (verbose==2)
		  fprintf(stdout, "\n");

		i=osip_rfc3264_complete_answer(cnf, remote_sdp, local_sdp, audio_tab[pos], mline);
		if (i!=0)
		  {
		    if (verbose)
		      fprintf(stdout, "Error Adding support for codec in answer?\n");
		  }
		else
		  {
		    if (verbose==2)
		      fprintf(stdout, "support for codec added in answer:\n");
		  }
	      }
	    
	    for (pos=0;video_tab[pos]!=NULL;pos++)
	      {
		int pos2 = 0;
		sdp_media_t *med = video_tab[pos];
		char *str = (char *) osip_list_get (med->m_payloads, 0);
		if (verbose==2)
		  fprintf(stdout, "\tm=%s %s %s %s\n",
			  med->m_media,
			  med->m_port,
			  med->m_proto,
			  str);
		while (!osip_list_eol (med->a_attributes, pos2))
		  {
		    sdp_attribute_t *attr =
		      (sdp_attribute_t *) osip_list_get (med->a_attributes, pos2);
		    if (verbose==2)
		      fprintf(stdout, "\ta=%s:%s\n",
			      attr->a_att_field,
			      attr->a_att_value);
		    pos2++;
		  }
		if (verbose==2)
		  fprintf(stdout, "\n");

		i=osip_rfc3264_complete_answer(cnf, remote_sdp, local_sdp, video_tab[pos], mline);
		if (i!=0)
		  {
		    if (verbose)
		      fprintf(stdout, "Error Adding support for codec in answer?\n");
		  }
		else
		  {
		    if (verbose==2)
		      fprintf(stdout, "support for codec added in answer:\n");
		  }
	      }	    
	  }

	mline++;
      }

    if (verbose)
      fprintf(stdout, "Result in answer:\n");
    sdp_message_to_str(local_sdp, &tmp);
    if (tmp!=NULL)
      {
	if (verbose)
	  fprintf(stdout, "\n%s\n", tmp);
	free(tmp);
      }
    else
      {
	if (verbose)
	  fprintf(stdout, "ERROR\n"); 
      }
  }

  osip_rfc3264_free(cnf);
  fclose (torture_file);
  fprintf (stdout, "test %s : ============================ OK\n", argv[2]);
  return 0;
}