switch_core_state_machine.c File Reference

#include <switch.h>
#include "private/switch_core_pvt.h"

Include dependency graph for switch_core_state_machine.c:

Go to the source code of this file.

Defines

#define STATE_MACRO(__STATE, __STATE_STR)

Functions

static void switch_core_standard_on_init (switch_core_session_t *session)
static void switch_core_standard_on_hangup (switch_core_session_t *session)
static void switch_core_standard_on_reporting (switch_core_session_t *session)
static void switch_core_standard_on_destroy (switch_core_session_t *session)
static void switch_core_standard_on_reset (switch_core_session_t *session)
static void switch_core_standard_on_routing (switch_core_session_t *session)
static void switch_core_standard_on_execute (switch_core_session_t *session)
static void switch_core_standard_on_exchange_media (switch_core_session_t *session)
static void switch_core_standard_on_soft_execute (switch_core_session_t *session)
static void switch_core_standard_on_park (switch_core_session_t *session)
static void switch_core_standard_on_consume_media (switch_core_session_t *session)
static void switch_core_standard_on_hibernate (switch_core_session_t *session)
void switch_core_state_machine_init (switch_memory_pool_t *pool)
void switch_core_session_run (switch_core_session_t *session)
void switch_core_session_destroy_state (switch_core_session_t *session)
static void api_hook (switch_core_session_t *session, const char *hook_var, int use_session)
void switch_core_session_hangup_state (switch_core_session_t *session, switch_bool_t force)
void switch_core_session_reporting_state (switch_core_session_t *session)


Define Documentation

#define STATE_MACRO ( __STATE,
__STATE_STR   ) 

Definition at line 292 of file switch_core_state_machine.c.

Referenced by switch_core_session_destroy_state(), switch_core_session_hangup_state(), switch_core_session_reporting_state(), and switch_core_session_run().


Function Documentation

static void api_hook ( switch_core_session_t session,
const char *  hook_var,
int  use_session 
) [static]

Definition at line 532 of file switch_core_state_machine.c.

References switch_core_session::channel, switch_stream_handle::data, switch_stream_handle::param_event, switch_api_execute(), switch_channel_event_set_data(), switch_channel_get_variables(), SWITCH_CHANNEL_SESSION_LOG, switch_event_expand_headers, SWITCH_LOG_DEBUG, switch_log_printf(), switch_safe_free, SWITCH_STANDARD_STREAM, switch_str_nil, and zstr.

Referenced by switch_core_session_hangup_state(), and switch_core_session_reporting_state().

00533 {
00534         if (!zstr(hook_var)) {
00535                 switch_stream_handle_t stream = { 0 };
00536                 char *cmd = strdup(hook_var);
00537                 char *arg = NULL;
00538                 char *expanded = NULL;
00539 
00540                 if ((arg = strchr(cmd, ':')) && *(arg + 1) == ':') {
00541                         *arg++ = '\0';
00542                         *arg++ = '\0';
00543                 } else {
00544                         if ((arg = strchr(cmd, ' '))) {
00545                                 *arg++ = '\0';
00546                         }
00547                 }
00548 
00549                 SWITCH_STANDARD_STREAM(stream);
00550 
00551                 switch_channel_get_variables(session->channel, &stream.param_event);
00552                 switch_channel_event_set_data(session->channel, stream.param_event);
00553                 expanded = switch_event_expand_headers(stream.param_event, arg);
00554 
00555                 switch_api_execute(cmd, expanded, use_session ? session : NULL, &stream);
00556 
00557                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Hangup Command %s %s(%s):\n%s\n",
00558                                                   use_session ? "with Session" : "with no Session", cmd, switch_str_nil(expanded),
00559                                                   switch_str_nil((char *) stream.data) );
00560 
00561                 if (expanded != arg) {
00562                         switch_safe_free(expanded);
00563                 }
00564 
00565                 switch_safe_free(cmd);
00566                 
00567                 switch_safe_free(stream.data);
00568         }
00569 }

void switch_core_session_run ( switch_core_session_t session  ) 

Definition at line 332 of file switch_core_state_machine.c.

References CF_BLOCK_STATE, CF_REDIRECT, CF_THREAD_SLEEPING, CF_TRANSFER, CS_CONSUME_MEDIA, CS_DESTROY, CS_EXCHANGE_MEDIA, CS_EXECUTE, CS_HANGUP, CS_HIBERNATE, CS_INIT, CS_NEW, CS_NONE, CS_PARK, CS_REPORTING, CS_RESET, CS_ROUTING, CS_SOFT_EXECUTE, switch_io_event_hook_state_run::next, SSF_THREAD_RUNNING, switch_endpoint_interface::state_handler, STATE_MACRO, switch_io_event_hook_state_run::state_run, switch_assert, SWITCH_CAUSE_INVALID_CALL_REFERENCE, switch_channel_clear_flag(), switch_channel_event_set_data(), switch_channel_get_name(), switch_channel_get_running_state(), switch_channel_get_state(), switch_channel_hangup, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag, switch_channel_set_running_state, switch_channel_set_state, switch_channel_test_flag(), switch_channel_wait_for_flag(), switch_clear_flag, switch_cond_next(), switch_core_session_hangup_state(), switch_core_session_reporting_state(), SWITCH_EVENT_CHANNEL_CREATE, switch_event_create, switch_event_fire, SWITCH_FALSE, switch_ivr_parse_all_events(), SWITCH_LOG_CRIT, SWITCH_LOG_DEBUG, switch_log_printf(), switch_mutex_lock(), switch_mutex_unlock(), switch_set_flag, SWITCH_STATUS_SUCCESS, switch_thread_cond_wait(), and SWITCH_TRUE.

00333 {
00334         switch_channel_state_t state = CS_NEW, midstate = CS_DESTROY, endstate;
00335         const switch_endpoint_interface_t *endpoint_interface;
00336         const switch_state_handler_table_t *driver_state_handler = NULL;
00337         const switch_state_handler_table_t *application_state_handler = NULL;
00338         int silly = 0;
00339         uint32_t new_loops = 60000;
00340 
00341         /*
00342            Life of the channel. you have channel and pool in your session
00343            everywhere you go you use the session to malloc with
00344            switch_core_session_alloc(session, <size>)
00345 
00346            The endpoint module gets the first crack at implementing the state
00347            if it wants to, it can cancel the default behavior by returning SWITCH_STATUS_FALSE
00348 
00349            Next comes the channel's event handler table that can be set by an application
00350            which also can veto the next behavior in line by returning SWITCH_STATUS_FALSE
00351 
00352            Finally the default state behavior is called.
00353 
00354 
00355          */
00356         switch_assert(session != NULL);
00357 
00358         switch_set_flag(session, SSF_THREAD_RUNNING);
00359         endpoint_interface = session->endpoint_interface;
00360         switch_assert(endpoint_interface != NULL);
00361 
00362         driver_state_handler = endpoint_interface->state_handler;
00363         switch_assert(driver_state_handler != NULL);
00364 
00365         switch_mutex_lock(session->mutex);
00366 
00367         while ((state = switch_channel_get_state(session->channel)) != CS_DESTROY) {
00368 
00369                 if (switch_channel_test_flag(session->channel, CF_BLOCK_STATE)) {
00370                         switch_channel_wait_for_flag(session->channel, CF_BLOCK_STATE, SWITCH_FALSE, 0, NULL);
00371                         if ((state = switch_channel_get_state(session->channel)) == CS_DESTROY) {
00372                                 break;
00373                         }
00374                 }
00375 
00376                 midstate = state;
00377                 if (state != switch_channel_get_running_state(session->channel) || state >= CS_HANGUP) {
00378                         int index = 0;
00379                         int proceed = 1;
00380                         int global_proceed = 1;
00381                         int do_extra_handlers = 1;
00382                         switch_io_event_hook_state_run_t *ptr;
00383                         switch_status_t rstatus = SWITCH_STATUS_SUCCESS;
00384 
00385                         switch_channel_set_running_state(session->channel, state);
00386                         switch_channel_clear_flag(session->channel, CF_TRANSFER);
00387                         switch_channel_clear_flag(session->channel, CF_REDIRECT);
00388                         
00389                         if (session->endpoint_interface->io_routines->state_run) {
00390                                 rstatus = session->endpoint_interface->io_routines->state_run(session);
00391                         }
00392                         
00393                         if (rstatus == SWITCH_STATUS_SUCCESS) {
00394                                 for (ptr = session->event_hooks.state_run; ptr; ptr = ptr->next) {
00395                                         if ((rstatus = ptr->state_run(session)) != SWITCH_STATUS_SUCCESS) {
00396                                                 break;
00397                                         }
00398                                 }
00399                         }
00400                         
00401                         switch (state) {
00402                         case CS_NEW:            /* Just created, Waiting for first instructions */
00403                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) State NEW\n", switch_channel_get_name(session->channel));
00404                                 break;
00405                         case CS_DESTROY:
00406                                 goto done;
00407                         case CS_REPORTING:      /* Call Detail */
00408                                 {
00409                                         switch_core_session_reporting_state(session);
00410                                         switch_channel_set_state(session->channel, CS_DESTROY);
00411                                 }
00412                                 goto done;
00413                         case CS_HANGUP: /* Deactivate and end the thread */
00414                                 {
00415                                         switch_core_session_hangup_state(session, SWITCH_TRUE);
00416                                         switch_channel_set_state(session->channel, CS_REPORTING);
00417                                 }
00418 
00419                                 break;
00420                         case CS_INIT:           /* Basic setup tasks */
00421                                 {
00422                                         switch_event_t *event;
00423 
00424                                         STATE_MACRO(init, "INIT");
00425                                         
00426                                         if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_CREATE) == SWITCH_STATUS_SUCCESS) {
00427                                                 switch_channel_event_set_data(session->channel, event);
00428                                                 switch_event_fire(&event);
00429                                         }
00430                                 }
00431                                 break;
00432                         case CS_ROUTING:        /* Look for a dialplan and find something to do */
00433                                 STATE_MACRO(routing, "ROUTING");
00434                                 break;
00435                         case CS_RESET:          /* Reset */
00436                                 STATE_MACRO(reset, "RESET");
00437                                 break;
00438                                 /* These other states are intended for prolonged durations so we do not signal lock for them */
00439                         case CS_EXECUTE:        /* Execute an Operation */
00440                                 STATE_MACRO(execute, "EXECUTE");
00441                                 break;
00442                         case CS_EXCHANGE_MEDIA: /* loop all data back to source */
00443                                 STATE_MACRO(exchange_media, "EXCHANGE_MEDIA");
00444                                 break;
00445                         case CS_SOFT_EXECUTE:   /* send/recieve data to/from another channel */
00446                                 STATE_MACRO(soft_execute, "SOFT_EXECUTE");
00447                                 break;
00448                         case CS_PARK:           /* wait in limbo */
00449                                 STATE_MACRO(park, "PARK");
00450                                 break;
00451                         case CS_CONSUME_MEDIA:  /* wait in limbo */
00452                                 STATE_MACRO(consume_media, "CONSUME_MEDIA");
00453                                 break;
00454                         case CS_HIBERNATE:      /* sleep */
00455                                 STATE_MACRO(hibernate, "HIBERNATE");
00456                                 break;
00457                         case CS_NONE:
00458                                 abort();
00459                                 break;
00460                         }
00461 
00462                         if (midstate == CS_DESTROY) {
00463                                 break;
00464                         }
00465 
00466                 }
00467 
00468                 endstate = switch_channel_get_state(session->channel);
00469 
00470                 if (endstate == switch_channel_get_running_state(session->channel)) {
00471                         if (endstate == CS_NEW) {
00472                                 switch_cond_next();
00473                                 switch_ivr_parse_all_events(session);
00474                                 if (!--new_loops) {
00475                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s Timeout waiting for next instruction in CS_NEW!\n",
00476                                                                           session->uuid_str);
00477                                         switch_channel_hangup(session->channel, SWITCH_CAUSE_INVALID_CALL_REFERENCE);
00478                                 }
00479                         } else {
00480                                 switch_ivr_parse_all_events(session);
00481                                 switch_ivr_parse_all_events(session);
00482 
00483                                 if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) {
00484                                         switch_channel_set_flag(session->channel, CF_THREAD_SLEEPING);
00485                                         if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) {
00486                                                 switch_thread_cond_wait(session->cond, session->mutex);
00487                                         }
00488                                         switch_channel_clear_flag(session->channel, CF_THREAD_SLEEPING);
00489                                 }
00490 
00491                                 switch_ivr_parse_all_events(session);
00492                                 switch_ivr_parse_all_events(session);
00493                         }
00494                 }
00495         }
00496   done:
00497         switch_mutex_unlock(session->mutex);
00498 
00499         switch_clear_flag(session, SSF_THREAD_RUNNING);
00500 }

static void switch_core_standard_on_consume_media ( switch_core_session_t session  )  [static]

Definition at line 275 of file switch_core_state_machine.c.

References switch_core_session::channel, switch_assert, switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, SWITCH_LOG_DEBUG, and switch_log_printf().

00276 {
00277         switch_assert(session != NULL);
00278         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard CONSUME_MEDIA\n", switch_channel_get_name(session->channel));
00279 }

static void switch_core_standard_on_destroy ( switch_core_session_t session  )  [static]

Definition at line 83 of file switch_core_state_machine.c.

References switch_core_session::channel, switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, SWITCH_LOG_DEBUG, and switch_log_printf().

00084 {
00085 
00086         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard DESTROY\n", switch_channel_get_name(session->channel));
00087 }

static void switch_core_standard_on_exchange_media ( switch_core_session_t session  )  [static]

Definition at line 255 of file switch_core_state_machine.c.

References switch_core_session::channel, switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, SWITCH_LOG_DEBUG, and switch_log_printf().

00256 {
00257 
00258         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard EXCHANGE_MEDIA\n", switch_channel_get_name(session->channel));
00259 }

static void switch_core_standard_on_execute ( switch_core_session_t session  )  [static]

Definition at line 191 of file switch_core_state_machine.c.

References switch_caller_application::application_data, switch_caller_application::application_name, CF_CONFIRM_BLIND_TRANSFER, CF_RECOVERED, CF_RESET, switch_core_session::channel, CS_EXECUTE, CS_PARK, switch_caller_extension::current_application, switch_core_session_message::from, switch_core_session_message::message_id, switch_caller_application::next, switch_core_session_message::numeric_arg, SWITCH_CAUSE_NORMAL_CLEARING, switch_channel_clear_flag(), switch_channel_get_caller_extension(), switch_channel_get_name(), switch_channel_get_state(), switch_channel_get_variable, switch_channel_hangup, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag, switch_channel_set_state, switch_channel_set_variable, switch_channel_test_flag(), switch_core_session_execute_application, switch_core_session_get_uuid(), switch_core_session_locate(), switch_core_session_receive_message, switch_core_session_rwunlock(), SWITCH_LOG_DEBUG, SWITCH_LOG_NOTICE, switch_log_printf(), SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE, and SWITCH_STATUS_SUCCESS.

00192 {
00193         switch_caller_extension_t *extension;
00194         const char *uuid;
00195 
00196         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard EXECUTE\n", switch_channel_get_name(session->channel));
00197 
00198         switch_channel_set_variable(session->channel, "call_uuid", switch_core_session_get_uuid(session));
00199 
00200         if (switch_channel_get_variable(session->channel, "recovered") && !switch_channel_test_flag(session->channel, CF_RECOVERED)) {
00201                 switch_channel_set_flag(session->channel, CF_RECOVERED);
00202         }
00203 
00204   top:
00205         switch_channel_clear_flag(session->channel, CF_RESET);
00206         
00207         if ((extension = switch_channel_get_caller_extension(session->channel)) == 0) {
00208                 switch_channel_hangup(session->channel, SWITCH_CAUSE_NORMAL_CLEARING);
00209                 return;
00210         }
00211 
00212         while (switch_channel_get_state(session->channel) == CS_EXECUTE && extension->current_application) {
00213                 switch_caller_application_t *current_application = extension->current_application;
00214 
00215                 extension->current_application = extension->current_application->next;
00216 
00217                 if (switch_core_session_execute_application(session,
00218                                                                                                         current_application->application_name,
00219                                                                                                         current_application->application_data) != SWITCH_STATUS_SUCCESS) {
00220                         return;
00221                 }
00222 
00223                 if (switch_channel_test_flag(session->channel, CF_RESET)) {
00224                         goto top;
00225                 }
00226 
00227         }
00228 
00229         if (switch_channel_ready(session->channel) && switch_channel_get_state(session->channel) == CS_EXECUTE && 
00230                 switch_channel_test_flag(session->channel, CF_CONFIRM_BLIND_TRANSFER) && 
00231                 (uuid = switch_channel_get_variable(session->channel, "blind_transfer_uuid"))) {
00232                 switch_core_session_t *other_session;
00233 
00234                 if ((other_session = switch_core_session_locate(uuid))) {
00235                         switch_core_session_message_t msg = { 0 };                      
00236                         msg.message_id = SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE;
00237                         msg.from = __FILE__;
00238                         msg.numeric_arg = 0;
00239                         switch_core_session_receive_message(other_session, &msg);
00240                         switch_core_session_rwunlock(other_session);
00241 
00242                         switch_channel_set_variable(session->channel, "park_timeout", "10:blind_transfer");
00243                         switch_channel_set_state(session->channel, CS_PARK);
00244                         switch_channel_clear_flag(session->channel, CF_CONFIRM_BLIND_TRANSFER);
00245                 }
00246         }
00247         
00248         if (switch_channel_ready(session->channel) && switch_channel_get_state(session->channel) == CS_EXECUTE) {
00249                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "%s has executed the last dialplan instruction, hanging up.\n",
00250                                                   switch_channel_get_name(session->channel));
00251                 switch_channel_hangup(session->channel, SWITCH_CAUSE_NORMAL_CLEARING);
00252         }
00253 }

static void switch_core_standard_on_hangup ( switch_core_session_t session  )  [static]

Definition at line 43 of file switch_core_state_machine.c.

References switch_caller_application::application_data, switch_caller_application::application_name, CF_ZOMBIE_EXEC, switch_core_session::channel, switch_caller_extension::current_application, switch_caller_application::next, switch_channel_cause2str(), switch_channel_get_caller_extension(), switch_channel_get_cause(), switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_test_flag(), switch_core_session_execute_application, SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_STATUS_IGNORE, and SWITCH_STATUS_SUCCESS.

00044 {
00045         switch_caller_extension_t *extension;
00046 
00047         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard HANGUP, cause: %s\n",
00048                                           switch_channel_get_name(session->channel), switch_channel_cause2str(switch_channel_get_cause(session->channel)));
00049         
00050         if (!switch_channel_test_flag(session->channel, CF_ZOMBIE_EXEC)) {
00051                 return;
00052         }
00053 
00054         if ((extension = switch_channel_get_caller_extension(session->channel)) == 0) {
00055                 return;
00056         }
00057 
00058         while(extension->current_application) {
00059                 switch_caller_application_t *current_application = extension->current_application;
00060                 switch_status_t status;
00061 
00062                 extension->current_application = extension->current_application->next;
00063 
00064                 status = switch_core_session_execute_application(session,
00065                                                                                                                  current_application->application_name, current_application->application_data);
00066                                                                                                                  
00067                 
00068                 if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_IGNORE) {
00069                         return;
00070                 }
00071         }
00072 
00073 
00074 }

static void switch_core_standard_on_hibernate ( switch_core_session_t session  )  [static]

Definition at line 281 of file switch_core_state_machine.c.

References switch_core_session::channel, switch_assert, switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, SWITCH_LOG_DEBUG, and switch_log_printf().

00282 {
00283         switch_assert(session != NULL);
00284         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard HIBERNATE\n", switch_channel_get_name(session->channel));
00285 }

static void switch_core_standard_on_init ( switch_core_session_t session  )  [static]

Definition at line 38 of file switch_core_state_machine.c.

References switch_core_session::channel, switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, SWITCH_LOG_DEBUG, and switch_log_printf().

00039 {
00040         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard INIT\n", switch_channel_get_name(session->channel));
00041 }

static void switch_core_standard_on_park ( switch_core_session_t session  )  [static]

Definition at line 267 of file switch_core_state_machine.c.

References switch_core_session::channel, switch_assert, switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, switch_core_session_reset(), switch_ivr_park(), SWITCH_LOG_DEBUG, switch_log_printf(), and SWITCH_TRUE.

00268 {
00269         switch_assert(session != NULL);
00270         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard PARK\n", switch_channel_get_name(session->channel));
00271         switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
00272         switch_ivr_park(session, NULL);
00273 }

static void switch_core_standard_on_reporting ( switch_core_session_t session  )  [static]

Definition at line 76 of file switch_core_state_machine.c.

References switch_core_session::channel, switch_channel_cause2str(), switch_channel_get_cause(), switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, SWITCH_LOG_DEBUG, and switch_log_printf().

00077 {
00078 
00079         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard REPORTING, cause: %s\n",
00080                                           switch_channel_get_name(session->channel), switch_channel_cause2str(switch_channel_get_cause(session->channel)));
00081 }

static void switch_core_standard_on_reset ( switch_core_session_t session  )  [static]

Definition at line 89 of file switch_core_state_machine.c.

References switch_core_session::channel, switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_variable, switch_core_session_get_uuid(), SWITCH_LOG_DEBUG, and switch_log_printf().

00090 {
00091         switch_channel_set_variable(session->channel, "call_uuid", switch_core_session_get_uuid(session));
00092 
00093         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard RESET\n", switch_channel_get_name(session->channel));
00094 }

static void switch_core_standard_on_routing ( switch_core_session_t session  )  [static]

Definition at line 96 of file switch_core_state_machine.c.

References CF_ANSWERED, CF_EARLY_MEDIA, CF_PROXY_MODE, CF_SIGNAL_BRIDGE_TTL, switch_core_session::channel, CS_CONSUME_MEDIA, CS_EXECUTE, switch_caller_profile::dialplan, switch_dialplan_interface::hunt_function, SMF_NONE, SWITCH_CALL_DIRECTION_OUTBOUND, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, SWITCH_CAUSE_NO_ROUTE_DESTINATION, switch_channel_direction(), switch_channel_expand_variables, switch_channel_get_caller_profile(), switch_channel_get_name(), switch_channel_get_queued_extension(), switch_channel_hangup, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_caller_extension(), switch_channel_set_state, switch_channel_set_variable, switch_channel_test_flag(), switch_core_session_get_uuid(), switch_core_session_strdup, SWITCH_FALSE, switch_ivr_blind_transfer_ack(), switch_ivr_media(), switch_loadable_module_get_dialplan_interface(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, SWITCH_LOG_INFO, switch_log_printf(), switch_separate_string(), SWITCH_STATUS_SUCCESS, UNPROTECT_INTERFACE, switch_core_session::uuid_str, and zstr.

00097 {
00098         switch_dialplan_interface_t *dialplan_interface = NULL;
00099         switch_caller_profile_t *caller_profile;
00100         switch_caller_extension_t *extension = NULL;
00101         char *expanded = NULL;
00102         char *dpstr = NULL;
00103 
00104         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard ROUTING\n", switch_channel_get_name(session->channel));
00105 
00106         switch_channel_set_variable(session->channel, "call_uuid", switch_core_session_get_uuid(session));
00107                 
00108         if ((switch_channel_test_flag(session->channel, CF_ANSWERED) ||
00109                  switch_channel_test_flag(session->channel, CF_EARLY_MEDIA) ||
00110                  switch_channel_test_flag(session->channel, CF_SIGNAL_BRIDGE_TTL)) && switch_channel_test_flag(session->channel, CF_PROXY_MODE)) {
00111                 switch_ivr_media(session->uuid_str, SMF_NONE);
00112         }
00113 
00114         if ((caller_profile = switch_channel_get_caller_profile(session->channel)) == 0) {
00115                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't get profile!\n");
00116                 switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
00117                 return;
00118         } else {
00119                 char *dp[25];
00120                 int argc, x, count = 0;
00121 
00122                 if ((extension = switch_channel_get_queued_extension(session->channel))) {
00123                         switch_channel_set_caller_extension(session->channel, extension);
00124                         switch_channel_set_state(session->channel, CS_EXECUTE);
00125                         goto end;
00126                 }
00127 
00128                 if (!zstr(caller_profile->dialplan)) {
00129                         if ((dpstr = switch_core_session_strdup(session, caller_profile->dialplan))) {
00130                                 expanded = switch_channel_expand_variables(session->channel, dpstr);
00131                                 argc = switch_separate_string(expanded, ',', dp, (sizeof(dp) / sizeof(dp[0])));
00132                                 for (x = 0; x < argc; x++) {
00133                                         char *dpname = dp[x];
00134                                         char *dparg = NULL;
00135 
00136                                         if (dpname) {
00137                                                 if ((dparg = strchr(dpname, ':'))) {
00138                                                         *dparg++ = '\0';
00139                                                 }
00140                                         } else {
00141                                                 continue;
00142                                         }
00143                                         if (!(dialplan_interface = switch_loadable_module_get_dialplan_interface(dpname))) {
00144                                                 continue;
00145                                         }
00146 
00147                                         count++;
00148 
00149                                         extension = dialplan_interface->hunt_function(session, dparg, NULL);
00150                                         UNPROTECT_INTERFACE(dialplan_interface);
00151 
00152                                         if (extension) {
00153                                                 switch_channel_set_caller_extension(session->channel, extension);
00154                                                 switch_channel_set_state(session->channel, CS_EXECUTE);
00155                                                 goto end;
00156                                         }
00157                                 }
00158                         }
00159                 }
00160 
00161                 if (!count) {
00162                         if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
00163                                 if (switch_channel_test_flag(session->channel, CF_ANSWERED)) {
00164                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
00165                                                                           "No Dialplan on answered channel, changing state to HANGUP\n");
00166                                         switch_channel_hangup(session->channel, SWITCH_CAUSE_NO_ROUTE_DESTINATION);
00167                                 } else {
00168                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No Dialplan, changing state to CONSUME_MEDIA\n");
00169                                         switch_channel_set_state(session->channel, CS_CONSUME_MEDIA);
00170                                 }
00171                                 goto end;
00172                         }
00173                 }
00174         }
00175 
00176         if (!extension) {
00177 
00178                 if (switch_ivr_blind_transfer_ack(session, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {
00179                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "No Route, Aborting\n");
00180                         switch_channel_hangup(session->channel, SWITCH_CAUSE_NO_ROUTE_DESTINATION);
00181                 }
00182         }
00183 
00184   end:
00185 
00186         if (expanded && dpstr && expanded != dpstr) {
00187                 free(expanded);
00188         }
00189 }

static void switch_core_standard_on_soft_execute ( switch_core_session_t session  )  [static]

Definition at line 261 of file switch_core_state_machine.c.

References switch_core_session::channel, switch_assert, switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, SWITCH_LOG_DEBUG, and switch_log_printf().

00262 {
00263         switch_assert(session != NULL);
00264         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard SOFT_EXECUTE\n", switch_channel_get_name(session->channel));
00265 }

void switch_core_state_machine_init ( switch_memory_pool_t pool  ) 

Definition at line 287 of file switch_core_state_machine.c.

Referenced by switch_core_init().

00288 {
00289         return;
00290 }


Generated on Sun May 20 04:00:10 2012 for FreeSWITCH API Documentation by  doxygen 1.4.7