aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2003-06-27 23:07:59 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2003-06-27 23:07:59 +0000
commitefde31a9908909b35ee154afe257030a56a6c520 (patch)
treea217001e6144b8c4d66ff283eb7456692247eb58 /apps
parentd148cde249b23d61820b91fd6baf483848cf6985 (diff)
Merge dynamic queue support
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@1127 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps')
-rwxr-xr-xapps/app_queue.c240
1 files changed, 240 insertions, 0 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c
index d98320145..a51338542 100755
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -35,6 +35,8 @@
#include <sys/signal.h>
#include <netinet/in.h>
+#include <tonezone.h>
+
#include <pthread.h>
#define DEFAULT_RETRY 5
@@ -63,6 +65,28 @@ static char *descrip =
" The optionnal URL will be sent to the called party if the channel supports\n"
"it.\n";
+// [PHM 06/26/03]
+static char *app_aqm = "AddQueueMember" ;
+static char *app_aqm_synopsis = "Dynamically adds queue members" ;
+static char *app_aqm_descrip =
+" AddQueueMember(queuename[|interface]):\n"
+"Dynamically adds interface to an existing queue\n"
+"Returns -1 if there is an error.\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"
+"Dynamically removes interface to an existing queue\n"
+"Returns -1 if there is an error.\n"
+"Example: RemoveQueueMember(techsupport|SIP/3000)\n"
+"";
+
+
+
+
/* We define a customer "local user" structure because we
use it not only for keeping track of what is in use but
also for keeping track of who we're dialing. */
@@ -643,6 +667,217 @@ static int valid_exit(struct queue_ent *qe, char digit)
return 0;
}
+// [PHM 06/26/03]
+
+static struct member * interface_exists( struct ast_call_queue * q, char * interface )
+{
+ struct member * ret = NULL ;
+ struct member *mem;
+ char buf[500] ;
+
+ if( q != NULL )
+ {
+ mem = q->members ;
+
+ while( mem != NULL ) {
+ sprintf( buf, "%s/%s", mem->tech, mem->loc);
+
+ if( strcmp( buf, interface ) == 0 ) {
+ ret = mem ;
+ break ;
+ }
+ else
+ mem = mem->next ;
+ }
+ }
+
+ return( ret ) ;
+}
+
+
+static struct member * create_queue_node( char * interface )
+{
+ struct member * cur ;
+ char * tmp ;
+
+ /* Add a new member */
+
+ cur = malloc(sizeof(struct member));
+
+ if (cur) {
+ memset(cur, 0, sizeof(struct member));
+ strncpy(cur->tech, interface, sizeof(cur->tech) - 1);
+ if ((tmp = strchr(cur->tech, '/')))
+ *tmp = '\0';
+ if ((tmp = strchr(interface, '/'))) {
+ tmp++;
+ strncpy(cur->loc, tmp, sizeof(cur->loc) - 1);
+ } else
+ ast_log(LOG_WARNING, "No location at interface '%s'\n", interface);
+ }
+
+ return( cur ) ;
+}
+
+
+static int rqm_exec(struct ast_channel *chan, void *data)
+{
+ int res=-1;
+ struct localuser *u;
+ char *queuename;
+ struct member * node ;
+ struct member * look ;
+ char info[512];
+ char *interface=NULL;
+ struct ast_call_queue *q;
+ int found=0 ;
+
+ if (!data) {
+ ast_log(LOG_WARNING, "RemoveQueueMember requires an argument (queuename|optional interface)\n");
+ return -1;
+ }
+
+ LOCAL_USER_ADD(u); // not sure if we need this, but better be safe than sorry ;-)
+
+ /* Parse our arguments XXX Check for failure XXX */
+ strncpy(info, (char *)data, strlen((char *)data) + AST_MAX_EXTENSION-1);
+ queuename = info;
+ if (queuename) {
+ interface = strchr(queuename, '|');
+ if (interface) {
+ *interface = '\0';
+ interface++;
+ }
+ else
+ interface = chan->name ;
+ }
+
+ if( ( q = queues) != NULL )
+ {
+ while( q && ( res != 0 ) && (!found) )
+ {
+ ast_pthread_mutex_lock(&q->lock);
+ if( strcmp( q->name, queuename) == 0 )
+ {
+ // found queue, try to remove interface
+ found=1 ;
+
+ if( ( node = interface_exists( q, interface ) ) != NULL )
+ {
+ if( ( look = q->members ) == node )
+ {
+ // 1st
+ q->members = node->next;
+ }
+ else
+ {
+ while( look != NULL )
+ if( look->next == node )
+ {
+ look->next = node->next ;
+ break ;
+ }
+ else
+ look = look->next ;
+ }
+
+ free( node ) ;
+
+ ast_log(LOG_NOTICE, "Removed interface '%s' to queue '%s'\n",
+ interface, queuename);
+ res = 0 ;
+ }
+ else
+ ast_log(LOG_WARNING, "Unable to remove interface '%s' from queue '%s': "
+ "Not there\n", interface, queuename);
+ }
+
+ ast_pthread_mutex_unlock(&q->lock);
+ q = q->next;
+ }
+ }
+
+ if( ! found )
+ ast_log(LOG_WARNING, "Unable to remove interface from queue '%s': No such queue\n", queuename);
+
+ LOCAL_USER_REMOVE(u);
+ return res;
+}
+
+
+
+static int aqm_exec(struct ast_channel *chan, void *data)
+{
+ int res=-1;
+ struct localuser *u;
+ char *queuename;
+ char info[512];
+ char *interface=NULL;
+ struct ast_call_queue *q;
+ struct member *save;
+ int found=0 ;
+
+ if (!data) {
+ ast_log(LOG_WARNING, "AddQueueMember requires an argument (queuename|optional interface)\n");
+ return -1;
+ }
+
+ LOCAL_USER_ADD(u); // not sure if we need this, but better be safe than sorry ;-)
+
+ /* Parse our arguments XXX Check for failure XXX */
+ strncpy(info, (char *)data, strlen((char *)data) + AST_MAX_EXTENSION-1);
+ queuename = info;
+ if (queuename) {
+ interface = strchr(queuename, '|');
+ if (interface) {
+ *interface = '\0';
+ interface++;
+ }
+ else
+ interface = chan->name ;
+ }
+
+ if( ( q = queues) != NULL )
+ {
+ while( q && ( res != 0 ) && (!found) )
+ {
+ ast_pthread_mutex_lock(&q->lock);
+ if( strcmp( q->name, queuename) == 0 )
+ {
+ // found queue, try to enable interface
+ found=1 ;
+
+ if( interface_exists( q, interface ) == NULL )
+ {
+ save = q->members ;
+ q->members = create_queue_node( interface ) ;
+
+ if( q->members != NULL )
+ q->members->next = save ;
+ else
+ q->members = save ;
+
+ ast_log(LOG_NOTICE, "Added interface '%s' to queue '%s'\n", interface, queuename);
+ res = 0 ;
+ }
+ else
+ ast_log(LOG_WARNING, "Unable to add interface '%s' to queue '%s': "
+ "Already there\n", interface, queuename);
+ }
+
+ ast_pthread_mutex_unlock(&q->lock);
+ q = q->next;
+ }
+ }
+
+ if( ! found )
+ ast_log(LOG_WARNING, "Unable to add interface to queue '%s': No such queue\n", queuename);
+
+ LOCAL_USER_REMOVE(u);
+ return res;
+}
+
+
static int queue_exec(struct ast_channel *chan, void *data)
{
int res=-1;
@@ -944,11 +1179,16 @@ int load_module(void)
if (!res) {
ast_cli_register(&cli_show_queues);
ast_manager_register( "Queues", 0, manager_queues_show, "Queues" );
+
+ // [PHM 06/26/03]
+ ast_register_application(app_aqm, aqm_exec, app_aqm_synopsis, app_aqm_descrip) ;
+ ast_register_application(app_rqm, rqm_exec, app_rqm_synopsis, app_rqm_descrip) ;
}
reload_queues();
return res;
}
+
int reload(void)
{
reload_queues();