Sat Apr 26 2014 22:01:35

Asterisk developer's documentation


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