Sat Jul 12 2014 17:18: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 /*** MODULEINFO
00029    <support_level>core</support_level>
00030  ***/
00031 
00032 #include "asterisk.h"
00033 
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 414270 $")
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 media frames if a generator is on both local channels */
00433    if (us
00434       && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)
00435       && ast_channel_generator(us)
00436       && ast_channel_generator(other)) {
00437       return 0;
00438    }
00439 
00440    /* grab a ref on the channel before unlocking the pvt,
00441     * other can not go away from us now regardless of locking */
00442    ast_channel_ref(other);
00443    if (us && us_locked) {
00444       ast_channel_unlock(us);
00445    }
00446    ao2_unlock(p);
00447 
00448    if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_RINGING) {
00449       ast_setstate(other, AST_STATE_RINGING);
00450    }
00451    ast_queue_frame(other, f);
00452 
00453    other = ast_channel_unref(other);
00454    if (us && us_locked) {
00455       ast_channel_lock(us);
00456    }
00457    ao2_lock(p);
00458 
00459    return 0;
00460 }
00461 
00462 static int local_answer(struct ast_channel *ast)
00463 {
00464    struct local_pvt *p = ast_channel_tech_pvt(ast);
00465    int isoutbound;
00466    int res = -1;
00467 
00468    if (!p) {
00469       return -1;
00470    }
00471 
00472    ao2_lock(p);
00473    ao2_ref(p, 1);
00474    isoutbound = IS_OUTBOUND(ast, p);
00475    if (isoutbound) {
00476       /* Pass along answer since somebody answered us */
00477       struct ast_frame answer = { AST_FRAME_CONTROL, { AST_CONTROL_ANSWER } };
00478       res = local_queue_frame(p, isoutbound, &answer, ast, 1);
00479    } else {
00480       ast_log(LOG_WARNING, "Huh?  Local is being asked to answer?\n");
00481    }
00482    ao2_unlock(p);
00483    ao2_ref(p, -1);
00484    return res;
00485 }
00486 
00487 /*!
00488  * \internal
00489  * \note This function assumes that we're only called from the "outbound" local channel side
00490  *
00491  * \note it is assummed p is locked and reffed before entering this function
00492  */
00493 static void check_bridge(struct ast_channel *ast, struct local_pvt *p)
00494 {
00495    struct ast_channel *owner;
00496    struct ast_channel *chan;
00497    struct ast_channel *bridged_chan;
00498    struct ast_frame *f;
00499 
00500    /* Do a few conditional checks early on just to see if this optimization is possible */
00501    if (ast_test_flag(p, LOCAL_NO_OPTIMIZATION | LOCAL_ALREADY_MASQED)
00502       || !p->chan || !p->owner) {
00503       return;
00504    }
00505 
00506    /* Safely get the channel bridged to p->chan */
00507    chan = ast_channel_ref(p->chan);
00508 
00509    ao2_unlock(p); /* don't call bridged channel with the pvt locked */
00510    bridged_chan = ast_bridged_channel(chan);
00511    ao2_lock(p);
00512 
00513    chan = ast_channel_unref(chan);
00514 
00515    /* since we had to unlock p to get the bridged chan, validate our
00516     * data once again and verify the bridged channel is what we expect
00517     * it to be in order to perform this optimization */
00518    if (ast_test_flag(p, LOCAL_NO_OPTIMIZATION | LOCAL_ALREADY_MASQED)
00519       || !p->chan || !p->owner
00520       || (ast_channel_internal_bridged_channel(p->chan) != bridged_chan)) {
00521       return;
00522    }
00523 
00524    /* only do the masquerade if we are being called on the outbound channel,
00525       if it has been bridged to another channel and if there are no pending
00526       frames on the owner channel (because they would be transferred to the
00527       outbound channel during the masquerade)
00528    */
00529    if (!ast_channel_internal_bridged_channel(p->chan) /* Not ast_bridged_channel!  Only go one step! */
00530       || !AST_LIST_EMPTY(ast_channel_readq(p->owner))
00531       || ast != p->chan /* Sanity check (should always be false) */) {
00532       return;
00533    }
00534 
00535    /* Masquerade bridged channel into owner */
00536    /* Lock everything we need, one by one, and give up if
00537       we can't get everything.  Remember, we'll get another
00538       chance in just a little bit */
00539    if (ast_channel_trylock(ast_channel_internal_bridged_channel(p->chan))) {
00540       return;
00541    }
00542    if (ast_check_hangup(ast_channel_internal_bridged_channel(p->chan))
00543       || ast_channel_trylock(p->owner)) {
00544       ast_channel_unlock(ast_channel_internal_bridged_channel(p->chan));
00545       return;
00546    }
00547 
00548    /*
00549     * At this point we have 4 locks:
00550     * p, p->chan (same as ast), p->chan->_bridge, p->owner
00551     *
00552     * Flush a voice or video frame on the outbound channel to make
00553     * the queue empty faster so we can get optimized out.
00554     */
00555    f = AST_LIST_FIRST(ast_channel_readq(p->chan));
00556    if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)) {
00557       AST_LIST_REMOVE_HEAD(ast_channel_readq(p->chan), frame_list);
00558       ast_frfree(f);
00559       f = AST_LIST_FIRST(ast_channel_readq(p->chan));
00560    }
00561 
00562    if (f
00563       || ast_check_hangup(p->owner)
00564       || ast_channel_masquerade(p->owner, ast_channel_internal_bridged_channel(p->chan))) {
00565       ast_channel_unlock(p->owner);
00566       ast_channel_unlock(ast_channel_internal_bridged_channel(p->chan));
00567       return;
00568    }
00569 
00570    /* Masquerade got setup. */
00571    ast_debug(4, "Masquerading %s <- %s\n",
00572       ast_channel_name(p->owner),
00573       ast_channel_name(ast_channel_internal_bridged_channel(p->chan)));
00574    if (ast_channel_monitor(p->owner)
00575       && !ast_channel_monitor(ast_channel_internal_bridged_channel(p->chan))) {
00576       struct ast_channel_monitor *tmp;
00577 
00578       /* If a local channel is being monitored, we don't want a masquerade
00579        * to cause the monitor to go away. Since the masquerade swaps the monitors,
00580        * pre-swapping the monitors before the masquerade will ensure that the monitor
00581        * ends up where it is expected.
00582        */
00583       tmp = ast_channel_monitor(p->owner);
00584       ast_channel_monitor_set(p->owner, ast_channel_monitor(ast_channel_internal_bridged_channel(p->chan)));
00585       ast_channel_monitor_set(ast_channel_internal_bridged_channel(p->chan), tmp);
00586    }
00587    if (ast_channel_audiohooks(p->chan)) {
00588       struct ast_audiohook_list *audiohooks_swapper;
00589 
00590       audiohooks_swapper = ast_channel_audiohooks(p->chan);
00591       ast_channel_audiohooks_set(p->chan, ast_channel_audiohooks(p->owner));
00592       ast_channel_audiohooks_set(p->owner, audiohooks_swapper);
00593    }
00594 
00595    /* If any Caller ID was set, preserve it after masquerade like above. We must check
00596     * to see if Caller ID was set because otherwise we'll mistakingly copy info not
00597     * set from the dialplan and will overwrite the real channel Caller ID. The reason
00598     * for this whole preswapping action is because the Caller ID is set on the channel
00599     * thread (which is the to be masqueraded away local channel) before both local
00600     * channels are optimized away.
00601     */
00602    if (ast_channel_caller(p->owner)->id.name.valid || ast_channel_caller(p->owner)->id.number.valid
00603       || ast_channel_caller(p->owner)->id.subaddress.valid || ast_channel_caller(p->owner)->ani.name.valid
00604       || ast_channel_caller(p->owner)->ani.number.valid || ast_channel_caller(p->owner)->ani.subaddress.valid) {
00605       SWAP(*ast_channel_caller(p->owner), *ast_channel_caller(ast_channel_internal_bridged_channel(p->chan)));
00606    }
00607    if (ast_channel_redirecting(p->owner)->from.name.valid || ast_channel_redirecting(p->owner)->from.number.valid
00608       || ast_channel_redirecting(p->owner)->from.subaddress.valid || ast_channel_redirecting(p->owner)->to.name.valid
00609       || ast_channel_redirecting(p->owner)->to.number.valid || ast_channel_redirecting(p->owner)->to.subaddress.valid) {
00610       SWAP(*ast_channel_redirecting(p->owner), *ast_channel_redirecting(ast_channel_internal_bridged_channel(p->chan)));
00611    }
00612    if (ast_channel_dialed(p->owner)->number.str || ast_channel_dialed(p->owner)->subaddress.valid) {
00613       SWAP(*ast_channel_dialed(p->owner), *ast_channel_dialed(ast_channel_internal_bridged_channel(p->chan)));
00614    }
00615    ast_app_group_update(p->chan, p->owner);
00616    ast_set_flag(p, LOCAL_ALREADY_MASQED);
00617 
00618    ast_channel_unlock(p->owner);
00619    ast_channel_unlock(ast_channel_internal_bridged_channel(p->chan));
00620 
00621    /* Do the masquerade now. */
00622    owner = ast_channel_ref(p->owner);
00623    ao2_unlock(p);
00624    ast_channel_unlock(ast);
00625    ast_do_masquerade(owner);
00626    ast_channel_unref(owner);
00627    ast_channel_lock(ast);
00628    ao2_lock(p);
00629 }
00630 
00631 static struct ast_frame  *local_read(struct ast_channel *ast)
00632 {
00633    return &ast_null_frame;
00634 }
00635 
00636 static int local_write(struct ast_channel *ast, struct ast_frame *f)
00637 {
00638    struct local_pvt *p = ast_channel_tech_pvt(ast);
00639    int res = -1;
00640    int isoutbound;
00641 
00642    if (!p) {
00643       return -1;
00644    }
00645 
00646    /* Just queue for delivery to the other side */
00647    ao2_ref(p, 1); /* ref for local_queue_frame */
00648    ao2_lock(p);
00649    isoutbound = IS_OUTBOUND(ast, p);
00650 
00651    if (isoutbound
00652       && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)) {
00653       check_bridge(ast, p);
00654    }
00655 
00656    if (!ast_test_flag(p, LOCAL_ALREADY_MASQED)) {
00657       res = local_queue_frame(p, isoutbound, f, ast, 1);
00658    } else {
00659       ast_debug(1, "Not posting to '%s' queue since already masqueraded out\n",
00660          ast_channel_name(ast));
00661       res = 0;
00662    }
00663    ao2_unlock(p);
00664    ao2_ref(p, -1);
00665 
00666    return res;
00667 }
00668 
00669 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
00670 {
00671    struct local_pvt *p = ast_channel_tech_pvt(newchan);
00672 
00673    if (!p) {
00674       return -1;
00675    }
00676 
00677    ao2_lock(p);
00678 
00679    if ((p->owner != oldchan) && (p->chan != oldchan)) {
00680       ast_log(LOG_WARNING, "Old channel %p wasn't %p or %p\n", oldchan, p->owner, p->chan);
00681       ao2_unlock(p);
00682       return -1;
00683    }
00684    if (p->owner == oldchan) {
00685       p->owner = newchan;
00686    } else {
00687       p->chan = newchan;
00688    }
00689 
00690    /* Do not let a masquerade cause a Local channel to be bridged to itself! */
00691    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))) {
00692       ast_log(LOG_WARNING, "You can not bridge a Local channel to itself!\n");
00693       ao2_unlock(p);
00694       ast_queue_hangup(newchan);
00695       return -1;
00696    }
00697 
00698    ao2_unlock(p);
00699    return 0;
00700 }
00701 
00702 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
00703 {
00704    struct local_pvt *p = ast_channel_tech_pvt(ast);
00705    int res = 0;
00706    struct ast_frame f = { AST_FRAME_CONTROL, };
00707    int isoutbound;
00708 
00709    if (!p) {
00710       return -1;
00711    }
00712 
00713    ao2_ref(p, 1); /* ref for local_queue_frame */
00714 
00715    /* If this is an MOH hold or unhold, do it on the Local channel versus real channel */
00716    if (!ast_test_flag(p, LOCAL_MOH_PASSTHRU) && condition == AST_CONTROL_HOLD) {
00717       ast_moh_start(ast, data, NULL);
00718    } else if (!ast_test_flag(p, LOCAL_MOH_PASSTHRU) && condition == AST_CONTROL_UNHOLD) {
00719       ast_moh_stop(ast);
00720    } else if (condition == AST_CONTROL_CONNECTED_LINE || condition == AST_CONTROL_REDIRECTING) {
00721       struct ast_channel *this_channel;
00722       struct ast_channel *the_other_channel;
00723       /* A connected line update frame may only contain a partial amount of data, such
00724        * as just a source, or just a ton, and not the full amount of information. However,
00725        * the collected information is all stored in the outgoing channel's connectedline
00726        * structure, so when receiving a connected line update on an outgoing local channel,
00727        * we need to transmit the collected connected line information instead of whatever
00728        * happens to be in this control frame. The same applies for redirecting information, which
00729        * is why it is handled here as well.*/
00730       ao2_lock(p);
00731       isoutbound = IS_OUTBOUND(ast, p);
00732       if (isoutbound) {
00733          this_channel = p->chan;
00734          the_other_channel = p->owner;
00735       } else {
00736          this_channel = p->owner;
00737          the_other_channel = p->chan;
00738       }
00739       if (the_other_channel) {
00740          unsigned char frame_data[1024];
00741          if (condition == AST_CONTROL_CONNECTED_LINE) {
00742             if (isoutbound) {
00743                ast_connected_line_copy_to_caller(ast_channel_caller(the_other_channel), ast_channel_connected(this_channel));
00744             }
00745             f.datalen = ast_connected_line_build_data(frame_data, sizeof(frame_data), ast_channel_connected(this_channel), NULL);
00746          } else {
00747             f.datalen = ast_redirecting_build_data(frame_data, sizeof(frame_data), ast_channel_redirecting(this_channel), NULL);
00748          }
00749          f.subclass.integer = condition;
00750          f.data.ptr = frame_data;
00751          res = local_queue_frame(p, isoutbound, &f, ast, 1);
00752       }
00753       ao2_unlock(p);
00754    } else {
00755       /* Queue up a frame representing the indication as a control frame */
00756       ao2_lock(p);
00757       /*
00758        * Block -1 stop tones events if we are to be optimized out.  We
00759        * don't need a flurry of these events on a local channel chain
00760        * when initially connected to slow the optimization process.
00761        */
00762       if (0 <= condition || ast_test_flag(p, LOCAL_NO_OPTIMIZATION)) {
00763          isoutbound = IS_OUTBOUND(ast, p);
00764          f.subclass.integer = condition;
00765          f.data.ptr = (void *) data;
00766          f.datalen = datalen;
00767          res = local_queue_frame(p, isoutbound, &f, ast, 1);
00768 
00769          if (!res && (condition == AST_CONTROL_T38_PARAMETERS) &&
00770              (datalen == sizeof(struct ast_control_t38_parameters))) {
00771             const struct ast_control_t38_parameters *parameters = data;
00772             
00773             if (parameters->request_response == AST_T38_REQUEST_PARMS) {
00774                res = AST_T38_REQUEST_PARMS;
00775             }
00776          }
00777       } else {
00778          ast_debug(4, "Blocked indication %d\n", condition);
00779       }
00780       ao2_unlock(p);
00781    }
00782 
00783    ao2_ref(p, -1);
00784    return res;
00785 }
00786 
00787 static int local_digit_begin(struct ast_channel *ast, char digit)
00788 {
00789    struct local_pvt *p = ast_channel_tech_pvt(ast);
00790    int res = -1;
00791    struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
00792    int isoutbound;
00793 
00794    if (!p) {
00795       return -1;
00796    }
00797 
00798    ao2_ref(p, 1); /* ref for local_queue_frame */
00799    ao2_lock(p);
00800    isoutbound = IS_OUTBOUND(ast, p);
00801    f.subclass.integer = digit;
00802    res = local_queue_frame(p, isoutbound, &f, ast, 0);
00803    ao2_unlock(p);
00804    ao2_ref(p, -1);
00805 
00806    return res;
00807 }
00808 
00809 static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
00810 {
00811    struct local_pvt *p = ast_channel_tech_pvt(ast);
00812    int res = -1;
00813    struct ast_frame f = { AST_FRAME_DTMF_END, };
00814    int isoutbound;
00815 
00816    if (!p) {
00817       return -1;
00818    }
00819 
00820    ao2_ref(p, 1); /* ref for local_queue_frame */
00821    ao2_lock(p);
00822    isoutbound = IS_OUTBOUND(ast, p);
00823    f.subclass.integer = digit;
00824    f.len = duration;
00825    res = local_queue_frame(p, isoutbound, &f, ast, 0);
00826    ao2_unlock(p);
00827    ao2_ref(p, -1);
00828 
00829    return res;
00830 }
00831 
00832 static int local_sendtext(struct ast_channel *ast, const char *text)
00833 {
00834    struct local_pvt *p = ast_channel_tech_pvt(ast);
00835    int res = -1;
00836    struct ast_frame f = { AST_FRAME_TEXT, };
00837    int isoutbound;
00838 
00839    if (!p) {
00840       return -1;
00841    }
00842 
00843    ao2_lock(p);
00844    ao2_ref(p, 1); /* ref for local_queue_frame */
00845    isoutbound = IS_OUTBOUND(ast, p);
00846    f.data.ptr = (char *) text;
00847    f.datalen = strlen(text) + 1;
00848    res = local_queue_frame(p, isoutbound, &f, ast, 0);
00849    ao2_unlock(p);
00850    ao2_ref(p, -1);
00851    return res;
00852 }
00853 
00854 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
00855 {
00856    struct local_pvt *p = ast_channel_tech_pvt(ast);
00857    int res = -1;
00858    struct ast_frame f = { AST_FRAME_HTML, };
00859    int isoutbound;
00860 
00861    if (!p) {
00862       return -1;
00863    }
00864 
00865    ao2_lock(p);
00866    ao2_ref(p, 1); /* ref for local_queue_frame */
00867    isoutbound = IS_OUTBOUND(ast, p);
00868    f.subclass.integer = subclass;
00869    f.data.ptr = (char *)data;
00870    f.datalen = datalen;
00871    res = local_queue_frame(p, isoutbound, &f, ast, 0);
00872    ao2_unlock(p);
00873    ao2_ref(p, -1);
00874 
00875    return res;
00876 }
00877 
00878 /*! \brief Initiate new call, part of PBX interface
00879  *         dest is the dial string */
00880 static int local_call(struct ast_channel *ast, const char *dest, int timeout)
00881 {
00882    struct local_pvt *p = ast_channel_tech_pvt(ast);
00883    int pvt_locked = 0;
00884 
00885    struct ast_channel *owner = NULL;
00886    struct ast_channel *chan = NULL;
00887    int res;
00888    struct ast_var_t *varptr;
00889    struct ast_var_t *clone_var;
00890    char *reduced_dest = ast_strdupa(dest);
00891    char *slash;
00892    const char *exten;
00893    const char *context;
00894 
00895    if (!p) {
00896       return -1;
00897    }
00898 
00899    /* since we are letting go of channel locks that were locked coming into
00900     * this function, then we need to give the tech pvt a ref */
00901    ao2_ref(p, 1);
00902    ast_channel_unlock(ast);
00903 
00904    awesome_locking(p, &chan, &owner);
00905    pvt_locked = 1;
00906 
00907    if (owner != ast) {
00908       res = -1;
00909       goto return_cleanup;
00910    }
00911 
00912    if (!owner || !chan) {
00913       res = -1;
00914       goto return_cleanup;
00915    }
00916 
00917    /*
00918     * Note that cid_num and cid_name aren't passed in the ast_channel_alloc
00919     * call, so it's done here instead.
00920     *
00921     * All these failure points just return -1. The individual strings will
00922     * be cleared when we destroy the channel.
00923     */
00924    ast_party_redirecting_copy(ast_channel_redirecting(chan), ast_channel_redirecting(owner));
00925 
00926    ast_party_dialed_copy(ast_channel_dialed(chan), ast_channel_dialed(owner));
00927 
00928    ast_connected_line_copy_to_caller(ast_channel_caller(chan), ast_channel_connected(owner));
00929    ast_connected_line_copy_from_caller(ast_channel_connected(chan), ast_channel_caller(owner));
00930 
00931    ast_channel_language_set(chan, ast_channel_language(owner));
00932    ast_channel_accountcode_set(chan, ast_channel_accountcode(owner));
00933    ast_channel_musicclass_set(chan, ast_channel_musicclass(owner));
00934    ast_cdr_update(chan);
00935 
00936    ast_channel_cc_params_init(chan, ast_channel_get_cc_config_params(owner));
00937 
00938    /* Make sure we inherit the AST_CAUSE_ANSWERED_ELSEWHERE if it's set on the queue/dial call request in the dialplan */
00939    if (ast_channel_hangupcause(ast) == AST_CAUSE_ANSWERED_ELSEWHERE) {
00940       ast_channel_hangupcause_set(chan, AST_CAUSE_ANSWERED_ELSEWHERE);
00941    }
00942 
00943    /* copy the channel variables from the incoming channel to the outgoing channel */
00944    /* Note that due to certain assumptions, they MUST be in the same order */
00945    AST_LIST_TRAVERSE(ast_channel_varshead(owner), varptr, entries) {
00946       clone_var = ast_var_assign(varptr->name, varptr->value);
00947       if (clone_var) {
00948          AST_LIST_INSERT_TAIL(ast_channel_varshead(chan), clone_var, entries);
00949       }
00950    }
00951    ast_channel_datastore_inherit(owner, chan);
00952    /* If the local channel has /n or /b on the end of it,
00953     * we need to lop that off for our argument to setting
00954     * up the CC_INTERFACES variable
00955     */
00956    if ((slash = strrchr(reduced_dest, '/'))) {
00957       *slash = '\0';
00958    }
00959    ast_set_cc_interfaces_chanvar(chan, reduced_dest);
00960 
00961    exten = ast_strdupa(ast_channel_exten(chan));
00962    context = ast_strdupa(ast_channel_context(chan));
00963 
00964    ao2_unlock(p);
00965    pvt_locked = 0;
00966 
00967    ast_channel_unlock(chan);
00968 
00969    if (!ast_exists_extension(chan, context, exten, 1,
00970       S_COR(ast_channel_caller(owner)->id.number.valid, ast_channel_caller(owner)->id.number.str, NULL))) {
00971       ast_log(LOG_NOTICE, "No such extension/context %s@%s while calling Local channel\n", exten, context);
00972       res = -1;
00973       chan = ast_channel_unref(chan); /* we already unlocked it, so clear it hear so the cleanup label won't touch it. */
00974       goto return_cleanup;
00975    }
00976 
00977    /*** DOCUMENTATION
00978       <managerEventInstance>
00979          <synopsis>Raised when two halves of a Local Channel form a bridge.</synopsis>
00980          <syntax>
00981             <parameter name="Channel1">
00982                <para>The name of the Local Channel half that bridges to another channel.</para>
00983             </parameter>
00984             <parameter name="Channel2">
00985                <para>The name of the Local Channel half that executes the dialplan.</para>
00986             </parameter>
00987             <parameter name="Context">
00988                <para>The context in the dialplan that Channel2 starts in.</para>
00989             </parameter>
00990             <parameter name="Exten">
00991                <para>The extension in the dialplan that Channel2 starts in.</para>
00992             </parameter>
00993             <parameter name="LocalOptimization">
00994                <enumlist>
00995                   <enum name="Yes"/>
00996                   <enum name="No"/>
00997                </enumlist>
00998             </parameter>
00999          </syntax>
01000       </managerEventInstance>
01001    ***/
01002    manager_event(EVENT_FLAG_CALL, "LocalBridge",
01003             "Channel1: %s\r\n"
01004             "Channel2: %s\r\n"
01005             "Uniqueid1: %s\r\n"
01006             "Uniqueid2: %s\r\n"
01007             "Context: %s\r\n"
01008             "Exten: %s\r\n"
01009             "LocalOptimization: %s\r\n",
01010          ast_channel_name(p->owner), ast_channel_name(p->chan), ast_channel_uniqueid(p->owner), ast_channel_uniqueid(p->chan),
01011          p->context, p->exten,
01012          ast_test_flag(p, LOCAL_NO_OPTIMIZATION) ? "No" : "Yes");
01013 
01014 
01015    /* Start switch on sub channel */
01016    if (!(res = ast_pbx_start(chan))) {
01017       ao2_lock(p);
01018       ast_set_flag(p, LOCAL_LAUNCHED_PBX);
01019       ao2_unlock(p);
01020    }
01021    chan = ast_channel_unref(chan); /* chan is already unlocked, clear it here so the cleanup lable won't touch it. */
01022 
01023 return_cleanup:
01024    if (p) {
01025       if (pvt_locked) {
01026          ao2_unlock(p);
01027       }
01028       ao2_ref(p, -1);
01029    }
01030    if (chan) {
01031       ast_channel_unlock(chan);
01032       chan = ast_channel_unref(chan);
01033    }
01034 
01035    /* owner is supposed to be == to ast,  if it
01036     * is, don't unlock it because ast must exit locked */
01037    if (owner) {
01038       if (owner != ast) {
01039          ast_channel_unlock(owner);
01040          ast_channel_lock(ast);
01041       }
01042       owner = ast_channel_unref(owner);
01043    } else {
01044       /* we have to exit with ast locked */
01045       ast_channel_lock(ast);
01046    }
01047 
01048    return res;
01049 }
01050 
01051 /*! \brief Hangup a call through the local proxy channel */
01052 static int local_hangup(struct ast_channel *ast)
01053 {
01054    struct local_pvt *p = ast_channel_tech_pvt(ast);
01055    int isoutbound;
01056    int hangup_chan = 0;
01057    int res = 0;
01058    struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = ast_channel_hangupcause(ast) };
01059    struct ast_channel *owner = NULL;
01060    struct ast_channel *chan = NULL;
01061 
01062    if (!p) {
01063       return -1;
01064    }
01065 
01066    /* give the pvt a ref since we are unlocking the channel. */
01067    ao2_ref(p, 1);
01068 
01069    /* the pvt isn't going anywhere, we gave it a ref */
01070    ast_channel_unlock(ast);
01071 
01072    /* lock everything */
01073    awesome_locking(p, &chan, &owner);
01074 
01075    if (ast != chan && ast != owner) {
01076       res = -1;
01077       goto local_hangup_cleanup;
01078    }
01079 
01080    isoutbound = IS_OUTBOUND(ast, p); /* just comparing pointer of ast */
01081 
01082    if (p->chan && ast_channel_hangupcause(ast) == AST_CAUSE_ANSWERED_ELSEWHERE) {
01083       ast_channel_hangupcause_set(p->chan, AST_CAUSE_ANSWERED_ELSEWHERE);
01084       ast_debug(2, "This local call has AST_CAUSE_ANSWERED_ELSEWHERE set.\n");
01085    }
01086 
01087    if (isoutbound) {
01088       const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
01089 
01090       if (status && p->owner) {
01091          ast_channel_hangupcause_set(p->owner, ast_channel_hangupcause(p->chan));
01092          pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
01093       }
01094 
01095       ast_clear_flag(p, LOCAL_LAUNCHED_PBX);
01096       p->chan = NULL;
01097    } else {
01098       if (p->chan) {
01099          ast_queue_hangup(p->chan);
01100       }
01101       p->owner = NULL;
01102    }
01103 
01104    ast_channel_tech_pvt_set(ast, NULL); /* this is one of our locked channels, doesn't matter which */
01105 
01106    if (!p->owner && !p->chan) {
01107       ao2_unlock(p);
01108 
01109       /* Remove from list */
01110       ao2_unlink(locals, p);
01111       ao2_ref(p, -1);
01112       p = NULL;
01113       res = 0;
01114       goto local_hangup_cleanup;
01115    }
01116    if (p->chan && !ast_test_flag(p, LOCAL_LAUNCHED_PBX)) {
01117       /* Need to actually hangup since there is no PBX */
01118       hangup_chan = 1;
01119    } else {
01120       local_queue_frame(p, isoutbound, &f, NULL, 0);
01121    }
01122 
01123 local_hangup_cleanup:
01124    if (p) {
01125       ao2_unlock(p);
01126       ao2_ref(p, -1);
01127    }
01128    if (owner) {
01129       ast_channel_unlock(owner);
01130       owner = ast_channel_unref(owner);
01131    }
01132    if (chan) {
01133       ast_channel_unlock(chan);
01134       if (hangup_chan) {
01135          ast_hangup(chan);
01136       }
01137       chan = ast_channel_unref(chan);
01138    }
01139 
01140    /* leave with the same stupid channel locked that came in */
01141    ast_channel_lock(ast);
01142    return res;
01143 }
01144 
01145 /*!
01146  * \internal
01147  * \brief struct local_pvt destructor.
01148  *
01149  * \param vdoomed Void local_pvt to destroy.
01150  *
01151  * \return Nothing
01152  */
01153 static void local_pvt_destructor(void *vdoomed)
01154 {
01155    struct local_pvt *doomed = vdoomed;
01156 
01157    doomed->reqcap = ast_format_cap_destroy(doomed->reqcap);
01158 
01159    ast_module_unref(ast_module_info->self);
01160 }
01161 
01162 /*! \brief Create a call structure */
01163 static struct local_pvt *local_alloc(const char *data, struct ast_format_cap *cap)
01164 {
01165    struct local_pvt *tmp = NULL;
01166    char *c = NULL, *opts = NULL;
01167 
01168    if (!(tmp = ao2_alloc(sizeof(*tmp), local_pvt_destructor))) {
01169       return NULL;
01170    }
01171    if (!(tmp->reqcap = ast_format_cap_dup(cap))) {
01172       ao2_ref(tmp, -1);
01173       return NULL;
01174    }
01175 
01176    ast_module_ref(ast_module_info->self);
01177 
01178    /* Initialize private structure information */
01179    ast_copy_string(tmp->exten, data, sizeof(tmp->exten));
01180 
01181    memcpy(&tmp->jb_conf, &g_jb_conf, sizeof(tmp->jb_conf));
01182 
01183    /* Look for options */
01184    if ((opts = strchr(tmp->exten, '/'))) {
01185       *opts++ = '\0';
01186       if (strchr(opts, 'n'))
01187          ast_set_flag(tmp, LOCAL_NO_OPTIMIZATION);
01188       if (strchr(opts, 'j')) {
01189          if (ast_test_flag(tmp, LOCAL_NO_OPTIMIZATION))
01190             ast_set_flag(&tmp->jb_conf, AST_JB_ENABLED);
01191          else {
01192             ast_log(LOG_ERROR, "You must use the 'n' option for chan_local "
01193                "to use the 'j' option to enable the jitterbuffer\n");
01194          }
01195       }
01196       if (strchr(opts, 'b')) {
01197          ast_set_flag(tmp, LOCAL_BRIDGE);
01198       }
01199       if (strchr(opts, 'm')) {
01200          ast_set_flag(tmp, LOCAL_MOH_PASSTHRU);
01201       }
01202    }
01203 
01204    /* Look for a context */
01205    if ((c = strchr(tmp->exten, '@')))
01206       *c++ = '\0';
01207 
01208    ast_copy_string(tmp->context, c ? c : "default", sizeof(tmp->context));
01209 #if 0
01210    /* We can't do this check here, because we don't know the CallerID yet, and
01211     * the CallerID could potentially affect what step is actually taken (or
01212     * even if that step exists). */
01213    if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) {
01214       ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->exten, tmp->context);
01215       tmp = local_pvt_destroy(tmp);
01216    } else {
01217 #endif
01218       /* Add to list */
01219       ao2_link(locals, tmp);
01220 #if 0
01221    }
01222 #endif
01223    return tmp; /* this is returned with a ref */
01224 }
01225 
01226 /*! \brief Start new local channel */
01227 static struct ast_channel *local_new(struct local_pvt *p, int state, const char *linkedid, struct ast_callid *callid)
01228 {
01229    struct ast_channel *tmp = NULL, *tmp2 = NULL;
01230    struct ast_format fmt;
01231    int generated_seqno = ast_atomic_fetchadd_int((int *)&name_sequence, +1);
01232    const char *t;
01233    int ama;
01234 
01235    /* Allocate two new Asterisk channels */
01236    /* safe accountcode */
01237    if (p->owner && ast_channel_accountcode(p->owner))
01238       t = ast_channel_accountcode(p->owner);
01239    else
01240       t = "";
01241 
01242    if (p->owner)
01243       ama = ast_channel_amaflags(p->owner);
01244    else
01245       ama = 0;
01246 
01247    /* Make sure that the ;2 channel gets the same linkedid as ;1. You can't pass linkedid to both
01248     * allocations since if linkedid isn't set, then each channel will generate its own linkedid. */
01249    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, (unsigned)generated_seqno))
01250       || !(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, (unsigned)generated_seqno))) {
01251       if (tmp) {
01252          tmp = ast_channel_release(tmp);
01253       }
01254       ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
01255       return NULL;
01256    }
01257 
01258    if (callid) {
01259       ast_channel_callid_set(tmp, callid);
01260       ast_channel_callid_set(tmp2, callid);
01261    }
01262 
01263    ast_channel_tech_set(tmp, &local_tech);
01264    ast_channel_tech_set(tmp2, &local_tech);
01265 
01266    ast_format_cap_copy(ast_channel_nativeformats(tmp), p->reqcap);
01267    ast_format_cap_copy(ast_channel_nativeformats(tmp2), p->reqcap);
01268 
01269    /* Determine our read/write format and set it on each channel */
01270    ast_best_codec(p->reqcap, &fmt);
01271    ast_format_copy(ast_channel_writeformat(tmp), &fmt);
01272    ast_format_copy(ast_channel_writeformat(tmp2), &fmt);
01273    ast_format_copy(ast_channel_rawwriteformat(tmp), &fmt);
01274    ast_format_copy(ast_channel_rawwriteformat(tmp2), &fmt);
01275    ast_format_copy(ast_channel_readformat(tmp), &fmt);
01276    ast_format_copy(ast_channel_readformat(tmp2), &fmt);
01277    ast_format_copy(ast_channel_rawreadformat(tmp), &fmt);
01278    ast_format_copy(ast_channel_rawreadformat(tmp2), &fmt);
01279 
01280    ast_channel_tech_pvt_set(tmp, p);
01281    ast_channel_tech_pvt_set(tmp2, p);
01282 
01283    ast_set_flag(ast_channel_flags(tmp), AST_FLAG_DISABLE_DEVSTATE_CACHE);
01284    ast_set_flag(ast_channel_flags(tmp2), AST_FLAG_DISABLE_DEVSTATE_CACHE);
01285 
01286    p->owner = tmp;
01287    p->chan = tmp2;
01288 
01289    ast_channel_context_set(tmp, p->context);
01290    ast_channel_context_set(tmp2, p->context);
01291    ast_channel_exten_set(tmp2, p->exten);
01292    ast_channel_priority_set(tmp, 1);
01293    ast_channel_priority_set(tmp2, 1);
01294 
01295    ast_jb_configure(tmp, &p->jb_conf);
01296 
01297    return tmp;
01298 }
01299 
01300 /*! \brief Part of PBX interface */
01301 static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
01302 {
01303    struct local_pvt *p;
01304    struct ast_channel *chan;
01305    struct ast_callid *callid = ast_read_threadstorage_callid();
01306 
01307    /* Allocate a new private structure and then Asterisk channel */
01308    p = local_alloc(data, cap);
01309    if (!p) {
01310       chan = NULL;
01311       goto local_request_end;
01312    }
01313    chan = local_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL, callid);
01314    if (!chan) {
01315       ao2_unlink(locals, p);
01316    } else if (ast_channel_cc_params_init(chan, requestor ? ast_channel_get_cc_config_params((struct ast_channel *)requestor) : NULL)) {
01317       ao2_unlink(locals, p);
01318       p->owner = ast_channel_release(p->owner);
01319       p->chan = ast_channel_release(p->chan);
01320       chan = NULL;
01321    }
01322    ao2_ref(p, -1); /* kill the ref from the alloc */
01323 
01324 local_request_end:
01325 
01326    if (callid) {
01327       ast_callid_unref(callid);
01328    }
01329 
01330    return chan;
01331 }
01332 
01333 /*! \brief CLI command "local show channels" */
01334 static char *locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
01335 {
01336    struct local_pvt *p = NULL;
01337    struct ao2_iterator it;
01338 
01339    switch (cmd) {
01340    case CLI_INIT:
01341       e->command = "local show channels";
01342       e->usage =
01343          "Usage: local show channels\n"
01344          "       Provides summary information on active local proxy channels.\n";
01345       return NULL;
01346    case CLI_GENERATE:
01347       return NULL;
01348    }
01349 
01350    if (a->argc != 3) {
01351       return CLI_SHOWUSAGE;
01352    }
01353 
01354    if (ao2_container_count(locals) == 0) {
01355       ast_cli(a->fd, "No local channels in use\n");
01356       return RESULT_SUCCESS;
01357    }
01358 
01359    it = ao2_iterator_init(locals, 0);
01360    while ((p = ao2_iterator_next(&it))) {
01361       ao2_lock(p);
01362       ast_cli(a->fd, "%s -- %s@%s\n", p->owner ? ast_channel_name(p->owner) : "<unowned>", p->exten, p->context);
01363       ao2_unlock(p);
01364       ao2_ref(p, -1);
01365    }
01366    ao2_iterator_destroy(&it);
01367 
01368    return CLI_SUCCESS;
01369 }
01370 
01371 static struct ast_cli_entry cli_local[] = {
01372    AST_CLI_DEFINE(locals_show, "List status of local channels"),
01373 };
01374 
01375 static int manager_optimize_away(struct mansession *s, const struct message *m)
01376 {
01377    const char *channel;
01378    struct local_pvt *p, *tmp = NULL;
01379    struct ast_channel *c;
01380    int found = 0;
01381    struct ao2_iterator it;
01382 
01383    channel = astman_get_header(m, "Channel");
01384 
01385    if (ast_strlen_zero(channel)) {
01386       astman_send_error(s, m, "'Channel' not specified.");
01387       return 0;
01388    }
01389 
01390    c = ast_channel_get_by_name(channel);
01391    if (!c) {
01392       astman_send_error(s, m, "Channel does not exist.");
01393       return 0;
01394    }
01395 
01396    p = ast_channel_tech_pvt(c);
01397    ast_channel_unref(c);
01398    c = NULL;
01399 
01400    it = ao2_iterator_init(locals, 0);
01401    while ((tmp = ao2_iterator_next(&it))) {
01402       if (tmp == p) {
01403          ao2_lock(tmp);
01404          found = 1;
01405          ast_clear_flag(tmp, LOCAL_NO_OPTIMIZATION);
01406          ao2_unlock(tmp);
01407          ao2_ref(tmp, -1);
01408          break;
01409       }
01410       ao2_ref(tmp, -1);
01411    }
01412    ao2_iterator_destroy(&it);
01413 
01414    if (found) {
01415       astman_send_ack(s, m, "Queued channel to be optimized away");
01416    } else {
01417       astman_send_error(s, m, "Unable to find channel");
01418    }
01419 
01420    return 0;
01421 }
01422 
01423 
01424 static int locals_cmp_cb(void *obj, void *arg, int flags)
01425 {
01426    return (obj == arg) ? CMP_MATCH : 0;
01427 }
01428 
01429 /*! \brief Load module into PBX, register channel */
01430 static int load_module(void)
01431 {
01432    if (!(local_tech.capabilities = ast_format_cap_alloc())) {
01433       return AST_MODULE_LOAD_FAILURE;
01434    }
01435    ast_format_cap_add_all(local_tech.capabilities);
01436 
01437    if (!(locals = ao2_container_alloc(BUCKET_SIZE, NULL, locals_cmp_cb))) {
01438       ast_format_cap_destroy(local_tech.capabilities);
01439       return AST_MODULE_LOAD_FAILURE;
01440    }
01441 
01442    /* Make sure we can register our channel type */
01443    if (ast_channel_register(&local_tech)) {
01444       ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
01445       ao2_ref(locals, -1);
01446       ast_format_cap_destroy(local_tech.capabilities);
01447       return AST_MODULE_LOAD_FAILURE;
01448    }
01449    ast_cli_register_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
01450    ast_manager_register_xml("LocalOptimizeAway", EVENT_FLAG_SYSTEM|EVENT_FLAG_CALL, manager_optimize_away);
01451 
01452    return AST_MODULE_LOAD_SUCCESS;
01453 }
01454 
01455 /*! \brief Unload the local proxy channel from Asterisk */
01456 static int unload_module(void)
01457 {
01458    struct local_pvt *p = NULL;
01459    struct ao2_iterator it;
01460 
01461    /* First, take us out of the channel loop */
01462    ast_cli_unregister_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
01463    ast_manager_unregister("LocalOptimizeAway");
01464    ast_channel_unregister(&local_tech);
01465 
01466    it = ao2_iterator_init(locals, 0);
01467    while ((p = ao2_iterator_next(&it))) {
01468       if (p->owner) {
01469          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
01470       }
01471       ao2_ref(p, -1);
01472    }
01473    ao2_iterator_destroy(&it);
01474    ao2_ref(locals, -1);
01475 
01476    ast_format_cap_destroy(local_tech.capabilities);
01477    return 0;
01478 }
01479 
01480 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Local Proxy Channel (Note: used internally by other modules)",
01481       .load = load_module,
01482       .unload = unload_module,
01483       .load_pri = AST_MODPRI_CHANNEL_DRIVER,
01484    );