Merge remote-tracking branch 'fsorig/master'

Conflicts:
	src/mod/endpoints/mod_sofia/mod_sofia.c
	src/mod/endpoints/mod_sofia/sofia_glue.c
This commit is contained in:
Moises Silva committed 2011-09-28 12:19:48 -04:00
commit b004bcfc6d
407 files changed
+25813 -41133

No files matched your search

+79 -33
View File
@@ -282,6 +282,8 @@ char *generate_pai_str(private_object_t *tech_pvt)
header = (tech_pvt->cid_type == CID_TYPE_RPID && !switch_stristr("aastra", ua)) ? "Remote-Party-ID" : "P-Asserted-Identity";
if (!zstr(callee_name) && !zstr(callee_number)) {
check_decode(callee_name, tech_pvt->session);
if (switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote)) {
pai = switch_core_session_sprintf(tech_pvt->session, "%s: \"%s\" <%s>%s\n"
"X-FS-Display-Name: %s\nX-FS-Display-Number: %s\n",
@@ -741,13 +743,6 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
}
}
if ((val = switch_channel_get_variable(channel, SOFIA_SESSION_TIMEOUT))) {
int v_session_timeout = atoi(val);
if (v_session_timeout >= 0) {
session_timeout = v_session_timeout;
}
}
if (sofia_test_flag(tech_pvt, TFLAG_NAT) ||
(val = switch_channel_get_variable(channel, "sip-force-contact")) ||
((val = switch_channel_get_variable(channel, "sip_sticky_contact")) && switch_true(val))) {
@@ -756,6 +751,13 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
switch_channel_set_variable(channel, "sip_nat_detected", "true");
}
if ((val = switch_channel_get_variable(channel, SOFIA_SESSION_TIMEOUT))) {
int v_session_timeout = atoi(val);
if (v_session_timeout >= 0) {
session_timeout = v_session_timeout;
}
}
if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) {
char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_RESPONSE_HEADER_PREFIX);
char *cid = NULL;
@@ -780,18 +782,27 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
}
}
if ((tech_pvt->session_timeout = session_timeout)) {
tech_pvt->session_refresher = switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? nua_local_refresher : nua_remote_refresher;
} else {
tech_pvt->session_refresher = nua_no_refresher;
}
if (sofia_use_soa(tech_pvt)) {
nua_respond(tech_pvt->nh, SIP_200_OK,
NUTAG_AUTOANSWER(0),
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
NUTAG_SESSION_TIMER(session_timeout),
NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
NUTAG_SESSION_REFRESHER(tech_pvt->session_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),
SOATAG_REUSE_REJECTED(1), SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1),
TAG_IF(is_proxy, SOATAG_RTP_SELECT(1)),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
@@ -802,8 +813,8 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
NUTAG_SESSION_TIMER(session_timeout),
NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
NUTAG_SESSION_REFRESHER(tech_pvt->session_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"),
@@ -1364,11 +1375,17 @@ static switch_status_t sofia_send_dtmf(switch_core_session_t *session, const swi
}
case DTMF_INFO:
{
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Sending INFO DTMF %c of length %d\n", dtmf->digit, dtmf->duration);
snprintf(message, sizeof(message), "Signal=%c\r\nDuration=%d\r\n", dtmf->digit, dtmf->duration / 8);
switch_mutex_lock(tech_pvt->sofia_mutex);
nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("application/dtmf-relay"), SIPTAG_PAYLOAD_STR(message), TAG_END());
switch_mutex_unlock(tech_pvt->sofia_mutex);
if (dtmf->digit == 'w') {
switch_yield(500000);
} else if (dtmf->digit == 'W') {
switch_yield(1000000);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Sending INFO DTMF %c of length %d\n", dtmf->digit, dtmf->duration / 8);
snprintf(message, sizeof(message), "Signal=%c\r\nDuration=%d\r\n", dtmf->digit, dtmf->duration / 8);
switch_mutex_lock(tech_pvt->sofia_mutex);
nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("application/dtmf-relay"), SIPTAG_PAYLOAD_STR(message), TAG_END());
switch_mutex_unlock(tech_pvt->sofia_mutex);
}
}
break;
case DTMF_NONE:
@@ -1393,6 +1410,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
if (msg->message_id == SWITCH_MESSAGE_INDICATE_SIGNAL_DATA) {
sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) msg->pointer_arg;
switch_mutex_lock(tech_pvt->sofia_mutex);
if (switch_core_session_in_thread(session)) {
de->session = session;
}
sofia_process_dispatch_event(&de);
switch_mutex_unlock(tech_pvt->sofia_mutex);
goto end;
@@ -1883,14 +1903,21 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
case SWITCH_MESSAGE_INDICATE_PHONE_EVENT:
{
const char *event = "talk";
if (!zstr(msg->string_arg) && strcasecmp(msg->string_arg, event)) {
if (!strcasecmp(msg->string_arg, "hold")) {
event = "hold";
} else {
} else if (strncasecmp(msg->string_arg, "talk", 4)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Invalid event.\n");
}
}
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active), SIPTAG_EVENT_STR(event), TAG_END());
if (!switch_channel_test_flag(channel, CF_ANSWERED) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
"Operation not permitted on an inbound non-answered call leg!\n");
} else {
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active), SIPTAG_EVENT_STR(event), TAG_END());
}
}
break;
case SWITCH_MESSAGE_INDICATE_SIMPLIFY:
@@ -1961,12 +1988,15 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
char message[256] = "";
const char *ua = switch_channel_get_variable(tech_pvt->channel, "sip_user_agent");
switch_event_t *event;
if (zstr(number)) {
number = tech_pvt->caller_profile->destination_number;
}
if (!sofia_test_flag(tech_pvt, TFLAG_UPDATING_DISPLAY)) {
if (sofia_test_flag(tech_pvt, TFLAG_UPDATING_DISPLAY)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR,
"Cannot send display update to %s Did not receive reply to last update\n", switch_channel_get_name(tech_pvt->channel));
} else {
if (zstr(tech_pvt->last_sent_callee_id_name) || strcmp(tech_pvt->last_sent_callee_id_name, name) ||
zstr(tech_pvt->last_sent_callee_id_number) || strcmp(tech_pvt->last_sent_callee_id_number, number)) {
@@ -1995,6 +2025,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <%s>", name, number);
sofia_set_flag_locked(tech_pvt, TFLAG_UPDATING_DISPLAY);
nua_update(tech_pvt->nh,
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)),
TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
@@ -2003,28 +2035,40 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
sofia_set_flag_locked(tech_pvt, TFLAG_UPDATING_DISPLAY);
nua_update(tech_pvt->nh,
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)),
TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
} else if ((ua && (switch_stristr("cisco/spa50", ua) || switch_stristr("cisco/spa525", ua)))) {
snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <sip:%s@%s>", name, number, tech_pvt->profile->sipip);
snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <sip:%s@%s>", name, number, tech_pvt->profile->sipip);
sofia_set_flag_locked(tech_pvt, TFLAG_UPDATING_DISPLAY);
nua_update(tech_pvt->nh,
TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
}
sofia_set_flag_locked(tech_pvt, TFLAG_UPDATING_DISPLAY);
nua_update(tech_pvt->nh,
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
}
tech_pvt->last_sent_callee_id_name = switch_core_session_strdup(tech_pvt->session, name);
tech_pvt->last_sent_callee_id_number = switch_core_session_strdup(tech_pvt->session, number);
switch_channel_set_variable(channel, "last_sent_callee_id_name", name);
switch_channel_set_variable(channel, "last_sent_callee_id_number", number);
if (switch_event_create(&event, SWITCH_EVENT_CALL_UPDATE) == SWITCH_STATUS_SUCCESS) {
const char *uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Direction", "SEND");
switch_channel_set_profile_var(channel, "callee_id_name", name);
switch_channel_set_profile_var(channel, "callee_id_number", number);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Sent-Callee-ID-Name", name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Sent-Callee-ID-Number", number);
//switch_channel_set_profile_var(channel, "callee_id_name", name);
//switch_channel_set_profile_var(channel, "callee_id_number", number);
if (uuid) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridged-To", uuid);
}
@@ -2057,6 +2101,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
} else if (ua && switch_stristr("polycom", ua)) {
snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <%s>", msg->string_arg, tech_pvt->caller_profile->destination_number);
nua_update(tech_pvt->nh,
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)),
TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
@@ -3580,12 +3626,12 @@ SWITCH_STANDARD_API(sofia_count_reg_function)
if (zstr(user)) {
sql = switch_mprintf("select count(*) "
"from sip_registrations where (sip_host='%q' or presence_hosts like '%%%q%%')",
(concat != NULL) ? concat : "", domain, domain);
domain, domain);
} else {
sql = switch_mprintf("select count(*) "
"from sip_registrations where (sip_user='%q' or dir_user='%q') and (sip_host='%q' or presence_hosts like '%%%q%%')",
(concat != NULL) ? concat : "", user, user, domain, domain);
"from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')",
user, domain, domain);
}
switch_assert(sql);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sql2str_callback, &cb);
@@ -4702,7 +4748,7 @@ static void general_event_handler(switch_event_t *event)
nua_notify(nh,
NUTAG_NEWSUB(1),
TAG_IF(dst->route_uri, NUTAG_PROXY(dst->contact)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
SIPTAG_EVENT_STR(es), TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(ct)), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_END());
+12 -4
View File
@@ -45,7 +45,7 @@
#define HAVE_APR
#include <switch.h>
#include <switch_version.h>
#define SOFIA_NAT_SESSION_TIMEOUT 1800
#define SOFIA_NAT_SESSION_TIMEOUT 90
#define SOFIA_MAX_ACL 100
#ifdef _MSC_VER
#define HAVE_FUNCTION 1
@@ -98,6 +98,7 @@ typedef struct private_object private_object_t;
#define SOFIA_SIP_RESPONSE_HEADER_PREFIX "sip_rh_"
#define SOFIA_SIP_RESPONSE_HEADER_PREFIX_T "~sip_rh_"
#define SOFIA_SIP_BYE_HEADER_PREFIX "sip_bye_h_"
#define SOFIA_SIP_BYE_HEADER_PREFIX_T "~sip_bye_h_"
#define SOFIA_SIP_PROGRESS_HEADER_PREFIX "sip_ph_"
#define SOFIA_SIP_PROGRESS_HEADER_PREFIX_T "~sip_ph_"
#define SOFIA_SIP_HEADER_PREFIX_T "~sip_h_"
@@ -143,6 +144,7 @@ typedef struct sofia_dispatch_event_s {
nua_t *nua;
sofia_profile_t *profile;
int save;
switch_core_session_t *session;
} sofia_dispatch_event_t;
struct sofia_private {
@@ -214,6 +216,7 @@ typedef enum {
PFLAG_MANAGE_SHARED_APPEARANCE,
PFLAG_MANAGE_SHARED_APPEARANCE_SYLANTRO,
PFLAG_DISABLE_SRV,
PFLAG_DISABLE_SRV503,
PFLAG_DISABLE_NAPTR,
PFLAG_AUTOFLUSH,
PFLAG_NAT_OPTIONS_PING,
@@ -249,6 +252,7 @@ typedef enum {
PFLAG_LIBERAL_DTMF,
PFLAG_AUTO_ASSIGN_PORT,
PFLAG_AUTO_ASSIGN_TLS_PORT,
PFLAG_SHUTDOWN,
/* No new flags below this line */
PFLAG_MAX
} PFLAGS;
@@ -320,7 +324,7 @@ typedef enum {
TFLAG_MAX
} TFLAGS;
#define SOFIA_MAX_MSG_QUEUE 51
#define SOFIA_MAX_MSG_QUEUE 101
#define SOFIA_MSG_QUEUE_SIZE 5000
struct mod_sofia_globals {
@@ -353,6 +357,7 @@ struct mod_sofia_globals {
int debug_presence;
int debug_sla;
int auto_restart;
int reg_deny_binding_fetch_and_no_lookup; /* backwards compatibility */
int auto_nat;
int tracelevel;
char *capture_server;
@@ -764,6 +769,8 @@ struct private_object {
sofia_cid_type_t cid_type;
switch_payload_t payload_space;
switch_payload_t ianacodes[SWITCH_MAX_CODECS];
uint32_t session_timeout;
enum nua_session_refresher session_refresher;
};
struct callback_t {
@@ -866,8 +873,8 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
void launch_sofia_profile_thread(sofia_profile_t *profile);
switch_status_t sofia_presence_chat_send(const char *proto, const char *from, const char *to, const char *subject,
const char *body, const char *type, const char *hint);
switch_status_t sofia_presence_chat_send(switch_event_t *message_event);
void sofia_glue_tech_absorb_sdp(private_object_t *tech_pvt);
/*
@@ -1115,6 +1122,7 @@ switch_t38_options_t *sofia_glue_extract_t38_options(switch_core_session_t *sess
char *sofia_glue_get_multipart(switch_core_session_t *session, const char *prefix, const char *sdp, char **mp_type);
void sofia_glue_tech_simplify(private_object_t *tech_pvt);
switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *profile, const char *user, const char *host);
switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_multi(sofia_profile_t *profile, const char *user, const char *host);
switch_bool_t sofia_glue_profile_exists(const char *key);
void sofia_glue_global_siptrace(switch_bool_t on);
void sofia_glue_global_capture(switch_bool_t on);
+156 -54
View File
@@ -48,7 +48,9 @@ extern su_log_t nth_server_log[];
extern su_log_t nua_log[];
extern su_log_t soa_log[];
extern su_log_t sresolv_log[];
#ifdef HAVE_SOFIA_STUN
extern su_log_t stun_log[];
#endif
extern su_log_t su_log_default[];
static void config_sofia_profile_urls(sofia_profile_t * profile);
@@ -85,7 +87,7 @@ void sofia_handle_sip_r_notify(switch_core_session_t *session, int status,
sofia_dispatch_event_t *de, tagi_t tags[])
{
if (status >= 300 && sip && sip->sip_call_id) {
if (status >= 300 && sip && sip->sip_call_id && (!sofia_private || !sofia_private->is_call)) {
char *sql;
sql = switch_mprintf("delete from sip_subscriptions where call_id='%q'", sip->sip_call_id->i_id);
switch_assert(sql != NULL);
@@ -504,6 +506,7 @@ void sofia_handle_sip_i_bye(switch_core_session_t *session, int status,
private_object_t *tech_pvt;
char *extra_headers;
const char *call_info = NULL;
const char *vval = NULL;
#ifdef MANUAL_BYE
int cause;
char st[80] = "";
@@ -555,6 +558,18 @@ void sofia_handle_sip_i_bye(switch_core_session_t *session, int status,
extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_BYE_HEADER_PREFIX);
sofia_glue_set_extra_headers(channel, sip, SOFIA_SIP_BYE_HEADER_PREFIX);
if (!(vval = switch_channel_get_variable(channel, "sip_copy_custom_headers")) || switch_true(vval)) {
switch_core_session_t *nsession = NULL;
switch_core_session_get_partner(session, &nsession);
if (nsession) {
switch_ivr_transfer_variable(session, nsession, SOFIA_SIP_BYE_HEADER_PREFIX_T);
switch_core_session_rwunlock(nsession);
}
}
switch_channel_hangup(channel, cause);
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
@@ -818,14 +833,14 @@ static void our_sofia_event_callback(nua_event_t event,
return;
}
} else if (!zstr(sofia_private->uuid)) {
if ((session = switch_core_session_locate(sofia_private->uuid))) {
if ((session = de->session) || (session = switch_core_session_locate(sofia_private->uuid))) {
tech_pvt = switch_core_session_get_private(session);
channel = switch_core_session_get_channel(session);
if (tech_pvt) {
switch_mutex_lock(tech_pvt->sofia_mutex);
locked = 1;
} else {
switch_core_session_rwunlock(session);
if (session != de->session) switch_core_session_rwunlock(session);
return;
}
@@ -957,6 +972,7 @@ static void our_sofia_event_callback(nua_event_t event,
break;
case nua_r_shutdown:
if (status >= 200) {
sofia_set_pflag(profile, PFLAG_SHUTDOWN);
su_root_break(profile->s_root);
}
break;
@@ -1110,7 +1126,7 @@ static void our_sofia_event_callback(nua_event_t event,
switch_mutex_unlock(tech_pvt->sofia_mutex);
}
if (session) {
if (session && session != de->session) {
switch_core_session_rwunlock(session);
}
}
@@ -1145,6 +1161,7 @@ void *SWITCH_THREAD_FUNC sofia_msg_thread_run(switch_thread_t *thread, void *obj
while(switch_queue_pop(q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) pop;
sofia_process_dispatch_event(&de);
switch_cond_next();
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "MSG Thread Ended\n");
@@ -1175,7 +1192,7 @@ static void sofia_msg_thread_start(int idx)
switch_threadattr_create(&thd_attr, mod_sofia_globals.pool);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_threadattr_priority_increase(thd_attr);
//switch_threadattr_priority_increase(thd_attr);
switch_thread_create(&mod_sofia_globals.msg_queue_thread[i],
thd_attr,
sofia_msg_thread_run,
@@ -1254,7 +1271,6 @@ void sofia_event_callback(nua_event_t event,
if (!zstr(sofia_private->uuid)) {
if ((session = switch_core_session_locate(sofia_private->uuid))) {
if (switch_core_session_running(session)) {
switch_core_session_queue_signal_data(session, de);
} else {
@@ -1788,6 +1804,8 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
NTATAG_USE_SRV(0)),
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_NAPTR),
NTATAG_USE_NAPTR(0)),
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_SRV503),
NTATAG_SRV_503(0)),
NTATAG_DEFAULT_PROXY(profile->outbound_proxy),
NTATAG_SERVER_RPORT(profile->server_rport_level),
NTATAG_CLIENT_RPORT(profile->client_rport_level),
@@ -1951,9 +1969,17 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
switch_thread_rwlock_wrlock(profile->rwlock);
sofia_reg_unregister(profile);
nua_shutdown(profile->nua);
su_root_run(profile->s_root);
sanity = 10;
while (!sofia_test_pflag(profile, PFLAG_SHUTDOWN)) {
su_root_step(profile->s_root, 1000);
if (!--sanity) {
break;
}
}
sofia_clear_pflag_locked(profile, PFLAG_RUNNING);
sofia_clear_pflag_locked(profile, PFLAG_SHUTDOWN);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Waiting for worker thread\n");
switch_thread_join(&st, worker_thread);
@@ -2076,8 +2102,10 @@ static su_log_t *sofia_get_logger(const char *name)
return soa_log;
} else if (!strcasecmp(name, "sresolv")) {
return sresolv_log;
#ifdef HAVE_SOFIA_STUN
} else if (!strcasecmp(name, "stun")) {
return stun_log;
#endif
} else if (!strcasecmp(name, "default")) {
return su_log_default;
} else {
@@ -2104,7 +2132,9 @@ switch_status_t sofia_set_loglevel(const char *name, int level)
su_log_set_level(nua_log, level);
su_log_set_level(soa_log, level);
su_log_set_level(sresolv_log, level);
#ifdef HAVE_SOFIA_STUN
su_log_set_level(stun_log, level);
#endif
return SWITCH_STATUS_SUCCESS;
}
@@ -2189,7 +2219,7 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
}
switch_mutex_lock(mod_sofia_globals.hash_mutex);
if ((gp = switch_core_hash_find(mod_sofia_globals.gateway_hash, name)) && (gp = switch_core_hash_find(mod_sofia_globals.gateway_hash, pkey))) {
if ((gp = switch_core_hash_find(mod_sofia_globals.gateway_hash, name)) && (gp = switch_core_hash_find(mod_sofia_globals.gateway_hash, pkey)) && !gp->deleted) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring duplicate gateway '%s'\n", name);
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
free(pkey);
@@ -2553,7 +2583,7 @@ static void parse_domain_tag(sofia_profile_t *profile, switch_xml_t x_domain_tag
if (sofia_glue_add_profile(switch_core_strdup(profile->pool, dname), profile) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", dname, profile->name);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Alias [%s] for profile [%s] (already exists)\n", dname, profile->name);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Alias [%s] for profile [%s] (already exists)\n", dname, profile->name);
}
}
@@ -2701,6 +2731,12 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
mod_sofia_globals.debug_sla = atoi(val);
} else if (!strcasecmp(var, "auto-restart")) {
mod_sofia_globals.auto_restart = switch_true(val);
} else if (!strcasecmp(var, "reg-deny-binding-fetch-and-no-lookup")) { /* backwards compatibility */
mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = switch_true(val); /* remove when noone complains about the extra lookup */
if (switch_true(val)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Enabling reg-deny-binding-fetch-and-no-lookup - this functionality is "
"deprecated and will be removed - let FS devs know if you think it should stay\n");
}
} else if (!strcasecmp(var, "rewrite-multicasted-fs-path")) {
if( (!strcasecmp(val, "to_host")) || (!strcasecmp(val, "1")) ) {
/* old behaviour */
@@ -3355,7 +3391,9 @@ switch_status_t config_sofia(int reload, char *profile_name)
su_log_redirect(nua_log, logger, NULL);
su_log_redirect(soa_log, logger, NULL);
su_log_redirect(sresolv_log, logger, NULL);
#ifdef HAVE_SOFIA_STUN
su_log_redirect(stun_log, logger, NULL);
#endif
}
if (!zstr(profile_name) && (profile = sofia_glue_find_profile(profile_name))) {
@@ -3376,6 +3414,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
}
mod_sofia_globals.auto_restart = SWITCH_TRUE;
mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = SWITCH_FALSE; /* handle backwards compatilibity - by default use new behavior */
mod_sofia_globals.rewrite_multicasted_fs_path = SWITCH_FALSE;
if ((settings = switch_xml_child(cfg, "global_settings"))) {
@@ -3392,6 +3431,12 @@ switch_status_t config_sofia(int reload, char *profile_name)
mod_sofia_globals.debug_sla = atoi(val);
} else if (!strcasecmp(var, "auto-restart")) {
mod_sofia_globals.auto_restart = switch_true(val);
} else if (!strcasecmp(var, "reg-deny-binding-fetch-and-no-lookup")) { /* backwards compatibility */
mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = switch_true(val); /* remove when noone complains about the extra lookup */
if (switch_true(val)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Enabling reg-deny-binding-fetch-and-no-lookup - this functionality is "
"deprecated and will be removed - let FS devs know if you think it should stay\n");
}
} else if (!strcasecmp(var, "rewrite-multicasted-fs-path")) {
if( (!strcasecmp(val, "to_host")) || (!strcasecmp(val, "1")) ) {
/* old behaviour */
@@ -3486,6 +3531,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
sofia_set_flag(profile, TFLAG_ENABLE_SOA);
sofia_set_pflag(profile, PFLAG_CID_IN_1XX);
profile->ndlb |= PFLAG_NDLB_ALLOW_NONDUP_SDP;
profile->te = 101;
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
@@ -3940,6 +3986,10 @@ switch_status_t config_sofia(int reload, char *profile_name)
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_DISABLE_NAPTR);
}
} else if (!strcasecmp(var, "disable-srv503")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_DISABLE_SRV503);
}
} else if (!strcasecmp(var, "unregister-on-options-fail")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL);
@@ -4153,10 +4203,14 @@ switch_status_t config_sofia(int reload, char *profile_name)
}
} else if (!strcasecmp(var, "alias")) {
sip_alias_node_t *node;
if ((node = switch_core_alloc(profile->pool, sizeof(*node)))) {
if ((node->url = switch_core_strdup(profile->pool, val))) {
node->next = profile->aliases;
profile->aliases = node;
if (zstr(val)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Alias Param has no data...\n");
} else {
if ((node = switch_core_alloc(profile->pool, sizeof(*node)))) {
if ((node->url = switch_core_strdup(profile->pool, val))) {
node->next = profile->aliases;
profile->aliases = node;
}
}
}
} else if (!strcasecmp(var, "dialplan")) {
@@ -5161,7 +5215,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
if (channel && (status == 180 || status == 183) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
const char *val;
if ((val = switch_channel_get_variable(channel, "sip_auto_answer")) && switch_true(val)) {
nua_notify(nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active), SIPTAG_EVENT_STR("talk"), TAG_END());
nua_notify(nh, NUTAG_NEWSUB(1), NUTAG_WITH_THIS_MSG(de->data->e_msg),
NUTAG_SUBSTATE(nua_substate_terminated), SIPTAG_EVENT_STR("talk"), TAG_END());
}
}
@@ -5243,6 +5298,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
break;
case nua_callstate_completing:
{
const char *invite_full_from = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_from");
const char *invite_full_to = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_to");
if (r_sdp && sofia_test_flag(tech_pvt, TFLAG_3PCC_INVITE) && !sofia_test_flag(tech_pvt, TFLAG_SDP)) {
sofia_set_flag(tech_pvt, TFLAG_SDP);
@@ -5266,12 +5324,18 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
const char *invite_route_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_route_uri");
nua_ack(nh,
TAG_IF(!zstr(invite_full_via), SIPTAG_VIA_STR(invite_full_via)),
TAG_IF(!zstr(invite_route_uri), SIPTAG_ROUTE_STR(invite_route_uri)),
TAG_END());
TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
TAG_IF(!zstr(invite_full_via), SIPTAG_VIA_STR(invite_full_via)),
TAG_IF(!zstr(invite_route_uri), SIPTAG_ROUTE_STR(invite_route_uri)),
TAG_END());
} else {
nua_ack(nh, TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
nua_ack(nh,
TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_END());
}
}
goto done;
@@ -5558,6 +5622,12 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
}
goto done;
} else {
if (switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_NEGOTIATED)) {
nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
goto done;
}
sofia_set_flag_locked(tech_pvt, TFLAG_REINVITE);
if (tech_pvt->num_codecs) {
@@ -5573,6 +5643,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
if (sofia_glue_tech_choose_port(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) {
goto done;
}
sofia_glue_set_local_sdp(tech_pvt, NULL, 0, NULL, 0);
if (sofia_glue_activate_rtp(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) {
@@ -6596,7 +6667,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
const char *signal_ptr;
const char *rec_header;
const char *clientcode_header;
switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0) };
switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0), 0, SWITCH_DTMF_ENDPOINT };
switch_event_t *event;
private_object_t *tech_pvt = NULL;
@@ -6735,35 +6806,37 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
goto end;
}
if (dtmf.digit && (tech_pvt->dtmf_type == DTMF_INFO ||
sofia_test_pflag(tech_pvt->profile, PFLAG_LIBERAL_DTMF) || sofia_test_flag(tech_pvt, TFLAG_LIBERAL_DTMF))) {
/* queue it up */
switch_channel_queue_dtmf(channel, &dtmf);
if (dtmf.digit) {
if (tech_pvt->dtmf_type == DTMF_INFO ||
sofia_test_pflag(tech_pvt->profile, PFLAG_LIBERAL_DTMF) || sofia_test_flag(tech_pvt, TFLAG_LIBERAL_DTMF)) {
/* queue it up */
switch_channel_queue_dtmf(channel, &dtmf);
/* print debug info */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "INFO DTMF(%c)\n", dtmf.digit);
/* print debug info */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "INFO DTMF(%c)\n", dtmf.digit);
if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
const char *uuid;
switch_core_session_t *session_b;
if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
const char *uuid;
switch_core_session_t *session_b;
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) && (session_b = switch_core_session_locate(uuid))) {
while (switch_channel_has_dtmf(channel)) {
switch_dtmf_t idtmf = { 0, 0 };
if (switch_channel_dequeue_dtmf(channel, &idtmf) == SWITCH_STATUS_SUCCESS) {
switch_core_session_send_dtmf(session_b, &idtmf);
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) && (session_b = switch_core_session_locate(uuid))) {
while (switch_channel_has_dtmf(channel)) {
switch_dtmf_t idtmf = { 0, 0 };
if (switch_channel_dequeue_dtmf(channel, &idtmf) == SWITCH_STATUS_SUCCESS) {
switch_core_session_send_dtmf(session_b, &idtmf);
}
}
switch_core_session_rwunlock(session_b);
}
switch_core_session_rwunlock(session_b);
}
}
/* Send 200 OK response */
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
"IGNORE INFO DTMF(%c) (This channel was not configured to use INFO DTMF!)\n", dtmf.digit);
/* Send 200 OK response */
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
"IGNORE INFO DTMF(%c) (This channel was not configured to use INFO DTMF!)\n", dtmf.digit);
}
}
goto end;
}
@@ -7423,6 +7496,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
if (sofia_glue_check_nat(profile, tech_pvt->remote_ip)) {
tech_pvt->user_via = sofia_glue_create_external_via(session, profile, tech_pvt->transport);
nua_set_hparams(tech_pvt->nh, SIPTAG_VIA_STR(tech_pvt->user_via), TAG_END());
}
if (sip->sip_contact && sip->sip_contact->m_url) {
@@ -7659,6 +7733,12 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
}
}
check_decode(displayname, session);
tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
from_user,
dialplan,
displayname, from_user, network_ip, from_user, aniii, NULL, MODNAME, context, destination_number);
if (!bnh && sip->sip_replaces) {
if (!(bnh = nua_handle_by_replaces(nua, sip->sip_replaces))) {
if (!(bnh = nua_handle_by_call_id(nua, sip->sip_replaces->rp_call_id))) {
@@ -7679,10 +7759,32 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
private_object_t *b_tech_pvt = NULL;
const char *app = switch_channel_get_variable(b_channel, SWITCH_CURRENT_APPLICATION_VARIABLE);
const char *data = switch_channel_get_variable(b_channel, SWITCH_CURRENT_APPLICATION_DATA_VARIABLE);
switch_caller_profile_t *orig_cp;
const char *sent_name, *sent_number;
orig_cp = switch_channel_get_caller_profile(b_channel);
sent_name = switch_channel_get_variable(b_channel, "last_sent_callee_id_name");
sent_number = switch_channel_get_variable(b_channel, "last_sent_callee_id_number");
if (!zstr(sent_name) && !zstr(sent_number)) {
tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, sent_name);
tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, sent_number);
} else {
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_name);
tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_number);
} else {
tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_name);
tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_number);
}
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Setting NAT mode based on %s\n", is_nat);
if (app && data && !strcasecmp(app, "conference")) {
destination_number = switch_core_session_sprintf(session, "answer,conference:%s", data);
dialplan = "inline";
tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,conference:%s", data);
tech_pvt->caller_profile->dialplan = "inline";
} else {
if (switch_core_session_check_interface(b_session, sofia_endpoint_interface)) {
b_tech_pvt = switch_core_session_get_private(b_session);
@@ -7712,7 +7814,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
if (switch_core_session_check_interface(c_session, sofia_endpoint_interface)) {
c_tech_pvt = switch_core_session_get_private(c_session);
}
if (!one_leg &&
(!b_tech_pvt || !sofia_test_flag(b_tech_pvt, TFLAG_SIP_HOLD)) &&
@@ -7729,21 +7831,25 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
}
if (do_conf) {
destination_number = switch_core_session_sprintf(session, "answer,conference:%s@sla+flags{mintwo}", uuid);
tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
"answer,conference:%s@sla+flags{mintwo}", uuid);
} else {
if (one_leg && c_app) {
if (c_data) {
destination_number = switch_core_session_sprintf(session, "answer,%s:%s", c_app, c_data);
tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
"answer,%s:%s", c_app, c_data);
} else {
destination_number = switch_core_session_sprintf(session, "answer,%s", c_app);
tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
"answer,%s", c_app);
}
} else {
switch_channel_mark_hold(b_channel, SWITCH_FALSE);
destination_number = switch_core_session_sprintf(session, "answer,intercept:%s", uuid);
tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
"answer,intercept:%s", uuid);
}
}
dialplan = "inline";
tech_pvt->caller_profile->dialplan = "inline";
}
}
switch_core_session_rwunlock(b_session);
@@ -7752,11 +7858,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
nua_handle_unref(bnh);
}
check_decode(displayname, session);
tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
from_user,
dialplan,
displayname, from_user, network_ip, from_user, aniii, NULL, MODNAME, context, destination_number);
if (tech_pvt->caller_profile) {
+166 -135
View File
@@ -48,12 +48,23 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t *
uint32_t port = t38_options->local_port;
const char *family = "IP4";
const char *username = tech_pvt->profile->username;
char MMR[32] = "";
char JBIG[32] = "";
char FILLBIT[32] = "";
const char *bit_removal_on = "a=T38FaxFillBitRemoval\n";
const char *bit_removal_off = "";
const char *mmr_on = "a=T38FaxTranscodingMMR\n";
const char *mmr_off = "";
const char *jbig_on = "a=T38FaxTranscodingJBIG\n";
const char *jbig_off = "";
const char *var;
int broken_boolean;
//sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
var = switch_channel_get_variable(tech_pvt->channel, "t38_broken_boolean");
broken_boolean = switch_true(var);
if (!ip) {
if (!(ip = tech_pvt->adv_sdp_audio_ip)) {
ip = tech_pvt->proxy_sdp_audio_ip;
@@ -94,48 +105,6 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t *
"o=%s %010u %010u IN %s %s\n"
"s=%s\n" "c=IN %s %s\n" "t=0 0\n", username, tech_pvt->owner_id, tech_pvt->session_id, family, ip, username, family, ip);
if(t38_options->T38FaxFillBitRemoval) {
if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxFillBitRemoval"))) {
switch_snprintf(FILLBIT, sizeof(FILLBIT), "a=T38FaxFillBitRemoval:1\n");
} else {
switch_set_string(FILLBIT, "a=T38FaxFillBitRemoval\n");
}
} else {
if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxFillBitRemoval"))) {
switch_snprintf(FILLBIT, sizeof(FILLBIT), "a=T38FaxFillBitRemoval:0\n");
} else {
switch_set_string(FILLBIT, "");
}
}
if( t38_options->T38FaxTranscodingMMR) {
if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxTranscodingMMR"))) {
switch_snprintf(MMR, sizeof(MMR), "a=T38FaxTranscodingMMR:1\n");
} else {
switch_set_string(MMR, "a=T38FaxTranscodingMMR\n");
}
} else {
if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxTranscodingMMR"))) {
switch_snprintf(MMR, sizeof(MMR), "a=T38FaxTranscodingMMR:0\n");
} else {
switch_set_string(MMR, "");
}
}
if( t38_options->T38FaxTranscodingJBIG) {
if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxTranscodingJBIG"))) {
switch_snprintf(JBIG, sizeof(JBIG), "a=T38FaxTranscodingJBIG:1\n");
} else {
switch_set_string(JBIG, "a=T38FaxTranscodingJBIG\n");
}
} else {
if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxTranscodingJBIG"))) {
switch_snprintf(JBIG, sizeof(JBIG), "a=T38FaxTranscodingJBIG:0\n");
} else {
switch_set_string(JBIG, "");
}
}
if (t38_options->T38FaxMaxBuffer) {
switch_snprintf(max_buf, sizeof(max_buf), "a=T38FaxMaxBuffer:%d\n", t38_options->T38FaxMaxBuffer);
};
@@ -145,6 +114,21 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t *
};
if (broken_boolean) {
bit_removal_on = "a=T38FaxFillBitRemoval:1\n";
bit_removal_off = "a=T38FaxFillBitRemoval:0\n";
mmr_on = "a=T38FaxTranscodingMMR:1\n";
mmr_off = "a=T38FaxTranscodingMMR:0\n";
jbig_on = "a=T38FaxTranscodingJBIG:1\n";
jbig_off = "a=T38FaxTranscodingJBIG:0\n";
}
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
"m=image %d udptl t38\n"
"a=T38FaxVersion:%d\n"
@@ -160,9 +144,9 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t *
port,
t38_options->T38FaxVersion,
t38_options->T38MaxBitRate,
FILLBIT,
MMR,
JBIG,
t38_options->T38FaxFillBitRemoval ? bit_removal_on : bit_removal_off,
t38_options->T38FaxTranscodingMMR ? mmr_on : mmr_off,
t38_options->T38FaxTranscodingJBIG ? jbig_on : jbig_off,
t38_options->T38FaxRateManagement,
max_buf,
max_data,
@@ -201,7 +185,12 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen,
for (i = 0; i < tech_pvt->num_codecs; i++) {
const switch_codec_implementation_t *imp = tech_pvt->codecs[i];
int this_ptime = (imp->microseconds_per_packet / 1000);
if (!strcasecmp(imp->iananame, "ilbc")) {
this_ptime = 20;
}
if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) {
continue;
}
@@ -210,12 +199,12 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen,
if (!cur_ptime) {
#if 0
if (ptime) {
if (ptime != imp->microseconds_per_packet / 1000) {
if (ptime != this_ptime) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Codec %s payload %d added to sdp wanting ptime %d but it's already %d (%s:%d:%d), disabling ptime.\n",
imp->iananame,
tech_pvt->ianacodes[i],
imp->microseconds_per_packet / 1000,
this_ptime,
ptime,
tech_pvt->codecs[0]->iananame,
tech_pvt->codecs[0]->ianacode,
@@ -224,15 +213,15 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen,
noptime = 1;
}
} else {
ptime = imp->microseconds_per_packet / 1000;
ptime = this_ptime;
}
#else
if (!ptime) {
ptime = imp->microseconds_per_packet / 1000;
ptime = this_ptime;
}
#endif
} else {
if ((imp->microseconds_per_packet / 1000) != cur_ptime) {
if (this_ptime != cur_ptime) {
continue;
}
}
@@ -266,18 +255,23 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen,
for (i = 0; i < tech_pvt->num_codecs; i++) {
const switch_codec_implementation_t *imp = tech_pvt->codecs[i];
char *fmtp = imp->fmtp;
int this_ptime = imp->microseconds_per_packet / 1000;
if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) {
continue;
}
if (!strcasecmp(imp->iananame, "ilbc")) {
this_ptime = 20;
}
if (!noptime) {
if (!cur_ptime) {
if (!ptime) {
ptime = imp->microseconds_per_packet / 1000;
ptime = this_ptime;
}
} else {
if ((imp->microseconds_per_packet / 1000) != cur_ptime) {
if (this_ptime != cur_ptime) {
continue;
}
}
@@ -496,7 +490,7 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %d", tech_pvt->pt);
if (tech_pvt->dtmf_type == DTMF_2833 && tech_pvt->te > 95) {
if ((tech_pvt->dtmf_type == DTMF_2833 || sofia_test_pflag(tech_pvt->profile, PFLAG_LIBERAL_DTMF) || sofia_test_flag(tech_pvt, TFLAG_LIBERAL_DTMF)) && tech_pvt->te > 95) {
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %d", tech_pvt->te);
}
@@ -583,6 +577,10 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
this_ptime = imp->microseconds_per_packet / 1000;
if (!strcasecmp(imp->iananame, "ilbc")) {
this_ptime = 20;
}
if (cur_ptime != this_ptime) {
char *bp = buf;
cur_ptime = this_ptime;
@@ -658,6 +656,8 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
if (ov_fmtp) {
pass_fmtp = ov_fmtp;
} else {
pass_fmtp = switch_channel_get_variable(tech_pvt->channel, "sip_video_fmtp");
}
}
@@ -874,6 +874,7 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *
switch_channel_set_cap(tech_pvt->channel, CC_PROXY_MEDIA);
switch_channel_set_cap(tech_pvt->channel, CC_JITTERBUFFER);
switch_channel_set_cap(tech_pvt->channel, CC_FS_RTP);
switch_channel_set_cap(tech_pvt->channel, CC_QUEUEABLE_DTMF_DELAY);
switch_core_session_set_private(session, tech_pvt);
@@ -1055,8 +1056,9 @@ switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt, int forc
tech_pvt->adv_sdp_audio_port = sdp_port;
tech_pvt->adv_sdp_audio_ip = tech_pvt->extrtpip = switch_core_session_strdup(tech_pvt->session, use_ip);
switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, tech_pvt->adv_sdp_audio_ip);
switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, tech_pvt->local_sdp_audio_ip);
switch_channel_set_variable_printf(tech_pvt->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE, "%d", sdp_port);
switch_channel_set_variable(tech_pvt->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE, tech_pvt->adv_sdp_audio_ip);
return SWITCH_STATUS_SUCCESS;
}
@@ -1907,7 +1909,7 @@ void sofia_glue_set_extra_headers(switch_channel_t *channel, sip_t const *sip, c
}
for (un = sip->sip_unknown; un; un = un->un_next) {
if (!strncasecmp(un->un_name, "X-", 2) || !strncasecmp(un->un_name, "P-", 2)) {
if ((!strncasecmp(un->un_name, "X-", 2) && strncasecmp(un->un_name, "X-FS-", 5)) || !strncasecmp(un->un_name, "P-", 2)) {
if (!zstr(un->un_value)) {
switch_snprintf(name, sizeof(name), "%s%s", prefix, un->un_name);
switch_channel_set_variable(channel, name, un->un_value);
@@ -2107,14 +2109,11 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
if (zstr(tech_pvt->invite_contact)) {
const char *contact;
if ((contact = switch_channel_get_variable(channel, "sip_contact_user"))) {
char *ip_addr;
char *ip_addr = tech_pvt->profile->sipip;
char *ipv6;
if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) {
ip_addr = (switch_check_network_list_ip(tech_pvt->remote_ip, tech_pvt->profile->local_network))
? tech_pvt->profile->sipip : tech_pvt->profile->extsipip;
} else {
ip_addr = tech_pvt->profile->extsipip ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip;
if ( !zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip ) ) {
ip_addr = tech_pvt->profile->extsipip;
}
ipv6 = strchr(ip_addr, ':');
@@ -2271,6 +2270,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
use_number = tech_pvt->caller_profile->caller_id_number;
}
check_decode(use_name, session);
switch (cid_type) {
case CID_TYPE_PID:
@@ -2366,6 +2366,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX);
session_timeout = tech_pvt->profile->session_timeout;
if ((val = switch_channel_get_variable(channel, SOFIA_SESSION_TIMEOUT))) {
int v_session_timeout = atoi(val);
if (v_session_timeout >= 0) {
@@ -2420,17 +2421,21 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
}
if (sofia_test_flag(tech_pvt, TFLAG_RECOVERED)) {
session_timeout = 0;
if ((tech_pvt->session_timeout = session_timeout)) {
tech_pvt->session_refresher = switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? nua_local_refresher : nua_remote_refresher;
} else {
tech_pvt->session_refresher = nua_no_refresher;
}
if (sofia_use_soa(tech_pvt)) {
nua_invite(tech_pvt->nh,
NUTAG_AUTOANSWER(0),
TAG_IF(zstr(tech_pvt->local_sdp_str), NUTAG_AUTOACK(0)),
TAG_IF(!zstr(tech_pvt->local_sdp_str), NUTAG_AUTOACK(1)),
NUTAG_SESSION_TIMER(session_timeout),
NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
//TAG_IF(zstr(tech_pvt->local_sdp_str), NUTAG_AUTOACK(0)),
//TAG_IF(!zstr(tech_pvt->local_sdp_str), NUTAG_AUTOACK(1)),
// The code above is breaking things...... grrr WE need this because we handle our own acks and there are 3pcc cases in there too
NUTAG_AUTOACK(0),
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)),
TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
@@ -2463,8 +2468,8 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
nua_invite(tech_pvt->nh,
NUTAG_AUTOANSWER(0),
NUTAG_AUTOACK(0),
NUTAG_SESSION_TIMER(session_timeout),
TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)),
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)),
TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
@@ -3029,7 +3034,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
}
if (!(sofia_test_pflag(tech_pvt->profile, PFLAG_REWRITE_TIMESTAMPS) ||
((val = switch_channel_get_variable(tech_pvt->channel, "rtp_rewrite_timestamps")) && !switch_true(val)))) {
((val = switch_channel_get_variable(tech_pvt->channel, "rtp_rewrite_timestamps")) && switch_true(val)))) {
flags |= SWITCH_RTP_FLAG_RAW_WRITE;
}
@@ -3109,8 +3114,9 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
}
switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->local_sdp_audio_port);
switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, tech_pvt->adv_sdp_audio_ip);
switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, tech_pvt->local_sdp_audio_ip);
switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE, tmp);
switch_channel_set_variable(tech_pvt->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE, tech_pvt->adv_sdp_audio_ip);
if (tech_pvt->rtp_session && sofia_test_flag(tech_pvt, TFLAG_REINVITE)) {
const char *rport = NULL;
@@ -3350,11 +3356,13 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
if (tech_pvt->te) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Set 2833 dtmf send payload to %u\n", tech_pvt->te);
switch_rtp_set_telephony_event(tech_pvt->rtp_session, tech_pvt->te);
switch_channel_set_variable_printf(tech_pvt->channel, "sip_2833_send_payload", "%d", tech_pvt->te);
}
if (tech_pvt->recv_te) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Set 2833 dtmf receive payload to %u\n", tech_pvt->recv_te);
switch_rtp_set_telephony_recv_event(tech_pvt->rtp_session, tech_pvt->recv_te);
switch_channel_set_variable_printf(tech_pvt->channel, "sip_2833_recv_payload", "%d", tech_pvt->recv_te);
}
if (tech_pvt->audio_recv_pt != tech_pvt->agreed_pt) {
@@ -3983,11 +3991,11 @@ void sofia_glue_copy_t38_options(switch_t38_options_t *t38_options, switch_core_
switch_channel_set_private(channel, "t38_options", local_t38_options);
}
static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_session_t *sdp, sdp_media_t *m)
{
switch_t38_options_t *t38_options = switch_channel_get_private(tech_pvt->channel, "t38_options");
sdp_attribute_t *attr;
const char *var;
if (!t38_options) {
t38_options = switch_core_session_alloc(tech_pvt->session, sizeof(switch_t38_options_t));
@@ -4003,6 +4011,12 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_
t38_options->remote_port = (switch_port_t)m->m_port;
if (sdp->sdp_origin) {
t38_options->sdp_o_line = switch_core_session_strdup(tech_pvt->session, sdp->sdp_origin->o_username);
} else {
t38_options->sdp_o_line = "unknown";
}
if (m->m_connections && m->m_connections->c_address) {
t38_options->remote_ip = switch_core_session_strdup(tech_pvt->session, m->m_connections->c_address);
} else if (sdp && sdp->sdp_connection && sdp->sdp_connection->c_address) {
@@ -4015,41 +4029,11 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_
} else if (!strcasecmp(attr->a_name, "T38MaxBitRate") && attr->a_value) {
t38_options->T38MaxBitRate = (uint32_t) atoi(attr->a_value);
} else if (!strcasecmp(attr->a_name, "T38FaxFillBitRemoval")) {
if (switch_stristr("T38FaxFillBitRemoval:", tech_pvt->remote_sdp_str)) {
switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxFillBitRemoval", "true");
if (atoi(attr->a_value) == 0) {
t38_options->T38FaxFillBitRemoval = SWITCH_FALSE;
} else {
t38_options->T38FaxFillBitRemoval = SWITCH_TRUE;
}
} else {
switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxFillBitRemoval", "false");
t38_options->T38FaxFillBitRemoval = SWITCH_TRUE;
}
t38_options->T38FaxFillBitRemoval = switch_safe_atoi(attr->a_value, 1);
} else if (!strcasecmp(attr->a_name, "T38FaxTranscodingMMR")) {
if (switch_stristr("T38FaxTranscodingMMR:", tech_pvt->remote_sdp_str)) {
switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxTranscodingMMR", "true");
if (atoi(attr->a_value) == 0) {
t38_options->T38FaxTranscodingMMR = SWITCH_FALSE;
} else {
t38_options->T38FaxTranscodingMMR = SWITCH_TRUE;
}
} else {
switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxTranscodingMMR", "false");
t38_options->T38FaxTranscodingMMR = SWITCH_TRUE;
}
t38_options->T38FaxTranscodingMMR = switch_safe_atoi(attr->a_value, 1);
} else if (!strcasecmp(attr->a_name, "T38FaxTranscodingJBIG")) {
if (switch_stristr("T38FaxTranscodingJBIG:", tech_pvt->remote_sdp_str)) {
switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxTranscodingJBIG", "true");
if (atoi(attr->a_value) == 0) {
t38_options->T38FaxTranscodingJBIG = SWITCH_FALSE;
} else {
t38_options->T38FaxTranscodingJBIG = SWITCH_TRUE;
}
} else {
switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxTranscodingJBIG", "false");
t38_options->T38FaxTranscodingJBIG = SWITCH_TRUE;
}
t38_options->T38FaxTranscodingJBIG = switch_safe_atoi(attr->a_value, 1);
} else if (!strcasecmp(attr->a_name, "T38FaxRateManagement") && attr->a_value) {
t38_options->T38FaxRateManagement = switch_core_session_strdup(tech_pvt->session, attr->a_value);
} else if (!strcasecmp(attr->a_name, "T38FaxMaxBuffer") && attr->a_value) {
@@ -4067,20 +4051,8 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_
switch_channel_set_private(tech_pvt->channel, "t38_options", t38_options);
switch_channel_set_app_flag_key("T38", tech_pvt->channel, CF_APP_T38);
if ((var = switch_channel_get_variable(tech_pvt->channel, "sip_execute_on_image"))) {
char *app, *arg = NULL;
app = switch_core_session_strdup(tech_pvt->session, var);
if (strstr(app, "::")) {
switch_core_session_execute_application_async(tech_pvt->session, app, arg);
} else {
if ((arg = strchr(app, ' '))) {
*arg++ = '\0';
}
switch_core_session_execute_application(tech_pvt->session, app, arg);
}
}
switch_channel_execute_on(tech_pvt->channel, "sip_execute_on_image");
switch_channel_api_on(tech_pvt->channel, "sip_api_on_image");
return t38_options;
}
@@ -4339,7 +4311,9 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
}
}
if ((m = sdp->sdp_media) && (m->m_mode == sdp_sendonly || m->m_mode == sdp_inactive)) {
if ((m = sdp->sdp_media) &&
(m->m_mode == sdp_sendonly || m->m_mode == sdp_inactive ||
(m->m_connections && m->m_connections->c_address && !strcmp(m->m_connections->c_address, "0.0.0.0")))) {
sendonly = 2; /* global sendonly always wins */
}
@@ -4408,6 +4382,11 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
total_codecs = tech_pvt->num_negotiated_codecs;
}
if (switch_stristr("T38FaxFillBitRemoval:", r_sdp) || switch_stristr("T38FaxTranscodingMMR:", r_sdp) ||
switch_stristr("T38FaxTranscodingJBIG:", r_sdp)) {
switch_channel_set_variable(tech_pvt->channel, "t38_broken_boolean", "true");
}
for (m = sdp->sdp_media; m; m = m->m_next) {
sdp_connection_t *connection;
switch_core_session_t *other_session;
@@ -4426,6 +4405,11 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
if (got_udptl && m->m_type == sdp_media_image && m->m_port) {
switch_t38_options_t *t38_options = tech_process_udptl(tech_pvt, sdp, m);
if (switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_NEGOTIATED)) {
match = 1;
goto done;
}
if (switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38)) {
sofia_set_flag(tech_pvt, TFLAG_NOREPLY);
}
@@ -4442,10 +4426,12 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
pass = switch_true(var);
}
/* can't remember if this is necessary but its causing a bug so i'll leave this comment here to remind me
if (sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU)) {
pass = 0;
}
*/
if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) ||
switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA) || !switch_rtp_ready(tech_pvt->rtp_session)) {
pass = 0;
@@ -4606,7 +4592,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
greed:
x = 0;
if (tech_pvt->rm_encoding) { // && !sofia_test_flag(tech_pvt, TFLAG_REINVITE)) {
if (tech_pvt->rm_encoding && !(sofia_test_pflag(tech_pvt->profile, PFLAG_LIBERAL_DTMF) || sofia_test_flag(tech_pvt, TFLAG_LIBERAL_DTMF))) { // && !sofia_test_flag(tech_pvt, TFLAG_REINVITE)) {
char *remote_host = tech_pvt->remote_sdp_audio_ip;
switch_port_t remote_port = tech_pvt->remote_sdp_audio_port;
int same = 0;
@@ -4831,27 +4817,41 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
}
}
if (!best_te && (sofia_test_pflag(tech_pvt->profile, PFLAG_LIBERAL_DTMF) || sofia_test_flag(tech_pvt, TFLAG_LIBERAL_DTMF))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"No 2833 in SDP. Liberal DTMF mode adding %d as telephone-event.\n", tech_pvt->profile->te);
best_te = tech_pvt->profile->te;
}
if (best_te) {
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
te = tech_pvt->te = (switch_payload_t) best_te;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set 2833 dtmf send payload to %u\n", best_te);
if (tech_pvt->rtp_session) {
switch_rtp_set_telephony_event(tech_pvt->rtp_session, (switch_payload_t) best_te);
switch_channel_set_variable_printf(tech_pvt->channel, "sip_2833_send_payload", "%d", best_te);
}
} else {
te = tech_pvt->recv_te = tech_pvt->te = (switch_payload_t) best_te;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set 2833 dtmf send/recv payload to %u\n", te);
if (tech_pvt->rtp_session) {
switch_rtp_set_telephony_event(tech_pvt->rtp_session, te);
switch_channel_set_variable_printf(tech_pvt->channel, "sip_2833_send_payload", "%d", te);
switch_rtp_set_telephony_recv_event(tech_pvt->rtp_session, te);
switch_channel_set_variable_printf(tech_pvt->channel, "sip_2833_recv_payload", "%d", te);
}
}
} else {
if (tech_pvt->dtmf_type == DTMF_2833) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Disable 2833 dtmf\n");
/* by default, use SIP INFO if 2833 is not in the SDP */
if (!switch_false(switch_channel_get_variable(channel, "sip_info_when_no_2833"))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No 2833 in SDP. Disable 2833 dtmf and switch to INFO\n");
switch_channel_set_variable(tech_pvt->channel, "dtmf_type", "info");
tech_pvt->dtmf_type = DTMF_INFO;
te = tech_pvt->recv_te = tech_pvt->te = 0;
} else {
switch_channel_set_variable(tech_pvt->channel, "dtmf_type", "none");
tech_pvt->dtmf_type = DTMF_NONE;
te = tech_pvt->recv_te = 0;
te = tech_pvt->recv_te = tech_pvt->te = 0;
}
}
@@ -5381,9 +5381,19 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName
tech_pvt->remote_port = atoi(switch_str_nil(switch_channel_get_variable(channel, "sip_network_port")));
tech_pvt->caller_profile = switch_channel_get_caller_profile(channel);
if ((tmp = switch_channel_get_variable(tech_pvt->channel, "sip_2833_send_payload"))) {
int te = atoi(tmp);
if (te > 64) {
tech_pvt->te = te;
}
}
if ((tmp = switch_channel_get_variable(tech_pvt->channel, "sip_2833_recv_payload"))) {
int te = atoi(tmp);
if (te > 64) {
tech_pvt->recv_te = te;
}
}
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
tech_pvt->dest = switch_core_session_sprintf(session, "sip:%s", switch_channel_get_variable(channel, "sip_req_uri"));
@@ -5437,6 +5447,7 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName
if (session) {
switch_caller_extension_t *extension = NULL;
const char *ip = switch_channel_get_variable(channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE);
const char *a_ip = switch_channel_get_variable(channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE);
const char *port = switch_channel_get_variable(channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
const char *r_ip = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE);
const char *r_port = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE);
@@ -5476,11 +5487,15 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName
tech_pvt->adv_sdp_audio_ip = tech_pvt->extrtpip = (char *) ip;
tech_pvt->adv_sdp_audio_port = tech_pvt->local_sdp_audio_port = (switch_port_t)atoi(port);
if ((tmp = switch_channel_get_variable(channel, "local_media_ip"))) {
tech_pvt->local_sdp_audio_ip = switch_core_session_strdup(session, tmp);
if (!zstr(ip)) {
tech_pvt->local_sdp_audio_ip = switch_core_session_strdup(session, ip);
tech_pvt->rtpip = tech_pvt->local_sdp_audio_ip;
}
if (!zstr(a_ip)) {
tech_pvt->adv_sdp_audio_ip = switch_core_session_strdup(session, a_ip);
}
if (r_ip && r_port) {
tech_pvt->remote_sdp_audio_ip = (char *) r_ip;
tech_pvt->remote_sdp_audio_port = (switch_port_t)atoi(r_port);
@@ -5538,6 +5553,14 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName
}
}
if (tech_pvt->te) {
switch_rtp_set_telephony_event(tech_pvt->rtp_session, tech_pvt->te);
}
if (tech_pvt->recv_te) {
switch_rtp_set_telephony_recv_event(tech_pvt->rtp_session, tech_pvt->recv_te);
}
}
if (switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) {
@@ -6546,6 +6569,14 @@ void sofia_glue_parse_rtp_bugs(switch_rtp_bug_flag_t *flag_pole, const char *str
if (switch_stristr("~IGNORE_DTMF_DURATION", str)) {
*flag_pole &= ~RTP_BUG_IGNORE_DTMF_DURATION;
}
if (switch_stristr("ACCEPT_ANY_PACKETS", str)) {
*flag_pole |= RTP_BUG_ACCEPT_ANY_PACKETS;
}
if (switch_stristr("~ACCEPT_ANY_PACKETS", str)) {
*flag_pole &= ~RTP_BUG_ACCEPT_ANY_PACKETS;
}
}
char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_dispatch_event_t *de, sofia_nat_parse_t *np)
+150 -46
View File
@@ -72,8 +72,8 @@ struct presence_helper {
char last_uuid[512];
};
switch_status_t sofia_presence_chat_send(const char *proto, const char *from, const char *to, const char *subject,
const char *body, const char *type, const char *hint)
switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
{
char *prof = NULL, *user = NULL, *host = NULL;
sofia_profile_t *profile = NULL;
@@ -93,6 +93,27 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
char *dup_dest = NULL;
char *p = NULL;
char *remote_host = NULL;
const char *proto;
const char *from;
const char *to;
//const char *subject;
const char *body;
const char *type;
const char *from_full;
char header[256] = "";
char *route_uri = NULL;
const char *network_ip = NULL, *network_port = NULL;
proto = switch_event_get_header(message_event, "proto");
from = switch_event_get_header(message_event, "from");
to = switch_event_get_header(message_event, "to");
//subject = switch_event_get_header(message_event, "subject");
body = switch_event_get_body(message_event);
type = switch_event_get_header(message_event, "type");
from_full = switch_event_get_header(message_event, "from_full");
network_ip = switch_event_get_header(message_event, "to_sip_ip");
network_port = switch_event_get_header(message_event, "to_sip_port");
if (!to) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing To: header.\n");
@@ -114,6 +135,10 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
user = prof;
prof = NULL;
}
if (!prof) {
prof = switch_event_get_header(message_event, "sip_profile");
}
if (!strncasecmp(user, "sip:", 4)) {
to_uri = user;
@@ -125,13 +150,14 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
} else {
host++;
}
if (!prof)
if (!prof) {
prof = host;
}
}
if (!prof || !(profile = sofia_glue_find_profile(prof))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Chat proto [%s]\nfrom [%s]\nto [%s]\n%s\nInvalid Profile %s\n", proto, from, to,
"Chat proto [%s]\nfrom [%s]\nto [%s]\n%s\nInvalid Profile %s\n", proto, from, to,
body ? body : "[no body]", prof ? prof : "NULL");
goto end;
}
@@ -143,24 +169,34 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
}
}
if (to_uri) {
switch_console_push_match(&list, to_uri);
} else if (!(list = sofia_reg_find_reg_url_multi(profile, user, host))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find registered user %s@%s\n", user, host);
goto end;
sofia_profile_t *test;
if ((test = sofia_glue_find_profile(host))) {
sofia_glue_release_profile(test);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Not sending to local box for %s@%s\n", user, host);
/* our box let's not send it */
} else {
char *tmp;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Can't find registered user %s@%s\n", user, host);
tmp = switch_mprintf("sip:%s@%s", user, host);
switch_console_push_match(&list, tmp);
free(tmp);
}
}
if (!strcasecmp(proto, SOFIA_CHAT_PROTO)) {
from = hint;
from = from_full;
} else {
char *fp, *p = NULL;
fp = strdup(from);
switch_assert(fp);
if (!fp) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
goto end;
}
if ((p = strchr(fp, '@'))) {
*p++ = '\0';
@@ -173,12 +209,23 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
}
}
ffrom = switch_mprintf("\"%s\" <sip:%s+%s@%s>", fp, proto, fp, p);
if (switch_stristr("global", proto)) {
ffrom = switch_mprintf("\"%s\" <sip:%s@%s>", fp, fp, p);
} else {
ffrom = switch_mprintf("\"%s\" <sip:%s+%s@%s>", fp, proto, fp, p);
}
from = ffrom;
switch_safe_free(fp);
}
if (!list) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Chat proto [%s]\nfrom [%s]\nto [%s]\n%s\nNobody to send to: Profile %s\n", proto, from, to,
body ? body : "[no body]", prof ? prof : "NULL");
goto end;
}
for (m = list->head; m; m = m->next) {
if (!(dst = sofia_glue_get_destination(m->val))) {
@@ -233,22 +280,35 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
}
/* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */
//printf("DEBUG To: [%s] From: [%s] Contact: [%s] RURI [%s] ip [%s] port [%s]\n", to, from, contact, dst->route_uri, network_ip, network_port);
//DUMP_EVENT(message_event);
if (zstr(dst->route_uri) && !zstr(user) && !zstr(network_ip) && (zstr(host) || strcmp(network_ip, host))) {
route_uri = switch_mprintf("sip:%s@%s:%s", user, network_ip, network_port);
}
msg_nh = nua_handle(profile->nua, NULL,
TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)),
TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
SIPTAG_FROM_STR(from),
TAG_IF(contact, NUTAG_URL(contact)),
SIPTAG_TO_STR(dup_dest),
SIPTAG_CONTACT_STR(contact_str),
TAG_END());
nua_handle_bind(msg_nh, &mod_sofia_globals.destroy_private);
switch_snprintf(header, sizeof(header), "X-FS-Sending-Message: %s", switch_core_get_uuid());
nua_message(msg_nh,
TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)),
TAG_IF(route_uri, NUTAG_PROXY(route_uri)),
TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
SIPTAG_FROM_STR(from),
TAG_IF(contact, NUTAG_URL(contact)),
SIPTAG_TO_STR(dup_dest),
SIPTAG_CONTACT_STR(contact_str),
TAG_IF(user_via, SIPTAG_VIA_STR(user_via)),
SIPTAG_CONTENT_TYPE_STR(ct),
SIPTAG_PAYLOAD_STR(body),
SIPTAG_HEADER_STR(header),
TAG_END());
sofia_glue_free_destination(dst);
@@ -261,6 +321,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
end:
switch_safe_free(contact);
switch_safe_free(route_uri);
switch_safe_free(ffrom);
switch_safe_free(dup);
@@ -702,7 +763,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
"from sip_registrations "
"left join sip_dialogs on "
"sip_dialogs.presence_id = sip_registrations.sip_user || '@' || sip_registrations.sip_host "
"sip_dialogs.presence_id = sip_registrations.sip_user %q '@' %q sip_registrations.sip_host "
"or (sip_dialogs.sip_from_user = sip_registrations.sip_user "
"and sip_dialogs.sip_from_host = sip_registrations.sip_host) "
@@ -713,6 +774,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
"(sip_registrations.orig_server_host='%q' or sip_registrations.sip_host='%q' "
"or sip_registrations.presence_hosts like '%%%q%%'))",
dh.status, dh.rpid,
switch_sql_concat(), switch_sql_concat(),
probe_euser, probe_host, probe_euser, probe_host, probe_host, probe_host);
switch_assert(sql);
@@ -1983,14 +2045,21 @@ static int broadsoft_sla_gather_state_callback(void *pArg, int argc, char **argv
if (uuid && (session = switch_core_session_locate(uuid))) {
switch_channel_t *channel = switch_core_session_get_channel(session);
if (zstr((callee_name = switch_channel_get_variable(channel, "effective_callee_id_name"))) &&
zstr((callee_name = switch_channel_get_variable(channel, "sip_callee_id_name")))) {
callee_name = switch_channel_get_variable(channel, "callee_id_name");
}
if (zstr((callee_number = switch_channel_get_variable(channel, "effective_callee_id_number"))) &&
zstr((callee_number = switch_channel_get_variable(channel, "sip_callee_id_number")))) {
callee_number = switch_channel_get_variable(channel, "destination_number");
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
if (zstr((callee_name = switch_channel_get_variable(channel, "effective_callee_id_name"))) &&
zstr((callee_name = switch_channel_get_variable(channel, "sip_callee_id_name")))) {
callee_name = switch_channel_get_variable(channel, "callee_id_name");
}
if (zstr((callee_number = switch_channel_get_variable(channel, "effective_callee_id_number"))) &&
zstr((callee_number = switch_channel_get_variable(channel, "sip_callee_id_number"))) &&
zstr((callee_number = switch_channel_get_variable(channel, "callee_id_number")))) {
callee_number = switch_channel_get_variable(channel, "destination_number");
}
} else {
callee_name = switch_channel_get_variable(channel, "caller_id_name");
callee_number = switch_channel_get_variable(channel, "caller_id_number");
}
if (zstr(callee_name) && !zstr(callee_number)) {
@@ -2849,13 +2918,25 @@ void sofia_presence_handle_sip_i_message(int status,
const char *to_host = NULL;
sip_payload_t *payload = sip->sip_payload;
char *msg = NULL;
const char *us;
char network_ip[80];
int network_port = 0;
if ((us = sofia_glue_get_unknown_header(sip, "X-FS-Sending-Message")) && !strcmp(us, switch_core_get_uuid())) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Not sending message to ourselves!\n");
goto end;
}
if (sip->sip_content_type && sip->sip_content_type->c_subtype) {
if (strstr(sip->sip_content_type->c_subtype, "composing")) {
return;
goto end;
}
}
sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
if (from) {
from_user = from->a_url->url_user;
from_host = from->a_url->url_host;
@@ -2867,7 +2948,7 @@ void sofia_presence_handle_sip_i_message(int status,
}
if (!to_user) {
return;
goto end;
}
if (payload) {
@@ -2906,33 +2987,56 @@ void sofia_presence_handle_sip_i_message(int status,
sofia_presence_set_hash_key(hash_key, sizeof(hash_key), sip);
}
if (sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT) && (tech_pvt = (private_object_t *) switch_core_hash_find(profile->chat_hash, hash_key))) {
if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", from_addr);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hint", full_from);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to", to_addr);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", "SIMPLE MESSAGE");
if (msg) {
switch_event_add_body(event, "%s", msg);
}
if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", from_addr);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_user", from_user);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_host", from_host);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to_user", to_user);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to_host", to_host);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_sip_ip", network_ip);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from_sip_port", "%d", network_port);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to", to_addr);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", "SIMPLE MESSAGE");
if (switch_core_session_queue_event(tech_pvt->session, &event) != SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true");
switch_event_fire(&event);
}
if (sip->sip_content_type && sip->sip_content_type->c_subtype) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", sip->sip_content_type->c_type);
} else {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "text/plain");
}
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_full", full_from);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "sip_profile", profile->name);
if (msg) {
switch_event_add_body(event, "%s", msg);
}
} else {
switch_core_chat_send(proto, SOFIA_CHAT_PROTO, from_addr, to_addr, "", msg, NULL, full_from);
abort();
}
if (sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT) && (tech_pvt = (private_object_t *) switch_core_hash_find(profile->chat_hash, hash_key))) {
switch_core_session_queue_event(tech_pvt->session, &event);
} else {
switch_core_chat_send(proto, event);
switch_event_destroy(&event);
}
switch_safe_free(to_addr);
switch_safe_free(from_addr);
if (full_from) {
su_free(nh->nh_home, full_from);
}
}
}
end:
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
}
void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip)
+216 -90
View File
@@ -30,9 +30,10 @@
* Marcel Barbulescu <marcelbarbulescu@gmail.com>
* David Knell <>
* Eliot Gable <egable AT.AT broadvox.com>
* Leon de Rooij <leon@scarlet-internet.nl>
*
*
* sofia_ref.c -- SOFIA SIP Endpoint (registration code)
* sofia_reg.c -- SOFIA SIP Endpoint (registration code)
*
*/
#include "mod_sofia.h"
@@ -240,37 +241,41 @@ void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now)
void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
{
sofia_gateway_t *gateway_ptr, *last = NULL;
sofia_gateway_t *check, *gateway_ptr, *last = NULL;
switch_event_t *event;
char *pkey;
switch_mutex_lock(profile->gw_mutex);
for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) {
if (gateway_ptr->deleted && gateway_ptr->state == REG_STATE_NOREG) {
if (last) {
last->next = gateway_ptr->next;
} else {
profile->gateways = gateway_ptr->next;
if (gateway_ptr->deleted) {
if ((check = switch_core_hash_find(mod_sofia_globals.gateway_hash, gateway_ptr->name)) && check == gateway_ptr) {
char *pkey = switch_mprintf("%s::%s", profile->name, gateway_ptr->name);
switch_assert(pkey);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing gateway %s from hash.\n", pkey);
switch_core_hash_delete(mod_sofia_globals.gateway_hash, pkey);
switch_core_hash_delete(mod_sofia_globals.gateway_hash, gateway_ptr->name);
free(pkey);
}
pkey = switch_mprintf("%s::%s", profile->name, gateway_ptr->name);
if (gateway_ptr->state == REG_STATE_NOREG) {
switch_core_hash_delete(mod_sofia_globals.gateway_hash, pkey);
switch_core_hash_delete(mod_sofia_globals.gateway_hash, gateway_ptr->name);
free(pkey);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleted gateway %s\n", gateway_ptr->name);
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_GATEWAY_DEL) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "profile-name", gateway_ptr->profile->name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Gateway", gateway_ptr->name);
switch_event_fire(&event);
}
if (gateway_ptr->ob_vars) {
switch_event_destroy(&gateway_ptr->ob_vars);
}
if (gateway_ptr->ib_vars) {
switch_event_destroy(&gateway_ptr->ib_vars);
if (last) {
last->next = gateway_ptr->next;
} else {
profile->gateways = gateway_ptr->next;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleted gateway %s\n", gateway_ptr->name);
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_GATEWAY_DEL) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "profile-name", gateway_ptr->profile->name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Gateway", gateway_ptr->name);
switch_event_fire(&event);
}
if (gateway_ptr->ob_vars) {
switch_event_destroy(&gateway_ptr->ob_vars);
}
if (gateway_ptr->ib_vars) {
switch_event_destroy(&gateway_ptr->ib_vars);
}
}
} else {
last = gateway_ptr;
@@ -466,6 +471,39 @@ int sofia_reg_find_callback(void *pArg, int argc, char **argv, char **columnName
return cbt->matches == 1 ? 0 : 1;
}
int sofia_reg_find_reg_with_positive_expires_callback(void *pArg, int argc, char **argv, char **columnNames)
{
struct callback_t *cbt = (struct callback_t *) pArg;
sofia_destination_t *dst = NULL;
long int expires;
char *contact = NULL;
expires = atol(argv[1]) - 60 - (long) switch_epoch_time_now(NULL);
if (expires > 0) {
dst = sofia_glue_get_destination(argv[0]);
contact = switch_mprintf("<%s>;expires=%ld", dst->contact, expires);
if (!cbt->len) {
switch_console_push_match(&cbt->list, contact);
switch_safe_free(contact);
sofia_glue_free_destination(dst);
cbt->matches++;
return 0;
}
switch_copy_string(cbt->val, contact, cbt->len);
switch_safe_free(contact);
sofia_glue_free_destination(dst);
cbt->matches++;
return cbt->matches == 1 ? 0 : 1;
}
return 0;
}
int sofia_reg_nat_callback(void *pArg, int argc, char **argv, char **columnNames)
{
sofia_profile_t *profile = (sofia_profile_t *) pArg;
@@ -875,6 +913,29 @@ switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *p
}
switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_multi(sofia_profile_t *profile, const char *user, const char *host)
{
struct callback_t cbt = { 0 };
char sql[512] = "";
if (!user) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Called with null user!\n");
return NULL;
}
if (host) {
switch_snprintf(sql, sizeof(sql), "select contact,expires from sip_registrations where sip_user='%s' and (sip_host='%s' or presence_hosts like '%%%s%%')",
user, host, host);
} else {
switch_snprintf(sql, sizeof(sql), "select contact,expires from sip_registrations where sip_user='%s'", user);
}
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_find_reg_with_positive_expires_callback, &cbt);
return cbt.list;
}
void sofia_reg_auth_challenge(sofia_profile_t *profile, nua_handle_t *nh, sofia_dispatch_event_t *de,
sofia_regtype_t regtype, const char *realm, int stale)
{
@@ -983,8 +1044,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
}
}
/* all callers must confirm that sip, sip->sip_request and sip->sip_contact are not NULL */
switch_assert(sip != NULL && sip->sip_contact != NULL && sip->sip_request != NULL);
/* all callers must confirm that sip and sip->sip_request are not NULL */
switch_assert(sip != NULL && sip->sip_request != NULL);
sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
@@ -1032,7 +1093,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
sub_host = to_host;
}
if (contact->m_url) {
if (contact && contact->m_url) {
const char *port = contact->m_url->url_port;
char new_port[25] = "";
const char *contact_host = contact->m_url->url_host;
@@ -1130,7 +1191,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
if (expires) {
exptime = expires->ex_delta;
} else if (contact->m_expires) {
} else if (contact && contact->m_expires) {
exptime = atol(contact->m_expires);
}
@@ -1163,11 +1224,13 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str);
if (contact)
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", rpid);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", reg_desc);
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);
if (contact)
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-user", from_user);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-host", from_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "network-ip", network_ip);
@@ -1178,7 +1241,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_event_fire(&s_event);
}
if (exptime && v_event && *v_event) {
if (contact && exptime && v_event && *v_event) {
char *exp_var;
char *allow_multireg = NULL;
int auto_connectile = 0;
@@ -1218,13 +1281,14 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
if (auto_connectile || (v_contact_str = switch_event_get_header(*v_event, "sip-force-contact"))) {
if (auto_connectile || (!strcasecmp(v_contact_str, "NDLB-connectile-dysfunction-2.0"))) {
char *path_encoded;
char *path_encoded = NULL;
size_t path_encoded_len;
char my_contact_str[1024];
switch_snprintf(my_contact_str, sizeof(my_contact_str), "sip:%s@%s:%d", contact->m_url->url_user, url_ip, network_port);
path_encoded_len = (strlen(my_contact_str) * 3) + 1;
if (!switch_stristr("fs_path=", contact_str)) {
switch_zmalloc(path_encoded, path_encoded_len);
switch_copy_string(path_encoded, ";fs_nat=yes;fs_path=", 21);
switch_url_encode(my_contact_str, path_encoded + 20, path_encoded_len - 20);
@@ -1237,7 +1301,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
} else {
switch_snprintf(contact_str + strlen(contact_str), sizeof(contact_str) - strlen(contact_str), "%s", path_encoded);
}
free(path_encoded);
switch_safe_free(path_encoded);
}
} else {
if (*received_data && sofia_test_pflag(profile, PFLAG_RECIEVED_IN_NAT_REG_CONTACT)) {
switch_snprintf(received_data, sizeof(received_data), ";received=%s:%d", url_ip, network_port);
@@ -1308,11 +1373,13 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str);
if (contact)
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", rpid);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", reg_desc);
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);
if (contact)
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-user", from_user);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-host", from_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "network-ip", network_ip);
@@ -1334,13 +1401,17 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
}
/* Log line added to support Fail2Ban */
if (sofia_test_pflag(profile, PFLAG_LOG_AUTH_FAIL)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SIP auth challenge (%s) on sofia profile '%s' "
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "SIP auth challenge (%s) on sofia profile '%s' "
"for [%s@%s] from ip %s\n", (regtype == REG_INVITE) ? "INVITE" : "REGISTER",
profile->name, to_user, to_host, network_ip);
}
switch_goto_int(r, 1, end);
}
if (!contact)
goto respond_200_ok;
reg:
@@ -1587,69 +1658,113 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
}
}
respond_200_ok:
if (regtype == REG_REGISTER) {
char exp_param[128] = "";
char date[80] = "";
switch_event_t *s_mwi_event = NULL;
switch_console_callback_match_t *contact_list = NULL;
tagi_t *contact_tags;
switch_console_callback_match_node_t *m;
int i;
s_event = NULL;
if (exptime) {
switch_snprintf(exp_param, sizeof(exp_param), "expires=%ld", exptime);
sip_contact_add_param(nua_handle_home(nh), sip->sip_contact, exp_param);
if (contact) {
if (exptime) {
switch_snprintf(exp_param, sizeof(exp_param), "expires=%ld", exptime);
sip_contact_add_param(nua_handle_home(nh), sip->sip_contact, exp_param);
if (sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER) ||
(reg_count == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) {
if (switch_event_create(&s_mwi_event, SWITCH_EVENT_MESSAGE_QUERY) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(s_mwi_event, SWITCH_STACK_BOTTOM, "Message-Account", "sip:%s@%s", mwi_user, mwi_host);
switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Sofia-Profile", profile->name);
switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Call-ID", call_id);
}
}
if (sofia_test_pflag(profile, PFLAG_PRESENCE_ON_REGISTER) ||
(reg_count == 1 && sofia_test_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER))
|| send_pres == 1 || (reg_count == 1 && send_pres == 2)) {
if (sofia_test_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)) {
if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name);
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host);
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, sub_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
switch_event_fire(&s_event);
if (sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER) ||
(reg_count == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) {
if (switch_event_create(&s_mwi_event, SWITCH_EVENT_MESSAGE_QUERY) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(s_mwi_event, SWITCH_STACK_BOTTOM, "Message-Account", "sip:%s@%s", mwi_user, mwi_host);
switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Sofia-Profile", profile->name);
switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Call-ID", call_id);
}
} else {
if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name);
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", "Registered");
switch_event_fire(&s_event);
}
}
}
} else {
switch_core_del_registration(to_user, reg_host, call_id);
if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_UNREGISTER) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", rpid);
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);
if (sofia_test_pflag(profile, PFLAG_PRESENCE_ON_REGISTER) ||
(reg_count == 1 && sofia_test_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER))
|| send_pres == 1 || (reg_count == 1 && send_pres == 2)) {
if (sofia_test_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)) {
if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name);
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host);
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, sub_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
switch_event_fire(&s_event);
}
} else {
if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name);
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", "Registered");
switch_event_fire(&s_event);
}
}
}
} else {
const char *username = "unknown";
if (auth_params) {
username = switch_event_get_header(auth_params, "sip_auth_username");
}
switch_core_del_registration(to_user, reg_host, call_id);
if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_UNREGISTER) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "username", username);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", rpid);
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);
}
}
}
switch_rfc822_date(date, switch_micro_time_now());
nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(sip->sip_contact),
TAG_IF(path_val, SIPTAG_PATH_STR(path_val)), NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_END());
/* generate and respond a 200 OK */
if (mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup) {
/* handle backwards compatibility - contacts will not be looked up but only copied from the request into the response
remove this condition later if nobody complains about the extra select of the below new behavior
also remove the parts in mod_sofia.h, sofia.c and sofia_reg.c that refer to reg_deny_binding_fetch_and_no_lookup */
nua_respond(nh, SIP_200_OK, TAG_IF(contact, SIPTAG_CONTACT(sip->sip_contact)), TAG_IF(path_val, SIPTAG_PATH_STR(path_val)),
NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_END());
} else if ((contact_list = sofia_reg_find_reg_url_with_positive_expires_multi(profile, from_user, reg_host))) {
/* all + 1 tag_i elements initialized as NULL - last one implies TAG_END() */
switch_zmalloc(contact_tags, sizeof(*contact_tags) * (contact_list->count + 1));
i = 0;
for (m = contact_list->head; m; m = m->next) {
contact_tags[i].t_tag = siptag_contact_str;
contact_tags[i].t_value = (tag_value_t) m->val;
++i;
}
nua_respond(nh, SIP_200_OK, TAG_IF(path_val, SIPTAG_PATH_STR(path_val)),
NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_NEXT(contact_tags));
switch_safe_free(contact_tags);
switch_console_free_matches(&contact_list);
} else {
/* respond without any contacts */
nua_respond(nh, SIP_200_OK, TAG_IF(path_val, SIPTAG_PATH_STR(path_val)),
NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_END());
}
if (s_event) {
switch_event_fire(&s_event);
@@ -1659,7 +1774,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_event_fire(&s_mwi_event);
}
if (*contact_str && sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE_SYLANTRO)) {
if (contact && *contact_str && sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE_SYLANTRO)) {
sofia_sla_handle_register(nua, profile, sip, de, exptime, contact_str);
}
@@ -1705,7 +1820,8 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
if (!(sip->sip_contact && sip->sip_contact->m_url)) {
/* backwards compatibility */
if (mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup && !(sip->sip_contact && sip->sip_contact->m_url)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO CONTACT! ip: %s, port: %i\n", network_ip, network_port);
nua_respond(nh, 400, "Missing Contact Header", TAG_END());
goto end;
@@ -2703,7 +2819,7 @@ sofia_gateway_t *sofia_reg_find_gateway_by_realm__(const char *file, const char
switch_mutex_lock(mod_sofia_globals.hash_mutex);
for (hi = switch_hash_first(NULL, mod_sofia_globals.gateway_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &var, NULL, &val);
if (key && (gateway = (sofia_gateway_t *) val) && gateway->register_realm && !strcasecmp(gateway->register_realm, key)) {
if (key && (gateway = (sofia_gateway_t *) val) && !gateway->deleted && gateway->register_realm && !strcasecmp(gateway->register_realm, key)) {
break;
} else {
gateway = NULL;
@@ -2757,6 +2873,7 @@ switch_status_t sofia_reg_add_gateway(sofia_profile_t *profile, const char *key,
{
switch_status_t status = SWITCH_STATUS_FALSE;
char *pkey = switch_mprintf("%s::%s", profile->name, key);
sofia_gateway_t *gp;
switch_mutex_lock(profile->gw_mutex);
@@ -2766,12 +2883,21 @@ switch_status_t sofia_reg_add_gateway(sofia_profile_t *profile, const char *key,
switch_mutex_unlock(profile->gw_mutex);
switch_mutex_lock(mod_sofia_globals.hash_mutex);
if (!switch_core_hash_find(mod_sofia_globals.gateway_hash, key)) {
status = switch_core_hash_insert(mod_sofia_globals.gateway_hash, key, gateway);
if ((gp = switch_core_hash_find(mod_sofia_globals.gateway_hash, key))) {
if (gp->deleted) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing deleted gateway from hash.\n");
switch_core_hash_delete(mod_sofia_globals.gateway_hash, gp->name);
switch_core_hash_delete(mod_sofia_globals.gateway_hash, pkey);
switch_core_hash_delete(mod_sofia_globals.gateway_hash, key);
}
}
if (!switch_core_hash_find(mod_sofia_globals.gateway_hash, pkey)) {
if (!switch_core_hash_find(mod_sofia_globals.gateway_hash, key) && !switch_core_hash_find(mod_sofia_globals.gateway_hash, pkey)) {
status = switch_core_hash_insert(mod_sofia_globals.gateway_hash, key, gateway);
status = switch_core_hash_insert(mod_sofia_globals.gateway_hash, pkey, gateway);
} else {
status = SWITCH_STATUS_FALSE;
}
switch_mutex_unlock(mod_sofia_globals.hash_mutex);