Merge dynamic queue support

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@1127 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Mark Spencer 2003-06-27 23:07:59 +00:00
parent f945ae2122
commit 71c9cbb2b1

View file

@ -35,6 +35,8 @@
#include <sys/signal.h> #include <sys/signal.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <tonezone.h>
#include <pthread.h> #include <pthread.h>
#define DEFAULT_RETRY 5 #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" " The optionnal URL will be sent to the called party if the channel supports\n"
"it.\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 /* We define a customer "local user" structure because we
use it not only for keeping track of what is in use but use it not only for keeping track of what is in use but
also for keeping track of who we're dialing. */ 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; 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) static int queue_exec(struct ast_channel *chan, void *data)
{ {
int res=-1; int res=-1;
@ -944,11 +1179,16 @@ int load_module(void)
if (!res) { if (!res) {
ast_cli_register(&cli_show_queues); ast_cli_register(&cli_show_queues);
ast_manager_register( "Queues", 0, manager_queues_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(); reload_queues();
return res; return res;
} }
int reload(void) int reload(void)
{ {
reload_queues(); reload_queues();