Thu May 24 14:21:52 2007

Asterisk developer's documentation


chan_local.c File Reference

Local Proxy Channel. More...

#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"

Include dependency graph for chan_local.c:

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_pvtlocal_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_channellocal_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_framelocal_read (struct ast_channel *ast)
static struct ast_channellocal_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 struct ast_channel_tech local_tech
static struct local_pvtlocals
static char show_locals_usage []
static const char tdesc [] = "Local Proxy Channel Driver"
static const char type [] = "Local"
static int usecnt = 0


Detailed Description

Local Proxy Channel.

Definition in file chan_local.c.


Define Documentation

#define IS_OUTBOUND ( a,
 )     (a == b->chan ? 1 : 0)

Definition at line 68 of file chan_local.c.


Function Documentation

AST_MUTEX_DEFINE_STATIC ( locallock   ) 

AST_MUTEX_DEFINE_STATIC ( usecnt_lock   ) 

static void check_bridge ( struct local_pvt p,
int  isoutbound 
) [static]

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 }

char* description ( void   ) 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 662 of file chan_local.c.

00663 {
00664    return (char *) desc;
00665 }

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;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 657 of file chan_local.c.

References ASTERISK_GPL_KEY.

00658 {
00659    return ASTERISK_GPL_KEY;
00660 }

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.

Returns:
int Always 0.

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 }

static struct local_pvt* local_alloc ( char *  data,
int  format 
) [static]

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 }

static int local_answer ( struct ast_channel ast  )  [static]

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 }

static int local_call ( struct ast_channel ast,
char *  dest,
int  timeout 
) [static]

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 }

static int local_digit ( struct ast_channel ast,
char  digit 
) [static]

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 }

static int local_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
) [static]

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 }

static int local_hangup ( struct ast_channel ast  )  [static]

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 }

static int local_indicate ( struct ast_channel ast,
int  condition 
) [static]

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 }

static struct ast_channel* local_new ( struct local_pvt p,
int  state 
) [static]

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 }

static int local_queue_frame ( struct local_pvt p,
int  isoutbound,
struct ast_frame f,
struct ast_channel us 
) [static]

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 }

static struct ast_frame * local_read ( struct ast_channel ast  )  [static]

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 }

static struct ast_channel * local_request ( const char *  type,
int  format,
void *  data,
int *  cause 
) [static]

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 }

static int local_sendhtml ( struct ast_channel ast,
int  subclass,
const char *  data,
int  datalen 
) [static]

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 }

static int local_write ( struct ast_channel ast,
struct ast_frame f 
) [static]

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 }

static int locals_show ( int  fd,
int  argc,
char **  argv 
) [static]

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 }

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.

Returns:
The return value is not used.

Definition at line 622 of file chan_local.c.

00623 {
00624    return 0;
00625 }

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).

Returns:
Zero on success, or non-zero on error.

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 }

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.

Returns:
The module's usecount.

Definition at line 652 of file chan_local.c.

00653 {
00654    return usecnt;
00655 }


Variable Documentation

struct ast_cli_entry cli_show_locals [static]

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().

const char desc[] = "Local Proxy Channel" [static]

Definition at line 61 of file chan_local.c.

struct ast_channel_tech local_tech [static]

Definition at line 85 of file chan_local.c.

Referenced by load_module(), local_new(), and unload_module().

struct local_pvt * locals [static]

char show_locals_usage[] [static]

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.

const char tdesc[] = "Local Proxy Channel Driver" [static]

Definition at line 63 of file chan_local.c.

const char type[] = "Local" [static]

Definition at line 62 of file chan_local.c.

int usecnt = 0 [static]

Definition at line 65 of file chan_local.c.


Generated on Thu May 24 14:21:52 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.7