Example #1
0
static void sdp_parse_media_ice_parameters(belle_sdp_media_description_t *media_desc, SalStreamDescription *stream) {
	belle_sip_list_t *attribute_it;
	belle_sdp_attribute_t *attribute;
	const char *att_name;
	const char *value;
	int nb_ice_candidates = 0;

	for (attribute_it = belle_sdp_media_description_get_attributes(media_desc); attribute_it != NULL; attribute_it=attribute_it->next) {
		attribute=BELLE_SDP_ATTRIBUTE(attribute_it->data);
		att_name = belle_sdp_attribute_get_name(attribute);
		value = belle_sdp_attribute_get_value(attribute);

		if (	(nb_ice_candidates < sizeof (stream->ice_candidates)/sizeof(SalIceCandidate))
				&& (keywordcmp("candidate", att_name) == 0)
				&& (value != NULL)) {
			SalIceCandidate *candidate = &stream->ice_candidates[nb_ice_candidates];
			char proto[4];
			int nb = sscanf(value, "%s %u %3s %u %s %d typ %s raddr %s rport %d",
				candidate->foundation, &candidate->componentID, proto, &candidate->priority, candidate->addr, &candidate->port,
				candidate->type, candidate->raddr, &candidate->rport);
			if (strcasecmp("udp",proto)==0 && ((nb == 7) || (nb == 9))) nb_ice_candidates++;
			else memset(candidate, 0, sizeof(*candidate));
		} else if ((keywordcmp("remote-candidates", att_name) == 0) && (value != NULL)) {
			SalIceRemoteCandidate candidate;
			unsigned int componentID;
			int offset;
			const char *ptr = value;
			const char *endptr = value + strlen(ptr);
			while (3 == sscanf(ptr, "%u %s %u%n", &componentID, candidate.addr, &candidate.port, &offset)) {
				if ((componentID > 0) && (componentID <= SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES)) {
					SalIceRemoteCandidate *remote_candidate = &stream->ice_remote_candidates[componentID - 1];
					strncpy(remote_candidate->addr, candidate.addr, sizeof(remote_candidate->addr)-1);
					remote_candidate->port = candidate.port;
				}
				ptr += offset;
				if (ptr < endptr) {
					if (ptr[offset] == ' ') ptr += 1;
				} else break;
			}
		} else if ((keywordcmp("ice-ufrag", att_name) == 0) && (value != NULL)) {
			strncpy(stream->ice_ufrag, value, sizeof(stream->ice_ufrag)-1);
		} else if ((keywordcmp("ice-pwd", att_name) == 0) && (value != NULL)) {
			strncpy(stream->ice_pwd, value, sizeof(stream->ice_pwd) -1);
		} else if (keywordcmp("ice-mismatch", att_name) == 0) {
			stream->ice_mismatch = TRUE;
		}
	}
}
Example #2
0
static int _sdp_message_get_mline_dir(sdp_message_t *sdp, int mline){
	int i;
	sdp_attribute_t *attr;
	for (i=0;(attr=sdp_message_attribute_get(sdp,mline,i))!=NULL;i++){
		if (keywordcmp("sendrecv",attr->a_att_field)==0){
			return SalStreamSendRecv;
		}else if (keywordcmp("sendonly",attr->a_att_field)==0){
			return SalStreamSendOnly;
		}else if (keywordcmp("recvonly",attr->a_att_field)==0){
			return SalStreamSendOnly;
		}else if (keywordcmp("inactive",attr->a_att_field)==0){
			return SalStreamInactive;
		}
	}
	return SalStreamSendRecv;
}
Example #3
0
static void sdp_parse_media_crypto_parameters(belle_sdp_media_description_t *media_desc, SalStreamDescription *stream) {
	belle_sip_list_t *attribute_it;
	belle_sdp_attribute_t *attribute;
	char tmp[256], tmp2[256];
	int valid_count = 0;
	int nb;

	memset ( &stream->crypto, 0, sizeof ( stream->crypto ) );
	for ( attribute_it=belle_sdp_media_description_get_attributes ( media_desc )
						; valid_count < SAL_CRYPTO_ALGO_MAX && attribute_it!=NULL;
			attribute_it=attribute_it->next ) {
		attribute=BELLE_SDP_ATTRIBUTE ( attribute_it->data );

		if ( keywordcmp ( "crypto",belle_sdp_attribute_get_name ( attribute ) ) ==0 && belle_sdp_attribute_get_value ( attribute ) !=NULL ) {
			nb = sscanf ( belle_sdp_attribute_get_value ( attribute ), "%d %256s inline:%256s",
							&stream->crypto[valid_count].tag,
							tmp,
							tmp2 );
			ms_message ( "Found valid crypto line (tag:%d algo:'%s' key:'%s'",
							stream->crypto[valid_count].tag,
							tmp,
							tmp2 );
			if ( nb == 3 ) {
				if ( keywordcmp ( "AES_CM_128_HMAC_SHA1_80",tmp ) == 0 )
					stream->crypto[valid_count].algo = AES_128_SHA1_80;
				else if ( keywordcmp ( "AES_CM_128_HMAC_SHA1_32",tmp ) == 0 )
					stream->crypto[valid_count].algo = AES_128_SHA1_32;
				else {
					ms_warning ( "Failed to parse crypto-algo: '%s'", tmp );
					stream->crypto[valid_count].algo = 0;
				}
				if ( stream->crypto[valid_count].algo ) {
					strncpy ( stream->crypto[valid_count].master_key, tmp2, 41 );
					stream->crypto[valid_count].master_key[40] = '\0';
					ms_message ( "Found valid crypto line (tag:%d algo:'%s' key:'%s'",
									stream->crypto[valid_count].tag,
									tmp,
									stream->crypto[valid_count].master_key );
					valid_count++;
				}
			} else {
				ms_warning ( "sdp has a strange a= line (%s) nb=%i",belle_sdp_attribute_get_value ( attribute ),nb );
			}
		}
	}
	ms_message ( "Found: %d valid crypto lines", valid_count );
}
Example #4
0
/* return the value of attr "field" */
static const char *sdp_message_a_attr_value_get(sdp_message_t *sdp,int pos,const char *field)
{
	int i;
	sdp_attribute_t *attr;
	for (i=0;(attr=sdp_message_attribute_get(sdp,pos,i))!=NULL;i++){
		if (keywordcmp(field,attr->a_att_field)==0 && attr->a_att_value!=NULL){
			return attr->a_att_value;
		}
	}
	return NULL;
}
Example #5
0
static bool_t sdp_parse_rtcp_fb_parameters(belle_sdp_media_description_t *media_desc, SalStreamDescription *stream) {
	belle_sip_list_t *it;
	belle_sdp_attribute_t *attribute;
	belle_sdp_rtcp_fb_attribute_t *fb_attribute;
	MSList *pt_it;
	PayloadType *pt;
	int8_t pt_num;
    bool_t retval = FALSE;
    
	/* Handle rtcp-fb attributes that concern all payload types. */
	for (it = belle_sdp_media_description_get_attributes(media_desc); it != NULL; it = it->next) {
		attribute = BELLE_SDP_ATTRIBUTE(it->data);
		if (keywordcmp("rtcp-fb", belle_sdp_attribute_get_name(attribute)) == 0) {
			fb_attribute = BELLE_SDP_RTCP_FB_ATTRIBUTE(attribute);
			if (belle_sdp_rtcp_fb_attribute_get_id(fb_attribute) == -1) {
				for (pt_it = stream->payloads; pt_it != NULL; pt_it = pt_it->next) {
					pt = (PayloadType *)pt_it->data;
					apply_rtcp_fb_attribute_to_payload(fb_attribute, stream, pt);
                    retval = TRUE;
				}
			}
		}
	}

	/* Handle rtcp-fb attributes that are specefic to a payload type. */
	for (it = belle_sdp_media_description_get_attributes(media_desc); it != NULL; it = it->next) {
		attribute = BELLE_SDP_ATTRIBUTE(it->data);
		if (keywordcmp("rtcp-fb", belle_sdp_attribute_get_name(attribute)) == 0) {
			fb_attribute = BELLE_SDP_RTCP_FB_ATTRIBUTE(attribute);
			pt_num = belle_sdp_rtcp_fb_attribute_get_id(fb_attribute);
			for (pt_it = stream->payloads; pt_it != NULL; pt_it = pt_it->next) {
				pt = (PayloadType *)pt_it->data;
                retval = TRUE;
				if (payload_type_get_number(pt) == (int)pt_num) {
					apply_rtcp_fb_attribute_to_payload(fb_attribute, stream, pt);
				}
			}
		}
	}
    return retval;
}
Example #6
0
MSCryptoSuite ms_crypto_suite_build_from_name_params(const MSCryptoSuiteNameParams *descrption){
	const char *name=descrption->name, *parameters=descrption->params;
	if (keywordcmp ( "AES_CM_128_HMAC_SHA1_80",name ) == 0 ){
		if (parameters && strstr(parameters,"UNENCRYPTED_SRTP")) return MS_NO_CIPHER_SHA1_80;
		else if (parameters && strstr(parameters,"UNAUTHENTICATED_SRTP")) return MS_AES_128_NO_AUTH;
		else return MS_AES_128_SHA1_80;
	}else if ( keywordcmp ( "AES_CM_128_HMAC_SHA1_32",name ) == 0 ){
		if (parameters && strstr(parameters,"UNENCRYPTED_SRTP")) goto error;
		if (parameters && strstr(parameters,"UNAUTHENTICATED_SRTP")) return MS_AES_128_NO_AUTH;
		else return MS_AES_128_SHA1_32;
	}else if ( keywordcmp ("AES_256_CM_HMAC_SHA1_32", name) == 0 ){
		if (parameters && strstr(parameters,"UNENCRYPTED_SRTP")) goto error;
		if (parameters && strstr(parameters,"UNAUTHENTICATED_SRTP")) goto error;
		return MS_AES_256_SHA1_32;
	}else if ( keywordcmp ("AES_256_CM_HMAC_SHA1_80", name) == 0 ){
		if (parameters && strstr(parameters,"UNENCRYPTED_SRTP")) goto error;
		if (parameters && strstr(parameters,"UNAUTHENTICATED_SRTP")) goto error;
		return MS_AES_256_SHA1_80;
	}
error:
	ms_error("Unsupported crypto suite '%s' with parameters '%s'",name, parameters ? parameters : "");
	return MS_CRYPTO_SUITE_INVALID;
}
Example #7
0
static int _sdp_message_get_a_ptime(sdp_message_t *sdp, int mline){
	int i,ret;
	sdp_attribute_t *attr;
	for (i=0;(attr=sdp_message_attribute_get(sdp,mline,i))!=NULL;i++){
		if (keywordcmp("ptime",attr->a_att_field)==0){
			int nb = sscanf(attr->a_att_value,"%i",&ret);
			/* the return value may depend on how %n is interpreted by the libc: see manpage*/
			if (nb == 1){
				return ret;
			}else ms_warning("sdp has a strange a=ptime line (%s) ",attr->a_att_value);
		}
	}
	return 0;
}
Example #8
0
static void sdp_parse_media_crypto_parameters(belle_sdp_media_description_t *media_desc, SalStreamDescription *stream) {
	belle_sip_list_t *attribute_it;
	belle_sdp_attribute_t *attribute;
	char tmp[256], tmp2[256], parameters[256]={0};
	int valid_count = 0;
	int nb;

	memset ( &stream->crypto, 0, sizeof ( stream->crypto ) );
	for ( attribute_it=belle_sdp_media_description_get_attributes ( media_desc )
						; valid_count < SAL_CRYPTO_ALGO_MAX && attribute_it!=NULL;
			attribute_it=attribute_it->next ) {
		attribute=BELLE_SDP_ATTRIBUTE ( attribute_it->data );

		if ( keywordcmp ( "crypto",belle_sdp_attribute_get_name ( attribute ) ) ==0 && belle_sdp_attribute_get_value ( attribute ) !=NULL ) {
			nb = sscanf ( belle_sdp_attribute_get_value ( attribute ), "%d %256s inline:%256s %256s",
							&stream->crypto[valid_count].tag,
							tmp,
							tmp2, parameters );
			
			if ( nb >= 3 ) {
				MSCryptoSuite cs;
				MSCryptoSuiteNameParams np;

				np.name=tmp;
				np.params=parameters[0]!='\0' ? parameters : NULL;
				cs=ms_crypto_suite_build_from_name_params(&np);
				if (cs==MS_CRYPTO_SUITE_INVALID){
					ms_warning ( "Failed to parse crypto-algo: '%s'", tmp );
					stream->crypto[valid_count].algo = 0;
				}else{
					char *sep;
					strncpy ( stream->crypto[valid_count].master_key, tmp2, sizeof(stream->crypto[valid_count].master_key)-1 );
					sep=strchr(stream->crypto[valid_count].master_key,'|');
					if (sep) *sep='\0';
					stream->crypto[valid_count].algo = cs;
					ms_message ( "Found valid crypto line (tag:%d algo:'%s' key:'%s'",
									stream->crypto[valid_count].tag,
									tmp,
									stream->crypto[valid_count].master_key );
					valid_count++;
				}
			}else{
				ms_warning ( "sdp has a strange a= line (%s) nb=%i",belle_sdp_attribute_get_value ( attribute ),nb );
			}
		}
	}
	ms_message("Found: %d valid crypto lines", valid_count );
}
Example #9
0
/* return the value of attr "field" for payload pt at line pos (field=rtpmap,fmtp...)*/
static const char *sdp_message_a_attr_value_get_with_pt(sdp_message_t *sdp,int pos,int pt,const char *field)
{
	int i,tmppt=0,scanned=0;
	char *tmp;
	sdp_attribute_t *attr;
	for (i=0;(attr=sdp_message_attribute_get(sdp,pos,i))!=NULL;i++){
		if (keywordcmp(field,attr->a_att_field)==0 && attr->a_att_value!=NULL){
			int nb = sscanf(attr->a_att_value,"%i %n",&tmppt,&scanned);
			/* the return value may depend on how %n is interpreted by the libc: see manpage*/
			if (nb == 1 || nb==2 ){
				if (pt==tmppt){
					tmp=attr->a_att_value+scanned;
					if (strlen(tmp)>0)
						return tmp;
				}
			}else ms_warning("sdp has a strange a= line (%s) nb=%i",attr->a_att_value,nb);
		}
	}
	return NULL;
}
Example #10
0
void CScriptDlg::OnChar(char ch)
{
	CScintillaWnd* pSelected = GetSelectedScintilla();

	long pos = pSelected->GetCurrentPosition();
	CString text = pSelected->GetText();

	if(pos > 3)
	{
		if(text.GetAt(pos-2) == '=')
		{
			if(text.GetAt(pos-3) != '!'
				&& text.GetAt(pos-3) != '<'
				&& text.GetAt(pos-3) != '>')
			{
				// we have typed something like x = 0
				// check to see if theres an 'if' at the start of the line
				
				char linebuf[1000];
				int curLine  =  pSelected->SendMessage(SCI_LINEFROMPOSITION, pos);
				int LineLength  =  pSelected->SendMessage(SCI_LINELENGTH,  curLine);

				WORD buflen = sizeof(linebuf);
				memcpy(linebuf,  &buflen,  sizeof(buflen));
				pSelected->SendMessage(SCI_GETLINE,  curLine,
				reinterpret_cast<LPARAM>(static_cast<char  *>(linebuf)));
				linebuf[LineLength]  =  '\0';

				char* strpos = &linebuf[0];
				for(int a = 0; a < LineLength; a++)
				{
					if(linebuf[a] == '\t' || linebuf[a] == ' ')
						strpos ++;
					else
						break;
				}

				if(keywordcmp(strpos, "if") || keywordcmp(strpos, "while") )
				{
					//okay the user has type something like: if x=0
					// so go back a char, insert another = so the user gets
					// if x==0
					pSelected->GotoPosition(pos-1);
					char equals[] = "=";
					 
					pSelected->SendMessage(SCI_REPLACESEL,  0, (LPARAM)equals);

					pos ++;
					pSelected->GotoPosition(pos);
				}
			}
		}
	}
	// The following code enables autoindent and autocolon to help out the programmer.

	if  (ch  ==  '\r'  ||  ch  ==  '\n') 
	{
		 char  linebuf[1000];
		 int  curLine  =  pSelected->SendMessage(SCI_LINEFROMPOSITION, pos+1);
		 int  lineLength  =  pSelected->SendMessage(SCI_LINELENGTH,  curLine);

		 if  (curLine  >  0  &&  lineLength  <=  2)  
		 {
			 int  prevLineLength  =  pSelected->SendMessage(SCI_LINELENGTH,  curLine  -  1);
			 if  (prevLineLength  <  sizeof(linebuf))  
			 {
				 WORD  buflen  =  sizeof(linebuf);
				 memcpy(linebuf,  &buflen,  sizeof(buflen));
				 pSelected->SendMessage(SCI_GETLINE,  curLine  -  1,
						reinterpret_cast<LPARAM>(static_cast<char  *>(linebuf)));
				 linebuf[prevLineLength]  =  '\0';
	
			
				 bool indent = false;
				 bool addcolon = false;

				 for  (int  p  =  0;  linebuf[p];  p++)  
				 { 
					 // note: space at the end to prevent errors
					 if (keywordcmp(&linebuf[p], "def")
						|| keywordcmp( &linebuf[p], "class")
						|| keywordcmp( &linebuf[p], "for")	
						|| keywordcmp( &linebuf[p], "while")
						|| keywordcmp( &linebuf[p], "if"))
					 {
						 addcolon = true;
						 indent = true;
					 }
					 if(keywordcmp(&linebuf[p], ":"))
					 {
						 indent = true;
						 addcolon = false;
					 }			 
				 }

				 int bracketdepth = 0;
				 for  (int  p  =  0;  linebuf[p];  p++)  
				 { 
					if (linebuf[p] == '(')
						 bracketdepth ++;
					 if (linebuf[p] == ')')
						 bracketdepth --;
					 if  (linebuf[p]  !=  ' '  &&  linebuf[p]  !=  '\t')
						linebuf[p]  =  '\0';

				 }

				 while(bracketdepth > 0)
				 {
					 pSelected->GotoPosition(pos-1);
					 char colon[] = ")";
					 
					 pSelected->SendMessage(SCI_REPLACESEL,  0, (LPARAM)colon);

					 pos ++;
					 pSelected->GotoPosition(pos);
					 bracketdepth --;
				 }
				 if(addcolon)
				 {
					 pSelected->GotoPosition(pos-1);
					 char colon[] = ":";
					 pSelected->SendMessage(SCI_REPLACESEL,  0, (LPARAM)colon);
					 pSelected->GotoPosition(pos+1);
				 }
				 pSelected->SendMessage(SCI_REPLACESEL,  0, (LPARAM)linebuf);
				 if(indent)
				 {
					 char tab[] = "\t";
					 pSelected->SendMessage(SCI_REPLACESEL,  0, (LPARAM)tab);
				 }
			 }
		}

	}
	if(ch == ')')
	{
		char linebuf[1000];
		int curLine  =  pSelected->SendMessage(SCI_LINEFROMPOSITION, pos);
		int LineLength  =  pSelected->SendMessage(SCI_LINELENGTH,  curLine);

		WORD buflen = sizeof(linebuf);
		memcpy(linebuf,  &buflen,  sizeof(buflen));
		pSelected->SendMessage(SCI_GETLINE,  curLine,
		reinterpret_cast<LPARAM>(static_cast<char  *>(linebuf)));
		linebuf[LineLength]  =  '\0';
		int bracketlevel = 0;
		for( int c = 0; c < LineLength; c++)
		{
			if(linebuf[c] == '(')
				bracketlevel ++;
			if(linebuf[c] == ')')
				bracketlevel --;
		}
		if(bracketlevel < 0)
		{
			pSelected->SendMessage(SCI_SETSEL, pos-1, pos);
			char blank[] = "";
			pSelected->SendMessage(SCI_REPLACESEL,  0, (LPARAM)blank);

		}
	}
	return;
}
Example #11
0
int sdp_to_media_description ( belle_sdp_session_description_t  *session_desc, SalMediaDescription *desc ) {
	/*
	typedef struct SalMediaDescription{
		int refcount;
		char addr[64];
		char username[64];
		int nstreams;
		int bandwidth;
		unsigned int session_ver;
		unsigned int session_id;
		SalStreamDescription streams[SAL_MEDIA_DESCRIPTION_MAX_STREAMS];
	} SalMediaDescription;
	 */
	belle_sdp_connection_t* cnx;
	belle_sip_list_t* media_desc_it;
	belle_sdp_media_description_t* media_desc;
	const char *mtype,*proto;
	SalStreamDescription *stream;
	belle_sdp_media_t* media;
	belle_sip_list_t* mime_params=NULL;
	belle_sip_list_t* mime_param_it=NULL;
	belle_sdp_mime_parameter_t* mime_param;
	PayloadType *pt;
	belle_sip_list_t* attribute_it;
	const belle_sdp_attribute_t* attribute;
	int valid_count = 0;
	char tmp[256], tmp2[256];
	int nb=0;
	SalStreamDir stream_dir=SalStreamSendRecv;
	const char* value;
	
	desc->n_active_streams = 0;
	desc->n_total_streams = 0;

	if ( ( cnx=belle_sdp_session_description_get_connection ( session_desc ) ) && belle_sdp_connection_get_address ( cnx ) ) {
		strncpy ( desc->addr,belle_sdp_connection_get_address ( cnx ),sizeof ( desc->addr ) );
	}
	if ( belle_sdp_session_description_get_bandwidth ( session_desc,"AS" ) >0 ) {
		desc->bandwidth=belle_sdp_session_description_get_bandwidth ( session_desc,"AS" );
	}
	/*in some very rare case, session attribute may set stream dir*/
	if ( belle_sdp_session_description_get_attribute ( session_desc,"sendrecv" ) ) {
		stream_dir=SalStreamSendRecv;
	} else if ( belle_sdp_session_description_get_attribute ( session_desc,"sendonly" ) ) {
		stream_dir=SalStreamSendOnly;
	} else if ( belle_sdp_session_description_get_attribute ( session_desc,"recvonly" ) ) {
		stream_dir=SalStreamRecvOnly;
	} else if ( belle_sdp_session_description_get_attribute ( session_desc,"inactive" ) ) {
		stream_dir=SalStreamInactive;
	}

	/* Get ICE remote ufrag and remote pwd, and ice_lite flag */
	value=belle_sdp_session_description_get_attribute_value(session_desc,"ice-ufrag");
	if (value) strncpy(desc->ice_ufrag, value, sizeof(desc->ice_ufrag));
	
	value=belle_sdp_session_description_get_attribute_value(session_desc,"ice-pwd");
	if (value) strncpy(desc->ice_pwd, value, sizeof(desc->ice_pwd));
	
	value=belle_sdp_session_description_get_attribute_value(session_desc,"ice-lite");
	if (value) desc->ice_lite = TRUE;
	
	for ( media_desc_it=belle_sdp_session_description_get_media_descriptions ( session_desc )
						; media_desc_it!=NULL
			; media_desc_it=media_desc_it->next ) {
		int nb_ice_candidates=0;
		media_desc=BELLE_SDP_MEDIA_DESCRIPTION ( media_desc_it->data );
		stream=&desc->streams[desc->n_total_streams];
		media=belle_sdp_media_description_get_media ( media_desc );

		memset ( stream,0,sizeof ( *stream ) );

		proto = belle_sdp_media_get_protocol ( media );
		stream->proto=SalProtoUnknown;
		if ( proto ) {
			if ( strcasecmp ( proto,"RTP/AVP" ) ==0 )
				stream->proto=SalProtoRtpAvp;
			else if ( strcasecmp ( proto,"RTP/SAVP" ) ==0 ) {
				stream->proto=SalProtoRtpSavp;
			}
		}
		if ( ( cnx=belle_sdp_media_description_get_connection ( media_desc ) ) && belle_sdp_connection_get_address ( cnx ) ) {
			strncpy ( stream->rtp_addr,belle_sdp_connection_get_address ( cnx ),sizeof ( stream->rtp_addr ) );
		}

		stream->rtp_port=belle_sdp_media_get_media_port ( media );

		if ( stream->rtp_port > 0 )
			desc->n_active_streams++;

		mtype = belle_sdp_media_get_media_type ( media );
		if ( strcasecmp ( "audio", mtype ) == 0 ) {
			stream->type=SalAudio;
		} else if ( strcasecmp ( "video", mtype ) == 0 ) {
			stream->type=SalVideo;
		} else {
			stream->type=SalOther;
			strncpy ( stream->typeother,mtype,sizeof ( stream->typeother )-1 );
		}

		if ( belle_sdp_media_description_get_bandwidth ( media_desc,"AS" ) >0 ) {
			stream->bandwidth=belle_sdp_media_description_get_bandwidth ( media_desc,"AS" );
		}


		if ( belle_sdp_media_description_get_attribute ( media_desc,"sendrecv" ) ) {
			stream->dir=SalStreamSendRecv;
		} else if ( belle_sdp_media_description_get_attribute ( media_desc,"sendonly" ) ) {
			stream->dir=SalStreamSendOnly;
		} else if ( belle_sdp_media_description_get_attribute ( media_desc,"recvonly" ) ) {
			stream->dir=SalStreamRecvOnly;
		} else if ( belle_sdp_media_description_get_attribute ( media_desc,"inactive" ) ) {
			stream->dir=SalStreamInactive;
		} else {
			stream->dir=stream_dir; /*takes default value if not present*/
		}

		/* for each payload type */
		mime_params=belle_sdp_media_description_build_mime_parameters ( media_desc );
		for ( mime_param_it=mime_params
							; mime_param_it!=NULL
				; mime_param_it=mime_param_it->next ) {
			mime_param=BELLE_SDP_MIME_PARAMETER ( mime_param_it->data )

					   pt=payload_type_new();
			payload_type_set_number ( pt,belle_sdp_mime_parameter_get_media_format ( mime_param ) );
			pt->clock_rate=belle_sdp_mime_parameter_get_rate ( mime_param );
			pt->mime_type=ms_strdup ( belle_sdp_mime_parameter_get_type ( mime_param ) );
			pt->channels=belle_sdp_mime_parameter_get_channel_count ( mime_param );
			payload_type_set_send_fmtp ( pt,belle_sdp_mime_parameter_get_parameters ( mime_param ) );
			stream->payloads=ms_list_append ( stream->payloads,pt );
			stream->ptime=belle_sdp_mime_parameter_get_ptime ( mime_param );
			ms_message ( "Found payload %s/%i fmtp=%s",pt->mime_type,pt->clock_rate,
						 pt->send_fmtp ? pt->send_fmtp : "" );
		}
		if ( mime_params ) belle_sip_list_free_with_data ( mime_params,belle_sip_object_unref );
		
		
		/* Get media specific RTCP attribute */
		stream->rtcp_port = stream->rtp_port + 1;
		snprintf(stream->rtcp_addr, sizeof(stream->rtcp_addr), "%s", stream->rtp_addr);
		attribute=belle_sdp_media_description_get_attribute(media_desc,"rtcp");
		if (attribute && (value=belle_sdp_attribute_get_value(attribute))!=NULL){
			char tmp[256];
			int nb = sscanf(value, "%d IN IP4 %s", &stream->rtcp_port, tmp);
			if (nb == 1) {
				/* SDP rtcp attribute only contains the port */
			} else if (nb == 2) {
				strncpy(stream->rtcp_addr, tmp, sizeof(stream->rtcp_addr));
			} else {
				ms_warning("sdp has a strange a=rtcp line (%s) nb=%i", value, nb);
			}
		}
		
		/* read crypto lines if any */
		if ( stream->proto == SalProtoRtpSavp ) {
			valid_count=0;
			memset ( &stream->crypto, 0, sizeof ( stream->crypto ) );
			for ( attribute_it=belle_sdp_media_description_get_attributes ( media_desc )
							   ; valid_count < SAL_CRYPTO_ALGO_MAX && attribute_it!=NULL;
					attribute_it=attribute_it->next ) {
				attribute=BELLE_SDP_ATTRIBUTE ( attribute_it->data );

				if ( keywordcmp ( "crypto",belle_sdp_attribute_get_name ( attribute ) ) ==0 && belle_sdp_attribute_get_value ( attribute ) !=NULL ) {
					nb = sscanf ( belle_sdp_attribute_get_value ( attribute ), "%d %256s inline:%256s",
								  &stream->crypto[valid_count].tag,
								  tmp,
								  tmp2 );
					ms_message ( "Found valid crypto line (tag:%d algo:'%s' key:'%s'",
								 stream->crypto[valid_count].tag,
								 tmp,
								 tmp2 );
					if ( nb == 3 ) {
						if ( keywordcmp ( "AES_CM_128_HMAC_SHA1_80",tmp ) == 0 )
							stream->crypto[valid_count].algo = AES_128_SHA1_80;
						else if ( keywordcmp ( "AES_CM_128_HMAC_SHA1_32",tmp ) == 0 )
							stream->crypto[valid_count].algo = AES_128_SHA1_32;
						else {
							ms_warning ( "Failed to parse crypto-algo: '%s'", tmp );
							stream->crypto[valid_count].algo = 0;
						}
						if ( stream->crypto[valid_count].algo ) {
							strncpy ( stream->crypto[valid_count].master_key, tmp2, 41 );
							stream->crypto[valid_count].master_key[40] = '\0';
							ms_message ( "Found valid crypto line (tag:%d algo:'%s' key:'%s'",
										 stream->crypto[valid_count].tag,
										 tmp,
										 stream->crypto[valid_count].master_key );
							valid_count++;
						}
					} else {
						ms_warning ( "sdp has a strange a= line (%s) nb=%i",belle_sdp_attribute_get_value ( attribute ),nb );
					}
				}
			}
			ms_message ( "Found: %d valid crypto lines", valid_count );
		}
		
		/* Get ICE candidate attributes if any */
		for (attribute_it = belle_sdp_media_description_get_attributes(media_desc); attribute_it != NULL; attribute_it=attribute_it->next) {
			const char *att_name;
			attribute=(belle_sdp_attribute_t*)attribute_it->data;
			att_name=belle_sdp_attribute_get_name(attribute);
			value=belle_sdp_attribute_get_value(attribute);
			if ((keywordcmp("candidate", att_name) == 0) && (value != NULL)) {
				SalIceCandidate *candidate = &stream->ice_candidates[nb_ice_candidates];
				int nb = sscanf(value, "%s %u UDP %u %s %d typ %s raddr %s rport %d",
					candidate->foundation, &candidate->componentID, &candidate->priority, candidate->addr, &candidate->port,
					candidate->type, candidate->raddr, &candidate->rport);
				if ((nb == 6) || (nb == 8)) nb_ice_candidates++;
				else memset(candidate, 0, sizeof(*candidate));
			} else if ((keywordcmp("remote-candidates", att_name) == 0) && (value != NULL)) {
				SalIceRemoteCandidate candidate;
				unsigned int componentID;
				int offset;
				const char *ptr = value;
				const char *endptr=value+strlen(ptr);
				while (3 == sscanf(ptr, "%u %s %u%n", &componentID, candidate.addr, &candidate.port, &offset)) {
					if ((componentID > 0) && (componentID <= SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES)) {
						SalIceRemoteCandidate *remote_candidate = &stream->ice_remote_candidates[componentID - 1];
						strncpy(remote_candidate->addr, candidate.addr, sizeof(remote_candidate->addr));
						remote_candidate->port = candidate.port;
					}
					ptr += offset;
					if (ptr<endptr){
						if (ptr[offset] == ' ') ptr += 1;
					}else break;
				}
			} else if ((keywordcmp("ice-ufrag", att_name) == 0) && (value != NULL)) {
				strncpy(stream->ice_ufrag, value, sizeof(stream->ice_ufrag));
			} else if ((keywordcmp("ice-pwd", att_name) == 0) && (value != NULL)) {
				strncpy(stream->ice_pwd, value, sizeof(stream->ice_pwd));
			} else if (keywordcmp("ice-mismatch", att_name) == 0) {
				stream->ice_mismatch = TRUE;
			}
		}
		desc->n_total_streams++;
	}
	return 0;
}
Example #12
0
void
sdp_context_read_answer (sdp_context_t *ctx, sdp_message_t *remote)
{
	char *mtype;
	char *proto, *port, *pt;
	int i, j,err;
	char *relay;
	sdp_payload_t payload,arg_payload;
	sdp_handler_t *sdph=ctx->handler;
	sdp_bandwidth_t *sbw=NULL;
	/* 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.localport = osip_atoi (sdp_message_m_port_get (ctx->offer, i));
		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");
		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->get_audio_codecs != NULL)
			{
				/* 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 */
					memcpy(&arg_payload,&payload,sizeof(payload));
					err = sdph->get_audio_codecs (ctx,
								      &arg_payload);
				}
			}
		}
		else if (keywordcmp ("video", mtype) == 0)
		{
			if (sdph->get_video_codecs != NULL)
			{
				/* 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 */
					memcpy(&arg_payload,&payload,sizeof(payload));
					err = sdph->get_video_codecs (ctx,
									 &arg_payload);
				}
			}
		}
	}
}
Example #13
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;
	}
}