Sat Mar 24 23:27:12 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 const 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    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 }

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 657 of file chan_local.c.

00658 {
00659    return (char *) desc;
00660 }

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 652 of file chan_local.c.

References ASTERISK_GPL_KEY.

00653 {
00654    return ASTERISK_GPL_KEY;
00655 }

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 605 of file chan_local.c.

References ast_channel_register(), ast_cli_register(), ast_log(), cli_show_locals, local_tech, and LOG_ERROR.

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 }

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

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(), free, locals, LOG_NOTICE, and malloc.

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 }

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

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

Definition at line 285 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.

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 }

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

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 }

static int local_hangup struct ast_channel ast  )  [static]
 

Definition at line 400 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.

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 }

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

Definition at line 269 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.

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 }

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

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

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 }

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 223 of file chan_local.c.

References AST_FRAME_NULL.

00224 {
00225    static struct ast_frame null = { AST_FRAME_NULL, };
00226 
00227    return &null;
00228 }

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

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 }

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

Definition at line 300 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.

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 }

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

Definition at line 230 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.

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 }

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

Definition at line 576 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.

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 }

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 617 of file chan_local.c.

00618 {
00619    return 0;
00620 }

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

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 647 of file chan_local.c.

00648 {
00649    return usecnt;
00650 }


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

const 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 596 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 Sat Mar 24 23:27:13 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.6