From cc11a78869eb2f0b5f75330c426b62cbfecb88fd Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Fri, 3 Oct 2014 18:54:53 +0000 Subject: app_queue: Add dialplan function to get the channel name at the specified position in a queue. The QUEUE_GET_CHANNEL function returns the caller's channel name at the specified position in a queue. QUEUE_GET_CHANNEL([,]) The queue position parameter defaults to 1 if not specified. Noop(${QUEUE_GET_CHANNEL(queuename, 2)}) "SIP/peer-00000002", if queue exist and have at least 2 callers Noop(${QUEUE_GET_CHANNEL(queuename, 1)}) Noop(${QUEUE_GET_CHANNEL(queuename)}) "SIP/peer-00000000", if queue exist and have at least 1 caller ASTERISK-24365 #close Reported by: Kristian Hogh Patches: queue_get_firstchannel.patch (license #6639) patch uploaded by Kristian Hogh rb4035.patch (license #6639) patch uploaded by Kristian Hogh Patch morphed from QUEUE_GET_FIRSTCHANEL to the more general QUEUE_GET_CHANNEL on reviewbord. Review: https://reviewboard.asterisk.org/r/4035/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@424493 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_queue.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/apps/app_queue.c b/apps/app_queue.c index 9647fcdbf..0540ee5fc 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -287,6 +287,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") QUEUE_MEMBER QUEUE_MEMBER_COUNT QUEUE_EXISTS + QUEUE_GET_CHANNEL QUEUE_WAITING_COUNT QUEUE_MEMBER_LIST QUEUE_MEMBER_PENALTY @@ -328,6 +329,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") QUEUE_MEMBER QUEUE_MEMBER_COUNT QUEUE_EXISTS + QUEUE_GET_CHANNEL QUEUE_WAITING_COUNT QUEUE_MEMBER_LIST QUEUE_MEMBER_PENALTY @@ -365,6 +367,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") QUEUE_MEMBER QUEUE_MEMBER_COUNT QUEUE_EXISTS + QUEUE_GET_CHANNEL QUEUE_WAITING_COUNT QUEUE_MEMBER_LIST QUEUE_MEMBER_PENALTY @@ -409,6 +412,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") QUEUE_MEMBER QUEUE_MEMBER_COUNT QUEUE_EXISTS + QUEUE_GET_CHANNEL QUEUE_WAITING_COUNT QUEUE_MEMBER_LIST QUEUE_MEMBER_PENALTY @@ -450,6 +454,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") QUEUE_MEMBER QUEUE_MEMBER_COUNT QUEUE_EXISTS + QUEUE_GET_CHANNEL QUEUE_WAITING_COUNT QUEUE_MEMBER_LIST QUEUE_MEMBER_PENALTY @@ -481,6 +486,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") QUEUE_MEMBER QUEUE_MEMBER_COUNT QUEUE_EXISTS + QUEUE_GET_CHANNEL QUEUE_WAITING_COUNT QUEUE_MEMBER_LIST QUEUE_MEMBER_PENALTY @@ -535,6 +541,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") QUEUE_MEMBER QUEUE_MEMBER_COUNT QUEUE_EXISTS + QUEUE_GET_CHANNEL QUEUE_WAITING_COUNT QUEUE_MEMBER_LIST QUEUE_MEMBER_PENALTY @@ -591,6 +598,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") QUEUE_MEMBER QUEUE_MEMBER_COUNT QUEUE_EXISTS + QUEUE_GET_CHANNEL QUEUE_WAITING_COUNT QUEUE_MEMBER_LIST QUEUE_MEMBER_PENALTY @@ -618,6 +626,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") QUEUE_MEMBER QUEUE_MEMBER_COUNT QUEUE_EXISTS + QUEUE_GET_CHANNEL QUEUE_WAITING_COUNT QUEUE_MEMBER_LIST QUEUE_MEMBER_PENALTY @@ -633,6 +642,35 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") Returns 1 if the specified queue exists, 0 if it does not + + Queue + QueueLog + AddQueueMember + RemoveQueueMember + PauseQueueMember + UnpauseQueueMember + QUEUE_VARIABLES + QUEUE_MEMBER + QUEUE_MEMBER_COUNT + QUEUE_EXISTS + QUEUE_GET_CHANNEL + QUEUE_WAITING_COUNT + QUEUE_MEMBER_LIST + QUEUE_MEMBER_PENALTY + + + + + Return caller at the specified position in a queue. + + + + + + + Returns the caller channel at position in the specified queuename. + If position is unspecified the first channel is returned. + Queue QueueLog @@ -670,6 +708,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") QUEUE_MEMBER QUEUE_MEMBER_COUNT QUEUE_EXISTS + QUEUE_GET_CHANNEL QUEUE_WAITING_COUNT QUEUE_MEMBER_LIST QUEUE_MEMBER_PENALTY @@ -696,6 +735,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") QUEUE_MEMBER QUEUE_MEMBER_COUNT QUEUE_EXISTS + QUEUE_GET_CHANNEL QUEUE_WAITING_COUNT QUEUE_MEMBER_LIST QUEUE_MEMBER_PENALTY @@ -724,6 +764,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") QUEUE_MEMBER QUEUE_MEMBER_COUNT QUEUE_EXISTS + QUEUE_GET_CHANNEL QUEUE_WAITING_COUNT QUEUE_MEMBER_LIST QUEUE_MEMBER_PENALTY @@ -8287,6 +8328,85 @@ static int queue_function_qac_dep(struct ast_channel *chan, const char *cmd, cha return 0; } +/*! \brief Dialplan function QUEUE_GET_CHANNEL() Get caller channel waiting at specified position in the queue */ +static int queue_function_queuegetchannel(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) +{ + int position; + char *parse; + struct call_queue *q; + struct ast_variable *var; + + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(queuename); + AST_APP_ARG(position); + ); + + buf[0] = '\0'; + + if (ast_strlen_zero(data)) { + ast_log(LOG_ERROR, "Missing argument. QUEUE_GET_CHANNEL(,)\n"); + return -1; + } + + parse = ast_strdupa(data); + AST_STANDARD_APP_ARGS(args, parse); + + if (ast_strlen_zero(args.queuename)) { + ast_log (LOG_ERROR, "The parameter is required.\n"); + return -1; + } + + if (ast_strlen_zero(args.position)) { + position = 1; + } else { + if (sscanf(args.position, "%30d", &position) != 1) { + ast_log (LOG_ERROR, " parameter must be an integer.\n"); + return -1; + } + if (position < 1) { + ast_log (LOG_ERROR, " parameter must be an integer greater than zero.\n"); + return -1; + } + } + + { + struct call_queue tmpq = { + .name = args.queuename, + }; + + q = ao2_t_find(queues, &tmpq, OBJ_POINTER, "Find for QUEUE_GET_CHANNEL()"); + } + if (q) { + ao2_lock(q); + if (q->count >= position) { + struct queue_ent *qe; + + for (qe = q->head; qe; qe = qe->next) { + if (qe->pos == position) { + ast_copy_string(buf, ast_channel_name(qe->chan), len); + break; + } + } + } + ao2_unlock(q); + queue_t_unref(q, "Done with reference in QUEUE_GET_CHANNEL()"); + return 0; + } + + var = ast_load_realtime("queues", "name", args.queuename, SENTINEL); + if (var) { + /* if the queue is realtime but was not found in memory, this + * means that the queue had been deleted from memory since it was + * "dead." + */ + ast_variables_destroy(var); + return 0; + } + + ast_log(LOG_WARNING, "queue %s was not found\n", args.queuename); + return 0; +} + /*! \brief Dialplan function QUEUE_WAITING_COUNT() Get number callers waiting in a specific queue */ static int queue_function_queuewaitingcount(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) { @@ -8464,6 +8584,11 @@ static struct ast_custom_function queuemembercount_dep = { .read = queue_function_qac_dep, }; +static struct ast_custom_function queuegetchannel_function = { + .name = "QUEUE_GET_CHANNEL", + .read = queue_function_queuegetchannel, +}; + static struct ast_custom_function queuewaitingcount_function = { .name = "QUEUE_WAITING_COUNT", .read = queue_function_queuewaitingcount, @@ -10679,6 +10804,7 @@ static int unload_module(void) ast_custom_function_unregister(&queuemembercount_function); ast_custom_function_unregister(&queuemembercount_dep); ast_custom_function_unregister(&queuememberlist_function); + ast_custom_function_unregister(&queuegetchannel_function); ast_custom_function_unregister(&queuewaitingcount_function); ast_custom_function_unregister(&queuememberpenalty_function); @@ -10779,6 +10905,7 @@ static int load_module(void) err |= ast_custom_function_register(&queuemembercount_function); err |= ast_custom_function_register(&queuemembercount_dep); err |= ast_custom_function_register(&queuememberlist_function); + err |= ast_custom_function_register(&queuegetchannel_function); err |= ast_custom_function_register(&queuewaitingcount_function); err |= ast_custom_function_register(&queuememberpenalty_function); -- cgit v1.2.3