Index: app_queue.c =================================================================== RCS file: /usr/cvsroot/asterisk/apps/app_queue.c,v retrieving revision 1.54 diff -u -r1.54 app_queue.c --- app_queue.c 8 Apr 2004 05:03:47 -0000 1.54 +++ app_queue.c 10 Apr 2004 18:25:46 -0000 @@ -1099,6 +1099,68 @@ return( cur ) ; } +/* Determine the extension a caller is coming from for dynamic + * queue addition */ +static int qm_determine_extension(struct ast_channel *chan, char **interface) { + char tmpchan[512]; + char *start, *end; + + *interface = NULL; + + // Copy it so we can mangle it + strncpy(tmpchan, chan->name, sizeof(tmpchan) - 1); + + /* SIP/exten-XXXX or Skinny/exten@peer-XXXX */ + if(!strncmp(tmpchan, "SIP", 3) || !strncmp(tmpchan, "Skinny", 6)) { + end = strrchr(tmpchan, '-'); + + if (end) + *end = '\0'; + + *interface = strdup(tmpchan); + } + + /* IAX2[user@peer]/N or IAX[user@peer]/N */ + if(!strncmp(tmpchan, "IAX", 3)) { + char *start, *end; + + start = strchr(tmpchan, '['); + end = strrchr(tmpchan, ']'); + + if(start && end) { + *start = '/'; + *end = '\0'; + *interface = strdup(tmpchan); + } + } + + /* H323/ip$AAA.BBB.CCC.DDD/NNNN or OH323/ip$AAA.BBB.CCC.DDD/NNNN */ + /* FIXME: This is a truly ugly hack, and may not even work right in all cases */ + if(!strncmp(tmpchan, "H323", 4) || !strncmp(tmpchan, "OH323", 5)) { + char callerid[512], *start, *end; + + strncpy(callerid, chan->callerid, 512); + start = strrchr(callerid, '<'); + end = strrchr(callerid, '>'); + + if(start && end) { + *start = '/'; + *end = '\0'; + strcpy(tmpchan, "H323"); + if(start) + strcat(tmpchan, start); + *interface = strdup(tmpchan); + } + } + + /* If there is no interface determined, log it and return -1 */ + if(!*interface) { + ast_log(LOG_WARNING, "Could not determine extension for channel: %s\n", tmpchan); + return -1; + } + + return 0; +} static int rqm_exec(struct ast_channel *chan, void *data) { @@ -1112,6 +1174,7 @@ char *interface=NULL; struct ast_call_queue *q; int found=0 ; + int free_interface = 0; if (!data) { ast_log(LOG_WARNING, "RemoveQueueMember requires an argument (queuename|optional interface)\n"); @@ -1130,15 +1193,12 @@ interface++; } else { - strncpy(tmpchan, chan->name, sizeof(tmpchan) - 1); - interface = strrchr(tmpchan, '-'); - if (interface) - *interface = '\0'; - interface = tmpchan; + qm_determine_extension(chan, &interface); + free_interface = 1; } } - if( ( q = queues) != NULL ) + if( ( q = queues) != NULL && interface ) { while( q && ( res != 0 ) && (!found) ) { @@ -1169,7 +1229,7 @@ free( node ) ; - ast_log(LOG_NOTICE, "Removed interface '%s' to queue '%s'\n", + ast_log(LOG_NOTICE, "Removed interface '%s' from queue '%s'\n", interface, queuename); res = 0 ; } @@ -1183,15 +1243,19 @@ } } - if( ! found ) + if( ! found && interface ) ast_log(LOG_WARNING, "Unable to remove interface from queue '%s': No such queue\n", queuename); + if( ! interface ) + ast_log(LOG_WARNING, "Nobody was removed from queue '%s' since no extension could be determined\n", queuename); + else + if(free_interface) + free(interface); + LOCAL_USER_REMOVE(u); return res; } - - static int aqm_exec(struct ast_channel *chan, void *data) { int res=-1; @@ -1203,6 +1267,7 @@ struct ast_call_queue *q; struct member *save; int found=0 ; + int free_interface = 0; if (!data) { ast_log(LOG_WARNING, "AddQueueMember requires an argument (queuename|optional interface)\n"); @@ -1221,15 +1286,12 @@ interface++; } else { - strncpy(tmpchan, chan->name, sizeof(tmpchan) - 1); - interface = strrchr(tmpchan, '-'); - if (interface) - *interface = '\0'; - interface = tmpchan; + qm_determine_extension(chan, &interface); + free_interface = 1; } } - if( ( q = queues) != NULL ) + if( ( q = queues) != NULL && interface ) { while( q && ( res != 0 ) && (!found) ) { @@ -1263,9 +1325,15 @@ } } - if( ! found ) + if( ! found && interface ) ast_log(LOG_WARNING, "Unable to add interface to queue '%s': No such queue\n", queuename); + if( ! interface ) + ast_log(LOG_WARNING, "Nobody was added to queue '%s' since no extension could be determined\n", queuename); + else + if(free_interface) + free(interface); + LOCAL_USER_REMOVE(u); return res; }