]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add parallelism to sofia by offsetting sip messages to the concerned sessions and...
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 16 Jun 2011 19:37:22 +0000 (14:37 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Thu, 16 Jun 2011 19:37:22 +0000 (14:37 -0500)
13 files changed:
libs/apr/include/apr_pools.h
libs/apr/memory/unix/apr_pools.c
src/include/switch_types.h
src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c
src/mod/endpoints/mod_sofia/sofia_presence.c
src/mod/endpoints/mod_sofia/sofia_reg.c
src/mod/endpoints/mod_sofia/sofia_sla.c
src/switch_core_memory.c
src/switch_core_session.c
src/switch_core_state_machine.c

index 5c82b38747eb41fbda8ff98fa0293d41066b5006..74ed59e35b31736f5b8e06b7cd0d3fc4f594888f 100644 (file)
@@ -409,7 +409,7 @@ APR_DECLARE(int) apr_pool_is_ancestor(apr_pool_t *a, apr_pool_t *b);
  * @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
 /**
index 42c64967cdca6934b9b6694d0472771b4c1846d8..99e1888b1fb3f718df314a5683189ba33ac2a6b8 100644 (file)
@@ -1895,9 +1895,13 @@ APR_DECLARE(int) apr_pool_is_ancestor(apr_pool_t *a, apr_pool_t *b)
     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;
 }
 
 
index bf5d5d88ea655819c3ddabb7b6e290a2b0080492..e84fb1082aa049e03716a5ae6c49642a526fa22b 100644 (file)
@@ -799,6 +799,7 @@ typedef enum {
        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;
 
index a7e6d99dc2d7dcc321d07e50295b35668b91586d..979d80037d1baf079605c6881ba274f8cefe5bd9 100644 (file)
@@ -1366,6 +1366,15 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
        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;
@@ -2158,7 +2167,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                        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");
@@ -4640,7 +4649,6 @@ static void general_event_handler(switch_event_t *event)
                                        
                                        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());
                                        
@@ -4826,7 +4834,6 @@ static void general_event_handler(switch_event_t *event)
                        }
 
                        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)),
@@ -5219,11 +5226,18 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
 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;
        }
@@ -5245,6 +5259,11 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown)
                }
        }
 
+       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();
 
index db8a6ff9e3c75e48e442f02a5a0bf4758f71d944..6542bae61520ed79b49e588f972cc5478d84974d 100644 (file)
@@ -134,6 +134,16 @@ typedef enum {
        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;
@@ -143,11 +153,13 @@ struct sofia_private {
        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 */
 /*************************************************************************************************************************************************************/
@@ -300,6 +312,9 @@ typedef enum {
        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;
@@ -313,6 +328,9 @@ struct mod_sofia_globals {
        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;
@@ -541,7 +559,7 @@ struct sofia_profile {
        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;
@@ -773,6 +791,8 @@ typedef struct {
 } 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);\
@@ -814,19 +834,24 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
 
 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);
 
@@ -851,9 +876,11 @@ void sofia_presence_mwi_event_handler(switch_event_t *event);
 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);
 
 
@@ -861,21 +888,28 @@ 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[]);
 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);
@@ -892,6 +926,7 @@ void sofia_glue_pass_sdp(private_object_t *tech_pvt, char *sdp);
 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);
@@ -1008,14 +1043,19 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t *
  * 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
@@ -1072,5 +1112,7 @@ switch_status_t sofia_glue_sdp_map(const char *r_sdp, switch_event_t **fmtp, swi
 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);
+
index bf9ff4e7c4c1bed1199b8ca1cff6823ff1d82389..026c3c9ba158d0fcdb8aa9f55b85aae6fe00e32e 100644 (file)
@@ -54,6 +54,7 @@ extern su_log_t su_log_default[];
 
 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);
@@ -63,18 +64,22 @@ static void set_variable_sip_param(switch_channel_t *channel, char *header_type,
 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) {
@@ -156,28 +161,29 @@ static char *strip_quotes(const char *in)
        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) {
@@ -187,9 +193,9 @@ static void extract_header_vars(sofia_profile_t *profile, sip_t const *sip, swit
                                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) {
@@ -201,16 +207,17 @@ static void extract_header_vars(sofia_profile_t *profile, sip_t const *sip, swit
 
                        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);
 
@@ -246,7 +253,8 @@ static void extract_vars(sofia_profile_t *profile, sip_t const *sip, switch_core
 
 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;
@@ -271,7 +279,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
        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;
                }
        }
@@ -279,7 +287,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
        /* 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;
        }
 
@@ -357,7 +365,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
                                }
                        }
                }
-               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 */
@@ -371,7 +379,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
                        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;
                }
        }
@@ -421,7 +429,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
 
        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;
@@ -433,7 +441,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
                        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))) {
@@ -470,7 +478,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
                }
 
        } 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:
@@ -485,7 +493,8 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
 
 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;
@@ -544,7 +553,7 @@ void sofia_handle_sip_i_bye(switch_core_session_t *session, int status,
        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);
@@ -636,7 +645,8 @@ void sofia_send_callee_id(switch_core_session_t *session, const char *name, cons
        }
 }
 
-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;
@@ -760,11 +770,12 @@ void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *pro
        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;
@@ -774,6 +785,13 @@ void sofia_event_callback(nua_event_t event,
        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 
@@ -855,8 +873,8 @@ void sofia_event_callback(nua_event_t event,
 
                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);
                }
@@ -873,7 +891,7 @@ void sofia_event_callback(nua_event_t event,
        }
 
        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;
        }
 
@@ -922,7 +940,7 @@ void sofia_event_callback(nua_event_t event,
                                        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);
                        }
                }
@@ -938,49 +956,49 @@ void sofia_event_callback(nua_event_t event,
                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;
@@ -993,13 +1011,13 @@ void sofia_event_callback(nua_event_t event,
                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:
 
@@ -1072,6 +1090,7 @@ void sofia_event_callback(nua_event_t event,
                }
                sofia_private->destroy_me = 12;
                sofia_private_free(sofia_private);
+
        }
 
        if (gateway) {
@@ -1087,6 +1106,169 @@ void sofia_event_callback(nua_event_t event,
        }
 }
 
+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;
@@ -1484,7 +1666,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
        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);
 
@@ -1727,7 +1909,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
                }
        }
 
-       su_home_unref(profile->home);
+       //su_home_unref(profile->home);
        su_root_destroy(profile->s_root);
        //pool = profile->pool;
 
@@ -3201,6 +3383,15 @@ switch_status_t config_sofia(int reload, char *profile_name)
                                                } 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);
@@ -4065,6 +4256,7 @@ const char *sofia_gateway_status_name(sofia_gateway_status_t status)
 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;
@@ -4130,6 +4322,7 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu
 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;
@@ -4144,7 +4337,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
                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);
@@ -4648,7 +4841,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
                                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);
@@ -4715,6 +4908,7 @@ static void launch_media_on_hold(switch_core_session_t *session)
 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;
@@ -5531,6 +5725,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                tech_pvt->sofia_private = NULL;
                        }
 
+                       nua_handle_unref(tech_pvt->nh);
                        tech_pvt->nh = NULL;
 
                        if (nh) {
@@ -5693,7 +5888,8 @@ nua_handle_t *sofia_global_nua_handle_by_replaces(sip_replaces_t *replaces)
 
 }
 
-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;
@@ -5710,7 +5906,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
        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;
        }
 
@@ -5725,7 +5921,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
        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);
@@ -6205,7 +6401,8 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
 }
 
 
-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;
@@ -6269,7 +6466,8 @@ static switch_status_t create_info_event(sip_t const *sip, nua_handle_t *nh, swi
        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;
@@ -6295,17 +6493,17 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                                        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());   
                                                
                                        }
 
@@ -6326,10 +6524,10 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
 
                                        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);
@@ -6337,7 +6535,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                        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;
                        }
@@ -6438,7 +6636,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                }
 
                                /* 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);
@@ -6450,7 +6648,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                        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;
                }
@@ -6458,7 +6656,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                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;
@@ -6471,7 +6669,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                        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;
@@ -6483,9 +6681,9 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                                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());
                                        }
                                }
                        }
@@ -6499,7 +6697,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                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;
 
@@ -6507,6 +6705,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
 
 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;
@@ -6519,7 +6718,7 @@ void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
                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);
@@ -6548,7 +6747,8 @@ void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
        }
 }
 
-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] = "";
@@ -6605,7 +6805,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
                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) {
@@ -6765,7 +6965,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
                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);
                                }
@@ -6964,7 +7164,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
                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);
@@ -7200,9 +7400,9 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
        }
 
        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))) {
@@ -7528,20 +7728,14 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
                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 = "";
@@ -7661,9 +7855,10 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
 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)
index 6fcf2e30cd9c6754334d6979fca11e6c96299c68..767558c0451a0d9d3156b71da7be830f26506b44 100644 (file)
@@ -2202,6 +2202,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
                        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)))) {
@@ -2290,7 +2291,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
 
                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();
                }
 
@@ -6484,7 +6485,7 @@ 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)
 {
        char *contact_str = NULL;
        const char *contact_host;//, *contact_user;
@@ -6507,7 +6508,7 @@ char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sof
                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;
index 2ca69c5f57ff283832a6d2cb6a91fc0027e59157..34c6799991984622d502591eca9fcb8ae1d3281d 100644 (file)
@@ -2094,6 +2094,7 @@ static void sync_sla(sofia_profile_t *profile, const char *to_user, const char *
 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[])
 {
 
@@ -2128,7 +2129,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
        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;
        }
@@ -2138,7 +2139,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
 
        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 */
@@ -2146,7 +2147,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
                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;
@@ -2200,14 +2201,14 @@ void sofia_presence_handle_sip_i_subscribe(int status,
                }
 
                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;
@@ -2256,7 +2257,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
                } 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;
@@ -2342,7 +2343,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
 
                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);
@@ -2354,7 +2355,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
                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++;
                        }
@@ -2382,7 +2383,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
                                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);
 
                }
                        
@@ -2392,7 +2393,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
                        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++;
                                }
@@ -2424,7 +2425,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
                                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);
@@ -2499,17 +2500,17 @@ void sofia_presence_handle_sip_i_subscribe(int status,
 
 
        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);
@@ -2538,6 +2539,7 @@ sofia_gateway_subscription_t *sofia_find_gateway_subscription(sofia_gateway_t *g
 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;
@@ -2557,7 +2559,7 @@ void sofia_presence_handle_sip_r_subscribe(int status,
        /* 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;
                }
        }
@@ -2604,21 +2606,26 @@ void sofia_presence_handle_sip_r_subscribe(int status,
        }
 }
 
+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());
@@ -2641,6 +2648,7 @@ uint32_t sofia_presence_contact_count(sofia_profile_t *profile, const char *cont
 }
 
 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[])
 {
        
@@ -2669,12 +2677,12 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
        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;
@@ -2704,7 +2712,7 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
                        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"))
@@ -2741,7 +2749,7 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
 
                        /* 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' "
@@ -2760,10 +2768,14 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
                                }
                                
                        } 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);
                        }
 
@@ -2781,11 +2793,11 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
                        }
 
                        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);
@@ -2802,9 +2814,9 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
        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);
@@ -2820,6 +2832,7 @@ void sofia_presence_set_hash_key(char *hash_key, int32_t len, sip_t const *sip)
 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) {
@@ -2866,7 +2879,7 @@ void sofia_presence_handle_sip_i_message(int status,
                        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));
@@ -2911,7 +2924,7 @@ void sofia_presence_handle_sip_i_message(int status,
                        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);
                        }
                }
        }
index 730576f9499b32970f0fb66e8ca4dc1b91e5970c..5fb5089d665ed494c3b978db81e5e0f724bb3484 100644 (file)
@@ -875,7 +875,8 @@ switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *p
 }
 
 
-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];
@@ -895,9 +896,9 @@ void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t
        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);
@@ -916,7 +917,8 @@ uint32_t sofia_reg_reg_count(sofia_profile_t *profile, const char *user, const c
        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;
@@ -976,11 +978,11 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
        /* all callers must confirm that sip, sip->sip_request and sip->sip_contact are not NULL */
        switch_assert(sip != NULL && sip->sip_contact != NULL && sip->sip_request != NULL);
 
-       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;
@@ -1011,7 +1013,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
                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);
        }
 
@@ -1139,7 +1141,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
                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, &reg_count)) == AUTH_STALE) {
                        stale = 1;
                }
@@ -1270,10 +1272,10 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
 
                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) {
@@ -1317,7 +1319,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
                        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);
@@ -1639,7 +1641,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
 
                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);
@@ -1650,7 +1652,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
                }
 
                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);
@@ -1670,6 +1672,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
 
 
 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] = "";
@@ -1692,7 +1695,7 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
        }
 #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);
@@ -1701,7 +1704,7 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
        }
 
        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;
        }
 
@@ -1765,7 +1768,7 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
                        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;
                }
        }
@@ -1783,7 +1786,7 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
                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);
@@ -1799,6 +1802,7 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
 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) {
@@ -1867,7 +1871,8 @@ void sofia_reg_handle_sip_r_register(int status,
 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;
@@ -2066,6 +2071,7 @@ static int sofia_reg_regcount_callback(void *pArg, int argc, char **argv, char *
 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,
index 05eba011bbf4b8af6caefbf47e16a676fc5eddf7..bd79920d1aac1bfbe3d68f13526fbc3bd8bb45c2 100644 (file)
@@ -68,7 +68,8 @@ int sofia_sla_supported(sip_t const *sip)
 }
 
 
-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] = "";
@@ -83,7 +84,7 @@ void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const
        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);
@@ -137,13 +138,15 @@ void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const
        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;
@@ -156,7 +159,7 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia
 
        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
@@ -225,7 +228,7 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia
                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());
@@ -245,6 +248,7 @@ struct sla_notify_helper {
 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) {
@@ -270,7 +274,8 @@ void sofia_sla_handle_sip_r_subscribe(int status,
        }
 }
 
-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;
index 7e6abf9c77c08ad797cf569b17bf167444c0a8e9..8af979bdb6499203bbf09b5274be38a42fac9bb3 100644 (file)
@@ -80,8 +80,8 @@ SWITCH_DECLARE(void *) switch_core_perform_session_alloc(switch_core_session_t *
 
 #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);
@@ -113,7 +113,8 @@ SWITCH_DECLARE(void *) switch_core_perform_permanent_alloc(switch_size_t 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);
@@ -154,7 +155,8 @@ SWITCH_DECLARE(char *) switch_core_perform_permanent_strdup(const char *todup, c
        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
@@ -221,12 +223,13 @@ SWITCH_DECLARE(char *) switch_core_sprintf(switch_memory_pool_t *pool, const cha
 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;
        }
@@ -245,8 +248,8 @@ SWITCH_DECLARE(char *) switch_core_perform_session_strdup(switch_core_session_t
 #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);
@@ -284,7 +287,8 @@ SWITCH_DECLARE(char *) switch_core_perform_strdup(switch_memory_pool_t *pool, co
 
 #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);
@@ -392,12 +396,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_new_memory_pool(switch_memor
 #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);
@@ -453,7 +458,8 @@ SWITCH_DECLARE(void *) switch_core_perform_alloc(switch_memory_pool_t *pool, swi
 
 #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
 
index 89a78f51e3d3859505d06aad7d263e5f5194ad37..9b20347fe3edf3ed1e8829f5302d50968ecab43d 100644 (file)
@@ -669,10 +669,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_perform_receive_message(swit
                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);
index 6551b2b777b36bd61083f0833eb43b9642ba9b48..3c8bd28c559608b56097369248d61ede014006d3 100644 (file)
@@ -401,6 +401,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
                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);