Пример #1
0
/* refuse the line */
static void refuse_mline(sdp_message_t *answer,char *mtype,char *proto, int mline)
{
	sdp_message_m_media_add (answer,
							 osip_strdup (mtype),
							 int_2char (0), NULL,
							 osip_strdup (proto));
	/* add a payload just to comply with sdp RFC.*/
	sdp_message_m_payload_add(answer,mline,int_2char(0));
}
Пример #2
0
/* to add payloads to the offer, must be called inside the write_offer callback */
void
sdp_context_add_payload (sdp_context_t * ctx, sdp_payload_t * payload, char *media)
{
	sdp_message_t *offer = ctx->offer;
	char *attr_field;
	if (!ctx->incb)
	{
		eXosip_trace (OSIP_ERROR,
			    ("You must not call sdp_context_add_*_payload outside the write_offer callback\n"));
		abort ();
	}
	if (payload->proto == NULL)
		payload->proto = "RTP/AVP";
	/*printf("payload->line=%i payload->pt=%i\n",payload->line, payload->pt);*/
	if (sdp_message_m_media_get (offer, payload->line) == NULL)
	{
		/*printf("Adding new mline %s \n",media);*/
		/* need a new line */
		sdp_message_m_media_add (offer, osip_strdup (media),
				 int_2char (payload->localport), NULL,
				 osip_strdup (payload->proto));
		if (ctx->relay){
			add_relay_info(offer,payload->line,ctx->relay,ctx->relay_session_id);
		}
	}
	sdp_message_m_payload_add (offer, payload->line, int_2char (payload->pt));
	if (payload->a_rtpmap != NULL)
	{
		attr_field =
			sstrdup_sprintf ("%i %s", payload->pt,
					 payload->a_rtpmap);
		sdp_message_a_attribute_add (offer, payload->line,
				     osip_strdup ("rtpmap"), attr_field);
	}
	if (payload->a_fmtp != NULL)
	{
		attr_field =
			sstrdup_sprintf ("%i %s", payload->pt,
					 payload->a_fmtp);
		sdp_message_a_attribute_add (offer, payload->line, osip_strdup ("fmtp"),
				     attr_field);
	}
	if (payload->b_as_bandwidth != 0)
	{	
		if (sdp_message_bandwidth_get(offer,payload->line,0)==NULL){
			attr_field =
			sstrdup_sprintf ("%i", payload->b_as_bandwidth);
			sdp_message_b_bandwidth_add (offer, payload->line, osip_strdup ("AS"),
				     attr_field);
		}
	}
}
Пример #3
0
static void add_payload(sdp_message_t *msg, int line, const PayloadType *pt, bool_t strip_well_known_rtpmaps)
{
	char attr[256];
	sdp_message_m_payload_add (msg,line, int_2char (payload_type_get_number(pt)));

	if (!strip_well_known_rtpmaps || !is_known_rtpmap(pt)){
		if (pt->channels>1)
			snprintf (attr,sizeof(attr),"%i %s/%i/%i", payload_type_get_number(pt), 
					pt->mime_type, pt->clock_rate,pt->channels);
		else
			snprintf (attr,sizeof(attr),"%i %s/%i", payload_type_get_number(pt), 
					pt->mime_type, pt->clock_rate);
		sdp_message_a_attribute_add (msg, line,
						 osip_strdup ("rtpmap"), osip_strdup(attr));
	}

	if (pt->recv_fmtp != NULL)
	{
		snprintf (attr,sizeof(attr),"%i %s", payload_type_get_number(pt),pt->recv_fmtp);
		sdp_message_a_attribute_add (msg, line, osip_strdup ("fmtp"),
				     osip_strdup(attr));
	}
}
Пример #4
0
static sdp_message_t *create_generic_sdp(const SalMediaDescription *desc)
{
	sdp_message_t *local;
	int inet6;
	char sessid[16];
	char sessver[16];
	
	snprintf(sessid,16,"%i",desc->session_id);
	snprintf(sessver,16,"%i",desc->session_ver);
	sdp_message_init (&local);
	if (strchr(desc->addr,':')!=NULL){
		inet6=1;
	}else inet6=0;
	sdp_message_v_version_set (local, osip_strdup ("0"));
	sdp_message_o_origin_set (local, osip_strdup (desc->username),
			  osip_strdup (sessid), osip_strdup (sessver),
			  osip_strdup ("IN"), inet6 ? osip_strdup("IP6") : osip_strdup ("IP4"),
			  osip_strdup (desc->addr));
	sdp_message_s_name_set (local, osip_strdup ("Talk"));
	if(!sal_media_description_has_dir (desc,SalStreamSendOnly))
	{
		sdp_message_c_connection_add (local, -1,
				osip_strdup ("IN"), inet6 ? osip_strdup ("IP6") : osip_strdup ("IP4"),
						osip_strdup (desc->addr), NULL, NULL);
	}
	else
	{
		sdp_message_c_connection_add (local, -1,
				osip_strdup ("IN"), inet6 ? osip_strdup ("IP6") : osip_strdup ("IP4"),
						inet6 ? osip_strdup ("::0") : osip_strdup ("0.0.0.0"), NULL, NULL);
	}		
	sdp_message_t_time_descr_add (local, osip_strdup ("0"), osip_strdup ("0"));
	if (desc->bandwidth>0) sdp_message_b_bandwidth_add (local, -1, osip_strdup ("AS"),
			int_2char(desc->bandwidth));
	return local;
}
Пример #5
0
static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription *desc){
	const char *mt=NULL;
	const MSList *elem;
	const char *addr;
	const char *dir="sendrecv";
	int port;
	bool_t strip_well_known_rtpmaps;
	
	switch (desc->type) {
	case SalAudio:
		mt="audio";
		break;
	case SalVideo:
		mt="video";
		break;
	case SalOther:
		mt=desc->typeother;
		break;
	}
	if (desc->candidates[0].addr[0]!='\0'){
		addr=desc->candidates[0].addr;
		port=desc->candidates[0].port;
	}else{
		addr=desc->addr;
		port=desc->port;
	}
	/*only add a c= line within the stream description if address are differents*/
	if (strcmp(addr,sdp_message_c_addr_get(msg, -1, 0))!=0){
		bool_t inet6;
		if (strchr(addr,':')!=NULL){
			inet6=TRUE;
		}else inet6=FALSE;
		sdp_message_c_connection_add (msg, lineno,
			      osip_strdup ("IN"), inet6 ? osip_strdup ("IP6") : osip_strdup ("IP4"),
			      osip_strdup (addr), NULL, NULL);
	}
	sdp_message_m_media_add (msg, osip_strdup (mt),
				 int_2char (port), NULL,
				 osip_strdup ("RTP/AVP"));
	if (desc->bandwidth>0) sdp_message_b_bandwidth_add (msg, lineno, osip_strdup ("AS"),
				     int_2char(desc->bandwidth));
	if (desc->ptime>0) sdp_message_a_attribute_add(msg,lineno,osip_strdup("ptime"),
	    			int_2char(desc->ptime));
	strip_well_known_rtpmaps=ms_list_size(desc->payloads)>5;
	if (desc->payloads){
		for(elem=desc->payloads;elem!=NULL;elem=elem->next){
			add_payload(msg, lineno, (PayloadType*)elem->data,strip_well_known_rtpmaps);
		}
	}else{
		/* to comply with SDP we cannot have an empty payload type number list */
		/* as it happens only when mline is declined with a zero port, it does not matter to put whatever codec*/
		sdp_message_m_payload_add (msg,lineno, int_2char (0));
	}
	switch(desc->dir){
		case SalStreamSendRecv:
			/*dir="sendrecv";*/
			dir=NULL;
		break;
		case SalStreamRecvOnly:
			dir="recvonly";
			break;
		case SalStreamSendOnly:
			dir="sendonly";
			break;
		case SalStreamInactive:
			dir="inactive";
			break;
	}
	if (dir) sdp_message_a_attribute_add (msg, lineno, osip_strdup (dir),NULL);
}
Пример #6
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;
	}
}