예제 #1
0
static void initiate_incoming(const SalStreamDescription *local_cap,
                              const SalStreamDescription *remote_offer,
                              SalStreamDescription *result, bool_t one_matching_codec) {
    result->payloads=match_payloads(local_cap->payloads,remote_offer->payloads, FALSE, one_matching_codec);
    result->proto=remote_offer->proto;
    result->type=local_cap->type;
    result->dir=compute_dir_incoming(local_cap->dir,remote_offer->dir);
    if (result->payloads && !only_telephone_event(result->payloads) && (remote_offer->rtp_port!=0 || remote_offer->rtp_port==SalStreamSendOnly)) {
        strcpy(result->rtp_addr,local_cap->rtp_addr);
        strcpy(result->rtcp_addr,local_cap->rtcp_addr);
        result->rtp_port=local_cap->rtp_port;
        result->rtcp_port=local_cap->rtcp_port;
        result->bandwidth=local_cap->bandwidth;
        result->ptime=local_cap->ptime;
    } else {
        result->rtp_port=0;
    }
    if (sal_stream_description_has_srtp(result) == TRUE) {
        /* select crypto algo */
        memset(result->crypto, 0, sizeof(result->crypto));
        if (!match_crypto_algo(local_cap->crypto, remote_offer->crypto, &result->crypto[0], &result->crypto_local_tag, TRUE))
            result->rtp_port = 0;

    }
    strcpy(result->ice_pwd, local_cap->ice_pwd);
    strcpy(result->ice_ufrag, local_cap->ice_ufrag);
    result->ice_mismatch = local_cap->ice_mismatch;
    result->ice_completed = local_cap->ice_completed;
    memcpy(result->ice_candidates, local_cap->ice_candidates, sizeof(result->ice_candidates));
    memcpy(result->ice_remote_candidates, local_cap->ice_remote_candidates, sizeof(result->ice_remote_candidates));
    strcpy(result->name,local_cap->name);
}
예제 #2
0
static void initiate_outgoing(const SalStreamDescription *local_offer,
                              const SalStreamDescription *remote_answer,
                              SalStreamDescription *result) {
    if (remote_answer->rtp_port!=0)
        result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads,TRUE,FALSE);
    result->proto=remote_answer->proto;
    result->type=local_offer->type;
    result->dir=compute_dir_outgoing(local_offer->dir,remote_answer->dir);

    if (result->payloads && !only_telephone_event(result->payloads)) {
        strcpy(result->rtp_addr,remote_answer->rtp_addr);
        strcpy(result->rtcp_addr,remote_answer->rtcp_addr);
        result->rtp_port=remote_answer->rtp_port;
        result->rtcp_port=remote_answer->rtcp_port;
        result->bandwidth=remote_answer->bandwidth;
        result->ptime=remote_answer->ptime;
    } else {
        result->rtp_port=0;
    }
    if (sal_stream_description_has_srtp(result) == TRUE) {
        /* verify crypto algo */
        memset(result->crypto, 0, sizeof(result->crypto));
        if (!match_crypto_algo(local_offer->crypto, remote_answer->crypto, &result->crypto[0], &result->crypto_local_tag, FALSE))
            result->rtp_port = 0;
    }
}
예제 #3
0
static void initiate_incoming(const SalStreamDescription *local_cap,
                              const SalStreamDescription *remote_offer,
                              SalStreamDescription *result, bool_t one_matching_codec) {
    result->payloads=match_payloads(local_cap->payloads,remote_offer->payloads, FALSE, one_matching_codec);
    result->proto=local_cap->proto;
    result->type=local_cap->type;
    result->dir=compute_dir_incoming(local_cap->dir,remote_offer->dir);
    if (result->payloads && !only_telephone_event(result->payloads)) {
        strcpy(result->addr,local_cap->addr);
        memcpy(result->candidates,local_cap->candidates,sizeof(result->candidates));
        result->port=local_cap->port;
        result->bandwidth=local_cap->bandwidth;
        result->ptime=local_cap->ptime;
    } else {
        result->port=0;
    }
}
예제 #4
0
static void initiate_outgoing(const SalStreamDescription *local_offer,
                              const SalStreamDescription *remote_answer,
                              SalStreamDescription *result) {
    if (remote_answer->port!=0)
        result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads,TRUE,FALSE);
    result->proto=local_offer->proto;
    result->type=local_offer->type;
    result->dir=compute_dir_outgoing(local_offer->dir,remote_answer->dir);

    if (result->payloads && !only_telephone_event(result->payloads)) {
        strcpy(result->addr,remote_answer->addr);
        result->port=remote_answer->port;
        result->bandwidth=remote_answer->bandwidth;
        result->ptime=remote_answer->ptime;
    } else {
        result->port=0;
    }
}
예제 #5
0
static void initiate_incoming(const SalStreamDescription *local_cap,
    					const SalStreamDescription *remote_offer,
    					SalStreamDescription *result, bool_t one_matching_codec){
	result->payloads=match_payloads(local_cap->payloads,remote_offer->payloads, FALSE, one_matching_codec);
	result->proto=remote_offer->proto;
	result->type=local_cap->type;
	result->dir=compute_dir_incoming(local_cap->dir,remote_offer->dir);
	if (result->payloads && !only_telephone_event(result->payloads) && (remote_offer->port!=0 || remote_offer->port==SalStreamSendOnly)){
		strcpy(result->addr,local_cap->addr);
		memcpy(result->candidates,local_cap->candidates,sizeof(result->candidates));
		result->port=local_cap->port;
		result->bandwidth=local_cap->bandwidth;
		result->ptime=local_cap->ptime;	
	}else{
		result->port=0;
	}
	if (result->proto == SalProtoRtpSavp) {
		/* select crypto algo */
		memset(result->crypto, 0, sizeof(result->crypto));
		if (!match_crypto_algo(local_cap->crypto, remote_offer->crypto, &result->crypto[0], &result->crypto_local_tag, TRUE))
			result->port = 0; 
		
	}
}
예제 #6
0
static void initiate_incoming(MSFactory *factory, const SalStreamDescription *local_cap,
						const SalStreamDescription *remote_offer,
						SalStreamDescription *result, bool_t one_matching_codec){
	result->payloads=match_payloads(factory, local_cap->payloads,remote_offer->payloads, FALSE, one_matching_codec);
	result->proto=remote_offer->proto;
	result->type=local_cap->type;
	result->dir=compute_dir_incoming(local_cap->dir,remote_offer->dir);
	if (!result->payloads || only_telephone_event(result->payloads) || remote_offer->rtp_port==0){
		result->rtp_port=0;
		return;
	}
	if (remote_offer->rtp_addr[0]!='\0' && ms_is_multicast(remote_offer->rtp_addr)) {
		if (sal_stream_description_has_srtp(result) == TRUE) {
			ms_message("SAVP not supported for multicast address for remote stream [%p]",remote_offer);
			result->rtp_port=0;
			return;
		}
		result->dir=remote_offer->dir;
		strcpy(result->rtp_addr,remote_offer->rtp_addr);
		strcpy(result->rtcp_addr,remote_offer->rtcp_addr);
		result->rtp_port=remote_offer->rtp_port;
		/*result->rtcp_port=remote_offer->rtcp_port;*/
		result->rtcp_port=0; /* rtcp not supported yet*/
		result->bandwidth=remote_offer->bandwidth;
		result->ptime=remote_offer->ptime;
		result->ttl=remote_offer->ttl;
		result->multicast_role = SalMulticastReceiver;
	} else {
		strcpy(result->rtp_addr,local_cap->rtp_addr);
		strcpy(result->rtcp_addr,local_cap->rtcp_addr);
		result->rtp_port=local_cap->rtp_port;
		result->rtcp_port=local_cap->rtcp_port;
		result->bandwidth=local_cap->bandwidth;
		result->ptime=local_cap->ptime;
	}

	if (sal_stream_description_has_srtp(result) == TRUE) {
		/* select crypto algo */
		memset(result->crypto, 0, sizeof(result->crypto));
		if (!match_crypto_algo(local_cap->crypto, remote_offer->crypto, &result->crypto[0], &result->crypto_local_tag, TRUE)) {
			result->rtp_port = 0;
			ms_message("No matching crypto algo for remote stream's offer [%p]",remote_offer);
		}

	}

	if (remote_offer->haveZrtpHash == 1) {
		if (ms_zrtp_available()) { /* if ZRTP is available, set the zrtp hash even if it is not selected */
			strncpy((char *)(result->zrtphash), (char *)(local_cap->zrtphash), sizeof(local_cap->zrtphash));
			result->haveZrtpHash =  1;
		}
	}

	strcpy(result->ice_pwd, local_cap->ice_pwd);
	strcpy(result->ice_ufrag, local_cap->ice_ufrag);
	result->ice_mismatch = local_cap->ice_mismatch;
	result->set_nortpproxy = local_cap->set_nortpproxy;
	memcpy(result->ice_candidates, local_cap->ice_candidates, sizeof(result->ice_candidates));
	memcpy(result->ice_remote_candidates, local_cap->ice_remote_candidates, sizeof(result->ice_remote_candidates));
	strcpy(result->name,local_cap->name);
	result->rtp_ssrc=local_cap->rtp_ssrc;
	strncpy(result->rtcp_cname,local_cap->rtcp_cname,sizeof(result->rtcp_cname));

	// Handle dtls stream attribute: if both local and remote have a dtls fingerprint and a dtls setup, add the local fingerprint to the answer
	// Note: local description usually stores dtls config at session level which means it apply to all streams, check this too
	if (((local_cap->dtls_role!=SalDtlsRoleInvalid)) && (remote_offer->dtls_role!=SalDtlsRoleInvalid)
			&& (strlen(local_cap->dtls_fingerprint)>0) && (strlen(remote_offer->dtls_fingerprint)>0)) {
		strncpy(result->dtls_fingerprint, local_cap->dtls_fingerprint,sizeof(result->dtls_fingerprint));
		if (remote_offer->dtls_role==SalDtlsRoleUnset) {
			result->dtls_role = SalDtlsRoleIsClient;
		}
	} else {
		result->dtls_fingerprint[0] = '\0';
		result->dtls_role = SalDtlsRoleInvalid;
	}
	result->rtcp_mux = remote_offer->rtcp_mux && local_cap->rtcp_mux;
    result->implicit_rtcp_fb = local_cap->implicit_rtcp_fb && remote_offer->implicit_rtcp_fb;
}
예제 #7
0
static void initiate_outgoing(MSFactory* factory, const SalStreamDescription *local_offer,
						const SalStreamDescription *remote_answer,
						SalStreamDescription *result){
	if (remote_answer->rtp_port!=0)
		result->payloads=match_payloads(factory, local_offer->payloads,remote_answer->payloads,TRUE,FALSE);
	else {
		ms_message("Local stream description [%p] rejected by peer",local_offer);
		result->rtp_port=0;
		return;
	}
	result->proto=remote_answer->proto;
	result->type=local_offer->type;

	if (local_offer->rtp_addr[0]!='\0' && ms_is_multicast(local_offer->rtp_addr)) {
			/*6.2 Multicast Streams
			...
		If a multicast stream is accepted, the address and port information
		in the answer MUST match that of the offer.  Similarly, the
		directionality information in the answer (sendonly, recvonly, or
		sendrecv) MUST equal that of the offer.  This is because all
		participants in a multicast session need to have equivalent views of
		the parameters of the session, an underlying assumption of the
		multicast bias of RFC 2327.*/
		if (strcmp(local_offer->rtp_addr,remote_answer->rtp_addr) !=0 ) {
			ms_message("Remote answered IP [%s] does not match offered [%s] for local stream description [%p]"
																,remote_answer->rtp_addr
																,local_offer->rtp_addr
																,local_offer);
			result->rtp_port=0;
			return;
		}
		if (local_offer->rtp_port!=remote_answer->rtp_port) {
			ms_message("Remote answered rtp port [%i] does not match offered [%i] for local stream description [%p]"
																,remote_answer->rtp_port
																,local_offer->rtp_port
																,local_offer);
			result->rtp_port=0;
			return;
		}
		if (local_offer->dir!=remote_answer->dir) {
			ms_message("Remote answered dir [%s] does not match offered [%s] for local stream description [%p]"
																,sal_stream_dir_to_string(remote_answer->dir)
																,sal_stream_dir_to_string(local_offer->dir)
																,local_offer);
			result->rtp_port=0;
			return;
		}
		if (local_offer->bandwidth!=remote_answer->bandwidth) {
			ms_message("Remote answered bandwidth [%i] does not match offered [%i] for local stream description [%p]"
																,remote_answer->bandwidth
																,local_offer->bandwidth
																,local_offer);
			result->rtp_port=0;
			return;
		}
		if (local_offer->ptime > 0 && local_offer->ptime!=remote_answer->ptime) {
			ms_message("Remote answered ptime [%i] does not match offered [%i] for local stream description [%p]"
																,remote_answer->ptime
																,local_offer->ptime
																,local_offer);
			result->rtp_port=0;
			return;
		}
		if (local_offer->ttl > 0 && local_offer->ttl!=remote_answer->ttl) {
			ms_message("Remote answered ttl [%i] does not match offered [%i] for local stream description [%p]"
																		,remote_answer->ttl
																		,local_offer->ttl
																		,local_offer);
			result->rtp_port=0;
			return;
		}
		result->ttl=local_offer->ttl;
		result->dir=local_offer->dir;
		result->multicast_role = SalMulticastSender;
	} else {
		result->dir=compute_dir_outgoing(local_offer->dir,remote_answer->dir);
	}



	if (result->payloads && !only_telephone_event(result->payloads)){
		strcpy(result->rtp_addr,remote_answer->rtp_addr);
		strcpy(result->rtcp_addr,remote_answer->rtcp_addr);
		result->rtp_port=remote_answer->rtp_port;
		result->rtcp_port=remote_answer->rtcp_port;
		result->bandwidth=remote_answer->bandwidth;
		result->ptime=remote_answer->ptime;
	}else{
		result->rtp_port=0;
	}
	if (sal_stream_description_has_srtp(result) == TRUE) {
		/* verify crypto algo */
		memset(result->crypto, 0, sizeof(result->crypto));
		if (!match_crypto_algo(local_offer->crypto, remote_answer->crypto, &result->crypto[0], &result->crypto_local_tag, FALSE))
			result->rtp_port = 0;
	}
	result->rtp_ssrc=local_offer->rtp_ssrc;
	strncpy(result->rtcp_cname,local_offer->rtcp_cname,sizeof(result->rtcp_cname));

	// Handle dtls session attribute: if both local and remote have a dtls fingerprint and a dtls setup, get the remote fingerprint into the result
	if ((local_offer->dtls_role!=SalDtlsRoleInvalid) && (remote_answer->dtls_role!=SalDtlsRoleInvalid)
			&&(strlen(local_offer->dtls_fingerprint)>0) && (strlen(remote_answer->dtls_fingerprint)>0)) {
		strncpy(result->dtls_fingerprint, remote_answer->dtls_fingerprint,sizeof(result->dtls_fingerprint));
		if (remote_answer->dtls_role==SalDtlsRoleIsClient) {
			result->dtls_role = SalDtlsRoleIsServer;
		} else {
			result->dtls_role = SalDtlsRoleIsClient;
		}
	} else {
		result->dtls_fingerprint[0] = '\0';
		result->dtls_role = SalDtlsRoleInvalid;
	}
	result->rtcp_mux = remote_answer->rtcp_mux && local_offer->rtcp_mux;
	result->implicit_rtcp_fb = local_offer->implicit_rtcp_fb && remote_answer->implicit_rtcp_fb;
}