#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 | local_pvt |
Defines | |
#define | IS_OUTBOUND(a, b) (a == b->chan ? 1 : 0) |
Functions | |
AST_MUTEX_DEFINE_STATIC (locallock) | |
AST_MUTEX_DEFINE_STATIC (usecnt_lock) | |
void | check_bridge (struct local_pvt *p, int isoutbound) |
char * | description () |
Provides a description of the module. | |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module () |
Initialize the module. | |
local_pvt * | local_alloc (char *data, int format) |
int | local_answer (struct ast_channel *ast) |
int | local_call (struct ast_channel *ast, char *dest, int timeout) |
int | local_digit (struct ast_channel *ast, char digit) |
int | local_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
int | local_hangup (struct ast_channel *ast) |
int | local_indicate (struct ast_channel *ast, int condition) |
ast_channel * | local_new (struct local_pvt *p, int state) |
int | local_queue_frame (struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us) |
ast_frame * | local_read (struct ast_channel *ast) |
ast_channel * | local_request (const char *type, int format, void *data, int *cause) |
int | local_sendhtml (struct ast_channel *ast, int subclass, const char *data, int datalen) |
int | local_write (struct ast_channel *ast, struct ast_frame *f) |
int | locals_show (int fd, int argc, char **argv) |
int | reload () |
Reload stuff. | |
int | unload_module () |
Cleanup all module structures, sockets, etc. | |
int | usecount () |
Provides a usecount. | |
Variables | |
ast_cli_entry | cli_show_locals |
const char | desc [] = "Local Proxy Channel" |
const struct ast_channel_tech | local_tech |
local_pvt * | locals |
char | show_locals_usage [] |
const char | tdesc [] = "Local Proxy Channel Driver" |
const char | type [] = "Local" |
int | usecnt = 0 |
Definition in file chan_local.c.
|
Definition at line 68 of file chan_local.c. |
|
|
|
|
|
Definition at line 183 of file chan_local.c. References ast_channel::_bridge, ast_channel::_softhangup, local_pvt::alreadymasqed, ast_channel_masquerade(), ast_mutex_trylock(), ast_mutex_unlock(), local_pvt::chan, ast_channel::lock, local_pvt::nooptimization, local_pvt::owner, and ast_channel::readq. Referenced by local_write(). 00184 { 00185 if (p->alreadymasqed || p->nooptimization) 00186 return; 00187 if (!p->chan || !p->owner) 00188 return; 00189 if (isoutbound&& p->chan->_bridge /* Not ast_bridged_channel! Only go one step! */ && !p->owner->readq) { 00190 /* Masquerade bridged channel into owner */ 00191 /* Lock everything we need, one by one, and give up if 00192 we can't get everything. Remember, we'll get another 00193 chance in just a little bit */ 00194 if (!ast_mutex_trylock(&(p->chan->_bridge)->lock)) { 00195 if (!p->chan->_bridge->_softhangup) { 00196 if (!ast_mutex_trylock(&p->owner->lock)) { 00197 if (!p->owner->_softhangup) { 00198 ast_channel_masquerade(p->owner, p->chan->_bridge); 00199 p->alreadymasqed = 1; 00200 } 00201 ast_mutex_unlock(&p->owner->lock); 00202 } 00203 ast_mutex_unlock(&(p->chan->_bridge)->lock); 00204 } 00205 } 00206 } else if (!isoutbound && p->owner && p->owner->_bridge && p->chan && !p->chan->readq) { 00207 /* Masquerade bridged channel into chan */ 00208 if (!ast_mutex_trylock(&(p->owner->_bridge)->lock)) { 00209 if (!p->owner->_bridge->_softhangup) { 00210 if (!ast_mutex_trylock(&p->chan->lock)) { 00211 if (!p->chan->_softhangup) { 00212 ast_channel_masquerade(p->chan, p->owner->_bridge); 00213 p->alreadymasqed = 1; 00214 } 00215 ast_mutex_unlock(&p->chan->lock); 00216 } 00217 } 00218 ast_mutex_unlock(&(p->owner->_bridge)->lock); 00219 } 00220 } 00221 }
|
|
Provides a description of the module.
Definition at line 657 of file chan_local.c. 00658 { 00659 return (char *) desc; 00660 }
|
|
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 652 of file chan_local.c. 00653 {
00654 return ASTERISK_GPL_KEY;
00655 }
|
|
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 605 of file chan_local.c. References ast_channel_register(), ast_cli_register(), ast_log(), cli_show_locals, local_tech, LOG_ERROR, and type. 00606 { 00607 /* Make sure we can register our channel type */ 00608 if (ast_channel_register(&local_tech)) { 00609 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); 00610 return -1; 00611 } 00612 ast_cli_register(&cli_show_locals); 00613 return 0; 00614 }
|
|
Definition at line 467 of file chan_local.c. References ast_exists_extension(), ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), local_pvt::context, local_pvt::exten, free, locals, local_pvt::lock, LOG_NOTICE, malloc, local_pvt::next, local_pvt::nooptimization, and local_pvt::reqformat. Referenced by local_request(). 00468 { 00469 struct local_pvt *tmp; 00470 char *c; 00471 char *opts; 00472 00473 tmp = malloc(sizeof(struct local_pvt)); 00474 if (tmp) { 00475 memset(tmp, 0, sizeof(struct local_pvt)); 00476 ast_mutex_init(&tmp->lock); 00477 strncpy(tmp->exten, data, sizeof(tmp->exten) - 1); 00478 opts = strchr(tmp->exten, '/'); 00479 if (opts) { 00480 *opts='\0'; 00481 opts++; 00482 if (strchr(opts, 'n')) 00483 tmp->nooptimization = 1; 00484 } 00485 c = strchr(tmp->exten, '@'); 00486 if (c) { 00487 *c = '\0'; 00488 c++; 00489 strncpy(tmp->context, c, sizeof(tmp->context) - 1); 00490 } else 00491 strncpy(tmp->context, "default", sizeof(tmp->context) - 1); 00492 tmp->reqformat = format; 00493 if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) { 00494 ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->exten, tmp->context); 00495 ast_mutex_destroy(&tmp->lock); 00496 free(tmp); 00497 tmp = NULL; 00498 } else { 00499 /* Add to list */ 00500 ast_mutex_lock(&locallock); 00501 tmp->next = locals; 00502 locals = tmp; 00503 ast_mutex_unlock(&locallock); 00504 } 00505 00506 } 00507 return tmp; 00508 }
|
|
Definition at line 165 of file chan_local.c. References AST_CONTROL_ANSWER, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), IS_OUTBOUND, local_queue_frame(), local_pvt::lock, LOG_WARNING, and ast_channel::tech_pvt. 00166 { 00167 struct local_pvt *p = ast->tech_pvt; 00168 int isoutbound; 00169 int res = -1; 00170 00171 ast_mutex_lock(&p->lock); 00172 isoutbound = IS_OUTBOUND(ast, p); 00173 if (isoutbound) { 00174 /* Pass along answer since somebody answered us */ 00175 struct ast_frame answer = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; 00176 res = local_queue_frame(p, isoutbound, &answer, ast); 00177 } else 00178 ast_log(LOG_WARNING, "Huh? Local is being asked to answer?\n"); 00179 ast_mutex_unlock(&p->lock); 00180 return res; 00181 }
|
|
Definition at line 319 of file chan_local.c. References ast_channel::accountcode, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_channel::cdrflags, local_pvt::chan, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_rdnis, ast_channel::language, local_pvt::launchedpbx, local_pvt::lock, LOG_ERROR, malloc, ast_var_t::name, local_pvt::owner, strdup, ast_channel::tech_pvt, ast_var_t::value, and ast_channel::varshead. 00320 { 00321 struct local_pvt *p = ast->tech_pvt; 00322 int res; 00323 struct ast_var_t *varptr = NULL, *new; 00324 size_t len, namelen; 00325 00326 ast_mutex_lock(&p->lock); 00327 if (p->owner->cid.cid_num) 00328 p->chan->cid.cid_num = strdup(p->owner->cid.cid_num); 00329 else 00330 p->chan->cid.cid_num = NULL; 00331 00332 if (p->owner->cid.cid_name) 00333 p->chan->cid.cid_name = strdup(p->owner->cid.cid_name); 00334 else 00335 p->chan->cid.cid_name = NULL; 00336 00337 if (p->owner->cid.cid_rdnis) 00338 p->chan->cid.cid_rdnis = strdup(p->owner->cid.cid_rdnis); 00339 else 00340 p->chan->cid.cid_rdnis = NULL; 00341 00342 if (p->owner->cid.cid_ani) 00343 p->chan->cid.cid_ani = strdup(p->owner->cid.cid_ani); 00344 else 00345 p->chan->cid.cid_ani = NULL; 00346 00347 strncpy(p->chan->language, p->owner->language, sizeof(p->chan->language) - 1); 00348 strncpy(p->chan->accountcode, p->owner->accountcode, sizeof(p->chan->accountcode) - 1); 00349 p->chan->cdrflags = p->owner->cdrflags; 00350 00351 /* copy the channel variables from the incoming channel to the outgoing channel */ 00352 /* Note that due to certain assumptions, they MUST be in the same order */ 00353 AST_LIST_TRAVERSE(&p->owner->varshead, varptr, entries) { 00354 namelen = strlen(varptr->name); 00355 len = sizeof(struct ast_var_t) + namelen + strlen(varptr->value) + 2; 00356 new = malloc(len); 00357 if (new) { 00358 memcpy(new, varptr, len); 00359 new->value = &(new->name[0]) + namelen + 1; 00360 AST_LIST_INSERT_TAIL(&p->chan->varshead, new, entries); 00361 } else { 00362 ast_log(LOG_ERROR, "Out of memory!\n"); 00363 } 00364 } 00365 00366 p->launchedpbx = 1; 00367 00368 /* Start switch on sub channel */ 00369 res = ast_pbx_start(p->chan); 00370 ast_mutex_unlock(&p->lock); 00371 return res; 00372 }
|
|
Definition at line 285 of file chan_local.c. References ast_mutex_lock(), ast_mutex_unlock(), IS_OUTBOUND, local_queue_frame(), local_pvt::lock, ast_frame::subclass, and ast_channel::tech_pvt. 00286 { 00287 struct local_pvt *p = ast->tech_pvt; 00288 int res = -1; 00289 struct ast_frame f = { AST_FRAME_DTMF, }; 00290 int isoutbound; 00291 00292 ast_mutex_lock(&p->lock); 00293 isoutbound = IS_OUTBOUND(ast, p); 00294 f.subclass = digit; 00295 res = local_queue_frame(p, isoutbound, &f, ast); 00296 ast_mutex_unlock(&p->lock); 00297 return res; 00298 }
|
|
Definition at line 251 of file chan_local.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), local_pvt::chan, local_pvt::lock, LOG_WARNING, local_pvt::owner, and ast_channel::tech_pvt. 00252 { 00253 struct local_pvt *p = newchan->tech_pvt; 00254 ast_mutex_lock(&p->lock); 00255 00256 if ((p->owner != oldchan) && (p->chan != oldchan)) { 00257 ast_log(LOG_WARNING, "Old channel wasn't %p but was %p/%p\n", oldchan, p->owner, p->chan); 00258 ast_mutex_unlock(&p->lock); 00259 return -1; 00260 } 00261 if (p->owner == oldchan) 00262 p->owner = newchan; 00263 else 00264 p->chan = newchan; 00265 ast_mutex_unlock(&p->lock); 00266 return 0; 00267 }
|
|
Definition at line 400 of file chan_local.c. References AST_CONTROL_HANGUP, ast_hangup(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), local_pvt::cancelqueue, local_pvt::chan, free, local_pvt::glaredetect, IS_OUTBOUND, local_pvt::launchedpbx, local_queue_frame(), locals, local_pvt::lock, local_pvt::next, local_pvt::owner, ast_channel::tech_pvt, and usecnt. 00401 { 00402 struct local_pvt *p = ast->tech_pvt; 00403 int isoutbound; 00404 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP }; 00405 struct local_pvt *cur, *prev=NULL; 00406 struct ast_channel *ochan = NULL; 00407 int glaredetect; 00408 00409 ast_mutex_lock(&p->lock); 00410 isoutbound = IS_OUTBOUND(ast, p); 00411 if (isoutbound) { 00412 p->chan = NULL; 00413 p->launchedpbx = 0; 00414 } else 00415 p->owner = NULL; 00416 ast->tech_pvt = NULL; 00417 00418 ast_mutex_lock(&usecnt_lock); 00419 usecnt--; 00420 ast_mutex_unlock(&usecnt_lock); 00421 00422 if (!p->owner && !p->chan) { 00423 /* Okay, done with the private part now, too. */ 00424 glaredetect = p->glaredetect; 00425 /* If we have a queue holding, don't actually destroy p yet, but 00426 let local_queue do it. */ 00427 if (p->glaredetect) 00428 p->cancelqueue = 1; 00429 ast_mutex_unlock(&p->lock); 00430 /* Remove from list */ 00431 ast_mutex_lock(&locallock); 00432 cur = locals; 00433 while(cur) { 00434 if (cur == p) { 00435 if (prev) 00436 prev->next = cur->next; 00437 else 00438 locals = cur->next; 00439 break; 00440 } 00441 prev = cur; 00442 cur = cur->next; 00443 } 00444 ast_mutex_unlock(&locallock); 00445 /* Grab / release lock just in case */ 00446 ast_mutex_lock(&p->lock); 00447 ast_mutex_unlock(&p->lock); 00448 /* And destroy */ 00449 if (!glaredetect) { 00450 ast_mutex_destroy(&p->lock); 00451 free(p); 00452 } 00453 return 0; 00454 } 00455 if (p->chan && !p->launchedpbx) 00456 /* Need to actually hangup since there is no PBX */ 00457 ochan = p->chan; 00458 else 00459 local_queue_frame(p, isoutbound, &f, NULL); 00460 ast_mutex_unlock(&p->lock); 00461 if (ochan) 00462 ast_hangup(ochan); 00463 return 0; 00464 }
|
|
Definition at line 269 of file chan_local.c. References ast_mutex_lock(), ast_mutex_unlock(), IS_OUTBOUND, local_queue_frame(), local_pvt::lock, ast_frame::subclass, and ast_channel::tech_pvt. 00270 { 00271 struct local_pvt *p = ast->tech_pvt; 00272 int res = -1; 00273 struct ast_frame f = { AST_FRAME_CONTROL, }; 00274 int isoutbound; 00275 00276 /* Queue up a frame representing the indication as a control frame */ 00277 ast_mutex_lock(&p->lock); 00278 isoutbound = IS_OUTBOUND(ast, p); 00279 f.subclass = condition; 00280 res = local_queue_frame(p, isoutbound, &f, ast); 00281 ast_mutex_unlock(&p->lock); 00282 return res; 00283 }
|
|
Definition at line 511 of file chan_local.c. References ast_channel_alloc(), ast_channel_free(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_RING, ast_update_use_count(), local_pvt::chan, ast_channel::context, local_pvt::context, ast_channel::exten, local_pvt::exten, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, local_pvt::owner, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, local_pvt::reqformat, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, usecnt, and ast_channel::writeformat. Referenced by local_request(). 00512 { 00513 struct ast_channel *tmp, *tmp2; 00514 int randnum = rand() & 0xffff; 00515 00516 tmp = ast_channel_alloc(1); 00517 tmp2 = ast_channel_alloc(1); 00518 if (!tmp || !tmp2) { 00519 if (tmp) 00520 ast_channel_free(tmp); 00521 if (tmp2) 00522 ast_channel_free(tmp2); 00523 ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n"); 00524 return NULL; 00525 } 00526 00527 tmp2->tech = tmp->tech = &local_tech; 00528 tmp->nativeformats = p->reqformat; 00529 tmp2->nativeformats = p->reqformat; 00530 snprintf(tmp->name, sizeof(tmp->name), "Local/%s@%s-%04x,1", p->exten, p->context, randnum); 00531 snprintf(tmp2->name, sizeof(tmp2->name), "Local/%s@%s-%04x,2", p->exten, p->context, randnum); 00532 tmp->type = type; 00533 tmp2->type = type; 00534 ast_setstate(tmp, state); 00535 ast_setstate(tmp2, AST_STATE_RING); 00536 tmp->writeformat = p->reqformat; 00537 tmp2->writeformat = p->reqformat; 00538 tmp->rawwriteformat = p->reqformat; 00539 tmp2->rawwriteformat = p->reqformat; 00540 tmp->readformat = p->reqformat; 00541 tmp2->readformat = p->reqformat; 00542 tmp->rawreadformat = p->reqformat; 00543 tmp2->rawreadformat = p->reqformat; 00544 tmp->tech_pvt = p; 00545 tmp2->tech_pvt = p; 00546 p->owner = tmp; 00547 p->chan = tmp2; 00548 ast_mutex_lock(&usecnt_lock); 00549 usecnt++; 00550 usecnt++; 00551 ast_mutex_unlock(&usecnt_lock); 00552 ast_update_use_count(); 00553 ast_copy_string(tmp->context, p->context, sizeof(tmp->context)); 00554 ast_copy_string(tmp2->context, p->context, sizeof(tmp2->context)); 00555 ast_copy_string(tmp2->exten, p->exten, sizeof(tmp->exten)); 00556 tmp->priority = 1; 00557 tmp2->priority = 1; 00558 00559 return tmp; 00560 }
|
|
Definition at line 117 of file chan_local.c. References ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), local_pvt::cancelqueue, local_pvt::chan, ast_frame::frametype, free, local_pvt::glaredetect, ast_channel::lock, local_pvt::lock, LOG_WARNING, ast_channel::name, local_pvt::owner, and ast_frame::subclass. Referenced by local_answer(), local_digit(), local_hangup(), local_indicate(), local_sendhtml(), and local_write(). 00118 { 00119 struct ast_channel *other; 00120 retrylock: 00121 /* Recalculate outbound channel */ 00122 if (isoutbound) { 00123 other = p->owner; 00124 } else { 00125 other = p->chan; 00126 } 00127 /* Set glare detection */ 00128 p->glaredetect = 1; 00129 if (p->cancelqueue) { 00130 /* We had a glare on the hangup. Forget all this business, 00131 return and destroy p. */ 00132 ast_mutex_unlock(&p->lock); 00133 ast_mutex_destroy(&p->lock); 00134 free(p); 00135 return -1; 00136 } 00137 if (!other) { 00138 p->glaredetect = 0; 00139 return 0; 00140 } 00141 if (ast_mutex_trylock(&other->lock)) { 00142 /* Failed to lock. Release main lock and try again */ 00143 ast_mutex_unlock(&p->lock); 00144 if (us) { 00145 if (ast_mutex_unlock(&us->lock)) { 00146 ast_log(LOG_WARNING, "%s wasn't locked while sending %d/%d\n", 00147 us->name, f->frametype, f->subclass); 00148 us = NULL; 00149 } 00150 } 00151 /* Wait just a bit */ 00152 usleep(1); 00153 /* Only we can destroy ourselves, so we can't disappear here */ 00154 if (us) 00155 ast_mutex_lock(&us->lock); 00156 ast_mutex_lock(&p->lock); 00157 goto retrylock; 00158 } 00159 ast_queue_frame(other, f); 00160 ast_mutex_unlock(&other->lock); 00161 p->glaredetect = 0; 00162 return 0; 00163 }
|
|
Definition at line 223 of file chan_local.c. 00224 { 00225 static struct ast_frame null = { AST_FRAME_NULL, }; 00226 00227 return &null; 00228 }
|
|
Definition at line 564 of file chan_local.c. References AST_STATE_DOWN, local_alloc(), and local_new(). 00565 { 00566 struct local_pvt *p; 00567 struct ast_channel *chan = NULL; 00568 00569 p = local_alloc(data, format); 00570 if (p) 00571 chan = local_new(p, AST_STATE_DOWN); 00572 return chan; 00573 }
|
|
Definition at line 300 of file chan_local.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_frame::data, ast_frame::datalen, IS_OUTBOUND, local_queue_frame(), local_pvt::lock, ast_frame::subclass, and ast_channel::tech_pvt. 00301 { 00302 struct local_pvt *p = ast->tech_pvt; 00303 int res = -1; 00304 struct ast_frame f = { AST_FRAME_HTML, }; 00305 int isoutbound; 00306 00307 ast_mutex_lock(&p->lock); 00308 isoutbound = IS_OUTBOUND(ast, p); 00309 f.subclass = subclass; 00310 f.data = (char *)data; 00311 f.datalen = datalen; 00312 res = local_queue_frame(p, isoutbound, &f, ast); 00313 ast_mutex_unlock(&p->lock); 00314 return res; 00315 }
|
|
Definition at line 230 of file chan_local.c. References local_pvt::alreadymasqed, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), check_bridge(), ast_frame::frametype, IS_OUTBOUND, local_queue_frame(), local_pvt::lock, LOG_DEBUG, ast_channel::name, and ast_channel::tech_pvt. 00231 { 00232 struct local_pvt *p = ast->tech_pvt; 00233 int res = -1; 00234 int isoutbound; 00235 00236 /* Just queue for delivery to the other side */ 00237 ast_mutex_lock(&p->lock); 00238 isoutbound = IS_OUTBOUND(ast, p); 00239 if (f && (f->frametype == AST_FRAME_VOICE)) 00240 check_bridge(p, isoutbound); 00241 if (!p->alreadymasqed) 00242 res = local_queue_frame(p, isoutbound, f, ast); 00243 else { 00244 ast_log(LOG_DEBUG, "Not posting to queue since already masked on '%s'\n", ast->name); 00245 res = 0; 00246 } 00247 ast_mutex_unlock(&p->lock); 00248 return res; 00249 }
|
|
Definition at line 576 of file chan_local.c. References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), local_pvt::context, local_pvt::exten, local_pvt::lock, ast_channel::name, local_pvt::next, and local_pvt::owner. 00577 { 00578 struct local_pvt *p; 00579 00580 if (argc != 3) 00581 return RESULT_SHOWUSAGE; 00582 ast_mutex_lock(&locallock); 00583 p = locals; 00584 while(p) { 00585 ast_mutex_lock(&p->lock); 00586 ast_cli(fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "<unowned>", p->exten, p->context); 00587 ast_mutex_unlock(&p->lock); 00588 p = p->next; 00589 } 00590 if (!locals) 00591 ast_cli(fd, "No local channels in use\n"); 00592 ast_mutex_unlock(&locallock); 00593 return RESULT_SUCCESS; 00594 }
|
|
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 617 of file chan_local.c. 00618 {
00619 return 0;
00620 }
|
|
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 623 of file chan_local.c. References ast_channel_unregister(), ast_cli_unregister(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, cli_show_locals, local_tech, locals, LOG_WARNING, local_pvt::next, and local_pvt::owner. 00624 { 00625 struct local_pvt *p; 00626 00627 /* First, take us out of the channel loop */ 00628 ast_cli_unregister(&cli_show_locals); 00629 ast_channel_unregister(&local_tech); 00630 if (!ast_mutex_lock(&locallock)) { 00631 /* Hangup all interfaces if they have an owner */ 00632 p = locals; 00633 while(p) { 00634 if (p->owner) 00635 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 00636 p = p->next; 00637 } 00638 locals = NULL; 00639 ast_mutex_unlock(&locallock); 00640 } else { 00641 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 00642 return -1; 00643 } 00644 return 0; 00645 }
|
|
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 647 of file chan_local.c. 00648 {
00649 return usecnt;
00650 }
|
|
Initial value: { { "local", "show", "channels", NULL }, locals_show, "Show status of local channels", show_locals_usage, NULL } Definition at line 600 of file chan_local.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 61 of file chan_local.c. |
|
Definition at line 85 of file chan_local.c. Referenced by load_module(), and unload_module(). |
|
|
|
Initial value: "Usage: local show channels\n" " Provides summary information on active local proxy channels.\n" Definition at line 596 of file chan_local.c. |
|
Definition at line 63 of file chan_local.c. |
|
Definition at line 62 of file chan_local.c. |
|
Definition at line 65 of file chan_local.c. Referenced by local_hangup(), and local_new(). |