Addition of scheduler engine and a few applications to use it.

This patch adds a scheduler thread to the core and moves the heartbeat
event to use the new scheduler as an example.

Also The following features are implemented that use this scheduler:

sched_hangup dialplan application:

<action application="sched_hangup" data="+10 normal_clearing bleg"/>

** The cause code is optional and the optional bleg keyword will only hangup the
   channel the current channel is bridged to if the call is in a bridge.

sched_transfer dialplan application:

<action application="sched_transfer" data="+10 1000 XML default"/>

** The last 2 args (dialplan and context) are optional

sched_broadcast dialplan application:

<action application="sched_broadcast" data="+10 playback:/tmp/foo.wav"/>
<action application="sched_broadcast" data="+10 playback!normal_clearing:/tmp/foo.wav"/>

** The optional !<cause_code> can be added to make the channel hangup after broadcasting the file.


sched_hangup api function:

sched_hangup +10 <uuid_string> normal_clearing

** The cause code is optional

sched_transfer api function:

sched_transfer +10 <uuid_string> 1000 XML default

** The last 2 args (dialplan and context) are optional

sched_broadcast api function:

sched_broadcast +10 <uuid_str> playback:/tmp/foo.wav
sched_broadcast +10 <uuid_str> playback!normal_clearing:/tmp/foo.wav

** The optional !<cause_code> can be added to make the channel hangup after broadcasting the file.

The new C functions in the core are documented in the doxeygen.

*NOTE* This commit should satisfy at least 2 bounties on the wiki



git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4785 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale
2007-03-28 23:37:12 +00:00
parent 24b1a46ceb
commit 8a4406ece2
9 changed files with 855 additions and 51 deletions

View File

@@ -51,6 +51,9 @@ static switch_api_interface_t originate_api_interface;
static switch_api_interface_t media_api_interface;
static switch_api_interface_t hold_api_interface;
static switch_api_interface_t broadcast_api_interface;
static switch_api_interface_t sched_broadcast_api_interface;
static switch_api_interface_t sched_transfer_api_interface;
static switch_api_interface_t sched_hangup_api_interface;
static switch_status_t status_function(char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream)
{
@@ -245,6 +248,89 @@ static switch_status_t transfer_function(char *cmd, switch_core_session_t *isess
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t sched_transfer_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
{
switch_core_session_t *session = NULL;
char *argv[6] = {0};
int argc = 0;
if (isession) {
return SWITCH_STATUS_FALSE;
}
argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
if (switch_strlen_zero(cmd) || argc < 2 || argc > 5) {
stream->write_function(stream, "USAGE: %s\n", sched_transfer_api_interface.syntax);
} else {
char *uuid = argv[1];
char *dest = argv[2];
char *dp = argv[3];
char *context = argv[4];
time_t when;
if (*argv[0] == '+') {
when = time (NULL) + atol(argv[0] + 1);
} else {
when = atol(argv[0]);
}
if ((session = switch_core_session_locate(uuid))) {
switch_ivr_schedule_transfer(when, uuid, dest, dp, context);
stream->write_function(stream, "OK\n");
switch_core_session_rwunlock(session);
} else {
stream->write_function(stream, "No Such Channel!\n");
}
}
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t sched_hangup_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
{
switch_core_session_t *session = NULL;
char *argv[4] = {0};
int argc = 0;
if (isession) {
return SWITCH_STATUS_FALSE;
}
argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
if (switch_strlen_zero(cmd) || argc < 1) {
stream->write_function(stream, "USAGE: %s\n", sched_hangup_api_interface.syntax);
} else {
char *uuid = argv[1];
char *cause_str = argv[2];
time_t when;
switch_call_cause_t cause = SWITCH_CAUSE_ALLOTTED_TIMEOUT;
if (*argv[0] == '+') {
when = time (NULL) + atol(argv[0] + 1);
} else {
when = atol(argv[0]);
}
if (cause_str) {
cause = switch_channel_str2cause(cause_str);
}
if ((session = switch_core_session_locate(uuid))) {
switch_ivr_schedule_hangup(when, uuid, cause, SWITCH_FALSE);
stream->write_function(stream, "OK\n");
switch_core_session_rwunlock(session);
} else {
stream->write_function(stream, "No Such Channel!\n");
}
}
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t uuid_media_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
{
char *argv[4] = {0};
@@ -313,6 +399,50 @@ static switch_status_t uuid_broadcast_function(char *cmd, switch_core_session_t
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t sched_broadcast_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
{
char *argv[4] = {0};
int argc = 0;
switch_status_t status = SWITCH_STATUS_FALSE;
if (isession) {
return status;
}
argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
if (switch_strlen_zero(cmd) || argc < 3) {
stream->write_function(stream, "USAGE: %s\n", sched_broadcast_api_interface.syntax);
} else {
switch_media_flag_t flags = SMF_NONE;
time_t when;
if (*argv[0] == '+') {
when = time (NULL) + atol(argv[0] + 1);
} else {
when = atol(argv[0]);
}
if (argv[3]) {
if (!strcmp(argv[3], "both")) {
flags |= (SMF_ECHO_ALEG | SMF_ECHO_BLEG);
} else if (!strcmp(argv[3], "aleg")) {
flags |= SMF_ECHO_ALEG;
} else if (!strcmp(argv[3], "bleg")) {
flags |= SMF_ECHO_BLEG;
}
} else {
flags |= SMF_ECHO_ALEG;
}
status = switch_ivr_schedule_broadcast(when, argv[1], argv[2], flags);
stream->write_function(stream, "+OK Message Scheduled\n");
}
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t uuid_hold_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
{
char *argv[4] = {0};
@@ -707,12 +837,36 @@ static switch_status_t help_function(char *cmd, switch_core_session_t *session,
return SWITCH_STATUS_SUCCESS;
}
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
};
static switch_api_interface_t sched_broadcast_api_interface = {
/*.interface_name */ "sched_broadcast",
/*.desc */ "Schedule a broadcast event to a running call",
/*.function */ sched_broadcast_function,
/*.syntax */ "[+]<time> <uuid> <path> [aleg|bleg|both]",
/*.next */ &sched_transfer_api_interface
};
static switch_api_interface_t sched_hangup_api_interface = {
/*.interface_name */ "sched_hangup",
/*.desc */ "Schedule a running call to hangup",
/*.function */ sched_hangup_function,
/*.syntax */ "[+]<time> <uuid> [<cause>]",
/*.next */ &sched_broadcast_api_interface
};
static switch_api_interface_t version_api_interface = {
/*.interface_name */ "version",
/*.desc */ "Show version of the switch",
/*.function */ version_function,
/*.syntax */ "",
/*.next */ NULL
/*.next */ &sched_hangup_api_interface
};
static switch_api_interface_t help_api_interface = {