Я использую Freeswitch ESL (Event Socket Library) в Node.js Когда я получаю приглашение на SIP. js от конечной точки sip класса c, содержимое SDP является обычным RTP. Мне нужно иметь возможность подключить конечную точку RTP к конечной точке SRTP с помощью Freeswitch в середине. Для этого нам нужно иметь возможность создать конечную точку на Freeswitch без SDP (3P CC INVITE), но мы хотим, чтобы эта конечная точка возвращала SRTP SDP, а не RTP SDP.
Основной вопрос: Поддерживает ли Freeswitch создание предложения SRTP из входящего 3P CC INVITE?
Я полагаю, что эта часть обрабатывает 3P CC INVITE в Freeswitch 1.8.5: https://github.com/signalwire/freeswitch/blob/v1.8.5/src/mod/endpoints/mod_sofia/sofia.c
if (sofia_test_pflag(profile, PFLAG_3PCC)) {
if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "No SDP in INVITE and 3pcc=yes cannot work with bypass or proxy media, hanging up.\n");
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "3PCC DISABLED");
switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING);
} else {
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP");
switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
switch_core_media_prepare_codecs(session, 1);
switch_channel_set_state(channel, CS_HIBERNATE);
switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0);
sofia_set_flag_locked(tech_pvt, TFLAG_3PCC);
if (sofia_use_soa(tech_pvt)) {
nua_respond(tech_pvt->nh, SIP_200_OK,
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
} else {
nua_respond(tech_pvt->nh, SIP_200_OK,
NUTAG_MEDIA_ENABLE(0),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
}
}
}
Возможно, можно использовать тот же шаблон, который они использовали для mod_verto: https://github.com/signalwire/freeswitch/blob/v1.8.5/src/mod/endpoints/mod_verto/mod_verto.c
Эта функция switch_core_media_gen_local_sdp , кажется, один для создания RTP SDP: https://github.com/signalwire/freeswitch/blob/v1.8.5/src/switch_core_media.c Как мы можем вместо этого изменить его на SRTP SDP?
static const char *get_media_profile_name(switch_core_session_t *session, int secure)
{
switch_assert(session);
if (switch_channel_test_flag(session->channel, CF_AVPF)) {
if (switch_channel_test_flag(session->channel, CF_DTLS) || secure) {
if (switch_channel_test_flag(session->channel, CF_AVPF_MOZ)) {
return "UDP/TLS/RTP/SAVPF";
} else {
return "RTP/SAVPF";
}
} else {
if (switch_channel_test_flag(session->channel, CF_AVPF_MOZ)) {
return "UDP/AVPF";
} else {
return "RTP/AVPF";
}
}
}
if (secure) {
return "RTP/SAVP";
}
return "RTP/AVP";
}
Существует 3 условия для включения SRTP:
session->channel->flags['CF_AVPF']
(session->channel->flags['CF_DTLS'] || secure)
session->channel->flags['CF_AVPF_MOZ']
Условия установки флага CF_AVPF вызывают switch_core_session_set_ice или:
if (is_outbound || switch_channel_test_flag(session->channel, CF_RECOVERING) ||
switch_channel_test_flag(session->channel, CF_3PCC)) {
if (!switch_channel_test_flag(session->channel, CF_AVPF) &&
switch_true(switch_channel_get_variable(session->channel, "media_webrtc"))) {
switch_channel_set_flag(session->channel, CF_AVPF);
switch_channel_set_flag(session->channel, CF_ICE);
smh->mparams->rtcp_audio_interval_msec = SWITCH_RTCP_AUDIO_INTERVAL_MSEC;
smh->mparams->rtcp_video_interval_msec = SWITCH_RTCP_VIDEO_INTERVAL_MSEC;
}
if (switch_true(switch_channel_get_variable(session->channel, "add_ice_candidates"))) {
switch_channel_set_flag(session->channel, CF_ICE);
}
if ( switch_rtp_has_dtls() && dtls_ok(session)) {
if (switch_channel_test_flag(session->channel, CF_AVPF) ||
switch_true(switch_channel_get_variable(smh->session->channel, "rtp_use_dtls"))) {
switch_channel_set_flag(smh->session->channel, CF_DTLS);
switch_channel_set_flag(smh->session->channel, CF_SECURE);
generate_local_fingerprint(smh, SWITCH_MEDIA_TYPE_AUDIO);
}
}
switch_core_session_parse_crypto_prefs(session);
switch_core_session_check_outgoing_crypto(session);
}
Условия установки флага CF_DTLS одинаковы как указано выше ( CF_AVPF ) или вызов check_ice :
if (switch_rtp_has_dtls() && dtls_ok(smh->session) && !strcasecmp(attr->a_name, "fingerprint") && !zstr(attr->a_value)) {
char *p;
engine->remote_dtls_fingerprint.type = switch_core_session_strdup(smh->session, attr->a_value);
if ((p = strchr(engine->remote_dtls_fingerprint.type, ' '))) {
*p++ = '\0';
if (switch_channel_test_flag(smh->session->channel, CF_REINVITE) && !switch_channel_test_flag(smh->session->channel, CF_RECOVERING) &&
!zstr(engine->remote_dtls_fingerprint.str) && !strcmp(engine->remote_dtls_fingerprint.str, p)) {
engine->new_dtls = 0;
} else {
switch_set_string(engine->remote_dtls_fingerprint.str, p);
engine->new_dtls = 1;
engine->new_ice = 1;
}
}
generate_local_fingerprint(smh, type);
switch_channel_set_flag(smh->session->channel, CF_DTLS);
}
* 1 044 * Существует также возможность отправить значение true для параметра
secure , но условий много.
Условия для установки CF_AVPF_MOZ флаг:
if (m->m_proto_name && !strcasecmp(m->m_proto_name, "UDP/TLS/RTP/SAVPF")) {
switch_channel_set_flag(session->channel, CF_AVPF_MOZ);
}
if (m->m_proto_name && !strcasecmp(m->m_proto_name, "UDP/RTP/AVPF")) {
switch_channel_set_flag(session->channel, CF_AVPF_MOZ);
}