channel_internal_api.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2012, 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  * \brief Channel Accessor API
00022  *
00023  * This file is intended to be the only file that ever accesses the
00024  * internals of an ast_channel. All other files should use the
00025  * accessor functions defined here.
00026  *
00027  * \author Terry Wilson
00028  */
00029 
00030 /*** MODULEINFO
00031    <support_level>core</support_level>
00032  ***/
00033 
00034 #include "asterisk.h"
00035 
00036 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 432834 $")
00037 
00038 #include <unistd.h>
00039 #include <fcntl.h>
00040 
00041 #include "asterisk/paths.h"
00042 #include "asterisk/channel.h"
00043 #include "asterisk/channel_internal.h"
00044 #include "asterisk/data.h"
00045 #include "asterisk/endpoints.h"
00046 #include "asterisk/indications.h"
00047 #include "asterisk/stasis_cache_pattern.h"
00048 #include "asterisk/stasis_channels.h"
00049 #include "asterisk/stasis_endpoints.h"
00050 #include "asterisk/stringfields.h"
00051 #include "asterisk/test.h"
00052 
00053 /*!
00054  * \brief Channel UniqueId structure
00055  * \note channel creation time used for determining LinkedId Propagation
00056  */
00057 struct ast_channel_id {
00058    time_t creation_time;            /*!< Creation time */
00059    int creation_unique;          /*!< sub-second unique value */
00060    char unique_id[AST_MAX_UNIQUEID];   /*!< Unique Identifier */
00061 };
00062 
00063 /*!
00064  * \brief Main Channel structure associated with a channel.
00065  *
00066  * \note When adding fields to this structure, it is important to add the field
00067  *       'in position' with like-aligned fields, so as to keep the compiler from
00068  *       having to add padding to align fields. The structure's fields are sorted
00069  *       in this order: pointers, structures, long, int/enum, short, char. This
00070  *       is especially important on 64-bit architectures, where mixing 4-byte
00071  *       and 8-byte fields causes 4 bytes of padding to be added before many
00072  *       8-byte fields.
00073  */
00074 struct ast_channel {
00075    const struct ast_channel_tech *tech;      /*!< Technology (point to channel driver) */
00076    void *tech_pvt;               /*!< Private data used by the technology driver */
00077    void *music_state;            /*!< Music State*/
00078    void *generatordata;          /*!< Current generator data if there is any */
00079    struct ast_generator *generator;    /*!< Current active data generator */
00080    struct ast_channel *masq;        /*!< Channel that will masquerade as us */
00081    struct ast_channel *masqr;       /*!< Who we are masquerading as */
00082    const char *blockproc;           /*!< Procedure causing blocking */
00083    const char *appl;          /*!< Current application */
00084    const char *data;          /*!< Data passed to current application */
00085    struct ast_sched_context *sched;                /*!< Schedule context */
00086    struct ast_filestream *stream;         /*!< Stream itself. */
00087    struct ast_filestream *vstream;        /*!< Video Stream itself. */
00088    ast_timing_func_t timingfunc;
00089    void *timingdata;
00090    struct ast_pbx *pbx;          /*!< PBX private structure for this channel */
00091    struct ast_trans_pvt *writetrans;      /*!< Write translation path */
00092    struct ast_trans_pvt *readtrans;    /*!< Read translation path */
00093    struct ast_audiohook_list *audiohooks;
00094    struct ast_framehook_list *framehooks;
00095    struct ast_cdr *cdr;          /*!< Call Detail Record */
00096    struct ast_tone_zone *zone;         /*!< Tone zone as set in indications.conf or
00097                       *   in the CHANNEL dialplan function */
00098    struct ast_channel_monitor *monitor;      /*!< Channel monitoring */
00099    ast_callid callid;         /*!< Bound call identifier pointer */
00100 #ifdef HAVE_EPOLL
00101    struct ast_epoll_data *epfd_data[AST_MAX_FDS];
00102 #endif
00103    struct ao2_container *dialed_causes;      /*!< Contains tech-specific and Asterisk cause data from dialed channels */
00104 
00105    AST_DECLARE_STRING_FIELDS(
00106       AST_STRING_FIELD(name);         /*!< ASCII unique channel name */
00107       AST_STRING_FIELD(language);     /*!< Language requested for voice prompts */
00108       AST_STRING_FIELD(musicclass);   /*!< Default music class */
00109       AST_STRING_FIELD(latest_musicclass);   /*!< Latest active music class */
00110       AST_STRING_FIELD(accountcode);  /*!< Account code for billing */
00111       AST_STRING_FIELD(peeraccount);  /*!< Peer account code for billing */
00112       AST_STRING_FIELD(userfield);    /*!< Userfield for CEL billing */
00113       AST_STRING_FIELD(call_forward); /*!< Where to forward to if asked to dial on this interface */
00114       AST_STRING_FIELD(parkinglot);   /*! Default parking lot, if empty, default parking lot  */
00115       AST_STRING_FIELD(hangupsource); /*! Who is responsible for hanging up this channel */
00116       AST_STRING_FIELD(dialcontext);  /*!< Dial: Extension context that we were called from */
00117    );
00118 
00119    struct ast_channel_id uniqueid;     /*!< Unique Channel Identifier - can be specified on creation */
00120    struct ast_channel_id linkedid;     /*!< Linked Channel Identifier - oldest propagated when bridged */
00121 
00122    struct timeval whentohangup; /*!< Non-zero, set to actual time when channel is to be hung up */
00123    pthread_t blocker;           /*!< If anyone is blocking, this is them */
00124 
00125    /*!
00126     * \brief Dialed/Called information.
00127     * \note Set on incoming channels to indicate the originally dialed party.
00128     * \note Dialed Number Identifier (DNID)
00129     */
00130    struct ast_party_dialed dialed;
00131 
00132    /*!
00133     * \brief Channel Caller ID information.
00134     * \note The caller id information is the caller id of this
00135     * channel when it is used to initiate a call.
00136     */
00137    struct ast_party_caller caller;
00138 
00139    /*!
00140     * \brief Channel Connected Line ID information.
00141     * \note The connected line information identifies the channel
00142     * connected/bridged to this channel.
00143     */
00144    struct ast_party_connected_line connected;
00145 
00146    /*!
00147     * \brief Channel Connected Line ID information that was last indicated.
00148     */
00149    struct ast_party_connected_line connected_indicated;
00150 
00151    /*! \brief Redirecting/Diversion information */
00152    struct ast_party_redirecting redirecting;
00153 
00154    struct ast_frame dtmff;          /*!< DTMF frame */
00155    struct varshead varshead;        /*!< A linked list for channel variables. See \ref AstChanVar */
00156    ast_group_t callgroup;           /*!< Call group for call pickups */
00157    ast_group_t pickupgroup;         /*!< Pickup group - which calls groups can be picked up? */
00158    struct ast_namedgroups *named_callgroups; /*!< Named call group for call pickups */
00159    struct ast_namedgroups *named_pickupgroups;  /*!< Named pickup group - which call groups can be picked up? */
00160    struct timeval creationtime;        /*!< The time of channel creation */
00161    struct timeval answertime;          /*!< The time the channel was answered */
00162    struct ast_readq_list readq;
00163    struct ast_jb jb;          /*!< The jitterbuffer state */
00164    struct timeval dtmf_tv;          /*!< The time that an in process digit began, or the last digit ended */
00165    struct ast_hangup_handler_list hangup_handlers;/*!< Hangup handlers on the channel. */
00166    struct ast_datastore_list datastores; /*!< Data stores on the channel */
00167    struct ast_autochan_list autochans; /*!< Autochans on the channel */
00168    unsigned long insmpl;            /*!< Track the read/written samples for monitor use */
00169    unsigned long outsmpl;           /*!< Track the read/written samples for monitor use */
00170 
00171    int fds[AST_MAX_FDS];            /*!< File descriptors for channel -- Drivers will poll on
00172                       *   these file descriptors, so at least one must be non -1.
00173                       *   See \arg \ref AstFileDesc */
00174    int softhangup;            /*!< Whether or not we have been hung up...  Do not set this value
00175                       *   directly, use ast_softhangup() */
00176    int unbridged;              /*!< If non-zero, the bridge core needs to re-evaluate the current
00177                                     bridging technology which is in use by this channel's bridge. */
00178    int fdno;               /*!< Which fd had an event detected on */
00179    int streamid;              /*!< For streaming playback, the schedule ID */
00180    int vstreamid;             /*!< For streaming video playback, the schedule ID */
00181    struct ast_format *oldwriteformat;  /*!< Original writer format */
00182    int timingfd;              /*!< Timing fd */
00183    enum ast_channel_state state;       /*!< State of line -- Don't write directly, use ast_setstate() */
00184    int rings;              /*!< Number of rings so far */
00185    int priority;              /*!< Dialplan: Current extension priority */
00186    int macropriority;            /*!< Macro: Current non-macro priority. See app_macro.c */
00187    int amaflags;              /*!< Set BEFORE PBX is started to determine AMA flags */
00188    enum ast_channel_adsicpe adsicpe;      /*!< Whether or not ADSI is detected on CPE */
00189    unsigned int fin;          /*!< Frames in counters. The high bit is a debug mask, so
00190                       *   the counter is only in the remaining bits */
00191    unsigned int fout;            /*!< Frames out counters. The high bit is a debug mask, so
00192                       *   the counter is only in the remaining bits */
00193    int hangupcause;           /*!< Why is the channel hanged up. See causes.h */
00194    unsigned int finalized:1;       /*!< Whether or not the channel has been successfully allocated */
00195    struct ast_flags flags;          /*!< channel flags of AST_FLAG_ type */
00196    int alertpipe[2];
00197    struct ast_format_cap *nativeformats;         /*!< Kinds of data this channel can natively handle */
00198    struct ast_format *readformat;            /*!< Requested read format (after translation) */
00199    struct ast_format *writeformat;           /*!< Requested write format (before translation) */
00200    struct ast_format *rawreadformat;         /*!< Raw read format (before translation) */
00201    struct ast_format *rawwriteformat;        /*!< Raw write format (after translation) */
00202    unsigned int emulate_dtmf_duration;    /*!< Number of ms left to emulate DTMF for */
00203 #ifdef HAVE_EPOLL
00204    int epfd;
00205 #endif
00206    int visible_indication;                         /*!< Indication currently playing on the channel */
00207    int hold_state;                     /*!< Current Hold/Unhold state */
00208 
00209    unsigned short transfercapability;     /*!< ISDN Transfer Capability - AST_FLAG_DIGITAL is not enough */
00210 
00211    struct ast_bridge *bridge;                      /*!< Bridge this channel is participating in */
00212    struct ast_bridge_channel *bridge_channel;/*!< The bridge_channel this channel is linked with. */
00213    struct ast_timer *timer;         /*!< timer object that provided timingfd */
00214 
00215    char context[AST_MAX_CONTEXT];         /*!< Dialplan: Current extension context */
00216    char exten[AST_MAX_EXTENSION];         /*!< Dialplan: Current extension number */
00217    char macrocontext[AST_MAX_CONTEXT];    /*!< Macro: Current non-macro context. See app_macro.c */
00218    char macroexten[AST_MAX_EXTENSION];    /*!< Macro: Current non-macro extension. See app_macro.c */
00219    char dtmf_digit_to_emulate;         /*!< Digit being emulated */
00220    char sending_dtmf_digit;         /*!< Digit this channel is currently sending out. (zero if not sending) */
00221    struct timeval sending_dtmf_tv;     /*!< The time this channel started sending the current digit. (Invalid if sending_dtmf_digit is zero.) */
00222    struct stasis_cp_single *topics;    /*!< Topic for all channel's events */
00223    struct stasis_forward *endpoint_forward;  /*!< Subscription for event forwarding to endpoint's topic */
00224    struct stasis_forward *endpoint_cache_forward; /*!< Subscription for cache updates to endpoint's topic */
00225 };
00226 
00227 /*! \brief The monotonically increasing integer counter for channel uniqueids */
00228 static int uniqueint;
00229 
00230 /* AST_DATA definitions, which will probably have to be re-thought since the channel will be opaque */
00231 
00232 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */
00233 #define DATA_EXPORT_CALLERID(MEMBER)            \
00234    MEMBER(ast_callerid, cid_dnid, AST_DATA_STRING)    \
00235    MEMBER(ast_callerid, cid_num, AST_DATA_STRING)     \
00236    MEMBER(ast_callerid, cid_name, AST_DATA_STRING)    \
00237    MEMBER(ast_callerid, cid_ani, AST_DATA_STRING)     \
00238    MEMBER(ast_callerid, cid_pres, AST_DATA_INTEGER)   \
00239    MEMBER(ast_callerid, cid_ani2, AST_DATA_INTEGER)   \
00240    MEMBER(ast_callerid, cid_tag, AST_DATA_STRING)
00241 
00242 AST_DATA_STRUCTURE(ast_callerid, DATA_EXPORT_CALLERID);
00243 #endif
00244 
00245 #define DATA_EXPORT_CHANNEL(MEMBER)                \
00246    MEMBER(ast_channel, blockproc, AST_DATA_STRING)          \
00247    MEMBER(ast_channel, appl, AST_DATA_STRING)            \
00248    MEMBER(ast_channel, data, AST_DATA_STRING)            \
00249    MEMBER(ast_channel, name, AST_DATA_STRING) \
00250    MEMBER(ast_channel, language, AST_DATA_STRING)           \
00251    MEMBER(ast_channel, musicclass, AST_DATA_STRING)         \
00252    MEMBER(ast_channel, accountcode, AST_DATA_STRING)        \
00253    MEMBER(ast_channel, peeraccount, AST_DATA_STRING)        \
00254    MEMBER(ast_channel, userfield, AST_DATA_STRING)          \
00255    MEMBER(ast_channel, call_forward, AST_DATA_STRING)       \
00256    MEMBER(ast_channel, parkinglot, AST_DATA_STRING)         \
00257    MEMBER(ast_channel, hangupsource, AST_DATA_STRING)       \
00258    MEMBER(ast_channel, dialcontext, AST_DATA_STRING)        \
00259    MEMBER(ast_channel, rings, AST_DATA_INTEGER)          \
00260    MEMBER(ast_channel, priority, AST_DATA_INTEGER)          \
00261    MEMBER(ast_channel, macropriority, AST_DATA_INTEGER)        \
00262    MEMBER(ast_channel, adsicpe, AST_DATA_INTEGER)           \
00263    MEMBER(ast_channel, fin, AST_DATA_UNSIGNED_INTEGER)         \
00264    MEMBER(ast_channel, fout, AST_DATA_UNSIGNED_INTEGER)        \
00265    MEMBER(ast_channel, emulate_dtmf_duration, AST_DATA_UNSIGNED_INTEGER)   \
00266    MEMBER(ast_channel, visible_indication, AST_DATA_INTEGER)      \
00267    MEMBER(ast_channel, context, AST_DATA_STRING)            \
00268    MEMBER(ast_channel, exten, AST_DATA_STRING)           \
00269    MEMBER(ast_channel, macrocontext, AST_DATA_STRING)       \
00270    MEMBER(ast_channel, macroexten, AST_DATA_STRING)
00271 
00272 AST_DATA_STRUCTURE(ast_channel, DATA_EXPORT_CHANNEL);
00273 
00274 static void channel_data_add_flags(struct ast_data *tree,
00275    struct ast_channel *chan)
00276 {
00277    ast_data_add_bool(tree, "DEFER_DTMF", ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF));
00278    ast_data_add_bool(tree, "WRITE_INT", ast_test_flag(ast_channel_flags(chan), AST_FLAG_WRITE_INT));
00279    ast_data_add_bool(tree, "BLOCKING", ast_test_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING));
00280    ast_data_add_bool(tree, "ZOMBIE", ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE));
00281    ast_data_add_bool(tree, "EXCEPTION", ast_test_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION));
00282    ast_data_add_bool(tree, "MOH", ast_test_flag(ast_channel_flags(chan), AST_FLAG_MOH));
00283    ast_data_add_bool(tree, "SPYING", ast_test_flag(ast_channel_flags(chan), AST_FLAG_SPYING));
00284    ast_data_add_bool(tree, "IN_AUTOLOOP", ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP));
00285    ast_data_add_bool(tree, "OUTGOING", ast_test_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING));
00286    ast_data_add_bool(tree, "IN_DTMF", ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF));
00287    ast_data_add_bool(tree, "EMULATE_DTMF", ast_test_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF));
00288    ast_data_add_bool(tree, "END_DTMF_ONLY", ast_test_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY));
00289    ast_data_add_bool(tree, "MASQ_NOSTREAM", ast_test_flag(ast_channel_flags(chan), AST_FLAG_MASQ_NOSTREAM));
00290    ast_data_add_bool(tree, "BRIDGE_HANGUP_RUN", ast_test_flag(ast_channel_flags(chan), AST_FLAG_BRIDGE_HANGUP_RUN));
00291    ast_data_add_bool(tree, "DISABLE_WORKAROUNDS", ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS));
00292    ast_data_add_bool(tree, "DISABLE_DEVSTATE_CACHE", ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE));
00293    ast_data_add_bool(tree, "BRIDGE_DUAL_REDIRECT_WAIT", ast_test_flag(ast_channel_flags(chan), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT));
00294    ast_data_add_bool(tree, "ORIGINATED", ast_test_flag(ast_channel_flags(chan), AST_FLAG_ORIGINATED));
00295    ast_data_add_bool(tree, "DEAD", ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEAD));
00296 }
00297 
00298 int ast_channel_data_add_structure(struct ast_data *tree,
00299    struct ast_channel *chan, int add_bridged)
00300 {
00301    struct ast_data *data_bridged;
00302    struct ast_data *data_cdr;
00303    struct ast_data *data_flags;
00304    struct ast_data *data_zones;
00305    struct ast_data *enum_node;
00306    struct ast_data *data_softhangup;
00307 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */
00308    struct ast_data *data_callerid;
00309    char value_str[100];
00310 #endif
00311 
00312    if (!tree) {
00313       return -1;
00314    }
00315 
00316    ast_data_add_structure(ast_channel, tree, chan);
00317 
00318    if (add_bridged) {
00319       RAII_VAR(struct ast_channel *, bc, ast_channel_bridge_peer(chan), ast_channel_cleanup);
00320       if (bc) {
00321          data_bridged = ast_data_add_node(tree, "bridged");
00322          if (!data_bridged) {
00323             return -1;
00324          }
00325          ast_channel_data_add_structure(data_bridged, bc, 0);
00326       }
00327    }
00328 
00329    ast_data_add_str(tree, "uniqueid", ast_channel_uniqueid(chan));
00330    ast_data_add_str(tree, "linkedid", ast_channel_linkedid(chan));
00331 
00332    ast_data_add_codec(tree, "oldwriteformat", ast_channel_oldwriteformat(chan));
00333    ast_data_add_codec(tree, "readformat", ast_channel_readformat(chan));
00334    ast_data_add_codec(tree, "writeformat", ast_channel_writeformat(chan));
00335    ast_data_add_codec(tree, "rawreadformat", ast_channel_rawreadformat(chan));
00336    ast_data_add_codec(tree, "rawwriteformat", ast_channel_rawwriteformat(chan));
00337    ast_data_add_codecs(tree, "nativeformats", ast_channel_nativeformats(chan));
00338 
00339    /* state */
00340    enum_node = ast_data_add_node(tree, "state");
00341    if (!enum_node) {
00342       return -1;
00343    }
00344    ast_data_add_str(enum_node, "text", ast_state2str(ast_channel_state(chan)));
00345    ast_data_add_int(enum_node, "value", ast_channel_state(chan));
00346 
00347    /* hangupcause */
00348    enum_node = ast_data_add_node(tree, "hangupcause");
00349    if (!enum_node) {
00350       return -1;
00351    }
00352    ast_data_add_str(enum_node, "text", ast_cause2str(ast_channel_hangupcause(chan)));
00353    ast_data_add_int(enum_node, "value", ast_channel_hangupcause(chan));
00354 
00355    /* amaflags */
00356    enum_node = ast_data_add_node(tree, "amaflags");
00357    if (!enum_node) {
00358       return -1;
00359    }
00360    ast_data_add_str(enum_node, "text", ast_channel_amaflags2string(ast_channel_amaflags(chan)));
00361    ast_data_add_int(enum_node, "value", ast_channel_amaflags(chan));
00362 
00363    /* transfercapability */
00364    enum_node = ast_data_add_node(tree, "transfercapability");
00365    if (!enum_node) {
00366       return -1;
00367    }
00368    ast_data_add_str(enum_node, "text", ast_transfercapability2str(ast_channel_transfercapability(chan)));
00369    ast_data_add_int(enum_node, "value", ast_channel_transfercapability(chan));
00370 
00371    /* _softphangup */
00372    data_softhangup = ast_data_add_node(tree, "softhangup");
00373    if (!data_softhangup) {
00374       return -1;
00375    }
00376    ast_data_add_bool(data_softhangup, "dev", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_DEV);
00377    ast_data_add_bool(data_softhangup, "asyncgoto", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO);
00378    ast_data_add_bool(data_softhangup, "shutdown", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_SHUTDOWN);
00379    ast_data_add_bool(data_softhangup, "timeout", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_TIMEOUT);
00380    ast_data_add_bool(data_softhangup, "appunload", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_APPUNLOAD);
00381    ast_data_add_bool(data_softhangup, "explicit", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_EXPLICIT);
00382 
00383    /* channel flags */
00384    data_flags = ast_data_add_node(tree, "flags");
00385    if (!data_flags) {
00386       return -1;
00387    }
00388    channel_data_add_flags(data_flags, chan);
00389 
00390    ast_data_add_uint(tree, "timetohangup", ast_channel_whentohangup(chan)->tv_sec);
00391 
00392 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */
00393    /* callerid */
00394    data_callerid = ast_data_add_node(tree, "callerid");
00395    if (!data_callerid) {
00396       return -1;
00397    }
00398    ast_data_add_structure(ast_callerid, data_callerid, &(chan->cid));
00399    /* insert the callerid ton */
00400    enum_node = ast_data_add_node(data_callerid, "cid_ton");
00401    if (!enum_node) {
00402       return -1;
00403    }
00404    ast_data_add_int(enum_node, "value", chan->cid.cid_ton);
00405    snprintf(value_str, sizeof(value_str), "TON: %s/Plan: %s",
00406       party_number_ton2str(chan->cid.cid_ton),
00407       party_number_plan2str(chan->cid.cid_ton));
00408    ast_data_add_str(enum_node, "text", value_str);
00409 #endif
00410 
00411    /* tone zone */
00412    if (ast_channel_zone(chan)) {
00413       data_zones = ast_data_add_node(tree, "zone");
00414       if (!data_zones) {
00415          return -1;
00416       }
00417       ast_tone_zone_data_add_structure(data_zones, ast_channel_zone(chan));
00418    }
00419 
00420    /* insert cdr */
00421    data_cdr = ast_data_add_node(tree, "cdr");
00422    if (!data_cdr) {
00423       return -1;
00424    }
00425 
00426    return 0;
00427 }
00428 
00429 int ast_channel_data_cmp_structure(const struct ast_data_search *tree,
00430    struct ast_channel *chan, const char *structure_name)
00431 {
00432    return ast_data_search_cmp_structure(tree, ast_channel, chan, structure_name);
00433 }
00434 
00435 /* ACCESSORS */
00436 
00437 #define DEFINE_STRINGFIELD_SETTERS_FOR(field, publish, assert_on_null) \
00438 void ast_channel_##field##_set(struct ast_channel *chan, const char *value) \
00439 { \
00440    if ((assert_on_null)) ast_assert(!ast_strlen_zero(value)); \
00441    if (!strcmp(value, chan->field)) return; \
00442    ast_string_field_set(chan, field, value); \
00443    if (publish && ast_channel_internal_is_finalized(chan)) ast_channel_publish_snapshot(chan); \
00444 } \
00445   \
00446 void ast_channel_##field##_build_va(struct ast_channel *chan, const char *fmt, va_list ap) \
00447 { \
00448    ast_string_field_build_va(chan, field, fmt, ap); \
00449    if (publish && ast_channel_internal_is_finalized(chan)) ast_channel_publish_snapshot(chan); \
00450 } \
00451 void ast_channel_##field##_build(struct ast_channel *chan, const char *fmt, ...) \
00452 { \
00453    va_list ap; \
00454    va_start(ap, fmt); \
00455    ast_channel_##field##_build_va(chan, fmt, ap); \
00456    va_end(ap); \
00457 }
00458 
00459 DEFINE_STRINGFIELD_SETTERS_FOR(name, 0, 1);
00460 DEFINE_STRINGFIELD_SETTERS_FOR(language, 1, 0);
00461 DEFINE_STRINGFIELD_SETTERS_FOR(musicclass, 0, 0);
00462 DEFINE_STRINGFIELD_SETTERS_FOR(latest_musicclass, 0, 0);
00463 DEFINE_STRINGFIELD_SETTERS_FOR(accountcode, 1, 0);
00464 DEFINE_STRINGFIELD_SETTERS_FOR(peeraccount, 1, 0);
00465 DEFINE_STRINGFIELD_SETTERS_FOR(userfield, 0, 0);
00466 DEFINE_STRINGFIELD_SETTERS_FOR(call_forward, 0, 0);
00467 DEFINE_STRINGFIELD_SETTERS_FOR(parkinglot, 0, 0);
00468 DEFINE_STRINGFIELD_SETTERS_FOR(hangupsource, 0, 0);
00469 DEFINE_STRINGFIELD_SETTERS_FOR(dialcontext, 0, 0);
00470 
00471 #define DEFINE_STRINGFIELD_GETTER_FOR(field) const char *ast_channel_##field(const struct ast_channel *chan) \
00472 { \
00473    return chan->field; \
00474 }
00475 
00476 DEFINE_STRINGFIELD_GETTER_FOR(name);
00477 DEFINE_STRINGFIELD_GETTER_FOR(language);
00478 DEFINE_STRINGFIELD_GETTER_FOR(musicclass);
00479 DEFINE_STRINGFIELD_GETTER_FOR(latest_musicclass);
00480 DEFINE_STRINGFIELD_GETTER_FOR(accountcode);
00481 DEFINE_STRINGFIELD_GETTER_FOR(peeraccount);
00482 DEFINE_STRINGFIELD_GETTER_FOR(userfield);
00483 DEFINE_STRINGFIELD_GETTER_FOR(call_forward);
00484 DEFINE_STRINGFIELD_GETTER_FOR(parkinglot);
00485 DEFINE_STRINGFIELD_GETTER_FOR(hangupsource);
00486 DEFINE_STRINGFIELD_GETTER_FOR(dialcontext);
00487 
00488 const char *ast_channel_uniqueid(const struct ast_channel *chan)
00489 {
00490    ast_assert(chan->uniqueid.unique_id[0] != '\0');
00491    return chan->uniqueid.unique_id;
00492 }
00493 
00494 const char *ast_channel_linkedid(const struct ast_channel *chan)
00495 {
00496    ast_assert(chan->linkedid.unique_id[0] != '\0');
00497    return chan->linkedid.unique_id;
00498 }
00499 
00500 const char *ast_channel_appl(const struct ast_channel *chan)
00501 {
00502    return chan->appl;
00503 }
00504 void ast_channel_appl_set(struct ast_channel *chan, const char *value)
00505 {
00506    chan->appl = value;
00507 }
00508 const char *ast_channel_blockproc(const struct ast_channel *chan)
00509 {
00510    return chan->blockproc;
00511 }
00512 void ast_channel_blockproc_set(struct ast_channel *chan, const char *value)
00513 {
00514    chan->blockproc = value;
00515 }
00516 const char *ast_channel_data(const struct ast_channel *chan)
00517 {
00518    return chan->data;
00519 }
00520 void ast_channel_data_set(struct ast_channel *chan, const char *value)
00521 {
00522    chan->data = value;
00523 }
00524 
00525 const char *ast_channel_context(const struct ast_channel *chan)
00526 {
00527    return chan->context;
00528 }
00529 void ast_channel_context_set(struct ast_channel *chan, const char *value)
00530 {
00531    ast_copy_string(chan->context, value, sizeof(chan->context));
00532 }
00533 const char *ast_channel_exten(const struct ast_channel *chan)
00534 {
00535    return chan->exten;
00536 }
00537 void ast_channel_exten_set(struct ast_channel *chan, const char *value)
00538 {
00539    ast_copy_string(chan->exten, value, sizeof(chan->exten));
00540 }
00541 const char *ast_channel_macrocontext(const struct ast_channel *chan)
00542 {
00543    return chan->macrocontext;
00544 }
00545 void ast_channel_macrocontext_set(struct ast_channel *chan, const char *value)
00546 {
00547    ast_copy_string(chan->macrocontext, value, sizeof(chan->macrocontext));
00548 }
00549 const char *ast_channel_macroexten(const struct ast_channel *chan)
00550 {
00551    return chan->macroexten;
00552 }
00553 void ast_channel_macroexten_set(struct ast_channel *chan, const char *value)
00554 {
00555    ast_copy_string(chan->macroexten, value, sizeof(chan->macroexten));
00556 }
00557 
00558 char ast_channel_dtmf_digit_to_emulate(const struct ast_channel *chan)
00559 {
00560    return chan->dtmf_digit_to_emulate;
00561 }
00562 void ast_channel_dtmf_digit_to_emulate_set(struct ast_channel *chan, char value)
00563 {
00564    chan->dtmf_digit_to_emulate = value;
00565 }
00566 
00567 char ast_channel_sending_dtmf_digit(const struct ast_channel *chan)
00568 {
00569    return chan->sending_dtmf_digit;
00570 }
00571 void ast_channel_sending_dtmf_digit_set(struct ast_channel *chan, char value)
00572 {
00573    chan->sending_dtmf_digit = value;
00574 }
00575 
00576 struct timeval ast_channel_sending_dtmf_tv(const struct ast_channel *chan)
00577 {
00578    return chan->sending_dtmf_tv;
00579 }
00580 void ast_channel_sending_dtmf_tv_set(struct ast_channel *chan, struct timeval value)
00581 {
00582    chan->sending_dtmf_tv = value;
00583 }
00584 
00585 enum ama_flags ast_channel_amaflags(const struct ast_channel *chan)
00586 {
00587    return chan->amaflags;
00588 }
00589 
00590 void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
00591 {
00592    if (chan->amaflags == value) {
00593       return;
00594    }
00595    chan->amaflags = value;
00596    ast_channel_publish_snapshot(chan);
00597 }
00598 
00599 #ifdef HAVE_EPOLL
00600 int ast_channel_epfd(const struct ast_channel *chan)
00601 {
00602    return chan->epfd;
00603 }
00604 void ast_channel_epfd_set(struct ast_channel *chan, int value)
00605 {
00606    chan->epfd = value;
00607 }
00608 #endif
00609 int ast_channel_fdno(const struct ast_channel *chan)
00610 {
00611    return chan->fdno;
00612 }
00613 void ast_channel_fdno_set(struct ast_channel *chan, int value)
00614 {
00615    chan->fdno = value;
00616 }
00617 int ast_channel_hangupcause(const struct ast_channel *chan)
00618 {
00619    return chan->hangupcause;
00620 }
00621 void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
00622 {
00623    chan->hangupcause = value;
00624 }
00625 int ast_channel_macropriority(const struct ast_channel *chan)
00626 {
00627    return chan->macropriority;
00628 }
00629 void ast_channel_macropriority_set(struct ast_channel *chan, int value)
00630 {
00631    chan->macropriority = value;
00632 }
00633 int ast_channel_priority(const struct ast_channel *chan)
00634 {
00635    return chan->priority;
00636 }
00637 void ast_channel_priority_set(struct ast_channel *chan, int value)
00638 {
00639    chan->priority = value;
00640 }
00641 int ast_channel_rings(const struct ast_channel *chan)
00642 {
00643    return chan->rings;
00644 }
00645 void ast_channel_rings_set(struct ast_channel *chan, int value)
00646 {
00647    chan->rings = value;
00648 }
00649 int ast_channel_streamid(const struct ast_channel *chan)
00650 {
00651    return chan->streamid;
00652 }
00653 void ast_channel_streamid_set(struct ast_channel *chan, int value)
00654 {
00655    chan->streamid = value;
00656 }
00657 int ast_channel_timingfd(const struct ast_channel *chan)
00658 {
00659    return chan->timingfd;
00660 }
00661 void ast_channel_timingfd_set(struct ast_channel *chan, int value)
00662 {
00663    chan->timingfd = value;
00664 }
00665 int ast_channel_visible_indication(const struct ast_channel *chan)
00666 {
00667    return chan->visible_indication;
00668 }
00669 void ast_channel_visible_indication_set(struct ast_channel *chan, int value)
00670 {
00671    chan->visible_indication = value;
00672 }
00673 int ast_channel_hold_state(const struct ast_channel *chan)
00674 {
00675    return chan->hold_state;
00676 }
00677 void ast_channel_hold_state_set(struct ast_channel *chan, int value)
00678 {
00679    chan->hold_state = value;
00680 }
00681 int ast_channel_vstreamid(const struct ast_channel *chan)
00682 {
00683    return chan->vstreamid;
00684 }
00685 void ast_channel_vstreamid_set(struct ast_channel *chan, int value)
00686 {
00687    chan->vstreamid = value;
00688 }
00689 unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
00690 {
00691    return chan->transfercapability;
00692 }
00693 void ast_channel_transfercapability_set(struct ast_channel *chan, unsigned short value)
00694 {
00695    chan->transfercapability = value;
00696 }
00697 unsigned int ast_channel_emulate_dtmf_duration(const struct ast_channel *chan)
00698 {
00699    return chan->emulate_dtmf_duration;
00700 }
00701 void ast_channel_emulate_dtmf_duration_set(struct ast_channel *chan, unsigned int value)
00702 {
00703    chan->emulate_dtmf_duration = value;
00704 }
00705 unsigned int ast_channel_fin(const struct ast_channel *chan)
00706 {
00707    return chan->fin;
00708 }
00709 void ast_channel_fin_set(struct ast_channel *chan, unsigned int value)
00710 {
00711    chan->fin = value;
00712 }
00713 unsigned int ast_channel_fout(const struct ast_channel *chan)
00714 {
00715    return chan->fout;
00716 }
00717 void ast_channel_fout_set(struct ast_channel *chan, unsigned int value)
00718 {
00719    chan->fout = value;
00720 }
00721 unsigned long ast_channel_insmpl(const struct ast_channel *chan)
00722 {
00723    return chan->insmpl;
00724 }
00725 void ast_channel_insmpl_set(struct ast_channel *chan, unsigned long value)
00726 {
00727    chan->insmpl = value;
00728 }
00729 unsigned long ast_channel_outsmpl(const struct ast_channel *chan)
00730 {
00731    return chan->outsmpl;
00732 }
00733 void ast_channel_outsmpl_set(struct ast_channel *chan, unsigned long value)
00734 {
00735    chan->outsmpl = value;
00736 }
00737 void *ast_channel_generatordata(const struct ast_channel *chan)
00738 {
00739    return chan->generatordata;
00740 }
00741 void ast_channel_generatordata_set(struct ast_channel *chan, void *value)
00742 {
00743    chan->generatordata = value;
00744 }
00745 void *ast_channel_music_state(const struct ast_channel *chan)
00746 {
00747    return chan->music_state;
00748 }
00749 void ast_channel_music_state_set(struct ast_channel *chan, void *value)
00750 {
00751    chan->music_state = value;
00752 }
00753 void *ast_channel_tech_pvt(const struct ast_channel *chan)
00754 {
00755    return chan->tech_pvt;
00756 }
00757 void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
00758 {
00759    chan->tech_pvt = value;
00760 }
00761 void *ast_channel_timingdata(const struct ast_channel *chan)
00762 {
00763    return chan->timingdata;
00764 }
00765 void ast_channel_timingdata_set(struct ast_channel *chan, void *value)
00766 {
00767    chan->timingdata = value;
00768 }
00769 struct ast_audiohook_list *ast_channel_audiohooks(const struct ast_channel *chan)
00770 {
00771    return chan->audiohooks;
00772 }
00773 void ast_channel_audiohooks_set(struct ast_channel *chan, struct ast_audiohook_list *value)
00774 {
00775    chan->audiohooks = value;
00776 }
00777 struct ast_cdr *ast_channel_cdr(const struct ast_channel *chan)
00778 {
00779    return chan->cdr;
00780 }
00781 void ast_channel_cdr_set(struct ast_channel *chan, struct ast_cdr *value)
00782 {
00783    chan->cdr = value;
00784 }
00785 struct ast_channel *ast_channel_masq(const struct ast_channel *chan)
00786 {
00787    return chan->masq;
00788 }
00789 void ast_channel_masq_set(struct ast_channel *chan, struct ast_channel *value)
00790 {
00791    chan->masq = value;
00792 }
00793 struct ast_channel *ast_channel_masqr(const struct ast_channel *chan)
00794 {
00795    return chan->masqr;
00796 }
00797 void ast_channel_masqr_set(struct ast_channel *chan, struct ast_channel *value)
00798 {
00799    chan->masqr = value;
00800 }
00801 struct ast_channel_monitor *ast_channel_monitor(const struct ast_channel *chan)
00802 {
00803    return chan->monitor;
00804 }
00805 void ast_channel_monitor_set(struct ast_channel *chan, struct ast_channel_monitor *value)
00806 {
00807    chan->monitor = value;
00808 }
00809 struct ast_filestream *ast_channel_stream(const struct ast_channel *chan)
00810 {
00811    return chan->stream;
00812 }
00813 void ast_channel_stream_set(struct ast_channel *chan, struct ast_filestream *value)
00814 {
00815    chan->stream = value;
00816 }
00817 struct ast_filestream *ast_channel_vstream(const struct ast_channel *chan)
00818 {
00819    return chan->vstream;
00820 }
00821 void ast_channel_vstream_set(struct ast_channel *chan, struct ast_filestream *value)
00822 {
00823    chan->vstream = value;
00824 }
00825 struct ast_format_cap *ast_channel_nativeformats(const struct ast_channel *chan)
00826 {
00827    return chan->nativeformats;
00828 }
00829 void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
00830 {
00831    ao2_replace(chan->nativeformats, value);
00832 }
00833 struct ast_framehook_list *ast_channel_framehooks(const struct ast_channel *chan)
00834 {
00835    return chan->framehooks;
00836 }
00837 void ast_channel_framehooks_set(struct ast_channel *chan, struct ast_framehook_list *value)
00838 {
00839    chan->framehooks = value;
00840 }
00841 struct ast_generator *ast_channel_generator(const struct ast_channel *chan)
00842 {
00843    return chan->generator;
00844 }
00845 void ast_channel_generator_set(struct ast_channel *chan, struct ast_generator *value)
00846 {
00847    chan->generator = value;
00848 }
00849 struct ast_pbx *ast_channel_pbx(const struct ast_channel *chan)
00850 {
00851    return chan->pbx;
00852 }
00853 void ast_channel_pbx_set(struct ast_channel *chan, struct ast_pbx *value)
00854 {
00855    chan->pbx = value;
00856 }
00857 struct ast_sched_context *ast_channel_sched(const struct ast_channel *chan)
00858 {
00859    return chan->sched;
00860 }
00861 void ast_channel_sched_set(struct ast_channel *chan, struct ast_sched_context *value)
00862 {
00863    chan->sched = value;
00864 }
00865 struct ast_timer *ast_channel_timer(const struct ast_channel *chan)
00866 {
00867    return chan->timer;
00868 }
00869 void ast_channel_timer_set(struct ast_channel *chan, struct ast_timer *value)
00870 {
00871    chan->timer = value;
00872 }
00873 struct ast_tone_zone *ast_channel_zone(const struct ast_channel *chan)
00874 {
00875    return chan->zone;
00876 }
00877 void ast_channel_zone_set(struct ast_channel *chan, struct ast_tone_zone *value)
00878 {
00879    chan->zone = value;
00880 }
00881 struct ast_trans_pvt *ast_channel_readtrans(const struct ast_channel *chan)
00882 {
00883    return chan->readtrans;
00884 }
00885 void ast_channel_readtrans_set(struct ast_channel *chan, struct ast_trans_pvt *value)
00886 {
00887    chan->readtrans = value;
00888 }
00889 struct ast_trans_pvt *ast_channel_writetrans(const struct ast_channel *chan)
00890 {
00891    return chan->writetrans;
00892 }
00893 void ast_channel_writetrans_set(struct ast_channel *chan, struct ast_trans_pvt *value)
00894 {
00895    chan->writetrans = value;
00896 }
00897 const struct ast_channel_tech *ast_channel_tech(const struct ast_channel *chan)
00898 {
00899    return chan->tech;
00900 }
00901 void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
00902 {
00903    chan->tech = value;
00904 }
00905 enum ast_channel_adsicpe ast_channel_adsicpe(const struct ast_channel *chan)
00906 {
00907    return chan->adsicpe;
00908 }
00909 void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
00910 {
00911    chan->adsicpe = value;
00912 }
00913 enum ast_channel_state ast_channel_state(const struct ast_channel *chan)
00914 {
00915    return chan->state;
00916 }
00917 ast_callid ast_channel_callid(const struct ast_channel *chan)
00918 {
00919    return chan->callid;
00920 }
00921 void ast_channel_callid_set(struct ast_channel *chan, ast_callid callid)
00922 {
00923    char call_identifier_from[AST_CALLID_BUFFER_LENGTH];
00924    char call_identifier_to[AST_CALLID_BUFFER_LENGTH];
00925    call_identifier_from[0] = '\0';
00926    ast_callid_strnprint(call_identifier_to, sizeof(call_identifier_to), callid);
00927    if (chan->callid) {
00928       ast_callid_strnprint(call_identifier_from, sizeof(call_identifier_from), chan->callid);
00929       ast_debug(3, "Channel Call ID changing from %s to %s\n", call_identifier_from, call_identifier_to);
00930    }
00931 
00932    chan->callid = callid;
00933 
00934    ast_test_suite_event_notify("CallIDChange",
00935       "State: CallIDChange\r\n"
00936       "Channel: %s\r\n"
00937       "CallID: %s\r\n"
00938       "PriorCallID: %s",
00939       ast_channel_name(chan),
00940       call_identifier_to,
00941       call_identifier_from);
00942 }
00943 
00944 void ast_channel_state_set(struct ast_channel *chan, enum ast_channel_state value)
00945 {
00946    chan->state = value;
00947 }
00948 void ast_channel_set_oldwriteformat(struct ast_channel *chan, struct ast_format *format)
00949 {
00950    ao2_replace(chan->oldwriteformat, format);
00951 }
00952 void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
00953 {
00954    ao2_replace(chan->rawreadformat, format);
00955 }
00956 void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
00957 {
00958    ao2_replace(chan->rawwriteformat, format);
00959 }
00960 void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
00961 {
00962    ao2_replace(chan->readformat, format);
00963 }
00964 void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
00965 {
00966    ao2_replace(chan->writeformat, format);
00967 }
00968 struct ast_format *ast_channel_oldwriteformat(struct ast_channel *chan)
00969 {
00970    return chan->oldwriteformat;
00971 }
00972 struct ast_format *ast_channel_rawreadformat(struct ast_channel *chan)
00973 {
00974    return chan->rawreadformat;
00975 }
00976 struct ast_format *ast_channel_rawwriteformat(struct ast_channel *chan)
00977 {
00978    return chan->rawwriteformat;
00979 }
00980 struct ast_format *ast_channel_readformat(struct ast_channel *chan)
00981 {
00982    return chan->readformat;
00983 }
00984 struct ast_format *ast_channel_writeformat(struct ast_channel *chan)
00985 {
00986    return chan->writeformat;
00987 }
00988 struct ast_hangup_handler_list *ast_channel_hangup_handlers(struct ast_channel *chan)
00989 {
00990    return &chan->hangup_handlers;
00991 }
00992 struct ast_datastore_list *ast_channel_datastores(struct ast_channel *chan)
00993 {
00994    return &chan->datastores;
00995 }
00996 struct ast_autochan_list *ast_channel_autochans(struct ast_channel *chan)
00997 {
00998    return &chan->autochans;
00999 }
01000 struct ast_readq_list *ast_channel_readq(struct ast_channel *chan)
01001 {
01002    return &chan->readq;
01003 }
01004 struct ast_frame *ast_channel_dtmff(struct ast_channel *chan)
01005 {
01006    return &chan->dtmff;
01007 }
01008 struct ast_jb *ast_channel_jb(struct ast_channel *chan)
01009 {
01010    return &chan->jb;
01011 }
01012 struct ast_party_caller *ast_channel_caller(struct ast_channel *chan)
01013 {
01014    return &chan->caller;
01015 }
01016 struct ast_party_connected_line *ast_channel_connected(struct ast_channel *chan)
01017 {
01018    return &chan->connected;
01019 }
01020 struct ast_party_connected_line *ast_channel_connected_indicated(struct ast_channel *chan)
01021 {
01022    return &chan->connected_indicated;
01023 }
01024 struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
01025 {
01026    return ast_party_id_merge(&chan->connected.id, &chan->connected.priv);
01027 }
01028 struct ast_party_dialed *ast_channel_dialed(struct ast_channel *chan)
01029 {
01030    return &chan->dialed;
01031 }
01032 struct ast_party_redirecting *ast_channel_redirecting(struct ast_channel *chan)
01033 {
01034    return &chan->redirecting;
01035 }
01036 struct ast_party_id ast_channel_redirecting_effective_orig(struct ast_channel *chan)
01037 {
01038    return ast_party_id_merge(&chan->redirecting.orig, &chan->redirecting.priv_orig);
01039 }
01040 struct ast_party_id ast_channel_redirecting_effective_from(struct ast_channel *chan)
01041 {
01042    return ast_party_id_merge(&chan->redirecting.from, &chan->redirecting.priv_from);
01043 }
01044 struct ast_party_id ast_channel_redirecting_effective_to(struct ast_channel *chan)
01045 {
01046    return ast_party_id_merge(&chan->redirecting.to, &chan->redirecting.priv_to);
01047 }
01048 struct timeval *ast_channel_dtmf_tv(struct ast_channel *chan)
01049 {
01050    return &chan->dtmf_tv;
01051 }
01052 struct timeval *ast_channel_whentohangup(struct ast_channel *chan)
01053 {
01054    return &chan->whentohangup;
01055 }
01056 struct varshead *ast_channel_varshead(struct ast_channel *chan)
01057 {
01058    return &chan->varshead;
01059 }
01060 void ast_channel_dtmff_set(struct ast_channel *chan, struct ast_frame *value)
01061 {
01062    chan->dtmff = *value;
01063 }
01064 void ast_channel_jb_set(struct ast_channel *chan, struct ast_jb *value)
01065 {
01066    chan->jb = *value;
01067 }
01068 void ast_channel_caller_set(struct ast_channel *chan, struct ast_party_caller *value)
01069 {
01070    chan->caller = *value;
01071 }
01072 void ast_channel_connected_set(struct ast_channel *chan, struct ast_party_connected_line *value)
01073 {
01074    chan->connected = *value;
01075 }
01076 void ast_channel_dialed_set(struct ast_channel *chan, struct ast_party_dialed *value)
01077 {
01078    chan->dialed = *value;
01079 }
01080 void ast_channel_redirecting_set(struct ast_channel *chan, struct ast_party_redirecting *value)
01081 {
01082    chan->redirecting = *value;
01083 }
01084 void ast_channel_dtmf_tv_set(struct ast_channel *chan, struct timeval *value)
01085 {
01086    chan->dtmf_tv = *value;
01087 }
01088 void ast_channel_whentohangup_set(struct ast_channel *chan, struct timeval *value)
01089 {
01090    chan->whentohangup = *value;
01091 }
01092 void ast_channel_varshead_set(struct ast_channel *chan, struct varshead *value)
01093 {
01094    chan->varshead = *value;
01095 }
01096 struct timeval ast_channel_creationtime(struct ast_channel *chan)
01097 {
01098    return chan->creationtime;
01099 }
01100 void ast_channel_creationtime_set(struct ast_channel *chan, struct timeval *value)
01101 {
01102    chan->creationtime = *value;
01103 }
01104 
01105 struct timeval ast_channel_answertime(struct ast_channel *chan)
01106 {
01107    return chan->answertime;
01108 }
01109 
01110 void ast_channel_answertime_set(struct ast_channel *chan, struct timeval *value)
01111 {
01112    chan->answertime = *value;
01113 }
01114 
01115 /* Evil softhangup accessors */
01116 int ast_channel_softhangup_internal_flag(struct ast_channel *chan)
01117 {
01118    return chan->softhangup;
01119 }
01120 void ast_channel_softhangup_internal_flag_set(struct ast_channel *chan, int value)
01121 {
01122    chan->softhangup = value;
01123 }
01124 void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value)
01125 {
01126    chan->softhangup |= value;
01127 }
01128 void ast_channel_softhangup_internal_flag_clear(struct ast_channel *chan, int value)
01129 {
01130    chan ->softhangup &= ~value;
01131 }
01132 
01133 int ast_channel_unbridged_nolock(struct ast_channel *chan)
01134 {
01135    return chan->unbridged;
01136 }
01137 
01138 int ast_channel_unbridged(struct ast_channel *chan)
01139 {
01140    int res;
01141    ast_channel_lock(chan);
01142    res = ast_channel_unbridged_nolock(chan);
01143    ast_channel_unlock(chan);
01144    return res;
01145 }
01146 
01147 void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value)
01148 {
01149    chan->unbridged = value;
01150    ast_queue_frame(chan, &ast_null_frame);
01151 }
01152 
01153 void ast_channel_set_unbridged(struct ast_channel *chan, int value)
01154 {
01155    ast_channel_lock(chan);
01156    ast_channel_set_unbridged_nolock(chan, value);
01157    ast_channel_unlock(chan);
01158 }
01159 
01160 void ast_channel_callid_cleanup(struct ast_channel *chan)
01161 {
01162    chan->callid = 0;
01163 }
01164 
01165 /* Typedef accessors */
01166 ast_group_t ast_channel_callgroup(const struct ast_channel *chan)
01167 {
01168    return chan->callgroup;
01169 }
01170 void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
01171 {
01172    chan->callgroup = value;
01173 }
01174 ast_group_t ast_channel_pickupgroup(const struct ast_channel *chan)
01175 {
01176    return chan->pickupgroup;
01177 }
01178 void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
01179 {
01180    chan->pickupgroup = value;
01181 }
01182 struct ast_namedgroups *ast_channel_named_callgroups(const struct ast_channel *chan)
01183 {
01184    return chan->named_callgroups;
01185 }
01186 void ast_channel_named_callgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
01187 {
01188    ast_unref_namedgroups(chan->named_callgroups);
01189    chan->named_callgroups = ast_ref_namedgroups(value);
01190 }
01191 struct ast_namedgroups *ast_channel_named_pickupgroups(const struct ast_channel *chan)
01192 {
01193    return chan->named_pickupgroups;
01194 }
01195 void ast_channel_named_pickupgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
01196 {
01197    ast_unref_namedgroups(chan->named_pickupgroups);
01198    chan->named_pickupgroups = ast_ref_namedgroups(value);
01199 }
01200 
01201 /* Alertpipe functions */
01202 int ast_channel_alert_write(struct ast_channel *chan)
01203 {
01204    char blah = 0x7F;
01205    return ast_channel_alert_writable(chan) && write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah);
01206 }
01207 
01208 ast_alert_status_t ast_channel_internal_alert_read(struct ast_channel *chan)
01209 {
01210    int flags;
01211    char blah;
01212 
01213    if (!ast_channel_internal_alert_readable(chan)) {
01214       return AST_ALERT_NOT_READABLE;
01215    }
01216 
01217    flags = fcntl(chan->alertpipe[0], F_GETFL);
01218    /* For some odd reason, the alertpipe occasionally loses nonblocking status,
01219     * which immediately causes a deadlock scenario.  Detect and prevent this. */
01220    if ((flags & O_NONBLOCK) == 0) {
01221       ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", ast_channel_name(chan));
01222       if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
01223          ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
01224          return AST_ALERT_READ_FATAL;
01225       }
01226    }
01227    if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) {
01228       if (errno != EINTR && errno != EAGAIN) {
01229          ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
01230          return AST_ALERT_READ_FAIL;
01231       }
01232    }
01233 
01234    return AST_ALERT_READ_SUCCESS;
01235 }
01236 
01237 int ast_channel_alert_writable(struct ast_channel *chan)
01238 {
01239    return chan->alertpipe[1] > -1;
01240 }
01241 
01242 int ast_channel_internal_alert_readable(struct ast_channel *chan)
01243 {
01244    return chan->alertpipe[0] > -1;
01245 }
01246 
01247 void ast_channel_internal_alertpipe_clear(struct ast_channel *chan)
01248 {
01249    chan->alertpipe[0] = chan->alertpipe[1] = -1;
01250 }
01251 
01252 void ast_channel_internal_alertpipe_close(struct ast_channel *chan)
01253 {
01254    if (ast_channel_internal_alert_readable(chan)) {
01255       close(chan->alertpipe[0]);
01256    }
01257    if (ast_channel_alert_writable(chan)) {
01258       close(chan->alertpipe[1]);
01259    }
01260 }
01261 
01262 int ast_channel_internal_alertpipe_init(struct ast_channel *chan)
01263 {
01264    if (pipe(chan->alertpipe)) {
01265       ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe! Try increasing max file descriptors with ulimit -n\n");
01266       return -1;
01267    } else {
01268       int flags = fcntl(chan->alertpipe[0], F_GETFL);
01269       if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
01270          ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
01271          return -1;
01272       }
01273       flags = fcntl(chan->alertpipe[1], F_GETFL);
01274       if (fcntl(chan->alertpipe[1], F_SETFL, flags | O_NONBLOCK) < 0) {
01275          ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
01276          return -1;
01277       }
01278    }
01279    return 0;
01280 }
01281 
01282 int ast_channel_internal_alert_readfd(struct ast_channel *chan)
01283 {
01284    return chan->alertpipe[0];
01285 }
01286 
01287 void ast_channel_internal_alertpipe_swap(struct ast_channel *chan1, struct ast_channel *chan2)
01288 {
01289    int i;
01290    for (i = 0; i < ARRAY_LEN(chan1->alertpipe); i++) {
01291       SWAP(chan1->alertpipe[i], chan2->alertpipe[i]);
01292    }
01293 }
01294 
01295 /* file descriptor array accessors */
01296 void ast_channel_internal_fd_set(struct ast_channel *chan, int which, int value)
01297 {
01298    chan->fds[which] = value;
01299 }
01300 void ast_channel_internal_fd_clear(struct ast_channel *chan, int which)
01301 {
01302    ast_channel_internal_fd_set(chan, which, -1);
01303 }
01304 void ast_channel_internal_fd_clear_all(struct ast_channel *chan)
01305 {
01306    int i;
01307    for (i = 0; i < AST_MAX_FDS; i++) {
01308       ast_channel_internal_fd_clear(chan, i);
01309    }
01310 }
01311 int ast_channel_fd(const struct ast_channel *chan, int which)
01312 {
01313    return chan->fds[which];
01314 }
01315 int ast_channel_fd_isset(const struct ast_channel *chan, int which)
01316 {
01317    return ast_channel_fd(chan, which) > -1;
01318 }
01319 
01320 #ifdef HAVE_EPOLL
01321 struct ast_epoll_data *ast_channel_internal_epfd_data(const struct ast_channel *chan, int which)
01322 {
01323    return chan->epfd_data[which];
01324 }
01325 void ast_channel_internal_epfd_data_set(struct ast_channel *chan, int which , struct ast_epoll_data *value)
01326 {
01327    chan->epfd_data[which] = value;
01328 }
01329 #endif
01330 
01331 pthread_t ast_channel_blocker(const struct ast_channel *chan)
01332 {
01333    return chan->blocker;
01334 }
01335 void ast_channel_blocker_set(struct ast_channel *chan, pthread_t value)
01336 {
01337    chan->blocker = value;
01338 }
01339 
01340 ast_timing_func_t ast_channel_timingfunc(const struct ast_channel *chan)
01341 {
01342    return chan->timingfunc;
01343 }
01344 void ast_channel_timingfunc_set(struct ast_channel *chan, ast_timing_func_t value)
01345 {
01346    chan->timingfunc = value;
01347 }
01348 
01349 struct ast_bridge *ast_channel_internal_bridge(const struct ast_channel *chan)
01350 {
01351    return chan->bridge;
01352 }
01353 void ast_channel_internal_bridge_set(struct ast_channel *chan, struct ast_bridge *value)
01354 {
01355    chan->bridge = value;
01356    ast_channel_publish_snapshot(chan);
01357 }
01358 
01359 struct ast_bridge_channel *ast_channel_internal_bridge_channel(const struct ast_channel *chan)
01360 {
01361    return chan->bridge_channel;
01362 }
01363 void ast_channel_internal_bridge_channel_set(struct ast_channel *chan, struct ast_bridge_channel *value)
01364 {
01365    chan->bridge_channel = value;
01366 }
01367 
01368 struct ast_flags *ast_channel_flags(struct ast_channel *chan)
01369 {
01370    return &chan->flags;
01371 }
01372 
01373 static int collect_names_cb(void *obj, void *arg, int flags) {
01374    struct ast_control_pvt_cause_code *cause_code = obj;
01375    struct ast_str **str = arg;
01376 
01377    ast_str_append(str, 0, "%s%s", (ast_str_strlen(*str) ? "," : ""), cause_code->chan_name);
01378 
01379    return 0;
01380 }
01381 
01382 struct ast_str *ast_channel_dialed_causes_channels(const struct ast_channel *chan)
01383 {
01384    struct ast_str *chanlist = ast_str_create(128);
01385 
01386    if (!chanlist) {
01387       return NULL;
01388    }
01389 
01390    ao2_callback(chan->dialed_causes, 0, collect_names_cb, &chanlist);
01391 
01392    return chanlist;
01393 }
01394 
01395 struct ast_control_pvt_cause_code *ast_channel_dialed_causes_find(const struct ast_channel *chan, const char *chan_name)
01396 {
01397    return ao2_find(chan->dialed_causes, chan_name, OBJ_KEY);
01398 }
01399 
01400 int ast_channel_dialed_causes_add(const struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
01401 {
01402    struct ast_control_pvt_cause_code *ao2_cause_code;
01403    ao2_find(chan->dialed_causes, cause_code->chan_name, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA);
01404    ao2_cause_code = ao2_alloc(datalen, NULL);
01405 
01406    if (ao2_cause_code) {
01407       memcpy(ao2_cause_code, cause_code, datalen);
01408       ao2_link(chan->dialed_causes, ao2_cause_code);
01409       ao2_ref(ao2_cause_code, -1);
01410       return 0;
01411    } else {
01412       return -1;
01413    }
01414 }
01415 
01416 void ast_channel_dialed_causes_clear(const struct ast_channel *chan)
01417 {
01418    ao2_callback(chan->dialed_causes, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
01419 }
01420 
01421 /* \brief Hash function for pvt cause code frames */
01422 static int pvt_cause_hash_fn(const void *vpc, const int flags)
01423 {
01424    const struct ast_control_pvt_cause_code *pc = vpc;
01425    return ast_str_hash(ast_tech_to_upper(ast_strdupa(pc->chan_name)));
01426 }
01427 
01428 /* \brief Comparison function for pvt cause code frames */
01429 static int pvt_cause_cmp_fn(void *obj, void *vstr, int flags)
01430 {
01431    struct ast_control_pvt_cause_code *pc = obj;
01432    char *str = ast_tech_to_upper(ast_strdupa(vstr));
01433    char *pc_str = ast_tech_to_upper(ast_strdupa(pc->chan_name));
01434    return !strcmp(pc_str, str) ? CMP_MATCH | CMP_STOP : 0;
01435 }
01436 
01437 #define DIALED_CAUSES_BUCKETS 37
01438 
01439 struct ast_channel *__ast_channel_internal_alloc(void (*destructor)(void *obj), const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *file, int line, const char *function)
01440 {
01441    struct ast_channel *tmp;
01442 #if defined(REF_DEBUG)
01443    tmp = __ao2_alloc_debug(sizeof(*tmp), destructor,
01444       AO2_ALLOC_OPT_LOCK_MUTEX, "", file, line, function, 1);
01445 #elif defined(__AST_DEBUG_MALLOC)
01446    tmp = __ao2_alloc_debug(sizeof(*tmp), destructor,
01447       AO2_ALLOC_OPT_LOCK_MUTEX, "", file, line, function, 0);
01448 #else
01449    tmp = ao2_alloc(sizeof(*tmp), destructor);
01450 #endif
01451 
01452    if ((ast_string_field_init(tmp, 128))) {
01453       return ast_channel_unref(tmp);
01454    }
01455 
01456    if (!(tmp->dialed_causes = ao2_container_alloc(DIALED_CAUSES_BUCKETS, pvt_cause_hash_fn, pvt_cause_cmp_fn))) {
01457       return ast_channel_unref(tmp);
01458    }
01459 
01460    /* set the creation time in the uniqueid */
01461    tmp->uniqueid.creation_time = time(NULL);
01462    tmp->uniqueid.creation_unique = ast_atomic_fetchadd_int(&uniqueint, 1);
01463 
01464    /* use provided id or default to historical {system-}time.# format */
01465    if (assignedids && !ast_strlen_zero(assignedids->uniqueid)) {
01466       ast_copy_string(tmp->uniqueid.unique_id, assignedids->uniqueid, sizeof(tmp->uniqueid.unique_id));
01467    } else if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
01468       snprintf(tmp->uniqueid.unique_id, sizeof(tmp->uniqueid.unique_id), "%li.%d",
01469          (long)(tmp->uniqueid.creation_time),
01470          tmp->uniqueid.creation_unique);
01471    } else {
01472       snprintf(tmp->uniqueid.unique_id, sizeof(tmp->uniqueid.unique_id), "%s-%li.%d",
01473          ast_config_AST_SYSTEM_NAME,
01474          (long)(tmp->uniqueid.creation_time),
01475          tmp->uniqueid.creation_unique);
01476    }
01477 
01478    /* copy linked id from parent channel if known */
01479    if (requestor) {
01480       tmp->linkedid = requestor->linkedid;
01481    } else {
01482       tmp->linkedid = tmp->uniqueid;
01483    }
01484 
01485    return tmp;
01486 }
01487 
01488 struct ast_channel *ast_channel_internal_oldest_linkedid(struct ast_channel *a, struct ast_channel *b)
01489 {
01490    ast_assert(a->linkedid.creation_time != 0);
01491    ast_assert(b->linkedid.creation_time != 0);
01492 
01493    if (a->linkedid.creation_time < b->linkedid.creation_time) {
01494       return a;
01495    }
01496    if (b->linkedid.creation_time < a->linkedid.creation_time) {
01497       return b;
01498    }
01499    if (a->linkedid.creation_unique < b->linkedid.creation_unique) {
01500       return a;
01501    }
01502    return b;
01503 }
01504 
01505 void ast_channel_internal_copy_linkedid(struct ast_channel *dest, struct ast_channel *source)
01506 {
01507    if (dest->linkedid.creation_time == source->linkedid.creation_time
01508       && dest->linkedid.creation_unique == source->linkedid.creation_unique
01509       && !strcmp(dest->linkedid.unique_id, source->linkedid.unique_id)) {
01510       return;
01511    }
01512    dest->linkedid = source->linkedid;
01513    ast_channel_publish_snapshot(dest);
01514 }
01515 
01516 void ast_channel_internal_swap_uniqueid_and_linkedid(struct ast_channel *a, struct ast_channel *b)
01517 {
01518    struct ast_channel_id temp;
01519 
01520    temp = a->uniqueid;
01521    a->uniqueid = b->uniqueid;
01522    b->uniqueid = temp;
01523 
01524    temp = a->linkedid;
01525    a->linkedid = b->linkedid;
01526    b->linkedid = temp;
01527 }
01528 
01529 void ast_channel_internal_swap_topics(struct ast_channel *a, struct ast_channel *b)
01530 {
01531    struct stasis_cp_single *temp;
01532 
01533    temp = a->topics;
01534    a->topics = b->topics;
01535    b->topics = temp;
01536 }
01537 
01538 void ast_channel_internal_set_fake_ids(struct ast_channel *chan, const char *uniqueid, const char *linkedid)
01539 {
01540    ast_copy_string(chan->uniqueid.unique_id, uniqueid, sizeof(chan->uniqueid.unique_id));
01541    ast_copy_string(chan->linkedid.unique_id, linkedid, sizeof(chan->linkedid.unique_id));
01542 }
01543 
01544 void ast_channel_internal_cleanup(struct ast_channel *chan)
01545 {
01546    if (chan->dialed_causes) {
01547       ao2_t_ref(chan->dialed_causes, -1,
01548          "done with dialed causes since the channel is going away");
01549       chan->dialed_causes = NULL;
01550    }
01551 
01552    ast_string_field_free_memory(chan);
01553 
01554    chan->endpoint_forward = stasis_forward_cancel(chan->endpoint_forward);
01555    chan->endpoint_cache_forward = stasis_forward_cancel(chan->endpoint_cache_forward);
01556 
01557    stasis_cp_single_unsubscribe(chan->topics);
01558    chan->topics = NULL;
01559 }
01560 
01561 void ast_channel_internal_finalize(struct ast_channel *chan)
01562 {
01563    chan->finalized = 1;
01564 }
01565 
01566 int ast_channel_internal_is_finalized(struct ast_channel *chan)
01567 {
01568    return chan->finalized;
01569 }
01570 
01571 struct stasis_topic *ast_channel_topic(struct ast_channel *chan)
01572 {
01573    if (!chan) {
01574       return ast_channel_topic_all();
01575    }
01576 
01577    return stasis_cp_single_topic(chan->topics);
01578 }
01579 
01580 struct stasis_topic *ast_channel_topic_cached(struct ast_channel *chan)
01581 {
01582    if (!chan) {
01583       return ast_channel_topic_all_cached();
01584    }
01585 
01586    return stasis_cp_single_topic_cached(chan->topics);
01587 }
01588 
01589 int ast_channel_forward_endpoint(struct ast_channel *chan,
01590    struct ast_endpoint *endpoint)
01591 {
01592    ast_assert(chan != NULL);
01593    ast_assert(endpoint != NULL);
01594 
01595    chan->endpoint_forward =
01596       stasis_forward_all(ast_channel_topic(chan),
01597          ast_endpoint_topic(endpoint));
01598    if (!chan->endpoint_forward) {
01599       return -1;
01600    }
01601 
01602    chan->endpoint_cache_forward = stasis_forward_all(ast_channel_topic_cached(chan),
01603       ast_endpoint_topic(endpoint));
01604    if (!chan->endpoint_cache_forward) {
01605       chan->endpoint_forward = stasis_forward_cancel(chan->endpoint_forward);
01606       return -1;
01607    }
01608 
01609    return 0;
01610 }
01611 
01612 int ast_channel_internal_setup_topics(struct ast_channel *chan)
01613 {
01614    const char *topic_name = chan->uniqueid.unique_id;
01615    ast_assert(chan->topics == NULL);
01616 
01617    if (ast_strlen_zero(topic_name)) {
01618       topic_name = "<dummy-channel>";
01619    }
01620 
01621    chan->topics = stasis_cp_single_create(
01622       ast_channel_cache_all(), topic_name);
01623    if (!chan->topics) {
01624       return -1;
01625    }
01626 
01627    return 0;
01628 }

Generated on Thu Apr 16 06:27:30 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6