[Freeswitch-svn] [commit] r4993 - in freeswitch/trunk/src: . include mod/applications/mod_dptools mod/applications/mod_enum mod/dialplans/mod_dialplan_directory mod/dialplans/mod_dialplan_xml
Freeswitch SVN
anthm at freeswitch.org
Fri Apr 20 19:45:14 EDT 2007
Author: anthm
Date: Fri Apr 20 19:45:14 2007
New Revision: 4993
Modified:
freeswitch/trunk/src/include/switch_core.h
freeswitch/trunk/src/include/switch_types.h
freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
freeswitch/trunk/src/mod/applications/mod_enum/mod_enum.c
freeswitch/trunk/src/mod/dialplans/mod_dialplan_directory/mod_dialplan_directory.c
freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
freeswitch/trunk/src/switch_core_session.c
freeswitch/trunk/src/switch_core_state_machine.c
Log:
add new execute_extension application to execute another extension in the current scope
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 19:45:14 2007
@@ -565,6 +565,8 @@
*/
SWITCH_DECLARE(switch_status_t) switch_core_session_event_send(char *uuid_str, switch_event_t **event);
+SWITCH_DECLARE(switch_status_t) switch_core_session_execute_exten(switch_core_session_t *session, char *exten, char *dialplan, char *context);
+
/*!
\brief Send an event to a session translating it to it's native message format
\param session the session to receive the event
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 19:45:14 2007
@@ -999,7 +999,7 @@
typedef switch_bool_t (*switch_media_bug_callback_t) (switch_media_bug_t *, void *, switch_abc_type_t);
typedef void (*switch_application_function_t) (switch_core_session_t *, char *);
typedef void (*switch_event_callback_t) (switch_event_t *);
-typedef switch_caller_extension_t *(*switch_dialplan_hunt_function_t) (switch_core_session_t *, void *);
+typedef switch_caller_extension_t *(*switch_dialplan_hunt_function_t) (switch_core_session_t *, void *, switch_caller_profile_t *);
typedef struct switch_scheduler_task switch_scheduler_task_t;
typedef void (*switch_scheduler_func_t) (switch_scheduler_task_t *task);
typedef switch_status_t (*switch_state_handler_t) (switch_core_session_t *);
Modified: freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c Fri Apr 20 19:45:14 2007
@@ -36,6 +36,7 @@
static const char modname[] = "mod_dptools";
static const switch_application_interface_t detect_speech_application_interface;
+static const switch_application_interface_t exe_application_interface;
static void detect_speech_function(switch_core_session_t *session, char *data)
{
@@ -64,6 +65,26 @@
}
+static void exe_function(switch_core_session_t *session, char *data)
+{
+ char *argv[4];
+ int argc;
+ char *lbuf = NULL;
+ char *extension;
+ char *context;
+ char *dialplan;
+
+ if (data && (lbuf = switch_core_session_strdup(session, data))
+ && (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
+ extension = argv[0];
+ dialplan = argv[1];
+ context = argv[2];
+ switch_core_session_execute_exten(session, extension, dialplan, context);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Usage: %s\n", exe_application_interface.syntax);
+ }
+}
+
static void ring_ready_function(switch_core_session_t *session, char *data)
{
switch_channel_t *channel;
@@ -606,7 +627,7 @@
}
-static switch_api_interface_t strepoch_api_interface = {
+static const switch_api_interface_t strepoch_api_interface = {
/*.interface_name */ "strepoch",
/*.desc */ "Convert a date string into epoch time",
/*.function */ strepoch_api_function,
@@ -614,7 +635,7 @@
/*.next */ NULL
};
-static switch_api_interface_t chat_api_interface = {
+static const switch_api_interface_t chat_api_interface = {
/*.interface_name */ "chat",
/*.desc */ "chat",
/*.function */ chat_api_function,
@@ -622,7 +643,7 @@
/*.next */ &strepoch_api_interface
};
-static switch_api_interface_t dptools_api_interface = {
+static const switch_api_interface_t dptools_api_interface = {
/*.interface_name */ "strftime",
/*.desc */ "strftime",
/*.function */ strftime_api_function,
@@ -630,7 +651,7 @@
/*.next */ &chat_api_interface
};
-static switch_api_interface_t presence_api_interface = {
+static const switch_api_interface_t presence_api_interface = {
/*.interface_name */ "presence",
/*.desc */ "presence",
/*.function */ presence_api_function,
@@ -639,18 +660,27 @@
};
+static const switch_application_interface_t exe_application_interface = {
+ /*.interface_name */ "execute_extension",
+ /*.application_function */ exe_function,
+ /*.long_desc */ "Execute an extension",
+ /*.short_desc */ "Execute an extension",
+ /*.syntax */ "<extension> <dialplan> <context>",
+ /* flags */ SAF_SUPPORT_NOMEDIA,
+ /*.next */
+};
-static switch_application_interface_t sched_transfer_application_interface = {
+static const switch_application_interface_t sched_transfer_application_interface = {
/*.interface_name */ "sched_transfer",
/*.application_function */ sched_transfer_function,
/*.long_desc */ "Schedule a transfer in the future",
/*.short_desc */ "Schedule a transfer in the future",
/*.syntax */ "[+]<time> <extension> <dialplan> <context>",
/* flags */ SAF_SUPPORT_NOMEDIA,
- /*.next */ NULL
+ /*.next */ &exe_application_interface
};
-static switch_application_interface_t sched_broadcast_application_interface = {
+static const switch_application_interface_t sched_broadcast_application_interface = {
/*.interface_name */ "sched_broadcast",
/*.application_function */ sched_broadcast_function,
/*.long_desc */ "Schedule a broadcast in the future",
@@ -660,7 +690,7 @@
/*.next */ &sched_transfer_application_interface
};
-static switch_application_interface_t sched_hangup_application_interface = {
+static const switch_application_interface_t sched_hangup_application_interface = {
/*.interface_name */ "sched_hangup",
/*.application_function */ sched_hangup_function,
/*.long_desc */ "Schedule a hangup in the future",
Modified: freeswitch/trunk/src/mod/applications/mod_enum/mod_enum.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_enum/mod_enum.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_enum/mod_enum.c Fri Apr 20 19:45:14 2007
@@ -519,10 +519,9 @@
}
-static switch_caller_extension_t *enum_dialplan_hunt(switch_core_session_t *session, void *arg)
+static switch_caller_extension_t *enum_dialplan_hunt(switch_core_session_t *session, void *arg, switch_caller_profile_t *caller_profile)
{
switch_caller_extension_t *extension = NULL;
- switch_caller_profile_t *caller_profile;
enum_record_t *results, *rp;
switch_channel_t *channel = switch_core_session_get_channel(session);
enum_route_t *rtp;
@@ -530,7 +529,9 @@
assert(channel != NULL);
- caller_profile = switch_channel_get_caller_profile(channel);
+ if (!caller_profile) {
+ caller_profile = switch_channel_get_caller_profile(channel);
+ }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ENUM Lookup on %s\n", caller_profile->destination_number);
Modified: freeswitch/trunk/src/mod/dialplans/mod_dialplan_directory/mod_dialplan_directory.c
==============================================================================
--- freeswitch/trunk/src/mod/dialplans/mod_dialplan_directory/mod_dialplan_directory.c (original)
+++ freeswitch/trunk/src/mod/dialplans/mod_dialplan_directory/mod_dialplan_directory.c Fri Apr 20 19:45:14 2007
@@ -83,9 +83,8 @@
switch_xml_free(xml);
}
-static switch_caller_extension_t *directory_dialplan_hunt(switch_core_session_t *session, void *arg)
+static switch_caller_extension_t *directory_dialplan_hunt(switch_core_session_t *session, void *arg, switch_caller_profile_t *caller_profile)
{
- switch_caller_profile_t *caller_profile;
switch_caller_extension_t *extension = NULL;
switch_channel_t *channel;
char *var, *val;
@@ -97,8 +96,10 @@
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
- caller_profile = switch_channel_get_caller_profile(channel);
-
+ if (!caller_profile) {
+ caller_profile = switch_channel_get_caller_profile(channel);
+ }
+
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Hello %s You Dialed %s!\n", caller_profile->caller_id_name,
caller_profile->destination_number);
Modified: freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
==============================================================================
--- freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c (original)
+++ freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c Fri Apr 20 19:45:14 2007
@@ -43,17 +43,15 @@
BREAK_NEVER
} break_t;
-static int parse_exten(switch_core_session_t *session, switch_xml_t xexten, switch_caller_extension_t **extension)
+static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *caller_profile, switch_xml_t xexten, switch_caller_extension_t **extension)
{
switch_xml_t xcond, xaction;
- switch_caller_profile_t *caller_profile;
switch_channel_t *channel;
char *exten_name = (char *) switch_xml_attr_soft(xexten, "name");
int proceed = 0;
switch_stream_handle_t stream = { 0 };
channel = switch_core_session_get_channel(session);
- caller_profile = switch_channel_get_caller_profile(channel);
for (xcond = switch_xml_child(xexten, "condition"); xcond; xcond = xcond->next) {
char *field = NULL;
@@ -291,24 +289,26 @@
return status;
}
-static switch_caller_extension_t *dialplan_hunt(switch_core_session_t *session, void *arg)
+static switch_caller_extension_t *dialplan_hunt(switch_core_session_t *session, void *arg, switch_caller_profile_t *caller_profile)
{
- switch_caller_profile_t *caller_profile;
switch_caller_extension_t *extension = NULL;
switch_channel_t *channel;
switch_xml_t alt_root = NULL, cfg, xml = NULL, xcontext, xexten;
char *alt_path = (char *) arg;
-
+
channel = switch_core_session_get_channel(session);
- if ((caller_profile = switch_channel_get_caller_profile(channel))) {
- if (!caller_profile->context) {
- caller_profile->context = "default";
+ if (!caller_profile) {
+ if (!(caller_profile = switch_channel_get_caller_profile(channel))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Obtaining Profile!\n");
+ goto done;
}
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Obtaining Profile!\n");
- goto done;
}
+
+ if (!caller_profile->context) {
+ caller_profile->context = "default";
+ }
+
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Processing %s->%s!\n", caller_profile->caller_id_name, caller_profile->destination_number);
@@ -352,7 +352,7 @@
int proceed = 0;
char *cont = (char *) switch_xml_attr_soft(xexten, "continue");
- proceed = parse_exten(session, xexten, &extension);
+ proceed = parse_exten(session, caller_profile, xexten, &extension);
if (proceed && !switch_true(cont)) {
break;
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 19:45:14 2007
@@ -871,3 +871,121 @@
switch_core_hash_init(&runtime.session_table, runtime.memory_pool);
switch_mutex_init(&runtime.session_table_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
}
+
+
+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_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))) {
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ new_profile = switch_caller_profile_clone(session, profile);
+ new_profile->destination_number = switch_core_session_strdup(session, exten);
+
+ if (!switch_strlen_zero(dialplan)) {
+ new_profile->dialplan = switch_core_session_strdup(session, dialplan);
+ }
+
+ if (!switch_strlen_zero(context)) {
+ new_profile->context = switch_core_session_strdup(session, context);
+ }
+
+ if (!(dpstr = switch_core_session_strdup(session, new_profile->dialplan))) {
+ abort();
+ }
+
+ argc = switch_separate_string(dpstr, ',', dp, (sizeof(dp) / sizeof(dp[0])));
+ for (x = 0; x < argc; x++) {
+ char *dpname = dp[x];
+ char *dparg = NULL;
+
+ if (dpname) {
+ if ((dparg = strchr(dpname, ':'))) {
+ *dparg++ = '\0';
+ }
+ }
+ if (!(dialplan_interface = switch_loadable_module_get_dialplan_interface(dpname))) {
+ continue;
+ }
+
+ count++;
+
+ if ((extension = dialplan_interface->hunt_function(session, dparg, new_profile)) != 0) {
+ break;
+ }
+ }
+
+ if (!extension) {
+ return SWITCH_STATUS_FALSE;
+ }
+
+ 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));
+ if ((application_interface = switch_loadable_module_get_application_interface(extension->current_application->application_name)) == 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Application %s\n", extension->current_application->application_name);
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if (switch_channel_test_flag(session->channel, CF_NOMEDIA) && !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Application %s Cannot be used with NO_MEDIA mode!\n",
+ extension->current_application->application_name);
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if (!application_interface->application_function) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Function for %s\n", extension->current_application->application_name);
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if ((expanded =
+ switch_channel_expand_variables(session->channel,
+ extension->current_application->application_data)) != extension->current_application->application_data) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Expanded String %s(%s)\n", extension->current_application->application_name,
+ expanded);
+ }
+
+ if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE) == SWITCH_STATUS_SUCCESS) {
+ switch_channel_event_set_data(session->channel, event);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Application", "%s", extension->current_application->application_name);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Application-Data-Orig", "%s", extension->current_application->application_data);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Application-Data", "%s", expanded);
+ switch_event_fire(&event);
+ }
+
+
+ if (switch_channel_get_variable(session->channel, "presence_id")) {
+ char *arg = switch_mprintf("%s(%s)", extension->current_application->application_name, expanded);
+ if (arg) {
+ switch_channel_presence(session->channel, "unknown", arg);
+ switch_safe_free(arg);
+ }
+ }
+
+ application_interface->application_function(session, expanded);
+
+ if (expanded != extension->current_application->application_data) {
+ switch_safe_free(expanded);
+ }
+
+ extension->current_application = extension->current_application->next;
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+
+}
+
+
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 19:45:14 2007
@@ -82,7 +82,7 @@
count++;
- if ((extension = dialplan_interface->hunt_function(session, dparg)) != 0) {
+ if ((extension = dialplan_interface->hunt_function(session, dparg, NULL)) != 0) {
switch_channel_set_caller_extension(session->channel, extension);
return;
}
More information about the Freeswitch-svn
mailing list