| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * Asterisk -- An open source telephony toolkit. | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * Copyright (C) 1999 - 2005, Digium, Inc. | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * Mark Spencer <markster@digium.com> | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Modified from app_zapbarge by David Troy <dave@toad.net> | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * Special thanks to comphealth.com for sponsoring this | 
					
						
							|  |  |  |  * GPL application. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * See http://www.asterisk.org for more information about
 | 
					
						
							|  |  |  |  * the Asterisk project. Please do not directly contact | 
					
						
							|  |  |  |  * any of the maintainers of this project for assistance; | 
					
						
							|  |  |  |  * the project provides a web site, mailing lists and IRC | 
					
						
							|  |  |  |  * channels for your use. | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This program is free software, distributed under the terms of | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * the GNU General Public License Version 2. See the LICENSE file | 
					
						
							|  |  |  |  * at the top of the source tree. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | /*! \file
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  |  * \brief Zap Scanner | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-12-30 21:18:06 +00:00
										 |  |  |  * \author Mark Spencer <markster@digium.com> | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-11-06 15:09:47 +00:00
										 |  |  |  * \ingroup applications | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-24 17:11:45 +00:00
										 |  |  | /*** MODULEINFO
 | 
					
						
							|  |  |  | 	<depend>zaptel</depend> | 
					
						
							|  |  |  |  ***/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-07 18:54:56 +00:00
										 |  |  | #include "asterisk.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							| 
									
										
										
										
											2005-11-08 04:48:00 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  | #include <unistd.h>
 | 
					
						
							|  |  |  | #include <errno.h>
 | 
					
						
							|  |  |  | #include <sys/ioctl.h>
 | 
					
						
							| 
									
										
										
										
											2006-07-05 16:44:41 +00:00
										 |  |  | #include <zaptel/zaptel.h>
 | 
					
						
							| 
									
										
										
										
											2004-06-04 15:44:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-06 22:39:32 +00:00
										 |  |  | #include "asterisk/lock.h"
 | 
					
						
							|  |  |  | #include "asterisk/file.h"
 | 
					
						
							|  |  |  | #include "asterisk/logger.h"
 | 
					
						
							|  |  |  | #include "asterisk/channel.h"
 | 
					
						
							|  |  |  | #include "asterisk/pbx.h"
 | 
					
						
							|  |  |  | #include "asterisk/module.h"
 | 
					
						
							|  |  |  | #include "asterisk/config.h"
 | 
					
						
							|  |  |  | #include "asterisk/app.h"
 | 
					
						
							|  |  |  | #include "asterisk/options.h"
 | 
					
						
							|  |  |  | #include "asterisk/utils.h"
 | 
					
						
							|  |  |  | #include "asterisk/cli.h"
 | 
					
						
							|  |  |  | #include "asterisk/say.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  | static char *app = "ZapScan"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *synopsis = "Scan Zap channels to monitor calls"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *descrip = | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | "  ZapScan([group]) allows a call center manager to monitor Zap channels in\n" | 
					
						
							|  |  |  | "a convenient way.  Use '#' to select the next channel and use '*' to exit\n" | 
					
						
							|  |  |  | "Limit scanning to a channel GROUP by setting the option group argument.\n"; | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define CONF_SIZE 160
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-05-20 16:30:10 +00:00
										 |  |  | static struct ast_channel *get_zap_channel_locked(int num) { | 
					
						
							| 
									
										
										
										
											2004-04-10 02:49:06 +00:00
										 |  |  | 	char name[80]; | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2004-04-10 02:49:06 +00:00
										 |  |  | 	snprintf(name,sizeof(name),"Zap/%d-1",num); | 
					
						
							| 
									
										
										
										
											2005-06-06 02:29:18 +00:00
										 |  |  | 	return ast_get_channel_by_name_locked(name); | 
					
						
							| 
									
										
										
										
											2004-04-10 02:49:06 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  | static int careful_write(int fd, unsigned char *data, int len) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 	int res; | 
					
						
							|  |  |  | 	while(len) { | 
					
						
							|  |  |  | 		res = write(fd, data, len); | 
					
						
							|  |  |  | 		if (res < 1) { | 
					
						
							|  |  |  | 			if (errno != EAGAIN) { | 
					
						
							|  |  |  | 				ast_log(LOG_WARNING, "Failed to write audio data to conference: %s\n", strerror(errno)); | 
					
						
							|  |  |  | 				return -1; | 
					
						
							|  |  |  | 			} else | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		len -= res; | 
					
						
							|  |  |  | 		data += res; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int conf_run(struct ast_channel *chan, int confno, int confflags) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 	int fd; | 
					
						
							|  |  |  | 	struct zt_confinfo ztc; | 
					
						
							|  |  |  | 	struct ast_frame *f; | 
					
						
							|  |  |  | 	struct ast_channel *c; | 
					
						
							|  |  |  | 	struct ast_frame fr; | 
					
						
							|  |  |  | 	int outfd; | 
					
						
							|  |  |  | 	int ms; | 
					
						
							|  |  |  | 	int nfds; | 
					
						
							|  |  |  | 	int res; | 
					
						
							|  |  |  | 	int flags; | 
					
						
							|  |  |  | 	int retryzap; | 
					
						
							|  |  |  | 	int origfd; | 
					
						
							|  |  |  | 	int ret = -1; | 
					
						
							|  |  |  | 	char input[4]; | 
					
						
							|  |  |  | 	int ic=0; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	ZT_BUFFERINFO bi; | 
					
						
							|  |  |  | 	char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET]; | 
					
						
							|  |  |  | 	char *buf = __buf + AST_FRIENDLY_OFFSET; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* Set it into U-law mode (write) */ | 
					
						
							|  |  |  | 	if (ast_set_write_format(chan, AST_FORMAT_ULAW) < 0) { | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Unable to set '%s' to write ulaw mode\n", chan->name); | 
					
						
							|  |  |  | 		goto outrun; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* Set it into U-law mode (read) */ | 
					
						
							|  |  |  | 	if (ast_set_read_format(chan, AST_FORMAT_ULAW) < 0) { | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Unable to set '%s' to read ulaw mode\n", chan->name); | 
					
						
							|  |  |  | 		goto outrun; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_indicate(chan, -1); | 
					
						
							| 
									
										
										
										
											2006-02-01 23:05:28 +00:00
										 |  |  | 	retryzap = strcasecmp(chan->tech->type, "Zap"); | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  |  zapretry: | 
					
						
							|  |  |  | 	origfd = chan->fds[0]; | 
					
						
							|  |  |  | 	if (retryzap) { | 
					
						
							|  |  |  | 		fd = open("/dev/zap/pseudo", O_RDWR); | 
					
						
							|  |  |  | 		if (fd < 0) { | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno)); | 
					
						
							|  |  |  | 			goto outrun; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		/* Make non-blocking */ | 
					
						
							|  |  |  | 		flags = fcntl(fd, F_GETFL); | 
					
						
							|  |  |  | 		if (flags < 0) { | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Unable to get flags: %s\n", strerror(errno)); | 
					
						
							|  |  |  | 			close(fd); | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |                         goto outrun; | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) { | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Unable to set flags: %s\n", strerror(errno)); | 
					
						
							|  |  |  | 			close(fd); | 
					
						
							|  |  |  | 			goto outrun; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		/* Setup buffering information */ | 
					
						
							|  |  |  | 		memset(&bi, 0, sizeof(bi)); | 
					
						
							|  |  |  | 		bi.bufsize = CONF_SIZE; | 
					
						
							|  |  |  | 		bi.txbufpolicy = ZT_POLICY_IMMEDIATE; | 
					
						
							|  |  |  | 		bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; | 
					
						
							|  |  |  | 		bi.numbufs = 4; | 
					
						
							|  |  |  | 		if (ioctl(fd, ZT_SET_BUFINFO, &bi)) { | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno)); | 
					
						
							|  |  |  | 			close(fd); | 
					
						
							|  |  |  | 			goto outrun; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |                 nfds = 1; | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		/* XXX Make sure we're not running on a pseudo channel XXX */ | 
					
						
							|  |  |  | 		fd = chan->fds[0]; | 
					
						
							|  |  |  | 		nfds = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	memset(&ztc, 0, sizeof(ztc)); | 
					
						
							|  |  |  | 	/* Check to see if we're in a conference... */ | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |         ztc.chan = 0; | 
					
						
							|  |  |  |         if (ioctl(fd, ZT_GETCONF, &ztc)) { | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 			ast_log(LOG_WARNING, "Error getting conference\n"); | 
					
						
							|  |  |  | 			close(fd); | 
					
						
							|  |  |  | 			goto outrun; | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (ztc.confmode) { | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 			/* Whoa, already in a conference...  Retry... */ | 
					
						
							|  |  |  | 			if (!retryzap) { | 
					
						
							|  |  |  | 				ast_log(LOG_DEBUG, "Zap channel is in a conference already, retrying with pseudo\n"); | 
					
						
							|  |  |  | 				retryzap = 1; | 
					
						
							|  |  |  | 				goto zapretry; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         memset(&ztc, 0, sizeof(ztc)); | 
					
						
							|  |  |  |         /* Add us to the conference */ | 
					
						
							|  |  |  |         ztc.chan = 0; | 
					
						
							|  |  |  |         ztc.confno = confno; | 
					
						
							|  |  |  |         ztc.confmode = ZT_CONF_MONITORBOTH; | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |         if (ioctl(fd, ZT_SETCONF, &ztc)) { | 
					
						
							|  |  |  |                 ast_log(LOG_WARNING, "Error setting conference\n"); | 
					
						
							|  |  |  |                 close(fd); | 
					
						
							|  |  |  |                 goto outrun; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         ast_log(LOG_DEBUG, "Placed channel %s in ZAP channel %d monitor\n", chan->name, confno); | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |         for(;;) { | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 			outfd = -1; | 
					
						
							|  |  |  | 			ms = -1; | 
					
						
							|  |  |  | 			c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms); | 
					
						
							|  |  |  | 			if (c) { | 
					
						
							|  |  |  | 				if (c->fds[0] != origfd) { | 
					
						
							|  |  |  | 					if (retryzap) { | 
					
						
							|  |  |  | 						/* Kill old pseudo */ | 
					
						
							|  |  |  | 						close(fd); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					ast_log(LOG_DEBUG, "Ooh, something swapped out under us, starting over\n"); | 
					
						
							|  |  |  | 					retryzap = 0; | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |                                 goto zapretry; | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				f = ast_read(c); | 
					
						
							|  |  |  | 				if (!f) | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				if(f->frametype == AST_FRAME_DTMF) { | 
					
						
							|  |  |  | 					if(f->subclass == '#') { | 
					
						
							|  |  |  | 						ret = 0; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else if (f->subclass == '*') { | 
					
						
							|  |  |  | 						ret = -1; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 						 | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							|  |  |  | 						input[ic++] = f->subclass; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					if(ic == 3) { | 
					
						
							|  |  |  | 						input[ic++] = '\0'; | 
					
						
							|  |  |  | 						ic=0; | 
					
						
							|  |  |  | 						ret = atoi(input); | 
					
						
							|  |  |  | 						ast_verbose(VERBOSE_PREFIX_3 "Zapscan: change channel to %d\n",ret); | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				if (fd != chan->fds[0]) { | 
					
						
							|  |  |  | 					if (f->frametype == AST_FRAME_VOICE) { | 
					
						
							|  |  |  | 						if (f->subclass == AST_FORMAT_ULAW) { | 
					
						
							|  |  |  | 							/* Carefully write */ | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |                                                 careful_write(fd, f->data, f->datalen); | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 						} else | 
					
						
							|  |  |  | 							ast_log(LOG_WARNING, "Huh?  Got a non-ulaw (%d) frame in the conference\n", f->subclass); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				ast_frfree(f); | 
					
						
							|  |  |  | 			} else if (outfd > -1) { | 
					
						
							|  |  |  | 				res = read(outfd, buf, CONF_SIZE); | 
					
						
							|  |  |  | 				if (res > 0) { | 
					
						
							|  |  |  | 					memset(&fr, 0, sizeof(fr)); | 
					
						
							|  |  |  | 					fr.frametype = AST_FRAME_VOICE; | 
					
						
							|  |  |  | 					fr.subclass = AST_FORMAT_ULAW; | 
					
						
							|  |  |  | 					fr.datalen = res; | 
					
						
							|  |  |  | 					fr.samples = res; | 
					
						
							|  |  |  | 					fr.data = buf; | 
					
						
							|  |  |  | 					fr.offset = AST_FRIENDLY_OFFSET; | 
					
						
							|  |  |  | 					if (ast_write(chan, &fr) < 0) { | 
					
						
							|  |  |  | 						ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno)); | 
					
						
							|  |  |  | 						/* break; */ | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} else | 
					
						
							|  |  |  | 					ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno)); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2006-06-11 14:44:58 +00:00
										 |  |  | 	if (f) | 
					
						
							|  |  |  | 		ast_frfree(f); | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |         if (fd != chan->fds[0]) | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 			close(fd); | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |         else { | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 			/* Take out of conference */ | 
					
						
							|  |  |  | 			/* Add us to the conference */ | 
					
						
							|  |  |  | 			ztc.chan = 0; | 
					
						
							|  |  |  | 			ztc.confno = 0; | 
					
						
							|  |  |  | 			ztc.confmode = 0; | 
					
						
							|  |  |  | 			if (ioctl(fd, ZT_SETCONF, &ztc)) { | 
					
						
							|  |  |  | 				ast_log(LOG_WARNING, "Error setting conference\n"); | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |                 } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  |  outrun: | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  |         return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int conf_exec(struct ast_channel *chan, void *data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 	int res=-1; | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 	struct ast_module_user *u; | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 	int confflags = 0; | 
					
						
							|  |  |  | 	int confno = 0; | 
					
						
							|  |  |  | 	char confstr[80] = "", *tmp = NULL; | 
					
						
							|  |  |  | 	struct ast_channel *tempchan = NULL, *lastchan = NULL,*ichan = NULL; | 
					
						
							|  |  |  | 	struct ast_frame *f; | 
					
						
							|  |  |  | 	char *desired_group; | 
					
						
							|  |  |  | 	int input=0,search_group=0; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 	u = ast_module_user_add(chan); | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if (chan->_state != AST_STATE_UP) | 
					
						
							|  |  |  | 		ast_answer(chan); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-05-10 13:22:15 +00:00
										 |  |  | 	desired_group = ast_strdupa(data); | 
					
						
							| 
									
										
										
										
											2005-11-08 01:55:31 +00:00
										 |  |  | 	if(!ast_strlen_zero(desired_group)) { | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 		ast_verbose(VERBOSE_PREFIX_3 "Scanning for group %s\n", desired_group); | 
					
						
							|  |  |  | 		search_group = 1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 	for (;;) { | 
					
						
							|  |  |  | 		if (ast_waitfor(chan, 100) < 0) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		f = ast_read(chan); | 
					
						
							|  |  |  | 		if (!f) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '*')) { | 
					
						
							| 
									
										
										
										
											2004-03-10 03:51:59 +00:00
										 |  |  | 			ast_frfree(f); | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ast_frfree(f); | 
					
						
							|  |  |  | 		ichan = NULL; | 
					
						
							|  |  |  | 		if(input) { | 
					
						
							|  |  |  | 			ichan = get_zap_channel_locked(input); | 
					
						
							|  |  |  | 			input = 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		tempchan = ichan ? ichan : ast_channel_walk_locked(tempchan); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if ( !tempchan && !lastchan ) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (tempchan && search_group) { | 
					
						
							| 
									
										
										
										
											2005-12-03 19:25:33 +00:00
										 |  |  | 			const char *mygroup; | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 			if((mygroup = pbx_builtin_getvar_helper(tempchan, "GROUP")) && (!strcmp(mygroup, desired_group))) { | 
					
						
							|  |  |  | 				ast_verbose(VERBOSE_PREFIX_3 "Found Matching Channel %s in group %s\n", tempchan->name, desired_group); | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2004-06-21 04:08:54 +00:00
										 |  |  | 				ast_mutex_unlock(&tempchan->lock); | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 				lastchan = tempchan; | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-02-01 23:05:28 +00:00
										 |  |  | 		if (tempchan && (!strcmp(tempchan->tech->type, "Zap")) && (tempchan != chan) ) { | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 			ast_verbose(VERBOSE_PREFIX_3 "Zap channel %s is in-use, monitoring...\n", tempchan->name); | 
					
						
							| 
									
										
										
										
											2005-07-10 23:12:25 +00:00
										 |  |  | 			ast_copy_string(confstr, tempchan->name, sizeof(confstr)); | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 			ast_mutex_unlock(&tempchan->lock); | 
					
						
							|  |  |  | 			if ((tmp = strchr(confstr,'-'))) { | 
					
						
							|  |  |  | 				*tmp = '\0'; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			confno = atoi(strchr(confstr,'/') + 1); | 
					
						
							|  |  |  | 			ast_stopstream(chan); | 
					
						
							|  |  |  | 			ast_say_number(chan, confno, AST_DIGIT_ANY, chan->language, (char *) NULL); | 
					
						
							|  |  |  | 			res = conf_run(chan, confno, confflags); | 
					
						
							|  |  |  | 			if (res<0) break; | 
					
						
							|  |  |  | 			input = res; | 
					
						
							|  |  |  | 		} else if (tempchan) | 
					
						
							|  |  |  | 			ast_mutex_unlock(&tempchan->lock); | 
					
						
							|  |  |  | 		lastchan = tempchan; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 	ast_module_user_remove(u); | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 	return res; | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | static int unload_module(void) | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2005-10-18 22:52:21 +00:00
										 |  |  | 	int res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	res = ast_unregister_application(app); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 	ast_module_user_hangup_all(); | 
					
						
							| 
									
										
										
										
											2005-10-18 22:52:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return res; | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | static int load_module(void) | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2004-12-21 01:21:12 +00:00
										 |  |  | 	return ast_register_application(app, conf_exec, synopsis, descrip); | 
					
						
							| 
									
										
										
										
											2004-01-11 07:37:47 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Scan Zap channels application"); | 
					
						
							| 
									
										
										
										
											2006-04-24 17:11:45 +00:00
										 |  |  | 
 |