Author: anthm Date: Fri Apr 20 21:03:58 2007 New Revision: 4994 Modified: freeswitch/trunk/src/include/private/switch_core.h freeswitch/trunk/src/include/switch_caller.h freeswitch/trunk/src/include/switch_core.h freeswitch/trunk/src/include/switch_types.h freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c freeswitch/trunk/src/switch_core_session.c freeswitch/trunk/src/switch_core_state_machine.c freeswitch/trunk/src/switch_ivr.c freeswitch/trunk/src/switch_ivr_menu.c freeswitch/trunk/src/switch_ivr_originate.c Log: add app log Modified: freeswitch/trunk/src/include/private/switch_core.h ============================================================================== --- freeswitch/trunk/src/include/private/switch_core.h (original) +++ freeswitch/trunk/src/include/private/switch_core.h Fri Apr 20 21:03:58 2007 @@ -126,6 +126,7 @@ switch_queue_t *private_event_queue; switch_thread_rwlock_t *bug_rwlock; switch_media_bug_t *bugs; + switch_app_log_t *app_log; }; struct switch_media_bug { Modified: freeswitch/trunk/src/include/switch_caller.h ============================================================================== --- freeswitch/trunk/src/include/switch_caller.h (original) +++ freeswitch/trunk/src/include/switch_caller.h Fri Apr 20 21:03:58 2007 @@ -117,6 +117,7 @@ switch_caller_application_t *last_application; /*! Pointer to the entire stack of applications for this extension */ switch_caller_application_t *applications; + struct switch_caller_profile *children; struct switch_caller_extension *next; }; Modified: freeswitch/trunk/src/include/switch_core.h ============================================================================== --- freeswitch/trunk/src/include/switch_core.h (original) +++ freeswitch/trunk/src/include/switch_core.h Fri Apr 20 21:03:58 2007 @@ -43,7 +43,7 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_MAX_CORE_THREAD_SESSION_OBJS 128 #define SWITCH_MAX_STREAMS 128 - struct switch_core_time_duration { +struct switch_core_time_duration { uint32_t mms; uint32_t ms; uint32_t sec; @@ -53,6 +53,12 @@ uint32_t yr; }; +struct switch_app_log { + char *app; + char *arg; + struct switch_app_log *next; +}; + /*! \brief A message object designed to allow unlike technologies to exchange data */ struct switch_core_session_message { /*! uuid of the sender (for replies) */ @@ -565,6 +571,9 @@ */ SWITCH_DECLARE(switch_status_t) switch_core_session_event_send(char *uuid_str, switch_event_t **event); +SWITCH_DECLARE(switch_app_log_t *) switch_core_session_get_app_log(switch_core_session_t *session); +SWITCH_DECLARE(switch_status_t) switch_core_session_exec(switch_core_session_t *session, + const switch_application_interface_t *application_interface, char *arg); SWITCH_DECLARE(switch_status_t) switch_core_session_execute_exten(switch_core_session_t *session, char *exten, char *dialplan, char *context); /*! Modified: freeswitch/trunk/src/include/switch_types.h ============================================================================== --- freeswitch/trunk/src/include/switch_types.h (original) +++ freeswitch/trunk/src/include/switch_types.h Fri Apr 20 21:03:58 2007 @@ -954,6 +954,7 @@ typedef uint16_t switch_port_t; typedef uint8_t switch_payload_t; +typedef struct switch_app_log switch_app_log_t; typedef struct switch_rtp switch_rtp_t; typedef struct switch_core_session_message switch_core_session_message_t; typedef struct switch_event_header switch_event_header_t; Modified: freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c ============================================================================== --- freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c (original) +++ freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c Fri Apr 20 21:03:58 2007 @@ -1615,7 +1615,7 @@ if ((application_interface = switch_loadable_module_get_application_interface(app_name))) { if (application_interface->application_function) { saveDepth = JS_SuspendRequest(cx); - application_interface->application_function(jss->session, app_arg); + switch_core_session_exec(jss->session, application_interface, app_arg); JS_ResumeRequest(cx, saveDepth); retval = JS_TRUE; } Modified: freeswitch/trunk/src/switch_core_session.c ============================================================================== --- freeswitch/trunk/src/switch_core_session.c (original) +++ freeswitch/trunk/src/switch_core_session.c Fri Apr 20 21:03:58 2007 @@ -873,19 +873,48 @@ } +SWITCH_DECLARE(switch_app_log_t *) switch_core_session_get_app_log(switch_core_session_t *session) +{ + return session->app_log; +} + +SWITCH_DECLARE(switch_status_t) switch_core_session_exec(switch_core_session_t *session, + const switch_application_interface_t *application_interface, char *arg) { + switch_app_log_t *log, *lp; + + log = switch_core_session_alloc(session, sizeof(*log)); + + assert(log != NULL); + + log->app = switch_core_session_strdup(session, application_interface->interface_name); + log->arg = switch_core_session_strdup(session, arg); + + for(lp = session->app_log; lp && lp->next; lp = lp->next); + + if (lp) { + lp->next = log; + } else { + session->app_log = log; + } + + application_interface->application_function(session, arg); + + return SWITCH_STATUS_SUCCESS; +} + SWITCH_DECLARE(switch_status_t) switch_core_session_execute_exten(switch_core_session_t *session, char *exten, char *dialplan, char *context) { char *dp[25]; char *dpstr; int argc, x, count = 0; char *expanded = NULL; - switch_caller_profile_t *profile, *new_profile; + switch_caller_profile_t *profile, *new_profile, *pp; switch_channel_t *channel; switch_dialplan_interface_t *dialplan_interface = NULL; switch_caller_extension_t *extension = NULL; const switch_application_interface_t *application_interface; switch_event_t *event; - + channel = switch_core_session_get_channel(session); if (!(profile = switch_channel_get_caller_profile(channel))) { @@ -922,7 +951,7 @@ } count++; - + if ((extension = dialplan_interface->hunt_function(session, dparg, new_profile)) != 0) { break; } @@ -932,6 +961,16 @@ return SWITCH_STATUS_FALSE; } + new_profile->caller_extension = extension; + + for(pp = profile->caller_extension->children; pp && pp->next; pp = pp->next); + + if (pp) { + pp->next = new_profile; + } else { + profile->caller_extension->children = new_profile; + } + while (switch_channel_ready(channel) && extension->current_application) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Execute %s(%s)\n", extension->current_application->application_name, switch_str_nil(extension->current_application->application_data)); @@ -975,7 +1014,7 @@ } } - application_interface->application_function(session, expanded); + switch_core_session_exec(session, application_interface, expanded); if (expanded != extension->current_application->application_data) { switch_safe_free(expanded); Modified: freeswitch/trunk/src/switch_core_state_machine.c ============================================================================== --- freeswitch/trunk/src/switch_core_state_machine.c (original) +++ freeswitch/trunk/src/switch_core_state_machine.c Fri Apr 20 21:03:58 2007 @@ -165,8 +165,8 @@ switch_safe_free(arg); } } - - application_interface->application_function(session, expanded); + switch_core_session_exec(session, application_interface, expanded); + //application_interface->application_function(session, expanded); if (expanded != extension->current_application->application_data) { switch_safe_free(expanded); Modified: freeswitch/trunk/src/switch_ivr.c ============================================================================== --- freeswitch/trunk/src/switch_ivr.c (original) +++ freeswitch/trunk/src/switch_ivr.c Fri Apr 20 21:03:58 2007 @@ -303,7 +303,7 @@ int x; switch_channel_set_flag(channel, CF_BROADCAST); for (x = 0; x < loops || loops < 0; x++) { - application_interface->application_function(session, app_arg); + switch_core_session_exec(session, application_interface, app_arg); if (!switch_channel_test_flag(channel, CF_BROADCAST)) { break; } @@ -1224,7 +1224,10 @@ switch_hash_index_t *hi; void *vval; const void *vvar; - switch_xml_t variable, variables, cdr, x_caller_profile, x_caller_extension, x_times, time_tag, x_application, x_callflow; + switch_xml_t variable, variables, cdr, x_caller_profile, x_caller_extension, x_times, time_tag, + x_application, x_callflow, x_inner_extension, x_apps; + switch_app_log_t *app_log; + char tmp[512]; int cdr_off = 0, v_off = 0; @@ -1239,6 +1242,24 @@ goto error; } + if ((app_log = switch_core_session_get_app_log(session))) { + int app_off = 0; + switch_app_log_t *ap; + + if (!(x_apps = switch_xml_add_child_d(cdr, "app_log", cdr_off++))) { + goto error; + } + for(ap = app_log; ap; ap = ap->next) { + + if (!(x_application = switch_xml_add_child_d(x_apps, "application", app_off++))) { + goto error; + } + + switch_xml_set_attr_d(x_application, "app_name", ap->app); + switch_xml_set_attr_d(x_application, "app_data", ap->arg); + } + } + for (hi = switch_channel_variable_first(channel, switch_core_session_get_pool(session)); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, &vvar, NULL, &vval); if (vvar && vval) { @@ -1263,6 +1284,7 @@ if (!(x_callflow = switch_xml_add_child_d(cdr, "callflow", cdr_off++))) { goto error; } + switch_xml_set_attr_d(x_callflow, "dialplan", caller_profile->dialplan); if (caller_profile->caller_extension) { switch_caller_application_t *ap; @@ -1287,8 +1309,47 @@ switch_xml_set_attr_d(x_application, "app_name", ap->application_name); switch_xml_set_attr_d(x_application, "app_data", ap->application_data); } + + if (caller_profile->caller_extension->children) { + switch_caller_profile_t *cp = NULL; + int i_off = 0; + for (cp = caller_profile->caller_extension->children; cp; cp = cp->next) { + switch_caller_application_t *ap; + int app_off = 0; + + if (!cp->caller_extension) { + continue; + } + if (!(x_inner_extension = switch_xml_add_child_d(x_caller_extension, "sub_extensions", i_off++))) { + goto error; + } + + if (!(x_caller_extension = switch_xml_add_child_d(x_inner_extension, "extension", cf_off++))) { + goto error; + } + switch_xml_set_attr_d(x_caller_extension, "name", cp->caller_extension->extension_name); + switch_xml_set_attr_d(x_caller_extension, "number", cp->caller_extension->extension_number); + switch_xml_set_attr_d(x_caller_extension, "dialplan", cp->dialplan); + if (cp->caller_extension->current_application) { + switch_xml_set_attr_d(x_caller_extension, "current_app", cp->caller_extension->current_application->application_name); + } + + for (ap = cp->caller_extension->applications; ap; ap = ap->next) { + if (!(x_application = switch_xml_add_child_d(x_caller_extension, "application", app_off++))) { + goto error; + } + if (ap == cp->caller_extension->current_application) { + switch_xml_set_attr_d(x_application, "last_executed", "true"); + } + switch_xml_set_attr_d(x_application, "app_name", ap->application_name); + switch_xml_set_attr_d(x_application, "app_data", ap->application_data); + } + } + } + } + if (!(x_caller_profile = switch_xml_add_child_d(x_callflow, "caller_profile", cf_off++))) { goto error; } @@ -1342,6 +1403,9 @@ caller_profile = caller_profile->next; } + + + *xml_cdr = cdr; return SWITCH_STATUS_SUCCESS; Modified: freeswitch/trunk/src/switch_ivr_menu.c ============================================================================== --- freeswitch/trunk/src/switch_ivr_menu.c (original) +++ freeswitch/trunk/src/switch_ivr_menu.c Fri Apr 20 21:03:58 2007 @@ -397,7 +397,7 @@ if (app_name && app_arg) { if ((application_interface = switch_loadable_module_get_application_interface(app_name))) { if (application_interface->application_function) { - application_interface->application_function(session, app_arg); + switch_core_session_exec(session, application_interface, app_arg); } } } Modified: freeswitch/trunk/src/switch_ivr_originate.c ============================================================================== --- freeswitch/trunk/src/switch_ivr_originate.c (original) +++ freeswitch/trunk/src/switch_ivr_originate.c Fri Apr 20 21:03:58 2007 @@ -107,7 +107,8 @@ goto wbreak; } - application_interface->application_function(collect->session, app_data); + switch_core_session_exec(collect->session, application_interface, app_data); + if (switch_channel_get_state(channel) < CS_HANGUP) { switch_channel_set_flag(channel, CF_WINNER); }