Index: include/asterisk/features.h =================================================================== --- include/asterisk/features.h (revision 253109) +++ include/asterisk/features.h (working copy) @@ -106,6 +106,20 @@ 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, void *data); + +/*! * \brief Determine system parking extension * \returns the call parking extension for drivers that provide special call parking help */ Index: main/features.c =================================================================== --- main/features.c (revision 253109) +++ main/features.c (working copy) @@ -1019,10 +1019,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", ""); @@ -1076,9 +1077,19 @@ 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, void *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) @@ -3766,6 +3777,54 @@ AST_APP_OPTION('s', AST_PARK_OPT_SILENCE), END_OPTIONS ); +static int parse_parking_options(char *data, struct ast_park_call_args *args) +{ + 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_log(LOG_WARNING, "Parsing parking options %s\n", parse); + AST_STANDARD_APP_ARGS(app_args, parse); + 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; + } +ast_log(LOG_WARNING, "Timeout: %d\n", args->timeout); + } + if (!ast_strlen_zero(app_args.return_con)) { + args->return_con = app_args.return_con; + } +ast_log(LOG_WARNING, "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_log(LOG_WARNING, "Return Context Again: %s\n", args->return_con); + args->flags = flags.flags; +ast_log(LOG_WARNING, "Flags: %d\n", flags.flags); + + return 0; +} + + /*! \brief Park a call */ static int park_call_exec(struct ast_channel *chan, const char *data) { @@ -3780,18 +3839,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 @@ -3812,32 +3859,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 253109) +++ res/res_agi.c (working copy) @@ -2629,6 +2629,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,6 +2965,7 @@ { { "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 },