00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 struct ast_channel {
00060 const struct ast_channel_tech *tech;
00061 void *tech_pvt;
00062 void *music_state;
00063 void *generatordata;
00064 struct ast_generator *generator;
00065 struct ast_channel * bridged_channel;
00066
00067
00068 struct ast_channel *masq;
00069 struct ast_channel *masqr;
00070 const char *blockproc;
00071 const char *appl;
00072 const char *data;
00073 struct ast_sched_context *sched;
00074 struct ast_filestream *stream;
00075 struct ast_filestream *vstream;
00076 ast_timing_func_t timingfunc;
00077 void *timingdata;
00078 struct ast_pbx *pbx;
00079 struct ast_trans_pvt *writetrans;
00080 struct ast_trans_pvt *readtrans;
00081 struct ast_audiohook_list *audiohooks;
00082 struct ast_framehook_list *framehooks;
00083 struct ast_cdr *cdr;
00084 struct ast_tone_zone *zone;
00085
00086 struct ast_channel_monitor *monitor;
00087 struct ast_callid *callid;
00088 #ifdef HAVE_EPOLL
00089 struct ast_epoll_data *epfd_data[AST_MAX_FDS];
00090 #endif
00091 struct ao2_container *dialed_causes;
00092
00093 AST_DECLARE_STRING_FIELDS(
00094 AST_STRING_FIELD(name);
00095 AST_STRING_FIELD(language);
00096 AST_STRING_FIELD(musicclass);
00097 AST_STRING_FIELD(accountcode);
00098 AST_STRING_FIELD(peeraccount);
00099 AST_STRING_FIELD(userfield);
00100 AST_STRING_FIELD(call_forward);
00101 AST_STRING_FIELD(uniqueid);
00102 AST_STRING_FIELD(linkedid);
00103 AST_STRING_FIELD(parkinglot);
00104 AST_STRING_FIELD(hangupsource);
00105 AST_STRING_FIELD(dialcontext);
00106 );
00107
00108 struct timeval whentohangup;
00109 pthread_t blocker;
00110
00111
00112
00113
00114
00115
00116 struct ast_party_dialed dialed;
00117
00118
00119
00120
00121
00122
00123 struct ast_party_caller caller;
00124
00125
00126
00127
00128
00129
00130 struct ast_party_connected_line connected;
00131
00132
00133 struct ast_party_redirecting redirecting;
00134
00135 struct ast_frame dtmff;
00136 struct varshead varshead;
00137 ast_group_t callgroup;
00138 ast_group_t pickupgroup;
00139 struct ast_namedgroups *named_callgroups;
00140 struct ast_namedgroups *named_pickupgroups;
00141 struct timeval creationtime;
00142 struct ast_readq_list readq;
00143 struct ast_jb jb;
00144 struct timeval dtmf_tv;
00145 struct ast_hangup_handler_list hangup_handlers;
00146 struct ast_datastore_list datastores;
00147 struct ast_autochan_list autochans;
00148 unsigned long insmpl;
00149 unsigned long outsmpl;
00150
00151 int fds[AST_MAX_FDS];
00152
00153
00154 int softhangup;
00155
00156 int fdno;
00157 int streamid;
00158 int vstreamid;
00159 struct ast_format oldwriteformat;
00160 int timingfd;
00161 enum ast_channel_state state;
00162 int rings;
00163 int priority;
00164 int macropriority;
00165 int amaflags;
00166 enum ast_channel_adsicpe adsicpe;
00167 unsigned int fin;
00168
00169 unsigned int fout;
00170
00171 int hangupcause;
00172 unsigned int finalized:1;
00173 struct ast_flags flags;
00174 int alertpipe[2];
00175 struct ast_format_cap *nativeformats;
00176 struct ast_format readformat;
00177 struct ast_format writeformat;
00178 struct ast_format rawreadformat;
00179 struct ast_format rawwriteformat;
00180 unsigned int emulate_dtmf_duration;
00181 #ifdef HAVE_EPOLL
00182 int epfd;
00183 #endif
00184 int visible_indication;
00185
00186 unsigned short transfercapability;
00187
00188 struct ast_bridge *bridge;
00189 struct ast_timer *timer;
00190
00191 char context[AST_MAX_CONTEXT];
00192 char exten[AST_MAX_EXTENSION];
00193 char macrocontext[AST_MAX_CONTEXT];
00194 char macroexten[AST_MAX_EXTENSION];
00195 char dtmf_digit_to_emulate;
00196 char sending_dtmf_digit;
00197 struct timeval sending_dtmf_tv;
00198 };
00199
00200
00201
00202 #if 0
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
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
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
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
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
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
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
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
00363
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
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
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
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
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
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
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
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
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
01115
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
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
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
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 }