#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) | |
static 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. | |
static struct local_pvt * | local_alloc (char *data, int format) |
static int | local_answer (struct ast_channel *ast) |
static int | local_call (struct ast_channel *ast, char *dest, int timeout) |
static int | local_digit (struct ast_channel *ast, char digit) |
static int | local_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
static int | local_hangup (struct ast_channel *ast) |
static int | local_indicate (struct ast_channel *ast, int condition) |
static struct ast_channel * | local_new (struct local_pvt *p, int state) |
static int | local_queue_frame (struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us) |
static struct ast_frame * | local_read (struct ast_channel *ast) |
static struct ast_channel * | local_request (const char *type, int format, void *data, int *cause) |
static int | local_sendhtml (struct ast_channel *ast, int subclass, const char *data, int datalen) |
static int | local_write (struct ast_channel *ast, struct ast_frame *f) |
static 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 | |
static struct ast_cli_entry | cli_show_locals |
static const char | desc [] = "Local Proxy Channel" |
static const struct ast_channel_tech | local_tech |
static struct local_pvt * | locals |
static char | show_locals_usage [] |
static const char | tdesc [] = "Local Proxy Channel Driver" |
static const char | type [] = "Local" |
static 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 00190 /* only do the masquerade if we are being called on the outbound channel, 00191 if it has been bridged to another channel and if there are no pending 00192 frames on the owner channel (because they would be transferred to the 00193 outbound channel during the masquerade) 00194 */ 00195 if (isoutbound && p->chan->_bridge /* Not ast_bridged_channel! Only go one step! */ && !p->owner->readq) { 00196 /* Masquerade bridged channel into owner */ 00197 /* Lock everything we need, one by one, and give up if 00198 we can't get everything. Remember, we'll get another 00199 chance in just a little bit */ 00200 if (!ast_mutex_trylock(&(p->chan->_bridge)->lock)) { 00201 if (!p->chan->_bridge->_softhangup) { 00202 if (!ast_mutex_trylock(&p->owner->lock)) { 00203 if (!p->owner->_softhangup) { 00204 ast_channel_masquerade(p->owner, p->chan->_bridge); 00205 p->alreadymasqed = 1; 00206 } 00207 ast_mutex_unlock(&p->owner->lock); 00208 } 00209 ast_mutex_unlock(&(p->chan->_bridge)->lock); 00210 } 00211 } 00212 /* We only allow masquerading in one 'direction'... it's important to preserve the state 00213 (group variables, etc.) that live on p->chan->_bridge (and were put there by the dialplan) 00214 when the local channels go away. 00215 */ 00216 #if 0 00217 } else if (!isoutbound && p->owner && p->owner->_bridge && p->chan && !p->chan->readq) { 00218 /* Masquerade bridged channel into chan */ 00219 if (!ast_mutex_trylock(&(p->owner->_bridge)->lock)) { 00220 if (!p->owner->_bridge->_softhangup) { 00221 if (!ast_mutex_trylock(&p->chan->lock)) { 00222 if (!p->chan->_softhangup) { 00223 ast_channel_masquerade(p->chan, p->owner->_bridge); 00224 p->alreadymasqed = 1; 00225 } 00226 ast_mutex_unlock(&p->chan->lock); 00227 } 00228 } 00229 ast_mutex_unlock(&(p->owner->_bridge)->lock); 00230 } 00231 #endif 00232 } 00233 }
|
|
Provides a description of the module.
Definition at line 662 of file chan_local.c. 00663 { 00664 return (char *) desc; 00665 }
|
|
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 657 of file chan_local.c. References ASTERISK_GPL_KEY. 00658 { 00659 return ASTERISK_GPL_KEY; 00660 }
|
|
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 610 of file chan_local.c. References ast_channel_register(), ast_cli_register(), ast_log(), cli_show_locals, local_tech, and LOG_ERROR. 00611 { 00612 /* Make sure we can register our channel type */ 00613 if (ast_channel_register(&local_tech)) { 00614 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); 00615 return -1; 00616 } 00617 ast_cli_register(&cli_show_locals); 00618 return 0; 00619 }
|
|
Definition at line 471 of file chan_local.c. References ast_exists_extension(), ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), free, locals, LOG_NOTICE, and malloc. Referenced by local_request(). 00472 { 00473 struct local_pvt *tmp; 00474 char *c; 00475 char *opts; 00476 00477 tmp = malloc(sizeof(struct local_pvt)); 00478 if (tmp) { 00479 memset(tmp, 0, sizeof(struct local_pvt)); 00480 ast_mutex_init(&tmp->lock); 00481 strncpy(tmp->exten, data, sizeof(tmp->exten) - 1); 00482 opts = strchr(tmp->exten, '/'); 00483 if (opts) { 00484 *opts='\0'; 00485 opts++; 00486 if (strchr(opts, 'n')) 00487 tmp->nooptimization = 1; 00488 } 00489 c = strchr(tmp->exten, '@'); 00490 if (c) { 00491 *c = '\0'; 00492 c++; 00493 strncpy(tmp->context, c, sizeof(tmp->context) - 1); 00494 } else 00495 strncpy(tmp->context, "default", sizeof(tmp->context) - 1); 00496 tmp->reqformat = format; 00497 if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) { 00498 ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->exten, tmp->context); 00499 ast_mutex_destroy(&tmp->lock); 00500 free(tmp); 00501 tmp = NULL; 00502 } else { 00503 /* Add to list */ 00504 ast_mutex_lock(&locallock); 00505 tmp->next = locals; 00506 locals = tmp; 00507 ast_mutex_unlock(&locallock); 00508 } 00509 00510 } 00511 return tmp; 00512 }
|
|
Definition at line 165 of file chan_local.c. References answer, AST_CONTROL_ANSWER, AST_FRAME_CONTROL, 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 331 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_set_callerid(), ast_channel::cdrflags, local_pvt::chan, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, 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. 00332 { 00333 struct local_pvt *p = ast->tech_pvt; 00334 int res; 00335 struct ast_var_t *varptr = NULL, *new; 00336 size_t len, namelen; 00337 00338 ast_mutex_lock(&p->lock); 00339 00340 ast_set_callerid(p->chan, 00341 p->owner->cid.cid_num, p->owner->cid.cid_name, 00342 p->owner->cid.cid_ani); 00343 00344 if (p->owner->cid.cid_rdnis) 00345 p->chan->cid.cid_rdnis = strdup(p->owner->cid.cid_rdnis); 00346 else 00347 p->chan->cid.cid_rdnis = NULL; 00348 00349 p->chan->cid.cid_pres = p->owner->cid.cid_pres; 00350 00351 strncpy(p->chan->language, p->owner->language, sizeof(p->chan->language) - 1); 00352 strncpy(p->chan->accountcode, p->owner->accountcode, sizeof(p->chan->accountcode) - 1); 00353 p->chan->cdrflags = p->owner->cdrflags; 00354 00355 /* copy the channel variables from the incoming channel to the outgoing channel */ 00356 /* Note that due to certain assumptions, they MUST be in the same order */ 00357 AST_LIST_TRAVERSE(&p->owner->varshead, varptr, entries) { 00358 namelen = strlen(varptr->name); 00359 len = sizeof(struct ast_var_t) + namelen + strlen(varptr->value) + 2; 00360 new = malloc(len); 00361 if (new) { 00362 memcpy(new, varptr, len); 00363 new->value = &(new->name[0]) + namelen + 1; 00364 AST_LIST_INSERT_TAIL(&p->chan->varshead, new, entries); 00365 } else { 00366 ast_log(LOG_ERROR, "Out of memory!\n"); 00367 } 00368 } 00369 00370 p->launchedpbx = 1; 00371 00372 /* Start switch on sub channel */ 00373 res = ast_pbx_start(p->chan); 00374 ast_mutex_unlock(&p->lock); 00375 return res; 00376 }
|
|
Definition at line 297 of file chan_local.c. References AST_FRAME_DTMF, ast_mutex_lock(), ast_mutex_unlock(), IS_OUTBOUND, local_queue_frame(), local_pvt::lock, ast_frame::subclass, and ast_channel::tech_pvt. 00298 { 00299 struct local_pvt *p = ast->tech_pvt; 00300 int res = -1; 00301 struct ast_frame f = { AST_FRAME_DTMF, }; 00302 int isoutbound; 00303 00304 ast_mutex_lock(&p->lock); 00305 isoutbound = IS_OUTBOUND(ast, p); 00306 f.subclass = digit; 00307 res = local_queue_frame(p, isoutbound, &f, ast); 00308 ast_mutex_unlock(&p->lock); 00309 return res; 00310 }
|
|
Definition at line 263 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. 00264 { 00265 struct local_pvt *p = newchan->tech_pvt; 00266 ast_mutex_lock(&p->lock); 00267 00268 if ((p->owner != oldchan) && (p->chan != oldchan)) { 00269 ast_log(LOG_WARNING, "Old channel wasn't %p but was %p/%p\n", oldchan, p->owner, p->chan); 00270 ast_mutex_unlock(&p->lock); 00271 return -1; 00272 } 00273 if (p->owner == oldchan) 00274 p->owner = newchan; 00275 else 00276 p->chan = newchan; 00277 ast_mutex_unlock(&p->lock); 00278 return 0; 00279 }
|
|
Definition at line 404 of file chan_local.c. References AST_CONTROL_HANGUP, AST_FRAME_CONTROL, 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_lock. 00405 { 00406 struct local_pvt *p = ast->tech_pvt; 00407 int isoutbound; 00408 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP }; 00409 struct local_pvt *cur, *prev=NULL; 00410 struct ast_channel *ochan = NULL; 00411 int glaredetect; 00412 00413 ast_mutex_lock(&p->lock); 00414 isoutbound = IS_OUTBOUND(ast, p); 00415 if (isoutbound) { 00416 p->chan = NULL; 00417 p->launchedpbx = 0; 00418 } else 00419 p->owner = NULL; 00420 ast->tech_pvt = NULL; 00421 00422 ast_mutex_lock(&usecnt_lock); 00423 usecnt--; 00424 ast_mutex_unlock(&usecnt_lock); 00425 00426 if (!p->owner && !p->chan) { 00427 /* Okay, done with the private part now, too. */ 00428 glaredetect = p->glaredetect; 00429 /* If we have a queue holding, don't actually destroy p yet, but 00430 let local_queue do it. */ 00431 if (p->glaredetect) 00432 p->cancelqueue = 1; 00433 ast_mutex_unlock(&p->lock); 00434 /* Remove from list */ 00435 ast_mutex_lock(&locallock); 00436 cur = locals; 00437 while(cur) { 00438 if (cur == p) { 00439 if (prev) 00440 prev->next = cur->next; 00441 else 00442 locals = cur->next; 00443 break; 00444 } 00445 prev = cur; 00446 cur = cur->next; 00447 } 00448 ast_mutex_unlock(&locallock); 00449 /* Grab / release lock just in case */ 00450 ast_mutex_lock(&p->lock); 00451 ast_mutex_unlock(&p->lock); 00452 /* And destroy */ 00453 if (!glaredetect) { 00454 ast_mutex_destroy(&p->lock); 00455 free(p); 00456 } 00457 return 0; 00458 } 00459 if (p->chan && !p->launchedpbx) 00460 /* Need to actually hangup since there is no PBX */ 00461 ochan = p->chan; 00462 else 00463 local_queue_frame(p, isoutbound, &f, NULL); 00464 ast_mutex_unlock(&p->lock); 00465 if (ochan) 00466 ast_hangup(ochan); 00467 return 0; 00468 }
|
|
Definition at line 281 of file chan_local.c. References AST_FRAME_CONTROL, ast_mutex_lock(), ast_mutex_unlock(), IS_OUTBOUND, local_queue_frame(), local_pvt::lock, ast_frame::subclass, and ast_channel::tech_pvt. 00282 { 00283 struct local_pvt *p = ast->tech_pvt; 00284 int res = -1; 00285 struct ast_frame f = { AST_FRAME_CONTROL, }; 00286 int isoutbound; 00287 00288 /* Queue up a frame representing the indication as a control frame */ 00289 ast_mutex_lock(&p->lock); 00290 isoutbound = IS_OUTBOUND(ast, p); 00291 f.subclass = condition; 00292 res = local_queue_frame(p, isoutbound, &f, ast); 00293 ast_mutex_unlock(&p->lock); 00294 return res; 00295 }
|
|
Definition at line 515 of file chan_local.c. References ast_best_codec(), 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, fmt, local_tech, 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_lock, and ast_channel::writeformat. Referenced by local_request(). 00516 { 00517 struct ast_channel *tmp, *tmp2; 00518 int randnum = rand() & 0xffff, fmt = 0; 00519 00520 tmp = ast_channel_alloc(1); 00521 tmp2 = ast_channel_alloc(1); 00522 if (!tmp || !tmp2) { 00523 if (tmp) 00524 ast_channel_free(tmp); 00525 if (tmp2) 00526 ast_channel_free(tmp2); 00527 ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n"); 00528 return NULL; 00529 } 00530 00531 tmp2->tech = tmp->tech = &local_tech; 00532 tmp->nativeformats = p->reqformat; 00533 tmp2->nativeformats = p->reqformat; 00534 snprintf(tmp->name, sizeof(tmp->name), "Local/%s@%s-%04x,1", p->exten, p->context, randnum); 00535 snprintf(tmp2->name, sizeof(tmp2->name), "Local/%s@%s-%04x,2", p->exten, p->context, randnum); 00536 tmp->type = type; 00537 tmp2->type = type; 00538 ast_setstate(tmp, state); 00539 ast_setstate(tmp2, AST_STATE_RING); 00540 fmt = ast_best_codec(p->reqformat); 00541 tmp->writeformat = fmt; 00542 tmp2->writeformat = fmt; 00543 tmp->rawwriteformat = fmt; 00544 tmp2->rawwriteformat = fmt; 00545 tmp->readformat = fmt; 00546 tmp2->readformat = fmt; 00547 tmp->rawreadformat = fmt; 00548 tmp2->rawreadformat = fmt; 00549 tmp->tech_pvt = p; 00550 tmp2->tech_pvt = p; 00551 p->owner = tmp; 00552 p->chan = tmp2; 00553 ast_mutex_lock(&usecnt_lock); 00554 usecnt++; 00555 usecnt++; 00556 ast_mutex_unlock(&usecnt_lock); 00557 ast_update_use_count(); 00558 ast_copy_string(tmp->context, p->context, sizeof(tmp->context)); 00559 ast_copy_string(tmp2->context, p->context, sizeof(tmp2->context)); 00560 ast_copy_string(tmp2->exten, p->exten, sizeof(tmp->exten)); 00561 tmp->priority = 1; 00562 tmp2->priority = 1; 00563 00564 return tmp; 00565 }
|
|
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 235 of file chan_local.c. References AST_FRAME_NULL. 00236 { 00237 static struct ast_frame null = { AST_FRAME_NULL, }; 00238 00239 return &null; 00240 }
|
|
Definition at line 569 of file chan_local.c. References AST_STATE_DOWN, local_alloc(), and local_new(). 00570 { 00571 struct local_pvt *p; 00572 struct ast_channel *chan = NULL; 00573 00574 p = local_alloc(data, format); 00575 if (p) 00576 chan = local_new(p, AST_STATE_DOWN); 00577 return chan; 00578 }
|
|
Definition at line 312 of file chan_local.c. References AST_FRAME_HTML, 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. 00313 { 00314 struct local_pvt *p = ast->tech_pvt; 00315 int res = -1; 00316 struct ast_frame f = { AST_FRAME_HTML, }; 00317 int isoutbound; 00318 00319 ast_mutex_lock(&p->lock); 00320 isoutbound = IS_OUTBOUND(ast, p); 00321 f.subclass = subclass; 00322 f.data = (char *)data; 00323 f.datalen = datalen; 00324 res = local_queue_frame(p, isoutbound, &f, ast); 00325 ast_mutex_unlock(&p->lock); 00326 return res; 00327 }
|
|
Definition at line 242 of file chan_local.c. References AST_FRAME_VOICE, 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. 00243 { 00244 struct local_pvt *p = ast->tech_pvt; 00245 int res = -1; 00246 int isoutbound; 00247 00248 /* Just queue for delivery to the other side */ 00249 ast_mutex_lock(&p->lock); 00250 isoutbound = IS_OUTBOUND(ast, p); 00251 if (f && (f->frametype == AST_FRAME_VOICE)) 00252 check_bridge(p, isoutbound); 00253 if (!p->alreadymasqed) 00254 res = local_queue_frame(p, isoutbound, f, ast); 00255 else { 00256 ast_log(LOG_DEBUG, "Not posting to queue since already masked on '%s'\n", ast->name); 00257 res = 0; 00258 } 00259 ast_mutex_unlock(&p->lock); 00260 return res; 00261 }
|
|
Definition at line 581 of file chan_local.c. References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), local_pvt::context, local_pvt::exten, locals, local_pvt::lock, ast_channel::name, local_pvt::next, local_pvt::owner, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00582 { 00583 struct local_pvt *p; 00584 00585 if (argc != 3) 00586 return RESULT_SHOWUSAGE; 00587 ast_mutex_lock(&locallock); 00588 p = locals; 00589 while(p) { 00590 ast_mutex_lock(&p->lock); 00591 ast_cli(fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "<unowned>", p->exten, p->context); 00592 ast_mutex_unlock(&p->lock); 00593 p = p->next; 00594 } 00595 if (!locals) 00596 ast_cli(fd, "No local channels in use\n"); 00597 ast_mutex_unlock(&locallock); 00598 return RESULT_SUCCESS; 00599 }
|
|
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 622 of file chan_local.c.
|
|
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 628 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. 00629 { 00630 struct local_pvt *p; 00631 00632 /* First, take us out of the channel loop */ 00633 ast_cli_unregister(&cli_show_locals); 00634 ast_channel_unregister(&local_tech); 00635 if (!ast_mutex_lock(&locallock)) { 00636 /* Hangup all interfaces if they have an owner */ 00637 p = locals; 00638 while(p) { 00639 if (p->owner) 00640 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 00641 p = p->next; 00642 } 00643 locals = NULL; 00644 ast_mutex_unlock(&locallock); 00645 } else { 00646 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 00647 return -1; 00648 } 00649 return 0; 00650 }
|
|
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 652 of file chan_local.c. 00653 { 00654 return usecnt; 00655 }
|
|
Initial value: { { "local", "show", "channels", NULL }, locals_show, "Show status of local channels", show_locals_usage, NULL } Definition at line 605 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(), local_new(), and unload_module(). |
|
|
|
Initial value: "Usage: local show channels\n" " Provides summary information on active local proxy channels.\n" Definition at line 601 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. |