mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-24 13:12:03 +00:00
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:
@@ -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 = {
|
||||
|
||||
@@ -96,6 +96,99 @@ static void transfer_function(switch_core_session_t *session, char *data)
|
||||
}
|
||||
}
|
||||
|
||||
static void sched_transfer_function(switch_core_session_t *session, char *data)
|
||||
{
|
||||
int argc;
|
||||
char *argv[4] = {0};
|
||||
char *mydata;
|
||||
|
||||
if (data && (mydata = switch_core_session_strdup(session, data))) {
|
||||
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 2) {
|
||||
time_t when;
|
||||
|
||||
if (*argv[0] == '+') {
|
||||
when = time (NULL) + atol(argv[0] + 1);
|
||||
} else {
|
||||
when = atol(argv[0]);
|
||||
}
|
||||
|
||||
switch_ivr_schedule_transfer(when, switch_core_session_get_uuid(session), argv[1], argv[2], argv[3]);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Args\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sched_hangup_function(switch_core_session_t *session, char *data)
|
||||
{
|
||||
int argc;
|
||||
char *argv[5] = {0};
|
||||
char *mydata;
|
||||
|
||||
if (data && (mydata = switch_core_session_strdup(session, data))) {
|
||||
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 1) {
|
||||
time_t when;
|
||||
switch_call_cause_t cause = SWITCH_CAUSE_ALLOTTED_TIMEOUT;
|
||||
switch_bool_t bleg = SWITCH_FALSE;
|
||||
|
||||
if (*argv[0] == '+') {
|
||||
when = time (NULL) + atol(argv[0] + 1);
|
||||
} else {
|
||||
when = atol(argv[0]);
|
||||
}
|
||||
|
||||
if (argv[1]) {
|
||||
cause = switch_channel_str2cause(argv[1]);
|
||||
}
|
||||
|
||||
if (argv[2] && !strcasecmp(argv[2], "bleg")) {
|
||||
bleg = SWITCH_TRUE;
|
||||
}
|
||||
|
||||
switch_ivr_schedule_hangup(when, switch_core_session_get_uuid(session), cause, bleg);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No time specified.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void sched_broadcast_function(switch_core_session_t *session, char *data)
|
||||
{
|
||||
int argc;
|
||||
char *argv[6] = {0};
|
||||
char *mydata;
|
||||
|
||||
if (data && (mydata = switch_core_session_strdup(session, data))) {
|
||||
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 2) {
|
||||
time_t when;
|
||||
switch_media_flag_t flags = SMF_NONE;
|
||||
|
||||
if (*argv[0] == '+') {
|
||||
when = time (NULL) + atol(argv[0] + 1);
|
||||
} else {
|
||||
when = atol(argv[0]);
|
||||
}
|
||||
|
||||
if (argv[2]) {
|
||||
if (!strcmp(argv[2], "both")) {
|
||||
flags |= (SMF_ECHO_ALEG | SMF_ECHO_BLEG);
|
||||
} else if (!strcmp(argv[2], "aleg")) {
|
||||
flags |= SMF_ECHO_ALEG;
|
||||
} else if (!strcmp(argv[2], "bleg")) {
|
||||
flags |= SMF_ECHO_BLEG;
|
||||
}
|
||||
} else {
|
||||
flags |= SMF_ECHO_ALEG;
|
||||
}
|
||||
|
||||
switch_ivr_schedule_broadcast(when, switch_core_session_get_uuid(session), argv[1], flags);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Args\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sleep_function(switch_core_session_t *session, char *data)
|
||||
{
|
||||
|
||||
@@ -509,6 +602,7 @@ static void ivr_application_function(switch_core_session_t *session, char *data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static switch_api_interface_t strepoch_api_interface = {
|
||||
/*.interface_name */ "strepoch",
|
||||
/*.desc */ "Convert a date string into epoch time",
|
||||
@@ -541,6 +635,39 @@ static switch_api_interface_t presence_api_interface = {
|
||||
/*.next */ &dptools_api_interface
|
||||
};
|
||||
|
||||
|
||||
|
||||
static 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
|
||||
};
|
||||
|
||||
static 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",
|
||||
/*.short_desc */ "Schedule a broadcast in the future",
|
||||
/*.syntax */ "[+]<time> <path> [aleg|bleg|both]",
|
||||
/* flags */ SAF_SUPPORT_NOMEDIA,
|
||||
/*.next */ &sched_transfer_application_interface
|
||||
};
|
||||
|
||||
static 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",
|
||||
/*.short_desc */ "Schedule a hangup in the future",
|
||||
/*.syntax */ "[+]<time> [<cause>]",
|
||||
/* flags */ SAF_SUPPORT_NOMEDIA,
|
||||
/*.next */ &sched_broadcast_application_interface
|
||||
};
|
||||
|
||||
|
||||
static const switch_application_interface_t queuedtmf_application_interface = {
|
||||
/*.interface_name */ "queue_dtmf",
|
||||
/*.application_function */ queue_dtmf_function,
|
||||
@@ -548,7 +675,7 @@ static const switch_application_interface_t queuedtmf_application_interface = {
|
||||
/* short_desc */ "Queue dtmf to be sent",
|
||||
/* syntax */ "<dtmf_data>",
|
||||
/* flags */ SAF_SUPPORT_NOMEDIA,
|
||||
/*.next */ NULL
|
||||
/*.next */ &sched_hangup_application_interface
|
||||
};
|
||||
|
||||
static const switch_application_interface_t redirect_application_interface = {
|
||||
|
||||
@@ -233,6 +233,7 @@ static void tts_function(switch_core_session_t *session, char *data)
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Done\n");
|
||||
}
|
||||
|
||||
#ifdef BUGTEST
|
||||
static switch_bool_t bug_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
|
||||
{
|
||||
switch_frame_t *frame;
|
||||
@@ -249,9 +250,11 @@ static switch_bool_t bug_callback(switch_media_bug_t *bug, void *user_data, swit
|
||||
|
||||
return SWITCH_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void bugtest_function(switch_core_session_t *session, char *data)
|
||||
{
|
||||
#ifdef BUGTEST
|
||||
switch_media_bug_t *bug;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_status_t status;
|
||||
@@ -264,6 +267,11 @@ static void bugtest_function(switch_core_session_t *session, char *data)
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
//switch_ivr_schedule_broadcast(time(NULL) + 10, switch_core_session_get_uuid(session), "/Users/anthm/sr8k.wav", SMF_ECHO_ALEG);
|
||||
//switch_ivr_schedule_transfer(time(NULL) + 10, switch_core_session_get_uuid(session), "2000", NULL, NULL);
|
||||
//switch_ivr_schedule_hangup(time(NULL) + 10, switch_core_session_get_uuid(session), SWITCH_CAUSE_ALLOTTED_TIMEOUT);
|
||||
|
||||
switch_ivr_play_file(session, NULL, data, NULL);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user