]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FSCORE-357
authorAnthony Minessale <anthony.minessale@gmail.com>
Tue, 28 Apr 2009 14:13:05 +0000 (14:13 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Tue, 28 Apr 2009 14:13:05 +0000 (14:13 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@13176 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_core.h
src/include/switch_types.h
src/switch_core_session.c
src/switch_core_state_machine.c
src/switch_ivr_bridge.c
src/switch_ivr_originate.c

index e1ba1ac312bd46753f8ac7f72d902ea575a5f784..f6cc1ae954eeaedb2071a7d26cccdc3529d6cdc8 100644 (file)
@@ -579,6 +579,7 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(_Inout_ switch_core_ses
 #define switch_core_session_destroy(session) switch_core_session_perform_destroy(session, __FILE__, __SWITCH_FUNC__, __LINE__)
 
 SWITCH_DECLARE(void) switch_core_session_destroy_state(switch_core_session_t *session);
+SWITCH_DECLARE(void) switch_core_session_reporting_state(switch_core_session_t *session);
 
 /*! 
   \brief Provide the total number of sessions
@@ -652,6 +653,13 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_perform_locate(const
 SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(_In_z_ const char *uuid_str);
 #endif
 
+
+#ifdef SWITCH_DEBUG_RWLOCKS
+#define switch_core_session_locate(uuid_str) switch_core_session_perform_force_locate(uuid_str, __FILE__, __SWITCH_FUNC__, __LINE__)
+#else
+SWITCH_DECLARE(switch_core_session_t *) switch_core_session_force_locate(_In_z_ const char *uuid_str);
+#endif
+
 /*! 
   \brief Retrieve a global variable from the core
   \param varname the name of the variable
index 660040f17810946b61566dab5b4a4614a4f37ffc..ffd83211faf1d0fddf13f0841001abbcdce68df0 100644 (file)
@@ -884,6 +884,7 @@ typedef enum {
        CF_DIVERT_EVENTS,
        CF_BLOCK_STATE,
        CF_FS_RTP,
+       CF_REPORTING,
        /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
        CF_FLAG_MAX
 } switch_channel_flag_t;
index 114a2e0fd97c27cbbd6e497b3449ad3d395625b2..342d0291b775bfafae9a7b8fcb186e5d0a5bec3d 100644 (file)
@@ -75,13 +75,58 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(const char *u
        return session;
 }
 
+
+
+
+#ifdef SWITCH_DEBUG_RWLOCKS
+SWITCH_DECLARE(switch_core_session_t *) switch_core_session_perform_force_locate(const char *uuid_str, const char *file, const char *func, int line)
+#else
+SWITCH_DECLARE(switch_core_session_t *) switch_core_session_force_locate(const char *uuid_str)
+#endif
+{
+       switch_core_session_t *session = NULL;
+       switch_status_t status;
+       
+       if (uuid_str) {
+               switch_mutex_lock(runtime.session_hash_mutex);
+               if ((session = switch_core_hash_find(session_manager.session_table, uuid_str))) {
+                       /* Acquire a read lock on the session */
+
+                       if (switch_test_flag(session, SSF_DESTROYED)) {
+                               status = SWITCH_STATUS_FALSE;
+#ifdef SWITCH_DEBUG_RWLOCKS
+                               switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "%s Read lock FAIL\n",
+                                                                 switch_channel_get_name(session->channel));
+#endif
+                       } else {
+                               status = (switch_status_t) switch_thread_rwlock_tryrdlock(session->rwlock);
+#ifdef SWITCH_DEBUG_RWLOCKS
+                               switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "%s Read lock ACQUIRED\n",
+                                                                 switch_channel_get_name(session->channel));
+#endif
+                       }
+
+                       if (status != SWITCH_STATUS_SUCCESS) {
+                               /* not available, forget it */
+                               session = NULL;
+                       }
+               }
+               switch_mutex_unlock(runtime.session_hash_mutex);
+       }
+
+       /* if its not NULL, now it's up to you to rwunlock this */
+       return session;
+}
+
+
 SWITCH_DECLARE(switch_status_t) switch_core_session_get_partner(switch_core_session_t *session, switch_core_session_t **partner)
 {
        const char *uuid;
        
        if ((uuid = switch_channel_get_variable(session->channel, SWITCH_SIGNAL_BOND_VARIABLE))) {
-               *partner = switch_core_session_locate(uuid);
-               return SWITCH_STATUS_SUCCESS;
+               if ((*partner = switch_core_session_locate(uuid))) {
+                       return SWITCH_STATUS_SUCCESS;
+               }
        }
 
        *partner = NULL;
index 603e3fd6b5e0f5795a0ccb82ce590620386ee64d..c8440f1d46cd575d4797c6f333eb441ad8961db5 100644 (file)
@@ -406,24 +406,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
                                goto done;
                        case CS_REPORTING: /* Call Detail */
                                {
-                                       const char *var = switch_channel_get_variable(session->channel, SWITCH_PROCESS_CDR_VARIABLE);
-                                       
-                                       if (!switch_strlen_zero(var)) {
-                                               if (!strcasecmp(var, "a_only")) {
-                                                       if (switch_channel_get_originator_caller_profile(session->channel)) {
-                                                               do_extra_handlers = 0;
-                                                       }
-                                               } else if (!strcasecmp(var, "b_only")) {
-                                                       if (switch_channel_get_originatee_caller_profile(session->channel)) {
-                                                               do_extra_handlers = 0;
-                                                       }
-                                               } else if (!switch_true(var)) {
-                                                       do_extra_handlers = 0;
-                                               }
-                                       }
-
-                                       STATE_MACRO(reporting, "REPORTING");
-                                       
+                                       switch_core_session_reporting_state(session);
                                        switch_channel_set_state(session->channel, CS_DESTROY);
                                }
                                goto done;
@@ -578,6 +561,56 @@ SWITCH_DECLARE(void) switch_core_session_destroy_state(switch_core_session_t *se
        return;
 }
 
+
+SWITCH_DECLARE(void) switch_core_session_reporting_state(switch_core_session_t *session)
+{
+       switch_channel_state_t state = switch_channel_get_state(session->channel), midstate = state;
+       const switch_endpoint_interface_t *endpoint_interface;
+       const switch_state_handler_table_t *driver_state_handler = NULL;
+       const switch_state_handler_table_t *application_state_handler = NULL;
+       int proceed = 1;
+       int global_proceed = 1;
+       int do_extra_handlers = 1;
+       int silly = 0;
+       int index = 0;
+
+       if (switch_channel_test_flag(session->channel, CF_REPORTING)) {
+               return;
+       }
+
+       switch_channel_set_flag(session->channel, CF_REPORTING);
+       
+       switch_assert(session != NULL);
+
+       session->thread_running = 1;
+       endpoint_interface = session->endpoint_interface;
+       switch_assert(endpoint_interface != NULL);
+
+       driver_state_handler = endpoint_interface->state_handler;
+       switch_assert(driver_state_handler != NULL);
+       
+
+       const char *var = switch_channel_get_variable(session->channel, SWITCH_PROCESS_CDR_VARIABLE);
+       
+       if (!switch_strlen_zero(var)) {
+               if (!strcasecmp(var, "a_only")) {
+                       if (switch_channel_get_originator_caller_profile(session->channel)) {
+                               do_extra_handlers = 0;
+                       }
+               } else if (!strcasecmp(var, "b_only")) {
+                       if (switch_channel_get_originatee_caller_profile(session->channel)) {
+                               do_extra_handlers = 0;
+                       }
+               } else if (!switch_true(var)) {
+                       do_extra_handlers = 0;
+               }
+       }
+
+       STATE_MACRO(reporting, "REPORTING");
+                                       
+       return;
+}
+
 /* For Emacs:
  * Local Variables:
  * mode:c
index 96ea48e09f367974e56dfda16bd0d3b5d2b4f187..67b119e65a43ecd9f1fd6cdcdb9f7e110deaf943 100644 (file)
@@ -503,32 +503,9 @@ static switch_status_t audio_bridge_on_exchange_media(switch_core_session_t *ses
                if (!switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_REDIRECT) && bd && !bd->clean_exit 
                        && state != CS_PARK && state != CS_ROUTING && !switch_channel_test_flag(channel, CF_INNER_BRIDGE)) {
                        switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
-                       }
-       }
-       
-
-       if (switch_true(switch_channel_get_variable(channel, SWITCH_COPY_XML_CDR_VARIABLE))) {
-               switch_core_session_t *other_session;
-               switch_channel_t *other_channel;
-               switch_xml_t cdr;
-               char *xml_text;
-
-               if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
-                       other_channel = switch_core_session_get_channel(other_session);
-                       
-                       switch_channel_wait_for_state(channel, other_channel, CS_REPORTING);
-                       
-                       if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) {
-                               if ((xml_text = switch_xml_toxml(cdr, SWITCH_FALSE))) {
-                                       switch_channel_set_variable(other_channel, "b_leg_cdr", xml_text);
-                                       switch_safe_free(xml_text);
-                               }
-                               switch_xml_free(cdr);
-                       }
-                       switch_core_session_rwunlock(other_session);
                }
        }
-
+       
        if (switch_channel_get_state(channel) == CS_EXCHANGE_MEDIA) {
                switch_channel_set_state(channel, CS_RESET);
        }
@@ -979,6 +956,21 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
                                switch_channel_set_variable(caller_channel, SWITCH_BRIDGE_HANGUP_CAUSE_VARIABLE, switch_channel_cause2str(cause));
                        }
 
+                       if (switch_channel_down(peer_channel) && switch_true(switch_channel_get_variable(peer_channel, SWITCH_COPY_XML_CDR_VARIABLE))) {
+                               switch_xml_t cdr;
+                               char *xml_text;
+                               
+                               switch_channel_wait_for_state(caller_channel, peer_channel, CS_DESTROY);
+
+                               if (switch_ivr_generate_xml_cdr(peer_session, &cdr) == SWITCH_STATUS_SUCCESS) {
+                                       if ((xml_text = switch_xml_toxml(cdr, SWITCH_FALSE))) {
+                                               switch_channel_set_variable(caller_channel, "b_leg_cdr", xml_text);
+                                               switch_safe_free(xml_text);
+                                       }
+                                       switch_xml_free(cdr);
+                               }
+                       }
+
                        switch_core_session_rwunlock(peer_session);
 
                } else {
index 8de666cfb24ceb2e901898957c89e86bd86d11e8..8d28c79bc7e718c60b0fa590ffbfe9193bd7b260 100644 (file)
@@ -2045,6 +2045,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
                             continue;
                         }
                                                
+                                               switch_channel_wait_for_state(caller_channel, switch_core_session_get_channel(originate_status[i].peer_session), CS_DESTROY);
+
                                                if (switch_ivr_generate_xml_cdr(originate_status[i].peer_session, &cdr) == SWITCH_STATUS_SUCCESS) {
                                                        if ((xml_text = switch_xml_toxml(cdr, SWITCH_FALSE))) {
                                                                switch_snprintf(buf, sizeof(buf), "%s_%d", cdr_var, ++cdr_total);