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); }
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; } }
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; } }
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; }
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; }