* @param pool The pool to tag
* @param tag The tag
*/
-APR_DECLARE(void) apr_pool_tag(apr_pool_t *pool, const char *tag);
+APR_DECLARE(char *) apr_pool_tag(apr_pool_t *pool, const char *tag);
#if APR_HAS_THREADS
/**
return 0;
}
-APR_DECLARE(void) apr_pool_tag(apr_pool_t *pool, const char *tag)
+APR_DECLARE(char *) apr_pool_tag(apr_pool_t *pool, const char *tag)
{
- pool->tag = tag;
+ if (tag) {
+ pool->tag = tag;
+ }
+
+ return pool->tag;
}
SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS,
SWITCH_MESSAGE_INDICATE_JITTER_BUFFER,
SWITCH_MESSAGE_INDICATE_RECOVERY_REFRESH,
+ SWITCH_MESSAGE_INDICATE_SIGNAL_DATA,
SWITCH_MESSAGE_INVALID
} switch_core_session_message_types_t;
private_object_t *tech_pvt = switch_core_session_get_private(session);
switch_status_t status = SWITCH_STATUS_SUCCESS;
+ 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);
+ sofia_process_dispatch_event(&de);
+ switch_mutex_unlock(tech_pvt->sofia_mutex);
+ goto end;
+ }
+
+
if (switch_channel_down(channel) || !tech_pvt || sofia_test_flag(tech_pvt, TFLAG_BYE)) {
status = SWITCH_STATUS_FALSE;
goto end;
to_host = switch_channel_get_variable(channel, "sip_to_host");
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Challenging call %s\n", to_uri);
- sofia_reg_auth_challenge(NULL, tech_pvt->profile, tech_pvt->nh, REG_INVITE, to_host, 0);
+ sofia_reg_auth_challenge(NULL, tech_pvt->profile, tech_pvt->nh, NULL, REG_INVITE, to_host, 0);
switch_channel_hangup(channel, SWITCH_CAUSE_USER_CHALLENGE);
} else if (code == 484 && msg->numeric_arg) {
const char *to = switch_channel_get_variable(channel, "sip_to_uri");
nua_notify(nh,
NUTAG_NEWSUB(1),
- NUTAG_WITH_THIS(profile->nua),
TAG_IF(dst->route_uri, NUTAG_PROXY(dst->contact)), 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());
}
nua_info(nh,
- NUTAG_WITH_THIS(profile->nua),
TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(ct)),
TAG_IF(cd, SIPTAG_CONTENT_DISPOSITION_STR(cd)),
TAG_IF(alert_info, SIPTAG_ALERT_INFO_STR(alert_info)),
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown)
{
int sanity = 0;
+ int i;
+
switch_console_del_complete_func("::sofia::list_profiles");
switch_console_set_complete("del sofia");
switch_mutex_lock(mod_sofia_globals.mutex);
+
+ for (i = 0; i < mod_sofia_globals.msg_queue_len; i++) {
+ switch_queue_push(mod_sofia_globals.msg_queue[i], NULL);
+ }
+
if (mod_sofia_globals.running == 1) {
mod_sofia_globals.running = 0;
}
}
}
+ for (i = 0; i < mod_sofia_globals.msg_queue_len; i++) {
+ switch_status_t st;
+ switch_thread_join(&st, mod_sofia_globals.msg_queue_thread[i]);
+ }
+
//switch_yield(1000000);
su_deinit();
DTMF_NONE
} sofia_dtmf_t;
+typedef struct sofia_dispatch_event_s {
+ nua_saved_event_t event[1];
+ nua_handle_t *nh;
+ nua_event_data_t const *data;
+ su_time_t when;
+ sip_t *sip;
+ nua_t *nua;
+ sofia_profile_t *profile;
+} sofia_dispatch_event_t;
+
struct sofia_private {
char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1];
sofia_gateway_t *gateway;
int destroy_me;
int is_call;
int is_static;
+ sofia_dispatch_event_t *de;
};
#define set_param(ptr,val) if (ptr) {free(ptr) ; ptr = NULL;} if (val) {ptr = strdup(val);}
#define set_anchor(t,m) if (t->Anchor) {delete t->Anchor;} t->Anchor = new SipMessage(m);
-#define sofia_private_free(_pvt) if (_pvt && ! _pvt->is_static) {free(_pvt); _pvt = NULL;}
+//#define sofia_private_free(_pvt) if (_pvt && ! _pvt->is_static) {free(_pvt); _pvt = NULL;}
+#define sofia_private_free(_pvt) _pvt = NULL
/* Local Structures */
/*************************************************************************************************************************************************************/
TFLAG_MAX
} TFLAGS;
+#define SOFIA_MAX_MSG_QUEUE 25
+#define SOFIA_MSG_QUEUE_SIZE 10
+
struct mod_sofia_globals {
switch_memory_pool_t *pool;
switch_hash_t *profile_hash;
char hostname[512];
switch_queue_t *presence_queue;
switch_queue_t *mwi_queue;
+ switch_queue_t *msg_queue[SOFIA_MAX_MSG_QUEUE];
+ switch_thread_t *msg_queue_thread[SOFIA_MAX_MSG_QUEUE];
+ int msg_queue_len;
struct sofia_private destroy_private;
struct sofia_private keep_private;
switch_event_node_t *in_node;
switch_mutex_t *ireg_mutex;
switch_mutex_t *gateway_mutex;
sofia_gateway_t *gateways;
- su_home_t *home;
+ //su_home_t *home;
switch_hash_t *chat_hash;
//switch_core_db_t *master_db;
switch_thread_rwlock_t *rwlock;
} sofia_nat_parse_t;
+#define NUTAG_WITH_THIS_MSG(msg) nutag_with, tag_ptr_v(msg)
+
#define sofia_test_pflag(obj, flag) ((obj)->pflags[flag] ? 1 : 0)
#define sofia_set_pflag(obj, flag) (obj)->pflags[flag] = 1
#define sofia_set_pflag_locked(obj, flag) assert(obj->flag_mutex != NULL);\
void sofia_presence_establish_presence(sofia_profile_t *profile);
-void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[]);
+void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[]);
-void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[]);
+void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[]);
-void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
+void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[]);
void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[]);
void sofia_event_callback(nua_event_t event,
int status,
char const *phrase,
- nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
+ nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ tagi_t tags[]);
void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void *obj);
void sofia_glue_track_event_handler(switch_event_t *event);
void sofia_presence_cancel(void);
switch_status_t config_sofia(int reload, char *profile_name);
-void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_regtype_t regtype, const char *realm, int stale);
+void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_dispatch_event_t *de,
+ sofia_regtype_t regtype, const char *realm, int stale);
auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t const *authorization,
- sip_t const *sip, const char *regstr, char *np, size_t nplen, char *ip, switch_event_t **v_event,
+ sip_t const *sip,
+ sofia_dispatch_event_t *de, const char *regstr, char *np, size_t nplen, char *ip, switch_event_t **v_event,
long exptime, sofia_regtype_t regtype, const char *to_user, switch_event_t **auth_params, long *reg_count);
char const *phrase,
nua_t *nua, sofia_profile_t *profile,
nua_handle_t *nh, sofia_private_t *sofia_private,
- switch_core_session_t *session, sofia_gateway_t *gateway, sip_t const *sip, tagi_t tags[]);
+ switch_core_session_t *session, sofia_gateway_t *gateway, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[]);
void sofia_reg_handle_sip_r_register(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[]);
void sofia_handle_sip_i_options(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private,
- sip_t const *sip, tagi_t tags[]);
+ sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[]);
void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[]);
void sofia_presence_handle_sip_i_message(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh,
- sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
+ sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[]);
void sofia_presence_handle_sip_r_subscribe(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh,
- sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
+ sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[]);
void sofia_presence_handle_sip_i_subscribe(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh,
- sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
+ sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[]);
void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic);
void sofia_glue_actually_execute_sql(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex);
switch_call_cause_t sofia_glue_sip_cause_to_freeswitch(int status);
void sofia_glue_do_xfer_invite(switch_core_session_t *session);
uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip,
+ sofia_dispatch_event_t *de,
sofia_regtype_t regtype, char *key, uint32_t keylen, switch_event_t **v_event, const char *is_nat);
extern switch_endpoint_interface_t *sofia_endpoint_interface;
void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip);
* SLA (shared line appearance) entrypoints
*/
-void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const *sip, long exptime, const char *full_contact);
-void sofia_sla_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]);
-void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]);
+void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const *sip,
+ sofia_dispatch_event_t *de, long exptime, const char *full_contact);
+void sofia_sla_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[]);
+void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[]);
void sofia_sla_handle_sip_r_subscribe(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[]);
-void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]);
+void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[]);
/*
* Logging control functions
void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl);
void sofia_glue_check_dtmf_type(private_object_t *tech_pvt);
void sofia_glue_parse_rtp_bugs(switch_rtp_bug_flag_t *flag_pole, const char *str);
-char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_nat_parse_t *np);
+char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_dispatch_event_t *de, sofia_nat_parse_t *np);
void sofia_glue_pause_jitterbuffer(switch_core_session_t *session, switch_bool_t on);
+void sofia_process_dispatch_event(sofia_dispatch_event_t **dep);
+
void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[]);
static void set_variable_sip_param(switch_channel_t *channel, char *header_type, sip_param_t const *params);
static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[]);
static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[]);
static void sofia_handle_sip_r_options(switch_core_session_t *session, int status, char const *phrase, nua_t *nua, sofia_profile_t *profile,
- nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
+ nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[]);
void sofia_handle_sip_r_notify(switch_core_session_t *session, int status,
char const *phrase,
- nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
+ nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[])
{
if (status >= 300 && sip && sip->sip_call_id) {
return r;
}
-static void extract_header_vars(sofia_profile_t *profile, sip_t const *sip, switch_core_session_t *session)
+static void extract_header_vars(sofia_profile_t *profile, sip_t const *sip,
+ switch_core_session_t *session, nua_handle_t *nh)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
char *full;
if (sip) {
if (sip->sip_route) {
- if ((full = sip_header_as_string(profile->home, (void *) sip->sip_route))) {
+ if ((full = sip_header_as_string(nh->nh_home, (void *) sip->sip_route))) {
const char *v = switch_channel_get_variable(channel, "sip_full_route");
if (!v) {
switch_channel_set_variable(channel, "sip_full_route", full);
}
- su_free(profile->home, full);
+ su_free(nh->nh_home, full);
}
}
if (sip->sip_via) {
- if ((full = sip_header_as_string(profile->home, (void *) sip->sip_via))) {
+ if ((full = sip_header_as_string(nh->nh_home, (void *) sip->sip_via))) {
const char *v = switch_channel_get_variable(channel, "sip_full_via");
if (!v) {
switch_channel_set_variable(channel, "sip_full_via", full);
}
- su_free(profile->home, full);
+ su_free(nh->nh_home, full);
}
}
if (sip->sip_from) {
switch_channel_set_variable(channel, "sip_from_display", p);
}
if (p != sip->sip_from->a_display) free(p);
- if ((full = sip_header_as_string(profile->home, (void *) sip->sip_from))) {
+ if ((full = sip_header_as_string(nh->nh_home, (void *) sip->sip_from))) {
switch_channel_set_variable(channel, "sip_full_from", full);
- su_free(profile->home, full);
+ su_free(nh->nh_home, full);
}
}
if (sip->sip_to) {
if (p != sip->sip_to->a_display) free(p);
- if ((full = sip_header_as_string(profile->home, (void *) sip->sip_to))) {
+ if ((full = sip_header_as_string(nh->nh_home, (void *) sip->sip_to))) {
switch_channel_set_variable(channel, "sip_full_to", full);
- su_free(profile->home, full);
+ su_free(nh->nh_home, full);
}
}
}
}
-static void extract_vars(sofia_profile_t *profile, sip_t const *sip, switch_core_session_t *session)
+static void extract_vars(sofia_profile_t *profile, sip_t const *sip,
+ switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
char const *phrase,
- nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
+ nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[])
{
switch_channel_t *channel = NULL;
private_object_t *tech_pvt = NULL;
if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
if (sip->sip_request->rq_url->url_user && !strncmp(sip->sip_request->rq_url->url_user, "sla-agent", sizeof("sla-agent"))) {
- sofia_sla_handle_sip_i_notify(nua, profile, nh, sip, tags);
+ sofia_sla_handle_sip_i_notify(nua, profile, nh, sip, de, tags);
goto end;
}
}
/* Automatically return a 200 OK for Event: keep-alive */
if (!strcasecmp(sip->sip_event->o_type, "keep-alive")) {
/* XXX MTK - is this right? in this case isn't sofia is already sending a 200 itself also? */
- nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
goto end;
}
}
}
}
- nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
}
/* if no session, assume it could be an incoming notify from a gateway subscription */
switch_channel_answer(channel);
switch_channel_set_variable(channel, "auto_answer_destination", switch_channel_get_variable(channel, "destination_number"));
switch_ivr_session_transfer(session, "auto_answer", NULL, NULL);
- nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
goto end;
}
}
if (sip && sip->sip_event && sip->sip_event->o_type && !strcasecmp(sip->sip_event->o_type, "message-summary")) {
/* unsolicited mwi, just say ok */
- nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
if (sofia_test_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY)) {
const char *mwi_status = NULL;
if (sip->sip_to && sip->sip_to->a_url && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host
&& sip->sip_payload && sip->sip_payload->pl_data ) {
- sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), NULL);
+ sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), NULL);
for (x = 0; x < profile->acl_count; x++) {
last_acl = profile->acl[x];
if (!(acl_ok = switch_check_network_list_ip(network_ip, last_acl))) {
}
} else {
- nua_respond(nh, 481, "Subscription Does Not Exist", NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, 481, "Subscription Does Not Exist", NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
}
end:
void sofia_handle_sip_i_bye(switch_core_session_t *session, int status,
char const *phrase,
- nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
+ nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[])
{
const char *tmp;
switch_channel_t *channel;
sofia_glue_set_extra_headers(channel, sip, SOFIA_SIP_BYE_HEADER_PREFIX);
switch_channel_hangup(channel, cause);
- nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua),
+ 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());
switch_safe_free(extra_headers);
}
}
-void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip, switch_bool_t send)
+void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip,
+ switch_bool_t send)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
sip_p_asserted_identity_t *passerted = NULL;
switch_safe_free(dup);
}
-
-void sofia_event_callback(nua_event_t event,
+//sofia_dispatch_event_t *de
+static void our_sofia_event_callback(nua_event_t event,
int status,
char const *phrase,
- nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
+ nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[])
{
struct private_object *tech_pvt = NULL;
auth_res_t auth_res = AUTH_FORBIDDEN;
int locked = 0;
int check_destroy = 1;
+
+ if (sofia_private && sofia_private->de) {
+ sofia_dispatch_event_t *qde = sofia_private->de;
+ sofia_private->de = NULL;
+ sofia_process_dispatch_event(&qde);
+ }
+
profile->last_sip_event = switch_time_now();
/* sofia_private will be == &mod_sofia_globals.keep_private whenever a request is done with a new handle that has to be
if (authorization) {
char network_ip[80];
- sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), NULL);
- auth_res = sofia_reg_parse_auth(profile, authorization, sip,
+ sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), NULL);
+ auth_res = sofia_reg_parse_auth(profile, authorization, sip, de,
(char *) sip->sip_request->rq_method_name, tech_pvt->key, strlen(tech_pvt->key), network_ip, NULL, 0,
REG_INVITE, NULL, NULL, NULL);
}
}
if (sip && (status == 401 || status == 407)) {
- sofia_reg_handle_sip_r_challenge(status, phrase, nua, profile, nh, sofia_private, session, gateway, sip, tags);
+ sofia_reg_handle_sip_r_challenge(status, phrase, nua, profile, nh, sofia_private, session, gateway, sip, de, tags);
goto done;
}
switch_channel_set_variable(channel, "sip_call_id", sip->sip_call_id->i_id);
}
- extract_header_vars(profile, sip, session);
+ extract_header_vars(profile, sip, session, nh);
sofia_glue_tech_track(tech_pvt->profile, session);
}
}
sofia_handle_sip_r_message(status, profile, nh, sip);
break;
case nua_r_invite:
- sofia_handle_sip_r_invite(session, status, phrase, nua, profile, nh, sofia_private, sip, tags);
+ sofia_handle_sip_r_invite(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
break;
case nua_r_options:
- sofia_handle_sip_r_options(session, status, phrase, nua, profile, nh, sofia_private, sip, tags);
+ sofia_handle_sip_r_options(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
break;
case nua_i_bye:
- sofia_handle_sip_i_bye(session, status, phrase, nua, profile, nh, sofia_private, sip, tags);
+ sofia_handle_sip_i_bye(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
break;
case nua_r_notify:
- sofia_handle_sip_r_notify(session, status, phrase, nua, profile, nh, sofia_private, sip, tags);
+ sofia_handle_sip_r_notify(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
break;
case nua_i_notify:
- sofia_handle_sip_i_notify(session, status, phrase, nua, profile, nh, sofia_private, sip, tags);
+ sofia_handle_sip_i_notify(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
break;
case nua_r_register:
- sofia_reg_handle_sip_r_register(status, phrase, nua, profile, nh, sofia_private, sip, tags);
+ sofia_reg_handle_sip_r_register(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
break;
case nua_i_options:
- sofia_handle_sip_i_options(status, phrase, nua, profile, nh, sofia_private, sip, tags);
+ sofia_handle_sip_i_options(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
break;
case nua_i_invite:
if (session) {
- sofia_handle_sip_i_reinvite(session, nua, profile, nh, sofia_private, sip, tags);
+ sofia_handle_sip_i_reinvite(session, nua, profile, nh, sofia_private, sip, de, tags);
} else {
- sofia_handle_sip_i_invite(nua, profile, nh, sofia_private, sip, tags);
+ sofia_handle_sip_i_invite(nua, profile, nh, sofia_private, sip, de, tags);
}
break;
case nua_i_publish:
- sofia_presence_handle_sip_i_publish(nua, profile, nh, sofia_private, sip, tags);
+ sofia_presence_handle_sip_i_publish(nua, profile, nh, sofia_private, sip, de, tags);
break;
case nua_i_register:
- //nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(sip->sip_contact), NUTAG_WITH_THIS(nua), TAG_END());
+ //nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(sip->sip_contact), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
//nua_handle_destroy(nh);
- sofia_reg_handle_sip_i_register(nua, profile, nh, sofia_private, sip, tags);
+ sofia_reg_handle_sip_i_register(nua, profile, nh, sofia_private, sip, de, tags);
break;
case nua_i_state:
- sofia_handle_sip_i_state(session, status, phrase, nua, profile, nh, sofia_private, sip, tags);
+ sofia_handle_sip_i_state(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
break;
case nua_i_message:
- sofia_presence_handle_sip_i_message(status, phrase, nua, profile, nh, sofia_private, sip, tags);
+ sofia_presence_handle_sip_i_message(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
break;
case nua_i_info:
- sofia_handle_sip_i_info(nua, profile, nh, session, sip, tags);
+ sofia_handle_sip_i_info(nua, profile, nh, session, sip, de, tags);
break;
case nua_i_update:
break;
break;
case nua_i_refer:
if (session)
- sofia_handle_sip_i_refer(nua, profile, nh, session, sip, tags);
+ sofia_handle_sip_i_refer(nua, profile, nh, session, sip, de, tags);
break;
case nua_r_subscribe:
- sofia_presence_handle_sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
+ sofia_presence_handle_sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
break;
case nua_i_subscribe:
- sofia_presence_handle_sip_i_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
+ sofia_presence_handle_sip_i_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
break;
case nua_r_authenticate:
}
sofia_private->destroy_me = 12;
sofia_private_free(sofia_private);
+
}
if (gateway) {
}
}
+void sofia_process_dispatch_event(sofia_dispatch_event_t **dep)
+{
+ sofia_dispatch_event_t *de = *dep;
+ *dep = NULL;
+
+ our_sofia_event_callback(de->data->e_event, de->data->e_status, de->data->e_phrase, de->nua, de->profile,
+ de->nh, nua_handle_magic(de->nh), de->sip, de, (tagi_t *) de->data->e_tags);
+ nua_handle_unref(de->nh);
+ nua_stack_unref(de->nua);
+ nua_destroy_event(de->event);
+ free(de);
+}
+
+
+void *SWITCH_THREAD_FUNC sofia_msg_thread_run(switch_thread_t *thread, void *obj)
+{
+ void *pop;
+ switch_queue_t *q = (switch_queue_t *) obj;
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "MSG Thread Started\n");
+
+ while (mod_sofia_globals.running == 1) {
+
+ if (switch_queue_pop(q, &pop) == SWITCH_STATUS_SUCCESS) {
+ sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) pop;
+
+ if (!pop) {
+ break;
+ }
+
+ sofia_process_dispatch_event(&de);
+ }
+ }
+
+ while (switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
+ sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) pop;
+ nua_handle_unref(de->nh);
+ nua_destroy_event(de->event);
+ free(de);
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "MSG Thread Ended\n");
+
+ return NULL;
+}
+
+static int IDX = 0;
+
+static 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])) {
+ return;
+ }
+
+ switch_mutex_lock(mod_sofia_globals.mutex);
+
+ if (idx >= mod_sofia_globals.msg_queue_len) {
+ int i;
+ mod_sofia_globals.msg_queue_len = idx + 1;
+
+ for (i = 0; i < mod_sofia_globals.msg_queue_len; i++) {
+ if (!mod_sofia_globals.msg_queue[i]) {
+ switch_threadattr_t *thd_attr = NULL;
+
+ switch_queue_create(&mod_sofia_globals.msg_queue[i], SOFIA_MSG_QUEUE_SIZE, mod_sofia_globals.pool);
+
+ 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_thread_create(&mod_sofia_globals.msg_queue_thread[i],
+ thd_attr,
+ sofia_msg_thread_run,
+ mod_sofia_globals.msg_queue[i],
+ mod_sofia_globals.pool);
+ }
+ }
+ }
+
+ switch_mutex_unlock(mod_sofia_globals.mutex);
+}
+
+
+static void sofia_queue_message(sofia_dispatch_event_t *de)
+{
+ int idx = 0;
+
+ 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);
+ }
+ }
+}
+
+
+void sofia_event_callback(nua_event_t event,
+ int status,
+ char const *phrase,
+ nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ tagi_t tags[])
+{
+ sofia_dispatch_event_t *de;
+
+ de = calloc(1, sizeof *de);
+ nua_save_event(nua, de->event);
+ de->nh = nua_handle_ref(nh);
+ de->data = nua_event_data(de->event);
+ de->sip = sip_object(de->data->e_msg);
+ de->profile = profile;
+ de->nua = nua_stack_ref(nua);
+
+ if (event == nua_i_invite && !sofia_private) {
+ if (!(sofia_private = su_alloc(nh->nh_home, sizeof(*sofia_private)))) {
+ abort();
+ }
+
+ memset(sofia_private, 0, sizeof(*sofia_private));
+ sofia_private->is_call++;
+ sofia_private->de = de;
+ nua_handle_bind(nh, sofia_private);
+ return;
+ }
+
+ if (sofia_private && sofia_private != &mod_sofia_globals.destroy_private && sofia_private != &mod_sofia_globals.keep_private) {
+ switch_core_session_message_t *msg;
+ switch_core_session_t *session;
+
+ if (!zstr(sofia_private->uuid)) {
+ if ((session = switch_core_session_locate(sofia_private->uuid))) {
+ msg = switch_core_session_alloc(session, sizeof(*msg));
+ msg->message_id = SWITCH_MESSAGE_INDICATE_SIGNAL_DATA;
+ msg->from = __FILE__;
+ msg->numeric_arg = status;
+ msg->pointer_arg = de;
+
+ if (switch_core_session_running(session)) {
+ switch_core_session_queue_message(session, msg);
+ } else {
+ switch_core_session_receive_message(session, msg);
+ }
+ switch_core_session_rwunlock(session);
+ return;
+ }
+ }
+ }
+
+ sofia_queue_message(de);
+}
+
+
void event_handler(switch_event_t *event)
{
char *subclass, *sql;
switch_mutex_unlock(mod_sofia_globals.mutex);
profile->s_root = su_root_create(NULL);
- profile->home = su_home_new(sizeof(*profile->home));
+ //profile->home = su_home_new(sizeof(*profile->home));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Creating agent for %s\n", profile->name);
}
}
- su_home_unref(profile->home);
+ //su_home_unref(profile->home);
su_root_destroy(profile->s_root);
//pool = profile->pool;
} else {
sofia_clear_pflag(profile, PFLAG_CID_IN_1XX);
}
+ } else if (!strcasecmp(var, "message-threads")) {
+ int num = atoi(val);
+
+ if (num < 1 || num >= SOFIA_MAX_MSG_QUEUE) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "message-threads must be between 1 and %d", SOFIA_MAX_MSG_QUEUE);
+ } else {
+ sofia_msg_thread_start(num);
+ }
+
} else if (!strcasecmp(var, "disable-hold")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_DISABLE_HOLD);
static void sofia_handle_sip_r_options(switch_core_session_t *session, int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[])
{
sofia_gateway_t *gateway = NULL;
static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[])
{
char *call_info = NULL;
switch_caller_profile_t *caller_profile = NULL;
int has_t38 = 0;
- sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
+ sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
switch_channel_set_variable_printf(channel, "sip_local_network_addr", "%s", profile->extsipip ? profile->extsipip : profile->sipip);
switch_channel_set_variable(channel, "sip_reply_host", network_ip);
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
}
- extract_header_vars(profile, sip, session);
+ extract_header_vars(profile, sip, session, nh);
extract_vars(profile, sip, session);
sofia_glue_tech_track(tech_pvt->profile, session);
sofia_clear_flag(tech_pvt, TFLAG_RECOVERING);
static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[])
{
const char *l_sdp = NULL, *r_sdp = NULL;
tech_pvt->sofia_private = NULL;
}
+ nua_handle_unref(tech_pvt->nh);
tech_pvt->nh = NULL;
if (nh) {
}
-void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[])
+void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[])
{
/* Incoming refer */
sip_from_t const *from;
switch_memory_pool_t *npool;
if (!(profile->mflags & MFLAG_REFER)) {
- nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
goto done;
}
home = su_home_new(sizeof(*home));
switch_assert(home != NULL);
- nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS(nua), SIPTAG_EXPIRES_STR("60"), TAG_END());
+ nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_EXPIRES_STR("60"), TAG_END());
if (sip->sip_referred_by) {
full_ref_by = sip_header_as_string(home, (void *) sip->sip_referred_by);
}
-static switch_status_t create_info_event(sip_t const *sip, nua_handle_t *nh, switch_event_t **revent)
+static switch_status_t create_info_event(sip_t const *sip,
+ nua_handle_t *nh, switch_event_t **revent)
{
sip_alert_info_t *alert_info = sip_alert_info(sip);
switch_event_t *event;
return SWITCH_STATUS_SUCCESS;
}
-void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[])
+void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[])
{
/* placeholder for string searching */
const char *signal_ptr;
if (switch_core_session_queue_event(session, &event) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "queued freeswitch event for INFO\n");
nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response"),
- SIPTAG_PAYLOAD_STR("+OK MESSAGE QUEUED"), NUTAG_WITH_THIS(nua), TAG_END());
+ SIPTAG_PAYLOAD_STR("+OK MESSAGE QUEUED"), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
} else {
switch_event_destroy(&event);
nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response"),
- SIPTAG_PAYLOAD_STR("-ERR MESSAGE NOT QUEUED"), NUTAG_WITH_THIS(nua), TAG_END());
+ SIPTAG_PAYLOAD_STR("-ERR MESSAGE NOT QUEUED"), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
}
}
} else {
nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response"),
- SIPTAG_PAYLOAD_STR("-ERR INVALID SESSION"), NUTAG_WITH_THIS(nua), TAG_END());
+ SIPTAG_PAYLOAD_STR("-ERR INVALID SESSION"), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
}
if ((status = switch_api_execute(cmd, arg, NULL, &stream)) == SWITCH_STATUS_SUCCESS) {
nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/api-response"),
- SIPTAG_PAYLOAD_STR(stream.data), NUTAG_WITH_THIS(nua), TAG_END());
+ SIPTAG_PAYLOAD_STR(stream.data), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
} else {
nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/api-response"),
- SIPTAG_PAYLOAD_STR("-ERR INVALID COMMAND"), NUTAG_WITH_THIS(nua), TAG_END());
+ SIPTAG_PAYLOAD_STR("-ERR INVALID COMMAND"), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
}
switch_safe_free(stream.data);
return;
}
- nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
return;
}
}
/* Send 200 OK response */
- nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END());
+ 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);
if (!zstr(clientcode_header)) {
switch_channel_set_variable(channel, "call_clientcode", clientcode_header);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Setting CMC to %s\n", clientcode_header);
- nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
}
goto end;
}
if ((rec_header = sofia_glue_get_unknown_header(sip, "record"))) {
if (zstr(profile->record_template)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Record attempted but no template defined.\n");
- nua_respond(nh, 488, "Recording not enabled", NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, 488, "Recording not enabled", NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
} else {
if (!strcasecmp(rec_header, "on")) {
char *file = NULL, *tmp = NULL;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Recording %s to %s\n", switch_channel_get_name(channel),
file);
switch_safe_free(tmp);
- nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
if (file != profile->record_template) {
free(file);
file = NULL;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Done recording %s to %s\n",
switch_channel_get_name(channel), file);
switch_ivr_stop_record_session(session, file);
- nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
} else {
- nua_respond(nh, 488, "Nothing to stop", NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, 488, "Nothing to stop", NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
}
}
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "dispatched freeswitch event for INFO\n");
}
- nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
return;
void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[])
{
char *call_info = NULL;
char via_space[2048];
char branch[16] = "";
- sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
+ sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
switch_stun_random_string(branch, sizeof(branch) - 1, "0123456789abcdef");
switch_snprintf(via_space, sizeof(via_space), "SIP/2.0/UDP %s;rport=%d;branch=%s", network_ip, network_port, branch);
}
}
-void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
+void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[])
{
switch_core_session_t *session = NULL;
char key[128] = "";
goto fail;
}
- sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
+ sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
if (sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)) {
if (sip && sip->sip_via) {
if (!strcmp(network_ip, profile->sipip) && network_port == profile->sip_port) {
calling_myself++;
} else {
- if (sofia_reg_handle_register(nua, profile, nh, sip, REG_INVITE, key, sizeof(key), &v_event, NULL)) {
+ if (sofia_reg_handle_register(nua, profile, nh, sip, de, REG_INVITE, key, sizeof(key), &v_event, NULL)) {
if (v_event) {
switch_event_destroy(&v_event);
}
check_decode(from_user, session);
}
- extract_header_vars(profile, sip, session);
+ extract_header_vars(profile, sip, session, nh);
if (sip->sip_request->rq_url) {
const char *req_uri = url_set_chanvars(session, sip->sip_request->rq_url, sip_req);
}
if ((alert_info = sip_alert_info(sip))) {
- char *tmp = sip_header_as_string(profile->home, (void *) alert_info);
+ char *tmp = sip_header_as_string(nh->nh_home, (void *) alert_info);
switch_channel_set_variable(channel, "alert_info", tmp);
- su_free(profile->home, tmp);
+ su_free(nh->nh_home, tmp);
}
if ((call_info = sip_call_info(sip))) {
switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
}
- if (!(sofia_private = malloc(sizeof(*sofia_private)))) {
- abort();
- }
- memset(sofia_private, 0, sizeof(*sofia_private));
- sofia_private->is_call++;
tech_pvt->sofia_private = sofia_private;
-
+ tech_pvt->nh = nua_handle_ref(nh);
+
if (profile->pres_type && sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT)) {
sofia_presence_set_chat_hash(tech_pvt, sip);
}
switch_copy_string(tech_pvt->sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid));
- nua_handle_bind(nh, tech_pvt->sofia_private);
- tech_pvt->nh = nh;
if (sip && switch_core_session_thread_launch(session) == SWITCH_STATUS_SUCCESS) {
const char *dialog_from_user = "", *dialog_from_host = "", *to_user = "", *to_host = "", *contact_user = "", *contact_host = "";
void sofia_handle_sip_i_options(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[])
{
- nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
}
void sofia_info_send_sipfrag(switch_core_session_t *aleg, switch_core_session_t *bleg)
switch_safe_free(d_url);
return SWITCH_STATUS_FALSE;
}
+ nua_handle_ref(tech_pvt->nh);
if (tech_pvt->dest && (strstr(tech_pvt->dest, ";fs_nat") || strstr(tech_pvt->dest, ";received")
|| ((val = switch_channel_get_variable(channel, "sip_sticky_contact")) && switch_true(val)))) {
switch_safe_free(d_url);
- if (!(sofia_private = malloc(sizeof(*sofia_private)))) {
+ if (!(sofia_private = su_alloc(tech_pvt->nh->nh_home, sizeof(*sofia_private)))) {
abort();
}
}
}
-char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_nat_parse_t *np)
+char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_dispatch_event_t *de, sofia_nat_parse_t *np)
{
char *contact_str = NULL;
const char *contact_host;//, *contact_user;
np = &lnp;
}
- sofia_glue_get_addr(nua_current_request(profile->nua), np->network_ip, sizeof(np->network_ip), &np->network_port);
+ sofia_glue_get_addr(de->data->e_msg, np->network_ip, sizeof(np->network_ip), &np->network_port);
if (sofia_glue_check_nat(profile, np->network_ip)) {
np->is_auto_nat = 1;
void sofia_presence_handle_sip_i_subscribe(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[])
{
to = sip->sip_to;
contact = sip->sip_contact;
- if (!(contact_str = sofia_glue_gen_contact_str(profile, sip, &np))) {
+ if (!(contact_str = sofia_glue_gen_contact_str(profile, sip, de, &np))) {
nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
return;
}
tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END());
- event = sip_header_as_string(profile->home, (void *) sip->sip_event);
+ event = sip_header_as_string(nh->nh_home, (void *) sip->sip_event);
/* the following could be refactored back to the calling event handler in sofia.c XXX MTK */
if (sip->sip_request->rq_url->url_user && !strncmp(sip->sip_request->rq_url->url_user, "sla-agent", sizeof("sla-agent"))) {
/* only fire this on <200 to try to avoid resubscribes. probably better ways to do this? */
if (status < 200) {
- sofia_sla_handle_sip_i_subscribe(nua, contact_str, profile, nh, sip, tags);
+ sofia_sla_handle_sip_i_subscribe(nua, contact_str, profile, nh, sip, de, tags);
}
switch_safe_free(contact_str);
return;
}
if (!(proto && to_user && to_host)) {
- nua_respond(nh, SIP_404_NOT_FOUND, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_404_NOT_FOUND, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
goto end;
}
}
call_id = sip->sip_call_id->i_id;
- full_from = sip_header_as_string(profile->home, (void *) sip->sip_from);
- full_via = sip_header_as_string(profile->home, (void *) sip->sip_via);
+ full_from = sip_header_as_string(nh->nh_home, (void *) sip->sip_from);
+ full_via = sip_header_as_string(nh->nh_home, (void *) sip->sip_via);
if (sip->sip_expires && sip->sip_expires->ex_delta > 31536000) {
sip->sip_expires->ex_delta = 31536000;
} else {
sip_accept_t *ap = sip->sip_accept;
char accept[256] = "";
- full_agent = sip_header_as_string(profile->home, (void *) sip->sip_user_agent);
+ full_agent = sip_header_as_string(nh->nh_home, (void *) sip->sip_user_agent);
while (ap) {
switch_snprintf(accept + strlen(accept), sizeof(accept) - strlen(accept), "%s%s ", ap->ac_type, ap->ac_next ? "," : "");
ap = ap->ac_next;
nua_respond(nh, SIP_202_ACCEPTED,
TAG_IF(new_contactstr, SIPTAG_CONTACT_STR(new_contactstr)),
- NUTAG_WITH_THIS(nua),
+ NUTAG_WITH_THIS_MSG(de->data->e_msg),
SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_EXPIRES_STR(exp_delta_str), TAG_IF(sticky, NUTAG_PROXY(sticky)), TAG_END());
switch_safe_free(new_contactstr);
char *p = NULL;
if (sip->sip_call_info) {
- full_call_info = sip_header_as_string(profile->home, (void *) sip->sip_call_info);
+ full_call_info = sip_header_as_string(nh->nh_home, (void *) sip->sip_call_info);
if ((p = strchr(full_call_info, ';'))) {
p++;
}
sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE);
}
- su_free(profile->home, full_call_info);
+ su_free(nh->nh_home, full_call_info);
}
char *p;
if (sip->sip_call_info) {
- full_call_info = sip_header_as_string(profile->home, (void *) sip->sip_call_info);
+ full_call_info = sip_header_as_string(nh->nh_home, (void *) sip->sip_call_info);
if ((p = strchr(full_call_info, ';'))) {
p++;
}
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE);
- su_free(profile->home, full_call_info);
+ su_free(nh->nh_home, full_call_info);
}
} else if (!strcasecmp(event, "call-info")) {
sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE);
if (event) {
- su_free(profile->home, event);
+ su_free(nh->nh_home, event);
}
if (full_from) {
- su_free(profile->home, full_from);
+ su_free(nh->nh_home, full_from);
}
if (full_via) {
- su_free(profile->home, full_via);
+ su_free(nh->nh_home, full_via);
}
if (full_agent) {
- su_free(profile->home, full_agent);
+ su_free(nh->nh_home, full_agent);
}
switch_safe_free(d_user);
void sofia_presence_handle_sip_r_subscribe(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[])
{
sip_event_t const *o = NULL;
/* the following could possibly be refactored back towards the calling event handler in sofia.c XXX MTK */
if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
if (!strcasecmp(o->o_type, "dialog") && msg_params_find(o->o_params, "sla")) {
- sofia_sla_handle_sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
+ sofia_sla_handle_sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
return;
}
}
}
}
+struct cpc {
+ sofia_profile_t *profile;
+ sofia_dispatch_event_t *de;
+};
+
static int sofia_counterpath_crutch(void *pArg, int argc, char **argv, char **columnNames)
{
nua_handle_t *nh;
- sofia_profile_t *profile = (sofia_profile_t *) pArg;
+ struct cpc *crutch = (struct cpc *) pArg;
char *call_id = argv[0];
char *pl = argv[1];
char *event_type = argv[2];
long exp_delta = atol(argv[3]);
- if ((nh = nua_handle_by_call_id(profile->nua, call_id))) {
+ if ((nh = nua_handle_by_call_id(crutch->profile->nua, call_id))) {
char sstr[128] = "", expstr[128] = "";
switch_snprintf(expstr, sizeof(expstr), "%d", exp_delta);
switch_snprintf(sstr, sizeof(sstr), "active;expires=%u", exp_delta);
nua_notify(nh,
- NUTAG_WITH_THIS(profile->nua),
+ NUTAG_WITH_THIS_MSG(crutch->de->data->e_msg),
SIPTAG_EXPIRES_STR(expstr),
SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_EVENT_STR(event_type),
SIPTAG_CONTENT_TYPE_STR("application/pidf+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END());
}
void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[])
{
if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
/* also it probably is unsafe to dereference so many things in a row without testing XXX MTK */
if (sip->sip_request->rq_url->url_user && !strncmp(sip->sip_request->rq_url->url_user, "sla-agent", sizeof("sla-agent"))) {
- sofia_sla_handle_sip_i_publish(nua, profile, nh, sip, tags);
+ sofia_sla_handle_sip_i_publish(nua, profile, nh, sip, de, tags);
return;
}
}
- contact_str = sofia_glue_gen_contact_str(profile, sip, NULL);
+ contact_str = sofia_glue_gen_contact_str(profile, sip, de, NULL);
if (from) {
from_user = (char *) from->a_url->url_user;
char *open_closed = "", *note_txt = "";
if (sip->sip_user_agent) {
- full_agent = sip_header_as_string(profile->home, (void *) sip->sip_user_agent);
+ full_agent = sip_header_as_string(nh->nh_home, (void *) sip->sip_user_agent);
}
if ((tuple = switch_xml_child(xml, "tuple")) && (status = switch_xml_child(tuple, "status"))
/* if (count > 1) let's not and say we did or all the clients who subscribe to their own presence will think they selves is offline */
- event_type = sip_header_as_string(profile->home, (void *) sip->sip_event);
+ event_type = sip_header_as_string(nh->nh_home, (void *) sip->sip_event);
if (count < 2) {
if ((sql = switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' "
}
} else if (contact_str) {
+ struct cpc crutch;
+
+ crutch.profile = profile;
+ crutch.de = de;
sql = switch_mprintf("select call_id,'%q','%q','%ld' from sip_subscriptions where sub_to_user='%q' and sub_to_host='%q' "
"and contact = '%q' ", payload->pl_data ? payload->pl_data : "", event_type, exp_delta,
from_user, from_host, contact_str);
- sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_counterpath_crutch, profile);
+ sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_counterpath_crutch, &crutch);
switch_safe_free(sql);
}
}
if (event_type) {
- su_free(profile->home, event_type);
+ su_free(nh->nh_home, event_type);
}
if (full_agent) {
- su_free(profile->home, full_agent);
+ su_free(nh->nh_home, full_agent);
}
switch_xml_free(xml);
switch_stun_random_string(etag, 8, NULL);
if (sub_count > 0) {
- nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), SIPTAG_ETAG_STR(etag), SIPTAG_EXPIRES_STR(expstr), TAG_END());
+ nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_ETAG_STR(etag), SIPTAG_EXPIRES_STR(expstr), TAG_END());
} else {
- nua_respond(nh, SIP_404_NOT_FOUND, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_404_NOT_FOUND, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
}
switch_safe_free(contact_str);
void sofia_presence_handle_sip_i_message(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[])
{
if (sip) {
char *full_from;
char proto[512] = SOFIA_CHAT_PROTO;
- full_from = sip_header_as_string(profile->home, (void *) sip->sip_from);
+ full_from = sip_header_as_string(nh->nh_home, (void *) sip->sip_from);
if ((p = strchr(to_user, '+'))) {
switch_copy_string(proto, to_user, sizeof(proto));
switch_safe_free(to_addr);
switch_safe_free(from_addr);
if (full_from) {
- su_free(profile->home, full_from);
+ su_free(nh->nh_home, full_from);
}
}
}
}
-void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_regtype_t regtype, const char *realm, int stale)
+void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_dispatch_event_t *de,
+ sofia_regtype_t regtype, const char *realm, int stale)
{
switch_uuid_t uuid;
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
auth_str = switch_mprintf("Digest realm=\"%q\", nonce=\"%q\",%s algorithm=MD5, qop=\"auth\"", realm, uuid_str, stale ? " stale=true," : "");
if (regtype == REG_REGISTER) {
- nua_respond(nh, SIP_401_UNAUTHORIZED, TAG_IF(nua, NUTAG_WITH_THIS(nua)), SIPTAG_WWW_AUTHENTICATE_STR(auth_str), TAG_END());
+ nua_respond(nh, SIP_401_UNAUTHORIZED, TAG_IF((nua && de), NUTAG_WITH_THIS_MSG(de->data->e_msg)), SIPTAG_WWW_AUTHENTICATE_STR(auth_str), TAG_END());
} else if (regtype == REG_INVITE) {
- nua_respond(nh, SIP_407_PROXY_AUTH_REQUIRED, TAG_IF(nua, NUTAG_WITH_THIS(nua)), SIPTAG_PROXY_AUTHENTICATE_STR(auth_str), TAG_END());
+ nua_respond(nh, SIP_407_PROXY_AUTH_REQUIRED, TAG_IF((nua && de), NUTAG_WITH_THIS_MSG(de->data->e_msg)), SIPTAG_PROXY_AUTHENTICATE_STR(auth_str), TAG_END());
}
switch_safe_free(auth_str);
return atoi(buf);
}
-uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, sofia_regtype_t regtype, char *key,
+uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip,
+ sofia_dispatch_event_t *de, sofia_regtype_t regtype, char *key,
uint32_t keylen, switch_event_t **v_event, const char *is_nat)
{
sip_to_t const *to = NULL;
/* 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);
- sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
+ sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
snprintf(network_port_c, sizeof(network_port_c), "%d", network_port);
- snprintf(url_ip, sizeof(url_ip), (msg_addrinfo(nua_current_request(nua)))->ai_addr->sa_family == AF_INET6 ? "[%s]" : "%s", network_ip);
+ snprintf(url_ip, sizeof(url_ip), (msg_addrinfo(de->data->e_msg))->ai_addr->sa_family == AF_INET6 ? "[%s]" : "%s", network_ip);
expires = sip->sip_expires;
authorization = sip->sip_authorization;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can not do authorization without a complete header in REGISTER request from %s:%d\n",
network_ip, network_port);
- nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
switch_goto_int(r, 1, end);
}
char *v_contact_str = NULL;
const char *username = "unknown";
const char *realm = reg_host;
- if ((auth_res = sofia_reg_parse_auth(profile, authorization, sip, sip->sip_request->rq_method_name,
+ if ((auth_res = sofia_reg_parse_auth(profile, authorization, sip, de, sip->sip_request->rq_method_name,
key, keylen, network_ip, v_event, exptime, regtype, to_user, &auth_params, ®_count)) == AUTH_STALE) {
stale = 1;
}
if (auth_res != AUTH_OK && !stale) {
if (auth_res == AUTH_FORBIDDEN) {
- nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
forbidden = 1;
} else {
- nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
}
if (profile->debug) {
realm = from_host;
}
- sofia_reg_auth_challenge(nua, profile, nh, regtype, realm, stale);
+ sofia_reg_auth_challenge(nua, profile, nh, de, regtype, realm, stale);
if (profile->debug) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Send challenge for [%s@%s]\n", to_user, to_host);
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(nua), SIPTAG_DATE_STR(date), TAG_END());
+ 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);
}
if (*contact_str && sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE_SYLANTRO)) {
- sofia_sla_handle_register(nua, profile, sip, exptime, contact_str);
+ sofia_sla_handle_register(nua, profile, sip, de, exptime, contact_str);
}
switch_goto_int(r, 1, end);
void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[])
{
char key[128] = "";
}
#endif
- sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
+ sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
if (!(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);
}
if (!(profile->mflags & MFLAG_REGISTER)) {
- nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
goto end;
}
type = REG_AUTO_REGISTER;
} else if (!ok) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by register acl \"%s\"\n", network_ip, profile->reg_acl[x]);
- nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
goto end;
}
}
is_nat = NULL;
}
- sofia_reg_handle_register(nua, profile, nh, sip, type, key, sizeof(key), &v_event, is_nat);
+ sofia_reg_handle_register(nua, profile, nh, sip, de, type, key, sizeof(key), &v_event, is_nat);
if (v_event) {
switch_event_destroy(&v_event);
void sofia_reg_handle_sip_r_register(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[])
{
if (status >= 500) {
void sofia_reg_handle_sip_r_challenge(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private,
- switch_core_session_t *session, sofia_gateway_t *gateway, sip_t const *sip, tagi_t tags[])
+ switch_core_session_t *session, sofia_gateway_t *gateway, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[])
{
sip_www_authenticate_t const *authenticate = NULL;
char const *realm = NULL;
auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
sip_authorization_t const *authorization,
sip_t const *sip,
+ sofia_dispatch_event_t *de,
const char *regstr,
char *np,
size_t nplen,
}
-void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const *sip, long exptime, const char *full_contact)
+void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const *sip,
+ sofia_dispatch_event_t *de, long exptime, const char *full_contact)
{
nua_handle_t *nh = NULL;
char exp_str[256] = "";
char *route_uri = NULL;
char port_str[25] = "";
- sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
+ sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
sql = switch_mprintf("select call_id from sip_shared_appearance_dialogs where hostname='%q' and profile_name='%q' and contact_str='%q'",
mod_sofia_globals.hostname, profile->name, contact_str);
free(contact_str);
}
-void sofia_sla_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[])
+void sofia_sla_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[])
{
/* at present there's no SLA versions that we deal with that do publish. to be safe, we say "OK" */
- nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END());
+ nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
}
-void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[])
+void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[])
{
char *aor = NULL;
char *subscriber = NULL;
sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url);
- sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
+ sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
/*
* XXX MTK FIXME - we don't look at the tag to see if NUTAG_SUBSTATE(nua_substate_terminated) or
* a Subscription-State header with state "terminated" and/or expiration of 0. So we never forget
sla_contact = switch_mprintf("<sip:%s@%s%s;transport=%s>", profile->sla_contact, profile->sipip, port_str, sofia_glue_transport2str(transport));
}
- nua_respond(nh, SIP_202_ACCEPTED, SIPTAG_CONTACT_STR(sla_contact), NUTAG_WITH_THIS(nua), TAG_IF(route_uri, NUTAG_PROXY(route_uri)), SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=300"), /* you thought the OTHER time was fake... need delta here FIXME XXX MTK */
+ nua_respond(nh, SIP_202_ACCEPTED, SIPTAG_CONTACT_STR(sla_contact), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_IF(route_uri, NUTAG_PROXY(route_uri)), SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=300"), /* you thought the OTHER time was fake... need delta here FIXME XXX MTK */
SIPTAG_EXPIRES_STR("300"), /* likewise, totally fake - FIXME XXX MTK */
/* sofia_presence says something about needing TAG_IF(sticky, NUTAG_PROXY(sticky)) for NAT stuff? */
TAG_END());
void sofia_sla_handle_sip_r_subscribe(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
+ sofia_dispatch_event_t *de,
tagi_t tags[])
{
if (status >= 300) {
}
}
-void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[])
+void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip,
+ sofia_dispatch_event_t *de, tagi_t tags[])
{
char *sql = NULL;
struct sla_notify_helper helper;
#ifdef DEBUG_ALLOC
if (memory > 500)
- switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_CONSOLE, "Session Allocate %d\n",
- (int) memory);
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Session Allocate %s %d\n",
+ apr_pool_tag(session->pool, NULL), (int) memory);
#endif
ptr = apr_palloc(session->pool, memory);
#endif
#ifdef DEBUG_ALLOC
- switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Perm Allocate %d\n", (int) memory);
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Perm Allocate %s %d\n",
+ apr_pool_tag(memory_manager.memory_pool, NULL), (int) memory);
#endif
ptr = apr_palloc(memory_manager.memory_pool, memory);
switch_assert(duped != NULL);
#ifdef DEBUG_ALLOC
- switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Perm Allocate %d\n", (int) len);
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Perm Allocate %s %d\n",
+ apr_pool_tag(memory_manager.memory_pool, NULL), (int) len);
#endif
#ifdef LOCK_MORE
SWITCH_DECLARE(char *) switch_core_perform_session_strdup(switch_core_session_t *session, const char *todup, const char *file, const char *func, int line)
{
char *duped = NULL;
- switch_assert(session != NULL);
- switch_assert(session->pool != NULL);
#ifdef DEBUG_ALLOC
switch_size_t len;
#endif
+ switch_assert(session != NULL);
+ switch_assert(session->pool != NULL);
+
if (!todup) {
return NULL;
}
#ifdef DEBUG_ALLOC
len = strlen(todup);
if (len > 500)
- switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_CONSOLE, "Sess Strdup Allocate %d\n",
- (int) len);
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Sess Strdup Allocate %s %ld\n",
+ apr_pool_tag(session->pool, NULL), strlen(todup));
#endif
duped = apr_pstrdup(session->pool, todup);
#ifdef DEBUG_ALLOC
if (len > 500)
- switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "core strdup Allocate %d\n", (int) len);
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Core Strdup Allocate %s %d\n",
+ apr_pool_tag(pool, NULL), (int)len);
#endif
duped = apr_pstrmemdup(pool, todup, len);
#endif
#endif
-#ifdef DEBUG_ALLOC2
- switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "New Pool\n");
-#endif
tmp = switch_core_sprintf(*pool, "%s:%d", file, line);
apr_pool_tag(*pool, tmp);
+#ifdef DEBUG_ALLOC2
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "New Pool %s\n", apr_pool_tag(*pool, NULL));
+#endif
+
#ifdef USE_MEM_LOCK
switch_mutex_unlock(memory_manager.mem_lock);
#ifdef DEBUG_ALLOC
if (memory > 500)
- switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Core Allocate %d\n", (int) memory);
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Core Allocate %s %d\n",
+ apr_pool_tag(pool, NULL), (int) memory);
/*switch_assert(memory < 20000); */
#endif
goto end;
}
- if (switch_channel_down(session->channel)) {
- switch_log_printf(SWITCH_CHANNEL_ID_LOG, message->_file, message->_func, message->_line,
- switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG, "%s skip receive message [%s] (channel is hungup already)\n",
- switch_channel_get_name(session->channel), message_names[message->message_id]);
+ if (switch_channel_down(session->channel) && message->message_id != SWITCH_MESSAGE_INDICATE_SIGNAL_DATA) {
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, message->_file, message->_func, message->_line,
+ switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG, "%s skip receive message [%s] (channel is hungup already)\n",
+ switch_channel_get_name(session->channel), message_names[message->message_id]);
} else if (session->endpoint_interface->io_routines->receive_message) {
status = session->endpoint_interface->io_routines->receive_message(session, message);
if (endstate == switch_channel_get_running_state(session->channel)) {
if (endstate == CS_NEW) {
switch_cond_next();
+ switch_ivr_parse_all_events(session);
if (!--new_loops) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s Timeout waiting for next instruction in CS_NEW!\n",
session->uuid_str);