#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/chanspy.h"
#include "asterisk/features.h"
#include "asterisk/options.h"
#include "asterisk/app.h"
#include "asterisk/utils.h"
#include "asterisk/say.h"
#include "asterisk/pbx.h"
#include "asterisk/translate.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
Include dependency graph for app_chanspy.c:
Go to the source code of this file.
Data Structures | |
struct | chanspy_translation_helper |
Defines | |
#define | ALL_DONE(u, ret) LOCAL_USER_REMOVE(u); return ret; |
#define | AST_NAME_STRLEN 256 |
#define | get_volfactor(x) x ? ((x > 0) ? (1 << x) : ((1 << abs(x)) * -1)) : 0 |
Enumerations | |
enum | { OPTION_QUIET = (1 << 0), OPTION_BRIDGED = (1 << 1), OPTION_VOLUME = (1 << 2), OPTION_GROUP = (1 << 3), OPTION_RECORD = (1 << 4) } |
enum | { OPT_ARG_VOLUME = 0, OPT_ARG_GROUP, OPT_ARG_RECORD, OPT_ARG_ARRAY_SIZE } |
Functions | |
AST_APP_OPTIONS (chanspy_opts,{AST_APP_OPTION('q', OPTION_QUIET), AST_APP_OPTION('b', OPTION_BRIDGED), AST_APP_OPTION_ARG('v', OPTION_VOLUME, OPT_ARG_VOLUME), AST_APP_OPTION_ARG('g', OPTION_GROUP, OPT_ARG_GROUP), AST_APP_OPTION_ARG('r', OPTION_RECORD, OPT_ARG_RECORD),}) | |
AST_MUTEX_DEFINE_STATIC (modlock) | |
static int | channel_spy (struct ast_channel *chan, struct ast_channel *spyee, int *volfactor, int fd) |
static int | chanspy_exec (struct ast_channel *chan, void *data) |
char * | description (void) |
Provides a description of the module. | |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
static struct ast_channel * | local_channel_walk (struct ast_channel *chan) |
static struct ast_channel * | local_get_channel_begin_name (char *name) |
static void | set_volume (struct ast_channel *chan, struct chanspy_translation_helper *csth) |
static void * | spy_alloc (struct ast_channel *chan, void *data) |
static int | spy_generate (struct ast_channel *chan, void *data, int len, int samples) |
static void | spy_release (struct ast_channel *chan, void *data) |
static int | start_spying (struct ast_channel *chan, struct ast_channel *spychan, struct ast_channel_spy *spy) |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
Variables | |
static const char * | app = "ChanSpy" |
enum { ... } | chanspy_opt_args |
enum { ... } | chanspy_opt_flags |
static const char * | chanspy_spy_type = "ChanSpy" |
static const char * | desc |
LOCAL_USER_DECL | |
static struct ast_generator | spygen |
STANDARD_LOCAL_USER | |
static const char * | synopsis = "Listen to the audio of an active channel\n" |
static signed char | volfactor_map [] |
Definition in file app_chanspy.c.
#define ALL_DONE | ( | u, | |||
ret | ) | LOCAL_USER_REMOVE(u); return ret; |
Definition at line 53 of file app_chanspy.c.
Referenced by _while_exec(), chanspy_exec(), and execif_exec().
#define AST_NAME_STRLEN 256 |
#define get_volfactor | ( | x | ) | x ? ((x > 0) ? (1 << x) : ((1 << abs(x)) * -1)) : 0 |
anonymous enum |
Definition at line 84 of file app_chanspy.c.
00084 { 00085 OPTION_QUIET = (1 << 0), /* Quiet, no announcement */ 00086 OPTION_BRIDGED = (1 << 1), /* Only look at bridged calls */ 00087 OPTION_VOLUME = (1 << 2), /* Specify initial volume */ 00088 OPTION_GROUP = (1 << 3), /* Only look at channels in group */ 00089 OPTION_RECORD = (1 << 4), /* Record */ 00090 } chanspy_opt_flags;
anonymous enum |
Definition at line 92 of file app_chanspy.c.
00092 { 00093 OPT_ARG_VOLUME = 0, 00094 OPT_ARG_GROUP, 00095 OPT_ARG_RECORD, 00096 OPT_ARG_ARRAY_SIZE, 00097 } chanspy_opt_args;
AST_APP_OPTIONS | ( | chanspy_opts | ) |
AST_MUTEX_DEFINE_STATIC | ( | modlock | ) |
static int channel_spy | ( | struct ast_channel * | chan, | |
struct ast_channel * | spyee, | |||
int * | volfactor, | |||
int | fd | |||
) | [static] |
Definition at line 237 of file app_chanspy.c.
References ast_activate_generator(), ast_channel_spy_free(), ast_channel_spy_remove(), ast_check_hangup(), ast_deactivate_generator(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, ast_frfree(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_verbose(), ast_waitfor(), ast_channel_spy::chan, CHANSPY_DONE, CHANSPY_FORMAT_AUDIO, CHANSPY_MIXAUDIO, CHANSPY_RUNNING, CHANSPY_TRIGGER_NONE, ast_frame::frametype, ast_channel::lock, ast_channel::name, name, option_verbose, ast_channel_spy::read_vol_adjustment, set_volume(), chanspy_translation_helper::spy, spygen, start_spying(), ast_channel_spy::status, ast_frame::subclass, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, chanspy_translation_helper::volfactor, and ast_channel_spy::write_vol_adjustment.
Referenced by chanspy_exec().
00238 { 00239 struct chanspy_translation_helper csth; 00240 int running, res = 0, x = 0; 00241 char inp[24]; 00242 char *name=NULL; 00243 struct ast_frame *f; 00244 00245 running = (chan && !ast_check_hangup(chan) && spyee && !ast_check_hangup(spyee)); 00246 00247 if (running) { 00248 memset(inp, 0, sizeof(inp)); 00249 name = ast_strdupa(spyee->name); 00250 if (option_verbose >= 2) 00251 ast_verbose(VERBOSE_PREFIX_2 "Spying on channel %s\n", name); 00252 00253 memset(&csth, 0, sizeof(csth)); 00254 ast_set_flag(&csth.spy, CHANSPY_FORMAT_AUDIO); 00255 ast_set_flag(&csth.spy, CHANSPY_TRIGGER_NONE); 00256 ast_set_flag(&csth.spy, CHANSPY_MIXAUDIO); 00257 csth.spy.type = chanspy_spy_type; 00258 csth.spy.status = CHANSPY_RUNNING; 00259 csth.spy.read_queue.format = AST_FORMAT_SLINEAR; 00260 csth.spy.write_queue.format = AST_FORMAT_SLINEAR; 00261 ast_mutex_init(&csth.spy.lock); 00262 csth.volfactor = *volfactor; 00263 set_volume(chan, &csth); 00264 csth.spy.read_vol_adjustment = csth.volfactor; 00265 csth.spy.write_vol_adjustment = csth.volfactor; 00266 csth.fd = fd; 00267 00268 if (start_spying(spyee, chan, &csth.spy)) 00269 running = 0; 00270 } 00271 00272 if (running) { 00273 running = 1; 00274 ast_activate_generator(chan, &spygen, &csth); 00275 00276 while (csth.spy.status == CHANSPY_RUNNING && 00277 chan && !ast_check_hangup(chan) && 00278 spyee && 00279 !ast_check_hangup(spyee) && 00280 running == 1 && 00281 (res = ast_waitfor(chan, -1) > -1)) { 00282 if ((f = ast_read(chan))) { 00283 res = 0; 00284 if (f->frametype == AST_FRAME_DTMF) { 00285 res = f->subclass; 00286 } 00287 ast_frfree(f); 00288 if (!res) { 00289 continue; 00290 } 00291 } else { 00292 break; 00293 } 00294 if (x == sizeof(inp)) { 00295 x = 0; 00296 } 00297 if (res < 0) { 00298 running = -1; 00299 } 00300 if (res == 0) { 00301 continue; 00302 } else if (res == '*') { 00303 running = 0; 00304 } else if (res == '#') { 00305 if (!ast_strlen_zero(inp)) { 00306 running = x ? atoi(inp) : -1; 00307 break; 00308 } else { 00309 (*volfactor)++; 00310 if (*volfactor > 4) { 00311 *volfactor = -4; 00312 } 00313 if (option_verbose > 2) { 00314 ast_verbose(VERBOSE_PREFIX_3 "Setting spy volume on %s to %d\n", chan->name, *volfactor); 00315 } 00316 csth.volfactor = *volfactor; 00317 set_volume(chan, &csth); 00318 csth.spy.read_vol_adjustment = csth.volfactor; 00319 csth.spy.write_vol_adjustment = csth.volfactor; 00320 } 00321 } else if (res >= 48 && res <= 57) { 00322 inp[x++] = res; 00323 } 00324 } 00325 ast_deactivate_generator(chan); 00326 00327 if (csth.spy.chan) { 00328 csth.spy.status = CHANSPY_DONE; 00329 ast_mutex_lock(&csth.spy.chan->lock); 00330 ast_channel_spy_remove(csth.spy.chan, &csth.spy); 00331 ast_mutex_unlock(&csth.spy.chan->lock); 00332 } 00333 00334 if (option_verbose >= 2) { 00335 ast_verbose(VERBOSE_PREFIX_2 "Done Spying on channel %s\n", name); 00336 } 00337 } else { 00338 running = 0; 00339 } 00340 00341 ast_channel_spy_free(&csth.spy); 00342 00343 return running; 00344 }
static int chanspy_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 346 of file app_chanspy.c.
References ALL_DONE, ast_answer(), ast_app_parse_options(), ast_app_separate_args(), ast_bridged_channel(), ast_channel_setoption(), ast_check_hangup(), ast_clear_flag, ast_config_AST_MONITOR_DIR, ast_fileexists(), AST_FLAG_SPYING, AST_FORMAT_SLINEAR, ast_log(), AST_NAME_STRLEN, AST_OPTION_TXGAIN, ast_say_character_str(), ast_say_digits(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitfordigit(), ast_waitstream(), channel_spy(), ast_flags::flags, group, ast_channel::language, local_channel_walk(), local_get_channel_begin_name(), LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::name, name, OPT_ARG_ARRAY_SIZE, OPT_ARG_GROUP, OPT_ARG_RECORD, OPT_ARG_VOLUME, OPTION_BRIDGED, OPTION_GROUP, OPTION_QUIET, OPTION_RECORD, OPTION_VOLUME, pbx_builtin_getvar_helper(), ast_channel::readformat, and ast_channel::writeformat.
Referenced by load_module().
00347 { 00348 struct localuser *u; 00349 struct ast_channel *peer=NULL, *prev=NULL; 00350 char name[AST_NAME_STRLEN], 00351 peer_name[AST_NAME_STRLEN + 5], 00352 *args, 00353 *ptr = NULL, 00354 *options = NULL, 00355 *spec = NULL, 00356 *argv[5], 00357 *mygroup = NULL, 00358 *recbase = NULL; 00359 int res = -1, 00360 volfactor = 0, 00361 silent = 0, 00362 argc = 0, 00363 bronly = 0, 00364 chosen = 0, 00365 count=0, 00366 waitms = 100, 00367 num = 0, 00368 oldrf = 0, 00369 oldwf = 0, 00370 fd = 0; 00371 struct ast_flags flags; 00372 signed char zero_volume = 0; 00373 00374 if (!(args = ast_strdupa((char *)data))) { 00375 ast_log(LOG_ERROR, "Out of memory!\n"); 00376 return -1; 00377 } 00378 00379 LOCAL_USER_ADD(u); 00380 00381 oldrf = chan->readformat; 00382 oldwf = chan->writeformat; 00383 if (ast_set_read_format(chan, AST_FORMAT_SLINEAR) < 0) { 00384 ast_log(LOG_ERROR, "Could Not Set Read Format.\n"); 00385 LOCAL_USER_REMOVE(u); 00386 return -1; 00387 } 00388 00389 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 00390 ast_log(LOG_ERROR, "Could Not Set Write Format.\n"); 00391 LOCAL_USER_REMOVE(u); 00392 return -1; 00393 } 00394 00395 ast_answer(chan); 00396 00397 ast_set_flag(chan, AST_FLAG_SPYING); /* so nobody can spy on us while we are spying */ 00398 00399 if ((argc = ast_app_separate_args(args, '|', argv, sizeof(argv) / sizeof(argv[0])))) { 00400 spec = argv[0]; 00401 if ( argc > 1) { 00402 options = argv[1]; 00403 } 00404 if (ast_strlen_zero(spec) || !strcmp(spec, "all")) { 00405 spec = NULL; 00406 } 00407 } 00408 00409 if (options) { 00410 char *opts[OPT_ARG_ARRAY_SIZE]; 00411 ast_app_parse_options(chanspy_opts, &flags, opts, options); 00412 if (ast_test_flag(&flags, OPTION_GROUP)) { 00413 mygroup = opts[OPT_ARG_GROUP]; 00414 } 00415 if (ast_test_flag(&flags, OPTION_RECORD)) { 00416 if (!(recbase = opts[OPT_ARG_RECORD])) { 00417 recbase = "chanspy"; 00418 } 00419 } 00420 silent = ast_test_flag(&flags, OPTION_QUIET); 00421 bronly = ast_test_flag(&flags, OPTION_BRIDGED); 00422 if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) { 00423 int vol; 00424 00425 if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &vol) != 1) || (vol > 4) || (vol < -4)) 00426 ast_log(LOG_NOTICE, "Volume factor must be a number between -4 and 4\n"); 00427 else 00428 volfactor = vol; 00429 } 00430 } 00431 00432 if (recbase) { 00433 char filename[512]; 00434 snprintf(filename,sizeof(filename),"%s/%s.%d.raw",ast_config_AST_MONITOR_DIR, recbase, (int)time(NULL)); 00435 if ((fd = open(filename, O_CREAT | O_WRONLY, O_TRUNC, 0644)) <= 0) { 00436 ast_log(LOG_WARNING, "Cannot open %s for recording\n", filename); 00437 fd = 0; 00438 } 00439 } 00440 00441 for(;;) { 00442 if (!silent) { 00443 res = ast_streamfile(chan, "beep", chan->language); 00444 if (!res) 00445 res = ast_waitstream(chan, ""); 00446 if (res < 0) { 00447 ast_clear_flag(chan, AST_FLAG_SPYING); 00448 break; 00449 } 00450 } 00451 00452 count = 0; 00453 res = ast_waitfordigit(chan, waitms); 00454 if (res < 0) { 00455 ast_clear_flag(chan, AST_FLAG_SPYING); 00456 break; 00457 } 00458 00459 peer = local_channel_walk(NULL); 00460 prev=NULL; 00461 while(peer) { 00462 if (peer != chan) { 00463 char *group = NULL; 00464 int igrp = 1; 00465 00466 if (peer == prev && !chosen) { 00467 break; 00468 } 00469 chosen = 0; 00470 group = pbx_builtin_getvar_helper(peer, "SPYGROUP"); 00471 if (mygroup) { 00472 if (!group || strcmp(mygroup, group)) { 00473 igrp = 0; 00474 } 00475 } 00476 00477 if (igrp && (!spec || ((strlen(spec) <= strlen(peer->name) && 00478 !strncasecmp(peer->name, spec, strlen(spec)))))) { 00479 if (peer && (!bronly || ast_bridged_channel(peer)) && 00480 !ast_check_hangup(peer) && !ast_test_flag(peer, AST_FLAG_SPYING)) { 00481 int x = 0; 00482 strncpy(peer_name, "spy-", 5); 00483 strncpy(peer_name + strlen(peer_name), peer->name, AST_NAME_STRLEN); 00484 ptr = strchr(peer_name, '/'); 00485 *ptr = '\0'; 00486 ptr++; 00487 for (x = 0 ; x < strlen(peer_name) ; x++) { 00488 if (peer_name[x] == '/') { 00489 break; 00490 } 00491 peer_name[x] = tolower(peer_name[x]); 00492 } 00493 00494 if (!silent) { 00495 if (ast_fileexists(peer_name, NULL, NULL) != -1) { 00496 res = ast_streamfile(chan, peer_name, chan->language); 00497 if (!res) 00498 res = ast_waitstream(chan, ""); 00499 if (res) 00500 break; 00501 } else 00502 res = ast_say_character_str(chan, peer_name, "", chan->language); 00503 if ((num=atoi(ptr))) 00504 ast_say_digits(chan, atoi(ptr), "", chan->language); 00505 } 00506 count++; 00507 prev = peer; 00508 res = channel_spy(chan, peer, &volfactor, fd); 00509 if (res == -1) { 00510 break; 00511 } else if (res > 1 && spec) { 00512 snprintf(name, AST_NAME_STRLEN, "%s/%d", spec, res); 00513 if ((peer = local_get_channel_begin_name(name))) { 00514 chosen = 1; 00515 } 00516 continue; 00517 } 00518 } 00519 } 00520 } 00521 if ((peer = local_channel_walk(peer)) == NULL) { 00522 break; 00523 } 00524 } 00525 waitms = count ? 100 : 5000; 00526 } 00527 00528 00529 if (fd > 0) { 00530 close(fd); 00531 } 00532 00533 if (oldrf && ast_set_read_format(chan, oldrf) < 0) { 00534 ast_log(LOG_ERROR, "Could Not Set Read Format.\n"); 00535 } 00536 00537 if (oldwf && ast_set_write_format(chan, oldwf) < 0) { 00538 ast_log(LOG_ERROR, "Could Not Set Write Format.\n"); 00539 } 00540 00541 ast_clear_flag(chan, AST_FLAG_SPYING); 00542 00543 ast_channel_setoption(chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0); 00544 00545 ALL_DONE(u, res); 00546 }
char* description | ( | void | ) |
Provides a description of the module.
Definition at line 564 of file app_chanspy.c.
00565 { 00566 return (char *) synopsis; 00567 }
char* key | ( | void | ) |
Returns the ASTERISK_GPL_KEY.
This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 576 of file app_chanspy.c.
References ASTERISK_GPL_KEY.
00577 { 00578 return ASTERISK_GPL_KEY; 00579 }
int load_module | ( | void | ) |
Initialize the module.
Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 559 of file app_chanspy.c.
References ast_register_application(), and chanspy_exec().
00560 { 00561 return ast_register_application(app, chanspy_exec, synopsis, desc); 00562 }
static struct ast_channel* local_channel_walk | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 117 of file app_chanspy.c.
References ast_channel_walk_locked(), ast_mutex_lock(), ast_mutex_unlock(), and ast_channel::lock.
Referenced by chanspy_exec(), and local_get_channel_begin_name().
00118 { 00119 struct ast_channel *ret; 00120 ast_mutex_lock(&modlock); 00121 if ((ret = ast_channel_walk_locked(chan))) { 00122 ast_mutex_unlock(&ret->lock); 00123 } 00124 ast_mutex_unlock(&modlock); 00125 return ret; 00126 }
static struct ast_channel* local_get_channel_begin_name | ( | char * | name | ) | [static] |
Definition at line 128 of file app_chanspy.c.
References ast_mutex_lock(), ast_mutex_unlock(), local_channel_walk(), and ast_channel::name.
Referenced by chanspy_exec().
00129 { 00130 struct ast_channel *chan, *ret = NULL; 00131 ast_mutex_lock(&modlock); 00132 chan = local_channel_walk(NULL); 00133 while (chan) { 00134 if (!strncmp(chan->name, name, strlen(name)) && strncmp(chan->name, "Zap/pseudo", 10)) { 00135 ret = chan; 00136 break; 00137 } 00138 chan = local_channel_walk(chan); 00139 } 00140 ast_mutex_unlock(&modlock); 00141 00142 return ret; 00143 }
static void set_volume | ( | struct ast_channel * | chan, | |
struct chanspy_translation_helper * | csth | |||
) | [static] |
Definition at line 229 of file app_chanspy.c.
References ast_channel_setoption(), AST_OPTION_TXGAIN, and chanspy_translation_helper::volfactor.
Referenced by channel_spy().
00230 { 00231 signed char volume_adjust = volfactor_map[csth->volfactor + 4]; 00232 00233 if (!ast_channel_setoption(chan, AST_OPTION_TXGAIN, &volume_adjust, sizeof(volume_adjust), 0)) 00234 csth->volfactor = 0; 00235 }
static void* spy_alloc | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 145 of file app_chanspy.c.
00146 { 00147 /* just store the data pointer in the channel structure */ 00148 return data; 00149 }
static int spy_generate | ( | struct ast_channel * | chan, | |
void * | data, | |||
int | len, | |||
int | samples | |||
) | [static] |
Definition at line 156 of file app_chanspy.c.
References ast_channel_spy_read_frame(), ast_frfree(), ast_mutex_lock(), ast_mutex_unlock(), ast_write(), CHANSPY_RUNNING, ast_frame::data, ast_frame::datalen, chanspy_translation_helper::fd, ast_channel_spy::lock, chanspy_translation_helper::spy, and ast_channel_spy::status.
00157 { 00158 struct chanspy_translation_helper *csth = data; 00159 struct ast_frame *f; 00160 00161 if (csth->spy.status != CHANSPY_RUNNING) 00162 /* Channel is already gone more than likely */ 00163 return -1; 00164 00165 ast_mutex_lock(&csth->spy.lock); 00166 f = ast_channel_spy_read_frame(&csth->spy, samples); 00167 ast_mutex_unlock(&csth->spy.lock); 00168 00169 if (!f) 00170 return 0; 00171 00172 if (ast_write(chan, f)) { 00173 ast_frfree(f); 00174 return -1; 00175 } 00176 00177 if (csth->fd) 00178 write(csth->fd, f->data, f->datalen); 00179 00180 ast_frfree(f); 00181 00182 return 0; 00183 }
static void spy_release | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
static int start_spying | ( | struct ast_channel * | chan, | |
struct ast_channel * | spychan, | |||
struct ast_channel_spy * | spy | |||
) | [static] |
Definition at line 192 of file app_chanspy.c.
References ast_bridged_channel(), ast_channel_spy_add(), AST_FLAG_NBRIDGE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_softhangup(), AST_SOFTHANGUP_UNBRIDGE, ast_test_flag, ast_channel::lock, LOG_NOTICE, and ast_channel::name.
Referenced by channel_spy().
00193 { 00194 int res; 00195 struct ast_channel *peer; 00196 00197 ast_log(LOG_NOTICE, "Attaching %s to %s\n", spychan->name, chan->name); 00198 00199 ast_mutex_lock(&chan->lock); 00200 res = ast_channel_spy_add(chan, spy); 00201 ast_mutex_unlock(&chan->lock); 00202 00203 if (!res && ast_test_flag(chan, AST_FLAG_NBRIDGE) && (peer = ast_bridged_channel(chan))) { 00204 ast_softhangup(peer, AST_SOFTHANGUP_UNBRIDGE); 00205 } 00206 00207 return res; 00208 }
int unload_module | ( | void | ) |
Cleanup all module structures, sockets, etc.
This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 548 of file app_chanspy.c.
References ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS.
00549 { 00550 int res; 00551 00552 res = ast_unregister_application(app); 00553 00554 STANDARD_HANGUP_LOCALUSERS; 00555 00556 return res; 00557 }
int usecount | ( | void | ) |
Provides a usecount.
This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 569 of file app_chanspy.c.
References STANDARD_USECOUNT.
00570 { 00571 int res; 00572 STANDARD_USECOUNT(res); 00573 return res; 00574 }
const char* app = "ChanSpy" [static] |
Definition at line 57 of file app_chanspy.c.
enum { ... } chanspy_opt_args |
enum { ... } chanspy_opt_flags |
const char* chanspy_spy_type = "ChanSpy" [static] |
Definition at line 82 of file app_chanspy.c.
const char* desc [static] |
Definition at line 58 of file app_chanspy.c.
Definition at line 108 of file app_chanspy.c.
struct ast_generator spygen [static] |
Initial value:
{ .alloc = spy_alloc, .release = spy_release, .generate = spy_generate, }
Definition at line 186 of file app_chanspy.c.
Referenced by channel_spy().
Definition at line 107 of file app_chanspy.c.
Definition at line 56 of file app_chanspy.c.
signed char volfactor_map[] [static] |
Definition at line 213 of file app_chanspy.c.