]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
fix sofia (part 2) you'd better 'make sure'
authorAnthony Minessale <anthony.minessale@gmail.com>
Thu, 28 Dec 2006 19:38:35 +0000 (19:38 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Thu, 28 Dec 2006 19:38:35 +0000 (19:38 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3860 d0543943-73ff-0310-b7d9-9358b9ac24b2

libs/sofia-sip/libsofia-sip-ua/nua/nua_notifier.c
src/mod/endpoints/mod_sofia/mod_sofia.c
src/switch_core.c
src/switch_ivr.c

index 31518a326b09e8115f321d30475558b6f218e019..ff5b276313d3ea14428325b71a46e96513370597 100644 (file)
@@ -599,7 +599,8 @@ static int nua_notify_usage_shutdown(nua_handle_t *nh,
 
   if (!cr->cr_usage) {
     /* Unnotify */
-    nua_stack_notify2(nh->nh_nua, nh, nua_r_destroy, du, NULL);
+       /* Commenting this line out to supress an attended transfer bug (awaiting fix from pessi) */
+    //nua_stack_notify2(nh->nh_nua, nh, nua_r_destroy, du, NULL);
     return cr->cr_usage != du;
   }
 
index 951350202edf34f0ce66e7850bb177f39ff3b1b4..80e5d552d0eb012dde2330ce9ccee83c714df0c3 100644 (file)
@@ -49,7 +49,7 @@ typedef struct sofia_profile sofia_profile_t;
 #define NUA_MAGIC_T sofia_profile_t
 
 struct sofia_private {
-       switch_core_session_t *session;
+    char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1];
        outbound_reg_t *oreg;
 };
 
@@ -167,8 +167,7 @@ typedef enum {
        TFLAG_XFER = (1 << 19),
        TFLAG_NOMEDIA = (1 << 20),
        TFLAG_BUGGY_2833 = (1 << 21),
-       TFLAG_SIP_HOLD = (1 << 22),
-       TFLAG_RWLOCK = (1 << 23)
+       TFLAG_SIP_HOLD = (1 << 22)
 } TFLAGS;
 
 static struct {
@@ -256,7 +255,6 @@ struct sofia_profile {
 
 struct private_object {
        sofia_private_t *sofia_private;
-       sofia_private_t *sofia_private2;
        uint32_t flags;
        switch_payload_t agreed_pt;
        switch_core_session_t *session;
@@ -374,7 +372,7 @@ static void sip_i_state(int status,
 static void sip_i_refer(nua_t *nua,
                                                sofia_profile_t *profile,
                                                nua_handle_t *nh,
-                                               sofia_private_t *sofia_private,
+                        switch_core_session_t *session,
                                                sip_t const *sip,
                                                tagi_t tags[]);
 
@@ -983,7 +981,7 @@ static void do_invite(switch_core_session_t *session)
                 abort();
             }
             memset(tech_pvt->sofia_private, 0, sizeof(*tech_pvt->sofia_private));
-                       tech_pvt->sofia_private->session = session;
+                       switch_copy_string(tech_pvt->sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid));
                        nua_handle_bind(tech_pvt->nh, tech_pvt->sofia_private);
 
                }
@@ -1057,14 +1055,7 @@ static void do_xfer_invite(switch_core_session_t *session)
                                                                  TAG_END());
                        
         
-        if (!(tech_pvt->sofia_private2 = malloc(sizeof(*tech_pvt->sofia_private2)))) {
-            abort();
-        }
-        memset(tech_pvt->sofia_private2, 0, sizeof(*tech_pvt->sofia_private2));
-        tech_pvt->sofia_private2->session = tech_pvt->sofia_private->session;
-               nua_handle_bind(tech_pvt->nh2, tech_pvt->sofia_private2);
-
-
+               nua_handle_bind(tech_pvt->nh2, tech_pvt->sofia_private);
 
                nua_invite(tech_pvt->nh2,
                                   TAG_IF(rpid, SIPTAG_HEADER_STR(rpid)),
@@ -1237,7 +1228,7 @@ static int hangup_cause_to_sip(switch_call_cause_t cause) {
 
 static switch_status_t sofia_on_hangup(switch_core_session_t *session)
 {
-       switch_core_session_t *asession;
+       switch_core_session_t *a_session;
        private_object_t *tech_pvt;
        switch_channel_t *channel = NULL;
        switch_call_cause_t cause;
@@ -1261,10 +1252,10 @@ static switch_status_t sofia_on_hangup(switch_core_session_t *session)
                switch_core_hash_delete(tech_pvt->profile->chat_hash, tech_pvt->hash_key);
        }
 
-       if (tech_pvt->kick && (asession = switch_core_session_locate(tech_pvt->kick))) {
-               switch_channel_t *a_channel = switch_core_session_get_channel(asession);
+       if (tech_pvt->kick && (a_session = switch_core_session_locate(tech_pvt->kick))) {
+               switch_channel_t *a_channel = switch_core_session_get_channel(a_session);
                switch_channel_hangup(a_channel, switch_channel_get_cause(channel));
-               switch_core_session_rwunlock(asession);
+               switch_core_session_rwunlock(a_session);
        }
 
        if (tech_pvt->nh) {
@@ -1297,7 +1288,7 @@ static switch_status_t sofia_on_hangup(switch_core_session_t *session)
        }
 
     if (tech_pvt->sofia_private) {
-        tech_pvt->sofia_private->session = NULL;
+        *tech_pvt->sofia_private->uuid = '\0';
     }
 
        return SWITCH_STATUS_SUCCESS;
@@ -1862,23 +1853,21 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                if (switch_test_flag(tech_pvt, TFLAG_XFER)) {
                        switch_clear_flag_locked(tech_pvt, TFLAG_XFER);
                        if (msg->pointer_arg) {
-                               switch_core_session_t *asession, *bsession = msg->pointer_arg;
+                               switch_core_session_t *a_session, *b_session = msg->pointer_arg;
 
-                               if ((asession = switch_core_session_locate(tech_pvt->xferto))) {
-                                       private_object_t *a_tech_pvt = switch_core_session_get_private(asession);
-                                       private_object_t *b_tech_pvt = switch_core_session_get_private(bsession);
+                               if ((a_session = switch_core_session_locate(tech_pvt->xferto))) {
+                                       private_object_t *a_tech_pvt = switch_core_session_get_private(a_session);
+                                       private_object_t *b_tech_pvt = switch_core_session_get_private(b_session);
 
                                        switch_set_flag_locked(a_tech_pvt, TFLAG_REINVITE);
-                                       a_tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(asession, b_tech_pvt->remote_sdp_audio_ip);
+                                       a_tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(a_session, b_tech_pvt->remote_sdp_audio_ip);
                                        a_tech_pvt->remote_sdp_audio_port = b_tech_pvt->remote_sdp_audio_port;
-                                       a_tech_pvt->local_sdp_audio_ip = switch_core_session_strdup(asession, b_tech_pvt->local_sdp_audio_ip);
+                                       a_tech_pvt->local_sdp_audio_ip = switch_core_session_strdup(a_session, b_tech_pvt->local_sdp_audio_ip);
                                        a_tech_pvt->local_sdp_audio_port = b_tech_pvt->local_sdp_audio_port;
                                        activate_rtp(a_tech_pvt);
                                        
-                                       b_tech_pvt->kick = switch_core_session_strdup(bsession, tech_pvt->xferto);
-                                       
-
-                                       switch_core_session_rwunlock(asession);
+                                       b_tech_pvt->kick = switch_core_session_strdup(b_session, tech_pvt->xferto);
+                    switch_core_session_rwunlock(a_session);
                                }
 
                                
@@ -2505,13 +2494,23 @@ static void sip_i_state(int status,
        int ss_state = nua_callstate_init;
        switch_channel_t *channel = NULL;
        private_object_t *tech_pvt = NULL;
-       switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
+       switch_core_session_t *session = NULL;
        const char *replaces_str = NULL;
        char *uuid;
        switch_core_session_t *other_session = NULL;
        switch_channel_t *other_channel = NULL;
        char st[80] = "";
 
+
+    if (sofia_private) {
+        if (!switch_strlen_zero(sofia_private->uuid)) {
+            if (!(session = switch_core_session_locate(sofia_private->uuid))) {
+                /* too late */
+                return;            
+            }
+        }
+    }
+
        
        tl_gets(tags, 
                        NUTAG_CALLSTATE_REF(ss_state),
@@ -2549,7 +2548,7 @@ static void sip_i_state(int status,
        }
 
        if (status == 988) {
-               return;
+               goto done;
        }
 
        switch ((enum nua_callstate)ss_state) {
@@ -2591,7 +2590,7 @@ static void sip_i_state(int status,
                                                switch_channel_pre_answer(other_channel);
                                                switch_core_session_rwunlock(other_session);
                                        }
-                                       return;
+                    goto done;
                                } else {
                                        sdp_parser_t *parser = sdp_parse(tech_pvt->home, r_sdp, (int)strlen(r_sdp), 0);
                                        sdp_session_t *sdp;
@@ -2628,7 +2627,7 @@ static void sip_i_state(int status,
        case nua_callstate_received: 
                if (session && switch_core_session_running(session)) {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Re-Entering Call State Received!\n");
-                       return;
+            goto done;
                }
 
                if (channel) {
@@ -2638,7 +2637,7 @@ static void sip_i_state(int status,
                                        switch_channel_set_state(channel, CS_INIT);
                                        switch_set_flag_locked(tech_pvt, TFLAG_READY);
                                        switch_core_session_thread_launch(session);
-                                       return;
+                    goto done;
                                } else {
                                        sdp_parser_t *parser = sdp_parse(tech_pvt->home, r_sdp, (int)strlen(r_sdp), 0);
                                        sdp_session_t *sdp;
@@ -2673,7 +2672,7 @@ static void sip_i_state(int status,
 
                                                        if ((b_private = nua_handle_magic(bnh))) {
                                                                char *br_b = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE);
-                                                               char *br_a = switch_core_session_get_uuid(b_private->session);
+                                                               char *br_a = b_private->uuid;
 
                                                                if (br_b) {
                                                                        switch_ivr_uuid_bridge(br_a, br_b);
@@ -2689,7 +2688,7 @@ static void sip_i_state(int status,
                                                        }
                                                        nua_handle_unref(bnh);
                                                }
-                                               return;
+                        goto done;
                                        }
 
                                        switch_channel_set_variable(channel, "endpoint_disposition", "NO CODECS");
@@ -2706,7 +2705,7 @@ static void sip_i_state(int status,
                if (tech_pvt && r_sdp) {
                        if (r_sdp) {
                                if (switch_test_flag(tech_pvt, TFLAG_NOMEDIA)) {
-                                       return;
+                    goto done;
                                } else {
                                        sdp_parser_t *parser = sdp_parse(tech_pvt->home, r_sdp, (int)strlen(r_sdp), 0);
                                        sdp_session_t *sdp;
@@ -2739,7 +2738,7 @@ static void sip_i_state(int status,
                        tech_pvt->nh2 = NULL;
                        tech_choose_port(tech_pvt);
                        activate_rtp(tech_pvt);
-                       return;
+                       goto done;
                }
 
                if (channel) {
@@ -2752,7 +2751,7 @@ static void sip_i_state(int status,
                                                switch_channel_answer(other_channel);
                                                switch_core_session_rwunlock(other_session);
                                        }
-                                       return;
+                                       goto done;
                                } else {
                                        sdp_parser_t *parser = sdp_parse(tech_pvt->home, r_sdp, (int)strlen(r_sdp), 0);
                                        sdp_session_t *sdp;
@@ -2775,7 +2774,7 @@ static void sip_i_state(int status,
                                                tech_choose_port(tech_pvt);
                                                activate_rtp(tech_pvt);
                         switch_channel_mark_answered(channel);
-                                               return;
+                                               goto done;
                                        }
                                        
                                        switch_channel_set_variable(channel, "endpoint_disposition", "NO CODECS");
@@ -2785,7 +2784,7 @@ static void sip_i_state(int status,
                                switch_set_flag_locked(tech_pvt, TFLAG_ANS);
                                switch_channel_set_variable(channel, "endpoint_disposition", "ANSWER");
                 switch_channel_mark_answered(channel);
-                               return;
+                               goto done;
                        } //else probably an ack
                }
                
@@ -2794,12 +2793,8 @@ static void sip_i_state(int status,
                break;
        case nua_callstate_terminated: 
                if (session) {
-                       if (switch_test_flag(tech_pvt, TFLAG_RWLOCK)) {
-                               switch_core_session_rwunlock(session);
-                               switch_clear_flag_locked(tech_pvt, TFLAG_RWLOCK);
-                       }
                        if (!switch_test_flag(tech_pvt, TFLAG_BYE)) {
-
+                
                                switch_set_flag_locked(tech_pvt, TFLAG_BYE);
                                if (switch_test_flag(tech_pvt, TFLAG_NOHUP)) {
                                        switch_clear_flag_locked(tech_pvt, TFLAG_NOHUP);
@@ -2812,18 +2807,25 @@ static void sip_i_state(int status,
 
             if (tech_pvt->sofia_private) {
                 free(tech_pvt->sofia_private);
-                nua_handle_bind(tech_pvt->nh, NULL);
                 tech_pvt->sofia_private = NULL;
             }
                        tech_pvt->nh = NULL;
-               }
+               } else if (sofia_private) {
+            free(sofia_private);
+        }
+
                if (nh) {
+            nua_handle_bind(nh, NULL);
                        nua_handle_destroy(nh);
                }
                break;
        }
-       
 
+ done:
+
+    if (session) {
+        switch_core_session_rwunlock(session);
+    }
 }
 
 
@@ -3532,7 +3534,7 @@ static void sip_r_subscribe(int status,
 static void sip_i_refer(nua_t *nua,
                                                sofia_profile_t *profile,
                                                nua_handle_t *nh,
-                                               sofia_private_t *sofia_private,
+                        switch_core_session_t *session,
                                                sip_t const *sip,
                                                tagi_t tags[])
 {
@@ -3540,273 +3542,254 @@ static void sip_i_refer(nua_t *nua,
        sip_from_t const *from;
        sip_to_t const *to;
        sip_refer_to_t const *refer_to;
-       switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
-
-       if (session) {
-               private_object_t *tech_pvt = NULL;
-               char *etmp = NULL, *exten = NULL;
-               switch_channel_t *channel_a = NULL, *channel_b = NULL;
+    private_object_t *tech_pvt = NULL;
+    char *etmp = NULL, *exten = NULL;
+    switch_channel_t *channel_a = NULL, *channel_b = NULL;
 
-               tech_pvt = switch_core_session_get_private(session);
-               channel_a = switch_core_session_get_channel(session);
+    tech_pvt = switch_core_session_get_private(session);
+    channel_a = switch_core_session_get_channel(session);
 
-               
-               if (!sip->sip_cseq || !(etmp = switch_mprintf("refer;id=%u", sip->sip_cseq->cs_seq))) {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
-                       goto done;
-               }
+    if (!sip->sip_cseq || !(etmp = switch_mprintf("refer;id=%u", sip->sip_cseq->cs_seq))) {
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
+        goto done;
+    }
 
 
-               if (switch_channel_test_flag(channel_a, CF_NOMEDIA)) {
-                       nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
-                                          SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden"),
-                                          SIPTAG_EVENT_STR(etmp),
-                                          TAG_END());
-                       goto done;
-               }
+    if (switch_channel_test_flag(channel_a, CF_NOMEDIA)) {
+        nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+                   SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden"),
+                   SIPTAG_EVENT_STR(etmp),
+                   TAG_END());
+        goto done;
+    }
                
-               from = sip->sip_from;
-               to = sip->sip_to;
+    from = sip->sip_from;
+    to = sip->sip_to;
 
-               if ((refer_to = sip->sip_refer_to)) {
-                       if (profile->pflags & PFLAG_FULL_ID) {
-                               exten = switch_mprintf("%s@%s", (char *) refer_to->r_url->url_user, (char *) refer_to->r_url->url_host);
-                       } else {
-                               exten = (char *) refer_to->r_url->url_user;
-                       }
+    if ((refer_to = sip->sip_refer_to)) {
+        if (profile->pflags & PFLAG_FULL_ID) {
+            exten = switch_mprintf("%s@%s", (char *) refer_to->r_url->url_user, (char *) refer_to->r_url->url_host);
+        } else {
+            exten = (char *) refer_to->r_url->url_user;
+        }
 
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Process REFER to [%s@%s]\n", exten, (char *) refer_to->r_url->url_host);
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Process REFER to [%s@%s]\n", exten, (char *) refer_to->r_url->url_host);
 
-                       if (refer_to->r_url->url_headers) {
-                               sip_replaces_t *replaces;
-                               nua_handle_t *bnh;
-                               char *rep;
+        if (refer_to->r_url->url_headers) {
+            sip_replaces_t *replaces;
+            nua_handle_t *bnh;
+            char *rep;
 
-                               if ((rep = strchr(refer_to->r_url->url_headers, '='))) {
-                                       char *br_a = NULL, *br_b = NULL;
-                                       char *buf;
-                                       rep++;
+            if ((rep = strchr(refer_to->r_url->url_headers, '='))) {
+                char *br_a = NULL, *br_b = NULL;
+                char *buf;
+                rep++;
 
                                        
 
-                                       if ((buf = switch_core_session_alloc(session, strlen(rep) + 1))) {
-                                               rep = url_unescape(buf, (const char *) rep); 
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Replaces: [%s]\n", rep);
-                                       } else {
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
-                                               goto done;
-                                       }
-                                       if ((replaces = sip_replaces_make(tech_pvt->home, rep)) && (bnh = nua_handle_by_replaces(nua, replaces))) {
-                                               sofia_private_t *b_private = NULL;
-                        private_object_t *tech_pvt_b = NULL;
-                                               switch_channel_set_variable(channel_a, SOFIA_REPLACES_HEADER, rep);     
-                                               if ((b_private = nua_handle_magic(bnh))) {
-                            tech_pvt_b = (private_object_t *) switch_core_session_get_private(b_private->session);
-                            channel_b = switch_core_session_get_channel(b_private->session);
+                if ((buf = switch_core_session_alloc(session, strlen(rep) + 1))) {
+                    rep = url_unescape(buf, (const char *) rep); 
+                    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Replaces: [%s]\n", rep);
+                } else {
+                    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
+                    goto done;
+                }
+                if ((replaces = sip_replaces_make(tech_pvt->home, rep)) && (bnh = nua_handle_by_replaces(nua, replaces))) {
+                    sofia_private_t *b_private = NULL;
+                    private_object_t *b_tech_pvt = NULL;
+                    switch_core_session_t *b_session = NULL;
+
+                    switch_channel_set_variable(channel_a, SOFIA_REPLACES_HEADER, rep);        
+                    if ((b_private = nua_handle_magic(bnh))) {
+                        if (!(b_session = switch_core_session_locate(b_private->uuid))) {
+                            goto done;
+                        }
+                        b_tech_pvt = (private_object_t *) switch_core_session_get_private(b_session);
+                        channel_b = switch_core_session_get_channel(b_session);
                                
-                                                       br_a = switch_channel_get_variable(channel_a, SWITCH_BRIDGE_VARIABLE);
-                                                       br_b = switch_channel_get_variable(channel_b, SWITCH_BRIDGE_VARIABLE);
+                        br_a = switch_channel_get_variable(channel_a, SWITCH_BRIDGE_VARIABLE);
+                        br_b = switch_channel_get_variable(channel_b, SWITCH_BRIDGE_VARIABLE);
 
-                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Attended Transfer [%s][%s]\n", br_a, br_b);
-                            
-                            if (switch_test_flag(tech_pvt, TFLAG_RWLOCK)) {
-                                switch_core_session_rwunlock(tech_pvt->session);
-                                switch_clear_flag_locked(tech_pvt, TFLAG_RWLOCK);
-                            }
-                            if (switch_test_flag(tech_pvt_b, TFLAG_RWLOCK)) {
-                                switch_core_session_rwunlock(tech_pvt_b->session);
-                                switch_clear_flag_locked(tech_pvt_b, TFLAG_RWLOCK);
-                            }
-    
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Attended Transfer [%s][%s]\n", br_a, br_b);
                             
-                                                       if (br_a && br_b) {
-                                                               switch_ivr_uuid_bridge(br_a, br_b);
-                                                               switch_channel_set_variable(channel_b, "endpoint_disposition", "ATTENDED_TRANSFER");
-                                switch_set_flag_locked(tech_pvt, TFLAG_BYE);
-                                                               nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
-                                                                                  SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
-                                                                                  SIPTAG_EVENT_STR(etmp),
-                                                                                  TAG_END());
+                        if (br_a && br_b) {
+                            switch_ivr_uuid_bridge(br_a, br_b);
+                            switch_channel_set_variable(channel_b, "endpoint_disposition", "ATTENDED_TRANSFER");
+                            switch_set_flag_locked(tech_pvt, TFLAG_BYE);
+                            switch_set_flag_locked(b_tech_pvt, TFLAG_BYE);
+                            nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+                                       SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
+                                       SIPTAG_EVENT_STR(etmp),
+                                       TAG_END());
                                 
-                                                       } else {
-                                if (!br_a && !br_b) {
-                                                                       switch_set_flag_locked(tech_pvt, TFLAG_NOHUP);
-                                                                       switch_set_flag_locked(tech_pvt_b, TFLAG_XFER);
-                                                                       tech_pvt_b->xferto = switch_core_session_strdup(b_private->session, switch_core_session_get_uuid(session));
-                                                               } else if (!br_a && br_b) {
-                                                                       switch_core_session_t *bsession;
-
-                                                                       if ((bsession = switch_core_session_locate(br_b))) {
-                                                                               private_object_t *b_tech_pvt = switch_core_session_get_private(bsession);
-                                                                               switch_channel_t *b_channel = switch_core_session_get_channel(bsession);
-                                                                               private_object_t *bp_tech_pvt = switch_core_session_get_private(b_private->session);
-
-                                                                               switch_core_session_get_uuid(b_private->session);
-                                                                               switch_set_flag_locked(tech_pvt, TFLAG_NOHUP);
+                        } else {
+                            if (!br_a && !br_b) {
+                                switch_set_flag_locked(tech_pvt, TFLAG_NOHUP);
+                                switch_set_flag_locked(b_tech_pvt, TFLAG_XFER);
+                                b_tech_pvt->xferto = switch_core_session_strdup(b_session, switch_core_session_get_uuid(session));
+                            } else if (!br_a && br_b) {
+                                switch_core_session_t *br_b_session;
+
+                                if ((br_b_session = switch_core_session_locate(br_b))) {
+                                    private_object_t *br_b_tech_pvt = switch_core_session_get_private(br_b_session);
+                                    switch_channel_t *br_b_channel = switch_core_session_get_channel(br_b_session);
+                                    
+                                    switch_set_flag_locked(tech_pvt, TFLAG_NOHUP);
                                                                                
-                                                                               switch_channel_clear_state_handler(b_channel, NULL);
-                                                                               switch_channel_set_state_flag(b_channel, CF_TRANSFER);
-                                                                               switch_channel_set_state(b_channel, CS_TRANSMIT);
+                                    switch_channel_clear_state_handler(br_b_channel, NULL);
+                                    switch_channel_set_state_flag(br_b_channel, CF_TRANSFER);
+                                    switch_channel_set_state(br_b_channel, CS_TRANSMIT);
 
-                                                                               switch_set_flag_locked(tech_pvt, TFLAG_REINVITE);
-                                                                               tech_pvt->local_sdp_audio_ip = switch_core_session_strdup(session, bp_tech_pvt->local_sdp_audio_ip);
-                                                                               tech_pvt->local_sdp_audio_port = bp_tech_pvt->local_sdp_audio_port;
+                                    switch_set_flag_locked(tech_pvt, TFLAG_REINVITE);
+                                    tech_pvt->local_sdp_audio_ip = switch_core_session_strdup(session, b_tech_pvt->local_sdp_audio_ip);
+                                    tech_pvt->local_sdp_audio_port = b_tech_pvt->local_sdp_audio_port;
 
-                                                                               tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(session, b_tech_pvt->remote_sdp_audio_ip);
-                                                                               tech_pvt->remote_sdp_audio_port = b_tech_pvt->remote_sdp_audio_port;
-                                                                               activate_rtp(tech_pvt);
+                                    tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(session, br_b_tech_pvt->remote_sdp_audio_ip);
+                                    tech_pvt->remote_sdp_audio_port = br_b_tech_pvt->remote_sdp_audio_port;
+                                    activate_rtp(tech_pvt);
        
-                                                                               b_tech_pvt->kick = switch_core_session_strdup(bsession, switch_core_session_get_uuid(session));
+                                    br_b_tech_pvt->kick = switch_core_session_strdup(br_b_session, switch_core_session_get_uuid(session));
                                                                                
 
-                                                                               switch_core_session_rwunlock(bsession);
-                                                                       }
-
-                                                                       switch_channel_hangup(channel_b, SWITCH_CAUSE_ATTENDED_TRANSFER);
-                                                               }
-                                switch_set_flag_locked(tech_pvt, TFLAG_BYE);
-                                                               nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
-                                                                                  SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
-                                                                                  SIPTAG_EVENT_STR(etmp),
-                                                                                  TAG_END());
+                                    switch_core_session_rwunlock(br_b_session);
+                                }
 
-                                                       }
-                                               }
-                                               nua_handle_unref(bnh);
-                                       } else { /* the other channel is on a different box, we have to go find them */
-                                               if (exten && (br_a = switch_channel_get_variable(channel_a, SWITCH_BRIDGE_VARIABLE))) {
-                                                       switch_core_session_t *asession;
-                                                       switch_channel_t *channel = switch_core_session_get_channel(session);
+                                switch_channel_hangup(channel_b, SWITCH_CAUSE_ATTENDED_TRANSFER);
+                            }
+                            switch_set_flag_locked(tech_pvt, TFLAG_BYE);
+                            nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+                                       SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
+                                       SIPTAG_EVENT_STR(etmp),
+                                       TAG_END());
+
+                        }
+                        if (b_session) {
+                            switch_core_session_rwunlock(b_session);
+                        }
+                    }
+                    nua_handle_unref(bnh);
+                } else { /* the other channel is on a different box, we have to go find them */
+                    if (exten && (br_a = switch_channel_get_variable(channel_a, SWITCH_BRIDGE_VARIABLE))) {
+                        switch_core_session_t *a_session;
+                        switch_channel_t *channel = switch_core_session_get_channel(session);
                                                        
-                                                       if ((asession = switch_core_session_locate(br_a))) {
-                                                               switch_core_session_t *tsession;
-                                                               switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
-                                                               uint32_t timeout = 60;
-                                                               char *tuuid_str;
-
-                                                               channel = switch_core_session_get_channel(asession);
-
-                                                               exten = switch_mprintf("sofia/%s/%s@%s:%s", 
-                                                                                                                          profile->name,
-                                                                                                                          (char *) refer_to->r_url->url_user,
-                                                                                                                          (char *) refer_to->r_url->url_host,
-                                                                                                                          refer_to->r_url->url_port
-                                                                                                                          );
-
-                                                               switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, rep);
+                        if ((a_session = switch_core_session_locate(br_a))) {
+                            switch_core_session_t *tsession;
+                            switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
+                            uint32_t timeout = 60;
+                            char *tuuid_str;
+
+                            channel = switch_core_session_get_channel(a_session);
+
+                            exten = switch_mprintf("sofia/%s/%s@%s:%s", 
+                                                   profile->name,
+                                                   (char *) refer_to->r_url->url_user,
+                                                   (char *) refer_to->r_url->url_host,
+                                                   refer_to->r_url->url_port
+                                                   );
+
+                            switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, rep);
                                                                
-                                                               if (switch_ivr_originate(asession,
-                                                                                                                &tsession,
-                                                                                                                &cause,
-                                                                                                                exten,
-                                                                                                                timeout,
-                                                                                                                &noop_state_handler,
-                                                                                                                NULL,
-                                                                                                                NULL,
-                                                                                                                NULL) != SWITCH_STATUS_SUCCESS) {
-                                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel! [%s]\n", exten);
-                                                                       nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
-                                                                                          SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden"),
-                                                                                          SIPTAG_EVENT_STR(etmp),
-                                                                                          TAG_END());
-                                                                       goto done;
-                                                               } 
-
-                                                               switch_core_session_rwunlock(asession);
-                                                               tuuid_str = switch_core_session_get_uuid(tsession);
-                                                               switch_ivr_uuid_bridge(br_a, tuuid_str);
-                                                               switch_channel_set_variable(channel_a, "endpoint_disposition", "ATTENDED_TRANSFER");
-                                switch_set_flag_locked(tech_pvt, TFLAG_BYE);
-                                if (switch_test_flag(tech_pvt, TFLAG_RWLOCK)) {
-                                    switch_core_session_rwunlock(tech_pvt->session);
-                                    switch_clear_flag_locked(tech_pvt, TFLAG_RWLOCK);
-                                }
-                                                               nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
-                                                                                  SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
-                                                                                  SIPTAG_EVENT_STR(etmp),
-                                                                                  TAG_END());
-                                                       } else {
-                                                               goto error;
-                                                       }
-
-                                               } else { error:
-                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Transfer! [%s]\n", br_a);
-                                                       switch_channel_set_variable(channel_a, "endpoint_disposition", "ATTENDED_TRANSFER_ERROR");
-                                                       nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
-                                                                          SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden"),
-                                                                          SIPTAG_EVENT_STR(etmp),
-                                                                          TAG_END());
-                                               }
-                                       }
-                               } else {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot parse Replaces!\n");
-                               }
-                               goto done;
-                       }
+                            if (switch_ivr_originate(a_session,
+                                                     &tsession,
+                                                     &cause,
+                                                     exten,
+                                                     timeout,
+                                                     &noop_state_handler,
+                                                     NULL,
+                                                     NULL,
+                                                     NULL) != SWITCH_STATUS_SUCCESS) {
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel! [%s]\n", exten);
+                                nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+                                           SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden"),
+                                           SIPTAG_EVENT_STR(etmp),
+                                           TAG_END());
+                                goto done;
+                            } 
+
+                            switch_core_session_rwunlock(a_session);
+                            tuuid_str = switch_core_session_get_uuid(tsession);
+                            switch_ivr_uuid_bridge(br_a, tuuid_str);
+                            switch_channel_set_variable(channel_a, "endpoint_disposition", "ATTENDED_TRANSFER");
+                            switch_set_flag_locked(tech_pvt, TFLAG_BYE);
+                            nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+                                       SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
+                                       SIPTAG_EVENT_STR(etmp),
+                                       TAG_END());
+                        } else {
+                            goto error;
+                        }
+
+                    } else { error:
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Transfer! [%s]\n", br_a);
+                        switch_channel_set_variable(channel_a, "endpoint_disposition", "ATTENDED_TRANSFER_ERROR");
+                        nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+                                   SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden"),
+                                   SIPTAG_EVENT_STR(etmp),
+                                   TAG_END());
+                    }
+                }
+            } else {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot parse Replaces!\n");
+            }
+            goto done;
+        }
 
-               } else {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Refer-To\n");
-                       goto done;
-               }
+    } else {
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Refer-To\n");
+        goto done;
+    }
 
-               if (exten) {
-                       switch_channel_t *channel = switch_core_session_get_channel(session);
-                       char *br;
+    if (exten) {
+        switch_channel_t *channel = switch_core_session_get_channel(session);
+        char *br;
                                
-                       if ((br = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE))) {
-                               switch_core_session_t *bsession;
+        if ((br = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE))) {
+            switch_core_session_t *b_session;
                                
-                               if ((bsession = switch_core_session_locate(br))) {
-                                       switch_channel_set_variable(channel, "TRANSFER_FALLBACK", (char *) from->a_user);
-                                       switch_ivr_session_transfer(bsession, exten, profile->dialplan, profile->context);
-                                       switch_core_session_rwunlock(bsession);
-                               
+            if ((b_session = switch_core_session_locate(br))) {
+                switch_channel_set_variable(channel, "TRANSFER_FALLBACK", (char *) from->a_user);
+                switch_ivr_session_transfer(b_session, exten, profile->dialplan, profile->context);
+                switch_core_session_rwunlock(b_session);
+            } 
 
-                               switch_channel_set_variable(channel, "endpoint_disposition", "BLIND_TRANSFER");
+            switch_channel_set_variable(channel, "endpoint_disposition", "BLIND_TRANSFER");
                 
-                /*
-                               nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
-                                                  SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
-                                                  SIPTAG_EVENT_STR(etmp),
-                                                  TAG_END());
-                */
-                if (switch_test_flag(tech_pvt, TFLAG_RWLOCK)) {
-                    switch_core_session_rwunlock(tech_pvt->session);
-                    switch_clear_flag_locked(tech_pvt, TFLAG_RWLOCK);
-                }
-                       } else {
-                               exten = switch_mprintf("sip:%s@%s:%s", 
-                                                                                          (char *) refer_to->r_url->url_user,
-                                                                                          (char *) refer_to->r_url->url_host,
-                                                                                          refer_to->r_url->url_port);
-                               tech_pvt->dest = switch_core_session_strdup(session, exten);
+            /*
+              nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+              SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
+              SIPTAG_EVENT_STR(etmp),
+              TAG_END());
+            */
+        } else {
+            exten = switch_mprintf("sip:%s@%s:%s", 
+                                   (char *) refer_to->r_url->url_user,
+                                   (char *) refer_to->r_url->url_host,
+                                   refer_to->r_url->url_port);
+            tech_pvt->dest = switch_core_session_strdup(session, exten);
                                
                                
-                               switch_set_flag_locked(tech_pvt, TFLAG_NOHUP);
-
-                /*
-                               nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
-                                                  SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
-                                                  SIPTAG_EVENT_STR(etmp),
-                                                  TAG_END());
-                */
-                if (switch_test_flag(tech_pvt, TFLAG_RWLOCK)) {
-                    switch_core_session_rwunlock(tech_pvt->session);
-                    switch_clear_flag_locked(tech_pvt, TFLAG_RWLOCK);
-                }
-                               do_xfer_invite(session);
+            switch_set_flag_locked(tech_pvt, TFLAG_NOHUP);
 
-                       }
-               }
+            /*
+              nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+              SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
+              SIPTAG_EVENT_STR(etmp),
+              TAG_END());
+            */
+            do_xfer_invite(session);
 
-       done:
-               if (exten && strchr(exten, '@')) {
-                       switch_safe_free(exten);
-               }
-               if (etmp) {
-                       switch_safe_free(etmp);
-               }
-       }
+        }
+    }
+
+ done:
+    if (exten && strchr(exten, '@')) {
+        switch_safe_free(exten);
+    }
+    if (etmp) {
+        switch_safe_free(etmp);
+    }
+       
 
 }
 
@@ -3977,251 +3960,249 @@ static void sip_i_invite(nua_t *nua,
                                                 sip_t const *sip,
                                                 tagi_t tags[])
 {
-       switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
+       switch_core_session_t *session = NULL;
        char key[128] = "";
        sip_unknown_t *un;
+    private_object_t *tech_pvt = NULL;
+    switch_channel_t *channel = NULL;
+    sip_from_t const *from = sip->sip_from;
+    sip_to_t const *to = sip->sip_to;
+    char *displayname;
+    char *username, *to_username = NULL;
+    char *url_user = (char *) from->a_url->url_user;
+    char *to_user, *to_host, *to_port;
+    char *req_user, *req_host, *req_port;
+    char *contact_user, *contact_host, *contact_port;
+    char *via_rport, *via_host, *via_port;
+    char *from_port;
+    char uri[1024];
 
-
-       if (!session) {
                
-               if ((profile->pflags & PFLAG_AUTH_CALLS)) {
-                       if (handle_register(nua, profile, nh, sip, REG_INVITE, key, sizeof(key))) {
-                               return;
-                       }
-               }
+    if ((profile->pflags & PFLAG_AUTH_CALLS)) {
+        if (handle_register(nua, profile, nh, sip, REG_INVITE, key, sizeof(key))) {
+            return;
+        }
+    }
 
-               if ((session = switch_core_session_request(&sofia_endpoint_interface, NULL))) {
-                       private_object_t *tech_pvt = NULL;
-                       switch_channel_t *channel = NULL;
-                       sip_from_t const *from = sip->sip_from;
-                       sip_to_t const *to = sip->sip_to;
-                       char *displayname;
-                       char *username, *to_username = NULL;
-                       char *url_user = (char *) from->a_url->url_user;
-                       char *to_user, *to_host, *to_port;
-            char *req_user, *req_host, *req_port;
-            char *contact_user, *contact_host, *contact_port;
-            char *via_rport, *via_host, *via_port;
-            char *from_port;
-            char uri[1024];
-
-                       if (!(tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)))) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
-                               terminate_session(&session, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
-                               return;
-                       }
+    if (!(session = switch_core_session_request(&sofia_endpoint_interface, NULL))) {
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Session Alloc Failed!\n");
+        return;
+    }
 
-                       if (!switch_strlen_zero(key)) {
-                               tech_pvt->key = switch_core_session_strdup(session, key);
-                       }
+    if (!(tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)))) {
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
+        terminate_session(&session, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
+        return;
+    }
 
-                       to_user = (char *) to->a_url->url_user;
-                       to_host = (char *) to->a_url->url_host;
-                       if (!(to_port = (char *) to->a_url->url_port)) {
-                               to_port = "5060";
-                       }
+    if (!switch_strlen_zero(key)) {
+        tech_pvt->key = switch_core_session_strdup(session, key);
+    }
+
+    to_user = (char *) to->a_url->url_user;
+    to_host = (char *) to->a_url->url_host;
+    if (!(to_port = (char *) to->a_url->url_port)) {
+        to_port = "5060";
+    }
                        
-                       if (switch_strlen_zero(to_user)) { /* if sofia doesnt parse the To: right, we'll have to do it */
-                               if ((to_user = sip_header_as_string(tech_pvt->home, (sip_header_t *) to))) {
-                                       char *p;
-                                       if (*to_user == '<') {
-                                               to_user++;
-                                       }
-                                       if ((p = strchr((to_user += 4), '@'))) {
-                                               *p++ = '\0';
-                                               to_host = p;
-                                               if ((p = strchr(to_host, '>'))) {
-                                                       *p = '\0';
-                                               }
-                                       }
-                               }
-                       }
+    if (switch_strlen_zero(to_user)) { /* if sofia doesnt parse the To: right, we'll have to do it */
+        if ((to_user = sip_header_as_string(tech_pvt->home, (sip_header_t *) to))) {
+            char *p;
+            if (*to_user == '<') {
+                to_user++;
+            }
+            if ((p = strchr((to_user += 4), '@'))) {
+                *p++ = '\0';
+                to_host = p;
+                if ((p = strchr(to_host, '>'))) {
+                    *p = '\0';
+                }
+            }
+        }
+    }
 
-                       if (switch_strlen_zero(url_user)) {
-                               url_user = "service";
-                       }
+    if (switch_strlen_zero(url_user)) {
+        url_user = "service";
+    }
                        
-                       if (!switch_strlen_zero(from->a_display)) {
-                               displayname = switch_core_session_strdup(session, (char *) from->a_display);
-                               if (*displayname == '"') {
-                                       char *p;
+    if (!switch_strlen_zero(from->a_display)) {
+        displayname = switch_core_session_strdup(session, (char *) from->a_display);
+        if (*displayname == '"') {
+            char *p;
                                
-                                       displayname++;
-                                       if ((p = strchr(displayname, '"'))) {
-                                               *p = '\0';
-                                       }
-                               }
-                       } else {
-                               displayname = url_user;
-                       }
+            displayname++;
+            if ((p = strchr(displayname, '"'))) {
+                *p = '\0';
+            }
+        }
+    } else {
+        displayname = url_user;
+    }
                        
-                       if (!(username = switch_mprintf("%s@%s", url_user, (char *) from->a_url->url_host))) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
-                               return;
-                       }
+    if (!(username = switch_mprintf("%s@%s", url_user, (char *) from->a_url->url_host))) {
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+        return;
+    }
 
-                       if (profile->pflags & PFLAG_FULL_ID)  {
-                               if (!(to_username = switch_mprintf("%s@%s:%s", (char *) to_user, (char *) to_host, to_port))) {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
-                                       switch_safe_free(username);
-                                       return;
-                               }
-                       }
+    if (profile->pflags & PFLAG_FULL_ID)  {
+        if (!(to_username = switch_mprintf("%s@%s:%s", (char *) to_user, (char *) to_host, to_port))) {
+            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+            switch_safe_free(username);
+            return;
+        }
+    }
 
-                       attach_private(session, profile, tech_pvt, username);
-                       switch_core_session_read_lock(session);
-                       switch_set_flag(tech_pvt, TFLAG_RWLOCK);
-                       channel = switch_core_session_get_channel(session);
-                       switch_channel_set_variable(channel, "endpoint_disposition", "INBOUND CALL");
-                       set_chat_hash(tech_pvt, sip);
+    attach_private(session, profile, tech_pvt, username);
+    channel = switch_core_session_get_channel(session);
+    switch_channel_set_variable(channel, "endpoint_disposition", "INBOUND CALL");
+    set_chat_hash(tech_pvt, sip);
                        
-                       switch_channel_set_variable(channel, "sip_from_user", (char *) from->a_url->url_user);
-                       if (from->a_url->url_user && *from->a_url->url_user == '+') {
-                               switch_channel_set_variable(channel, "sip_from_user_stripped", (char *)(from->a_url->url_user+1));
-                       } else {
-                               switch_channel_set_variable(channel, "sip_from_user_stripped", (char *)from->a_url->url_user);
-                       }
-                       switch_channel_set_variable(channel, "sip_from_host", (char *) from->a_url->url_host);
+    switch_channel_set_variable(channel, "sip_from_user", (char *) from->a_url->url_user);
+    if (from->a_url->url_user && *from->a_url->url_user == '+') {
+        switch_channel_set_variable(channel, "sip_from_user_stripped", (char *)(from->a_url->url_user+1));
+    } else {
+        switch_channel_set_variable(channel, "sip_from_user_stripped", (char *)from->a_url->url_user);
+    }
+    switch_channel_set_variable(channel, "sip_from_host", (char *) from->a_url->url_host);
 
             
-            if (!(from_port = (char *) from->a_url->url_port)) {
-                from_port = "5060";
-            }
+    if (!(from_port = (char *) from->a_url->url_port)) {
+        from_port = "5060";
+    }
 
-                       switch_channel_set_variable(channel, "sip_from_port", from_port);
+    switch_channel_set_variable(channel, "sip_from_port", from_port);
 
 
-            snprintf(uri, sizeof(uri), "%s@%s:%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host, from_port);
-            switch_channel_set_variable(channel, "sip_from_uri", uri);
+    snprintf(uri, sizeof(uri), "%s@%s:%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host, from_port);
+    switch_channel_set_variable(channel, "sip_from_uri", uri);
             
             
-                       switch_channel_set_variable(channel, "sip_to_user", to_user);
-                       switch_channel_set_variable(channel, "sip_to_host", to_host);
-                       switch_channel_set_variable(channel, "sip_to_port", to_port);
+    switch_channel_set_variable(channel, "sip_to_user", to_user);
+    switch_channel_set_variable(channel, "sip_to_host", to_host);
+    switch_channel_set_variable(channel, "sip_to_port", to_port);
 
-            snprintf(uri, sizeof(uri), "%s@%s:%s", to_user, to_host, to_port);
-            switch_channel_set_variable(channel, "sip_to_uri", uri);
+    snprintf(uri, sizeof(uri), "%s@%s:%s", to_user, to_host, to_port);
+    switch_channel_set_variable(channel, "sip_to_uri", uri);
 
 
-            req_user = (char *) sip->sip_request->rq_url->url_user;
-            req_host = (char *) sip->sip_request->rq_url->url_host;
-            if (!(req_port = (char *) sip->sip_request->rq_url->url_port)) {
-                req_port = "5060";
-            }
+    req_user = (char *) sip->sip_request->rq_url->url_user;
+    req_host = (char *) sip->sip_request->rq_url->url_host;
+    if (!(req_port = (char *) sip->sip_request->rq_url->url_port)) {
+        req_port = "5060";
+    }
             
-                       switch_channel_set_variable(channel, "sip_req_user", req_user);
-                       switch_channel_set_variable(channel, "sip_req_host", req_host);
-                       switch_channel_set_variable(channel, "sip_req_port", req_port);
-
-            contact_user = (char *) sip->sip_contact->m_url->url_user;
-            contact_host = (char *) sip->sip_contact->m_url->url_host;
-            if (!(contact_port = (char *) sip->sip_contact->m_url->url_port)) {
-                contact_port = "5060";
-            }
+    switch_channel_set_variable(channel, "sip_req_user", req_user);
+    switch_channel_set_variable(channel, "sip_req_host", req_host);
+    switch_channel_set_variable(channel, "sip_req_port", req_port);
+
+    contact_user = (char *) sip->sip_contact->m_url->url_user;
+    contact_host = (char *) sip->sip_contact->m_url->url_host;
+    if (!(contact_port = (char *) sip->sip_contact->m_url->url_port)) {
+        contact_port = "5060";
+    }
             
-                       switch_channel_set_variable(channel, "sip_contact_user", contact_user);
-                       switch_channel_set_variable(channel, "sip_contact_host", contact_host);
-                       switch_channel_set_variable(channel, "sip_contact_port", contact_port);
+    switch_channel_set_variable(channel, "sip_contact_user", contact_user);
+    switch_channel_set_variable(channel, "sip_contact_host", contact_host);
+    switch_channel_set_variable(channel, "sip_contact_port", contact_port);
 
-            via_host = (char *) sip->sip_via->v_host;
-            if (!(via_port = (char *) sip->sip_via->v_port)) {
-                via_port = "5060";
-            }
-            if (!(via_rport = (char *) sip->sip_via->v_rport)) {
-                via_rport = "5060";
-            }
+    via_host = (char *) sip->sip_via->v_host;
+    if (!(via_port = (char *) sip->sip_via->v_port)) {
+        via_port = "5060";
+    }
+    if (!(via_rport = (char *) sip->sip_via->v_rport)) {
+        via_rport = "5060";
+    }
             
-                       switch_channel_set_variable(channel, "sip_via_host", via_host);
-                       switch_channel_set_variable(channel, "sip_via_port", via_port);
-                       switch_channel_set_variable(channel, "sip_via_rport", via_rport);
+    switch_channel_set_variable(channel, "sip_via_host", via_host);
+    switch_channel_set_variable(channel, "sip_via_port", via_port);
+    switch_channel_set_variable(channel, "sip_via_rport", via_rport);
 
             
-            snprintf(uri, sizeof(uri), "%s@%s:%s", req_user, req_host, req_port);
-            switch_channel_set_variable(channel, "sip_req_uri", uri);
-
-
-                       if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
-                                                                                                                                         (char *) from->a_url->url_user,
-                                                                                                                                         profile->dialplan,
-                                                                                                                                         displayname,
-                                                                                                                                         (char *) from->a_url->url_user,
-                                                                                                                                         (char *) from->a_url->url_host,
-                                                                                                                                         NULL,
-                                                                                                                                         NULL,
-                                                                                                                                         NULL,
-                                                                                                                                         (char *)modname,
-                                                                                                                                         (profile->context && !strcasecmp(profile->context, "_domain_")) ? 
-                                                                                                                                         (char *) from->a_url->url_host : profile->context,
-                                                                                                                                         to_username ? to_username : (char *) to_user
-                                                                                                                                         )) != 0) {
-                               
-                               
-                               for (un=sip->sip_unknown; un; un=un->un_next) {
-                                       if (!strncasecmp(un->un_name, "Alert-Info", 10)) {
-                                               if (!switch_strlen_zero(un->un_value)) { 
-                                                       switch_channel_set_variable(channel, "alert_info", (char *)un->un_value);
-                                               }
-                                       // Loop thru Known Headers Here so we can do something with them
-                                       } else if (!strncasecmp(un->un_name, "Remote-Party-ID", 15)) {
-                                               int argc, x, screen = 1;
-                                               char *mydata, *argv[10] = { 0 };
-                                               if (!switch_strlen_zero(un->un_value)) { 
-                                                       if ((mydata = strdup(un->un_value))) {
-                                                               argc = switch_separate_string(mydata, ';', argv, (sizeof(argv) / sizeof(argv[0]))); 
-
-                                                               // Do We really need this at this time 
-                                                               // clid_uri = argv[0];
-
-                                                               for (x=1; x < argc && argv[x]; x++){
-                                                                       // we dont need to do anything with party yet we should only be seeing party=calling here anyway
-                                                                       // maybe thats a dangerous assumption bit oh well yell at me later
-                                                                       // if (!strncasecmp(argv[x], "party", 5)) {
-                                                                       //      party = argv[x];
-                                                                       // } else 
-                                                                       if (!strncasecmp(argv[x], "privacy=", 8)) {
-                                                                               char *arg = argv[x] + 9;
-
-                                                                               if (!strcasecmp(arg, "yes")) {
-                                                                                       switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
-                                                                               } else if (!strcasecmp(arg, "full")) {
-                                                                                       switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
-                                                                               } else if (!strcasecmp(arg, "name")) {
-                                                                                       switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME);
-                                                                               } else if (!strcasecmp(arg, "number")) {
-                                                                                       switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER);
-                                                                               } else {
-                                                                                       switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME);
-                                                                                       switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER);
-                                                                               }
-
-                                                                       } else if (!strncasecmp(argv[x], "screen=", 7) && screen > 0) {
-                                                                               char *arg = argv[x] + 8;
-                                                                               if (!strcasecmp(arg, "no")) {
-                                                                                       screen = 0;
-                                                                                       switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_SCREEN);
-                                                                               }
-                                                                       }
-                                                               }
-                                                               free(mydata);
-                                                       }
-                                               }
-                                               break;
-                                       }
-                               }
+    snprintf(uri, sizeof(uri), "%s@%s:%s", req_user, req_host, req_port);
+    switch_channel_set_variable(channel, "sip_req_uri", uri);
+
+
+    if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
+                                                              (char *) from->a_url->url_user,
+                                                              profile->dialplan,
+                                                              displayname,
+                                                              (char *) from->a_url->url_user,
+                                                              (char *) from->a_url->url_host,
+                                                              NULL,
+                                                              NULL,
+                                                              NULL,
+                                                              (char *)modname,
+                                                              (profile->context && !strcasecmp(profile->context, "_domain_")) ? 
+                                                              (char *) from->a_url->url_host : profile->context,
+                                                              to_username ? to_username : (char *) to_user
+                                                              )) != 0) {
 
-                               switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
-                               switch_safe_free(username);
-                               switch_safe_free(to_username);
-                       }
+                               
+        for (un=sip->sip_unknown; un; un=un->un_next) {
+            if (!strncasecmp(un->un_name, "Alert-Info", 10)) {
+                if (!switch_strlen_zero(un->un_value)) { 
+                    switch_channel_set_variable(channel, "alert_info", (char *)un->un_value);
+                }
+                // Loop thru Known Headers Here so we can do something with them
+            } else if (!strncasecmp(un->un_name, "Remote-Party-ID", 15)) {
+                int argc, x, screen = 1;
+                char *mydata, *argv[10] = { 0 };
+                if (!switch_strlen_zero(un->un_value)) { 
+                    if ((mydata = strdup(un->un_value))) {
+                        argc = switch_separate_string(mydata, ';', argv, (sizeof(argv) / sizeof(argv[0]))); 
+
+                        // Do We really need this at this time 
+                        // clid_uri = argv[0];
+
+                        for (x=1; x < argc && argv[x]; x++){
+                            // we dont need to do anything with party yet we should only be seeing party=calling here anyway
+                            // maybe thats a dangerous assumption bit oh well yell at me later
+                            // if (!strncasecmp(argv[x], "party", 5)) {
+                            // party = argv[x];
+                            // } else 
+                            if (!strncasecmp(argv[x], "privacy=", 8)) {
+                                char *arg = argv[x] + 9;
+
+                                if (!strcasecmp(arg, "yes")) {
+                                    switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
+                                } else if (!strcasecmp(arg, "full")) {
+                                    switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
+                                } else if (!strcasecmp(arg, "name")) {
+                                    switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME);
+                                } else if (!strcasecmp(arg, "number")) {
+                                    switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER);
+                                } else {
+                                    switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME);
+                                    switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER);
+                                }
 
-            if (!(tech_pvt->sofia_private = malloc(sizeof(*tech_pvt->sofia_private)))) {
-                abort();
+                            } else if (!strncasecmp(argv[x], "screen=", 7) && screen > 0) {
+                                char *arg = argv[x] + 8;
+                                if (!strcasecmp(arg, "no")) {
+                                    screen = 0;
+                                    switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_SCREEN);
+                                }
+                            }
+                        }
+                        free(mydata);
+                    }
+                }
+                break;
             }
-            memset(tech_pvt->sofia_private, 0, sizeof(*tech_pvt->sofia_private));
-                       tech_pvt->sofia_private->session = session;
-                       nua_handle_bind(nh, tech_pvt->sofia_private);
-               }
-       }
+        }
+
+        switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
+        switch_safe_free(username);
+        switch_safe_free(to_username);
+    }
+
+    if (!(tech_pvt->sofia_private = malloc(sizeof(*tech_pvt->sofia_private)))) {
+        abort();
+    }
+    memset(tech_pvt->sofia_private, 0, sizeof(*tech_pvt->sofia_private));
+    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);
+
 }
 
 static void sip_i_register(nua_t *nua,
@@ -4273,17 +4254,16 @@ static void sip_r_register(int status,
 }
 
 static void sip_r_challenge(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[])
+                            char const *phrase,
+                            nua_t *nua,
+                            sofia_profile_t *profile,
+                            nua_handle_t *nh,
+                            switch_core_session_t *session,
+                            sip_t const *sip,
+                            tagi_t tags[])
 {
        outbound_reg_t *oreg = NULL;
        sip_www_authenticate_t const *authenticate = NULL;
-       switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
        char const *realm = NULL; 
        char *p = NULL, *duprealm = NULL, *qrealm = NULL;
        char const *scheme = NULL;
@@ -4386,16 +4366,19 @@ static void event_callback(nua_event_t event,
 {
        struct private_object *tech_pvt = NULL;
        auth_res_t auth_res = AUTH_FORBIDDEN;
-       switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
+       switch_core_session_t *session = NULL;
        
+    if (sofia_private) {
+        if (!switch_strlen_zero(sofia_private->uuid)) {
 
-       if (session) {
-               if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
-                       /* too late */
-                       return;
-               }
-               tech_pvt = switch_core_session_get_private(session);
-       }
+            if ((session = switch_core_session_locate(sofia_private->uuid))) {
+                tech_pvt = switch_core_session_get_private(session);
+            } else {
+                /* too late */
+                return;            
+            }
+        }
+    }
 
        if (status != 100 && status != 200) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "event [%s] status [%d][%s] session: %s\n",
@@ -4432,122 +4415,73 @@ static void event_callback(nua_event_t event,
        }
 
        if (sip && (status == 401 || status == 407)) {
-               sip_r_challenge(status, phrase, nua, profile, nh, sofia_private, sip, tags);
+               sip_r_challenge(status, phrase, nua, profile, nh, session, sip, tags);
                goto done;
        }
        
        switch (event) {
        case nua_r_shutdown:    
-               //sip_r_shutdown(status, phrase, nua, profile, nh, sofia_private, sip, tags);
-               break;
-
        case nua_r_get_params:    
-               //sip_r_get_params(status, phrase, nua, profile, nh, sofia_private, sip, tags);
-               break;
-
        case nua_r_invite:
-               break;
-
+        break;
        case nua_r_register:
                sip_r_register(status, phrase, nua, profile, nh, sofia_private, sip, tags);
                break;
-    
-       case nua_r_unregister:
-               //sip_r_unregister(status, phrase, nua, profile, nh, sofia_private, sip, tags);
+    case nua_r_unregister:
                break;
-    
-       case nua_r_options:
-               //sip_r_options(status, phrase, nua, profile, nh, sofia_private, sip, tags);
+    case nua_r_options:
                break;
-
        case nua_i_options:
                sip_i_options(status, phrase, nua, profile, nh, sofia_private, sip, tags);
                break;
-
        case nua_i_fork:
-               //sip_i_fork(status, phrase, nua, profile, nh, sofia_private, sip, tags);
                break;
-    
-       case nua_i_invite:
-               sip_i_invite(nua, profile, nh, sofia_private, sip, tags);
+    case nua_i_invite:
+        if (!session) {
+            sip_i_invite(nua, profile, nh, sofia_private, sip, tags);
+        }
                break;
-
        case nua_i_publish:
                sip_i_publish(nua, profile, nh, sofia_private, sip, tags);
                break;
-
     case nua_i_register:
                sip_i_register (nua, profile, nh, sofia_private, sip, tags);
         break;
-
        case nua_i_prack:
-               //sip_i_prack(nua, profile, nh, sofia_private, sip, tags);
                break;
-
        case nua_i_state:
                sip_i_state(status, phrase, nua, profile, nh, sofia_private, sip, tags);
                break;
-    
-       case nua_r_bye:
-               //sip_r_bye(status, phrase, nua, profile, nh, sofia_private, sip, tags);
-               break;
-
+    case nua_r_bye:
        case nua_i_bye:
-               //sip_i_bye(nua, profile, nh, sofia_private, sip, tags);
-               break;
-
        case nua_i_message:
                sip_i_message(status, phrase, nua, profile, nh, sofia_private, sip, tags);
                break;
-
        case nua_r_info:
-               //sip_r_info(status, phrase, nua, profile, nh, sofia_private, sip, tags);
                break;
-
        case nua_i_info:
                sip_i_info(nua, profile, nh, session, sip, tags);
                break;
-
        case nua_r_refer:
-               //sip_r_refer(status, phrase, nua, profile, nh, sofia_private, sip, tags);
                break;
-
        case nua_i_refer:
-               sip_i_refer(nua, profile, nh, sofia_private, sip, tags);
+        if (session) {
+            sip_i_refer(nua, profile, nh, session, sip, tags);
+        }
                break;
-
-     
-       case nua_r_subscribe:
+    case nua_r_subscribe:
                sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
                break;
-
        case nua_i_subscribe:
                sip_i_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
                break;
-
        case nua_r_unsubscribe:
-               //sip_r_unsubscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
-               break;
-
        case nua_r_publish:
-               //sip_r_publish(status, phrase, nua, profile, nh, sofia_private, sip, tags);
-               break;
        case nua_r_message:
        case nua_r_notify:
-               break;
-     
-       case nua_i_notify:
-               //sip_i_notify(nua, profile, nh, sofia_private, sip, tags);
-               break;
-
+    case nua_i_notify:
        case nua_i_cancel:
-               //sip_i_cancel(nua, profile, nh, sofia_private, sip, tags);
-               break;
-
        case nua_i_error:
-               //sip_i_error(nua, profile, nh, sofia_private, status, phrase, tags);
-               break;
-
        case nua_i_active:
        case nua_i_ack:
        case nua_i_terminated:
index fb30a7068c201208919ba89d7b220d66ff498186..331645831bc07091c9783587463a2211ff7648fa 100644 (file)
@@ -67,10 +67,16 @@ struct switch_media_bug {
        uint32_t flags;
        struct switch_media_bug *next;
 };
-       
+
+typedef enum {
+    SSF_NONE = 0,
+    SSF_DESTROYED = (1 << 0)
+} switch_session_flag_t;
+
 struct switch_core_session {
        uint32_t id;
        char name[80];
+    switch_session_flag_t flags;
        int thread_running;
        switch_memory_pool_t *pool;
        switch_channel_t *channel;
@@ -567,24 +573,22 @@ SWITCH_DECLARE(char *) switch_core_get_variable(char *varname)
 
 SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(char *uuid_str)
 {
-       switch_core_session_t *session;
+       switch_core_session_t *session = NULL;
 
        if (uuid_str) {
                switch_mutex_lock(runtime.session_table_mutex);
                if ((session = switch_core_hash_find(runtime.session_table, uuid_str))) {
                        /* Acquire a read lock on the session */
-                       if (switch_thread_rwlock_tryrdlock(session->rwlock) != SWITCH_STATUS_SUCCESS) {
+                       if (switch_test_flag(session, SSF_DESTROYED) || switch_thread_rwlock_tryrdlock(session->rwlock) != SWITCH_STATUS_SUCCESS) {
                                /* not available, forget it */
                                session = NULL;
                        }
                }
                switch_mutex_unlock(runtime.session_table_mutex);
-
-               /* if its not NULL, now it's up to you to rwunlock this */
-               return session;
-       } else {
-               return NULL;
        }
+
+    /* if its not NULL, now it's up to you to rwunlock this */
+    return session;
 }
 
 SWITCH_DECLARE(void) switch_core_session_hupall(switch_call_cause_t cause)
@@ -3232,6 +3236,14 @@ SWITCH_DECLARE(void) switch_core_session_destroy(switch_core_session_t **session
 
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Close Channel %s\n", switch_channel_get_name((*session)->channel));
 
+       switch_mutex_lock(runtime.session_table_mutex);
+       switch_core_hash_delete(runtime.session_table, (*session)->uuid_str);
+       if (runtime.session_count) {
+               runtime.session_count--;
+       }
+    switch_set_flag((*session), SSF_DESTROYED);
+       switch_mutex_unlock(runtime.session_table_mutex);
+
        if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DESTROY) == SWITCH_STATUS_SUCCESS) {
                switch_channel_event_set_data((*session)->channel, event);
                switch_event_fire(&event);
@@ -3247,11 +3259,6 @@ SWITCH_DECLARE(void) switch_core_session_destroy(switch_core_session_t **session
        apr_pool_destroy(pool);
        pool = NULL;
 
-       switch_mutex_lock(runtime.session_table_mutex);
-       if (runtime.session_count) {
-               runtime.session_count--;
-       }
-       switch_mutex_unlock(runtime.session_table_mutex);
 }
 
 SWITCH_DECLARE(switch_status_t) switch_core_hash_init(switch_hash_t **hash, switch_memory_pool_t *pool)
@@ -3342,11 +3349,8 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread(switch_thread_t *thre
 {
        switch_core_session_t *session = obj;
        session->thread = thread;
-       snprintf(session->name, sizeof(session->name), "%u", session->id);
-       switch_mutex_lock(runtime.session_table_mutex);
-       session->id = runtime.session_id++;
-       switch_core_hash_insert(runtime.session_table, session->uuid_str, session);
-       switch_mutex_unlock(runtime.session_table_mutex);
+
+
 
        switch_core_session_run(session);
        switch_core_media_bug_remove_all(session);
@@ -3354,9 +3358,6 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread(switch_thread_t *thre
        switch_core_session_write_lock(session);
        switch_core_session_rwunlock(session);
 
-       switch_mutex_lock(runtime.session_table_mutex);
-       switch_core_hash_delete(runtime.session_table, session->uuid_str);
-       switch_mutex_unlock(runtime.session_table_mutex);
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Session %u (%s) Ended\n", session->id, switch_channel_get_name(session->channel));
        switch_core_session_destroy(&session);
        return NULL;
@@ -3479,9 +3480,13 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request(const switch
        switch_thread_cond_create(&session->cond, session->pool);
        switch_thread_rwlock_create(&session->rwlock, session->pool);
 
+       snprintf(session->name, sizeof(session->name), "%u", session->id);
        switch_mutex_lock(runtime.session_table_mutex);
+       session->id = runtime.session_id++;
+       switch_core_hash_insert(runtime.session_table, session->uuid_str, session);
        runtime.session_count++;
        switch_mutex_unlock(runtime.session_table_mutex);
+
        return session;
 }
 
index 58f105a56d56efffd8def770833a7c1cceb6c1c0..9d8a994d7be63d9bbcda364cb96dea848a94acb5 100644 (file)
@@ -3308,12 +3308,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
 
             if (switch_channel_test_flag(caller_channel, CF_TRANSFER) && !switch_channel_test_flag(peer_channel, CF_TRANSFER)) {
                 //switch_channel_hangup(peer_channel, SWITCH_CAUSE_NORMAL_CLEARING);
-                switch_yield(2000000);
+                //switch_yield(2000000);
             }
 
             if (!switch_channel_test_flag(caller_channel, CF_TRANSFER) && switch_channel_test_flag(peer_channel, CF_TRANSFER)) {
                 //switch_channel_hangup(caller_channel, SWITCH_CAUSE_NORMAL_CLEARING);
-                switch_yield(2000000);
+                //switch_yield(2000000);
             }