mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-10-16 08:14:13 +00:00
Merge branch 'master' into smgmaster
Conflicts: src/mod/endpoints/mod_sofia/mod_sofia.c
This commit is contained in:
commit
10d252b0fa
246 files changed
+15717
-6277
No files matched your search
@@ -508,7 +508,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
|
||||
TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)), TAG_END());
|
||||
}
|
||||
} else {
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Sending CANCEL to %s\n", switch_channel_get_name(channel));
|
||||
if (!tech_pvt->got_bye) {
|
||||
switch_channel_set_variable(channel, "sip_hangup_disposition", "send_cancel");
|
||||
@@ -573,7 +573,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
||||
char *sticky = NULL;
|
||||
const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full");
|
||||
|
||||
if (sofia_test_flag(tech_pvt, TFLAG_ANS) || switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (sofia_test_flag(tech_pvt, TFLAG_ANS) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -653,7 +653,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
||||
switch_channel_clear_flag(channel, CF_PROXY_MODE);
|
||||
}
|
||||
|
||||
if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
|
||||
tech_pvt->num_codecs = 0;
|
||||
sofia_glue_tech_prepare_codecs(tech_pvt);
|
||||
@@ -723,7 +723,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
||||
TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
|
||||
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
|
||||
NUTAG_SESSION_TIMER(session_timeout),
|
||||
TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)),
|
||||
NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
|
||||
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
|
||||
SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")),
|
||||
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
|
||||
@@ -739,7 +739,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
||||
TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
|
||||
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
|
||||
NUTAG_SESSION_TIMER(session_timeout),
|
||||
TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)),
|
||||
NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
|
||||
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
|
||||
SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")),
|
||||
SIPTAG_CONTENT_TYPE_STR("application/sdp"),
|
||||
@@ -906,7 +906,7 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
|
||||
tech_pvt->read_frame.flags = SFF_NONE;
|
||||
|
||||
status = switch_rtp_zerocopy_read_frame(tech_pvt->rtp_session, &tech_pvt->read_frame, flags);
|
||||
|
||||
|
||||
if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
|
||||
if (status == SWITCH_STATUS_TIMEOUT) {
|
||||
|
||||
@@ -1084,7 +1084,7 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
|
||||
tech_pvt->last_ts = 0;
|
||||
|
||||
/* inform them of the codec they are actually sending */
|
||||
|
||||
#if 0
|
||||
if (++tech_pvt->codec_reinvites > 2) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
|
||||
"Ok, some devices *cough* X-lite *cough*\n"
|
||||
@@ -1093,7 +1093,10 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
|
||||
} else {
|
||||
sofia_glue_do_invite(session);
|
||||
}
|
||||
#endif
|
||||
|
||||
*frame = &silence_frame;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1316,6 +1319,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||
|
||||
/* ones that do not need to lock sofia mutex */
|
||||
switch (msg->message_id) {
|
||||
case SWITCH_MESSAGE_INDICATE_RECOVERY_REFRESH:
|
||||
case SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC:
|
||||
{
|
||||
sofia_glue_tech_track(tech_pvt->profile, session);
|
||||
@@ -1332,6 +1336,61 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SWITCH_MESSAGE_INDICATE_JITTER_BUFFER:
|
||||
{
|
||||
if (switch_rtp_ready(tech_pvt->rtp_session)) {
|
||||
int len, maxlen = 0, qlen = 0, maxqlen = 50;
|
||||
|
||||
if (msg->string_arg) {
|
||||
char *p;
|
||||
const char *s;
|
||||
|
||||
if (!strncasecmp(msg->string_arg, "debug:", 6)) {
|
||||
s = msg->string_arg + 6;
|
||||
if (s && !strcmp(s, "off")) {
|
||||
s = NULL;
|
||||
}
|
||||
switch_rtp_debug_jitter_buffer(tech_pvt->rtp_session, s);
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
if ((len = atoi(msg->string_arg))) {
|
||||
qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000);
|
||||
}
|
||||
|
||||
if (qlen) {
|
||||
if ((p = strchr(msg->string_arg, ':'))) {
|
||||
p++;
|
||||
maxlen = atol(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (maxlen) {
|
||||
maxqlen = maxlen / (tech_pvt->read_impl.microseconds_per_packet / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
if (qlen) {
|
||||
if (switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen, maxqlen,
|
||||
tech_pvt->read_impl.samples_per_packet,
|
||||
tech_pvt->read_impl.samples_per_second) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session),
|
||||
SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames) (%d max frames)\n", len, qlen, maxqlen);
|
||||
switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session),
|
||||
SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", len, qlen);
|
||||
}
|
||||
|
||||
} else {
|
||||
switch_rtp_deactivate_jitter_buffer(tech_pvt->rtp_session);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_DEBUG_AUDIO:
|
||||
{
|
||||
if (switch_rtp_ready(tech_pvt->rtp_session) && !zstr(msg->string_array_arg[0]) && !zstr(msg->string_array_arg[1])) {
|
||||
@@ -1629,7 +1688,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||
sofia_glue_tech_set_local_sdp(tech_pvt, NULL, SWITCH_FALSE);
|
||||
|
||||
if (!(switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_test_flag(channel, CF_EARLY_MEDIA))) {
|
||||
if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
|
||||
|
||||
tech_pvt->num_codecs = 0;
|
||||
@@ -2144,7 +2203,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||
} else {
|
||||
if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || !tech_pvt->iananame) {
|
||||
sofia_clear_flag_locked(tech_pvt, TFLAG_LATE_NEGOTIATION);
|
||||
if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
|
||||
|
||||
tech_pvt->num_codecs = 0;
|
||||
@@ -3338,6 +3397,36 @@ SWITCH_STANDARD_API(sofia_count_reg_function)
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void select_from_profile(sofia_profile_t *profile,
|
||||
const char *user,
|
||||
const char *domain,
|
||||
const char *concat,
|
||||
const char *exclude_contact,
|
||||
switch_stream_handle_t *stream)
|
||||
{
|
||||
struct cb_helper cb;
|
||||
char *sql;
|
||||
|
||||
cb.row_process = 0;
|
||||
|
||||
cb.profile = profile;
|
||||
cb.stream = stream;
|
||||
|
||||
if (exclude_contact) {
|
||||
sql = switch_mprintf("select contact, profile_name, '%q' "
|
||||
"from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%') "
|
||||
"and contact not like '%%%s%%'", (concat != NULL) ? concat : "", user, domain, domain, exclude_contact);
|
||||
} else {
|
||||
sql = switch_mprintf("select contact, profile_name, '%q' "
|
||||
"from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')",
|
||||
(concat != NULL) ? concat : "", user, domain, domain);
|
||||
}
|
||||
|
||||
switch_assert(sql);
|
||||
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, contact_callback, &cb);
|
||||
switch_safe_free(sql);
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_API(sofia_contact_function)
|
||||
{
|
||||
char *data;
|
||||
@@ -3350,6 +3439,7 @@ SWITCH_STANDARD_API(sofia_contact_function)
|
||||
const char *exclude_contact = NULL;
|
||||
const char *user_replacement = NULL;
|
||||
char *reply = "error/facility_not_subscribed";
|
||||
switch_stream_handle_t mystream = { 0 };
|
||||
|
||||
if (!cmd) {
|
||||
stream->write_function(stream, "%s", "");
|
||||
@@ -3385,57 +3475,52 @@ SWITCH_STANDARD_API(sofia_contact_function)
|
||||
}
|
||||
}
|
||||
|
||||
if (!profile_name && domain) {
|
||||
profile_name = domain;
|
||||
if (zstr(domain)) {
|
||||
domain = switch_core_get_variable("domain");
|
||||
}
|
||||
|
||||
if (user && profile_name) {
|
||||
char *sql;
|
||||
if (!user) goto end;
|
||||
|
||||
if (!(profile = sofia_glue_find_profile(profile_name))) {
|
||||
profile_name = domain;
|
||||
domain = NULL;
|
||||
}
|
||||
|
||||
if (!profile && profile_name) {
|
||||
if (zstr(profile_name) || strcmp(profile_name, "*") || zstr(domain)) {
|
||||
if (!zstr(profile_name)) {
|
||||
profile = sofia_glue_find_profile(profile_name);
|
||||
}
|
||||
|
||||
if (!profile) {
|
||||
profile = sofia_glue_find_profile(domain);
|
||||
}
|
||||
}
|
||||
|
||||
if (profile) {
|
||||
struct cb_helper cb;
|
||||
switch_stream_handle_t mystream = { 0 };
|
||||
if (profile || !zstr(domain)) {
|
||||
SWITCH_STANDARD_STREAM(mystream);
|
||||
switch_assert(mystream.data);
|
||||
}
|
||||
|
||||
cb.row_process = 0;
|
||||
if (profile) {
|
||||
if (zstr(domain)) {
|
||||
domain = profile->name;
|
||||
}
|
||||
|
||||
if (!domain || (!strchr(domain, '.') && strcmp(profile_name, domain))) {
|
||||
domain = profile->name;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_STREAM(mystream);
|
||||
switch_assert(mystream.data);
|
||||
cb.profile = profile;
|
||||
cb.stream = &mystream;
|
||||
|
||||
if (exclude_contact) {
|
||||
sql = switch_mprintf("select contact, profile_name, '%q' "
|
||||
"from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%') "
|
||||
"and contact not like '%%%s%%'", (concat != NULL) ? concat : "", user, domain, domain, exclude_contact);
|
||||
} else {
|
||||
sql = switch_mprintf("select contact, profile_name, '%q' "
|
||||
"from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')",
|
||||
(concat != NULL) ? concat : "", user, domain, domain);
|
||||
}
|
||||
|
||||
switch_assert(sql);
|
||||
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, contact_callback, &cb);
|
||||
switch_safe_free(sql);
|
||||
reply = (char *) mystream.data;
|
||||
if (!zstr(reply) && end_of(reply) == ',') {
|
||||
end_of(reply) = '\0';
|
||||
}
|
||||
|
||||
if (zstr(reply)) {
|
||||
reply = "error/user_not_registered";
|
||||
if (!zstr(profile->domain_name) && !zstr(profile_name) && !strcmp(profile_name, profile->name)) {
|
||||
domain = profile->domain_name;
|
||||
}
|
||||
|
||||
select_from_profile(profile, user, domain, concat, exclude_contact, &mystream);
|
||||
sofia_glue_release_profile(profile);
|
||||
|
||||
} else if (!zstr(domain)) {
|
||||
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
||||
if (mod_sofia_globals.profile_hash) {
|
||||
switch_hash_index_t *hi;
|
||||
const void *var;
|
||||
void *val;
|
||||
|
||||
for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
|
||||
switch_hash_this(hi, &var, NULL, &val);
|
||||
if ((profile = (sofia_profile_t *) val) && !strcmp((char *)var, profile->name)) {
|
||||
select_from_profile(profile, user, domain, concat, exclude_contact, &mystream);
|
||||
profile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (user_replacement) {
|
||||
@@ -3530,18 +3615,27 @@ copydone:
|
||||
|
||||
switch_safe_free(mystream.data);
|
||||
}
|
||||
|
||||
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
||||
}
|
||||
|
||||
reply = (char *) mystream.data;
|
||||
|
||||
end:
|
||||
|
||||
if (zstr(reply)) {
|
||||
reply = "error/user_not_registered";
|
||||
} else if (end_of(reply) == ',') {
|
||||
end_of(reply) = '\0';
|
||||
}
|
||||
|
||||
if (reply) {
|
||||
stream->write_function(stream, "%s", reply);
|
||||
}
|
||||
stream->write_function(stream, "%s", reply);
|
||||
reply = NULL;
|
||||
|
||||
switch_safe_free(mystream.data);
|
||||
|
||||
switch_safe_free(data);
|
||||
|
||||
if (profile) {
|
||||
sofia_glue_release_profile(profile);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -3942,7 +4036,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (profile->domain_name && profile->domain_name != profile->name) {
|
||||
if (profile->domain_name && strcmp(profile->domain_name, profile->name)) {
|
||||
profile_name = profile->domain_name;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user