#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/signal.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/manager.h"
Go to the source code of this file.
Data Structures | |
struct | feature_pvt |
struct | feature_sub |
Defines | |
#define | IS_OUTBOUND(a, b) (a == b->chan ? 1 : 0) |
#define | SUB_CALLWAIT 1 |
#define | SUB_REAL 0 |
#define | SUB_THREEWAY 2 |
Functions | |
AST_MUTEX_DEFINE_STATIC (featurelock) | |
AST_MUTEX_DEFINE_STATIC (usecnt_lock) | |
char * | description () |
Provides a description of the module. | |
static struct feature_pvt * | features_alloc (char *data, int format) |
static int | features_answer (struct ast_channel *ast) |
static int | features_call (struct ast_channel *ast, char *dest, int timeout) |
static int | features_digit (struct ast_channel *ast, char digit) |
static int | features_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
static int | features_hangup (struct ast_channel *ast) |
static int | features_indicate (struct ast_channel *ast, int condition) |
static struct ast_channel * | features_new (struct feature_pvt *p, int state, int index) |
static struct ast_frame * | features_read (struct ast_channel *ast) |
static struct ast_channel * | features_request (const char *type, int format, void *data, int *cause) |
static int | features_show (int fd, int argc, char **argv) |
static int | features_write (struct ast_channel *ast, struct ast_frame *f) |
static int | indexof (struct feature_pvt *p, struct ast_channel *owner, int nullok) |
static void | init_sub (struct feature_sub *sub) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module () |
Initialize the module. | |
int | reload () |
Reload stuff. | |
static void | restore_channel (struct feature_pvt *p, int index) |
int | unload_module () |
Cleanup all module structures, sockets, etc. | |
static void | update_features (struct feature_pvt *p, int index) |
int | usecount () |
Provides a usecount. | |
Variables | |
static struct ast_cli_entry | cli_show_features |
static const char | desc [] = "Feature Proxy Channel" |
static struct feature_pvt * | features |
static struct ast_channel_tech | features_tech |
static char | show_features_usage [] |
static const char | tdesc [] = "Feature Proxy Channel Driver" |
static const char | type [] = "Feature" |
static int | usecnt = 0 |
Definition in file chan_features.c.
#define IS_OUTBOUND | ( | a, | |||
b | ) | (a == b->chan ? 1 : 0) |
Definition at line 70 of file chan_features.c.
Referenced by local_answer(), local_digit(), local_hangup(), local_indicate(), local_sendhtml(), and local_write().
#define SUB_CALLWAIT 1 |
Definition at line 94 of file chan_features.c.
Referenced by available(), features_hangup(), ss_thread(), zap_show_channel(), zt_bridge(), zt_call(), zt_handle_event(), zt_hangup(), zt_read(), and zt_request().
#define SUB_REAL 0 |
Definition at line 93 of file chan_features.c.
Referenced by __unload_module(), __zt_exception(), attempt_transfer(), available(), bump_gains(), chandup(), check_for_conference(), destroy_channel(), disable_dtmf_detect(), do_monitor(), enable_dtmf_detect(), features_hangup(), features_request(), get_alarms(), handle_init_event(), mkintf(), reset_conf(), restore_conference(), restore_gains(), save_conference(), send_callerid(), ss_thread(), zap_show_channel(), zt_answer(), zt_bridge(), zt_call(), zt_confmute(), zt_digit(), zt_disable_ec(), zt_enable_ec(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_new(), zt_read(), zt_request(), zt_ring_phone(), zt_setoption(), zt_train_ec(), and zt_unlink().
#define SUB_THREEWAY 2 |
Definition at line 95 of file chan_features.c.
Referenced by attempt_transfer(), available(), features_hangup(), ss_thread(), zap_show_channel(), zt_answer(), zt_bridge(), zt_handle_event(), and zt_hangup().
AST_MUTEX_DEFINE_STATIC | ( | featurelock | ) |
AST_MUTEX_DEFINE_STATIC | ( | usecnt_lock | ) |
char* description | ( | void | ) |
Provides a description of the module.
Definition at line 591 of file chan_features.c.
00592 { 00593 return (char *) desc; 00594 }
static struct feature_pvt* features_alloc | ( | char * | data, | |
int | format | |||
) | [static] |
Definition at line 399 of file chan_features.c.
References ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_request(), ast_strdupa, feature_pvt::dest, features, init_sub(), LOG_NOTICE, malloc, feature_pvt::next, and feature_pvt::tech.
Referenced by features_request().
00400 { 00401 struct feature_pvt *tmp; 00402 char *dest=NULL; 00403 char *tech; 00404 int x; 00405 int status; 00406 struct ast_channel *chan; 00407 00408 tech = ast_strdupa(data); 00409 if (tech) { 00410 dest = strchr(tech, '/'); 00411 if (dest) { 00412 *dest = '\0'; 00413 dest++; 00414 } 00415 } 00416 if (!tech || !dest) { 00417 ast_log(LOG_NOTICE, "Format for feature channel is Feature/Tech/Dest ('%s' not valid)!\n", 00418 data); 00419 return NULL; 00420 } 00421 ast_mutex_lock(&featurelock); 00422 tmp = features; 00423 while(tmp) { 00424 if (!strcasecmp(tmp->tech, tech) && !strcmp(tmp->dest, dest)) 00425 break; 00426 tmp = tmp->next; 00427 } 00428 ast_mutex_unlock(&featurelock); 00429 if (!tmp) { 00430 chan = ast_request(tech, format, dest, &status); 00431 if (!chan) { 00432 ast_log(LOG_NOTICE, "Unable to allocate subchannel '%s/%s'\n", tech, dest); 00433 return NULL; 00434 } 00435 tmp = malloc(sizeof(struct feature_pvt)); 00436 if (tmp) { 00437 memset(tmp, 0, sizeof(struct feature_pvt)); 00438 for (x=0;x<3;x++) 00439 init_sub(tmp->subs + x); 00440 ast_mutex_init(&tmp->lock); 00441 strncpy(tmp->tech, tech, sizeof(tmp->tech) - 1); 00442 strncpy(tmp->dest, dest, sizeof(tmp->dest) - 1); 00443 tmp->subchan = chan; 00444 ast_mutex_lock(&featurelock); 00445 tmp->next = features; 00446 features = tmp; 00447 ast_mutex_unlock(&featurelock); 00448 } 00449 } 00450 return tmp; 00451 }
static int features_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 227 of file chan_features.c.
References ast_answer(), ast_mutex_lock(), ast_mutex_unlock(), indexof(), feature_pvt::lock, feature_pvt::subchan, and ast_channel::tech_pvt.
00228 { 00229 struct feature_pvt *p = ast->tech_pvt; 00230 int res = -1; 00231 int x; 00232 00233 ast_mutex_lock(&p->lock); 00234 x = indexof(p, ast, 0); 00235 if (!x && p->subchan) 00236 res = ast_answer(p->subchan); 00237 ast_mutex_unlock(&p->lock); 00238 return res; 00239 }
static int features_call | ( | struct ast_channel * | ast, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 319 of file chan_features.c.
References ast_channel::accountcode, ast_call(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_channel::cdrflags, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, indexof(), ast_channel::language, feature_pvt::lock, LOG_NOTICE, feature_pvt::owner, strdup, feature_pvt::subchan, ast_channel::tech_pvt, and update_features().
00320 { 00321 struct feature_pvt *p = ast->tech_pvt; 00322 int res = -1; 00323 int x; 00324 char *dest2; 00325 00326 dest2 = strchr(dest, '/'); 00327 if (dest2) { 00328 ast_mutex_lock(&p->lock); 00329 x = indexof(p, ast, 0); 00330 if (!x && p->subchan) { 00331 p->subchan->cid.cid_name = p->owner->cid.cid_name ? 00332 strdup(p->owner->cid.cid_name) : NULL; 00333 p->subchan->cid.cid_num = p->owner->cid.cid_num ? 00334 strdup(p->owner->cid.cid_num) : NULL; 00335 p->subchan->cid.cid_ani = p->owner->cid.cid_ani ? 00336 strdup(p->owner->cid.cid_ani) : NULL; 00337 p->subchan->cid.cid_rdnis = p->owner->cid.cid_rdnis ? 00338 strdup(p->owner->cid.cid_rdnis) : NULL; 00339 00340 p->subchan->cid.cid_pres = p->owner->cid.cid_pres; 00341 strncpy(p->subchan->language, p->owner->language, sizeof(p->subchan->language) - 1); 00342 strncpy(p->subchan->accountcode, p->owner->accountcode, sizeof(p->subchan->accountcode) - 1); 00343 p->subchan->cdrflags = p->owner->cdrflags; 00344 res = ast_call(p->subchan, dest2, timeout); 00345 update_features(p, x); 00346 } else 00347 ast_log(LOG_NOTICE, "Uhm yah, not quite there with the call waiting...\n"); 00348 ast_mutex_unlock(&p->lock); 00349 } 00350 return res; 00351 }
static int features_digit | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 304 of file chan_features.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_senddigit(), indexof(), feature_pvt::lock, feature_pvt::subchan, and ast_channel::tech_pvt.
00305 { 00306 struct feature_pvt *p = ast->tech_pvt; 00307 int res = -1; 00308 int x; 00309 00310 /* Queue up a frame representing the indication as a control frame */ 00311 ast_mutex_lock(&p->lock); 00312 x = indexof(p, ast, 0); 00313 if (!x && p->subchan) 00314 res = ast_senddigit(p->subchan, digit); 00315 ast_mutex_unlock(&p->lock); 00316 return res; 00317 }
static int features_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 273 of file chan_features.c.
References ast_mutex_lock(), ast_mutex_unlock(), feature_pvt::lock, feature_sub::owner, feature_pvt::owner, feature_pvt::subs, and ast_channel::tech_pvt.
00274 { 00275 struct feature_pvt *p = newchan->tech_pvt; 00276 int x; 00277 00278 ast_mutex_lock(&p->lock); 00279 if (p->owner == oldchan) 00280 p->owner = newchan; 00281 for (x = 0; x < 3; x++) { 00282 if (p->subs[x].owner == oldchan) 00283 p->subs[x].owner = newchan; 00284 } 00285 ast_mutex_unlock(&p->lock); 00286 return 0; 00287 }
static int features_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 353 of file chan_features.c.
References ast_hangup(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), features, free, indexof(), feature_pvt::lock, feature_pvt::next, feature_sub::owner, restore_channel(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, feature_pvt::subchan, feature_pvt::subs, and ast_channel::tech_pvt.
00354 { 00355 struct feature_pvt *p = ast->tech_pvt; 00356 struct feature_pvt *cur, *prev=NULL; 00357 int x; 00358 00359 ast_mutex_lock(&p->lock); 00360 x = indexof(p, ast, 0); 00361 if (x > -1) { 00362 restore_channel(p, x); 00363 p->subs[x].owner = NULL; 00364 /* XXX Re-arrange, unconference, etc XXX */ 00365 } 00366 ast->tech_pvt = NULL; 00367 00368 00369 if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) { 00370 ast_mutex_unlock(&p->lock); 00371 /* Remove from list */ 00372 ast_mutex_lock(&featurelock); 00373 cur = features; 00374 while(cur) { 00375 if (cur == p) { 00376 if (prev) 00377 prev->next = cur->next; 00378 else 00379 features = cur->next; 00380 break; 00381 } 00382 prev = cur; 00383 cur = cur->next; 00384 } 00385 ast_mutex_unlock(&featurelock); 00386 ast_mutex_lock(&p->lock); 00387 /* And destroy */ 00388 if (p->subchan) 00389 ast_hangup(p->subchan); 00390 ast_mutex_unlock(&p->lock); 00391 ast_mutex_destroy(&p->lock); 00392 free(p); 00393 return 0; 00394 } 00395 ast_mutex_unlock(&p->lock); 00396 return 0; 00397 }
static int features_indicate | ( | struct ast_channel * | ast, | |
int | condition | |||
) | [static] |
Definition at line 289 of file chan_features.c.
References ast_indicate(), ast_mutex_lock(), ast_mutex_unlock(), indexof(), feature_pvt::lock, feature_pvt::subchan, and ast_channel::tech_pvt.
00290 { 00291 struct feature_pvt *p = ast->tech_pvt; 00292 int res = -1; 00293 int x; 00294 00295 /* Queue up a frame representing the indication as a control frame */ 00296 ast_mutex_lock(&p->lock); 00297 x = indexof(p, ast, 0); 00298 if (!x && p->subchan) 00299 res = ast_indicate(p->subchan, condition); 00300 ast_mutex_unlock(&p->lock); 00301 return res; 00302 }
static struct ast_channel* features_new | ( | struct feature_pvt * | p, | |
int | state, | |||
int | index | |||
) | [static] |
Definition at line 453 of file chan_features.c.
References ast_channel_alloc(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), ast_update_use_count(), feature_pvt::dest, features_tech, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, feature_pvt::owner, feature_sub::owner, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, feature_pvt::subchan, feature_pvt::subs, feature_pvt::tech, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, usecnt_lock, and ast_channel::writeformat.
Referenced by features_request().
00454 { 00455 struct ast_channel *tmp; 00456 int x,y; 00457 if (!p->subchan) { 00458 ast_log(LOG_WARNING, "Called upon channel with no subchan:(\n"); 00459 return NULL; 00460 } 00461 if (p->subs[index].owner) { 00462 ast_log(LOG_WARNING, "Called to put index %d already there!\n", index); 00463 return NULL; 00464 } 00465 tmp = ast_channel_alloc(0); 00466 if (!tmp) { 00467 ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); 00468 return NULL; 00469 } 00470 tmp->tech = &features_tech; 00471 for (x=1;x<4;x++) { 00472 snprintf(tmp->name, sizeof(tmp->name), "Feature/%s/%s-%d", p->tech, p->dest, x); 00473 for (y=0;y<3;y++) { 00474 if (y == index) 00475 continue; 00476 if (p->subs[y].owner && !strcasecmp(p->subs[y].owner->name, tmp->name)) 00477 break; 00478 } 00479 if (y >= 3) 00480 break; 00481 } 00482 tmp->type = type; 00483 ast_setstate(tmp, state); 00484 tmp->writeformat = p->subchan->writeformat; 00485 tmp->rawwriteformat = p->subchan->rawwriteformat; 00486 tmp->readformat = p->subchan->readformat; 00487 tmp->rawreadformat = p->subchan->rawreadformat; 00488 tmp->nativeformats = p->subchan->readformat; 00489 tmp->tech_pvt = p; 00490 p->subs[index].owner = tmp; 00491 if (!p->owner) 00492 p->owner = tmp; 00493 ast_mutex_lock(&usecnt_lock); 00494 usecnt++; 00495 ast_mutex_unlock(&usecnt_lock); 00496 ast_update_use_count(); 00497 return tmp; 00498 }
static struct ast_frame * features_read | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 241 of file chan_features.c.
References AST_FRAME_NULL, ast_mutex_lock(), ast_mutex_unlock(), ast_read(), indexof(), feature_pvt::lock, feature_pvt::subchan, ast_channel::tech_pvt, and update_features().
00242 { 00243 static struct ast_frame null_frame = { AST_FRAME_NULL, }; 00244 struct feature_pvt *p = ast->tech_pvt; 00245 struct ast_frame *f; 00246 int x; 00247 00248 f = &null_frame; 00249 ast_mutex_lock(&p->lock); 00250 x = indexof(p, ast, 0); 00251 if (!x && p->subchan) { 00252 update_features(p, x); 00253 f = ast_read(p->subchan); 00254 } 00255 ast_mutex_unlock(&p->lock); 00256 return f; 00257 }
static struct ast_channel * features_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 501 of file chan_features.c.
References AST_STATE_DOWN, features_alloc(), features_new(), SUB_REAL, feature_pvt::subs, and update_features().
00502 { 00503 struct feature_pvt *p; 00504 struct ast_channel *chan = NULL; 00505 00506 p = features_alloc(data, format); 00507 if (p && !p->subs[SUB_REAL].owner) 00508 chan = features_new(p, AST_STATE_DOWN, SUB_REAL); 00509 if (chan) 00510 update_features(p,SUB_REAL); 00511 return chan; 00512 }
static int features_show | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 514 of file chan_features.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), feature_pvt::dest, features, feature_pvt::lock, ast_channel::name, feature_pvt::next, feature_pvt::owner, RESULT_SHOWUSAGE, RESULT_SUCCESS, and feature_pvt::tech.
00515 { 00516 struct feature_pvt *p; 00517 00518 if (argc != 3) 00519 return RESULT_SHOWUSAGE; 00520 ast_mutex_lock(&featurelock); 00521 p = features; 00522 while(p) { 00523 ast_mutex_lock(&p->lock); 00524 ast_cli(fd, "%s -- %s/%s\n", p->owner ? p->owner->name : "<unowned>", p->tech, p->dest); 00525 ast_mutex_unlock(&p->lock); 00526 p = p->next; 00527 } 00528 if (!features) 00529 ast_cli(fd, "No feature channels in use\n"); 00530 ast_mutex_unlock(&featurelock); 00531 return RESULT_SUCCESS; 00532 }
static int features_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 259 of file chan_features.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_write(), indexof(), feature_pvt::lock, feature_pvt::subchan, and ast_channel::tech_pvt.
00260 { 00261 struct feature_pvt *p = ast->tech_pvt; 00262 int res = -1; 00263 int x; 00264 00265 ast_mutex_lock(&p->lock); 00266 x = indexof(p, ast, 0); 00267 if (!x && p->subchan) 00268 res = ast_write(p->subchan, f); 00269 ast_mutex_unlock(&p->lock); 00270 return res; 00271 }
static int indexof | ( | struct feature_pvt * | p, | |
struct ast_channel * | owner, | |||
int | nullok | |||
) | [inline, static] |
Definition at line 131 of file chan_features.c.
References ast_log(), LOG_WARNING, feature_sub::owner, and feature_pvt::subs.
Referenced by features_answer(), features_call(), features_digit(), features_hangup(), features_indicate(), features_read(), and features_write().
00132 { 00133 int x; 00134 if (!owner) { 00135 ast_log(LOG_WARNING, "indexof called on NULL owner??\n"); 00136 return -1; 00137 } 00138 for (x=0; x<3; x++) { 00139 if (owner == p->subs[x].owner) 00140 return x; 00141 } 00142 return -1; 00143 }
static void init_sub | ( | struct feature_sub * | sub | ) | [inline, static] |
Definition at line 123 of file chan_features.c.
References feature_sub::alertpipebackup, feature_sub::inthreeway, feature_sub::pfd, and feature_sub::timingfdbackup.
Referenced by features_alloc().
00124 { 00125 sub->inthreeway = 0; 00126 sub->pfd = -1; 00127 sub->timingfdbackup = -1; 00128 sub->alertpipebackup[0] = sub->alertpipebackup[1] = -1; 00129 }
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 586 of file chan_features.c.
References ASTERISK_GPL_KEY.
00587 { 00588 return ASTERISK_GPL_KEY; 00589 }
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 542 of file chan_features.c.
References ast_channel_register(), ast_cli_register(), ast_log(), cli_show_features, features_tech, and LOG_ERROR.
00543 { 00544 /* Make sure we can register our sip channel type */ 00545 if (ast_channel_register(&features_tech)) { 00546 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); 00547 return -1; 00548 } 00549 ast_cli_register(&cli_show_features); 00550 return 0; 00551 }
int reload | ( | void | ) |
Reload stuff.
This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.
Definition at line 553 of file chan_features.c.
static void restore_channel | ( | struct feature_pvt * | p, | |
int | index | |||
) | [static] |
Definition at line 166 of file chan_features.c.
References ast_channel::alertpipe, feature_sub::alertpipebackup, AST_MAX_FDS, ast_channel::fds, feature_sub::owner, feature_pvt::subs, ast_channel::timingfd, and feature_sub::timingfdbackup.
Referenced by features_hangup(), and update_features().
00167 { 00168 /* Restore timing/alertpipe */ 00169 p->subs[index].owner->timingfd = p->subs[index].timingfdbackup; 00170 p->subs[index].owner->alertpipe[0] = p->subs[index].alertpipebackup[0]; 00171 p->subs[index].owner->alertpipe[1] = p->subs[index].alertpipebackup[1]; 00172 p->subs[index].owner->fds[AST_MAX_FDS-1] = p->subs[index].alertpipebackup[0]; 00173 p->subs[index].owner->fds[AST_MAX_FDS-2] = p->subs[index].timingfdbackup; 00174 }
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 558 of file chan_features.c.
References ast_channel_unregister(), ast_cli_unregister(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, cli_show_features, features, features_tech, free, LOG_WARNING, feature_pvt::next, and feature_pvt::owner.
00559 { 00560 struct feature_pvt *p, *prev; 00561 /* First, take us out of the channel loop */ 00562 ast_cli_unregister(&cli_show_features); 00563 ast_channel_unregister(&features_tech); 00564 if (!ast_mutex_lock(&featurelock)) { 00565 /* Hangup all interfaces if they have an owner */ 00566 for (p = features; p; p = p->next) { 00567 prev = p; 00568 if (p->owner) 00569 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 00570 free(prev); 00571 } 00572 features = NULL; 00573 ast_mutex_unlock(&featurelock); 00574 } else { 00575 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 00576 return -1; 00577 } 00578 return 0; 00579 }
static void update_features | ( | struct feature_pvt * | p, | |
int | index | |||
) | [static] |
Definition at line 176 of file chan_features.c.
References ast_channel::alertpipe, AST_MAX_FDS, ast_set_read_format(), ast_set_write_format(), ast_channel::fds, ast_channel::nativeformats, feature_sub::owner, ast_channel::readformat, restore_channel(), feature_pvt::subchan, feature_pvt::subs, ast_channel::timingfd, and ast_channel::writeformat.
Referenced by features_call(), features_read(), and features_request().
00177 { 00178 int x; 00179 if (p->subs[index].owner) { 00180 for (x=0; x<AST_MAX_FDS; x++) { 00181 if (index) 00182 p->subs[index].owner->fds[x] = -1; 00183 else 00184 p->subs[index].owner->fds[x] = p->subchan->fds[x]; 00185 } 00186 if (!index) { 00187 /* Copy timings from master channel */ 00188 p->subs[index].owner->timingfd = p->subchan->timingfd; 00189 p->subs[index].owner->alertpipe[0] = p->subchan->alertpipe[0]; 00190 p->subs[index].owner->alertpipe[1] = p->subchan->alertpipe[1]; 00191 if (p->subs[index].owner->nativeformats != p->subchan->readformat) { 00192 p->subs[index].owner->nativeformats = p->subchan->readformat; 00193 if (p->subs[index].owner->readformat) 00194 ast_set_read_format(p->subs[index].owner, p->subs[index].owner->readformat); 00195 if (p->subs[index].owner->writeformat) 00196 ast_set_write_format(p->subs[index].owner, p->subs[index].owner->writeformat); 00197 } 00198 } else{ 00199 restore_channel(p, index); 00200 } 00201 } 00202 }
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 581 of file chan_features.c.
00582 { 00583 return usecnt; 00584 }
struct ast_cli_entry cli_show_features [static] |
Initial value:
{ { "feature", "show", "channels", NULL }, features_show, "Show status of feature channels", show_features_usage, NULL }
Definition at line 538 of file chan_features.c.
Referenced by load_module(), and unload_module().
const char desc[] = "Feature Proxy Channel" [static] |
Definition at line 63 of file chan_features.c.
struct feature_pvt * features [static] |
Referenced by ast_feature_interpret(), features_alloc(), features_hangup(), features_show(), unload_module(), and zt_new().
struct ast_channel_tech features_tech [static] |
Definition at line 107 of file chan_features.c.
Referenced by features_new(), load_module(), and unload_module().
char show_features_usage[] [static] |
Initial value:
"Usage: feature show channels\n" " Provides summary information on feature channels.\n"
Definition at line 534 of file chan_features.c.
const char tdesc[] = "Feature Proxy Channel Driver" [static] |
Definition at line 65 of file chan_features.c.
const char type[] = "Feature" [static] |
Definition at line 64 of file chan_features.c.
int usecnt = 0 [static] |
Definition at line 67 of file chan_features.c.