Merge remote branch 'fsorig/master'

This commit is contained in:
Moises Silva
2012-05-07 15:46:08 -04:00
683 changed files with 43414 additions and 75312 deletions
+19 -25
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -91,6 +91,10 @@ static switch_status_t sofia_on_init(switch_core_session_t *session)
sofia_set_flag(tech_pvt, TFLAG_RECOVERED);
}
if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
nua_respond(tech_pvt->nh, 101, "Dialing", TAG_END());
}
if (sofia_test_flag(tech_pvt, TFLAG_OUTBOUND) || sofia_test_flag(tech_pvt, TFLAG_RECOVERING)) {
const char *var;
@@ -495,7 +499,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
val = switch_channel_get_variable(tech_pvt->channel, "disable_q850_reason");
if (!val || switch_false(val)) {
if ((val = switch_channel_get_variable(tech_pvt->channel, "sip_reason_str"))) {
if ((val = switch_channel_get_variable(tech_pvt->channel, "sip_reason"))) {
switch_snprintf(reason, sizeof(reason), "%s", val);
} else {
if (switch_channel_test_flag(channel, CF_INTERCEPT) || cause == SWITCH_CAUSE_PICKED_OFF || cause == SWITCH_CAUSE_LOSE_RACE) {
@@ -1929,6 +1933,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
switch_channel_set_flag(channel, CF_REQ_MEDIA);
}
sofia_set_flag_locked(tech_pvt, TFLAG_SENT_UPDATE);
switch_channel_set_variable(channel, "sip_require_timer", "false");
sofia_glue_do_invite(session);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Request to send IMAGE on channel with not t38 options.\n",
@@ -2087,20 +2092,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
case SWITCH_MESSAGE_INDICATE_DISPLAY:
{
const char *name = msg->string_array_arg[0], *number = msg->string_array_arg[1];
char *arg = NULL;
char *argv[2] = { 0 };
//int argc;
if (zstr(name) && !zstr(msg->string_arg)) {
arg = strdup(msg->string_arg);
switch_assert(arg);
switch_separate_string(arg, '|', argv, (sizeof(argv) / sizeof(argv[0])));
name = argv[0];
number = argv[1];
}
if (!zstr(name)) {
char message[256] = "";
const char *ua = switch_channel_get_variable(tech_pvt->channel, "sip_user_agent");
@@ -2181,9 +2173,6 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
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) {
@@ -2208,8 +2197,6 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
}
}
}
switch_safe_free(arg);
}
break;
@@ -2422,6 +2409,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
char *sdp = (char *) msg->pointer_arg;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Responding with %d [%s]\n", code, reason);
sofia_clear_flag(tech_pvt, TFLAG_REINVITED);
if (!zstr((sdp))) {
if (!strcasecmp(sdp, "t38")) {
@@ -5364,7 +5352,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
switch_chat_interface_t *chat_interface;
switch_api_interface_t *api_interface;
switch_management_interface_t *management_interface;
uint32_t cpus = switch_core_cpu_count();
struct in_addr in;
memset(&mod_sofia_globals, 0, sizeof(mod_sofia_globals));
@@ -5402,9 +5389,16 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for profiles to start\n");
switch_yield(1500000);
/* start one message thread per cpu */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Starting %u message threads.\n", cpus);
sofia_msg_thread_start(cpus);
mod_sofia_globals.cpu_count = switch_core_cpu_count();
mod_sofia_globals.max_msg_queues = mod_sofia_globals.cpu_count + 1;
if (mod_sofia_globals.max_msg_queues > SOFIA_MAX_MSG_QUEUE) {
mod_sofia_globals.max_msg_queues = SOFIA_MAX_MSG_QUEUE;
}
/* start one message thread */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Starting initial message thread.\n");
sofia_msg_thread_start(0);
if (switch_event_bind_removable(modname, SWITCH_EVENT_CUSTOM, MULTICAST_EVENT, event_handler, NULL,
&mod_sofia_globals.custom_node) != SWITCH_STATUS_SUCCESS) {
+24 -4
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -24,7 +24,7 @@
* Contributor(s):
*
* Anthony Minessale II <anthm@freeswitch.org>
* Ken Rice, Asteria Solutions Group, Inc <ken@asteriasgi.com>
* Ken Rice <krice@freeswitch.org>
* Paul D. Tinsley <pdt at jackhammer.org>
* Bret McDanel <trixter AT 0xdecafbad.com>
* Marcel Barbulescu <marcelbarbulescu@gmail.com>
@@ -78,6 +78,7 @@ typedef struct private_object private_object_t;
#define MY_EVENT_REGISTER "sofia::register"
#define MY_EVENT_PRE_REGISTER "sofia::pre_register"
#define MY_EVENT_REGISTER_ATTEMPT "sofia::register_attempt"
#define MY_EVENT_REGISTER_FAILURE "sofia::register_failure"
#define MY_EVENT_UNREGISTER "sofia::unregister"
#define MY_EVENT_EXPIRE "sofia::expire"
#define MY_EVENT_GATEWAY_STATE "sofia::gateway_state"
@@ -330,12 +331,13 @@ typedef enum {
TFLAG_LIBERAL_DTMF,
TFLAG_GOT_ACK,
TFLAG_CAPTURE,
TFLAG_REINVITED,
/* No new flags below this line */
TFLAG_MAX
} TFLAGS;
#define SOFIA_MAX_MSG_QUEUE 101
#define SOFIA_MSG_QUEUE_SIZE 5000
#define SOFIA_MAX_MSG_QUEUE 64
#define SOFIA_MSG_QUEUE_SIZE 250
struct mod_sofia_globals {
switch_memory_pool_t *pool;
@@ -345,6 +347,8 @@ struct mod_sofia_globals {
uint32_t callid;
int32_t running;
int32_t threads;
int cpu_count;
int max_msg_queues;
switch_mutex_t *mutex;
char guess_ip[80];
char hostname[512];
@@ -509,12 +513,25 @@ typedef enum {
PRES_TYPE_PASSIVE = 2
} sofia_presence_type_t;
typedef enum {
PRES_HELD_EARLY = 0,
PRES_HELD_CONFIRMED = 1,
PRES_HELD_TERMINATED = 2
} sofia_presence_held_calls_type_t;
typedef enum {
MEDIA_OPT_NONE = 0,
MEDIA_OPT_MEDIA_ON_HOLD = (1 << 0),
MEDIA_OPT_BYPASS_AFTER_ATT_XFER = (1 << 1)
} sofia_media_options_t;
typedef enum {
PAID_DEFAULT = 0,
PAID_USER,
PAID_USER_DOMAIN,
PAID_VERBATIM
} sofia_paid_type_t;
#define MAX_RTPIP 50
struct sofia_profile {
@@ -616,6 +633,7 @@ struct sofia_profile {
int server_rport_level;
int client_rport_level;
sofia_presence_type_t pres_type;
sofia_presence_held_calls_type_t pres_held_type;
sofia_media_options_t media_options;
uint32_t force_subscription_expires;
uint32_t force_publish_expires;
@@ -652,6 +670,8 @@ struct sofia_profile {
uint32_t sip_force_expires;
uint32_t sip_expires_max_deviation;
int ireg_seconds;
sofia_paid_type_t paid_type;
uint32_t rtp_digit_delay;
};
struct private_object {
+161 -64
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -24,7 +24,7 @@
* Contributor(s):
*
* Anthony Minessale II <anthm@freeswitch.org>
* Ken Rice, Asteria Solutions Group, Inc <ken@asteriasgi.com>
* Ken Rice <krice@freeswitch.org>
* Paul D. Tinsley <pdt at jackhammer.org>
* Bret McDanel <trixter AT 0xdecafbad.com>
* Marcel Barbulescu <marcelbarbulescu@gmail.com>
@@ -469,12 +469,33 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
if (switch_event_create(&s_event, SWITCH_EVENT_NOTIFY_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event", sip->sip_event->o_type);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "pl_data", sip->sip_payload ? sip->sip_payload->pl_data : "");
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "sip_content_type", sip->sip_content_type->c_type);
if ( sip->sip_content_type != NULL )
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "sip_content_type", sip->sip_content_type->c_type);
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", sofia_private->gateway->profile->sip_port);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", sofia_private->gateway->profile->name);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", sofia_private->gateway->profile->url);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "gateway_name", sofia_private->gateway->name);
if ( sip->sip_call_info != NULL ) {
sip_call_info_t *call_info = sip->sip_call_info;
int cur_len = 0;
char *tmp = NULL;
char *hold = strdup(sip_header_as_string(nua_handle_home(nh), (void *) call_info));
cur_len = strlen(hold);
while ( call_info->ci_next != NULL) {
call_info = call_info->ci_next;
tmp = strdup(sip_header_as_string(nua_handle_home(nh), (void *) call_info));
cur_len = cur_len + strlen(tmp) +2;
hold = realloc(hold, cur_len);
switch_assert(hold);
strcat(hold,",");
strcat(hold, tmp);
free(tmp);
}
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "Call-Info", hold);
free(hold);
}
switch_event_fire(&s_event);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "dispatched freeswitch event for message-summary NOTIFY\n");
} else {
@@ -1235,8 +1256,25 @@ void *SWITCH_THREAD_FUNC sofia_msg_thread_run(switch_thread_t *thread, void *obj
{
void *pop;
switch_queue_t *q = (switch_queue_t *) obj;
int my_id;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "MSG Thread Started\n");
for (my_id = 0; my_id < mod_sofia_globals.msg_queue_len; my_id++) {
if (mod_sofia_globals.msg_queue[my_id] == q) {
break;
}
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "MSG Thread %d Started\n", my_id);
#ifdef HAVE_CPU_SET_MACROS
{
cpu_set_t set;
CPU_ZERO(&set);
CPU_SET(my_id, &set);
sched_setaffinity(0, sizeof(set), &set);
}
#endif
while(switch_queue_pop(q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
@@ -1250,12 +1288,11 @@ void *SWITCH_THREAD_FUNC sofia_msg_thread_run(switch_thread_t *thread, void *obj
return NULL;
}
static int IDX = 0;
void sofia_msg_thread_start(int idx)
{
if (idx >= SOFIA_MAX_MSG_QUEUE || (idx < mod_sofia_globals.msg_queue_len && mod_sofia_globals.msg_queue_thread[idx])) {
if (idx >= mod_sofia_globals.max_msg_queues ||
idx >= SOFIA_MAX_MSG_QUEUE || (idx < mod_sofia_globals.msg_queue_len && mod_sofia_globals.msg_queue_thread[idx])) {
return;
}
@@ -1273,7 +1310,7 @@ 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,
@@ -1289,31 +1326,32 @@ void sofia_msg_thread_start(int idx)
static void sofia_queue_message(sofia_dispatch_event_t *de)
{
int idx = 0;
int idx = 0, queued = 0;
if (mod_sofia_globals.running == 0) {
if (mod_sofia_globals.running == 0 || !mod_sofia_globals.msg_queue[0]) {
sofia_process_dispatch_event(&de);
return;
}
again:
switch_mutex_lock(mod_sofia_globals.mutex);
idx = IDX;
IDX++;
if (IDX >= mod_sofia_globals.msg_queue_len) IDX = 0;
switch_mutex_unlock(mod_sofia_globals.mutex);
sofia_msg_thread_start(idx);
if (switch_queue_trypush(mod_sofia_globals.msg_queue[idx], de) != SWITCH_STATUS_SUCCESS) {
if (mod_sofia_globals.msg_queue_len < SOFIA_MAX_MSG_QUEUE) {
sofia_msg_thread_start(idx + 1);
goto again;
} else {
switch_queue_push(mod_sofia_globals.msg_queue[idx], de);
for (idx = 0; idx < mod_sofia_globals.msg_queue_len; idx++) {
if (switch_queue_trypush(mod_sofia_globals.msg_queue[idx], de) == SWITCH_STATUS_SUCCESS) {
queued++;
break;
}
}
if (!queued) {
if (mod_sofia_globals.msg_queue_len < mod_sofia_globals.max_msg_queues) {
sofia_msg_thread_start(mod_sofia_globals.msg_queue_len + 1);
goto again;
}
switch_queue_push(mod_sofia_globals.msg_queue[0], de);
}
}
@@ -1958,6 +1996,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
NUTAG_AUTOACK(0),
NUTAG_AUTOALERT(0),
NUTAG_ENABLEMESSENGER(1),
NTATAG_EXTRA_100(0),
TAG_IF((profile->mflags & MFLAG_REGISTER), NUTAG_ALLOW("REGISTER")),
TAG_IF((profile->mflags & MFLAG_REFER), NUTAG_ALLOW("REFER")),
TAG_IF(!sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_ALLOW("PRACK")),
@@ -2630,9 +2669,8 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s", proxy);
}
gateway->register_from = switch_core_sprintf(gateway->pool, "<sip:%s@%s;transport=%s>",
from_user, !zstr(from_domain) ? from_domain : proxy, register_transport);
gateway->register_from = switch_core_sprintf(gateway->pool, "<sip:%s@%s>",
from_user, !zstr(from_domain) ? from_domain : proxy);
if (ping_freq) {
if (ping_freq >= 5) {
@@ -2640,10 +2678,8 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
gateway->ping_max = ping_max;
gateway->ping_min = ping_min;
gateway->ping = switch_epoch_time_now(NULL) + ping_freq;
gateway->options_to_uri = switch_core_sprintf(gateway->pool, "<sip:%s;transport=%s>",
!zstr(from_domain) ? from_domain : proxy, register_transport);
//gateway->options_from_uri = switch_core_sprintf(gateway->pool, "<sip:%s;transport=%s>",
// profile->extrtpip ? profile->extrtpip : profile->sipip, register_transport);
gateway->options_to_uri = switch_core_sprintf(gateway->pool, "<sip:%s>",
!zstr(from_domain) ? from_domain : proxy);
gateway->options_from_uri = gateway->options_to_uri;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: invalid ping!\n");
@@ -2960,6 +2996,12 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
} else {
sofia_clear_pflag(profile, PFLAG_PASS_CALLEE_ID);
}
} else if (!strcasecmp(var, "rtp-digit-delay")) {
int delay = val ? atoi(val) : 0;
if (delay < 0) delay = 0;
profile->rtp_digit_delay = (uint32_t) delay;
} else if (!strcasecmp(var, "watchdog-enabled")) {
profile->watchdog_enabled = switch_true(val);
} else if (!strcasecmp(var, "watchdog-step-timeout")) {
@@ -3497,6 +3539,18 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
} else {
profile->sip_expires_max_deviation = 0;
}
} else if (!strcasecmp(var, "p-asserted-id-parse")) {
if (!strncasecmp(val, "default", 7)) {
profile->paid_type = PAID_DEFAULT;
} else if (!strncasecmp(val, "user-only", 9)) {
profile->paid_type = PAID_USER;
} else if (!strncasecmp(val, "user-domain", 11)) {
profile->paid_type = PAID_USER_DOMAIN;
} else if (!strncasecmp(val, "verbatim", 8)) {
profile->paid_type = PAID_VERBATIM;
} else {
profile->paid_type = PAID_DEFAULT;
}
}
}
}
@@ -3636,18 +3690,6 @@ 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, "message-threads")) {
int num = atoi(val);
if (num < 1 || num > SOFIA_MAX_MSG_QUEUE - 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "message-threads must be between 1 and %d", SOFIA_MAX_MSG_QUEUE -1);
}
if (num < 1) num = 1;
if (num > SOFIA_MAX_MSG_QUEUE - 1) num = SOFIA_MAX_MSG_QUEUE -1;
sofia_msg_thread_start(num);
} 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)) {
@@ -3732,6 +3774,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
switch_thread_rwlock_create(&profile->rwlock, profile->pool);
switch_mutex_init(&profile->flag_mutex, SWITCH_MUTEX_NESTED, profile->pool);
profile->dtmf_duration = 100;
profile->rtp_digit_delay = 40;
profile->sip_force_expires = 0;
profile->sip_expires_max_deviation = 0;
profile->tls_version = 0;
@@ -3756,6 +3799,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
profile->ndlb |= PFLAG_NDLB_ALLOW_NONDUP_SDP;
profile->te = 101;
profile->ireg_seconds = IREG_SECONDS;
profile->paid_type = PAID_DEFAULT;
profile->tls_verify_policy = TPTLS_VERIFY_NONE;
@@ -3829,6 +3873,12 @@ switch_status_t config_sofia(int reload, char *profile_name)
} else {
sofia_clear_pflag(profile, PFLAG_LIBERAL_DTMF);
}
} else if (!strcasecmp(var, "rtp-digit-delay")) {
int delay = atoi(val);
if (delay < 0) {
delay = 0;
}
profile->rtp_digit_delay = (uint32_t) delay;
} else if (!strcasecmp(var, "watchdog-enabled")) {
profile->watchdog_enabled = switch_true(val);
} else if (!strcasecmp(var, "watchdog-step-timeout")) {
@@ -4203,6 +4253,12 @@ switch_status_t config_sofia(int reload, char *profile_name)
} else if (switch_true(val)) {
profile->pres_type = PRES_TYPE_FULL;
}
} else if (!strcasecmp(var, "presence-hold-state")) {
if (!strcasecmp(val, "confirmed")) {
profile->pres_held_type = PRES_HELD_CONFIRMED;
} else if (!strcasecmp(val, "terminated")) {
profile->pres_held_type = PRES_HELD_TERMINATED;
}
} else if (!strcasecmp(var, "presence-privacy")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_PRESENCE_PRIVACY);
@@ -4571,6 +4627,18 @@ switch_status_t config_sofia(int reload, char *profile_name)
} else {
sofia_clear_pflag(profile, PFLAG_NO_CONNECTION_REUSE);
}
} else if (!strcasecmp(var, "p-asserted-id-parse")) {
if (!strncasecmp(val, "default", 7)) {
profile->paid_type = PAID_DEFAULT;
} else if (!strncasecmp(val, "user-only", 9)) {
profile->paid_type = PAID_USER;
} else if (!strncasecmp(val, "user-domain", 11)) {
profile->paid_type = PAID_USER_DOMAIN;
} else if (!strncasecmp(val, "verbatim", 8)) {
profile->paid_type = PAID_VERBATIM;
} else {
profile->paid_type = PAID_DEFAULT;
}
}
}
@@ -5480,7 +5548,6 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
switch_channel_t *channel = NULL;
private_object_t *tech_pvt = NULL;
const char *replaces_str = NULL;
const char *uuid;
switch_core_session_t *other_session = NULL;
switch_channel_t *other_channel = NULL;
//private_object_t *other_tech_pvt = NULL;
@@ -5672,8 +5739,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
goto done;
}
}
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
&& (other_session = switch_core_session_locate(uuid))) {
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
other_channel = switch_core_session_get_channel(other_session);
if (!switch_channel_get_variable(other_channel, SWITCH_B_SDP_VARIABLE)) {
switch_channel_set_variable(other_channel, SWITCH_B_SDP_VARIABLE, r_sdp);
@@ -5704,9 +5770,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
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);
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
&& (other_session = switch_core_session_locate(uuid))) {
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
other_channel = switch_core_session_get_channel(other_session);
//other_tech_pvt = switch_core_session_get_private(other_session);
@@ -5744,6 +5808,23 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
goto done;
case nua_callstate_received:
if (!sofia_test_flag(tech_pvt, TFLAG_SDP)) {
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
if(sofia_test_flag(other_tech_pvt, TFLAG_REINVITED)) {
/* Due to a race between simultaneous reinvites to both legs of a bridge,
an earlier call to nua_invite silently failed.
So we reject the incoming invite with a 491 and redo the failed outgoing invite. */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Other leg already handling a reinvite, so responding with 491\n");
nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING, TAG_END());
switch_core_session_rwunlock(other_session);
sofia_glue_do_invite(session);
goto done;
}
}
if (r_sdp && !sofia_test_flag(tech_pvt, TFLAG_SDP)) {
if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOMEDIA");
@@ -5889,8 +5970,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
sofia_set_flag_locked(tech_pvt, TFLAG_NOSDP_REINVITE);
if ((switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) && sofia_test_pflag(profile, PFLAG_3PCC_PROXY)) {
sofia_set_flag_locked(tech_pvt, TFLAG_3PCC);
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
&& (other_session = switch_core_session_locate(uuid))) {
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
switch_core_session_message_t *msg;
msg = switch_core_session_alloc(other_session, sizeof(*msg));
msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT;
@@ -5931,11 +6011,11 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
if (switch_stristr("m=image", r_sdp)) {
is_t38 = 1;
}
if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
&& (other_session = switch_core_session_locate(uuid))) {
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
switch_core_session_message_t *msg;
private_object_t *other_tech_pvt;
if (switch_channel_test_flag(channel, CF_PROXY_MODE) && !is_t38 && profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) {
if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp)) {
@@ -5999,6 +6079,16 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
}
}
other_tech_pvt = switch_core_session_get_private(other_session);
if(sofia_test_flag(other_tech_pvt, TFLAG_REINVITED)) {
/* The other leg won the reinvite race */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Other leg already handling reinvite, so responding with 491\n");
nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING, TAG_END());
switch_core_session_rwunlock(other_session);
goto done;
}
sofia_set_flag(tech_pvt, TFLAG_REINVITED);
msg = switch_core_session_alloc(other_session, sizeof(*msg));
msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT;
msg->from = __FILE__;
@@ -6144,8 +6234,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
}
}
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
&& (other_session = switch_core_session_locate(uuid))) {
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
other_channel = switch_core_session_get_channel(other_session);
if (!switch_channel_get_variable(other_channel, SWITCH_B_SDP_VARIABLE)) {
switch_channel_set_variable(other_channel, SWITCH_B_SDP_VARIABLE, r_sdp);
@@ -6214,8 +6303,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
switch_channel_mark_answered(channel);
if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
&& (other_session = switch_core_session_locate(uuid))) {
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
//other_channel = switch_core_session_get_channel(other_session);
//switch_channel_answer(other_channel);
switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
@@ -6241,8 +6329,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
}
}
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
&& (other_session = switch_core_session_locate(uuid))) {
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
other_channel = switch_core_session_get_channel(other_session);
if (!switch_channel_get_variable(other_channel, SWITCH_B_SDP_VARIABLE)) {
switch_channel_set_variable(other_channel, SWITCH_B_SDP_VARIABLE, r_sdp);
@@ -7460,7 +7547,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
nua_respond(nh, 400, "Missing Contact Header", TAG_END());
goto fail;
}
sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
if (sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)) {
@@ -7784,9 +7871,17 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
if ((passerted = sip_p_asserted_identity(sip))) {
if (passerted->paid_url && passerted->paid_url->url_user) {
char *full_paid_header = sip_header_as_string(nh->nh_home, (void *) passerted);
//char *full_paid_header = (char *)(passerted->paid_common->h_data);
from_user = passerted->paid_url->url_user;
if (!zstr(full_paid_header)) {
switch_channel_set_variable(channel, "sip_P-Asserted-Identity", from_user);
if (profile->paid_type == PAID_DEFAULT || profile->paid_type == PAID_USER) {
switch_channel_set_variable(channel, "sip_P-Asserted-Identity", from_user);
} else if (profile->paid_type == PAID_USER_DOMAIN) {
switch_channel_set_variable(channel, "sip_P-Asserted-Identity",
switch_core_session_sprintf(session, "%s@%s", passerted->paid_url->url_user, passerted->paid_url->url_host));
} else if (profile->paid_type == PAID_VERBATIM) {
switch_channel_set_variable(channel, "sip_P-Asserted-Identity", full_paid_header);
}
}
}
if (!zstr(passerted->paid_display)) {
@@ -8282,8 +8377,10 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
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 (is_nat) {
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")) {
+54 -46
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -24,7 +24,7 @@
* Contributor(s):
*
* Anthony Minessale II <anthm@freeswitch.org>
* Ken Rice, Asteria Solutions Group, Inc <ken@asteriasgi.com>
* Ken Rice <krice@freeswitch.org>
* Paul D. Tinsley <pdt at jackhammer.org>
* Bret McDanel <trixter AT 0xdecafbad.com>
* Eliot Gable <egable AT.AT broadvox.com>
@@ -1614,7 +1614,6 @@ void sofia_glue_tech_patch_sdp(private_object_t *tech_pvt)
char vport_buf[25] = "";
char *new_sdp;
int bad = 0;
int skip_video = 0, skip_audio = 0, skip_image = 0;
if (zstr(tech_pvt->local_sdp_str)) {
return;
@@ -1649,14 +1648,6 @@ void sofia_glue_tech_patch_sdp(private_object_t *tech_pvt)
qe = q + len - 1;
if (switch_stristr("m=video 0", p)) {
skip_video = 1;
} else if (switch_stristr("m=audio 0", p)) {
skip_audio = 1;
} else if (switch_stristr("m=image 0", p)) {
skip_image = 1;
}
while (p && *p) {
if (p >= pe) {
bad = 1;
@@ -1748,7 +1739,7 @@ void sofia_glue_tech_patch_sdp(private_object_t *tech_pvt)
}
} else if ((!skip_audio && !strncmp("m=audio ", p, 8)) || (!skip_image && !strncmp("m=image ", p, 8))) {
} else if ((!strncmp("m=audio ", p, 8) && *(p + 9) != '0') || (!strncmp("m=image ", p, 8) && *(p + 9) != '0')) {
strncpy(q, p, 8);
p += 8;
@@ -1784,7 +1775,7 @@ void sofia_glue_tech_patch_sdp(private_object_t *tech_pvt)
has_audio++;
} else if (!skip_video && !strncmp("m=video ", p, 8)) {
} else if (!strncmp("m=video ", p, 8) && *(p + 9) != '0') {
if (!has_video) {
sofia_glue_tech_choose_video_port(tech_pvt, 1);
tech_pvt->video_rm_encoding = "PROXY-VID";
@@ -2066,6 +2057,8 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
char *mp = NULL, *mp_type = NULL;
char *record_route = NULL;
const char *recover_via = NULL;
int require_timer = 1;
if (sofia_test_flag(tech_pvt, TFLAG_RECOVERING)) {
const char *recover_contact = switch_channel_get_variable(tech_pvt->channel, "sip_recover_contact");
@@ -2096,6 +2089,11 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
}
if ((val = switch_channel_get_variable_dup(channel, "sip_require_timer", SWITCH_FALSE, -1)) && switch_false(val)) {
require_timer = 0;
}
cid_name = caller_profile->caller_id_name;
cid_num = caller_profile->caller_id_number;
sofia_glue_tech_prepare_codecs(tech_pvt);
@@ -2355,28 +2353,6 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
switch_channel_set_variable(channel, "sip_to_host", sofia_glue_get_host(to_str, switch_core_session_get_pool(session)));
switch_channel_set_variable(channel, "sip_from_host", sofia_glue_get_host(from_str, switch_core_session_get_pool(session)));
if (!switch_channel_get_variable(channel, "presence_id")) {
char *from = switch_core_session_strdup(session, from_str);
const char *s;
if ((s = switch_stristr("<", from))) {
from = (char *)s + 1;
}
if (!strncasecmp(from, "sip:", 4)) {
from += 4;
}
if (!strncasecmp(from, "sips:", 5)) {
from += 5;
}
if ((p = strchr(from, ':')) || (p = strchr(from, ';')) || (p = strchr(from, '>'))) {
*p++ = '\0';
}
switch_channel_set_variable(channel, "presence_id", from);
}
if (!(tech_pvt->nh = nua_handle(tech_pvt->profile->nua, NULL,
NUTAG_URL(url_str),
@@ -2638,6 +2614,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE)),
TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL)),
TAG_IF(rep, SIPTAG_REPLACES_STR(rep)),
TAG_IF(!require_timer, NUTAG_TIMER_AUTOREQUIRE(0)),
TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_HOLD(holdstr)), TAG_END());
} else {
nua_invite(tech_pvt->nh,
@@ -2663,6 +2640,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
TAG_IF(!zstr(route), SIPTAG_ROUTE_STR(route)),
TAG_IF(!zstr(invite_route_uri), NUTAG_INITIAL_ROUTE_STR(invite_route_uri)),
TAG_IF(tech_pvt->profile->minimum_session_expires, NUTAG_MIN_SE(tech_pvt->profile->minimum_session_expires)),
TAG_IF(!require_timer, NUTAG_TIMER_AUTOREQUIRE(0)),
TAG_IF(cseq, SIPTAG_CSEQ(cseq)),
NUTAG_MEDIA_ENABLE(0),
SIPTAG_CONTENT_TYPE_STR(mp_type ? mp_type : "application/sdp"),
@@ -3153,6 +3131,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
uint32_t rtp_hold_timeout_sec = tech_pvt->profile->rtp_hold_timeout_sec;
char *timer_name = NULL;
const char *var;
uint32_t delay = tech_pvt->profile->rtp_digit_delay;
switch_assert(tech_pvt != NULL);
@@ -3170,10 +3149,6 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
sofia_set_flag_locked(tech_pvt, TFLAG_SECURE);
}
if ((var = switch_channel_get_variable(tech_pvt->channel, "sip_liberal_dtmf")) && switch_true(var)) {
sofia_set_flag_locked(tech_pvt, TFLAG_LIBERAL_DTMF);
}
if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE)) {
status = SWITCH_STATUS_SUCCESS;
goto end;
@@ -3554,6 +3529,20 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
tech_pvt->cng_pt = 0;
}
if (((val = switch_channel_get_variable(tech_pvt->channel, "rtp_digit_delay")))) {
int delayi = atoi(val);
if (delayi < 0) delayi = 0;
delay = (uint32_t) delay;
}
if (delay) {
switch_rtp_set_interdigit_delay(tech_pvt->rtp_session, delay);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG,
"%s Set rtp dtmf delay to %u\n", switch_channel_get_name(tech_pvt->channel), delay);
}
if (tech_pvt->cng_pt && !sofia_test_pflag(tech_pvt->profile, PFLAG_SUPPRESS_CNG)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Set comfort noise payload to %u\n", tech_pvt->cng_pt);
switch_rtp_set_cng_pt(tech_pvt->rtp_session, tech_pvt->cng_pt);
@@ -3892,13 +3881,25 @@ void sofia_glue_set_r_sdp_codec_string(switch_core_session_t *session, const cha
if (zstr(attr->a_name)) {
continue;
}
if (!strcasecmp(attr->a_name, "ptime")) {
dptime = atoi(attr->a_value);
break;
}
}
switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Looking for zrtp-hash to set sdp_zrtp_hash_string\n");
for (m = sdp->sdp_media; m; m = m->m_next) {
for (attr = m->m_attributes; attr; attr = attr->a_next) {
if (zstr(attr->a_name)) continue;
if (!strcasecmp(attr->a_name, "zrtp-hash") && attr->a_value) {
switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Found zrtp-hash, setting sdp_zrtp_hash_string=%s\n", attr->a_value);
switch_channel_set_variable(channel, "sdp_zrtp_hash_string", attr->a_value);
switch_channel_set_flag(channel, CF_ZRTP_HASH);
break;
}
}
}
for (m = sdp->sdp_media; m; m = m->m_next) {
ptime = dptime;
if (m->m_type == sdp_media_image && m->m_port) {
@@ -4490,6 +4491,10 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
}
}
if ((val = switch_channel_get_variable(tech_pvt->channel, "sip_liberal_dtmf")) && switch_true(val)) {
sofia_set_flag_locked(tech_pvt, TFLAG_LIBERAL_DTMF);
}
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")))) {
@@ -4875,12 +4880,12 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
map_bit_rate = switch_known_bitrate((switch_payload_t)map->rm_pt);
if (!ptime && !strcasecmp(map->rm_encoding, "g723")) {
ptime = codec_ms = 30;
codec_ms = 30;
}
if (zstr(map->rm_fmtp)) {
if (!strcasecmp(map->rm_encoding, "ilbc")) {
ptime = codec_ms = 30;
codec_ms = 30;
map_bit_rate = 13330;
}
} else {
@@ -5959,7 +5964,7 @@ void sofia_glue_tech_track(sofia_profile_t *profile, switch_core_session_t *sess
}
if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) {
xml_cdr_text = switch_xml_toxml(cdr, SWITCH_FALSE);
xml_cdr_text = switch_xml_toxml_nolock(cdr, SWITCH_FALSE);
switch_xml_free(cdr);
}
@@ -7030,14 +7035,17 @@ char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, nua
if (contact->m_url->url_params) {
contact_str = switch_mprintf("%s <sip:%s@%s%s%s%s;%s>%s",
contact_str = switch_mprintf("%s <sip:%s%s%s%s%s%s;%s>%s",
display, contact->m_url->url_user,
contact->m_url->url_user ? "@" : "",
ipv6 ? "[" : "",
contact_host, ipv6 ? "]" : "", new_port, contact->m_url->url_params, np->is_nat ? ";fs_nat=yes" : "");
} else {
contact_str = switch_mprintf("%s <sip:%s@%s%s%s%s>%s",
contact_str = switch_mprintf("%s <sip:%s%s%s%s%s%s>%s",
display,
contact->m_url->url_user, ipv6 ? "[" : "", contact_host, ipv6 ? "]" : "", new_port, np->is_nat ? ";fs_nat=yes" : "");
contact->m_url->url_user,
contact->m_url->url_user ? "@" : "",
ipv6 ? "[" : "", contact_host, ipv6 ? "]" : "", new_port, np->is_nat ? ";fs_nat=yes" : "");
}
}
+69 -23
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -24,7 +24,7 @@
* Contributor(s):
*
* Anthony Minessale II <anthm@freeswitch.org>
* Ken Rice, Asteria Solutions Group, Inc <ken@asteriasgi.com>
* Ken Rice <krice@freeswitch.org>
* Paul D. Tinsley <pdt at jackhammer.org>
* Bret McDanel <trixter AT 0xdecafbad.com>
*
@@ -1168,6 +1168,11 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
}
#endif
if (hup && dh.hits > 0) {
goto done;
}
if (zstr(call_id) && (dh.hits && presence_source && (!strcasecmp(presence_source, "register") || switch_stristr("register", status)))) {
goto done;
}
@@ -1284,10 +1289,10 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
}
if (hup) {
if (hup && dh.hits < 1) {
/* so many phones get confused when whe hangup we have to reprobe to get them all to reset to absolute states so the lights stay correct */
switch_event_t *s_event;
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);
@@ -1299,6 +1304,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
}
}
if (!zstr((char *) helper.stream.data)) {
char *this_sql = (char *) helper.stream.data;
char *next = NULL;
@@ -1755,6 +1761,20 @@ static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char *
remote_user = to_user;
remote_host = local_host;
}
else if (proto && !strcasecmp(proto, "pickup")) {
local_user = to_user;
local_user_param = switch_mprintf(";proto=%s", proto);
event_status = "hold";
if (skip_proto) {
buf_to_free = switch_mprintf("sip:%s", to_user);
} else {
buf_to_free = switch_mprintf("sip:pickup+%s", to_user);
}
remote_uri = buf_to_free;
strcpy(remote_display_buf, "pickup");
remote_user = to_user;
remote_host = local_host;
}
else if (proto && !strcasecmp(proto, "conf")) {
local_user = to_user;
local_user_param = switch_mprintf(";proto=%s", proto);
@@ -2545,7 +2565,13 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
}
if (holding) {
astate = "early";
if (profile->pres_held_type == PRES_HELD_CONFIRMED) {
astate = "confirmed";
} else if (profile->pres_held_type == PRES_HELD_TERMINATED) {
astate = "terminated";
} else {
astate = "early";
}
}
@@ -2614,6 +2640,18 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
stream.write_function(&stream, "<target uri=\"sip:park+%s\"/>\n", uuid);
}
stream.write_function(&stream, "</remote>\n");
} else if (!strcasecmp(proto, "pickup")) {
stream.write_function(&stream, "<local>\n<identity display=\"pickup\">sip:%s@%s;proto=pickup</identity>\n",
!zstr(clean_to_user) ? clean_to_user : "unknown", host);
stream.write_function(&stream, "<target uri=\"sip:%s@%s;proto=pickup\">\n", !zstr(clean_to_user) ? clean_to_user : "unknown", host);
stream.write_function(&stream, "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n</target>\n</local>\n");
stream.write_function(&stream, "<remote>\n<identity display=\"pickup\">sip:%s</identity>\n", uuid);
if (skip_proto) {
stream.write_function(&stream, "<target uri=\"sip:%s\"/>\n", uuid);
} else {
stream.write_function(&stream, "<target uri=\"sip:pickup+%s\"/>\n", uuid);
}
stream.write_function(&stream, "</remote>\n");
} else if (!strcasecmp(proto, "conf")) {
stream.write_function(&stream, "<local>\n<identity display=\"conference\">sip:%s@%s;proto=conference</identity>\n",
!zstr(clean_to_user) ? clean_to_user : "unknown", host);
@@ -2647,7 +2685,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
if (!zstr(astate) && !zstr(uuid) &&
helper && helper->stream.data && strcmp(helper->last_uuid, uuid) && strcasecmp(astate, "terminated") && strchr(uuid, '-')) {
helper->stream.write_function(&helper->stream, "update sip_dialogs set state='%s' where hostname='%q' and profile_name='%q' and uuid='%s';",
mod_sofia_globals.hostname, profile->name, astate, uuid);
astate, mod_sofia_globals.hostname, profile->name, uuid);
switch_copy_string(helper->last_uuid, uuid, sizeof(helper->last_uuid));
}
@@ -2703,9 +2741,9 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
rpid = "on-the-phone";
force_status = 1;
} else if (!strcmp(astate, "terminated") || !strcmp(astate, "hangup")) {
rpid = "online";
dialog_rpid = "";
force_event_status = "Available";
//rpid = "online";
//dialog_rpid = "";
//force_event_status = "Available";
term = 1;
}
@@ -2778,8 +2816,8 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
if (!zstr(uuid) && strchr(uuid, '-') && !zstr(status_line) && !zstr(rpid) && (zstr(register_source) || strcasecmp(register_source, "register"))) {
char *sql = switch_mprintf("update sip_dialogs set rpid='%q',status='%q' where hostname='%q' and profile_name='%q' and uuid='%q'",
mod_sofia_globals.hostname, profile->name,
rpid, status_line, uuid);
rpid, status_line,
mod_sofia_globals.hostname, profile->name, uuid);
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
}
}
@@ -3588,8 +3626,8 @@ void sofia_presence_handle_sip_i_subscribe(int status,
" from sip_subscriptions where hostname='%q' and profile_name='%q' and "
"event='message-summary' and sip_user='%q' "
"and (sip_host='%q' or presence_hosts like '%%%q%%')",
mod_sofia_globals.hostname, profile->name,
to_host, to_user, to_host, to_host))) {
to_host, mod_sofia_globals.hostname, profile->name,
to_user, to_host, to_host))) {
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_sub_reg_callback, profile);
switch_safe_free(sql);
@@ -3880,16 +3918,24 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
open_closed = basic->txt;
}
if ((person = switch_xml_child(xml, "dm:person")) && (note = switch_xml_child(person, "dm:note"))) {
note_txt = note->txt;
if ((person = switch_xml_child(xml, "dm:person"))) {
if ((note = switch_xml_child(person, "dm:note"))) {
note_txt = note->txt;
} else if ((note = switch_xml_child(person, "rpid:note"))) {
note_txt = note->txt;
}
if ((act = switch_xml_child(person, "rpid:activities")) && act->child && act->child->name) {
if ((rpid = strchr(act->child->name, ':'))) {
rpid++;
} else {
rpid = act->child->name;
}
}
if (zstr(note_txt)) note_txt = rpid;
}
if (person && (act = switch_xml_child(person, "rpid:activities")) && act->child && act->child->name) {
if ((rpid = strchr(act->child->name, ':'))) {
rpid++;
} else {
rpid = act->child->name;
}
if (!strcasecmp(open_closed, "closed")) {
rpid = note_txt = "Unregistered";
}
if (sofia_test_pflag(profile, PFLAG_MULTIREG) && !open) {
@@ -3901,7 +3947,7 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
event_type = sip_header_as_string(nh->nh_home, (void *) sip->sip_event);
if (count < 2) {
if (count != 1) {
if ((sql = switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' "
" and profile_name='%q' and hostname='%q'",
from_user, from_host, profile->name, mod_sofia_globals.hostname))) {
@@ -3928,7 +3974,7 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
switch_str_nil(payload->pl_data),
mod_sofia_globals.hostname, profile->name,
from_user, from_host, event_type);
from_user, from_host, event_type, contact_str);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_send_sql, &cb);
switch_safe_free(sql);
+34 -11
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -127,22 +127,20 @@ static void sofia_reg_kill_sub(sofia_gateway_t *gateway_ptr)
static void sofia_reg_kill_reg(sofia_gateway_t *gateway_ptr)
{
if (gateway_ptr->nh) {
nua_handle_bind(gateway_ptr->nh, NULL);
}
if (gateway_ptr->state != REG_STATE_REGED && gateway_ptr->state != REG_STATE_UNREGISTER) {
if (gateway_ptr->nh) {
nua_handle_destroy(gateway_ptr->nh);
gateway_ptr->nh = NULL;
}
if (!gateway_ptr->nh) {
return;
}
if (gateway_ptr->nh) {
if (gateway_ptr->state == REG_STATE_REGED || gateway_ptr->state == REG_STATE_UNREGISTER) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "UN-Registering %s\n", gateway_ptr->name);
nua_unregister(gateway_ptr->nh, NUTAG_URL(gateway_ptr->register_url), NUTAG_REGISTRAR(gateway_ptr->register_proxy), TAG_END());
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Destroying registration handle for %s\n", gateway_ptr->name);
}
nua_handle_bind(gateway_ptr->nh, NULL);
nua_handle_destroy(gateway_ptr->nh);
gateway_ptr->nh = NULL;
}
void sofia_reg_fire_custom_gateway_state_event(sofia_gateway_t *gateway, int status, const char *phrase)
@@ -1243,6 +1241,20 @@ 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, "username", username);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "realm", realm);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "user-agent", agent);
switch (auth_res) {
case AUTH_OK:
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "auth-result", "SUCCESS");
break;
case AUTH_RENEWED:
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "auth-result", "RENEWED");
break;
case AUTH_STALE:
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "auth-result", "STALE");
break;
case AUTH_FORBIDDEN:
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "auth-result", "FORBIDDEN");
break;
}
switch_event_fire(&s_event);
}
@@ -1380,6 +1392,17 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
(regtype == REG_INVITE) ? "INVITE" : "REGISTER", profile->name, to_user, to_host, network_ip);
}
if (forbidden && switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REGISTER_FAILURE) == 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, "to-user", to_user);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-host", to_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "network-ip", network_ip);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "user-agent", agent);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "network-port", network_port_c);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "registration-type", (regtype == REG_INVITE) ? "INVITE" : "REGISTER");
switch_event_fire(&s_event);
}
switch_goto_int(r, 1, end);
}
}