Index: CHANGES
===================================================================
--- CHANGES (revision 270257)
+++ CHANGES (working copy)
@@ -1475,6 +1475,8 @@
of the URI parameter to the AGI function call in your dial plan. Also note
that specifying a port number in the AGI URI will disable SRV lookups,
even if you use the hagi: protocol.
+ * Added PARK command to park a call via AGI. Accepts the same options as the
+ dialplan command. Returns the parking lot slot number if successful.
Logger changes
--------------
Index: include/asterisk/features.h
===================================================================
--- include/asterisk/features.h (revision 270257)
+++ include/asterisk/features.h (working copy)
@@ -105,9 +105,23 @@
*/
int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *host, int timeout, int *extout);
-/*!
+/*!
+ * \brief Park a call via a masqueraded channel with parking arguments
+ * \param rchan the real channel to be parked
+ * \param host the channel to have the parking read to.
+ * \param timeout is a timeout in milliseconds
+ * \param extout is a parameter to an int that will hold the parked location, or NULL if you want.
+ * \param data is the list of options to be passed to the parking application
+ *
+ * Masquerade the channel rchan into a new, empty channel which is then parked with ast_park_call
+ * \retval 0 on success.
+ * \retval -1 on failure.
+*/
+int ast_masq_park_call_args(struct ast_channel *rchan, struct ast_channel *host, int timeout, int *extout, const char *data);
+
+/*!
* \brief Determine system parking extension
- * \returns the call parking extension for drivers that provide special call parking help
+ * \returns the call parking extension for drivers that provide special call parking help
*/
const char *ast_parking_ext(void);
Index: main/features.c
===================================================================
--- main/features.c (revision 270257)
+++ main/features.c (working copy)
@@ -1020,10 +1020,11 @@
if (!args) {
args = &park_args;
- args->timeout = timeout;
- args->extout = extout;
}
+ args->timeout = timeout;
+ args->extout = extout;
+
if ((args->pu = park_space_reserve(rchan, peer, args)) == NULL) {
if (peer)
ast_stream_and_wait(peer, "beeperr", "");
@@ -1071,15 +1072,79 @@
return 0;
}
+AST_APP_OPTIONS(park_call_options, BEGIN_OPTIONS
+ AST_APP_OPTION('r', AST_PARK_OPT_RINGING),
+ AST_APP_OPTION('R', AST_PARK_OPT_RANDOMIZE),
+ AST_APP_OPTION('s', AST_PARK_OPT_SILENCE),
+END_OPTIONS );
+
+static int parse_parking_options(const char *data, struct ast_park_call_args *args)
+{
+ char *parse = NULL;
+ struct ast_flags flags = { 0 };
+
+ AST_DECLARE_APP_ARGS(app_args,
+ AST_APP_ARG(timeout);
+ AST_APP_ARG(return_con);
+ AST_APP_ARG(return_ext);
+ AST_APP_ARG(return_pri);
+ AST_APP_ARG(options);
+ );
+
+ parse = ast_strdupa(data);
+ ast_debug(1, "Parsing parking options %s\n", parse);
+ AST_STANDARD_APP_ARGS(app_args, parse);
+
+ if (parse) {
+ if (!ast_strlen_zero(app_args.timeout)) {
+ if (sscanf(app_args.timeout, "%30d", &args->timeout) != 1) {
+ ast_log(LOG_WARNING, "Invalid timeout '%s' provided\n", app_args.timeout);
+ args->timeout = 0;
+ }
+ ast_debug(1, "Parking lot timeout: %d\n", args->timeout);
+ }
+ if (!ast_strlen_zero(app_args.return_con)) {
+ args->return_con = app_args.return_con;
+ }
+ ast_debug(1, "Return Context: %s\n", args->return_con);
+ if (!ast_strlen_zero(app_args.return_ext)) {
+ args->return_ext = app_args.return_ext;
+ }
+ if (!ast_strlen_zero(app_args.return_pri)) {
+ if (sscanf(app_args.return_pri, "%30d", &args->return_pri) != 1) {
+ ast_log(LOG_WARNING, "Invalid priority '%s' specified\n", app_args.return_pri);
+ args->return_pri = 0;
+ }
+ }
+ }
+
+ ast_app_parse_options(park_call_options, &flags, NULL, app_args.options);
+ ast_debug(1, "Return Context Again: %s\n", args->return_con);
+ args->flags = flags.flags;
+ ast_debug(1, "Flags: %d\n", flags.flags);
+
+ return 0;
+}
+
/* Park call via masqueraded channel */
int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
{
return masq_park_call(rchan, peer, timeout, extout, 0, NULL);
}
+/* Park call via masqueraded channel with arguments */
+int ast_masq_park_call_args(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout, const char *data)
+{
+ struct ast_park_call_args args = {
+ .orig_chan_name = ast_strdupa(rchan->name),
+ };
+ parse_parking_options(data, &args);
+ return masq_park_call(rchan, peer, timeout, extout, 0, &args);
+}
+
static int masq_park_call_announce_args(struct ast_channel *rchan, struct ast_channel *peer, struct ast_park_call_args *args)
{
- return masq_park_call(rchan, peer, 0, NULL, 1, args);
+ return masq_park_call(rchan, peer, args->timeout, args->extout, 1, args);
}
static int masq_park_call_announce(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
@@ -3780,12 +3845,6 @@
return copylot;
}
-AST_APP_OPTIONS(park_call_options, BEGIN_OPTIONS
- AST_APP_OPTION('r', AST_PARK_OPT_RINGING),
- AST_APP_OPTION('R', AST_PARK_OPT_RANDOMIZE),
- AST_APP_OPTION('s', AST_PARK_OPT_SILENCE),
-END_OPTIONS );
-
/*! \brief Park a call */
static int park_call_exec(struct ast_channel *chan, const char *data)
{
@@ -3800,18 +3859,6 @@
lot context eventually */
int res = 0;
- char *parse = NULL;
- AST_DECLARE_APP_ARGS(app_args,
- AST_APP_ARG(timeout);
- AST_APP_ARG(return_con);
- AST_APP_ARG(return_ext);
- AST_APP_ARG(return_pri);
- AST_APP_ARG(options);
- );
-
- parse = ast_strdupa(data);
- AST_STANDARD_APP_ARGS(app_args, parse);
-
ast_copy_string(orig_exten, chan->exten, sizeof(orig_exten));
/* Setup the exten/priority to be s/1 since we don't know
@@ -3832,32 +3879,9 @@
struct ast_park_call_args args = {
.orig_chan_name = orig_chan_name,
};
- struct ast_flags flags = { 0 };
- if (parse) {
- if (!ast_strlen_zero(app_args.timeout)) {
- if (sscanf(app_args.timeout, "%30d", &args.timeout) != 1) {
- ast_log(LOG_WARNING, "Invalid timeout '%s' provided\n", app_args.timeout);
- args.timeout = 0;
- }
- }
- if (!ast_strlen_zero(app_args.return_con)) {
- args.return_con = app_args.return_con;
- }
- if (!ast_strlen_zero(app_args.return_ext)) {
- args.return_ext = app_args.return_ext;
- }
- if (!ast_strlen_zero(app_args.return_pri)) {
- if (sscanf(app_args.return_pri, "%30d", &args.return_pri) != 1) {
- ast_log(LOG_WARNING, "Invalid priority '%s' specified\n", app_args.return_pri);
- args.return_pri = 0;
- }
- }
- }
+ parse_parking_options(data, &args);
- ast_app_parse_options(park_call_options, &flags, NULL, app_args.options);
- args.flags = flags.flags;
-
res = masq_park_call_announce_args(chan, chan, &args);
/* Continue on in the dialplan */
if (res == 1) {
Index: res/res_agi.c
===================================================================
--- res/res_agi.c (revision 270257)
+++ res/res_agi.c (working copy)
@@ -316,6 +316,18 @@
Does nothing.
+
+
+ Park the current channel
+
+
+
+
+
+ Parks the current call and returns the parking lot number into into which the call was parked.
+ Returns 1 and the parking lot number if successful, 0 otherwise.
+
+
Receives one character from channels supporting it.
@@ -2629,6 +2641,25 @@
return RESULT_SUCCESS;
}
+static int handle_park(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
+{
+ int res;
+ int space;
+
+ if (argc == 2) {
+ res = ast_masq_park_call_args(chan, NULL, 0, &space, argv[1]);
+ } else {
+ res = ast_masq_park_call(chan, NULL, 0, &space);
+ }
+
+ if (!res) {
+ ast_agi_send(agi->fd, chan, "200 result=1 (%d)\n", space);
+ } else {
+ ast_agi_send(agi->fd, chan, "200 result=0\n");
+ }
+ return RESULT_SUCCESS;
+}
+
static int handle_setmusic(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
{
if (argc < 3) {
@@ -2946,9 +2977,10 @@
{ { "get", "variable", NULL }, handle_getvariable, NULL, NULL, 1 },
{ { "hangup", NULL }, handle_hangup, NULL, NULL, 0 },
{ { "noop", NULL }, handle_noop, NULL, NULL, 1 },
+ { { "park", NULL }, handle_park, NULL, NULL, 1 },
{ { "receive", "char", NULL }, handle_recvchar, NULL, NULL, 0 },
{ { "receive", "text", NULL }, handle_recvtext, NULL, NULL, 0 },
- { { "record", "file", NULL }, handle_recordfile, NULL, NULL, 0 },
+ { { "record", "file", NULL }, handle_recordfile, NULL, NULL, 0 },
{ { "say", "alpha", NULL }, handle_sayalpha, NULL, NULL, 0},
{ { "say", "digits", NULL }, handle_saydigits, NULL, NULL, 0 },
{ { "say", "number", NULL }, handle_saynumber, NULL, NULL, 0 },