Tue Aug 24 2010 19:41:28

Asterisk developer's documentation


chan_local.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2005, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \author Mark Spencer <markster@digium.com>
00022  *
00023  * \brief Local Proxy Channel
00024  * 
00025  * \ingroup channel_drivers
00026  */
00027 
00028 #include "asterisk.h"
00029 
00030 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 281391 $")
00031 
00032 #include <fcntl.h>
00033 #include <sys/signal.h>
00034 
00035 #include "asterisk/lock.h"
00036 #include "asterisk/channel.h"
00037 #include "asterisk/config.h"
00038 #include "asterisk/module.h"
00039 #include "asterisk/pbx.h"
00040 #include "asterisk/sched.h"
00041 #include "asterisk/io.h"
00042 #include "asterisk/rtp.h"
00043 #include "asterisk/acl.h"
00044 #include "asterisk/callerid.h"
00045 #include "asterisk/file.h"
00046 #include "asterisk/cli.h"
00047 #include "asterisk/app.h"
00048 #include "asterisk/musiconhold.h"
00049 #include "asterisk/manager.h"
00050 #include "asterisk/stringfields.h"
00051 #include "asterisk/devicestate.h"
00052 
00053 static const char tdesc[] = "Local Proxy Channel Driver";
00054 
00055 #define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
00056 
00057 static struct ast_jb_conf g_jb_conf = {
00058    .flags = 0,
00059    .max_size = -1,
00060    .resync_threshold = -1,
00061    .impl = "",
00062    .target_extra = -1,
00063 };
00064 
00065 static struct ast_channel *local_request(const char *type, int format, void *data, int *cause);
00066 static int local_digit_begin(struct ast_channel *ast, char digit);
00067 static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
00068 static int local_call(struct ast_channel *ast, char *dest, int timeout);
00069 static int local_hangup(struct ast_channel *ast);
00070 static int local_answer(struct ast_channel *ast);
00071 static struct ast_frame *local_read(struct ast_channel *ast);
00072 static int local_write(struct ast_channel *ast, struct ast_frame *f);
00073 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
00074 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
00075 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
00076 static int local_sendtext(struct ast_channel *ast, const char *text);
00077 static int local_devicestate(void *data);
00078 static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
00079 static int local_queryoption(struct ast_channel *ast, int option, void *data, int *datalen);
00080 
00081 /* PBX interface structure for channel registration */
00082 static const struct ast_channel_tech local_tech = {
00083    .type = "Local",
00084    .description = tdesc,
00085    .capabilities = -1,
00086    .requester = local_request,
00087    .send_digit_begin = local_digit_begin,
00088    .send_digit_end = local_digit_end,
00089    .call = local_call,
00090    .hangup = local_hangup,
00091    .answer = local_answer,
00092    .read = local_read,
00093    .write = local_write,
00094    .write_video = local_write,
00095    .exception = local_read,
00096    .indicate = local_indicate,
00097    .fixup = local_fixup,
00098    .send_html = local_sendhtml,
00099    .send_text = local_sendtext,
00100    .devicestate = local_devicestate,
00101    .bridged_channel = local_bridgedchannel,
00102    .queryoption = local_queryoption,
00103 };
00104 
00105 struct local_pvt {
00106    ast_mutex_t lock;       /* Channel private lock */
00107    unsigned int flags;                     /* Private flags */
00108    char context[AST_MAX_CONTEXT];      /* Context to call */
00109    char exten[AST_MAX_EXTENSION];      /* Extension to call */
00110    int reqformat;          /* Requested format */
00111    struct ast_jb_conf jb_conf;      /*!< jitterbuffer configuration for this local channel */
00112    struct ast_channel *owner;    /* Master Channel - Bridging happens here */
00113    struct ast_channel *chan;     /* Outbound channel - PBX is run here */
00114    struct ast_module_user *u_owner; /*! reference to keep the module loaded while in use */
00115    struct ast_module_user *u_chan;     /*! reference to keep the module loaded while in use */
00116    AST_LIST_ENTRY(local_pvt) list;     /* Next entity */
00117 };
00118 
00119 #define LOCAL_GLARE_DETECT    (1 << 0) /*!< Detect glare on hangup */
00120 #define LOCAL_CANCEL_QUEUE    (1 << 1) /*!< Cancel queue */
00121 #define LOCAL_ALREADY_MASQED  (1 << 2) /*!< Already masqueraded */
00122 #define LOCAL_LAUNCHED_PBX    (1 << 3) /*!< PBX was launched */
00123 #define LOCAL_NO_OPTIMIZATION (1 << 4) /*!< Do not optimize using masquerading */
00124 #define LOCAL_BRIDGE          (1 << 5) /*!< Report back the "true" channel as being bridged to */
00125 #define LOCAL_MOH_PASSTHRU    (1 << 6) /*!< Pass through music on hold start/stop frames */
00126 
00127 static AST_LIST_HEAD_STATIC(locals, local_pvt);
00128 
00129 /*! \brief Adds devicestate to local channels */
00130 static int local_devicestate(void *data)
00131 {
00132    char *exten = ast_strdupa(data);
00133    char *context = NULL, *opts = NULL;
00134    int res;
00135    struct local_pvt *lp;
00136 
00137    if (!(context = strchr(exten, '@'))) {
00138       ast_log(LOG_WARNING, "Someone used Local/%s somewhere without a @context. This is bad.\n", exten);
00139       return AST_DEVICE_INVALID; 
00140    }
00141 
00142    *context++ = '\0';
00143 
00144    /* Strip options if they exist */
00145    if ((opts = strchr(context, '/')))
00146       *opts = '\0';
00147 
00148    ast_debug(3, "Checking if extension %s@%s exists (devicestate)\n", exten, context);
00149 
00150    res = ast_exists_extension(NULL, context, exten, 1, NULL);
00151    if (!res)      
00152       return AST_DEVICE_INVALID;
00153    
00154    res = AST_DEVICE_NOT_INUSE;
00155    AST_LIST_LOCK(&locals);
00156    AST_LIST_TRAVERSE(&locals, lp, list) {
00157       if (!strcmp(exten, lp->exten) && !strcmp(context, lp->context) && lp->owner) {
00158          res = AST_DEVICE_INUSE;
00159          break;
00160       }
00161    }
00162    AST_LIST_UNLOCK(&locals);
00163 
00164    return res;
00165 }
00166 
00167 /*!
00168  * \note Assumes the pvt is no longer in the pvts list
00169  */
00170 static struct local_pvt *local_pvt_destroy(struct local_pvt *pvt)
00171 {
00172    ast_mutex_destroy(&pvt->lock);
00173    ast_free(pvt);
00174    return NULL;
00175 }
00176 
00177 /*! \brief Return the bridged channel of a Local channel */
00178 static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge)
00179 {
00180    struct local_pvt *p = bridge->tech_pvt;
00181    struct ast_channel *bridged = bridge;
00182 
00183    if (!p) {
00184       ast_debug(1, "Asked for bridged channel on '%s'/'%s', returning <none>\n",
00185          chan->name, bridge->name);
00186       return NULL;
00187    }
00188 
00189    ast_mutex_lock(&p->lock);
00190 
00191    if (ast_test_flag(p, LOCAL_BRIDGE)) {
00192       /* Find the opposite channel */
00193       bridged = (bridge == p->owner ? p->chan : p->owner);
00194       
00195       /* Now see if the opposite channel is bridged to anything */
00196       if (!bridged) {
00197          bridged = bridge;
00198       } else if (bridged->_bridge) {
00199          bridged = bridged->_bridge;
00200       }
00201    }
00202 
00203    ast_mutex_unlock(&p->lock);
00204 
00205    return bridged;
00206 }
00207 
00208 static int local_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
00209 {
00210    struct local_pvt *p = ast->tech_pvt;
00211    struct ast_channel *chan, *bridged;
00212    int res;
00213 
00214    if (!p) {
00215       return -1;
00216    }
00217 
00218    if (option != AST_OPTION_T38_STATE) {
00219       /* AST_OPTION_T38_STATE is the only supported option at this time */
00220       return -1;
00221    }
00222 
00223    ast_mutex_lock(&p->lock);
00224    chan = IS_OUTBOUND(ast, p) ? p->owner : p->chan;
00225 
00226 try_again:
00227    if (!chan) {
00228       ast_mutex_unlock(&p->lock);
00229       return -1;
00230    }
00231 
00232    if (ast_channel_trylock(chan)) {
00233       DEADLOCK_AVOIDANCE(&p->lock);
00234       chan = IS_OUTBOUND(ast, p) ? p->owner : p->chan;
00235       goto try_again;
00236    }
00237 
00238    bridged = ast_bridged_channel(chan);
00239    if (!bridged) {
00240       /* can't query channel unless we are bridged */
00241       ast_mutex_unlock(&p->lock);
00242       ast_channel_unlock(chan);
00243       return -1;
00244    }
00245 
00246    if (ast_channel_trylock(bridged)) {
00247       ast_channel_unlock(chan);
00248       DEADLOCK_AVOIDANCE(&p->lock);
00249       chan = IS_OUTBOUND(ast, p) ? p->owner : p->chan;
00250       goto try_again;
00251    }
00252 
00253    res = ast_channel_queryoption(bridged, option, data, datalen, 0);
00254    ast_mutex_unlock(&p->lock);
00255    ast_channel_unlock(chan);
00256    ast_channel_unlock(bridged);
00257    return res;
00258 }
00259 
00260 static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, 
00261    struct ast_channel *us, int us_locked)
00262 {
00263    struct ast_channel *other = NULL;
00264 
00265    /* Recalculate outbound channel */
00266    other = isoutbound ? p->owner : p->chan;
00267 
00268    if (!other) {
00269       return 0;
00270    }
00271 
00272    /* do not queue frame if generator is on both local channels */
00273    if (us && us->generator && other->generator) {
00274       return 0;
00275    }
00276 
00277    /* Set glare detection */
00278    ast_set_flag(p, LOCAL_GLARE_DETECT);
00279 
00280    /* Ensure that we have both channels locked */
00281    while (other && ast_channel_trylock(other)) {
00282       int res;
00283       if ((res = ast_mutex_unlock(&p->lock))) {
00284          ast_log(LOG_ERROR, "chan_local bug! '&p->lock' was not locked when entering local_queue_frame! (%s)\n", strerror(res));
00285          return -1;
00286       }
00287       if (us && us_locked) {
00288          do {
00289             CHANNEL_DEADLOCK_AVOIDANCE(us);
00290          } while (ast_mutex_trylock(&p->lock));
00291       } else {
00292          usleep(1);
00293          ast_mutex_lock(&p->lock);
00294       }
00295       other = isoutbound ? p->owner : p->chan;
00296    }
00297 
00298    /* Since glare detection only occurs within this function, and because
00299     * a pvt flag cannot be set without having the pvt lock, this is the only
00300     * location where we could detect a cancelling of the queue. */
00301    if (ast_test_flag(p, LOCAL_CANCEL_QUEUE)) {
00302       /* We had a glare on the hangup.  Forget all this business,
00303       return and destroy p.  */
00304       ast_mutex_unlock(&p->lock);
00305       p = local_pvt_destroy(p);
00306       if (other) {
00307          ast_channel_unlock(other);
00308       }
00309       return -1;
00310    }
00311 
00312    if (other) {
00313       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_RINGING) {
00314          ast_setstate(other, AST_STATE_RINGING);
00315       }
00316       ast_queue_frame(other, f);
00317       ast_channel_unlock(other);
00318    }
00319 
00320    ast_clear_flag(p, LOCAL_GLARE_DETECT);
00321 
00322    return 0;
00323 }
00324 
00325 static int local_answer(struct ast_channel *ast)
00326 {
00327    struct local_pvt *p = ast->tech_pvt;
00328    int isoutbound;
00329    int res = -1;
00330 
00331    if (!p)
00332       return -1;
00333 
00334    ast_mutex_lock(&p->lock);
00335    isoutbound = IS_OUTBOUND(ast, p);
00336    if (isoutbound) {
00337       /* Pass along answer since somebody answered us */
00338       struct ast_frame answer = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
00339       res = local_queue_frame(p, isoutbound, &answer, ast, 1);
00340    } else
00341       ast_log(LOG_WARNING, "Huh?  Local is being asked to answer?\n");
00342    if (!res)
00343       ast_mutex_unlock(&p->lock);
00344    return res;
00345 }
00346 
00347 /*!
00348  * \internal
00349  * \note This function assumes that we're only called from the "outbound" local channel side
00350  */
00351 static void check_bridge(struct local_pvt *p)
00352 {
00353    struct ast_channel_monitor *tmp;
00354    if (ast_test_flag(p, LOCAL_ALREADY_MASQED) || ast_test_flag(p, LOCAL_NO_OPTIMIZATION) || !p->chan || !p->owner || (p->chan->_bridge != ast_bridged_channel(p->chan)))
00355       return;
00356 
00357    /* only do the masquerade if we are being called on the outbound channel,
00358       if it has been bridged to another channel and if there are no pending
00359       frames on the owner channel (because they would be transferred to the
00360       outbound channel during the masquerade)
00361    */
00362    if (p->chan->_bridge /* Not ast_bridged_channel!  Only go one step! */ && AST_LIST_EMPTY(&p->owner->readq)) {
00363       /* Masquerade bridged channel into owner */
00364       /* Lock everything we need, one by one, and give up if
00365          we can't get everything.  Remember, we'll get another
00366          chance in just a little bit */
00367       if (!ast_channel_trylock(p->chan->_bridge)) {
00368          if (!ast_check_hangup(p->chan->_bridge)) {
00369             if (!ast_channel_trylock(p->owner)) {
00370                if (!ast_check_hangup(p->owner)) {
00371                   if (p->owner->monitor && !p->chan->_bridge->monitor) {
00372                      /* If a local channel is being monitored, we don't want a masquerade
00373                       * to cause the monitor to go away. Since the masquerade swaps the monitors,
00374                       * pre-swapping the monitors before the masquerade will ensure that the monitor
00375                       * ends up where it is expected.
00376                       */
00377                      tmp = p->owner->monitor;
00378                      p->owner->monitor = p->chan->_bridge->monitor;
00379                      p->chan->_bridge->monitor = tmp;
00380                   }
00381                   if (p->chan->audiohooks) {
00382                      struct ast_audiohook_list *audiohooks_swapper;
00383                      audiohooks_swapper = p->chan->audiohooks;
00384                      p->chan->audiohooks = p->owner->audiohooks;
00385                      p->owner->audiohooks = audiohooks_swapper;
00386                   }
00387 
00388                   /* If any Caller ID was set, preserve it after masquerade like above. We must check
00389                    * to see if Caller ID was set because otherwise we'll mistakingly copy info not
00390                    * set from the dialplan and will overwrite the real channel Caller ID. The reason
00391                    * for this whole preswapping action is because the Caller ID is set on the channel
00392                    * thread (which is the to be masqueraded away local channel) before both local
00393                    * channels are optimized away.
00394                    */
00395                   if (p->owner->cid.cid_dnid || p->owner->cid.cid_num ||
00396                      p->owner->cid.cid_name || p->owner->cid.cid_ani ||
00397                      p->owner->cid.cid_rdnis || p->owner->cid.cid_pres ||  
00398                      p->owner->cid.cid_ani2 || p->owner->cid.cid_ton ||  
00399                      p->owner->cid.cid_tns) {
00400 
00401                      struct ast_callerid tmpcid;
00402                      tmpcid = p->owner->cid;
00403                      p->owner->cid = p->chan->_bridge->cid;
00404                      p->chan->_bridge->cid = tmpcid;
00405                   }
00406 
00407                   ast_app_group_update(p->chan, p->owner);
00408                   ast_channel_masquerade(p->owner, p->chan->_bridge);
00409                   ast_set_flag(p, LOCAL_ALREADY_MASQED);
00410                }
00411                ast_channel_unlock(p->owner);
00412             }
00413             ast_channel_unlock(p->chan->_bridge);
00414          }
00415       }
00416    }
00417 }
00418 
00419 static struct ast_frame  *local_read(struct ast_channel *ast)
00420 {
00421    return &ast_null_frame;
00422 }
00423 
00424 static int local_write(struct ast_channel *ast, struct ast_frame *f)
00425 {
00426    struct local_pvt *p = ast->tech_pvt;
00427    int res = -1;
00428    int isoutbound;
00429 
00430    if (!p)
00431       return -1;
00432 
00433    /* Just queue for delivery to the other side */
00434    ast_mutex_lock(&p->lock);
00435    isoutbound = IS_OUTBOUND(ast, p);
00436    if (isoutbound && f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO))
00437       check_bridge(p);
00438    if (!ast_test_flag(p, LOCAL_ALREADY_MASQED))
00439       res = local_queue_frame(p, isoutbound, f, ast, 1);
00440    else {
00441       ast_debug(1, "Not posting to queue since already masked on '%s'\n", ast->name);
00442       res = 0;
00443    }
00444    if (!res)
00445       ast_mutex_unlock(&p->lock);
00446    return res;
00447 }
00448 
00449 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
00450 {
00451    struct local_pvt *p = newchan->tech_pvt;
00452 
00453    if (!p)
00454       return -1;
00455 
00456    ast_mutex_lock(&p->lock);
00457 
00458    if ((p->owner != oldchan) && (p->chan != oldchan)) {
00459       ast_log(LOG_WARNING, "Old channel wasn't %p but was %p/%p\n", oldchan, p->owner, p->chan);
00460       ast_mutex_unlock(&p->lock);
00461       return -1;
00462    }
00463    if (p->owner == oldchan)
00464       p->owner = newchan;
00465    else
00466       p->chan = newchan;
00467    ast_mutex_unlock(&p->lock);
00468    return 0;
00469 }
00470 
00471 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
00472 {
00473    struct local_pvt *p = ast->tech_pvt;
00474    int res = 0;
00475    struct ast_frame f = { AST_FRAME_CONTROL, };
00476    int isoutbound;
00477 
00478    if (!p)
00479       return -1;
00480 
00481    /* If this is an MOH hold or unhold, do it on the Local channel versus real channel */
00482    if (!ast_test_flag(p, LOCAL_MOH_PASSTHRU) && condition == AST_CONTROL_HOLD) {
00483       ast_moh_start(ast, data, NULL);
00484    } else if (!ast_test_flag(p, LOCAL_MOH_PASSTHRU) && condition == AST_CONTROL_UNHOLD) {
00485       ast_moh_stop(ast);
00486    } else {
00487       /* Queue up a frame representing the indication as a control frame */
00488       ast_mutex_lock(&p->lock);
00489       isoutbound = IS_OUTBOUND(ast, p);
00490       f.subclass = condition;
00491       f.data.ptr = (void*)data;
00492       f.datalen = datalen;
00493       if (!(res = local_queue_frame(p, isoutbound, &f, ast, 1)))
00494          ast_mutex_unlock(&p->lock);
00495    }
00496 
00497    return res;
00498 }
00499 
00500 static int local_digit_begin(struct ast_channel *ast, char digit)
00501 {
00502    struct local_pvt *p = ast->tech_pvt;
00503    int res = -1;
00504    struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
00505    int isoutbound;
00506 
00507    if (!p)
00508       return -1;
00509 
00510    ast_mutex_lock(&p->lock);
00511    isoutbound = IS_OUTBOUND(ast, p);
00512    f.subclass = digit;
00513    if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
00514       ast_mutex_unlock(&p->lock);
00515 
00516    return res;
00517 }
00518 
00519 static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
00520 {
00521    struct local_pvt *p = ast->tech_pvt;
00522    int res = -1;
00523    struct ast_frame f = { AST_FRAME_DTMF_END, };
00524    int isoutbound;
00525 
00526    if (!p)
00527       return -1;
00528 
00529    ast_mutex_lock(&p->lock);
00530    isoutbound = IS_OUTBOUND(ast, p);
00531    f.subclass = digit;
00532    f.len = duration;
00533    if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
00534       ast_mutex_unlock(&p->lock);
00535 
00536    return res;
00537 }
00538 
00539 static int local_sendtext(struct ast_channel *ast, const char *text)
00540 {
00541    struct local_pvt *p = ast->tech_pvt;
00542    int res = -1;
00543    struct ast_frame f = { AST_FRAME_TEXT, };
00544    int isoutbound;
00545 
00546    if (!p)
00547       return -1;
00548 
00549    ast_mutex_lock(&p->lock);
00550    isoutbound = IS_OUTBOUND(ast, p);
00551    f.data.ptr = (char *) text;
00552    f.datalen = strlen(text) + 1;
00553    if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
00554       ast_mutex_unlock(&p->lock);
00555    return res;
00556 }
00557 
00558 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
00559 {
00560    struct local_pvt *p = ast->tech_pvt;
00561    int res = -1;
00562    struct ast_frame f = { AST_FRAME_HTML, };
00563    int isoutbound;
00564 
00565    if (!p)
00566       return -1;
00567    
00568    ast_mutex_lock(&p->lock);
00569    isoutbound = IS_OUTBOUND(ast, p);
00570    f.subclass = subclass;
00571    f.data.ptr = (char *)data;
00572    f.datalen = datalen;
00573    if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
00574       ast_mutex_unlock(&p->lock);
00575    return res;
00576 }
00577 
00578 /*! \brief Initiate new call, part of PBX interface 
00579  *    dest is the dial string */
00580 static int local_call(struct ast_channel *ast, char *dest, int timeout)
00581 {
00582    struct local_pvt *p = ast->tech_pvt;
00583    int res;
00584    struct ast_var_t *varptr = NULL, *new;
00585    size_t len, namelen;
00586 
00587    if (!p)
00588       return -1;
00589    
00590    ast_mutex_lock(&p->lock);
00591 
00592    /*
00593     * Note that cid_num and cid_name aren't passed in the ast_channel_alloc
00594     * call, so it's done here instead.
00595     */
00596    p->chan->cid.cid_dnid = ast_strdup(p->owner->cid.cid_dnid);
00597    p->chan->cid.cid_num = ast_strdup(p->owner->cid.cid_num);
00598    p->chan->cid.cid_name = ast_strdup(p->owner->cid.cid_name);
00599    p->chan->cid.cid_rdnis = ast_strdup(p->owner->cid.cid_rdnis);
00600    p->chan->cid.cid_ani = ast_strdup(p->owner->cid.cid_ani);
00601    p->chan->cid.cid_pres = p->owner->cid.cid_pres;
00602    p->chan->cid.cid_ani2 = p->owner->cid.cid_ani2;
00603    p->chan->cid.cid_ton = p->owner->cid.cid_ton;
00604    p->chan->cid.cid_tns = p->owner->cid.cid_tns;
00605    ast_string_field_set(p->chan, language, p->owner->language);
00606    ast_string_field_set(p->chan, accountcode, p->owner->accountcode);
00607    ast_string_field_set(p->chan, musicclass, p->owner->musicclass);
00608    ast_cdr_update(p->chan);
00609    p->chan->cdrflags = p->owner->cdrflags;
00610 
00611    if (!ast_exists_extension(NULL, p->chan->context, p->chan->exten, 1, p->owner->cid.cid_num)) {
00612       ast_log(LOG_NOTICE, "No such extension/context %s@%s while calling Local channel\n", p->chan->exten, p->chan->context);
00613       ast_mutex_unlock(&p->lock);
00614       return -1;
00615    }
00616 
00617    /* Make sure we inherit the ANSWERED_ELSEWHERE flag if it's set on the queue/dial call request in the dialplan */
00618    if (ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE)) {
00619       ast_set_flag(p->chan, AST_FLAG_ANSWERED_ELSEWHERE);
00620    }
00621 
00622    /* copy the channel variables from the incoming channel to the outgoing channel */
00623    /* Note that due to certain assumptions, they MUST be in the same order */
00624    AST_LIST_TRAVERSE(&p->owner->varshead, varptr, entries) {
00625       namelen = strlen(varptr->name);
00626       len = sizeof(struct ast_var_t) + namelen + strlen(varptr->value) + 2;
00627       if ((new = ast_calloc(1, len))) {
00628          memcpy(new, varptr, len);
00629          new->value = &(new->name[0]) + namelen + 1;
00630          AST_LIST_INSERT_TAIL(&p->chan->varshead, new, entries);
00631       }
00632    }
00633    ast_channel_datastore_inherit(p->owner, p->chan);
00634 
00635    /* Start switch on sub channel */
00636    if (!(res = ast_pbx_start(p->chan)))
00637       ast_set_flag(p, LOCAL_LAUNCHED_PBX);
00638 
00639    ast_mutex_unlock(&p->lock);
00640    return res;
00641 }
00642 
00643 /*! \brief Hangup a call through the local proxy channel */
00644 static int local_hangup(struct ast_channel *ast)
00645 {
00646    struct local_pvt *p = ast->tech_pvt;
00647    int isoutbound;
00648    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = ast->hangupcause };
00649    struct ast_channel *ochan = NULL;
00650    int glaredetect = 0, res = 0;
00651 
00652    if (!p)
00653       return -1;
00654 
00655    ast_mutex_lock(&p->lock);
00656 
00657    isoutbound = IS_OUTBOUND(ast, p);
00658 
00659    if (p->chan && ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE)) {
00660       ast_set_flag(p->chan, AST_FLAG_ANSWERED_ELSEWHERE);
00661       ast_debug(2, "This local call has the ANSWERED_ELSEWHERE flag set.\n");
00662    }
00663 
00664    if (isoutbound) {
00665       const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
00666       if ((status) && (p->owner)) {
00667          /* Deadlock avoidance */
00668          while (p->owner && ast_channel_trylock(p->owner)) {
00669             ast_mutex_unlock(&p->lock);
00670             if (p->chan) {
00671                ast_channel_unlock(p->chan);
00672             }
00673             usleep(1);
00674             if (p->chan) {
00675                ast_channel_lock(p->chan);
00676             }
00677             ast_mutex_lock(&p->lock);
00678          }
00679          if (p->owner) {
00680             pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
00681             ast_channel_unlock(p->owner);
00682          }
00683       }
00684       p->chan = NULL;
00685       ast_clear_flag(p, LOCAL_LAUNCHED_PBX);
00686       ast_module_user_remove(p->u_chan);
00687    } else {
00688       ast_module_user_remove(p->u_owner);
00689       while (p->chan && ast_channel_trylock(p->chan)) {
00690             ast_mutex_unlock(&p->lock);
00691             if (p->owner) {
00692                ast_channel_unlock(p->owner);
00693             }
00694             usleep(1);
00695             if (p->owner) {
00696                ast_channel_lock(p->owner);
00697             }
00698             ast_mutex_lock(&p->lock);
00699       }
00700 
00701       p->owner = NULL;
00702       if (p->chan) {
00703          ast_queue_hangup(p->chan);
00704          ast_channel_unlock(p->chan);
00705       }
00706    }
00707    
00708    ast->tech_pvt = NULL;
00709    
00710    if (!p->owner && !p->chan) {
00711       /* Okay, done with the private part now, too. */
00712       glaredetect = ast_test_flag(p, LOCAL_GLARE_DETECT);
00713       /* If we have a queue holding, don't actually destroy p yet, but
00714          let local_queue do it. */
00715       if (glaredetect)
00716          ast_set_flag(p, LOCAL_CANCEL_QUEUE);
00717       /* Remove from list */
00718       AST_LIST_LOCK(&locals);
00719       AST_LIST_REMOVE(&locals, p, list);
00720       AST_LIST_UNLOCK(&locals);
00721       ast_mutex_unlock(&p->lock);
00722       /* And destroy */
00723       if (!glaredetect) {
00724          p = local_pvt_destroy(p);
00725       }
00726       return 0;
00727    }
00728    if (p->chan && !ast_test_flag(p, LOCAL_LAUNCHED_PBX))
00729       /* Need to actually hangup since there is no PBX */
00730       ochan = p->chan;
00731    else
00732       res = local_queue_frame(p, isoutbound, &f, NULL, 1);
00733    if (!res)
00734       ast_mutex_unlock(&p->lock);
00735    if (ochan)
00736       ast_hangup(ochan);
00737    return 0;
00738 }
00739 
00740 /*! \brief Create a call structure */
00741 static struct local_pvt *local_alloc(const char *data, int format)
00742 {
00743    struct local_pvt *tmp = NULL;
00744    char *c = NULL, *opts = NULL;
00745 
00746    if (!(tmp = ast_calloc(1, sizeof(*tmp))))
00747       return NULL;
00748 
00749    /* Initialize private structure information */
00750    ast_mutex_init(&tmp->lock);
00751    ast_copy_string(tmp->exten, data, sizeof(tmp->exten));
00752 
00753    memcpy(&tmp->jb_conf, &g_jb_conf, sizeof(tmp->jb_conf));
00754 
00755    /* Look for options */
00756    if ((opts = strchr(tmp->exten, '/'))) {
00757       *opts++ = '\0';
00758       if (strchr(opts, 'n'))
00759          ast_set_flag(tmp, LOCAL_NO_OPTIMIZATION);
00760       if (strchr(opts, 'j')) {
00761          if (ast_test_flag(tmp, LOCAL_NO_OPTIMIZATION))
00762             ast_set_flag(&tmp->jb_conf, AST_JB_ENABLED);
00763          else {
00764             ast_log(LOG_ERROR, "You must use the 'n' option for chan_local "
00765                "to use the 'j' option to enable the jitterbuffer\n");
00766          }
00767       }
00768       if (strchr(opts, 'b')) {
00769          ast_set_flag(tmp, LOCAL_BRIDGE);
00770       }
00771       if (strchr(opts, 'm')) {
00772          ast_set_flag(tmp, LOCAL_MOH_PASSTHRU);
00773       }
00774    }
00775 
00776    /* Look for a context */
00777    if ((c = strchr(tmp->exten, '@')))
00778       *c++ = '\0';
00779 
00780    ast_copy_string(tmp->context, c ? c : "default", sizeof(tmp->context));
00781 
00782    tmp->reqformat = format;
00783 
00784 #if 0
00785    /* We can't do this check here, because we don't know the CallerID yet, and
00786     * the CallerID could potentially affect what step is actually taken (or
00787     * even if that step exists). */
00788    if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) {
00789       ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->exten, tmp->context);
00790       tmp = local_pvt_destroy(tmp);
00791    } else {
00792 #endif
00793       /* Add to list */
00794       AST_LIST_LOCK(&locals);
00795       AST_LIST_INSERT_HEAD(&locals, tmp, list);
00796       AST_LIST_UNLOCK(&locals);
00797 #if 0
00798    }
00799 #endif
00800    
00801    return tmp;
00802 }
00803 
00804 /*! \brief Start new local channel */
00805 static struct ast_channel *local_new(struct local_pvt *p, int state)
00806 {
00807    struct ast_channel *tmp = NULL, *tmp2 = NULL;
00808    int randnum = ast_random() & 0xffff, fmt = 0;
00809    const char *t;
00810    int ama;
00811 
00812    /* Allocate two new Asterisk channels */
00813    /* safe accountcode */
00814    if (p->owner && p->owner->accountcode)
00815       t = p->owner->accountcode;
00816    else
00817       t = "";
00818 
00819    if (p->owner)
00820       ama = p->owner->amaflags;
00821    else
00822       ama = 0;
00823    if (!(tmp = ast_channel_alloc(1, state, 0, 0, t, p->exten, p->context, ama, "Local/%s@%s-%04x;1", p->exten, p->context, randnum)) 
00824          || !(tmp2 = ast_channel_alloc(1, AST_STATE_RING, 0, 0, t, p->exten, p->context, ama, "Local/%s@%s-%04x;2", p->exten, p->context, randnum))) {
00825       if (tmp)
00826          ast_channel_free(tmp);
00827       if (tmp2)
00828          ast_channel_free(tmp2);
00829       ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
00830       return NULL;
00831    } 
00832 
00833    tmp2->tech = tmp->tech = &local_tech;
00834 
00835    tmp->nativeformats = p->reqformat;
00836    tmp2->nativeformats = p->reqformat;
00837 
00838    /* Determine our read/write format and set it on each channel */
00839    fmt = ast_best_codec(p->reqformat);
00840    tmp->writeformat = fmt;
00841    tmp2->writeformat = fmt;
00842    tmp->rawwriteformat = fmt;
00843    tmp2->rawwriteformat = fmt;
00844    tmp->readformat = fmt;
00845    tmp2->readformat = fmt;
00846    tmp->rawreadformat = fmt;
00847    tmp2->rawreadformat = fmt;
00848 
00849    tmp->tech_pvt = p;
00850    tmp2->tech_pvt = p;
00851 
00852    p->owner = tmp;
00853    p->chan = tmp2;
00854    p->u_owner = ast_module_user_add(p->owner);
00855    p->u_chan = ast_module_user_add(p->chan);
00856 
00857    ast_copy_string(tmp->context, p->context, sizeof(tmp->context));
00858    ast_copy_string(tmp2->context, p->context, sizeof(tmp2->context));
00859    ast_copy_string(tmp2->exten, p->exten, sizeof(tmp->exten));
00860    tmp->priority = 1;
00861    tmp2->priority = 1;
00862 
00863    ast_jb_configure(tmp, &p->jb_conf);
00864 
00865    return tmp;
00866 }
00867 
00868 /*! \brief Part of PBX interface */
00869 static struct ast_channel *local_request(const char *type, int format, void *data, int *cause)
00870 {
00871    struct local_pvt *p = NULL;
00872    struct ast_channel *chan = NULL;
00873 
00874    /* Allocate a new private structure and then Asterisk channel */
00875    if ((p = local_alloc(data, format))) {
00876       if (!(chan = local_new(p, AST_STATE_DOWN))) {
00877          AST_LIST_LOCK(&locals);
00878          AST_LIST_REMOVE(&locals, p, list);
00879          AST_LIST_UNLOCK(&locals);
00880          p = local_pvt_destroy(p);
00881       }
00882    }
00883 
00884    return chan;
00885 }
00886 
00887 /*! \brief CLI command "local show channels" */
00888 static char *locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
00889 {
00890    struct local_pvt *p = NULL;
00891 
00892    switch (cmd) {
00893    case CLI_INIT:
00894       e->command = "local show channels";
00895       e->usage =
00896          "Usage: local show channels\n"
00897          "       Provides summary information on active local proxy channels.\n";
00898       return NULL;
00899    case CLI_GENERATE:
00900       return NULL;
00901    }
00902 
00903    if (a->argc != 3)
00904       return CLI_SHOWUSAGE;
00905 
00906    AST_LIST_LOCK(&locals);
00907    if (!AST_LIST_EMPTY(&locals)) {
00908       AST_LIST_TRAVERSE(&locals, p, list) {
00909          ast_mutex_lock(&p->lock);
00910          ast_cli(a->fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "<unowned>", p->exten, p->context);
00911          ast_mutex_unlock(&p->lock);
00912       }
00913    } else
00914       ast_cli(a->fd, "No local channels in use\n");
00915    AST_LIST_UNLOCK(&locals);
00916 
00917    return CLI_SUCCESS;
00918 }
00919 
00920 static struct ast_cli_entry cli_local[] = {
00921    AST_CLI_DEFINE(locals_show, "List status of local channels"),
00922 };
00923 
00924 /*! \brief Load module into PBX, register channel */
00925 static int load_module(void)
00926 {
00927    /* Make sure we can register our channel type */
00928    if (ast_channel_register(&local_tech)) {
00929       ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
00930       return AST_MODULE_LOAD_FAILURE;
00931    }
00932    ast_cli_register_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
00933    return AST_MODULE_LOAD_SUCCESS;
00934 }
00935 
00936 /*! \brief Unload the local proxy channel from Asterisk */
00937 static int unload_module(void)
00938 {
00939    struct local_pvt *p = NULL;
00940 
00941    /* First, take us out of the channel loop */
00942    ast_cli_unregister_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
00943    ast_channel_unregister(&local_tech);
00944    if (!AST_LIST_LOCK(&locals)) {
00945       /* Hangup all interfaces if they have an owner */
00946       AST_LIST_TRAVERSE(&locals, p, list) {
00947          if (p->owner)
00948             ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
00949       }
00950       AST_LIST_UNLOCK(&locals);
00951    } else {
00952       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
00953       return -1;
00954    }     
00955    return 0;
00956 }
00957 
00958 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Local Proxy Channel (Note: used internally by other modules)");