Sat Apr 26 2014 22:01:32

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 /*** MODULEINFO
00029    <support_level>core</support_level>
00030  ***/
00031 
00032 #include "asterisk.h"
00033 
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 407457 $")
00035 
00036 #include <fcntl.h>
00037 #include <sys/signal.h>
00038 
00039 #include "asterisk/lock.h"
00040 #include "asterisk/causes.h"
00041 #include "asterisk/channel.h"
00042 #include "asterisk/config.h"
00043 #include "asterisk/module.h"
00044 #include "asterisk/pbx.h"
00045 #include "asterisk/sched.h"
00046 #include "asterisk/io.h"
00047 #include "asterisk/acl.h"
00048 #include "asterisk/callerid.h"
00049 #include "asterisk/file.h"
00050 #include "asterisk/cli.h"
00051 #include "asterisk/app.h"
00052 #include "asterisk/musiconhold.h"
00053 #include "asterisk/manager.h"
00054 #include "asterisk/stringfields.h"
00055 #include "asterisk/devicestate.h"
00056 #include "asterisk/astobj2.h"
00057 
00058 /*** DOCUMENTATION
00059    <manager name="LocalOptimizeAway" language="en_US">
00060       <synopsis>
00061          Optimize away a local channel when possible.
00062       </synopsis>
00063       <syntax>
00064          <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
00065          <parameter name="Channel" required="true">
00066             <para>The channel name to optimize away.</para>
00067          </parameter>
00068       </syntax>
00069       <description>
00070          <para>A local channel created with "/n" will not automatically optimize away.
00071          Calling this command on the local channel will clear that flag and allow
00072          it to optimize away if it's bridged or when it becomes bridged.</para>
00073       </description>
00074    </manager>
00075  ***/
00076 
00077 static const char tdesc[] = "Local Proxy Channel Driver";
00078 
00079 #define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
00080 
00081 /* right now we are treating the locals astobj2 container as a
00082  * list.  If there is ever a reason to make this more efficient
00083  * increasing the bucket size would help. */
00084 static const int BUCKET_SIZE = 1;
00085 
00086 static struct ao2_container *locals;
00087 
00088 static unsigned int name_sequence = 0;
00089 
00090 static struct ast_jb_conf g_jb_conf = {
00091    .flags = 0,
00092    .max_size = -1,
00093    .resync_threshold = -1,
00094    .impl = "",
00095    .target_extra = -1,
00096 };
00097 
00098 static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
00099 static int local_digit_begin(struct ast_channel *ast, char digit);
00100 static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
00101 static int local_call(struct ast_channel *ast, const char *dest, int timeout);
00102 static int local_hangup(struct ast_channel *ast);
00103 static int local_answer(struct ast_channel *ast);
00104 static struct ast_frame *local_read(struct ast_channel *ast);
00105 static int local_write(struct ast_channel *ast, struct ast_frame *f);
00106 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
00107 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
00108 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
00109 static int local_sendtext(struct ast_channel *ast, const char *text);
00110 static int local_devicestate(const char *data);
00111 static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
00112 static int local_queryoption(struct ast_channel *ast, int option, void *data, int *datalen);
00113 static int local_setoption(struct ast_channel *chan, int option, void *data, int datalen);
00114 
00115 /* PBX interface structure for channel registration */
00116 static struct ast_channel_tech local_tech = {
00117    .type = "Local",
00118    .description = tdesc,
00119    .requester = local_request,
00120    .send_digit_begin = local_digit_begin,
00121    .send_digit_end = local_digit_end,
00122    .call = local_call,
00123    .hangup = local_hangup,
00124    .answer = local_answer,
00125    .read = local_read,
00126    .write = local_write,
00127    .write_video = local_write,
00128    .exception = local_read,
00129    .indicate = local_indicate,
00130    .fixup = local_fixup,
00131    .send_html = local_sendhtml,
00132    .send_text = local_sendtext,
00133    .devicestate = local_devicestate,
00134    .bridged_channel = local_bridgedchannel,
00135    .queryoption = local_queryoption,
00136    .setoption = local_setoption,
00137 };
00138 
00139 /*! \brief the local pvt structure for all channels
00140 
00141    The local channel pvt has two ast_chan objects - the "owner" and the "next channel", the outbound channel
00142 
00143    ast_chan owner -> local_pvt -> ast_chan chan -> yet-another-pvt-depending-on-channel-type
00144 
00145 */
00146 struct local_pvt {
00147    unsigned int flags;             /*!< Private flags */
00148    char context[AST_MAX_CONTEXT];  /*!< Context to call */
00149    char exten[AST_MAX_EXTENSION];  /*!< Extension to call */
00150    struct ast_format_cap *reqcap;  /*!< Requested format capabilities */
00151    struct ast_jb_conf jb_conf;     /*!< jitterbuffer configuration for this local channel */
00152    struct ast_channel *owner;      /*!< Master Channel - Bridging happens here */
00153    struct ast_channel *chan;       /*!< Outbound channel - PBX is run here */
00154 };
00155 
00156 #define LOCAL_ALREADY_MASQED  (1 << 0) /*!< Already masqueraded */
00157 #define LOCAL_LAUNCHED_PBX    (1 << 1) /*!< PBX was launched */
00158 #define LOCAL_NO_OPTIMIZATION (1 << 2) /*!< Do not optimize using masquerading */
00159 #define LOCAL_BRIDGE          (1 << 3) /*!< Report back the "true" channel as being bridged to */
00160 #define LOCAL_MOH_PASSTHRU    (1 << 4) /*!< Pass through music on hold start/stop frames */
00161 
00162 /* 
00163  * \brief Send a pvt in with no locks held and get all locks
00164  *
00165  * \note NO locks should be held prior to calling this function
00166  * \note The pvt must have a ref held before calling this function
00167  * \note if outchan or outowner is set != NULL after calling this function
00168  *       those channels are locked and reffed.
00169  * \note Batman.
00170  */
00171 static void awesome_locking(struct local_pvt *p, struct ast_channel **outchan, struct ast_channel **outowner)
00172 {
00173    struct ast_channel *chan = NULL;
00174    struct ast_channel *owner = NULL;
00175 
00176    for (;;) {
00177       ao2_lock(p);
00178       if (p->chan) {
00179          chan = p->chan;
00180          ast_channel_ref(chan);
00181       }
00182       if (p->owner) {
00183          owner = p->owner;
00184          ast_channel_ref(owner);
00185       }
00186       ao2_unlock(p);
00187 
00188       /* if we don't have both channels, then this is very easy */
00189       if (!owner || !chan) {
00190          if (owner) {
00191             ast_channel_lock(owner);
00192          } else if(chan) {
00193             ast_channel_lock(chan);
00194          }
00195          ao2_lock(p);
00196       } else {
00197          /* lock both channels first, then get the pvt lock */
00198          ast_channel_lock_both(chan, owner);
00199          ao2_lock(p);
00200       }
00201 
00202       /* Now that we have all the locks, validate that nothing changed */
00203       if (p->owner != owner || p->chan != chan) {
00204          if (owner) {
00205             ast_channel_unlock(owner);
00206             owner = ast_channel_unref(owner);
00207          }
00208          if (chan) {
00209             ast_channel_unlock(chan);
00210             chan = ast_channel_unref(chan);
00211          }
00212          ao2_unlock(p);
00213          continue;
00214       }
00215 
00216       break;
00217    }
00218    *outowner = p->owner;
00219    *outchan = p->chan;
00220 }
00221 
00222 /* Called with ast locked */
00223 static int local_setoption(struct ast_channel *ast, int option, void * data, int datalen)
00224 {
00225    int res = 0;
00226    struct local_pvt *p = NULL;
00227    struct ast_channel *otherchan = NULL;
00228    ast_chan_write_info_t *write_info;
00229 
00230    if (option != AST_OPTION_CHANNEL_WRITE) {
00231       return -1;
00232    }
00233 
00234    write_info = data;
00235 
00236    if (write_info->version != AST_CHAN_WRITE_INFO_T_VERSION) {
00237       ast_log(LOG_ERROR, "The chan_write_info_t type has changed, and this channel hasn't been updated!\n");
00238       return -1;
00239    }
00240 
00241    if (!strcmp(write_info->function, "CHANNEL")
00242       && !strncasecmp(write_info->data, "hangup_handler_", 15)) {
00243       /* Block CHANNEL(hangup_handler_xxx) writes to the other local channel. */
00244       return 0;
00245    }
00246 
00247    /* get the tech pvt */
00248    if (!(p = ast_channel_tech_pvt(ast))) {
00249       return -1;
00250    }
00251    ao2_ref(p, 1);
00252    ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */
00253 
00254    /* get the channel we are supposed to write to */
00255    ao2_lock(p);
00256    otherchan = (write_info->chan == p->owner) ? p->chan : p->owner;
00257    if (!otherchan || otherchan == write_info->chan) {
00258       res = -1;
00259       otherchan = NULL;
00260       ao2_unlock(p);
00261       goto setoption_cleanup;
00262    }
00263    ast_channel_ref(otherchan);
00264 
00265    /* clear the pvt lock before grabbing the channel */
00266    ao2_unlock(p);
00267 
00268    ast_channel_lock(otherchan);
00269    res = write_info->write_fn(otherchan, write_info->function, write_info->data, write_info->value);
00270    ast_channel_unlock(otherchan);
00271 
00272 setoption_cleanup:
00273    if (p) {
00274       ao2_ref(p, -1);
00275    }
00276    if (otherchan) {
00277       ast_channel_unref(otherchan);
00278    }
00279    ast_channel_lock(ast); /* Lock back before we leave */
00280    return res;
00281 }
00282 
00283 /*! \brief Adds devicestate to local channels */
00284 static int local_devicestate(const char *data)
00285 {
00286    char *exten = ast_strdupa(data);
00287    char *context = NULL, *opts = NULL;
00288    int res;
00289    struct local_pvt *lp;
00290    struct ao2_iterator it;
00291 
00292    if (!(context = strchr(exten, '@'))) {
00293       ast_log(LOG_WARNING, "Someone used Local/%s somewhere without a @context. This is bad.\n", exten);
00294       return AST_DEVICE_INVALID;
00295    }
00296 
00297    *context++ = '\0';
00298 
00299    /* Strip options if they exist */
00300    if ((opts = strchr(context, '/')))
00301       *opts = '\0';
00302 
00303    ast_debug(3, "Checking if extension %s@%s exists (devicestate)\n", exten, context);
00304 
00305    res = ast_exists_extension(NULL, context, exten, 1, NULL);
00306    if (!res)
00307       return AST_DEVICE_INVALID;
00308 
00309    res = AST_DEVICE_NOT_INUSE;
00310 
00311    it = ao2_iterator_init(locals, 0);
00312    for (; (lp = ao2_iterator_next(&it)); ao2_ref(lp, -1)) {
00313       int is_inuse;
00314 
00315       ao2_lock(lp);
00316       is_inuse = !strcmp(exten, lp->exten)
00317          && !strcmp(context, lp->context)
00318          && lp->owner
00319          && ast_test_flag(lp, LOCAL_LAUNCHED_PBX);
00320       ao2_unlock(lp);
00321       if (is_inuse) {
00322          res = AST_DEVICE_INUSE;
00323          ao2_ref(lp, -1);
00324          break;
00325       }
00326    }
00327    ao2_iterator_destroy(&it);
00328 
00329    return res;
00330 }
00331 
00332 /*! \brief Return the bridged channel of a Local channel */
00333 static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge)
00334 {
00335    struct local_pvt *p = ast_channel_tech_pvt(bridge);
00336    struct ast_channel *bridged = bridge;
00337 
00338    if (!p) {
00339       ast_debug(1, "Asked for bridged channel on '%s'/'%s', returning <none>\n",
00340          ast_channel_name(chan), ast_channel_name(bridge));
00341       return NULL;
00342    }
00343 
00344    ao2_lock(p);
00345 
00346    if (ast_test_flag(p, LOCAL_BRIDGE)) {
00347       /* Find the opposite channel */
00348       bridged = (bridge == p->owner ? p->chan : p->owner);
00349 
00350       /* Now see if the opposite channel is bridged to anything */
00351       if (!bridged) {
00352          bridged = bridge;
00353       } else if (ast_channel_internal_bridged_channel(bridged)) {
00354          bridged = ast_channel_internal_bridged_channel(bridged);
00355       }
00356    }
00357 
00358    ao2_unlock(p);
00359 
00360    return bridged;
00361 }
00362 
00363 /* Called with ast locked */
00364 static int local_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
00365 {
00366    struct local_pvt *p;
00367    struct ast_channel *bridged = NULL;
00368    struct ast_channel *tmp = NULL;
00369    int res = 0;
00370 
00371    if (option != AST_OPTION_T38_STATE) {
00372       /* AST_OPTION_T38_STATE is the only supported option at this time */
00373       return -1;
00374    }
00375 
00376    /* for some reason the channel is not locked in channel.c when this function is called */
00377    if (!(p = ast_channel_tech_pvt(ast))) {
00378       return -1;
00379    }
00380 
00381    ao2_lock(p);
00382    if (!(tmp = IS_OUTBOUND(ast, p) ? p->owner : p->chan)) {
00383       ao2_unlock(p);
00384       return -1;
00385    }
00386    ast_channel_ref(tmp);
00387    ao2_unlock(p);
00388    ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */
00389 
00390    ast_channel_lock(tmp);
00391    if (!(bridged = ast_bridged_channel(tmp))) {
00392       res = -1;
00393       ast_channel_unlock(tmp);
00394       goto query_cleanup;
00395    }
00396    ast_channel_ref(bridged);
00397    ast_channel_unlock(tmp);
00398 
00399 query_cleanup:
00400    if (bridged) {
00401       res = ast_channel_queryoption(bridged, option, data, datalen, 0);
00402       bridged = ast_channel_unref(bridged);
00403    }
00404    if (tmp) {
00405       tmp = ast_channel_unref(tmp);
00406    }
00407    ast_channel_lock(ast); /* Lock back before we leave */
00408 
00409    return res;
00410 }
00411 
00412 /*! \brief queue a frame on a to either the p->owner or p->chan
00413  *
00414  * \note the local_pvt MUST have it's ref count bumped before entering this function and
00415  * decremented after this function is called.  This is a side effect of the deadlock
00416  * avoidance that is necessary to lock 2 channels and a tech_pvt.  Without a ref counted
00417  * local_pvt, it is impossible to guarantee it will not be destroyed by another thread
00418  * during deadlock avoidance.
00419  */
00420 static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f,
00421    struct ast_channel *us, int us_locked)
00422 {
00423    struct ast_channel *other = NULL;
00424 
00425    /* Recalculate outbound channel */
00426    other = isoutbound ? p->owner : p->chan;
00427 
00428    if (!other) {
00429       return 0;
00430    }
00431 
00432    /* do not queue frame if generator is on both local channels */
00433    if (us && ast_channel_generator(us) && ast_channel_generator(other)) {
00434       return 0;
00435    }
00436 
00437    /* grab a ref on the channel before unlocking the pvt,
00438     * other can not go away from us now regardless of locking */
00439    ast_channel_ref(other);
00440    if (us && us_locked) {
00441       ast_channel_unlock(us);
00442    }
00443    ao2_unlock(p);
00444 
00445    if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_RINGING) {
00446       ast_setstate(other, AST_STATE_RINGING);
00447    }
00448    ast_queue_frame(other, f);
00449 
00450    other = ast_channel_unref(other);
00451    if (us && us_locked) {
00452       ast_channel_lock(us);
00453    }
00454    ao2_lock(p);
00455 
00456    return 0;
00457 }
00458 
00459 static int local_answer(struct ast_channel *ast)
00460 {
00461    struct local_pvt *p = ast_channel_tech_pvt(ast);
00462    int isoutbound;
00463    int res = -1;
00464 
00465    if (!p) {
00466       return -1;
00467    }
00468 
00469    ao2_lock(p);
00470    ao2_ref(p, 1);
00471    isoutbound = IS_OUTBOUND(ast, p);
00472    if (isoutbound) {
00473       /* Pass along answer since somebody answered us */
00474       struct ast_frame answer = { AST_FRAME_CONTROL, { AST_CONTROL_ANSWER } };
00475       res = local_queue_frame(p, isoutbound, &answer, ast, 1);
00476    } else {
00477       ast_log(LOG_WARNING, "Huh?  Local is being asked to answer?\n");
00478    }
00479    ao2_unlock(p);
00480    ao2_ref(p, -1);
00481    return res;
00482 }
00483 
00484 /*!
00485  * \internal
00486  * \note This function assumes that we're only called from the "outbound" local channel side
00487  *
00488  * \note it is assummed p is locked and reffed before entering this function
00489  */
00490 static void check_bridge(struct ast_channel *ast, struct local_pvt *p)
00491 {
00492    struct ast_channel *owner;
00493    struct ast_channel *chan;
00494    struct ast_channel *bridged_chan;
00495    struct ast_frame *f;
00496 
00497    /* Do a few conditional checks early on just to see if this optimization is possible */
00498    if (ast_test_flag(p, LOCAL_NO_OPTIMIZATION | LOCAL_ALREADY_MASQED)
00499       || !p->chan || !p->owner) {
00500       return;
00501    }
00502 
00503    /* Safely get the channel bridged to p->chan */
00504    chan = ast_channel_ref(p->chan);
00505 
00506    ao2_unlock(p); /* don't call bridged channel with the pvt locked */
00507    bridged_chan = ast_bridged_channel(chan);
00508    ao2_lock(p);
00509 
00510    chan = ast_channel_unref(chan);
00511 
00512    /* since we had to unlock p to get the bridged chan, validate our
00513     * data once again and verify the bridged channel is what we expect
00514     * it to be in order to perform this optimization */
00515    if (ast_test_flag(p, LOCAL_NO_OPTIMIZATION | LOCAL_ALREADY_MASQED)
00516       || !p->chan || !p->owner
00517       || (ast_channel_internal_bridged_channel(p->chan) != bridged_chan)) {
00518       return;
00519    }
00520 
00521    /* only do the masquerade if we are being called on the outbound channel,
00522       if it has been bridged to another channel and if there are no pending
00523       frames on the owner channel (because they would be transferred to the
00524       outbound channel during the masquerade)
00525    */
00526    if (!ast_channel_internal_bridged_channel(p->chan) /* Not ast_bridged_channel!  Only go one step! */
00527       || !AST_LIST_EMPTY(ast_channel_readq(p->owner))
00528       || ast != p->chan /* Sanity check (should always be false) */) {
00529       return;
00530    }
00531 
00532    /* Masquerade bridged channel into owner */
00533    /* Lock everything we need, one by one, and give up if
00534       we can't get everything.  Remember, we'll get another
00535       chance in just a little bit */
00536    if (ast_channel_trylock(ast_channel_internal_bridged_channel(p->chan))) {
00537       return;
00538    }
00539    if (ast_check_hangup(ast_channel_internal_bridged_channel(p->chan))
00540       || ast_channel_trylock(p->owner)) {
00541       ast_channel_unlock(ast_channel_internal_bridged_channel(p->chan));
00542       return;
00543    }
00544 
00545    /*
00546     * At this point we have 4 locks:
00547     * p, p->chan (same as ast), p->chan->_bridge, p->owner
00548     *
00549     * Flush a voice or video frame on the outbound channel to make
00550     * the queue empty faster so we can get optimized out.
00551     */
00552    f = AST_LIST_FIRST(ast_channel_readq(p->chan));
00553    if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)) {
00554       AST_LIST_REMOVE_HEAD(ast_channel_readq(p->chan), frame_list);
00555       ast_frfree(f);
00556       f = AST_LIST_FIRST(ast_channel_readq(p->chan));
00557    }
00558 
00559    if (f
00560       || ast_check_hangup(p->owner)
00561       || ast_channel_masquerade(p->owner, ast_channel_internal_bridged_channel(p->chan))) {
00562       ast_channel_unlock(p->owner);
00563       ast_channel_unlock(ast_channel_internal_bridged_channel(p->chan));
00564       return;
00565    }
00566 
00567    /* Masquerade got setup. */
00568    ast_debug(4, "Masquerading %s <- %s\n",
00569       ast_channel_name(p->owner),
00570       ast_channel_name(ast_channel_internal_bridged_channel(p->chan)));
00571    if (ast_channel_monitor(p->owner)
00572       && !ast_channel_monitor(ast_channel_internal_bridged_channel(p->chan))) {
00573       struct ast_channel_monitor *tmp;
00574 
00575       /* If a local channel is being monitored, we don't want a masquerade
00576        * to cause the monitor to go away. Since the masquerade swaps the monitors,
00577        * pre-swapping the monitors before the masquerade will ensure that the monitor
00578        * ends up where it is expected.
00579        */
00580       tmp = ast_channel_monitor(p->owner);
00581       ast_channel_monitor_set(p->owner, ast_channel_monitor(ast_channel_internal_bridged_channel(p->chan)));
00582       ast_channel_monitor_set(ast_channel_internal_bridged_channel(p->chan), tmp);
00583    }
00584    if (ast_channel_audiohooks(p->chan)) {
00585       struct ast_audiohook_list *audiohooks_swapper;
00586 
00587       audiohooks_swapper = ast_channel_audiohooks(p->chan);
00588       ast_channel_audiohooks_set(p->chan, ast_channel_audiohooks(p->owner));
00589       ast_channel_audiohooks_set(p->owner, audiohooks_swapper);
00590    }
00591 
00592    /* If any Caller ID was set, preserve it after masquerade like above. We must check
00593     * to see if Caller ID was set because otherwise we'll mistakingly copy info not
00594     * set from the dialplan and will overwrite the real channel Caller ID. The reason
00595     * for this whole preswapping action is because the Caller ID is set on the channel
00596     * thread (which is the to be masqueraded away local channel) before both local
00597     * channels are optimized away.
00598     */
00599    if (ast_channel_caller(p->owner)->id.name.valid || ast_channel_caller(p->owner)->id.number.valid
00600       || ast_channel_caller(p->owner)->id.subaddress.valid || ast_channel_caller(p->owner)->ani.name.valid
00601       || ast_channel_caller(p->owner)->ani.number.valid || ast_channel_caller(p->owner)->ani.subaddress.valid) {
00602       SWAP(*ast_channel_caller(p->owner), *ast_channel_caller(ast_channel_internal_bridged_channel(p->chan)));
00603    }
00604    if (ast_channel_redirecting(p->owner)->from.name.valid || ast_channel_redirecting(p->owner)->from.number.valid
00605       || ast_channel_redirecting(p->owner)->from.subaddress.valid || ast_channel_redirecting(p->owner)->to.name.valid
00606       || ast_channel_redirecting(p->owner)->to.number.valid || ast_channel_redirecting(p->owner)->to.subaddress.valid) {
00607       SWAP(*ast_channel_redirecting(p->owner), *ast_channel_redirecting(ast_channel_internal_bridged_channel(p->chan)));
00608    }
00609    if (ast_channel_dialed(p->owner)->number.str || ast_channel_dialed(p->owner)->subaddress.valid) {
00610       SWAP(*ast_channel_dialed(p->owner), *ast_channel_dialed(ast_channel_internal_bridged_channel(p->chan)));
00611    }
00612    ast_app_group_update(p->chan, p->owner);
00613    ast_set_flag(p, LOCAL_ALREADY_MASQED);
00614 
00615    ast_channel_unlock(p->owner);
00616    ast_channel_unlock(ast_channel_internal_bridged_channel(p->chan));
00617 
00618    /* Do the masquerade now. */
00619    owner = ast_channel_ref(p->owner);
00620    ao2_unlock(p);
00621    ast_channel_unlock(ast);
00622    ast_do_masquerade(owner);
00623    ast_channel_unref(owner);
00624    ast_channel_lock(ast);
00625    ao2_lock(p);
00626 }
00627 
00628 static struct ast_frame  *local_read(struct ast_channel *ast)
00629 {
00630    return &ast_null_frame;
00631 }
00632 
00633 static int local_write(struct ast_channel *ast, struct ast_frame *f)
00634 {
00635    struct local_pvt *p = ast_channel_tech_pvt(ast);
00636    int res = -1;
00637    int isoutbound;
00638 
00639    if (!p) {
00640       return -1;
00641    }
00642 
00643    /* Just queue for delivery to the other side */
00644    ao2_ref(p, 1); /* ref for local_queue_frame */
00645    ao2_lock(p);
00646    isoutbound = IS_OUTBOUND(ast, p);
00647 
00648    if (isoutbound
00649       && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)) {
00650       check_bridge(ast, p);
00651    }
00652 
00653    if (!ast_test_flag(p, LOCAL_ALREADY_MASQED)) {
00654       res = local_queue_frame(p, isoutbound, f, ast, 1);
00655    } else {
00656       ast_debug(1, "Not posting to '%s' queue since already masqueraded out\n",
00657          ast_channel_name(ast));
00658       res = 0;
00659    }
00660    ao2_unlock(p);
00661    ao2_ref(p, -1);
00662 
00663    return res;
00664 }
00665 
00666 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
00667 {
00668    struct local_pvt *p = ast_channel_tech_pvt(newchan);
00669 
00670    if (!p) {
00671       return -1;
00672    }
00673 
00674    ao2_lock(p);
00675 
00676    if ((p->owner != oldchan) && (p->chan != oldchan)) {
00677       ast_log(LOG_WARNING, "Old channel %p wasn't %p or %p\n", oldchan, p->owner, p->chan);
00678       ao2_unlock(p);
00679       return -1;
00680    }
00681    if (p->owner == oldchan) {
00682       p->owner = newchan;
00683    } else {
00684       p->chan = newchan;
00685    }
00686 
00687    /* Do not let a masquerade cause a Local channel to be bridged to itself! */
00688    if (!ast_check_hangup(newchan) && ((p->owner && ast_channel_internal_bridged_channel(p->owner) == p->chan) || (p->chan && ast_channel_internal_bridged_channel(p->chan) == p->owner))) {
00689       ast_log(LOG_WARNING, "You can not bridge a Local channel to itself!\n");
00690       ao2_unlock(p);
00691       ast_queue_hangup(newchan);
00692       return -1;
00693    }
00694 
00695    ao2_unlock(p);
00696    return 0;
00697 }
00698 
00699 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
00700 {
00701    struct local_pvt *p = ast_channel_tech_pvt(ast);
00702    int res = 0;
00703    struct ast_frame f = { AST_FRAME_CONTROL, };
00704    int isoutbound;
00705 
00706    if (!p) {
00707       return -1;
00708    }
00709 
00710    ao2_ref(p, 1); /* ref for local_queue_frame */
00711 
00712    /* If this is an MOH hold or unhold, do it on the Local channel versus real channel */
00713    if (!ast_test_flag(p, LOCAL_MOH_PASSTHRU) && condition == AST_CONTROL_HOLD) {
00714       ast_moh_start(ast, data, NULL);
00715    } else if (!ast_test_flag(p, LOCAL_MOH_PASSTHRU) && condition == AST_CONTROL_UNHOLD) {
00716       ast_moh_stop(ast);
00717    } else if (condition == AST_CONTROL_CONNECTED_LINE || condition == AST_CONTROL_REDIRECTING) {
00718       struct ast_channel *this_channel;
00719       struct ast_channel *the_other_channel;
00720       /* A connected line update frame may only contain a partial amount of data, such
00721        * as just a source, or just a ton, and not the full amount of information. However,
00722        * the collected information is all stored in the outgoing channel's connectedline
00723        * structure, so when receiving a connected line update on an outgoing local channel,
00724        * we need to transmit the collected connected line information instead of whatever
00725        * happens to be in this control frame. The same applies for redirecting information, which
00726        * is why it is handled here as well.*/
00727       ao2_lock(p);
00728       isoutbound = IS_OUTBOUND(ast, p);
00729       if (isoutbound) {
00730          this_channel = p->chan;
00731          the_other_channel = p->owner;
00732       } else {
00733          this_channel = p->owner;
00734          the_other_channel = p->chan;
00735       }
00736       if (the_other_channel) {
00737          unsigned char frame_data[1024];
00738          if (condition == AST_CONTROL_CONNECTED_LINE) {
00739             if (isoutbound) {
00740                ast_connected_line_copy_to_caller(ast_channel_caller(the_other_channel), ast_channel_connected(this_channel));
00741             }
00742             f.datalen = ast_connected_line_build_data(frame_data, sizeof(frame_data), ast_channel_connected(this_channel), NULL);
00743          } else {
00744             f.datalen = ast_redirecting_build_data(frame_data, sizeof(frame_data), ast_channel_redirecting(this_channel), NULL);
00745          }
00746          f.subclass.integer = condition;
00747          f.data.ptr = frame_data;
00748          res = local_queue_frame(p, isoutbound, &f, ast, 1);
00749       }
00750       ao2_unlock(p);
00751    } else {
00752       /* Queue up a frame representing the indication as a control frame */
00753       ao2_lock(p);
00754       /*
00755        * Block -1 stop tones events if we are to be optimized out.  We
00756        * don't need a flurry of these events on a local channel chain
00757        * when initially connected to slow the optimization process.
00758        */
00759       if (0 <= condition || ast_test_flag(p, LOCAL_NO_OPTIMIZATION)) {
00760          isoutbound = IS_OUTBOUND(ast, p);
00761          f.subclass.integer = condition;
00762          f.data.ptr = (void *) data;
00763          f.datalen = datalen;
00764          res = local_queue_frame(p, isoutbound, &f, ast, 1);
00765 
00766          if (!res && (condition == AST_CONTROL_T38_PARAMETERS) &&
00767              (datalen == sizeof(struct ast_control_t38_parameters))) {
00768             const struct ast_control_t38_parameters *parameters = data;
00769             
00770             if (parameters->request_response == AST_T38_REQUEST_PARMS) {
00771                res = AST_T38_REQUEST_PARMS;
00772             }
00773          }
00774       } else {
00775          ast_debug(4, "Blocked indication %d\n", condition);
00776       }
00777       ao2_unlock(p);
00778    }
00779 
00780    ao2_ref(p, -1);
00781    return res;
00782 }
00783 
00784 static int local_digit_begin(struct ast_channel *ast, char digit)
00785 {
00786    struct local_pvt *p = ast_channel_tech_pvt(ast);
00787    int res = -1;
00788    struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
00789    int isoutbound;
00790 
00791    if (!p) {
00792       return -1;
00793    }
00794 
00795    ao2_ref(p, 1); /* ref for local_queue_frame */
00796    ao2_lock(p);
00797    isoutbound = IS_OUTBOUND(ast, p);
00798    f.subclass.integer = digit;
00799    res = local_queue_frame(p, isoutbound, &f, ast, 0);
00800    ao2_unlock(p);
00801    ao2_ref(p, -1);
00802 
00803    return res;
00804 }
00805 
00806 static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
00807 {
00808    struct local_pvt *p = ast_channel_tech_pvt(ast);
00809    int res = -1;
00810    struct ast_frame f = { AST_FRAME_DTMF_END, };
00811    int isoutbound;
00812 
00813    if (!p) {
00814       return -1;
00815    }
00816 
00817    ao2_ref(p, 1); /* ref for local_queue_frame */
00818    ao2_lock(p);
00819    isoutbound = IS_OUTBOUND(ast, p);
00820    f.subclass.integer = digit;
00821    f.len = duration;
00822    res = local_queue_frame(p, isoutbound, &f, ast, 0);
00823    ao2_unlock(p);
00824    ao2_ref(p, -1);
00825 
00826    return res;
00827 }
00828 
00829 static int local_sendtext(struct ast_channel *ast, const char *text)
00830 {
00831    struct local_pvt *p = ast_channel_tech_pvt(ast);
00832    int res = -1;
00833    struct ast_frame f = { AST_FRAME_TEXT, };
00834    int isoutbound;
00835 
00836    if (!p) {
00837       return -1;
00838    }
00839 
00840    ao2_lock(p);
00841    ao2_ref(p, 1); /* ref for local_queue_frame */
00842    isoutbound = IS_OUTBOUND(ast, p);
00843    f.data.ptr = (char *) text;
00844    f.datalen = strlen(text) + 1;
00845    res = local_queue_frame(p, isoutbound, &f, ast, 0);
00846    ao2_unlock(p);
00847    ao2_ref(p, -1);
00848    return res;
00849 }
00850 
00851 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
00852 {
00853    struct local_pvt *p = ast_channel_tech_pvt(ast);
00854    int res = -1;
00855    struct ast_frame f = { AST_FRAME_HTML, };
00856    int isoutbound;
00857 
00858    if (!p) {
00859       return -1;
00860    }
00861 
00862    ao2_lock(p);
00863    ao2_ref(p, 1); /* ref for local_queue_frame */
00864    isoutbound = IS_OUTBOUND(ast, p);
00865    f.subclass.integer = subclass;
00866    f.data.ptr = (char *)data;
00867    f.datalen = datalen;
00868    res = local_queue_frame(p, isoutbound, &f, ast, 0);
00869    ao2_unlock(p);
00870    ao2_ref(p, -1);
00871 
00872    return res;
00873 }
00874 
00875 /*! \brief Initiate new call, part of PBX interface
00876  *         dest is the dial string */
00877 static int local_call(struct ast_channel *ast, const char *dest, int timeout)
00878 {
00879    struct local_pvt *p = ast_channel_tech_pvt(ast);
00880    int pvt_locked = 0;
00881 
00882    struct ast_channel *owner = NULL;
00883    struct ast_channel *chan = NULL;
00884    int res;
00885    struct ast_var_t *varptr;
00886    struct ast_var_t *clone_var;
00887    char *reduced_dest = ast_strdupa(dest);
00888    char *slash;
00889    const char *exten;
00890    const char *context;
00891 
00892    if (!p) {
00893       return -1;
00894    }
00895 
00896    /* since we are letting go of channel locks that were locked coming into
00897     * this function, then we need to give the tech pvt a ref */
00898    ao2_ref(p, 1);
00899    ast_channel_unlock(ast);
00900 
00901    awesome_locking(p, &chan, &owner);
00902    pvt_locked = 1;
00903 
00904    if (owner != ast) {
00905       res = -1;
00906       goto return_cleanup;
00907    }
00908 
00909    if (!owner || !chan) {
00910       res = -1;
00911       goto return_cleanup;
00912    }
00913 
00914    /*
00915     * Note that cid_num and cid_name aren't passed in the ast_channel_alloc
00916     * call, so it's done here instead.
00917     *
00918     * All these failure points just return -1. The individual strings will
00919     * be cleared when we destroy the channel.
00920     */
00921    ast_party_redirecting_copy(ast_channel_redirecting(chan), ast_channel_redirecting(owner));
00922 
00923    ast_party_dialed_copy(ast_channel_dialed(chan), ast_channel_dialed(owner));
00924 
00925    ast_connected_line_copy_to_caller(ast_channel_caller(chan), ast_channel_connected(owner));
00926    ast_connected_line_copy_from_caller(ast_channel_connected(chan), ast_channel_caller(owner));
00927 
00928    ast_channel_language_set(chan, ast_channel_language(owner));
00929    ast_channel_accountcode_set(chan, ast_channel_accountcode(owner));
00930    ast_channel_musicclass_set(chan, ast_channel_musicclass(owner));
00931    ast_cdr_update(chan);
00932 
00933    ast_channel_cc_params_init(chan, ast_channel_get_cc_config_params(owner));
00934 
00935    /* Make sure we inherit the AST_CAUSE_ANSWERED_ELSEWHERE if it's set on the queue/dial call request in the dialplan */
00936    if (ast_channel_hangupcause(ast) == AST_CAUSE_ANSWERED_ELSEWHERE) {
00937       ast_channel_hangupcause_set(chan, AST_CAUSE_ANSWERED_ELSEWHERE);
00938    }
00939 
00940    /* copy the channel variables from the incoming channel to the outgoing channel */
00941    /* Note that due to certain assumptions, they MUST be in the same order */
00942    AST_LIST_TRAVERSE(ast_channel_varshead(owner), varptr, entries) {
00943       clone_var = ast_var_assign(varptr->name, varptr->value);
00944       if (clone_var) {
00945          AST_LIST_INSERT_TAIL(ast_channel_varshead(chan), clone_var, entries);
00946       }
00947    }
00948    ast_channel_datastore_inherit(owner, chan);
00949    /* If the local channel has /n or /b on the end of it,
00950     * we need to lop that off for our argument to setting
00951     * up the CC_INTERFACES variable
00952     */
00953    if ((slash = strrchr(reduced_dest, '/'))) {
00954       *slash = '\0';
00955    }
00956    ast_set_cc_interfaces_chanvar(chan, reduced_dest);
00957 
00958    exten = ast_strdupa(ast_channel_exten(chan));
00959    context = ast_strdupa(ast_channel_context(chan));
00960 
00961    ao2_unlock(p);
00962    pvt_locked = 0;
00963 
00964    ast_channel_unlock(chan);
00965 
00966    if (!ast_exists_extension(chan, context, exten, 1,
00967       S_COR(ast_channel_caller(owner)->id.number.valid, ast_channel_caller(owner)->id.number.str, NULL))) {
00968       ast_log(LOG_NOTICE, "No such extension/context %s@%s while calling Local channel\n", exten, context);
00969       res = -1;
00970       chan = ast_channel_unref(chan); /* we already unlocked it, so clear it hear so the cleanup label won't touch it. */
00971       goto return_cleanup;
00972    }
00973 
00974    /*** DOCUMENTATION
00975       <managerEventInstance>
00976          <synopsis>Raised when two halves of a Local Channel form a bridge.</synopsis>
00977          <syntax>
00978             <parameter name="Channel1">
00979                <para>The name of the Local Channel half that bridges to another channel.</para>
00980             </parameter>
00981             <parameter name="Channel2">
00982                <para>The name of the Local Channel half that executes the dialplan.</para>
00983             </parameter>
00984             <parameter name="Context">
00985                <para>The context in the dialplan that Channel2 starts in.</para>
00986             </parameter>
00987             <parameter name="Exten">
00988                <para>The extension in the dialplan that Channel2 starts in.</para>
00989             </parameter>
00990             <parameter name="LocalOptimization">
00991                <enumlist>
00992                   <enum name="Yes"/>
00993                   <enum name="No"/>
00994                </enumlist>
00995             </parameter>
00996          </syntax>
00997       </managerEventInstance>
00998    ***/
00999    manager_event(EVENT_FLAG_CALL, "LocalBridge",
01000             "Channel1: %s\r\n"
01001             "Channel2: %s\r\n"
01002             "Uniqueid1: %s\r\n"
01003             "Uniqueid2: %s\r\n"
01004             "Context: %s\r\n"
01005             "Exten: %s\r\n"
01006             "LocalOptimization: %s\r\n",
01007          ast_channel_name(p->owner), ast_channel_name(p->chan), ast_channel_uniqueid(p->owner), ast_channel_uniqueid(p->chan),
01008          p->context, p->exten,
01009          ast_test_flag(p, LOCAL_NO_OPTIMIZATION) ? "No" : "Yes");
01010 
01011 
01012    /* Start switch on sub channel */
01013    if (!(res = ast_pbx_start(chan))) {
01014       ao2_lock(p);
01015       ast_set_flag(p, LOCAL_LAUNCHED_PBX);
01016       ao2_unlock(p);
01017    }
01018    chan = ast_channel_unref(chan); /* chan is already unlocked, clear it here so the cleanup lable won't touch it. */
01019 
01020 return_cleanup:
01021    if (p) {
01022       if (pvt_locked) {
01023          ao2_unlock(p);
01024       }
01025       ao2_ref(p, -1);
01026    }
01027    if (chan) {
01028       ast_channel_unlock(chan);
01029       chan = ast_channel_unref(chan);
01030    }
01031 
01032    /* owner is supposed to be == to ast,  if it
01033     * is, don't unlock it because ast must exit locked */
01034    if (owner) {
01035       if (owner != ast) {
01036          ast_channel_unlock(owner);
01037          ast_channel_lock(ast);
01038       }
01039       owner = ast_channel_unref(owner);
01040    } else {
01041       /* we have to exit with ast locked */
01042       ast_channel_lock(ast);
01043    }
01044 
01045    return res;
01046 }
01047 
01048 /*! \brief Hangup a call through the local proxy channel */
01049 static int local_hangup(struct ast_channel *ast)
01050 {
01051    struct local_pvt *p = ast_channel_tech_pvt(ast);
01052    int isoutbound;
01053    int hangup_chan = 0;
01054    int res = 0;
01055    struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = ast_channel_hangupcause(ast) };
01056    struct ast_channel *owner = NULL;
01057    struct ast_channel *chan = NULL;
01058 
01059    if (!p) {
01060       return -1;
01061    }
01062 
01063    /* give the pvt a ref since we are unlocking the channel. */
01064    ao2_ref(p, 1);
01065 
01066    /* the pvt isn't going anywhere, we gave it a ref */
01067    ast_channel_unlock(ast);
01068 
01069    /* lock everything */
01070    awesome_locking(p, &chan, &owner);
01071 
01072    if (ast != chan && ast != owner) {
01073       res = -1;
01074       goto local_hangup_cleanup;
01075    }
01076 
01077    isoutbound = IS_OUTBOUND(ast, p); /* just comparing pointer of ast */
01078 
01079    if (p->chan && ast_channel_hangupcause(ast) == AST_CAUSE_ANSWERED_ELSEWHERE) {
01080       ast_channel_hangupcause_set(p->chan, AST_CAUSE_ANSWERED_ELSEWHERE);
01081       ast_debug(2, "This local call has AST_CAUSE_ANSWERED_ELSEWHERE set.\n");
01082    }
01083 
01084    if (isoutbound) {
01085       const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
01086 
01087       if (status && p->owner) {
01088          ast_channel_hangupcause_set(p->owner, ast_channel_hangupcause(p->chan));
01089          pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
01090       }
01091 
01092       ast_clear_flag(p, LOCAL_LAUNCHED_PBX);
01093       p->chan = NULL;
01094    } else {
01095       if (p->chan) {
01096          ast_queue_hangup(p->chan);
01097       }
01098       p->owner = NULL;
01099    }
01100 
01101    ast_channel_tech_pvt_set(ast, NULL); /* this is one of our locked channels, doesn't matter which */
01102 
01103    if (!p->owner && !p->chan) {
01104       ao2_unlock(p);
01105 
01106       /* Remove from list */
01107       ao2_unlink(locals, p);
01108       ao2_ref(p, -1);
01109       p = NULL;
01110       res = 0;
01111       goto local_hangup_cleanup;
01112    }
01113    if (p->chan && !ast_test_flag(p, LOCAL_LAUNCHED_PBX)) {
01114       /* Need to actually hangup since there is no PBX */
01115       hangup_chan = 1;
01116    } else {
01117       local_queue_frame(p, isoutbound, &f, NULL, 0);
01118    }
01119 
01120 local_hangup_cleanup:
01121    if (p) {
01122       ao2_unlock(p);
01123       ao2_ref(p, -1);
01124    }
01125    if (owner) {
01126       ast_channel_unlock(owner);
01127       owner = ast_channel_unref(owner);
01128    }
01129    if (chan) {
01130       ast_channel_unlock(chan);
01131       if (hangup_chan) {
01132          ast_hangup(chan);
01133       }
01134       chan = ast_channel_unref(chan);
01135    }
01136 
01137    /* leave with the same stupid channel locked that came in */
01138    ast_channel_lock(ast);
01139    return res;
01140 }
01141 
01142 /*!
01143  * \internal
01144  * \brief struct local_pvt destructor.
01145  *
01146  * \param vdoomed Void local_pvt to destroy.
01147  *
01148  * \return Nothing
01149  */
01150 static void local_pvt_destructor(void *vdoomed)
01151 {
01152    struct local_pvt *doomed = vdoomed;
01153 
01154    doomed->reqcap = ast_format_cap_destroy(doomed->reqcap);
01155 
01156    ast_module_unref(ast_module_info->self);
01157 }
01158 
01159 /*! \brief Create a call structure */
01160 static struct local_pvt *local_alloc(const char *data, struct ast_format_cap *cap)
01161 {
01162    struct local_pvt *tmp = NULL;
01163    char *c = NULL, *opts = NULL;
01164 
01165    if (!(tmp = ao2_alloc(sizeof(*tmp), local_pvt_destructor))) {
01166       return NULL;
01167    }
01168    if (!(tmp->reqcap = ast_format_cap_dup(cap))) {
01169       ao2_ref(tmp, -1);
01170       return NULL;
01171    }
01172 
01173    ast_module_ref(ast_module_info->self);
01174 
01175    /* Initialize private structure information */
01176    ast_copy_string(tmp->exten, data, sizeof(tmp->exten));
01177 
01178    memcpy(&tmp->jb_conf, &g_jb_conf, sizeof(tmp->jb_conf));
01179 
01180    /* Look for options */
01181    if ((opts = strchr(tmp->exten, '/'))) {
01182       *opts++ = '\0';
01183       if (strchr(opts, 'n'))
01184          ast_set_flag(tmp, LOCAL_NO_OPTIMIZATION);
01185       if (strchr(opts, 'j')) {
01186          if (ast_test_flag(tmp, LOCAL_NO_OPTIMIZATION))
01187             ast_set_flag(&tmp->jb_conf, AST_JB_ENABLED);
01188          else {
01189             ast_log(LOG_ERROR, "You must use the 'n' option for chan_local "
01190                "to use the 'j' option to enable the jitterbuffer\n");
01191          }
01192       }
01193       if (strchr(opts, 'b')) {
01194          ast_set_flag(tmp, LOCAL_BRIDGE);
01195       }
01196       if (strchr(opts, 'm')) {
01197          ast_set_flag(tmp, LOCAL_MOH_PASSTHRU);
01198       }
01199    }
01200 
01201    /* Look for a context */
01202    if ((c = strchr(tmp->exten, '@')))
01203       *c++ = '\0';
01204 
01205    ast_copy_string(tmp->context, c ? c : "default", sizeof(tmp->context));
01206 #if 0
01207    /* We can't do this check here, because we don't know the CallerID yet, and
01208     * the CallerID could potentially affect what step is actually taken (or
01209     * even if that step exists). */
01210    if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) {
01211       ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->exten, tmp->context);
01212       tmp = local_pvt_destroy(tmp);
01213    } else {
01214 #endif
01215       /* Add to list */
01216       ao2_link(locals, tmp);
01217 #if 0
01218    }
01219 #endif
01220    return tmp; /* this is returned with a ref */
01221 }
01222 
01223 /*! \brief Start new local channel */
01224 static struct ast_channel *local_new(struct local_pvt *p, int state, const char *linkedid, struct ast_callid *callid)
01225 {
01226    struct ast_channel *tmp = NULL, *tmp2 = NULL;
01227    struct ast_format fmt;
01228    int generated_seqno = ast_atomic_fetchadd_int((int *)&name_sequence, +1);
01229    const char *t;
01230    int ama;
01231 
01232    /* Allocate two new Asterisk channels */
01233    /* safe accountcode */
01234    if (p->owner && ast_channel_accountcode(p->owner))
01235       t = ast_channel_accountcode(p->owner);
01236    else
01237       t = "";
01238 
01239    if (p->owner)
01240       ama = ast_channel_amaflags(p->owner);
01241    else
01242       ama = 0;
01243 
01244    /* Make sure that the ;2 channel gets the same linkedid as ;1. You can't pass linkedid to both
01245     * allocations since if linkedid isn't set, then each channel will generate its own linkedid. */
01246    if (!(tmp = ast_channel_alloc(1, state, 0, 0, t, p->exten, p->context, linkedid, ama, "Local/%s@%s-%08x;1", p->exten, p->context, generated_seqno))
01247       || !(tmp2 = ast_channel_alloc(1, AST_STATE_RING, 0, 0, t, p->exten, p->context, ast_channel_linkedid(tmp), ama, "Local/%s@%s-%08x;2", p->exten, p->context, generated_seqno))) {
01248       if (tmp) {
01249          tmp = ast_channel_release(tmp);
01250       }
01251       ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
01252       return NULL;
01253    }
01254 
01255    if (callid) {
01256       ast_channel_callid_set(tmp, callid);
01257       ast_channel_callid_set(tmp2, callid);
01258    }
01259 
01260    ast_channel_tech_set(tmp, &local_tech);
01261    ast_channel_tech_set(tmp2, &local_tech);
01262 
01263    ast_format_cap_copy(ast_channel_nativeformats(tmp), p->reqcap);
01264    ast_format_cap_copy(ast_channel_nativeformats(tmp2), p->reqcap);
01265 
01266    /* Determine our read/write format and set it on each channel */
01267    ast_best_codec(p->reqcap, &fmt);
01268    ast_format_copy(ast_channel_writeformat(tmp), &fmt);
01269    ast_format_copy(ast_channel_writeformat(tmp2), &fmt);
01270    ast_format_copy(ast_channel_rawwriteformat(tmp), &fmt);
01271    ast_format_copy(ast_channel_rawwriteformat(tmp2), &fmt);
01272    ast_format_copy(ast_channel_readformat(tmp), &fmt);
01273    ast_format_copy(ast_channel_readformat(tmp2), &fmt);
01274    ast_format_copy(ast_channel_rawreadformat(tmp), &fmt);
01275    ast_format_copy(ast_channel_rawreadformat(tmp2), &fmt);
01276 
01277    ast_channel_tech_pvt_set(tmp, p);
01278    ast_channel_tech_pvt_set(tmp2, p);
01279 
01280    ast_set_flag(ast_channel_flags(tmp), AST_FLAG_DISABLE_DEVSTATE_CACHE);
01281    ast_set_flag(ast_channel_flags(tmp2), AST_FLAG_DISABLE_DEVSTATE_CACHE);
01282 
01283    p->owner = tmp;
01284    p->chan = tmp2;
01285 
01286    ast_channel_context_set(tmp, p->context);
01287    ast_channel_context_set(tmp2, p->context);
01288    ast_channel_exten_set(tmp2, p->exten);
01289    ast_channel_priority_set(tmp, 1);
01290    ast_channel_priority_set(tmp2, 1);
01291 
01292    ast_jb_configure(tmp, &p->jb_conf);
01293 
01294    return tmp;
01295 }
01296 
01297 /*! \brief Part of PBX interface */
01298 static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
01299 {
01300    struct local_pvt *p;
01301    struct ast_channel *chan;
01302    struct ast_callid *callid = ast_read_threadstorage_callid();
01303 
01304    /* Allocate a new private structure and then Asterisk channel */
01305    p = local_alloc(data, cap);
01306    if (!p) {
01307       chan = NULL;
01308       goto local_request_end;
01309    }
01310    chan = local_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL, callid);
01311    if (!chan) {
01312       ao2_unlink(locals, p);
01313    } else if (ast_channel_cc_params_init(chan, requestor ? ast_channel_get_cc_config_params((struct ast_channel *)requestor) : NULL)) {
01314       ao2_unlink(locals, p);
01315       p->owner = ast_channel_release(p->owner);
01316       p->chan = ast_channel_release(p->chan);
01317       chan = NULL;
01318    }
01319    ao2_ref(p, -1); /* kill the ref from the alloc */
01320 
01321 local_request_end:
01322 
01323    if (callid) {
01324       ast_callid_unref(callid);
01325    }
01326 
01327    return chan;
01328 }
01329 
01330 /*! \brief CLI command "local show channels" */
01331 static char *locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
01332 {
01333    struct local_pvt *p = NULL;
01334    struct ao2_iterator it;
01335 
01336    switch (cmd) {
01337    case CLI_INIT:
01338       e->command = "local show channels";
01339       e->usage =
01340          "Usage: local show channels\n"
01341          "       Provides summary information on active local proxy channels.\n";
01342       return NULL;
01343    case CLI_GENERATE:
01344       return NULL;
01345    }
01346 
01347    if (a->argc != 3) {
01348       return CLI_SHOWUSAGE;
01349    }
01350 
01351    if (ao2_container_count(locals) == 0) {
01352       ast_cli(a->fd, "No local channels in use\n");
01353       return RESULT_SUCCESS;
01354    }
01355 
01356    it = ao2_iterator_init(locals, 0);
01357    while ((p = ao2_iterator_next(&it))) {
01358       ao2_lock(p);
01359       ast_cli(a->fd, "%s -- %s@%s\n", p->owner ? ast_channel_name(p->owner) : "<unowned>", p->exten, p->context);
01360       ao2_unlock(p);
01361       ao2_ref(p, -1);
01362    }
01363    ao2_iterator_destroy(&it);
01364 
01365    return CLI_SUCCESS;
01366 }
01367 
01368 static struct ast_cli_entry cli_local[] = {
01369    AST_CLI_DEFINE(locals_show, "List status of local channels"),
01370 };
01371 
01372 static int manager_optimize_away(struct mansession *s, const struct message *m)
01373 {
01374    const char *channel;
01375    struct local_pvt *p, *tmp = NULL;
01376    struct ast_channel *c;
01377    int found = 0;
01378    struct ao2_iterator it;
01379 
01380    channel = astman_get_header(m, "Channel");
01381 
01382    if (ast_strlen_zero(channel)) {
01383       astman_send_error(s, m, "'Channel' not specified.");
01384       return 0;
01385    }
01386 
01387    c = ast_channel_get_by_name(channel);
01388    if (!c) {
01389       astman_send_error(s, m, "Channel does not exist.");
01390       return 0;
01391    }
01392 
01393    p = ast_channel_tech_pvt(c);
01394    ast_channel_unref(c);
01395    c = NULL;
01396 
01397    it = ao2_iterator_init(locals, 0);
01398    while ((tmp = ao2_iterator_next(&it))) {
01399       if (tmp == p) {
01400          ao2_lock(tmp);
01401          found = 1;
01402          ast_clear_flag(tmp, LOCAL_NO_OPTIMIZATION);
01403          ao2_unlock(tmp);
01404          ao2_ref(tmp, -1);
01405          break;
01406       }
01407       ao2_ref(tmp, -1);
01408    }
01409    ao2_iterator_destroy(&it);
01410 
01411    if (found) {
01412       astman_send_ack(s, m, "Queued channel to be optimized away");
01413    } else {
01414       astman_send_error(s, m, "Unable to find channel");
01415    }
01416 
01417    return 0;
01418 }
01419 
01420 
01421 static int locals_cmp_cb(void *obj, void *arg, int flags)
01422 {
01423    return (obj == arg) ? CMP_MATCH : 0;
01424 }
01425 
01426 /*! \brief Load module into PBX, register channel */
01427 static int load_module(void)
01428 {
01429    if (!(local_tech.capabilities = ast_format_cap_alloc())) {
01430       return AST_MODULE_LOAD_FAILURE;
01431    }
01432    ast_format_cap_add_all(local_tech.capabilities);
01433 
01434    if (!(locals = ao2_container_alloc(BUCKET_SIZE, NULL, locals_cmp_cb))) {
01435       ast_format_cap_destroy(local_tech.capabilities);
01436       return AST_MODULE_LOAD_FAILURE;
01437    }
01438 
01439    /* Make sure we can register our channel type */
01440    if (ast_channel_register(&local_tech)) {
01441       ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
01442       ao2_ref(locals, -1);
01443       ast_format_cap_destroy(local_tech.capabilities);
01444       return AST_MODULE_LOAD_FAILURE;
01445    }
01446    ast_cli_register_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
01447    ast_manager_register_xml("LocalOptimizeAway", EVENT_FLAG_SYSTEM|EVENT_FLAG_CALL, manager_optimize_away);
01448 
01449    return AST_MODULE_LOAD_SUCCESS;
01450 }
01451 
01452 /*! \brief Unload the local proxy channel from Asterisk */
01453 static int unload_module(void)
01454 {
01455    struct local_pvt *p = NULL;
01456    struct ao2_iterator it;
01457 
01458    /* First, take us out of the channel loop */
01459    ast_cli_unregister_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
01460    ast_manager_unregister("LocalOptimizeAway");
01461    ast_channel_unregister(&local_tech);
01462 
01463    it = ao2_iterator_init(locals, 0);
01464    while ((p = ao2_iterator_next(&it))) {
01465       if (p->owner) {
01466          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
01467       }
01468       ao2_ref(p, -1);
01469    }
01470    ao2_iterator_destroy(&it);
01471    ao2_ref(locals, -1);
01472 
01473    ast_format_cap_destroy(local_tech.capabilities);
01474    return 0;
01475 }
01476 
01477 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Local Proxy Channel (Note: used internally by other modules)",
01478       .load = load_module,
01479       .unload = unload_module,
01480       .load_pri = AST_MODPRI_CHANNEL_DRIVER,
01481    );