]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add 'show tasks' and sched_api api commands
authorAnthony Minessale <anthony.minessale@gmail.com>
Fri, 30 Mar 2007 00:10:33 +0000 (00:10 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Fri, 30 Mar 2007 00:10:33 +0000 (00:10 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4797 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_types.h
src/mod/applications/mod_commands/mod_commands.c
src/switch_core_sqldb.c
src/switch_core_state_machine.c
src/switch_event.c
src/switch_ivr_async.c
src/switch_scheduler.c

index 2260ca3174a283325a62fda1707f395e8ba255d8..36f1c02e86fc61fa51385fdc17a8cdeeb1ffd731 100644 (file)
@@ -797,6 +797,10 @@ typedef enum {
        SWITCH_EVENT_PRIVATE_COMMAND    - A private command event 
        SWITCH_EVENT_HEARTBEAT                  - Machine is alive
        SWITCH_EVENT_TRAP                               - Error Trap
+       SWITCH_EVENT_ADD_SCHEDULE               - Something has been scheduled
+       SWITCH_EVENT_DEL_SCHEDULE               - Something has been unscheduled
+       SWITCH_EVENT_EXE_SCHEDULE               - Something scheduled has been executed
+       SWITCH_EVENT_RE_SCHEDULE                - Something scheduled has been rescheduled
     SWITCH_EVENT_ALL                           - All events at once
 </pre>
 
@@ -839,6 +843,10 @@ typedef enum {
        SWITCH_EVENT_PRIVATE_COMMAND,
        SWITCH_EVENT_HEARTBEAT,
        SWITCH_EVENT_TRAP,
+       SWITCH_EVENT_ADD_SCHEDULE,
+       SWITCH_EVENT_DEL_SCHEDULE,
+       SWITCH_EVENT_EXE_SCHEDULE,
+       SWITCH_EVENT_RE_SCHEDULE,
        SWITCH_EVENT_ALL
 } switch_event_types_t;
 
index 856d2fa97d913f78ea4c810f499dc986f484e859..b4049d26c852bff278e4886602eddc605437e22c 100644 (file)
@@ -696,6 +696,56 @@ static switch_status_t originate_function(char *cmd, switch_core_session_t *ises
        return SWITCH_STATUS_SUCCESS;;
 }
 
+static void sch_api_callback(switch_scheduler_task_t *task)
+{
+       char *cmd, *arg = NULL;
+       switch_stream_handle_t stream = { 0 };
+
+       assert(task);
+
+       cmd = (char *) task->cmd_arg;
+       
+       if ((arg = strchr(cmd, ' '))) {
+               *arg++ = '\0';
+       }
+
+       SWITCH_STANDARD_STREAM(stream);
+       switch_api_execute(cmd, arg, NULL, &stream);
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Command %s(%s):\n%s\n", cmd, arg, switch_str_nil((char *)stream.data));
+       switch_safe_free(stream.data);
+}
+
+static switch_status_t sched_api_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+{
+       char *tm = NULL, *dcmd;
+       time_t when;
+
+       assert(cmd != NULL);
+       tm = strdup(cmd);
+       assert(tm != NULL);
+       
+       if ((dcmd = strchr(tm, ' '))) {
+               uint32_t id;
+
+               *dcmd++ = '\0';
+
+               if (*tm == '+') {
+                       when = time(NULL) + atol(tm + 1);
+               } else {
+                       when = atol(tm);
+               }
+               id = switch_scheduler_add_task(when, sch_api_callback, (char *) __SWITCH_FUNC__, dcmd, 0, strdup(dcmd), SSHF_FREE_ARG);
+               stream->write_function(stream, "Added task %u\n", id);
+       } else {
+               stream->write_function(stream, "Invalid syntax\n");
+       }       
+
+       switch_safe_free(tm);
+       
+       return SWITCH_STATUS_SUCCESS;
+}
+
+
 struct holder {
        switch_stream_handle_t *stream;
        char *http;
@@ -769,6 +819,8 @@ static switch_status_t show_function(char *cmd, switch_core_session_t *session,
                return SWITCH_STATUS_SUCCESS;
        } else if (!strcmp(cmd, "codec") || !strcmp(cmd, "dialplan") || !strcmp(cmd, "file") || !strcmp(cmd, "timer")) {
                sprintf(sql, "select type, name from interfaces where type = '%s'", cmd);
+       } else if (!strcmp(cmd, "tasks")) {
+               sprintf(sql, "select * from %s", cmd);
        } else if (!strcmp(cmd, "application") || !strcmp(cmd, "api")) {
                sprintf(sql, "select name, description, syntax from interfaces where type = '%s' and description != ''", cmd);
        } else if (!strcmp(cmd, "calls")) {
@@ -849,12 +901,20 @@ static switch_status_t help_function(char *cmd, switch_core_session_t *session,
        return SWITCH_STATUS_SUCCESS;
 }
 
+static switch_api_interface_t sched_api_api_interface = {
+       /*.interface_name */ "sched_api",
+       /*.desc */ "Schedule an api command",
+       /*.function */ sched_api_function,
+       /*.syntax */ "[+]<time> <command string>",
+       /*.next */ NULL
+};
+
 static switch_api_interface_t sched_transfer_api_interface = {
        /*.interface_name */ "sched_transfer",
        /*.desc */ "Schedule a broadcast event to a running call",
        /*.function */ sched_transfer_function,
        /*.syntax */ "[+]<time> <uuid> <extension> [<dialplan>] [<context>]",
-       /*.next */ NULL
+       /*.next */ &sched_api_api_interface
 };
 
 static switch_api_interface_t sched_broadcast_api_interface = {
index 2406c7cfd16e310dd642aa894b543e113179f1fd..d2601215c64f4933268710310072549c878e7632 100644 (file)
@@ -225,8 +225,25 @@ static void core_event_handler(switch_event_t *event)
        char *sql = NULL;
 
        switch (event->event_id) {
+       case SWITCH_EVENT_ADD_SCHEDULE:
+               sql = switch_mprintf("insert into tasks values('%q','%q','%q','%q')",
+                                                        switch_event_get_header(event, "task-id"),
+                                                        switch_event_get_header(event, "task-desc"),
+                                                        switch_event_get_header(event, "task-group"),
+                                                        switch_event_get_header(event, "task-runtime")
+                                                        );
+               break;
+       case SWITCH_EVENT_DEL_SCHEDULE:
+       case SWITCH_EVENT_EXE_SCHEDULE:
+               sql = switch_mprintf("delete from tasks where task_id=%q", switch_event_get_header(event, "task-id"));
+               break;
+       case SWITCH_EVENT_RE_SCHEDULE:
+               sql = switch_mprintf("update tasks set task_runtime='%q' where task_id=%q",
+                                                        switch_event_get_header(event, "task-runtime"),
+                                                        switch_event_get_header(event, "task-id"));
+               break;
        case SWITCH_EVENT_CHANNEL_DESTROY:
-               sql = switch_mprintf("delete from channels where uuid='%s'", switch_event_get_header(event, "unique-id"));
+               sql = switch_mprintf("delete from channels where uuid='%q'", switch_event_get_header(event, "unique-id"));
                break;
        case SWITCH_EVENT_CHANNEL_CREATE:
                sql = switch_mprintf("insert into channels (uuid,created,name,state) values('%q','%q','%q','%q')",
@@ -375,14 +392,23 @@ SWITCH_DECLARE(void) switch_core_sqldb_start(switch_memory_pool_t *pool)
                        "   type             VARCHAR(255),\n"
                        "   name             VARCHAR(255),\n"
                        "   description      VARCHAR(255),\n" "   syntax           VARCHAR(255)\n" ");\n";
+               char create_tasks_sql[] =
+                       "CREATE TABLE tasks (\n"
+                       "   task_id             INTEGER(4),\n"
+                       "   task_desc           VARCHAR(255),\n"
+                       "   task_group          VARCHAR(255),\n"
+                       "   task_runtime        INTEGER(8)\n"
+                       ");\n";
 
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening DB\n");
                switch_core_db_exec(runtime.db, "drop table channels", NULL, NULL, NULL);
                switch_core_db_exec(runtime.db, "drop table calls", NULL, NULL, NULL);
                switch_core_db_exec(runtime.db, "drop table interfaces", NULL, NULL, NULL);
+               switch_core_db_exec(runtime.db, "drop table tasks", NULL, NULL, NULL);
                switch_core_db_exec(runtime.db, create_channels_sql, NULL, NULL, NULL);
                switch_core_db_exec(runtime.db, create_calls_sql, NULL, NULL, NULL);
                switch_core_db_exec(runtime.db, create_interfaces_sql, NULL, NULL, NULL);
+               switch_core_db_exec(runtime.db, create_tasks_sql, NULL, NULL, NULL);
                if (switch_event_bind("core_db", SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL) !=
                        SWITCH_STATUS_SUCCESS) {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind event handler!\n");
index b444221d53ce14d3847168f608661ea62ac5ed97..d73974cad8c955d28ffd2d7b9bc78190bb52fb64 100644 (file)
@@ -134,6 +134,13 @@ static void switch_core_standard_on_execute(switch_core_session_t *session)
                        switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
                        return;
                }
+               
+               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);
+                       switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+                       return;
+               }
 
                if (!application_interface->application_function) {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Function for %s\n",
index 2c7fb82d7e8f4b3414dc5040111d2de481f5dc58..bb9ec11daad6c327ffd167fe3504fb9de85b719c 100644 (file)
@@ -133,6 +133,10 @@ static char *EVENT_NAMES[] = {
        "PRIVATE_COMMAND",
        "HEARTBEAT",
        "TRAP",
+       "ADD_SCHEDULE",
+       "DEL_SCHEDULE",
+       "EXE_SCHEDULE",
+       "RE_SCHEDULE",
        "ALL"
 };
 
index 853a28aa2f6dacb519c11decd054778a0ccc70c7..2502e4046eb9971106adf9a86e47b2c46265173b 100644 (file)
@@ -795,3 +795,5 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(char *uuid, char *path, swi
        return SWITCH_STATUS_SUCCESS;
 
 }
+
+
index 3b6fbb5e26bc6ffc490d4adb864ea7b2f69f52a7..9b6a3ca445954e38b6ae44952628885e5d16177a 100644 (file)
@@ -22,15 +22,30 @@ static struct {
        switch_memory_pool_t *memory_pool;
 } globals;
 
-static void switch_scheduler_execute(switch_scheduler_task_container_t * tp)
+static void switch_scheduler_execute(switch_scheduler_task_container_t *tp)
 {
+       switch_event_t *event;
        //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Executing task %u %s (%s)\n", tp->task.task_id, tp->desc, switch_str_nil(tp->task.group));
 
        tp->func(&tp->task);
 
        if (tp->task.runtime > tp->executed) {
                tp->executed = 0;
+               if (switch_event_create(&event, SWITCH_EVENT_RE_SCHEDULE) == SWITCH_STATUS_SUCCESS) {
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tp->task.task_id);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Desc", "%s", tp->desc);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Group", "%s", switch_str_nil(tp->task.group));
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Runtime", "%" TIME_T_FMT, tp->task.runtime);
+                       switch_event_fire(&event);
+               }
        } else {
+               if (switch_event_create(&event, SWITCH_EVENT_DEL_SCHEDULE) == SWITCH_STATUS_SUCCESS) {
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tp->task.task_id);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Desc", "%s", tp->desc);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Group", "%s", switch_str_nil(tp->task.group));
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Runtime", "%" TIME_T_FMT, tp->task.runtime);
+                       switch_event_fire(&event);
+               }
                tp->destroyed = 1;
        }
 }
@@ -134,6 +149,7 @@ SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime,
                                                                                                   uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags)
 {
        switch_scheduler_task_container_t *container, *tp;
+       switch_event_t *event;
 
        switch_mutex_lock(globals.task_mutex);
        switch_zmalloc(container, sizeof(*container));
@@ -163,7 +179,13 @@ SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime,
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Added task %u %s (%s) to run at %" TIME_T_FMT "\n",
                                          tp->task.task_id, tp->desc, switch_str_nil(tp->task.group), task_runtime);
 
-
+       if (switch_event_create(&event, SWITCH_EVENT_ADD_SCHEDULE) == SWITCH_STATUS_SUCCESS) {
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tp->task.task_id);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Desc", "%s", tp->desc);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Group", "%s", switch_str_nil(tp->task.group));
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Runtime", "%" TIME_T_FMT, tp->task.runtime);
+               switch_event_fire(&event);
+       }
        return container->task.task_id;
 }
 
@@ -171,11 +193,19 @@ SWITCH_DECLARE(switch_status_t) switch_scheduler_del_task_id(uint32_t task_id)
 {
        switch_scheduler_task_container_t *tp;
        switch_status_t status = SWITCH_STATUS_FALSE;
+       switch_event_t *event;
 
        switch_mutex_lock(globals.task_mutex);
        for (tp = globals.task_list; tp; tp = tp->next) {
                if (tp->task.task_id == task_id) {
                        tp->destroyed++;
+                       if (switch_event_create(&event, SWITCH_EVENT_DEL_SCHEDULE) == SWITCH_STATUS_SUCCESS) {
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tp->task.task_id);
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Desc", "%s", tp->desc);
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Group", "%s", switch_str_nil(tp->task.group));
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Runtime", "%" TIME_T_FMT, tp->task.runtime);
+                               switch_event_fire(&event);
+                       }
                        status = SWITCH_STATUS_SUCCESS;
                        break;
                }
@@ -189,10 +219,18 @@ SWITCH_DECLARE(switch_status_t) switch_scheduler_del_task_group(char *group)
 {
        switch_scheduler_task_container_t *tp;
        switch_status_t status = SWITCH_STATUS_FALSE;
+       switch_event_t *event;
 
        switch_mutex_lock(globals.task_mutex);
        for (tp = globals.task_list; tp; tp = tp->next) {
                if (!strcmp(tp->task.group, group)) {
+                       if (switch_event_create(&event, SWITCH_EVENT_DEL_SCHEDULE) == SWITCH_STATUS_SUCCESS) {
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tp->task.task_id);
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Desc", "%s", tp->desc);
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Group", "%s", switch_str_nil(tp->task.group));
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Runtime", "%" TIME_T_FMT, tp->task.runtime);
+                               switch_event_fire(&event);
+                       }
                        tp->destroyed++;
                        status = SWITCH_STATUS_SUCCESS;
                }