Index: apps/app_queue.c =================================================================== RCS file: /usr/cvsroot/asterisk/apps/app_queue.c,v retrieving revision 1.176 diff -u -r1.176 app_queue.c --- apps/app_queue.c 6 Nov 2005 15:09:46 -0000 1.176 +++ apps/app_queue.c 7 Nov 2005 09:49:51 -0000 @@ -74,6 +74,8 @@ #include "asterisk/channel.h" #include "asterisk/pbx.h" #include "asterisk/options.h" +#include "asterisk/app.h" +#include "asterisk/linkedlists.h" #include "asterisk/module.h" #include "asterisk/translate.h" #include "asterisk/say.h" @@ -152,29 +154,41 @@ static char *app_aqm = "AddQueueMember" ; static char *app_aqm_synopsis = "Dynamically adds queue members" ; static char *app_aqm_descrip = -" AddQueueMember(queuename[|interface[|penalty]]):\n" +" AddQueueMember(queuename[|[interface]|[penalty][|options]]):\n" "Dynamically adds interface to an existing queue.\n" "If the interface is already in the queue and there exists an n+101 priority\n" "then it will then jump to this priority. Otherwise it will return an error\n" "Returns -1 if there is an error.\n" +"The option string may contain zero or the following character:\n" +" 'j' -- jump to +101 priority when appropriate.\n" +" This application sets the following channel variable upon completion:\n" +" AQMSTATUS The status of the attempt to add a queue member as a \n" +" text string, one of\n" +" ADDED | MEMBERALREADY | NOSUCHQUEUE \n" "Example: AddQueueMember(techsupport|SIP/3000)\n" ""; static char *app_rqm = "RemoveQueueMember" ; static char *app_rqm_synopsis = "Dynamically removes queue members" ; static char *app_rqm_descrip = -" RemoveQueueMember(queuename[|interface]):\n" +" RemoveQueueMember(queuename[|interface[|options]]):\n" "Dynamically removes interface to an existing queue\n" "If the interface is NOT in the queue and there exists an n+101 priority\n" "then it will then jump to this priority. Otherwise it will return an error\n" "Returns -1 if there is an error.\n" +"The option string may contain zero or the following character:\n" +" 'j' -- jump to +101 priority when appropriate.\n" +" This application sets the following channel variable upon completion:\n" +" RQMSTATUS The status of the attempt to remove a queue member as a\n" +" text string, one of\n" +" REMOVED | NOTINQUEUE | NOSUCHQUEUE \n" "Example: RemoveQueueMember(techsupport|SIP/3000)\n" ""; static char *app_pqm = "PauseQueueMember" ; static char *app_pqm_synopsis = "Pauses a queue member" ; static char *app_pqm_descrip = -" PauseQueueMember([queuename]|interface):\n" +" PauseQueueMember([queuename]|interface[|options]):\n" "Pauses (blocks calls for) a queue member.\n" "The given interface will be paused in the given queue. This prevents\n" "any calls from being sent from the queue to the interface until it is\n" @@ -184,15 +198,27 @@ "is given and the interface is not in any queue, it will jump to\n" " priority n+101, if it exists. Returns -1 if the interface is not\n" "found and no extension to jump to exists, 0 otherwise.\n" +"The option string may contain zero or the following character:\n" +" 'j' -- jump to +101 priority when appropriate.\n" +" This application sets the following channel variable upon completion:\n" +" PQMSTATUS The status of the attempt to pause a queue member as a\n" +" text string, one of\n" +" PAUSED | NOTFOUND\n" "Example: PauseQueueMember(|SIP/3000)\n"; static char *app_upqm = "UnpauseQueueMember" ; static char *app_upqm_synopsis = "Unpauses a queue member" ; static char *app_upqm_descrip = -" UnpauseQueueMember([queuename]|interface):\n" +" UnpauseQueueMember([queuename]|interface[|options]):\n" "Unpauses (resumes calls to) a queue member.\n" "This is the counterpart to PauseQueueMember and operates exactly the\n" "same way, except it unpauses instead of pausing the given interface.\n" +"The option string may contain zero or the following character:\n" +" 'j' -- jump to +101 priority when appropriate.\n" +" This application sets the following channel variable upon completion:\n" +" UPQMSTATUS The status of the attempt to unpause a queue \n" +" member as a text string, one of\n" +" UNPAUSED | NOTFOUND\n" "Example: UnpauseQueueMember(|SIP/3000)\n"; /*! \brief Persistent Members astdb family */ @@ -246,6 +272,7 @@ LOCAL_USER_DECL; + struct queue_ent { struct ast_call_queue *parent; /*!< What queue is our parent */ char moh[80]; /*!< Name of musiconhold to be used */ @@ -2557,88 +2584,112 @@ static int pqm_exec(struct ast_channel *chan, void *data) { struct localuser *u; - char *queuename, *interface; + char *parse; + int priority_jump = 0; + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(queuename); + AST_APP_ARG(interface); + AST_APP_ARG(options); + ); if (ast_strlen_zero(data)) { - ast_log(LOG_WARNING, "PauseQueueMember requires an argument ([queuename]|interface])\n"); + ast_log(LOG_WARNING, "PauseQueueMember requires an argument ([queuename]|interface[|options])\n"); return -1; } LOCAL_USER_ADD(u); - queuename = ast_strdupa((char *)data); - if (!queuename) { - ast_log(LOG_ERROR, "Out of memory\n"); + if (!(parse = ast_strdupa(data))) { + ast_log(LOG_WARNING, "Memory Error!\n"); LOCAL_USER_REMOVE(u); return -1; } - interface = strchr(queuename, '|'); - if (!interface) { - ast_log(LOG_WARNING, "Missing interface argument to PauseQueueMember ([queuename]|interface])\n"); + AST_STANDARD_APP_ARGS(args, parse); + + if (args.options) { + if (strchr(args.options, 'j')) + priority_jump = 1; + } + + if (ast_strlen_zero(args.interface)) { + ast_log(LOG_WARNING, "Missing interface argument to PauseQueueMember ([queuename]|interface[|options])\n"); LOCAL_USER_REMOVE(u); return -1; } - *interface = '\0'; - interface++; - - if (set_member_paused(queuename, interface, 1)) { - ast_log(LOG_WARNING, "Attempt to pause interface %s, not found\n", interface); - if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) { - LOCAL_USER_REMOVE(u); - return 0; + if (set_member_paused(args.queuename, args.interface, 1)) { + ast_log(LOG_WARNING, "Attempt to pause interface %s, not found\n", args.interface); + if (priority_jump || option_priority_jumping) { + if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) { + pbx_builtin_setvar_helper(chan, "PQMSTATUS", "NOTFOUND"); + LOCAL_USER_REMOVE(u); + return 0; + } } LOCAL_USER_REMOVE(u); + pbx_builtin_setvar_helper(chan, "PQMSTATUS", "NOTFOUND"); return -1; } LOCAL_USER_REMOVE(u); - + pbx_builtin_setvar_helper(chan, "PQMSTATUS", "PAUSED"); return 0; } static int upqm_exec(struct ast_channel *chan, void *data) { struct localuser *u; - char *queuename, *interface; + char *parse; + int priority_jump = 0; + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(queuename); + AST_APP_ARG(interface); + AST_APP_ARG(options); + ); if (ast_strlen_zero(data)) { - ast_log(LOG_WARNING, "UnpauseQueueMember requires an argument ([queuename]|interface])\n"); + ast_log(LOG_WARNING, "UnpauseQueueMember requires an argument ([queuename]|interface[|options])\n"); return -1; } LOCAL_USER_ADD(u); - queuename = ast_strdupa((char *)data); - if (!queuename) { - ast_log(LOG_ERROR, "Out of memory\n"); + if (!(parse = ast_strdupa(data))) { + ast_log(LOG_WARNING, "Memory Error!\n"); LOCAL_USER_REMOVE(u); return -1; } - interface = strchr(queuename, '|'); - if (!interface) { - ast_log(LOG_WARNING, "Missing interface argument to PauseQueueMember ([queuename]|interface])\n"); + AST_STANDARD_APP_ARGS(args, parse); + + if (args.options) { + if (strchr(args.options, 'j')) + priority_jump = 1; + } + + if (ast_strlen_zero(args.interface)) { + ast_log(LOG_WARNING, "Missing interface argument to PauseQueueMember ([queuename]|interface[|options])\n"); LOCAL_USER_REMOVE(u); return -1; } - *interface = '\0'; - interface++; - - if (set_member_paused(queuename, interface, 0)) { - ast_log(LOG_WARNING, "Attempt to unpause interface %s, not found\n", interface); - if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) { - LOCAL_USER_REMOVE(u); - return 0; + if (set_member_paused(args.queuename, args.interface, 0)) { + ast_log(LOG_WARNING, "Attempt to unpause interface %s, not found\n", args.interface); + if (priority_jump || option_priority_jumping) { + if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) { + pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "NOTFOUND"); + LOCAL_USER_REMOVE(u); + return 0; + } } LOCAL_USER_REMOVE(u); + pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "NOTFOUND"); return -1; } LOCAL_USER_REMOVE(u); - + pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "UNPAUSED"); return 0; } @@ -2646,52 +2697,58 @@ { int res=-1; struct localuser *u; - char *info, *queuename; - char tmpchan[256]=""; - char *interface = NULL; + char *parse, *temppos = NULL; + int priority_jump = 0; + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(queuename); + AST_APP_ARG(interface); + AST_APP_ARG(options); + ); + if (ast_strlen_zero(data)) { - ast_log(LOG_WARNING, "RemoveQueueMember requires an argument (queuename[|interface])\n"); + ast_log(LOG_WARNING, "RemoveQueueMember requires an argument (queuename[|interface[|options]])\n"); return -1; } LOCAL_USER_ADD(u); - info = ast_strdupa(data); - if (!info) { - ast_log(LOG_ERROR, "Out of memory\n"); + if (!(parse = ast_strdupa(data))) { + ast_log(LOG_WARNING, "Memory Error!\n"); LOCAL_USER_REMOVE(u); return -1; } - queuename = info; - if (queuename) { - interface = strchr(queuename, '|'); - if (interface) { - *interface = '\0'; - interface++; - } - else { - ast_copy_string(tmpchan, chan->name, sizeof(tmpchan)); - interface = strrchr(tmpchan, '-'); - if (interface) - *interface = '\0'; - interface = tmpchan; - } + AST_STANDARD_APP_ARGS(args, parse); + + if (ast_strlen_zero(args.interface)) { + ast_copy_string(args.interface, chan->name, sizeof(args.interface)); + temppos = strrchr(args.interface, '-'); + if (temppos) + *temppos = '\0'; } - switch (remove_from_queue(queuename, interface)) { + if (args.options) { + if (strchr(args.options, 'j')) + priority_jump = 1; + } + + switch (remove_from_queue(args.queuename, args.interface)) { case RES_OKAY: - ast_log(LOG_NOTICE, "Removed interface '%s' from queue '%s'\n", interface, queuename); + ast_log(LOG_NOTICE, "Removed interface '%s' from queue '%s'\n", args.interface, args.queuename); + pbx_builtin_setvar_helper(chan, "RQMSTATUS", "REMOVED"); res = 0; break; case RES_EXISTS: - ast_log(LOG_WARNING, "Unable to remove interface '%s' from queue '%s': Not there\n", interface, queuename); - ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101); + ast_log(LOG_WARNING, "Unable to remove interface '%s' from queue '%s': Not there\n", args.interface, args.queuename); + if (priority_jump || option_priority_jumping) + ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101); + pbx_builtin_setvar_helper(chan, "RQMSTATUS", "NOTINQUEUE"); res = 0; break; case RES_NOSUCHQUEUE: - ast_log(LOG_WARNING, "Unable to remove interface from queue '%s': No such queue\n", queuename); + ast_log(LOG_WARNING, "Unable to remove interface from queue '%s': No such queue\n", args.queuename); + pbx_builtin_setvar_helper(chan, "RQMSTATUS", "NOSUCHQUEUE"); res = 0; break; case RES_OUTOFMEMORY: @@ -2707,72 +2764,71 @@ { int res=-1; struct localuser *u; - char *queuename; - char *info; - char tmpchan[512]=""; - char *interface=NULL; - char *penaltys=NULL; + char *parse, *temppos = NULL; + int priority_jump = 0; + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(queuename); + AST_APP_ARG(interface); + AST_APP_ARG(penalty); + AST_APP_ARG(options); + ); int penalty = 0; if (ast_strlen_zero(data)) { - ast_log(LOG_WARNING, "AddQueueMember requires an argument (queuename[|[interface][|penalty]])\n"); + ast_log(LOG_WARNING, "AddQueueMember requires an argument (queuename[|[interface]|[penalty][|options]])\n"); return -1; } LOCAL_USER_ADD(u); - info = ast_strdupa(data); - if (!info) { - ast_log(LOG_ERROR, "Out of memory\n"); + if (!(parse = ast_strdupa(data))) { + ast_log(LOG_WARNING, "Memory Error!\n"); LOCAL_USER_REMOVE(u); return -1; } - queuename = info; - if (queuename) { - interface = strchr(queuename, '|'); - if (interface) { - *interface = '\0'; - interface++; - } - if (interface) { - penaltys = strchr(interface, '|'); - if (penaltys) { - *penaltys = '\0'; - penaltys++; - } - } - if (ast_strlen_zero(interface)) { - ast_copy_string(tmpchan, chan->name, sizeof(tmpchan)); - interface = strrchr(tmpchan, '-'); - if (interface) - *interface = '\0'; - interface = tmpchan; - } - if (!ast_strlen_zero(penaltys)) { - if ((sscanf(penaltys, "%d", &penalty) != 1) || penalty < 0) { - ast_log(LOG_WARNING, "Penalty '%s' is invalid, must be an integer >= 0\n", penaltys); - penalty = 0; - } + AST_STANDARD_APP_ARGS(args, parse); + + if (ast_strlen_zero(args.interface)) { + ast_copy_string(args.interface, chan->name, sizeof(args.interface)); + temppos = strrchr(args.interface, '-'); + if (temppos) + *temppos = '\0'; + } + + if (!ast_strlen_zero(args.penalty)) { + if ((sscanf(args.penalty, "%d", &penalty) != 1) || penalty < 0) { + ast_log(LOG_WARNING, "Penalty '%s' is invalid, must be an integer >= 0\n", args.penalty); + penalty = 0; } } + + if (args.options) { + if (strchr(args.options, 'j')) + priority_jump = 1; + } - switch (add_to_queue(queuename, interface, penalty, 0, queue_persistent_members)) { + + switch (add_to_queue(args.queuename, args.interface, penalty, 0, queue_persistent_members)) { case RES_OKAY: - ast_log(LOG_NOTICE, "Added interface '%s' to queue '%s'\n", interface, queuename); + ast_log(LOG_NOTICE, "Added interface '%s' to queue '%s'\n", args.interface, args.queuename); + pbx_builtin_setvar_helper(chan, "AQMSTATUS", "ADDED"); res = 0; break; case RES_EXISTS: - ast_log(LOG_WARNING, "Unable to add interface '%s' to queue '%s': Already there\n", interface, queuename); - ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101); + ast_log(LOG_WARNING, "Unable to add interface '%s' to queue '%s': Already there\n", args.interface, args.queuename); + if (priority_jump || option_priority_jumping) + ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101); + pbx_builtin_setvar_helper(chan, "AQMSTATUS", "MEMBERALREADY"); res = 0; break; case RES_NOSUCHQUEUE: - ast_log(LOG_WARNING, "Unable to add interface to queue '%s': No such queue\n", queuename); + ast_log(LOG_WARNING, "Unable to add interface to queue '%s': No such queue\n", args.queuename); + pbx_builtin_setvar_helper(chan, "AQMSTATUS", "NOSUCHQUEUE"); res = 0; break; case RES_OUTOFMEMORY: - ast_log(LOG_ERROR, "Out of memory adding member %s to queue %s\n", interface, queuename); + ast_log(LOG_ERROR, "Out of memory adding member %s to queue %s\n", args.interface, args.queuename); break; }