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 #include "asterisk.h"
00031
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 408642 $")
00033
00034 #include "asterisk/_private.h"
00035
00036 #include <sys/time.h>
00037 #include <signal.h>
00038 #include <math.h>
00039
00040 #include "asterisk/paths.h"
00041
00042 #include "asterisk/pbx.h"
00043 #include "asterisk/frame.h"
00044 #include "asterisk/mod_format.h"
00045 #include "asterisk/sched.h"
00046 #include "asterisk/channel.h"
00047 #include "asterisk/musiconhold.h"
00048 #include "asterisk/say.h"
00049 #include "asterisk/file.h"
00050 #include "asterisk/cli.h"
00051 #include "asterisk/translate.h"
00052 #include "asterisk/manager.h"
00053 #include "asterisk/cel.h"
00054 #include "asterisk/chanvars.h"
00055 #include "asterisk/linkedlists.h"
00056 #include "asterisk/indications.h"
00057 #include "asterisk/monitor.h"
00058 #include "asterisk/causes.h"
00059 #include "asterisk/callerid.h"
00060 #include "asterisk/utils.h"
00061 #include "asterisk/lock.h"
00062 #include "asterisk/app.h"
00063 #include "asterisk/transcap.h"
00064 #include "asterisk/devicestate.h"
00065 #include "asterisk/threadstorage.h"
00066 #include "asterisk/slinfactory.h"
00067 #include "asterisk/audiohook.h"
00068 #include "asterisk/framehook.h"
00069 #include "asterisk/timing.h"
00070 #include "asterisk/autochan.h"
00071 #include "asterisk/stringfields.h"
00072 #include "asterisk/global_datastores.h"
00073 #include "asterisk/data.h"
00074 #include "asterisk/features.h"
00075 #include "asterisk/test.h"
00076
00077 #ifdef HAVE_EPOLL
00078 #include <sys/epoll.h>
00079 #endif
00080
00081 #if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
00082 #if defined(HAVE_PRI)
00083 #include "libpri.h"
00084 #endif
00085 #endif
00086
00087 struct ast_epoll_data {
00088 struct ast_channel *chan;
00089 int which;
00090 };
00091
00092
00093 #if 0
00094 #define MONITOR_CONSTANT_DELAY
00095 #define MONITOR_DELAY 150 * 8
00096 #endif
00097
00098
00099 static int shutting_down;
00100
00101 static int uniqueint;
00102 static int chancount;
00103
00104 unsigned long global_fin, global_fout;
00105
00106 AST_THREADSTORAGE(state2str_threadbuf);
00107 #define STATE2STR_BUFSIZE 32
00108
00109
00110
00111 #define AST_DEFAULT_EMULATE_DTMF_DURATION 100
00112
00113
00114 #define AST_MIN_DTMF_DURATION 80
00115
00116
00117
00118 #define AST_MIN_DTMF_GAP 45
00119
00120
00121 struct chanlist {
00122 const struct ast_channel_tech *tech;
00123 AST_LIST_ENTRY(chanlist) list;
00124 };
00125
00126 #ifdef CHANNEL_TRACE
00127
00128 struct ast_chan_trace_data {
00129 int enabled;
00130 AST_LIST_HEAD_NOLOCK(, ast_chan_trace) trace;
00131 };
00132
00133
00134 struct ast_chan_trace {
00135 char context[AST_MAX_CONTEXT];
00136 char exten[AST_MAX_EXTENSION];
00137 int priority;
00138 AST_LIST_ENTRY(ast_chan_trace) entry;
00139 };
00140 #endif
00141
00142
00143 static AST_RWLIST_HEAD_STATIC(backends, chanlist);
00144
00145 #ifdef LOW_MEMORY
00146 #define NUM_CHANNEL_BUCKETS 61
00147 #else
00148 #define NUM_CHANNEL_BUCKETS 1567
00149 #endif
00150
00151 #if 0
00152 #define DATA_EXPORT_CALLERID(MEMBER) \
00153 MEMBER(ast_callerid, cid_dnid, AST_DATA_STRING) \
00154 MEMBER(ast_callerid, cid_num, AST_DATA_STRING) \
00155 MEMBER(ast_callerid, cid_name, AST_DATA_STRING) \
00156 MEMBER(ast_callerid, cid_ani, AST_DATA_STRING) \
00157 MEMBER(ast_callerid, cid_pres, AST_DATA_INTEGER) \
00158 MEMBER(ast_callerid, cid_ani2, AST_DATA_INTEGER) \
00159 MEMBER(ast_callerid, cid_tag, AST_DATA_STRING)
00160
00161 AST_DATA_STRUCTURE(ast_callerid, DATA_EXPORT_CALLERID);
00162 #endif
00163
00164 #define DATA_EXPORT_CHANNEL(MEMBER) \
00165 MEMBER(ast_channel, blockproc, AST_DATA_STRING) \
00166 MEMBER(ast_channel, appl, AST_DATA_STRING) \
00167 MEMBER(ast_channel, data, AST_DATA_STRING) \
00168 MEMBER(ast_channel, name, AST_DATA_STRING) \
00169 MEMBER(ast_channel, language, AST_DATA_STRING) \
00170 MEMBER(ast_channel, musicclass, AST_DATA_STRING) \
00171 MEMBER(ast_channel, accountcode, AST_DATA_STRING) \
00172 MEMBER(ast_channel, peeraccount, AST_DATA_STRING) \
00173 MEMBER(ast_channel, userfield, AST_DATA_STRING) \
00174 MEMBER(ast_channel, call_forward, AST_DATA_STRING) \
00175 MEMBER(ast_channel, uniqueid, AST_DATA_STRING) \
00176 MEMBER(ast_channel, linkedid, AST_DATA_STRING) \
00177 MEMBER(ast_channel, parkinglot, AST_DATA_STRING) \
00178 MEMBER(ast_channel, hangupsource, AST_DATA_STRING) \
00179 MEMBER(ast_channel, dialcontext, AST_DATA_STRING) \
00180 MEMBER(ast_channel, rings, AST_DATA_INTEGER) \
00181 MEMBER(ast_channel, priority, AST_DATA_INTEGER) \
00182 MEMBER(ast_channel, macropriority, AST_DATA_INTEGER) \
00183 MEMBER(ast_channel, adsicpe, AST_DATA_INTEGER) \
00184 MEMBER(ast_channel, fin, AST_DATA_UNSIGNED_INTEGER) \
00185 MEMBER(ast_channel, fout, AST_DATA_UNSIGNED_INTEGER) \
00186 MEMBER(ast_channel, emulate_dtmf_duration, AST_DATA_UNSIGNED_INTEGER) \
00187 MEMBER(ast_channel, visible_indication, AST_DATA_INTEGER) \
00188 MEMBER(ast_channel, context, AST_DATA_STRING) \
00189 MEMBER(ast_channel, exten, AST_DATA_STRING) \
00190 MEMBER(ast_channel, macrocontext, AST_DATA_STRING) \
00191 MEMBER(ast_channel, macroexten, AST_DATA_STRING)
00192
00193 AST_DATA_STRUCTURE(ast_channel, DATA_EXPORT_CHANNEL);
00194
00195
00196
00197 static struct ao2_container *channels;
00198
00199
00200
00201
00202
00203 struct causes_map {
00204 int cause;
00205 const char *name;
00206 const char *desc;
00207 };
00208
00209 static const struct causes_map causes[] = {
00210 { AST_CAUSE_UNALLOCATED, "UNALLOCATED", "Unallocated (unassigned) number" },
00211 { AST_CAUSE_NO_ROUTE_TRANSIT_NET, "NO_ROUTE_TRANSIT_NET", "No route to specified transmit network" },
00212 { AST_CAUSE_NO_ROUTE_DESTINATION, "NO_ROUTE_DESTINATION", "No route to destination" },
00213 { AST_CAUSE_MISDIALLED_TRUNK_PREFIX, "MISDIALLED_TRUNK_PREFIX", "Misdialed trunk prefix" },
00214 { AST_CAUSE_CHANNEL_UNACCEPTABLE, "CHANNEL_UNACCEPTABLE", "Channel unacceptable" },
00215 { AST_CAUSE_CALL_AWARDED_DELIVERED, "CALL_AWARDED_DELIVERED", "Call awarded and being delivered in an established channel" },
00216 { AST_CAUSE_PRE_EMPTED, "PRE_EMPTED", "Pre-empted" },
00217 { AST_CAUSE_NUMBER_PORTED_NOT_HERE, "NUMBER_PORTED_NOT_HERE", "Number ported elsewhere" },
00218 { AST_CAUSE_NORMAL_CLEARING, "NORMAL_CLEARING", "Normal Clearing" },
00219 { AST_CAUSE_USER_BUSY, "USER_BUSY", "User busy" },
00220 { AST_CAUSE_NO_USER_RESPONSE, "NO_USER_RESPONSE", "No user responding" },
00221 { AST_CAUSE_NO_ANSWER, "NO_ANSWER", "User alerting, no answer" },
00222 { AST_CAUSE_SUBSCRIBER_ABSENT, "SUBSCRIBER_ABSENT", "Subscriber absent" },
00223 { AST_CAUSE_CALL_REJECTED, "CALL_REJECTED", "Call Rejected" },
00224 { AST_CAUSE_NUMBER_CHANGED, "NUMBER_CHANGED", "Number changed" },
00225 { AST_CAUSE_REDIRECTED_TO_NEW_DESTINATION, "REDIRECTED_TO_NEW_DESTINATION", "Redirected to new destination" },
00226 { AST_CAUSE_ANSWERED_ELSEWHERE, "ANSWERED_ELSEWHERE", "Answered elsewhere" },
00227 { AST_CAUSE_DESTINATION_OUT_OF_ORDER, "DESTINATION_OUT_OF_ORDER", "Destination out of order" },
00228 { AST_CAUSE_INVALID_NUMBER_FORMAT, "INVALID_NUMBER_FORMAT", "Invalid number format" },
00229 { AST_CAUSE_FACILITY_REJECTED, "FACILITY_REJECTED", "Facility rejected" },
00230 { AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY, "RESPONSE_TO_STATUS_ENQUIRY", "Response to STATus ENQuiry" },
00231 { AST_CAUSE_NORMAL_UNSPECIFIED, "NORMAL_UNSPECIFIED", "Normal, unspecified" },
00232 { AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, "NORMAL_CIRCUIT_CONGESTION", "Circuit/channel congestion" },
00233 { AST_CAUSE_NETWORK_OUT_OF_ORDER, "NETWORK_OUT_OF_ORDER", "Network out of order" },
00234 { AST_CAUSE_NORMAL_TEMPORARY_FAILURE, "NORMAL_TEMPORARY_FAILURE", "Temporary failure" },
00235 { AST_CAUSE_SWITCH_CONGESTION, "SWITCH_CONGESTION", "Switching equipment congestion" },
00236 { AST_CAUSE_ACCESS_INFO_DISCARDED, "ACCESS_INFO_DISCARDED", "Access information discarded" },
00237 { AST_CAUSE_REQUESTED_CHAN_UNAVAIL, "REQUESTED_CHAN_UNAVAIL", "Requested channel not available" },
00238 { AST_CAUSE_FACILITY_NOT_SUBSCRIBED, "FACILITY_NOT_SUBSCRIBED", "Facility not subscribed" },
00239 { AST_CAUSE_OUTGOING_CALL_BARRED, "OUTGOING_CALL_BARRED", "Outgoing call barred" },
00240 { AST_CAUSE_INCOMING_CALL_BARRED, "INCOMING_CALL_BARRED", "Incoming call barred" },
00241 { AST_CAUSE_BEARERCAPABILITY_NOTAUTH, "BEARERCAPABILITY_NOTAUTH", "Bearer capability not authorized" },
00242 { AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, "BEARERCAPABILITY_NOTAVAIL", "Bearer capability not available" },
00243 { AST_CAUSE_BEARERCAPABILITY_NOTIMPL, "BEARERCAPABILITY_NOTIMPL", "Bearer capability not implemented" },
00244 { AST_CAUSE_CHAN_NOT_IMPLEMENTED, "CHAN_NOT_IMPLEMENTED", "Channel not implemented" },
00245 { AST_CAUSE_FACILITY_NOT_IMPLEMENTED, "FACILITY_NOT_IMPLEMENTED", "Facility not implemented" },
00246 { AST_CAUSE_INVALID_CALL_REFERENCE, "INVALID_CALL_REFERENCE", "Invalid call reference value" },
00247 { AST_CAUSE_INCOMPATIBLE_DESTINATION, "INCOMPATIBLE_DESTINATION", "Incompatible destination" },
00248 { AST_CAUSE_INVALID_MSG_UNSPECIFIED, "INVALID_MSG_UNSPECIFIED", "Invalid message unspecified" },
00249 { AST_CAUSE_MANDATORY_IE_MISSING, "MANDATORY_IE_MISSING", "Mandatory information element is missing" },
00250 { AST_CAUSE_MESSAGE_TYPE_NONEXIST, "MESSAGE_TYPE_NONEXIST", "Message type nonexist." },
00251 { AST_CAUSE_WRONG_MESSAGE, "WRONG_MESSAGE", "Wrong message" },
00252 { AST_CAUSE_IE_NONEXIST, "IE_NONEXIST", "Info. element nonexist or not implemented" },
00253 { AST_CAUSE_INVALID_IE_CONTENTS, "INVALID_IE_CONTENTS", "Invalid information element contents" },
00254 { AST_CAUSE_WRONG_CALL_STATE, "WRONG_CALL_STATE", "Message not compatible with call state" },
00255 { AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, "RECOVERY_ON_TIMER_EXPIRE", "Recover on timer expiry" },
00256 { AST_CAUSE_MANDATORY_IE_LENGTH_ERROR, "MANDATORY_IE_LENGTH_ERROR", "Mandatory IE length error" },
00257 { AST_CAUSE_PROTOCOL_ERROR, "PROTOCOL_ERROR", "Protocol error, unspecified" },
00258 { AST_CAUSE_INTERWORKING, "INTERWORKING", "Interworking, unspecified" },
00259 };
00260
00261 struct ast_variable *ast_channeltype_list(void)
00262 {
00263 struct chanlist *cl;
00264 struct ast_variable *var = NULL, *prev = NULL;
00265
00266 AST_RWLIST_RDLOCK(&backends);
00267 AST_RWLIST_TRAVERSE(&backends, cl, list) {
00268 if (prev) {
00269 if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description, "")))
00270 prev = prev->next;
00271 } else {
00272 var = ast_variable_new(cl->tech->type, cl->tech->description, "");
00273 prev = var;
00274 }
00275 }
00276 AST_RWLIST_UNLOCK(&backends);
00277
00278 return var;
00279 }
00280
00281 static void channel_data_add_flags(struct ast_data *tree,
00282 struct ast_channel *chan)
00283 {
00284 ast_data_add_bool(tree, "DEFER_DTMF", ast_test_flag(chan, AST_FLAG_DEFER_DTMF));
00285 ast_data_add_bool(tree, "WRITE_INT", ast_test_flag(chan, AST_FLAG_WRITE_INT));
00286 ast_data_add_bool(tree, "BLOCKING", ast_test_flag(chan, AST_FLAG_BLOCKING));
00287 ast_data_add_bool(tree, "ZOMBIE", ast_test_flag(chan, AST_FLAG_ZOMBIE));
00288 ast_data_add_bool(tree, "EXCEPTION", ast_test_flag(chan, AST_FLAG_EXCEPTION));
00289 ast_data_add_bool(tree, "MOH", ast_test_flag(chan, AST_FLAG_MOH));
00290 ast_data_add_bool(tree, "SPYING", ast_test_flag(chan, AST_FLAG_SPYING));
00291 ast_data_add_bool(tree, "NBRIDGE", ast_test_flag(chan, AST_FLAG_NBRIDGE));
00292 ast_data_add_bool(tree, "IN_AUTOLOOP", ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP));
00293 ast_data_add_bool(tree, "OUTGOING", ast_test_flag(chan, AST_FLAG_OUTGOING));
00294 ast_data_add_bool(tree, "IN_DTMF", ast_test_flag(chan, AST_FLAG_IN_DTMF));
00295 ast_data_add_bool(tree, "EMULATE_DTMF", ast_test_flag(chan, AST_FLAG_EMULATE_DTMF));
00296 ast_data_add_bool(tree, "END_DTMF_ONLY", ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY));
00297 ast_data_add_bool(tree, "ANSWERED_ELSEWHERE", ast_test_flag(chan, AST_FLAG_ANSWERED_ELSEWHERE));
00298 ast_data_add_bool(tree, "MASQ_NOSTREAM", ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM));
00299 ast_data_add_bool(tree, "BRIDGE_HANGUP_RUN", ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN));
00300 ast_data_add_bool(tree, "BRIDGE_HANGUP_DONT", ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT));
00301 ast_data_add_bool(tree, "DISABLE_WORKAROUNDS", ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS));
00302 ast_data_add_bool(tree, "DISABLE_DEVSTATE_CACHE", ast_test_flag(chan, AST_FLAG_DISABLE_DEVSTATE_CACHE));
00303 }
00304
00305 #if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
00306 static const char *party_number_ton2str(int ton)
00307 {
00308 #if defined(HAVE_PRI)
00309 switch ((ton >> 4) & 0x07) {
00310 case PRI_TON_INTERNATIONAL:
00311 return "International";
00312 case PRI_TON_NATIONAL:
00313 return "National";
00314 case PRI_TON_NET_SPECIFIC:
00315 return "Network Specific";
00316 case PRI_TON_SUBSCRIBER:
00317 return "Subscriber";
00318 case PRI_TON_ABBREVIATED:
00319 return "Abbreviated";
00320 case PRI_TON_RESERVED:
00321 return "Reserved";
00322 case PRI_TON_UNKNOWN:
00323 default:
00324 break;
00325 }
00326 #endif
00327 return "Unknown";
00328 }
00329 #endif
00330
00331 #if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
00332 static const char *party_number_plan2str(int plan)
00333 {
00334 #if defined(HAVE_PRI)
00335 switch (plan & 0x0F) {
00336 default:
00337 case PRI_NPI_UNKNOWN:
00338 break;
00339 case PRI_NPI_E163_E164:
00340 return "Public (E.163/E.164)";
00341 case PRI_NPI_X121:
00342 return "Data (X.121)";
00343 case PRI_NPI_F69:
00344 return "Telex (F.69)";
00345 case PRI_NPI_NATIONAL:
00346 return "National Standard";
00347 case PRI_NPI_PRIVATE:
00348 return "Private";
00349 case PRI_NPI_RESERVED:
00350 return "Reserved";
00351 }
00352 #endif
00353 return "Unknown";
00354 }
00355 #endif
00356
00357 int ast_channel_data_add_structure(struct ast_data *tree,
00358 struct ast_channel *chan, int add_bridged)
00359 {
00360 struct ast_channel *bc;
00361 struct ast_data *data_bridged;
00362 struct ast_data *data_cdr;
00363 struct ast_data *data_flags;
00364 struct ast_data *data_zones;
00365 struct ast_data *enum_node;
00366 struct ast_data *data_softhangup;
00367 #if 0
00368 struct ast_data *data_callerid;
00369 char value_str[100];
00370 #endif
00371
00372 if (!tree) {
00373 return -1;
00374 }
00375
00376 ast_data_add_structure(ast_channel, tree, chan);
00377
00378 if (add_bridged) {
00379 bc = ast_bridged_channel(chan);
00380 if (bc) {
00381 data_bridged = ast_data_add_node(tree, "bridged");
00382 if (!data_bridged) {
00383 return -1;
00384 }
00385 ast_channel_data_add_structure(data_bridged, bc, 0);
00386 }
00387 }
00388
00389 ast_data_add_codecs(tree, "oldwriteformat", chan->oldwriteformat);
00390 ast_data_add_codecs(tree, "nativeformats", chan->nativeformats);
00391 ast_data_add_codecs(tree, "readformat", chan->readformat);
00392 ast_data_add_codecs(tree, "writeformat", chan->writeformat);
00393 ast_data_add_codecs(tree, "rawreadformat", chan->rawreadformat);
00394 ast_data_add_codecs(tree, "rawwriteformat", chan->rawwriteformat);
00395
00396
00397 enum_node = ast_data_add_node(tree, "state");
00398 if (!enum_node) {
00399 return -1;
00400 }
00401 ast_data_add_str(enum_node, "text", ast_state2str(chan->_state));
00402 ast_data_add_int(enum_node, "value", chan->_state);
00403
00404
00405 enum_node = ast_data_add_node(tree, "hangupcause");
00406 if (!enum_node) {
00407 return -1;
00408 }
00409 ast_data_add_str(enum_node, "text", ast_cause2str(chan->hangupcause));
00410 ast_data_add_int(enum_node, "value", chan->hangupcause);
00411
00412
00413 enum_node = ast_data_add_node(tree, "amaflags");
00414 if (!enum_node) {
00415 return -1;
00416 }
00417 ast_data_add_str(enum_node, "text", ast_cdr_flags2str(chan->amaflags));
00418 ast_data_add_int(enum_node, "value", chan->amaflags);
00419
00420
00421 enum_node = ast_data_add_node(tree, "transfercapability");
00422 if (!enum_node) {
00423 return -1;
00424 }
00425 ast_data_add_str(enum_node, "text", ast_transfercapability2str(chan->transfercapability));
00426 ast_data_add_int(enum_node, "value", chan->transfercapability);
00427
00428
00429 data_softhangup = ast_data_add_node(tree, "softhangup");
00430 if (!data_softhangup) {
00431 return -1;
00432 }
00433 ast_data_add_bool(data_softhangup, "dev", chan->_softhangup & AST_SOFTHANGUP_DEV);
00434 ast_data_add_bool(data_softhangup, "asyncgoto", chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO);
00435 ast_data_add_bool(data_softhangup, "shutdown", chan->_softhangup & AST_SOFTHANGUP_SHUTDOWN);
00436 ast_data_add_bool(data_softhangup, "timeout", chan->_softhangup & AST_SOFTHANGUP_TIMEOUT);
00437 ast_data_add_bool(data_softhangup, "appunload", chan->_softhangup & AST_SOFTHANGUP_APPUNLOAD);
00438 ast_data_add_bool(data_softhangup, "explicit", chan->_softhangup & AST_SOFTHANGUP_EXPLICIT);
00439 ast_data_add_bool(data_softhangup, "unbridge", chan->_softhangup & AST_SOFTHANGUP_UNBRIDGE);
00440
00441
00442 data_flags = ast_data_add_node(tree, "flags");
00443 if (!data_flags) {
00444 return -1;
00445 }
00446 channel_data_add_flags(data_flags, chan);
00447
00448 ast_data_add_uint(tree, "timetohangup", chan->whentohangup.tv_sec);
00449
00450 #if 0
00451
00452 data_callerid = ast_data_add_node(tree, "callerid");
00453 if (!data_callerid) {
00454 return -1;
00455 }
00456 ast_data_add_structure(ast_callerid, data_callerid, &(chan->cid));
00457
00458 enum_node = ast_data_add_node(data_callerid, "cid_ton");
00459 if (!enum_node) {
00460 return -1;
00461 }
00462 ast_data_add_int(enum_node, "value", chan->cid.cid_ton);
00463 snprintf(value_str, sizeof(value_str), "TON: %s/Plan: %s",
00464 party_number_ton2str(chan->cid.cid_ton),
00465 party_number_plan2str(chan->cid.cid_ton));
00466 ast_data_add_str(enum_node, "text", value_str);
00467 #endif
00468
00469
00470 if (chan->zone) {
00471 data_zones = ast_data_add_node(tree, "zone");
00472 if (!data_zones) {
00473 return -1;
00474 }
00475 ast_tone_zone_data_add_structure(data_zones, chan->zone);
00476 }
00477
00478
00479 data_cdr = ast_data_add_node(tree, "cdr");
00480 if (!data_cdr) {
00481 return -1;
00482 }
00483
00484 ast_cdr_data_add_structure(data_cdr, chan->cdr, 1);
00485
00486 return 0;
00487 }
00488
00489 int ast_channel_data_cmp_structure(const struct ast_data_search *tree,
00490 struct ast_channel *chan, const char *structure_name)
00491 {
00492 return ast_data_search_cmp_structure(tree, ast_channel, chan, structure_name);
00493 }
00494
00495
00496 static char *handle_cli_core_show_channeltypes(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
00497 {
00498 #define FORMAT "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n"
00499 struct chanlist *cl;
00500 int count_chan = 0;
00501
00502 switch (cmd) {
00503 case CLI_INIT:
00504 e->command = "core show channeltypes";
00505 e->usage =
00506 "Usage: core show channeltypes\n"
00507 " Lists available channel types registered in your\n"
00508 " Asterisk server.\n";
00509 return NULL;
00510 case CLI_GENERATE:
00511 return NULL;
00512 }
00513
00514 if (a->argc != 3)
00515 return CLI_SHOWUSAGE;
00516
00517 ast_cli(a->fd, FORMAT, "Type", "Description", "Devicestate", "Indications", "Transfer");
00518 ast_cli(a->fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
00519
00520 AST_RWLIST_RDLOCK(&backends);
00521 AST_RWLIST_TRAVERSE(&backends, cl, list) {
00522 ast_cli(a->fd, FORMAT, cl->tech->type, cl->tech->description,
00523 (cl->tech->devicestate) ? "yes" : "no",
00524 (cl->tech->indicate) ? "yes" : "no",
00525 (cl->tech->transfer) ? "yes" : "no");
00526 count_chan++;
00527 }
00528 AST_RWLIST_UNLOCK(&backends);
00529
00530 ast_cli(a->fd, "----------\n%d channel drivers registered.\n", count_chan);
00531
00532 return CLI_SUCCESS;
00533
00534 #undef FORMAT
00535 }
00536
00537 static char *complete_channeltypes(struct ast_cli_args *a)
00538 {
00539 struct chanlist *cl;
00540 int which = 0;
00541 int wordlen;
00542 char *ret = NULL;
00543
00544 if (a->pos != 3)
00545 return NULL;
00546
00547 wordlen = strlen(a->word);
00548
00549 AST_RWLIST_RDLOCK(&backends);
00550 AST_RWLIST_TRAVERSE(&backends, cl, list) {
00551 if (!strncasecmp(a->word, cl->tech->type, wordlen) && ++which > a->n) {
00552 ret = ast_strdup(cl->tech->type);
00553 break;
00554 }
00555 }
00556 AST_RWLIST_UNLOCK(&backends);
00557
00558 return ret;
00559 }
00560
00561
00562 static char *handle_cli_core_show_channeltype(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
00563 {
00564 struct chanlist *cl = NULL;
00565 char buf[512];
00566
00567 switch (cmd) {
00568 case CLI_INIT:
00569 e->command = "core show channeltype";
00570 e->usage =
00571 "Usage: core show channeltype <name>\n"
00572 " Show details about the specified channel type, <name>.\n";
00573 return NULL;
00574 case CLI_GENERATE:
00575 return complete_channeltypes(a);
00576 }
00577
00578 if (a->argc != 4)
00579 return CLI_SHOWUSAGE;
00580
00581 AST_RWLIST_RDLOCK(&backends);
00582
00583 AST_RWLIST_TRAVERSE(&backends, cl, list) {
00584 if (!strncasecmp(cl->tech->type, a->argv[3], strlen(cl->tech->type)))
00585 break;
00586 }
00587
00588
00589 if (!cl) {
00590 ast_cli(a->fd, "\n%s is not a registered channel driver.\n", a->argv[3]);
00591 AST_RWLIST_UNLOCK(&backends);
00592 return CLI_FAILURE;
00593 }
00594
00595 ast_cli(a->fd,
00596 "-- Info about channel driver: %s --\n"
00597 " Device State: %s\n"
00598 " Indication: %s\n"
00599 " Transfer : %s\n"
00600 " Capabilities: %s\n"
00601 " Digit Begin: %s\n"
00602 " Digit End: %s\n"
00603 " Send HTML : %s\n"
00604 " Image Support: %s\n"
00605 " Text Support: %s\n",
00606 cl->tech->type,
00607 (cl->tech->devicestate) ? "yes" : "no",
00608 (cl->tech->indicate) ? "yes" : "no",
00609 (cl->tech->transfer) ? "yes" : "no",
00610 ast_getformatname_multiple(buf, sizeof(buf), (cl->tech->capabilities) ? cl->tech->capabilities : -1),
00611 (cl->tech->send_digit_begin) ? "yes" : "no",
00612 (cl->tech->send_digit_end) ? "yes" : "no",
00613 (cl->tech->send_html) ? "yes" : "no",
00614 (cl->tech->send_image) ? "yes" : "no",
00615 (cl->tech->send_text) ? "yes" : "no"
00616
00617 );
00618
00619 AST_RWLIST_UNLOCK(&backends);
00620
00621 return CLI_SUCCESS;
00622 }
00623
00624 static struct ast_cli_entry cli_channel[] = {
00625 AST_CLI_DEFINE(handle_cli_core_show_channeltypes, "List available channel types"),
00626 AST_CLI_DEFINE(handle_cli_core_show_channeltype, "Give more details on that channel type")
00627 };
00628
00629 static struct ast_frame *kill_read(struct ast_channel *chan)
00630 {
00631
00632 return NULL;
00633 }
00634
00635 static struct ast_frame *kill_exception(struct ast_channel *chan)
00636 {
00637
00638 return NULL;
00639 }
00640
00641 static int kill_write(struct ast_channel *chan, struct ast_frame *frame)
00642 {
00643
00644 return -1;
00645 }
00646
00647 static int kill_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
00648 {
00649
00650 return 0;
00651 }
00652
00653 static int kill_hangup(struct ast_channel *chan)
00654 {
00655 chan->tech_pvt = NULL;
00656 return 0;
00657 }
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 const struct ast_channel_tech ast_kill_tech = {
00669 .type = "Kill",
00670 .description = "Kill channel (should not see this)",
00671 .capabilities = -1,
00672 .read = kill_read,
00673 .exception = kill_exception,
00674 .write = kill_write,
00675 .fixup = kill_fixup,
00676 .hangup = kill_hangup,
00677 };
00678
00679 #ifdef CHANNEL_TRACE
00680
00681 static void ast_chan_trace_destroy_cb(void *data)
00682 {
00683 struct ast_chan_trace *trace;
00684 struct ast_chan_trace_data *traced = data;
00685 while ((trace = AST_LIST_REMOVE_HEAD(&traced->trace, entry))) {
00686 ast_free(trace);
00687 }
00688 ast_free(traced);
00689 }
00690
00691
00692 static const struct ast_datastore_info ast_chan_trace_datastore_info = {
00693 .type = "ChanTrace",
00694 .destroy = ast_chan_trace_destroy_cb
00695 };
00696
00697
00698 int ast_channel_trace_serialize(struct ast_channel *chan, struct ast_str **buf)
00699 {
00700 int total = 0;
00701 struct ast_chan_trace *trace;
00702 struct ast_chan_trace_data *traced;
00703 struct ast_datastore *store;
00704
00705 ast_channel_lock(chan);
00706 store = ast_channel_datastore_find(chan, &ast_chan_trace_datastore_info, NULL);
00707 if (!store) {
00708 ast_channel_unlock(chan);
00709 return total;
00710 }
00711 traced = store->data;
00712 ast_str_reset(*buf);
00713 AST_LIST_TRAVERSE(&traced->trace, trace, entry) {
00714 if (ast_str_append(buf, 0, "[%d] => %s, %s, %d\n", total, trace->context, trace->exten, trace->priority) < 0) {
00715 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
00716 total = -1;
00717 break;
00718 }
00719 total++;
00720 }
00721 ast_channel_unlock(chan);
00722 return total;
00723 }
00724
00725
00726 int ast_channel_trace_is_enabled(struct ast_channel *chan)
00727 {
00728 struct ast_datastore *store = ast_channel_datastore_find(chan, &ast_chan_trace_datastore_info, NULL);
00729 if (!store)
00730 return 0;
00731 return ((struct ast_chan_trace_data *)store->data)->enabled;
00732 }
00733
00734
00735 static int ast_channel_trace_data_update(struct ast_channel *chan, struct ast_chan_trace_data *traced)
00736 {
00737 struct ast_chan_trace *trace;
00738 if (!traced->enabled)
00739 return 0;
00740
00741
00742 if ((!AST_LIST_EMPTY(&traced->trace) && strcasecmp(AST_LIST_FIRST(&traced->trace)->context, chan->context)) ||
00743 (AST_LIST_EMPTY(&traced->trace))) {
00744
00745 if (AST_LIST_EMPTY(&traced->trace))
00746 ast_log(LOG_DEBUG, "Setting initial trace context to %s\n", chan->context);
00747 else
00748 ast_log(LOG_DEBUG, "Changing trace context from %s to %s\n", AST_LIST_FIRST(&traced->trace)->context, chan->context);
00749
00750 trace = ast_malloc(sizeof(*trace));
00751 if (!trace)
00752 return -1;
00753
00754 ast_copy_string(trace->context, chan->context, sizeof(trace->context));
00755 ast_copy_string(trace->exten, chan->exten, sizeof(trace->exten));
00756 trace->priority = chan->priority;
00757 AST_LIST_INSERT_HEAD(&traced->trace, trace, entry);
00758 }
00759 return 0;
00760 }
00761
00762
00763 int ast_channel_trace_update(struct ast_channel *chan)
00764 {
00765 struct ast_datastore *store = ast_channel_datastore_find(chan, &ast_chan_trace_datastore_info, NULL);
00766 if (!store)
00767 return 0;
00768 return ast_channel_trace_data_update(chan, store->data);
00769 }
00770
00771
00772 int ast_channel_trace_enable(struct ast_channel *chan)
00773 {
00774 struct ast_datastore *store = ast_channel_datastore_find(chan, &ast_chan_trace_datastore_info, NULL);
00775 struct ast_chan_trace_data *traced;
00776 if (!store) {
00777 store = ast_datastore_alloc(&ast_chan_trace_datastore_info, "ChanTrace");
00778 if (!store)
00779 return -1;
00780 traced = ast_calloc(1, sizeof(*traced));
00781 if (!traced) {
00782 ast_datastore_free(store);
00783 return -1;
00784 }
00785 store->data = traced;
00786 AST_LIST_HEAD_INIT_NOLOCK(&traced->trace);
00787 ast_channel_datastore_add(chan, store);
00788 }
00789 ((struct ast_chan_trace_data *)store->data)->enabled = 1;
00790 ast_channel_trace_data_update(chan, store->data);
00791 return 0;
00792 }
00793
00794
00795 int ast_channel_trace_disable(struct ast_channel *chan)
00796 {
00797 struct ast_datastore *store = ast_channel_datastore_find(chan, &ast_chan_trace_datastore_info, NULL);
00798 if (!store)
00799 return 0;
00800 ((struct ast_chan_trace_data *)store->data)->enabled = 0;
00801 return 0;
00802 }
00803 #endif
00804
00805
00806 int ast_check_hangup(struct ast_channel *chan)
00807 {
00808 if (chan->_softhangup)
00809 return 1;
00810 if (ast_tvzero(chan->whentohangup))
00811 return 0;
00812 if (ast_tvdiff_ms(chan->whentohangup, ast_tvnow()) > 0)
00813 return 0;
00814 ast_debug(4, "Hangup time has come: %" PRIi64 "\n", ast_tvdiff_ms(chan->whentohangup, ast_tvnow()));
00815 ast_test_suite_event_notify("HANGUP_TIME", "Channel: %s", chan->name);
00816 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
00817 return 1;
00818 }
00819
00820 int ast_check_hangup_locked(struct ast_channel *chan)
00821 {
00822 int res;
00823 ast_channel_lock(chan);
00824 res = ast_check_hangup(chan);
00825 ast_channel_unlock(chan);
00826 return res;
00827 }
00828
00829 static int ast_channel_softhangup_cb(void *obj, void *arg, int flags)
00830 {
00831 struct ast_channel *chan = obj;
00832
00833 ast_softhangup(chan, AST_SOFTHANGUP_SHUTDOWN);
00834
00835 return 0;
00836 }
00837
00838 void ast_begin_shutdown(int hangup)
00839 {
00840 shutting_down = 1;
00841
00842 if (hangup) {
00843 ao2_callback(channels, OBJ_NODATA | OBJ_MULTIPLE, ast_channel_softhangup_cb, NULL);
00844 }
00845 }
00846
00847
00848 int ast_active_channels(void)
00849 {
00850 return channels ? ao2_container_count(channels) : 0;
00851 }
00852
00853 int ast_undestroyed_channels(void)
00854 {
00855 return ast_atomic_fetchadd_int(&chancount, 0);
00856 }
00857
00858
00859 void ast_cancel_shutdown(void)
00860 {
00861 shutting_down = 0;
00862 }
00863
00864
00865 int ast_shutting_down(void)
00866 {
00867 return shutting_down;
00868 }
00869
00870
00871 void ast_channel_setwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
00872 {
00873 chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow());
00874 ast_queue_frame(chan, &ast_null_frame);
00875 return;
00876 }
00877
00878 void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
00879 {
00880 struct timeval when = { offset, };
00881 ast_channel_setwhentohangup_tv(chan, when);
00882 }
00883
00884
00885 int ast_channel_cmpwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
00886 {
00887 struct timeval whentohangup;
00888
00889 if (ast_tvzero(chan->whentohangup))
00890 return ast_tvzero(offset) ? 0 : -1;
00891
00892 if (ast_tvzero(offset))
00893 return 1;
00894
00895 whentohangup = ast_tvadd(offset, ast_tvnow());
00896
00897 return ast_tvdiff_ms(whentohangup, chan->whentohangup);
00898 }
00899
00900 int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset)
00901 {
00902 struct timeval when = { offset, };
00903 return ast_channel_cmpwhentohangup_tv(chan, when);
00904 }
00905
00906
00907 int ast_channel_register(const struct ast_channel_tech *tech)
00908 {
00909 struct chanlist *chan;
00910
00911 AST_RWLIST_WRLOCK(&backends);
00912
00913 AST_RWLIST_TRAVERSE(&backends, chan, list) {
00914 if (!strcasecmp(tech->type, chan->tech->type)) {
00915 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
00916 AST_RWLIST_UNLOCK(&backends);
00917 return -1;
00918 }
00919 }
00920
00921 if (!(chan = ast_calloc(1, sizeof(*chan)))) {
00922 AST_RWLIST_UNLOCK(&backends);
00923 return -1;
00924 }
00925 chan->tech = tech;
00926 AST_RWLIST_INSERT_HEAD(&backends, chan, list);
00927
00928 ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
00929
00930 ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description);
00931
00932 AST_RWLIST_UNLOCK(&backends);
00933
00934 return 0;
00935 }
00936
00937
00938 void ast_channel_unregister(const struct ast_channel_tech *tech)
00939 {
00940 struct chanlist *chan;
00941
00942 ast_debug(1, "Unregistering channel type '%s'\n", tech->type);
00943
00944 AST_RWLIST_WRLOCK(&backends);
00945
00946 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
00947 if (chan->tech == tech) {
00948 AST_LIST_REMOVE_CURRENT(list);
00949 ast_free(chan);
00950 ast_verb(2, "Unregistered channel type '%s'\n", tech->type);
00951 break;
00952 }
00953 }
00954 AST_LIST_TRAVERSE_SAFE_END;
00955
00956 AST_RWLIST_UNLOCK(&backends);
00957 }
00958
00959
00960 const struct ast_channel_tech *ast_get_channel_tech(const char *name)
00961 {
00962 struct chanlist *chanls;
00963 const struct ast_channel_tech *ret = NULL;
00964
00965 AST_RWLIST_RDLOCK(&backends);
00966
00967 AST_RWLIST_TRAVERSE(&backends, chanls, list) {
00968 if (!strcasecmp(name, chanls->tech->type)) {
00969 ret = chanls->tech;
00970 break;
00971 }
00972 }
00973
00974 AST_RWLIST_UNLOCK(&backends);
00975
00976 return ret;
00977 }
00978
00979
00980 const char *ast_cause2str(int cause)
00981 {
00982 int x;
00983
00984 for (x = 0; x < ARRAY_LEN(causes); x++) {
00985 if (causes[x].cause == cause)
00986 return causes[x].desc;
00987 }
00988
00989 return "Unknown";
00990 }
00991
00992
00993 int ast_str2cause(const char *name)
00994 {
00995 int x;
00996
00997 for (x = 0; x < ARRAY_LEN(causes); x++)
00998 if (!strncasecmp(causes[x].name, name, strlen(causes[x].name)))
00999 return causes[x].cause;
01000
01001 return -1;
01002 }
01003
01004
01005
01006
01007 const char *ast_state2str(enum ast_channel_state state)
01008 {
01009 char *buf;
01010
01011 switch (state) {
01012 case AST_STATE_DOWN:
01013 return "Down";
01014 case AST_STATE_RESERVED:
01015 return "Rsrvd";
01016 case AST_STATE_OFFHOOK:
01017 return "OffHook";
01018 case AST_STATE_DIALING:
01019 return "Dialing";
01020 case AST_STATE_RING:
01021 return "Ring";
01022 case AST_STATE_RINGING:
01023 return "Ringing";
01024 case AST_STATE_UP:
01025 return "Up";
01026 case AST_STATE_BUSY:
01027 return "Busy";
01028 case AST_STATE_DIALING_OFFHOOK:
01029 return "Dialing Offhook";
01030 case AST_STATE_PRERING:
01031 return "Pre-ring";
01032 default:
01033 if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE)))
01034 return "Unknown";
01035 snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state);
01036 return buf;
01037 }
01038 }
01039
01040
01041 char *ast_transfercapability2str(int transfercapability)
01042 {
01043 switch (transfercapability) {
01044 case AST_TRANS_CAP_SPEECH:
01045 return "SPEECH";
01046 case AST_TRANS_CAP_DIGITAL:
01047 return "DIGITAL";
01048 case AST_TRANS_CAP_RESTRICTED_DIGITAL:
01049 return "RESTRICTED_DIGITAL";
01050 case AST_TRANS_CAP_3_1K_AUDIO:
01051 return "3K1AUDIO";
01052 case AST_TRANS_CAP_DIGITAL_W_TONES:
01053 return "DIGITAL_W_TONES";
01054 case AST_TRANS_CAP_VIDEO:
01055 return "VIDEO";
01056 default:
01057 return "UNKNOWN";
01058 }
01059 }
01060
01061
01062 format_t ast_best_codec(format_t fmts)
01063 {
01064
01065
01066 int x;
01067 static const format_t prefs[] =
01068 {
01069
01070 AST_FORMAT_ULAW,
01071
01072 AST_FORMAT_ALAW,
01073 AST_FORMAT_G719,
01074 AST_FORMAT_SIREN14,
01075 AST_FORMAT_SIREN7,
01076 AST_FORMAT_TESTLAW,
01077
01078 AST_FORMAT_G722,
01079
01080 AST_FORMAT_SLINEAR16,
01081 AST_FORMAT_SLINEAR,
01082
01083 AST_FORMAT_G726,
01084
01085 AST_FORMAT_G726_AAL2,
01086
01087 AST_FORMAT_ADPCM,
01088
01089
01090 AST_FORMAT_GSM,
01091
01092 AST_FORMAT_ILBC,
01093
01094 AST_FORMAT_SPEEX16,
01095 AST_FORMAT_SPEEX,
01096
01097
01098 AST_FORMAT_LPC10,
01099
01100 AST_FORMAT_G729A,
01101
01102 AST_FORMAT_G723_1,
01103 };
01104 char buf[512];
01105
01106
01107 fmts &= AST_FORMAT_AUDIO_MASK;
01108
01109
01110 for (x = 0; x < ARRAY_LEN(prefs); x++) {
01111 if (fmts & prefs[x])
01112 return prefs[x];
01113 }
01114
01115 ast_log(LOG_WARNING, "Don't know any of %s formats\n", ast_getformatname_multiple(buf, sizeof(buf), fmts));
01116
01117 return 0;
01118 }
01119
01120 static const struct ast_channel_tech null_tech = {
01121 .type = "NULL",
01122 .description = "Null channel (should not see this)",
01123 };
01124
01125 static void ast_channel_destructor(void *obj);
01126 static void ast_dummy_channel_destructor(void *obj);
01127
01128
01129 static struct ast_channel * attribute_malloc __attribute__((format(printf, 13, 0)))
01130 __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char *cid_name,
01131 const char *acctcode, const char *exten, const char *context,
01132 const char *linkedid, const int amaflag, const char *file, int line,
01133 const char *function, const char *name_fmt, va_list ap1, va_list ap2)
01134 {
01135 struct ast_channel *tmp;
01136 int x;
01137 int flags;
01138 struct varshead *headp;
01139 char *tech = "", *tech2 = NULL;
01140
01141
01142 if (shutting_down) {
01143 ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n");
01144 return NULL;
01145 }
01146
01147 #if defined(REF_DEBUG)
01148 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line,
01149 function, 1);
01150 #elif defined(__AST_DEBUG_MALLOC)
01151 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line,
01152 function, 0);
01153 #else
01154 tmp = ao2_alloc(sizeof(*tmp), ast_channel_destructor);
01155 #endif
01156 if (!tmp) {
01157
01158 return NULL;
01159 }
01160
01161
01162
01163
01164
01165 tmp->timingfd = -1;
01166 for (x = 0; x < ARRAY_LEN(tmp->alertpipe); ++x) {
01167 tmp->alertpipe[x] = -1;
01168 }
01169 for (x = 0; x < ARRAY_LEN(tmp->fds); ++x) {
01170 tmp->fds[x] = -1;
01171 }
01172 #ifdef HAVE_EPOLL
01173 tmp->epfd = epoll_create(25);
01174 #endif
01175
01176 if (!(tmp->sched = sched_context_create())) {
01177 ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
01178 return ast_channel_unref(tmp);
01179 }
01180
01181 ast_party_dialed_init(&tmp->dialed);
01182 ast_party_caller_init(&tmp->caller);
01183 ast_party_connected_line_init(&tmp->connected);
01184 ast_party_redirecting_init(&tmp->redirecting);
01185
01186 if (cid_name) {
01187 tmp->caller.id.name.valid = 1;
01188 tmp->caller.id.name.str = ast_strdup(cid_name);
01189 if (!tmp->caller.id.name.str) {
01190 return ast_channel_unref(tmp);
01191 }
01192 }
01193 if (cid_num) {
01194 tmp->caller.id.number.valid = 1;
01195 tmp->caller.id.number.str = ast_strdup(cid_num);
01196 if (!tmp->caller.id.number.str) {
01197 return ast_channel_unref(tmp);
01198 }
01199 }
01200
01201 if ((tmp->timer = ast_timer_open())) {
01202 if (strcmp(ast_timer_get_name(tmp->timer), "timerfd")) {
01203 needqueue = 0;
01204 }
01205 tmp->timingfd = ast_timer_fd(tmp->timer);
01206 }
01207
01208 if (needqueue) {
01209 if (pipe(tmp->alertpipe)) {
01210 ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe! Try increasing max file descriptors with ulimit -n\n");
01211 return ast_channel_unref(tmp);
01212 } else {
01213 flags = fcntl(tmp->alertpipe[0], F_GETFL);
01214 if (fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
01215 ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
01216 return ast_channel_unref(tmp);
01217 }
01218 flags = fcntl(tmp->alertpipe[1], F_GETFL);
01219 if (fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK) < 0) {
01220 ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
01221 return ast_channel_unref(tmp);
01222 }
01223 }
01224 }
01225
01226
01227
01228
01229
01230
01231
01232
01233 if ((ast_string_field_init(tmp, 128))) {
01234 return ast_channel_unref(tmp);
01235 }
01236
01237
01238 ast_channel_set_fd(tmp, AST_ALERT_FD, tmp->alertpipe[0]);
01239
01240 ast_channel_set_fd(tmp, AST_TIMING_FD, tmp->timingfd);
01241
01242
01243 tmp->_state = state;
01244
01245 tmp->streamid = -1;
01246
01247 tmp->fin = global_fin;
01248 tmp->fout = global_fout;
01249
01250 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
01251 ast_string_field_build(tmp, uniqueid, "%li.%d", (long) time(NULL),
01252 ast_atomic_fetchadd_int(&uniqueint, 1));
01253 } else {
01254 ast_string_field_build(tmp, uniqueid, "%s-%li.%d", ast_config_AST_SYSTEM_NAME,
01255 (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1));
01256 }
01257
01258 if (!ast_strlen_zero(linkedid)) {
01259 ast_string_field_set(tmp, linkedid, linkedid);
01260 } else {
01261 ast_string_field_set(tmp, linkedid, tmp->uniqueid);
01262 }
01263
01264 if (!ast_strlen_zero(name_fmt)) {
01265 char *slash, *slash2;
01266
01267
01268
01269
01270
01271
01272
01273 ast_string_field_build_va(tmp, name, name_fmt, ap1, ap2);
01274 tech = ast_strdupa(tmp->name);
01275 if ((slash = strchr(tech, '/'))) {
01276 if ((slash2 = strchr(slash + 1, '/'))) {
01277 tech2 = slash + 1;
01278 *slash2 = '\0';
01279 }
01280 *slash = '\0';
01281 }
01282 } else {
01283
01284
01285
01286
01287 ast_string_field_set(tmp, name, "-**Unknown**");
01288 }
01289
01290
01291
01292
01293 if (amaflag)
01294 tmp->amaflags = amaflag;
01295 else
01296 tmp->amaflags = ast_default_amaflags;
01297
01298 if (!ast_strlen_zero(acctcode))
01299 ast_string_field_set(tmp, accountcode, acctcode);
01300 else
01301 ast_string_field_set(tmp, accountcode, ast_default_accountcode);
01302
01303 if (!ast_strlen_zero(context))
01304 ast_copy_string(tmp->context, context, sizeof(tmp->context));
01305 else
01306 strcpy(tmp->context, "default");
01307
01308 if (!ast_strlen_zero(exten))
01309 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
01310 else
01311 strcpy(tmp->exten, "s");
01312
01313 tmp->priority = 1;
01314
01315 tmp->cdr = ast_cdr_alloc();
01316 ast_cdr_init(tmp->cdr, tmp);
01317 ast_cdr_start(tmp->cdr);
01318
01319 ast_atomic_fetchadd_int(&chancount, +1);
01320 ast_cel_report_event(tmp, AST_CEL_CHANNEL_START, NULL, NULL, NULL);
01321
01322 headp = &tmp->varshead;
01323 AST_LIST_HEAD_INIT_NOLOCK(headp);
01324
01325 AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores);
01326
01327 AST_LIST_HEAD_INIT_NOLOCK(&tmp->autochans);
01328
01329 ast_string_field_set(tmp, language, defaultlanguage);
01330
01331 tmp->tech = &null_tech;
01332
01333 ao2_link(channels, tmp);
01334
01335
01336
01337
01338
01339
01340
01341 if (ast_get_channel_tech(tech) || (tech2 && ast_get_channel_tech(tech2))) {
01342 ast_manager_event(tmp, EVENT_FLAG_CALL, "Newchannel",
01343 "Channel: %s\r\n"
01344 "ChannelState: %d\r\n"
01345 "ChannelStateDesc: %s\r\n"
01346 "CallerIDNum: %s\r\n"
01347 "CallerIDName: %s\r\n"
01348 "AccountCode: %s\r\n"
01349 "Exten: %s\r\n"
01350 "Context: %s\r\n"
01351 "Uniqueid: %s\r\n",
01352 tmp->name,
01353 state,
01354 ast_state2str(state),
01355 S_OR(cid_num, ""),
01356 S_OR(cid_name, ""),
01357 tmp->accountcode,
01358 S_OR(exten, ""),
01359 S_OR(context, ""),
01360 tmp->uniqueid);
01361 }
01362
01363 return tmp;
01364 }
01365
01366 struct ast_channel *__ast_channel_alloc(int needqueue, int state, const char *cid_num,
01367 const char *cid_name, const char *acctcode,
01368 const char *exten, const char *context,
01369 const char *linkedid, const int amaflag,
01370 const char *file, int line, const char *function,
01371 const char *name_fmt, ...)
01372 {
01373 va_list ap1, ap2;
01374 struct ast_channel *result;
01375
01376 va_start(ap1, name_fmt);
01377 va_start(ap2, name_fmt);
01378 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
01379 linkedid, amaflag, file, line, function, name_fmt, ap1, ap2);
01380 va_end(ap1);
01381 va_end(ap2);
01382
01383 return result;
01384 }
01385
01386
01387
01388 #if defined(REF_DEBUG) || defined(__AST_DEBUG_MALLOC)
01389 struct ast_channel *__ast_dummy_channel_alloc(const char *file, int line, const char *function)
01390 #else
01391 struct ast_channel *ast_dummy_channel_alloc(void)
01392 #endif
01393 {
01394 struct ast_channel *tmp;
01395 struct varshead *headp;
01396 int x;
01397
01398 #if defined(REF_DEBUG)
01399 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel",
01400 file, line, function, 1);
01401 #elif defined(__AST_DEBUG_MALLOC)
01402 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel",
01403 file, line, function, 0);
01404 #else
01405 tmp = ao2_alloc(sizeof(*tmp), ast_dummy_channel_destructor);
01406 #endif
01407 if (!tmp) {
01408
01409 return NULL;
01410 }
01411
01412 if ((ast_string_field_init(tmp, 128))) {
01413 return ast_channel_unref(tmp);
01414 }
01415
01416
01417
01418
01419
01420
01421 tmp->timingfd = -1;
01422 for (x = 0; x < ARRAY_LEN(tmp->alertpipe); ++x) {
01423 tmp->alertpipe[x] = -1;
01424 }
01425 for (x = 0; x < ARRAY_LEN(tmp->fds); ++x) {
01426 tmp->fds[x] = -1;
01427 }
01428 #ifdef HAVE_EPOLL
01429 tmp->epfd = -1;
01430 #endif
01431
01432 headp = &tmp->varshead;
01433 AST_LIST_HEAD_INIT_NOLOCK(headp);
01434
01435 return tmp;
01436 }
01437
01438 static int __ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, int head, struct ast_frame *after)
01439 {
01440 struct ast_frame *f;
01441 struct ast_frame *cur;
01442 unsigned int new_frames = 0;
01443 unsigned int new_voice_frames = 0;
01444 unsigned int queued_frames = 0;
01445 unsigned int queued_voice_frames = 0;
01446 AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
01447
01448 ast_channel_lock(chan);
01449
01450
01451
01452
01453
01454 cur = AST_LIST_LAST(&chan->readq);
01455 if (cur && cur->frametype == AST_FRAME_CONTROL && !head && (!after || after == cur)) {
01456 switch (cur->subclass.integer) {
01457 case AST_CONTROL_END_OF_Q:
01458 if (fin->frametype == AST_FRAME_CONTROL
01459 && fin->subclass.integer == AST_CONTROL_HANGUP) {
01460
01461
01462
01463
01464 AST_LIST_REMOVE(&chan->readq, cur, frame_list);
01465 ast_frfree(cur);
01466
01467
01468
01469
01470
01471
01472 after = NULL;
01473 break;
01474 }
01475
01476 case AST_CONTROL_HANGUP:
01477
01478 ast_channel_unlock(chan);
01479 return 0;
01480 default:
01481 break;
01482 }
01483 }
01484
01485
01486 AST_LIST_HEAD_INIT_NOLOCK(&frames);
01487 for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
01488 if (!(f = ast_frdup(cur))) {
01489 if (AST_LIST_FIRST(&frames)) {
01490 ast_frfree(AST_LIST_FIRST(&frames));
01491 }
01492 ast_channel_unlock(chan);
01493 return -1;
01494 }
01495
01496 AST_LIST_INSERT_TAIL(&frames, f, frame_list);
01497 new_frames++;
01498 if (f->frametype == AST_FRAME_VOICE) {
01499 new_voice_frames++;
01500 }
01501 }
01502
01503
01504 AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) {
01505 queued_frames++;
01506 if (cur->frametype == AST_FRAME_VOICE) {
01507 queued_voice_frames++;
01508 }
01509 }
01510
01511 if ((queued_frames + new_frames > 128 || queued_voice_frames + new_voice_frames > 96)) {
01512 int count = 0;
01513 ast_log(LOG_WARNING, "Exceptionally long %squeue length queuing to %s\n", queued_frames + new_frames > 128 ? "" : "voice ", chan->name);
01514 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, cur, frame_list) {
01515
01516 if (!AST_LIST_NEXT(cur, frame_list)) {
01517 break;
01518 } else if (cur->frametype == AST_FRAME_VOICE || cur->frametype == AST_FRAME_VIDEO || cur->frametype == AST_FRAME_NULL) {
01519 if (++count > 64) {
01520 break;
01521 }
01522 AST_LIST_REMOVE_CURRENT(frame_list);
01523 ast_frfree(cur);
01524 }
01525 }
01526 AST_LIST_TRAVERSE_SAFE_END;
01527 }
01528
01529 if (after) {
01530 AST_LIST_INSERT_LIST_AFTER(&chan->readq, &frames, after, frame_list);
01531 } else {
01532 if (head) {
01533 AST_LIST_APPEND_LIST(&frames, &chan->readq, frame_list);
01534 AST_LIST_HEAD_INIT_NOLOCK(&chan->readq);
01535 }
01536 AST_LIST_APPEND_LIST(&chan->readq, &frames, frame_list);
01537 }
01538
01539 if (chan->alertpipe[1] > -1) {
01540 int blah[new_frames];
01541
01542 memset(blah, 1, sizeof(blah));
01543 if (write(chan->alertpipe[1], &blah, sizeof(blah)) != (sizeof(blah))) {
01544 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s (qlen = %d): %s!\n",
01545 chan->name, queued_frames, strerror(errno));
01546 }
01547 } else if (chan->timingfd > -1) {
01548 ast_timer_enable_continuous(chan->timer);
01549 } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
01550 pthread_kill(chan->blocker, SIGURG);
01551 }
01552
01553 ast_channel_unlock(chan);
01554
01555 return 0;
01556 }
01557
01558 int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
01559 {
01560 return __ast_queue_frame(chan, fin, 0, NULL);
01561 }
01562
01563 int ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *fin)
01564 {
01565 return __ast_queue_frame(chan, fin, 1, NULL);
01566 }
01567
01568
01569 int ast_queue_hangup(struct ast_channel *chan)
01570 {
01571 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
01572
01573 if (!ast_channel_trylock(chan)) {
01574 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01575 ast_channel_unlock(chan);
01576 }
01577 return ast_queue_frame(chan, &f);
01578 }
01579
01580
01581 int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
01582 {
01583 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
01584
01585 if (cause >= 0)
01586 f.data.uint32 = cause;
01587
01588
01589 if (!ast_channel_trylock(chan)) {
01590 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01591 if (cause < 0)
01592 f.data.uint32 = chan->hangupcause;
01593
01594 ast_channel_unlock(chan);
01595 }
01596
01597 return ast_queue_frame(chan, &f);
01598 }
01599
01600
01601 int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
01602 {
01603 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control };
01604 return ast_queue_frame(chan, &f);
01605 }
01606
01607
01608 int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control,
01609 const void *data, size_t datalen)
01610 {
01611 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control, .data.ptr = (void *) data, .datalen = datalen };
01612 return ast_queue_frame(chan, &f);
01613 }
01614
01615
01616 int ast_channel_defer_dtmf(struct ast_channel *chan)
01617 {
01618 int pre = 0;
01619
01620 if (chan) {
01621 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
01622 ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
01623 }
01624 return pre;
01625 }
01626
01627
01628 void ast_channel_undefer_dtmf(struct ast_channel *chan)
01629 {
01630 if (chan)
01631 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
01632 }
01633
01634 struct ast_channel *ast_channel_callback(ao2_callback_data_fn *cb_fn, void *arg,
01635 void *data, int ao2_flags)
01636 {
01637 return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data);
01638 }
01639
01640 struct ast_channel_iterator {
01641
01642 struct ao2_iterator simple_iterator;
01643
01644
01645
01646 struct ao2_iterator *active_iterator;
01647 };
01648
01649 struct ast_channel_iterator *ast_channel_iterator_destroy(struct ast_channel_iterator *i)
01650 {
01651 ao2_iterator_destroy(i->active_iterator);
01652 ast_free(i);
01653
01654 return NULL;
01655 }
01656
01657 static struct ast_channel_iterator *channel_iterator_search(const char *name,
01658 size_t name_len, const char *exten,
01659 const char *context)
01660 {
01661 struct ast_channel_iterator *i;
01662 struct ast_channel tmp_chan = {
01663 .name = name,
01664
01665
01666
01667 .rings = name_len,
01668 };
01669
01670 if (!(i = ast_calloc(1, sizeof(*i)))) {
01671 return NULL;
01672 }
01673
01674 if (exten) {
01675 ast_copy_string(tmp_chan.exten, exten, sizeof(tmp_chan.exten));
01676 }
01677
01678 if (context) {
01679 ast_copy_string(tmp_chan.context, context, sizeof(tmp_chan.context));
01680 }
01681
01682 if (!(i->active_iterator = ao2_find(channels, &tmp_chan,
01683 OBJ_MULTIPLE | ((!ast_strlen_zero(name) && (name_len == 0)) ? OBJ_POINTER : 0)))) {
01684 ast_free(i);
01685 return NULL;
01686 }
01687
01688 return i;
01689 }
01690
01691 struct ast_channel_iterator *ast_channel_iterator_by_exten_new(const char *exten, const char *context)
01692 {
01693 return channel_iterator_search(NULL, 0, exten, context);
01694 }
01695
01696 struct ast_channel_iterator *ast_channel_iterator_by_name_new(const char *name, size_t name_len)
01697 {
01698 return channel_iterator_search(name, name_len, NULL, NULL);
01699 }
01700
01701 struct ast_channel_iterator *ast_channel_iterator_all_new(void)
01702 {
01703 struct ast_channel_iterator *i;
01704
01705 if (!(i = ast_calloc(1, sizeof(*i)))) {
01706 return NULL;
01707 }
01708
01709 i->simple_iterator = ao2_iterator_init(channels, 0);
01710 i->active_iterator = &i->simple_iterator;
01711
01712 return i;
01713 }
01714
01715 struct ast_channel *ast_channel_iterator_next(struct ast_channel_iterator *i)
01716 {
01717 return ao2_iterator_next(i->active_iterator);
01718 }
01719
01720 static int ast_channel_cmp_cb(void *obj, void *arg, int flags)
01721 {
01722 struct ast_channel *chan = obj, *cmp_args = arg;
01723 size_t name_len;
01724 int ret = CMP_MATCH;
01725
01726
01727
01728
01729 name_len = cmp_args->rings;
01730
01731 ast_channel_lock(chan);
01732
01733 if (!ast_strlen_zero(cmp_args->name)) {
01734 if ((!name_len && strcasecmp(chan->name, cmp_args->name)) ||
01735 (name_len && strncasecmp(chan->name, cmp_args->name, name_len))) {
01736 ret = 0;
01737 }
01738 } else if (!ast_strlen_zero(cmp_args->exten)) {
01739 if (cmp_args->context && strcasecmp(chan->context, cmp_args->context) &&
01740 strcasecmp(chan->macrocontext, cmp_args->context)) {
01741 ret = 0;
01742 }
01743 if (ret && strcasecmp(chan->exten, cmp_args->exten) &&
01744 strcasecmp(chan->macroexten, cmp_args->exten)) {
01745 ret = 0;
01746 }
01747 } else if (!ast_strlen_zero(cmp_args->uniqueid)) {
01748 if ((!name_len && strcasecmp(chan->uniqueid, cmp_args->uniqueid)) ||
01749 (name_len && strncasecmp(chan->uniqueid, cmp_args->uniqueid, name_len))) {
01750 ret = 0;
01751 }
01752 } else {
01753 ret = 0;
01754 }
01755
01756 ast_channel_unlock(chan);
01757
01758 return ret;
01759 }
01760
01761 static struct ast_channel *ast_channel_get_full(const char *name, size_t name_len,
01762 const char *exten, const char *context)
01763 {
01764 struct ast_channel tmp_chan = {
01765 .name = name,
01766
01767
01768
01769 .rings = name_len,
01770 };
01771 struct ast_channel *chan;
01772
01773 if (exten) {
01774 ast_copy_string(tmp_chan.exten, exten, sizeof(tmp_chan.exten));
01775 }
01776
01777 if (context) {
01778 ast_copy_string(tmp_chan.context, context, sizeof(tmp_chan.context));
01779 }
01780
01781 if ((chan = ao2_find(channels, &tmp_chan,
01782 (!ast_strlen_zero(name) && (name_len == 0)) ? OBJ_POINTER : 0))) {
01783 return chan;
01784 }
01785
01786 if (!name) {
01787 return NULL;
01788 }
01789
01790
01791
01792
01793 {
01794 struct ast_channel tmp_chan2 = {
01795 .uniqueid = name,
01796 .rings = name_len,
01797 };
01798
01799 return ao2_find(channels, &tmp_chan2, 0);
01800 }
01801 }
01802
01803 struct ast_channel *ast_channel_get_by_name(const char *name)
01804 {
01805 return ast_channel_get_full(name, 0, NULL, NULL);
01806 }
01807
01808 struct ast_channel *ast_channel_get_by_name_prefix(const char *name, size_t name_len)
01809 {
01810 return ast_channel_get_full(name, name_len, NULL, NULL);
01811 }
01812
01813 struct ast_channel *ast_channel_get_by_exten(const char *exten, const char *context)
01814 {
01815 return ast_channel_get_full(NULL, 0, exten, context);
01816 }
01817
01818 int ast_is_deferrable_frame(const struct ast_frame *frame)
01819 {
01820
01821
01822
01823
01824 switch (frame->frametype) {
01825 case AST_FRAME_CONTROL:
01826 case AST_FRAME_TEXT:
01827 case AST_FRAME_IMAGE:
01828 case AST_FRAME_HTML:
01829 return 1;
01830
01831 case AST_FRAME_DTMF_END:
01832 case AST_FRAME_DTMF_BEGIN:
01833 case AST_FRAME_VOICE:
01834 case AST_FRAME_VIDEO:
01835 case AST_FRAME_NULL:
01836 case AST_FRAME_IAX:
01837 case AST_FRAME_CNG:
01838 case AST_FRAME_MODEM:
01839 return 0;
01840 }
01841 return 0;
01842 }
01843
01844
01845 int ast_safe_sleep_conditional(struct ast_channel *chan, int timeout_ms, int (*cond)(void*), void *data)
01846 {
01847 struct ast_frame *f;
01848 struct ast_silence_generator *silgen = NULL;
01849 int res = 0;
01850 struct timeval start;
01851 int ms;
01852 AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames;
01853
01854 AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames);
01855
01856
01857 if (ast_opt_transmit_silence && !chan->generatordata) {
01858 silgen = ast_channel_start_silence_generator(chan);
01859 }
01860
01861 start = ast_tvnow();
01862 while ((ms = ast_remaining_ms(start, timeout_ms))) {
01863 struct ast_frame *dup_f = NULL;
01864
01865 if (cond && ((*cond)(data) == 0)) {
01866 break;
01867 }
01868 ms = ast_waitfor(chan, ms);
01869 if (ms < 0) {
01870 res = -1;
01871 break;
01872 }
01873 if (ms > 0) {
01874 f = ast_read(chan);
01875 if (!f) {
01876 res = -1;
01877 break;
01878 }
01879
01880 if (!ast_is_deferrable_frame(f)) {
01881 ast_frfree(f);
01882 continue;
01883 }
01884
01885 if ((dup_f = ast_frisolate(f))) {
01886 if (dup_f != f) {
01887 ast_frfree(f);
01888 }
01889 AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list);
01890 }
01891 }
01892 }
01893
01894
01895 if (silgen) {
01896 ast_channel_stop_silence_generator(chan, silgen);
01897 }
01898
01899
01900
01901
01902
01903 ast_channel_lock(chan);
01904 while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list))) {
01905 if (!res) {
01906 ast_queue_frame_head(chan, f);
01907 }
01908 ast_frfree(f);
01909 }
01910 ast_channel_unlock(chan);
01911
01912 return res;
01913 }
01914
01915
01916 int ast_safe_sleep(struct ast_channel *chan, int ms)
01917 {
01918 return ast_safe_sleep_conditional(chan, ms, NULL, NULL);
01919 }
01920
01921 struct ast_channel *ast_channel_release(struct ast_channel *chan)
01922 {
01923
01924 ao2_unlink(channels, chan);
01925 return ast_channel_unref(chan);
01926 }
01927
01928 void ast_party_name_init(struct ast_party_name *init)
01929 {
01930 init->str = NULL;
01931 init->char_set = AST_PARTY_CHAR_SET_ISO8859_1;
01932 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
01933 init->valid = 0;
01934 }
01935
01936 void ast_party_name_copy(struct ast_party_name *dest, const struct ast_party_name *src)
01937 {
01938 if (dest == src) {
01939
01940 return;
01941 }
01942
01943 ast_free(dest->str);
01944 dest->str = ast_strdup(src->str);
01945 dest->char_set = src->char_set;
01946 dest->presentation = src->presentation;
01947 dest->valid = src->valid;
01948 }
01949
01950 void ast_party_name_set_init(struct ast_party_name *init, const struct ast_party_name *guide)
01951 {
01952 init->str = NULL;
01953 init->char_set = guide->char_set;
01954 init->presentation = guide->presentation;
01955 init->valid = guide->valid;
01956 }
01957
01958 void ast_party_name_set(struct ast_party_name *dest, const struct ast_party_name *src)
01959 {
01960 if (dest == src) {
01961
01962 return;
01963 }
01964
01965 if (src->str && src->str != dest->str) {
01966 ast_free(dest->str);
01967 dest->str = ast_strdup(src->str);
01968 }
01969
01970 dest->char_set = src->char_set;
01971 dest->presentation = src->presentation;
01972 dest->valid = src->valid;
01973 }
01974
01975 void ast_party_name_free(struct ast_party_name *doomed)
01976 {
01977 ast_free(doomed->str);
01978 doomed->str = NULL;
01979 }
01980
01981 void ast_party_number_init(struct ast_party_number *init)
01982 {
01983 init->str = NULL;
01984 init->plan = 0;
01985 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
01986 init->valid = 0;
01987 }
01988
01989 void ast_party_number_copy(struct ast_party_number *dest, const struct ast_party_number *src)
01990 {
01991 if (dest == src) {
01992
01993 return;
01994 }
01995
01996 ast_free(dest->str);
01997 dest->str = ast_strdup(src->str);
01998 dest->plan = src->plan;
01999 dest->presentation = src->presentation;
02000 dest->valid = src->valid;
02001 }
02002
02003 void ast_party_number_set_init(struct ast_party_number *init, const struct ast_party_number *guide)
02004 {
02005 init->str = NULL;
02006 init->plan = guide->plan;
02007 init->presentation = guide->presentation;
02008 init->valid = guide->valid;
02009 }
02010
02011 void ast_party_number_set(struct ast_party_number *dest, const struct ast_party_number *src)
02012 {
02013 if (dest == src) {
02014
02015 return;
02016 }
02017
02018 if (src->str && src->str != dest->str) {
02019 ast_free(dest->str);
02020 dest->str = ast_strdup(src->str);
02021 }
02022
02023 dest->plan = src->plan;
02024 dest->presentation = src->presentation;
02025 dest->valid = src->valid;
02026 }
02027
02028 void ast_party_number_free(struct ast_party_number *doomed)
02029 {
02030 ast_free(doomed->str);
02031 doomed->str = NULL;
02032 }
02033
02034 void ast_party_subaddress_init(struct ast_party_subaddress *init)
02035 {
02036 init->str = NULL;
02037 init->type = 0;
02038 init->odd_even_indicator = 0;
02039 init->valid = 0;
02040 }
02041
02042 void ast_party_subaddress_copy(struct ast_party_subaddress *dest, const struct ast_party_subaddress *src)
02043 {
02044 if (dest == src) {
02045
02046 return;
02047 }
02048
02049 ast_free(dest->str);
02050 dest->str = ast_strdup(src->str);
02051 dest->type = src->type;
02052 dest->odd_even_indicator = src->odd_even_indicator;
02053 dest->valid = src->valid;
02054 }
02055
02056 void ast_party_subaddress_set_init(struct ast_party_subaddress *init, const struct ast_party_subaddress *guide)
02057 {
02058 init->str = NULL;
02059 init->type = guide->type;
02060 init->odd_even_indicator = guide->odd_even_indicator;
02061 init->valid = guide->valid;
02062 }
02063
02064 void ast_party_subaddress_set(struct ast_party_subaddress *dest, const struct ast_party_subaddress *src)
02065 {
02066 if (dest == src) {
02067
02068 return;
02069 }
02070
02071 if (src->str && src->str != dest->str) {
02072 ast_free(dest->str);
02073 dest->str = ast_strdup(src->str);
02074 }
02075
02076 dest->type = src->type;
02077 dest->odd_even_indicator = src->odd_even_indicator;
02078 dest->valid = src->valid;
02079 }
02080
02081 void ast_party_subaddress_free(struct ast_party_subaddress *doomed)
02082 {
02083 ast_free(doomed->str);
02084 doomed->str = NULL;
02085 }
02086
02087 void ast_party_id_init(struct ast_party_id *init)
02088 {
02089 ast_party_name_init(&init->name);
02090 ast_party_number_init(&init->number);
02091 ast_party_subaddress_init(&init->subaddress);
02092 init->tag = NULL;
02093 }
02094
02095 void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
02096 {
02097 if (dest == src) {
02098
02099 return;
02100 }
02101
02102 ast_party_name_copy(&dest->name, &src->name);
02103 ast_party_number_copy(&dest->number, &src->number);
02104 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
02105
02106 ast_free(dest->tag);
02107 dest->tag = ast_strdup(src->tag);
02108 }
02109
02110 void ast_party_id_set_init(struct ast_party_id *init, const struct ast_party_id *guide)
02111 {
02112 ast_party_name_set_init(&init->name, &guide->name);
02113 ast_party_number_set_init(&init->number, &guide->number);
02114 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
02115 init->tag = NULL;
02116 }
02117
02118 void ast_party_id_set(struct ast_party_id *dest, const struct ast_party_id *src, const struct ast_set_party_id *update)
02119 {
02120 if (dest == src) {
02121
02122 return;
02123 }
02124
02125 if (!update || update->name) {
02126 ast_party_name_set(&dest->name, &src->name);
02127 }
02128 if (!update || update->number) {
02129 ast_party_number_set(&dest->number, &src->number);
02130 }
02131 if (!update || update->subaddress) {
02132 ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
02133 }
02134
02135 if (src->tag && src->tag != dest->tag) {
02136 ast_free(dest->tag);
02137 dest->tag = ast_strdup(src->tag);
02138 }
02139 }
02140
02141 void ast_party_id_free(struct ast_party_id *doomed)
02142 {
02143 ast_party_name_free(&doomed->name);
02144 ast_party_number_free(&doomed->number);
02145 ast_party_subaddress_free(&doomed->subaddress);
02146
02147 ast_free(doomed->tag);
02148 doomed->tag = NULL;
02149 }
02150
02151 int ast_party_id_presentation(const struct ast_party_id *id)
02152 {
02153 int number_priority;
02154 int number_value;
02155 int number_screening;
02156 int name_priority;
02157 int name_value;
02158
02159
02160 if (!id->name.valid) {
02161 name_value = AST_PRES_UNAVAILABLE;
02162 name_priority = 3;
02163 } else {
02164 name_value = id->name.presentation & AST_PRES_RESTRICTION;
02165 switch (name_value) {
02166 case AST_PRES_RESTRICTED:
02167 name_priority = 0;
02168 break;
02169 case AST_PRES_ALLOWED:
02170 name_priority = 1;
02171 break;
02172 case AST_PRES_UNAVAILABLE:
02173 name_priority = 2;
02174 break;
02175 default:
02176 name_value = AST_PRES_UNAVAILABLE;
02177 name_priority = 3;
02178 break;
02179 }
02180 }
02181
02182
02183 if (!id->number.valid) {
02184 number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
02185 number_value = AST_PRES_UNAVAILABLE;
02186 number_priority = 3;
02187 } else {
02188 number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE;
02189 number_value = id->number.presentation & AST_PRES_RESTRICTION;
02190 switch (number_value) {
02191 case AST_PRES_RESTRICTED:
02192 number_priority = 0;
02193 break;
02194 case AST_PRES_ALLOWED:
02195 number_priority = 1;
02196 break;
02197 case AST_PRES_UNAVAILABLE:
02198 number_priority = 2;
02199 break;
02200 default:
02201 number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
02202 number_value = AST_PRES_UNAVAILABLE;
02203 number_priority = 3;
02204 break;
02205 }
02206 }
02207
02208
02209 if (name_priority < number_priority) {
02210 number_value = name_value;
02211 }
02212 if (number_value == AST_PRES_UNAVAILABLE) {
02213 return AST_PRES_NUMBER_NOT_AVAILABLE;
02214 }
02215
02216 return number_value | number_screening;
02217 }
02218
02219 void ast_party_dialed_init(struct ast_party_dialed *init)
02220 {
02221 init->number.str = NULL;
02222 init->number.plan = 0;
02223 ast_party_subaddress_init(&init->subaddress);
02224 init->transit_network_select = 0;
02225 }
02226
02227 void ast_party_dialed_copy(struct ast_party_dialed *dest, const struct ast_party_dialed *src)
02228 {
02229 if (dest == src) {
02230
02231 return;
02232 }
02233
02234 ast_free(dest->number.str);
02235 dest->number.str = ast_strdup(src->number.str);
02236 dest->number.plan = src->number.plan;
02237 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
02238 dest->transit_network_select = src->transit_network_select;
02239 }
02240
02241 void ast_party_dialed_set_init(struct ast_party_dialed *init, const struct ast_party_dialed *guide)
02242 {
02243 init->number.str = NULL;
02244 init->number.plan = guide->number.plan;
02245 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
02246 init->transit_network_select = guide->transit_network_select;
02247 }
02248
02249 void ast_party_dialed_set(struct ast_party_dialed *dest, const struct ast_party_dialed *src)
02250 {
02251 if (src->number.str && src->number.str != dest->number.str) {
02252 ast_free(dest->number.str);
02253 dest->number.str = ast_strdup(src->number.str);
02254 }
02255 dest->number.plan = src->number.plan;
02256
02257 ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
02258
02259 dest->transit_network_select = src->transit_network_select;
02260 }
02261
02262 void ast_party_dialed_free(struct ast_party_dialed *doomed)
02263 {
02264 ast_free(doomed->number.str);
02265 doomed->number.str = NULL;
02266 ast_party_subaddress_free(&doomed->subaddress);
02267 }
02268
02269 void ast_party_caller_init(struct ast_party_caller *init)
02270 {
02271 ast_party_id_init(&init->id);
02272 ast_party_id_init(&init->ani);
02273 init->ani2 = 0;
02274 }
02275
02276 void ast_party_caller_copy(struct ast_party_caller *dest, const struct ast_party_caller *src)
02277 {
02278 if (dest == src) {
02279
02280 return;
02281 }
02282
02283 ast_party_id_copy(&dest->id, &src->id);
02284 ast_party_id_copy(&dest->ani, &src->ani);
02285 dest->ani2 = src->ani2;
02286 }
02287
02288 void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
02289 {
02290 ast_party_id_set_init(&init->id, &guide->id);
02291 ast_party_id_set_init(&init->ani, &guide->ani);
02292 init->ani2 = guide->ani2;
02293 }
02294
02295 void ast_party_caller_set(struct ast_party_caller *dest, const struct ast_party_caller *src, const struct ast_set_party_caller *update)
02296 {
02297 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
02298 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL);
02299 dest->ani2 = src->ani2;
02300 }
02301
02302 void ast_party_caller_free(struct ast_party_caller *doomed)
02303 {
02304 ast_party_id_free(&doomed->id);
02305 ast_party_id_free(&doomed->ani);
02306 }
02307
02308 void ast_party_connected_line_init(struct ast_party_connected_line *init)
02309 {
02310 ast_party_id_init(&init->id);
02311 ast_party_id_init(&init->ani);
02312 init->ani2 = 0;
02313 init->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
02314 }
02315
02316 void ast_party_connected_line_copy(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
02317 {
02318 if (dest == src) {
02319
02320 return;
02321 }
02322
02323 ast_party_id_copy(&dest->id, &src->id);
02324 ast_party_id_copy(&dest->ani, &src->ani);
02325 dest->ani2 = src->ani2;
02326 dest->source = src->source;
02327 }
02328
02329 void ast_party_connected_line_set_init(struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
02330 {
02331 ast_party_id_set_init(&init->id, &guide->id);
02332 ast_party_id_set_init(&init->ani, &guide->ani);
02333 init->ani2 = guide->ani2;
02334 init->source = guide->source;
02335 }
02336
02337 void ast_party_connected_line_set(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src, const struct ast_set_party_connected_line *update)
02338 {
02339 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
02340 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL);
02341 dest->ani2 = src->ani2;
02342 dest->source = src->source;
02343 }
02344
02345 void ast_party_connected_line_collect_caller(struct ast_party_connected_line *connected, struct ast_party_caller *caller)
02346 {
02347 connected->id = caller->id;
02348 connected->ani = caller->ani;
02349 connected->ani2 = caller->ani2;
02350 connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
02351 }
02352
02353 void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
02354 {
02355 ast_party_id_free(&doomed->id);
02356 ast_party_id_free(&doomed->ani);
02357 }
02358
02359 void ast_party_redirecting_init(struct ast_party_redirecting *init)
02360 {
02361 ast_party_id_init(&init->from);
02362 ast_party_id_init(&init->to);
02363 init->count = 0;
02364 init->reason = AST_REDIRECTING_REASON_UNKNOWN;
02365 }
02366
02367 void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
02368 {
02369 if (dest == src) {
02370
02371 return;
02372 }
02373
02374 ast_party_id_copy(&dest->from, &src->from);
02375 ast_party_id_copy(&dest->to, &src->to);
02376 dest->count = src->count;
02377 dest->reason = src->reason;
02378 }
02379
02380 void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const struct ast_party_redirecting *guide)
02381 {
02382 ast_party_id_set_init(&init->from, &guide->from);
02383 ast_party_id_set_init(&init->to, &guide->to);
02384 init->count = guide->count;
02385 init->reason = guide->reason;
02386 }
02387
02388 void ast_party_redirecting_set(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src, const struct ast_set_party_redirecting *update)
02389 {
02390 ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL);
02391 ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL);
02392 dest->reason = src->reason;
02393 dest->count = src->count;
02394 }
02395
02396 void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
02397 {
02398 ast_party_id_free(&doomed->from);
02399 ast_party_id_free(&doomed->to);
02400 }
02401
02402
02403 static void ast_channel_destructor(void *obj)
02404 {
02405 struct ast_channel *chan = obj;
02406 int fd;
02407 #ifdef HAVE_EPOLL
02408 int i;
02409 #endif
02410 struct ast_var_t *vardata;
02411 struct ast_frame *f;
02412 struct varshead *headp;
02413 struct ast_datastore *datastore;
02414 char device_name[AST_CHANNEL_NAME];
02415
02416 if (chan->name) {
02417
02418 ast_cel_report_event(chan, AST_CEL_CHANNEL_END, NULL, NULL, NULL);
02419 ast_cel_check_retire_linkedid(chan);
02420 }
02421
02422
02423 ast_channel_lock(chan);
02424 while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
02425
02426 ast_datastore_free(datastore);
02427 ast_channel_unlock(chan);
02428
02429
02430
02431 ast_channel_lock(chan);
02432 ast_channel_unlock(chan);
02433
02434 if (chan->tech_pvt) {
02435 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
02436 ast_free(chan->tech_pvt);
02437 }
02438
02439 if (chan->sched)
02440 sched_context_destroy(chan->sched);
02441
02442 if (chan->name) {
02443 char *dashptr;
02444
02445
02446 ast_copy_string(device_name, chan->name, sizeof(device_name));
02447 if ((dashptr = strrchr(device_name, '-'))) {
02448 *dashptr = '\0';
02449 }
02450 } else {
02451 device_name[0] = '\0';
02452 }
02453
02454
02455 if (chan->monitor)
02456 chan->monitor->stop( chan, 0 );
02457
02458
02459 if (chan->music_state)
02460 ast_moh_cleanup(chan);
02461
02462
02463 if (chan->readtrans)
02464 ast_translator_free_path(chan->readtrans);
02465 if (chan->writetrans)
02466 ast_translator_free_path(chan->writetrans);
02467 if (chan->pbx)
02468 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
02469
02470 ast_party_dialed_free(&chan->dialed);
02471 ast_party_caller_free(&chan->caller);
02472 ast_party_connected_line_free(&chan->connected);
02473 ast_party_redirecting_free(&chan->redirecting);
02474
02475
02476 if ((fd = chan->alertpipe[0]) > -1)
02477 close(fd);
02478 if ((fd = chan->alertpipe[1]) > -1)
02479 close(fd);
02480 if (chan->timer) {
02481 ast_timer_close(chan->timer);
02482 chan->timer = NULL;
02483 }
02484 #ifdef HAVE_EPOLL
02485 for (i = 0; i < AST_MAX_FDS; i++) {
02486 if (chan->epfd_data[i])
02487 free(chan->epfd_data[i]);
02488 }
02489 close(chan->epfd);
02490 #endif
02491 while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list)))
02492 ast_frfree(f);
02493
02494
02495
02496 headp = &chan->varshead;
02497 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
02498 ast_var_delete(vardata);
02499
02500 ast_app_group_discard(chan);
02501
02502
02503 ast_jb_destroy(chan);
02504
02505 if (chan->cdr) {
02506 ast_cdr_discard(chan->cdr);
02507 chan->cdr = NULL;
02508 }
02509
02510 if (chan->zone) {
02511 chan->zone = ast_tone_zone_unref(chan->zone);
02512 }
02513
02514 ast_string_field_free_memory(chan);
02515
02516 if (device_name[0]) {
02517
02518
02519
02520
02521
02522
02523
02524 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, (chan->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), device_name);
02525 }
02526 ast_atomic_fetchadd_int(&chancount, -1);
02527 }
02528
02529
02530 static void ast_dummy_channel_destructor(void *obj)
02531 {
02532 struct ast_channel *chan = obj;
02533 struct ast_var_t *vardata;
02534 struct varshead *headp;
02535 struct ast_datastore *datastore;
02536
02537
02538 while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry))) {
02539
02540 ast_datastore_free(datastore);
02541 }
02542
02543 headp = &chan->varshead;
02544
02545 ast_party_dialed_free(&chan->dialed);
02546 ast_party_caller_free(&chan->caller);
02547 ast_party_connected_line_free(&chan->connected);
02548 ast_party_redirecting_free(&chan->redirecting);
02549
02550
02551
02552 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
02553 ast_var_delete(vardata);
02554
02555 if (chan->cdr) {
02556 ast_cdr_discard(chan->cdr);
02557 chan->cdr = NULL;
02558 }
02559
02560 ast_string_field_free_memory(chan);
02561 }
02562
02563 struct ast_datastore *ast_channel_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
02564 {
02565 return ast_datastore_alloc(info, uid);
02566 }
02567
02568 int ast_channel_datastore_free(struct ast_datastore *datastore)
02569 {
02570 return ast_datastore_free(datastore);
02571 }
02572
02573 int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
02574 {
02575 struct ast_datastore *datastore = NULL, *datastore2;
02576
02577 AST_LIST_TRAVERSE(&from->datastores, datastore, entry) {
02578 if (datastore->inheritance > 0) {
02579 datastore2 = ast_datastore_alloc(datastore->info, datastore->uid);
02580 if (datastore2) {
02581 datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL;
02582 datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1;
02583 AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry);
02584 }
02585 }
02586 }
02587 return 0;
02588 }
02589
02590 int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
02591 {
02592 int res = 0;
02593
02594 AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
02595
02596 return res;
02597 }
02598
02599 int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
02600 {
02601 return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1;
02602 }
02603
02604 struct ast_datastore *ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
02605 {
02606 struct ast_datastore *datastore = NULL;
02607
02608 if (info == NULL)
02609 return NULL;
02610
02611 AST_LIST_TRAVERSE(&chan->datastores, datastore, entry) {
02612 if (datastore->info != info) {
02613 continue;
02614 }
02615
02616 if (uid == NULL) {
02617
02618 break;
02619 }
02620
02621 if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) {
02622
02623 break;
02624 }
02625 }
02626
02627 return datastore;
02628 }
02629
02630
02631 void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
02632 {
02633 #ifdef HAVE_EPOLL
02634 struct epoll_event ev;
02635 struct ast_epoll_data *aed = NULL;
02636
02637 if (chan->fds[which] > -1) {
02638 epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev);
02639 aed = chan->epfd_data[which];
02640 }
02641
02642
02643 if (fd > -1) {
02644 if (!aed && (!(aed = ast_calloc(1, sizeof(*aed)))))
02645 return;
02646
02647 chan->epfd_data[which] = aed;
02648 aed->chan = chan;
02649 aed->which = which;
02650
02651 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
02652 ev.data.ptr = aed;
02653 epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev);
02654 } else if (aed) {
02655
02656 free(aed);
02657 chan->epfd_data[which] = NULL;
02658 }
02659 #endif
02660 chan->fds[which] = fd;
02661 return;
02662 }
02663
02664
02665 void ast_poll_channel_add(struct ast_channel *chan0, struct ast_channel *chan1)
02666 {
02667 #ifdef HAVE_EPOLL
02668 struct epoll_event ev;
02669 int i = 0;
02670
02671 if (chan0->epfd == -1)
02672 return;
02673
02674
02675 for (i = 0; i < AST_MAX_FDS; i++) {
02676 if (chan1->fds[i] == -1)
02677 continue;
02678 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
02679 ev.data.ptr = chan1->epfd_data[i];
02680 epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev);
02681 }
02682
02683 #endif
02684 return;
02685 }
02686
02687
02688 void ast_poll_channel_del(struct ast_channel *chan0, struct ast_channel *chan1)
02689 {
02690 #ifdef HAVE_EPOLL
02691 struct epoll_event ev;
02692 int i = 0;
02693
02694 if (chan0->epfd == -1)
02695 return;
02696
02697 for (i = 0; i < AST_MAX_FDS; i++) {
02698 if (chan1->fds[i] == -1)
02699 continue;
02700 epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev);
02701 }
02702
02703 #endif
02704 return;
02705 }
02706
02707 void ast_channel_clear_softhangup(struct ast_channel *chan, int flag)
02708 {
02709 ast_channel_lock(chan);
02710
02711 chan->_softhangup &= ~flag;
02712
02713 if (!chan->_softhangup) {
02714 struct ast_frame *fr;
02715
02716
02717
02718
02719
02720
02721 fr = AST_LIST_LAST(&chan->readq);
02722 if (fr && fr->frametype == AST_FRAME_CONTROL &&
02723 fr->subclass.integer == AST_CONTROL_END_OF_Q) {
02724 AST_LIST_REMOVE(&chan->readq, fr, frame_list);
02725 ast_frfree(fr);
02726 }
02727 }
02728
02729 ast_channel_unlock(chan);
02730 }
02731
02732
02733 int ast_softhangup_nolock(struct ast_channel *chan, int cause)
02734 {
02735 ast_debug(1, "Soft-Hanging up channel '%s'\n", chan->name);
02736
02737 chan->_softhangup |= cause;
02738 ast_queue_frame(chan, &ast_null_frame);
02739
02740 if (ast_test_flag(chan, AST_FLAG_BLOCKING))
02741 pthread_kill(chan->blocker, SIGURG);
02742 return 0;
02743 }
02744
02745
02746 int ast_softhangup(struct ast_channel *chan, int cause)
02747 {
02748 int res;
02749
02750 ast_channel_lock(chan);
02751 res = ast_softhangup_nolock(chan, cause);
02752 ast_channel_unlock(chan);
02753
02754 return res;
02755 }
02756
02757 static void free_translation(struct ast_channel *clonechan)
02758 {
02759 if (clonechan->writetrans)
02760 ast_translator_free_path(clonechan->writetrans);
02761 if (clonechan->readtrans)
02762 ast_translator_free_path(clonechan->readtrans);
02763 clonechan->writetrans = NULL;
02764 clonechan->readtrans = NULL;
02765 clonechan->rawwriteformat = clonechan->nativeformats;
02766 clonechan->rawreadformat = clonechan->nativeformats;
02767 }
02768
02769 void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
02770 {
02771 struct ast_channel *bridge;
02772
02773 ast_channel_lock(chan);
02774 if (force || ast_strlen_zero(chan->hangupsource)) {
02775 ast_string_field_set(chan, hangupsource, source);
02776 }
02777 bridge = ast_bridged_channel(chan);
02778 if (bridge) {
02779 ast_channel_ref(bridge);
02780 }
02781 ast_channel_unlock(chan);
02782
02783 if (bridge) {
02784 ast_channel_lock(bridge);
02785 if (force || ast_strlen_zero(bridge->hangupsource)) {
02786 ast_string_field_set(bridge, hangupsource, source);
02787 }
02788 ast_channel_unlock(bridge);
02789 ast_channel_unref(bridge);
02790 }
02791 }
02792
02793 static void destroy_hooks(struct ast_channel *chan)
02794 {
02795 if (chan->audiohooks) {
02796 ast_audiohook_detach_list(chan->audiohooks);
02797 chan->audiohooks = NULL;
02798 }
02799
02800 ast_framehook_list_destroy(chan);
02801 }
02802
02803
02804 int ast_hangup(struct ast_channel *chan)
02805 {
02806 char extra_str[64];
02807 int was_zombie;
02808
02809 ast_autoservice_stop(chan);
02810
02811 ast_channel_lock(chan);
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821 while (chan->masq) {
02822 ast_channel_unlock(chan);
02823 ast_do_masquerade(chan);
02824 ast_channel_lock(chan);
02825 }
02826
02827 if (chan->masqr) {
02828
02829
02830
02831
02832
02833 ast_set_flag(chan, AST_FLAG_ZOMBIE);
02834 destroy_hooks(chan);
02835 ast_channel_unlock(chan);
02836 return 0;
02837 }
02838
02839
02840 if (!(was_zombie = ast_test_flag(chan, AST_FLAG_ZOMBIE))) {
02841 ast_set_flag(chan, AST_FLAG_ZOMBIE);
02842 }
02843
02844 ast_channel_unlock(chan);
02845 ao2_unlink(channels, chan);
02846 ast_channel_lock(chan);
02847
02848 destroy_hooks(chan);
02849
02850 free_translation(chan);
02851
02852 if (chan->stream) {
02853 ast_closestream(chan->stream);
02854 chan->stream = NULL;
02855 }
02856
02857 if (chan->vstream) {
02858 ast_closestream(chan->vstream);
02859 chan->vstream = NULL;
02860 }
02861 if (chan->sched) {
02862 sched_context_destroy(chan->sched);
02863 chan->sched = NULL;
02864 }
02865
02866 if (chan->generatordata) {
02867 if (chan->generator && chan->generator->release) {
02868 chan->generator->release(chan, chan->generatordata);
02869 }
02870 }
02871 chan->generatordata = NULL;
02872 chan->generator = NULL;
02873
02874 snprintf(extra_str, sizeof(extra_str), "%d,%s,%s", chan->hangupcause, chan->hangupsource, S_OR(pbx_builtin_getvar_helper(chan, "DIALSTATUS"), ""));
02875 ast_cel_report_event(chan, AST_CEL_HANGUP, NULL, extra_str, NULL);
02876
02877 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
02878 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
02879 "is blocked by thread %ld in procedure %s! Expect a failure\n",
02880 (long) pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
02881 ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0);
02882 }
02883 if (!was_zombie) {
02884 ast_debug(1, "Hanging up channel '%s'\n", chan->name);
02885
02886 if (chan->tech->hangup) {
02887 chan->tech->hangup(chan);
02888 }
02889 } else {
02890 ast_debug(1, "Hanging up zombie '%s'\n", chan->name);
02891 }
02892
02893 ast_channel_unlock(chan);
02894
02895 ast_cc_offer(chan);
02896 ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup",
02897 "Channel: %s\r\n"
02898 "Uniqueid: %s\r\n"
02899 "CallerIDNum: %s\r\n"
02900 "CallerIDName: %s\r\n"
02901 "ConnectedLineNum: %s\r\n"
02902 "ConnectedLineName: %s\r\n"
02903 "Cause: %d\r\n"
02904 "Cause-txt: %s\r\n",
02905 chan->name,
02906 chan->uniqueid,
02907 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"),
02908 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"),
02909 S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, "<unknown>"),
02910 S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, "<unknown>"),
02911 chan->hangupcause,
02912 ast_cause2str(chan->hangupcause)
02913 );
02914
02915 if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) &&
02916 !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) &&
02917 (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) {
02918 ast_channel_lock(chan);
02919 ast_cdr_end(chan->cdr);
02920 ast_cdr_detach(chan->cdr);
02921 chan->cdr = NULL;
02922 ast_channel_unlock(chan);
02923 }
02924
02925 ast_channel_unref(chan);
02926
02927 return 0;
02928 }
02929
02930 int ast_raw_answer(struct ast_channel *chan, int cdr_answer)
02931 {
02932 int res = 0;
02933
02934 ast_channel_lock(chan);
02935
02936
02937 if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
02938 ast_channel_unlock(chan);
02939 return 0;
02940 }
02941
02942
02943 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02944 ast_channel_unlock(chan);
02945 return -1;
02946 }
02947
02948 ast_channel_unlock(chan);
02949
02950 switch (chan->_state) {
02951 case AST_STATE_RINGING:
02952 case AST_STATE_RING:
02953 ast_channel_lock(chan);
02954 if (chan->tech->answer) {
02955 res = chan->tech->answer(chan);
02956 }
02957 ast_setstate(chan, AST_STATE_UP);
02958 if (cdr_answer) {
02959 ast_cdr_answer(chan->cdr);
02960 }
02961 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
02962 ast_channel_unlock(chan);
02963 break;
02964 case AST_STATE_UP:
02965 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
02966
02967
02968
02969 if (cdr_answer) {
02970 ast_cdr_answer(chan->cdr);
02971 }
02972 break;
02973 default:
02974 break;
02975 }
02976
02977 ast_indicate(chan, -1);
02978
02979 return res;
02980 }
02981
02982 int __ast_answer(struct ast_channel *chan, unsigned int delay, int cdr_answer)
02983 {
02984 int res = 0;
02985 enum ast_channel_state old_state;
02986
02987 old_state = chan->_state;
02988 if ((res = ast_raw_answer(chan, cdr_answer))) {
02989 return res;
02990 }
02991
02992 switch (old_state) {
02993 case AST_STATE_RINGING:
02994 case AST_STATE_RING:
02995
02996
02997
02998 do {
02999 AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
03000 struct ast_frame *cur, *new;
03001 int timeout_ms = MAX(delay, 500);
03002 unsigned int done = 0;
03003 struct timeval start;
03004
03005 AST_LIST_HEAD_INIT_NOLOCK(&frames);
03006
03007 start = ast_tvnow();
03008 for (;;) {
03009 int ms = ast_remaining_ms(start, timeout_ms);
03010 ms = ast_waitfor(chan, ms);
03011 if (ms < 0) {
03012 ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", chan->name, strerror(errno));
03013 res = -1;
03014 break;
03015 }
03016 if (ms == 0) {
03017 ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", chan->name, MAX(delay, 500));
03018 break;
03019 }
03020 cur = ast_read(chan);
03021 if (!cur || ((cur->frametype == AST_FRAME_CONTROL) &&
03022 (cur->subclass.integer == AST_CONTROL_HANGUP))) {
03023 if (cur) {
03024 ast_frfree(cur);
03025 }
03026 res = -1;
03027 ast_debug(2, "Hangup of channel %s detected in answer routine\n", chan->name);
03028 break;
03029 }
03030
03031 if ((new = ast_frisolate(cur)) != cur) {
03032 ast_frfree(cur);
03033 }
03034
03035 AST_LIST_INSERT_HEAD(&frames, new, frame_list);
03036
03037
03038
03039
03040
03041 if (delay) {
03042 continue;
03043 }
03044
03045 switch (new->frametype) {
03046
03047 case AST_FRAME_VOICE:
03048 case AST_FRAME_VIDEO:
03049 case AST_FRAME_TEXT:
03050 case AST_FRAME_DTMF_BEGIN:
03051 case AST_FRAME_DTMF_END:
03052 case AST_FRAME_IMAGE:
03053 case AST_FRAME_HTML:
03054 case AST_FRAME_MODEM:
03055 done = 1;
03056 break;
03057 case AST_FRAME_CONTROL:
03058 case AST_FRAME_IAX:
03059 case AST_FRAME_NULL:
03060 case AST_FRAME_CNG:
03061 break;
03062 }
03063
03064 if (done) {
03065 break;
03066 }
03067 }
03068
03069 if (res == 0) {
03070 ast_channel_lock(chan);
03071 while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) {
03072 ast_queue_frame_head(chan, cur);
03073 ast_frfree(cur);
03074 }
03075 ast_channel_unlock(chan);
03076 }
03077 } while (0);
03078 break;
03079 default:
03080 break;
03081 }
03082
03083 return res;
03084 }
03085
03086 int ast_answer(struct ast_channel *chan)
03087 {
03088 return __ast_answer(chan, 0, 1);
03089 }
03090
03091 void ast_deactivate_generator(struct ast_channel *chan)
03092 {
03093 ast_channel_lock(chan);
03094 if (chan->generatordata) {
03095 if (chan->generator && chan->generator->release)
03096 chan->generator->release(chan, chan->generatordata);
03097 chan->generatordata = NULL;
03098 chan->generator = NULL;
03099 ast_channel_set_fd(chan, AST_GENERATOR_FD, -1);
03100 ast_clear_flag(chan, AST_FLAG_WRITE_INT);
03101 ast_settimeout(chan, 0, NULL, NULL);
03102 }
03103 ast_channel_unlock(chan);
03104 }
03105
03106 static int generator_force(const void *data)
03107 {
03108
03109 void *tmp;
03110 int res;
03111 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
03112 struct ast_channel *chan = (struct ast_channel *)data;
03113
03114 ast_channel_lock(chan);
03115 tmp = chan->generatordata;
03116 chan->generatordata = NULL;
03117 if (chan->generator)
03118 generate = chan->generator->generate;
03119 ast_channel_unlock(chan);
03120
03121 if (!tmp || !generate)
03122 return 0;
03123
03124 res = generate(chan, tmp, 0, ast_format_rate(chan->writeformat & AST_FORMAT_AUDIO_MASK) / 50);
03125
03126 ast_channel_lock(chan);
03127 if (chan->generator && generate == chan->generator->generate) {
03128 chan->generatordata = tmp;
03129 }
03130 ast_channel_unlock(chan);
03131
03132 if (res) {
03133 ast_debug(1, "Auto-deactivating generator\n");
03134 ast_deactivate_generator(chan);
03135 }
03136
03137 return 0;
03138 }
03139
03140 int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
03141 {
03142 int res = 0;
03143
03144 ast_channel_lock(chan);
03145 if (chan->generatordata) {
03146 if (chan->generator && chan->generator->release)
03147 chan->generator->release(chan, chan->generatordata);
03148 chan->generatordata = NULL;
03149 }
03150 if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
03151 res = -1;
03152 }
03153 if (!res) {
03154 ast_settimeout(chan, 50, generator_force, chan);
03155 chan->generator = gen;
03156 }
03157 ast_channel_unlock(chan);
03158
03159 ast_prod(chan);
03160
03161 return res;
03162 }
03163
03164
03165 int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
03166 {
03167 int winner = -1;
03168 ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
03169 return winner;
03170 }
03171
03172
03173 #ifdef HAVE_EPOLL
03174 static struct ast_channel *ast_waitfor_nandfds_classic(struct ast_channel **c, int n, int *fds, int nfds,
03175 int *exception, int *outfd, int *ms)
03176 #else
03177 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
03178 int *exception, int *outfd, int *ms)
03179 #endif
03180 {
03181 struct timeval start = { 0 , 0 };
03182 struct pollfd *pfds = NULL;
03183 int res;
03184 long rms;
03185 int x, y, max;
03186 int sz;
03187 struct timeval now = { 0, 0 };
03188 struct timeval whentohangup = { 0, 0 }, diff;
03189 struct ast_channel *winner = NULL;
03190 struct fdmap {
03191 int chan;
03192 int fdno;
03193 } *fdmap = NULL;
03194
03195 if (outfd)
03196 *outfd = -99999;
03197 if (exception)
03198 *exception = 0;
03199
03200 if ((sz = n * AST_MAX_FDS + nfds)) {
03201 pfds = ast_alloca(sizeof(*pfds) * sz);
03202 fdmap = ast_alloca(sizeof(*fdmap) * sz);
03203 } else {
03204
03205 return NULL;
03206 }
03207
03208
03209 for (x = 0; x < n; x++) {
03210 while (c[x]->masq) {
03211 ast_do_masquerade(c[x]);
03212 }
03213
03214 ast_channel_lock(c[x]);
03215 if (!ast_tvzero(c[x]->whentohangup)) {
03216 if (ast_tvzero(whentohangup))
03217 now = ast_tvnow();
03218 diff = ast_tvsub(c[x]->whentohangup, now);
03219 if (diff.tv_sec < 0 || ast_tvzero(diff)) {
03220 ast_test_suite_event_notify("HANGUP_TIME", "Channel: %s", c[x]->name);
03221
03222 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03223 ast_channel_unlock(c[x]);
03224 return c[x];
03225 }
03226 if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0)
03227 whentohangup = diff;
03228 }
03229 ast_channel_unlock(c[x]);
03230 }
03231
03232 rms = *ms;
03233
03234 if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX / 1000) {
03235 rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000;
03236 if (*ms >= 0 && *ms < rms) {
03237 rms = *ms;
03238 }
03239 } else if (!ast_tvzero(whentohangup) && rms < 0) {
03240
03241 rms = INT_MAX;
03242 }
03243
03244
03245
03246
03247
03248 max = 0;
03249 for (x = 0; x < n; x++) {
03250 for (y = 0; y < AST_MAX_FDS; y++) {
03251 fdmap[max].fdno = y;
03252 fdmap[max].chan = x;
03253 max += ast_add_fd(&pfds[max], c[x]->fds[y]);
03254 }
03255 CHECK_BLOCKING(c[x]);
03256 }
03257
03258 for (x = 0; x < nfds; x++) {
03259 fdmap[max].chan = -1;
03260 max += ast_add_fd(&pfds[max], fds[x]);
03261 }
03262
03263 if (*ms > 0)
03264 start = ast_tvnow();
03265
03266 if (sizeof(int) == 4) {
03267 do {
03268 int kbrms = rms;
03269 if (kbrms > 600000)
03270 kbrms = 600000;
03271 res = ast_poll(pfds, max, kbrms);
03272 if (!res)
03273 rms -= kbrms;
03274 } while (!res && (rms > 0));
03275 } else {
03276 res = ast_poll(pfds, max, rms);
03277 }
03278 for (x = 0; x < n; x++)
03279 ast_clear_flag(c[x], AST_FLAG_BLOCKING);
03280 if (res < 0) {
03281 if (errno != EINTR)
03282 *ms = -1;
03283 return NULL;
03284 }
03285 if (!ast_tvzero(whentohangup)) {
03286 now = ast_tvnow();
03287 for (x = 0; x < n; x++) {
03288 if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) {
03289 ast_test_suite_event_notify("HANGUP_TIME", "Channel: %s", c[x]->name);
03290 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03291 if (winner == NULL)
03292 winner = c[x];
03293 }
03294 }
03295 }
03296 if (res == 0) {
03297 *ms = 0;
03298 return winner;
03299 }
03300
03301
03302
03303
03304
03305 for (x = 0; x < max; x++) {
03306 res = pfds[x].revents;
03307 if (res == 0)
03308 continue;
03309 if (fdmap[x].chan >= 0) {
03310 winner = c[fdmap[x].chan];
03311 if (res & POLLPRI)
03312 ast_set_flag(winner, AST_FLAG_EXCEPTION);
03313 else
03314 ast_clear_flag(winner, AST_FLAG_EXCEPTION);
03315 winner->fdno = fdmap[x].fdno;
03316 } else {
03317 if (outfd)
03318 *outfd = pfds[x].fd;
03319 if (exception)
03320 *exception = (res & POLLPRI) ? -1 : 0;
03321 winner = NULL;
03322 }
03323 }
03324 if (*ms > 0) {
03325 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03326 if (*ms < 0)
03327 *ms = 0;
03328 }
03329 return winner;
03330 }
03331
03332 #ifdef HAVE_EPOLL
03333 static struct ast_channel *ast_waitfor_nandfds_simple(struct ast_channel *chan, int *ms)
03334 {
03335 struct timeval start = { 0 , 0 };
03336 int res = 0;
03337 struct epoll_event ev[1];
03338 long diff, rms = *ms;
03339 struct ast_channel *winner = NULL;
03340 struct ast_epoll_data *aed = NULL;
03341
03342
03343
03344 while (chan->masq) {
03345 ast_do_masquerade(chan);
03346 }
03347
03348 ast_channel_lock(chan);
03349
03350 if (!ast_tvzero(chan->whentohangup)) {
03351 if ((diff = ast_tvdiff_ms(chan->whentohangup, ast_tvnow())) < 0) {
03352
03353 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03354 ast_channel_unlock(chan);
03355 return NULL;
03356 }
03357
03358 if (rms > diff)
03359 rms = diff;
03360 }
03361
03362 ast_channel_unlock(chan);
03363
03364
03365 CHECK_BLOCKING(chan);
03366
03367 if (*ms > 0)
03368 start = ast_tvnow();
03369
03370
03371 res = epoll_wait(chan->epfd, ev, 1, rms);
03372
03373
03374 ast_clear_flag(chan, AST_FLAG_BLOCKING);
03375
03376
03377 if (res < 0) {
03378 if (errno != EINTR)
03379 *ms = -1;
03380 return NULL;
03381 }
03382
03383
03384 if (!ast_tvzero(chan->whentohangup)) {
03385 if (ast_tvdiff_ms(ast_tvnow(), chan->whentohangup) >= 0) {
03386 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03387 winner = chan;
03388 }
03389 }
03390
03391
03392 if (!res) {
03393 *ms = 0;
03394 return winner;
03395 }
03396
03397
03398 aed = ev[0].data.ptr;
03399 chan->fdno = aed->which;
03400 if (ev[0].events & EPOLLPRI)
03401 ast_set_flag(chan, AST_FLAG_EXCEPTION);
03402 else
03403 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03404
03405 if (*ms > 0) {
03406 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03407 if (*ms < 0)
03408 *ms = 0;
03409 }
03410
03411 return chan;
03412 }
03413
03414 static struct ast_channel *ast_waitfor_nandfds_complex(struct ast_channel **c, int n, int *ms)
03415 {
03416 struct timeval start = { 0 , 0 };
03417 int res = 0, i;
03418 struct epoll_event ev[25] = { { 0, } };
03419 struct timeval now = { 0, 0 };
03420 long whentohangup = 0, diff = 0, rms = *ms;
03421 struct ast_channel *winner = NULL;
03422
03423 for (i = 0; i < n; i++) {
03424 while (c[i]->masq) {
03425 ast_do_masquerade(c[i]);
03426 }
03427
03428 ast_channel_lock(c[i]);
03429 if (!ast_tvzero(c[i]->whentohangup)) {
03430 if (whentohangup == 0)
03431 now = ast_tvnow();
03432 if ((diff = ast_tvdiff_ms(c[i]->whentohangup, now)) < 0) {
03433 c[i]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03434 ast_channel_unlock(c[i]);
03435 return c[i];
03436 }
03437 if (!whentohangup || whentohangup > diff)
03438 whentohangup = diff;
03439 }
03440 ast_channel_unlock(c[i]);
03441 CHECK_BLOCKING(c[i]);
03442 }
03443
03444 rms = *ms;
03445 if (whentohangup) {
03446 rms = whentohangup;
03447 if (*ms >= 0 && *ms < rms)
03448 rms = *ms;
03449 }
03450
03451 if (*ms > 0)
03452 start = ast_tvnow();
03453
03454 res = epoll_wait(c[0]->epfd, ev, 25, rms);
03455
03456 for (i = 0; i < n; i++)
03457 ast_clear_flag(c[i], AST_FLAG_BLOCKING);
03458
03459 if (res < 0) {
03460 if (errno != EINTR)
03461 *ms = -1;
03462 return NULL;
03463 }
03464
03465 if (whentohangup) {
03466 now = ast_tvnow();
03467 for (i = 0; i < n; i++) {
03468 if (!ast_tvzero(c[i]->whentohangup) && ast_tvdiff_ms(now, c[i]->whentohangup) >= 0) {
03469 c[i]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03470 if (!winner)
03471 winner = c[i];
03472 }
03473 }
03474 }
03475
03476 if (!res) {
03477 *ms = 0;
03478 return winner;
03479 }
03480
03481 for (i = 0; i < res; i++) {
03482 struct ast_epoll_data *aed = ev[i].data.ptr;
03483
03484 if (!ev[i].events || !aed)
03485 continue;
03486
03487 winner = aed->chan;
03488 if (ev[i].events & EPOLLPRI)
03489 ast_set_flag(winner, AST_FLAG_EXCEPTION);
03490 else
03491 ast_clear_flag(winner, AST_FLAG_EXCEPTION);
03492 winner->fdno = aed->which;
03493 }
03494
03495 if (*ms > 0) {
03496 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03497 if (*ms < 0)
03498 *ms = 0;
03499 }
03500
03501 return winner;
03502 }
03503
03504 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
03505 int *exception, int *outfd, int *ms)
03506 {
03507
03508 if (outfd)
03509 *outfd = -99999;
03510 if (exception)
03511 *exception = 0;
03512
03513
03514 if (!n || nfds || c[0]->epfd == -1)
03515 return ast_waitfor_nandfds_classic(c, n, fds, nfds, exception, outfd, ms);
03516 else if (!nfds && n == 1)
03517 return ast_waitfor_nandfds_simple(c[0], ms);
03518 else
03519 return ast_waitfor_nandfds_complex(c, n, ms);
03520 }
03521 #endif
03522
03523 struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
03524 {
03525 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
03526 }
03527
03528 int ast_waitfor(struct ast_channel *c, int ms)
03529 {
03530 if (ms < 0) {
03531 do {
03532 ms = 100000;
03533 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
03534 } while (!ms);
03535 } else {
03536 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
03537 }
03538 return ms;
03539 }
03540
03541 int ast_waitfordigit(struct ast_channel *c, int ms)
03542 {
03543 return ast_waitfordigit_full(c, ms, -1, -1);
03544 }
03545
03546 int ast_settimeout(struct ast_channel *c, unsigned int rate, int (*func)(const void *data), void *data)
03547 {
03548 return ast_settimeout_full(c, rate, func, data, 0);
03549 }
03550
03551 int ast_settimeout_full(struct ast_channel *c, unsigned int rate, int (*func)(const void *data), void *data, unsigned int is_ao2_obj)
03552 {
03553 int res;
03554 unsigned int real_rate = rate, max_rate;
03555
03556 ast_channel_lock(c);
03557
03558 if (c->timingfd == -1) {
03559 ast_channel_unlock(c);
03560 return -1;
03561 }
03562
03563 if (!func) {
03564 rate = 0;
03565 data = NULL;
03566 }
03567
03568 if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) {
03569 real_rate = max_rate;
03570 }
03571
03572 ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate);
03573
03574 res = ast_timer_set_rate(c->timer, real_rate);
03575
03576 if (c->timingdata && ast_test_flag(c, AST_FLAG_TIMINGDATA_IS_AO2_OBJ)) {
03577 ao2_ref(c->timingdata, -1);
03578 }
03579
03580 c->timingfunc = func;
03581 c->timingdata = data;
03582
03583 if (data && is_ao2_obj) {
03584 ao2_ref(data, 1);
03585 ast_set_flag(c, AST_FLAG_TIMINGDATA_IS_AO2_OBJ);
03586 } else {
03587 ast_clear_flag(c, AST_FLAG_TIMINGDATA_IS_AO2_OBJ);
03588 }
03589
03590 if (func == NULL && rate == 0 && c->fdno == AST_TIMING_FD) {
03591
03592
03593
03594
03595
03596
03597 c->fdno = -1;
03598 }
03599
03600 ast_channel_unlock(c);
03601
03602 return res;
03603 }
03604
03605 int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, int cmdfd)
03606 {
03607 struct timeval start = ast_tvnow();
03608 int ms;
03609
03610
03611 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03612 return -1;
03613
03614
03615 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
03616
03617
03618
03619
03620 while ((ms = ast_remaining_ms(start, timeout_ms))) {
03621 struct ast_channel *rchan;
03622 int outfd = -1;
03623
03624 errno = 0;
03625
03626
03627
03628 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
03629
03630 if (!rchan && outfd < 0 && ms) {
03631 if (errno == 0 || errno == EINTR)
03632 continue;
03633 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
03634 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03635 return -1;
03636 } else if (outfd > -1) {
03637
03638 ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n");
03639 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03640 return 1;
03641 } else if (rchan) {
03642 int res;
03643 struct ast_frame *f = ast_read(c);
03644 if (!f)
03645 return -1;
03646
03647 switch (f->frametype) {
03648 case AST_FRAME_DTMF_BEGIN:
03649 break;
03650 case AST_FRAME_DTMF_END:
03651 res = f->subclass.integer;
03652 ast_frfree(f);
03653 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03654 return res;
03655 case AST_FRAME_CONTROL:
03656 switch (f->subclass.integer) {
03657 case AST_CONTROL_HANGUP:
03658 ast_frfree(f);
03659 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03660 return -1;
03661 case AST_CONTROL_RINGING:
03662 case AST_CONTROL_ANSWER:
03663 case AST_CONTROL_SRCUPDATE:
03664 case AST_CONTROL_SRCCHANGE:
03665 case AST_CONTROL_CONNECTED_LINE:
03666 case AST_CONTROL_REDIRECTING:
03667 case AST_CONTROL_UPDATE_RTP_PEER:
03668 case AST_CONTROL_HOLD:
03669 case AST_CONTROL_UNHOLD:
03670 case -1:
03671
03672 break;
03673 default:
03674 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer);
03675 break;
03676 }
03677 break;
03678 case AST_FRAME_VOICE:
03679
03680 if (audiofd > -1) {
03681 if (write(audiofd, f->data.ptr, f->datalen) < 0) {
03682 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
03683 }
03684 }
03685 default:
03686
03687 break;
03688 }
03689 ast_frfree(f);
03690 }
03691 }
03692
03693 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03694
03695 return 0;
03696 }
03697
03698 static void send_dtmf_event(struct ast_channel *chan, const char *direction, const char digit, const char *begin, const char *end)
03699 {
03700 ast_manager_event(chan, EVENT_FLAG_DTMF,
03701 "DTMF",
03702 "Channel: %s\r\n"
03703 "Uniqueid: %s\r\n"
03704 "Digit: %c\r\n"
03705 "Direction: %s\r\n"
03706 "Begin: %s\r\n"
03707 "End: %s\r\n",
03708 chan->name, chan->uniqueid, digit, direction, begin, end);
03709 }
03710
03711 static void ast_read_generator_actions(struct ast_channel *chan, struct ast_frame *f)
03712 {
03713 if (chan->generator && chan->generator->generate && chan->generatordata && !ast_internal_timing_enabled(chan)) {
03714 void *tmp = chan->generatordata;
03715 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = chan->generator->generate;
03716 int res;
03717 int samples;
03718
03719 if (chan->timingfunc) {
03720 ast_debug(1, "Generator got voice, switching to phase locked mode\n");
03721 ast_settimeout(chan, 0, NULL, NULL);
03722 }
03723
03724 chan->generatordata = NULL;
03725
03726 if (f->subclass.codec != chan->writeformat) {
03727 float factor;
03728 factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass.codec));
03729 samples = (int) ( ((float) f->samples) * factor );
03730 } else {
03731 samples = f->samples;
03732 }
03733
03734
03735
03736
03737
03738
03739
03740
03741
03742 ast_channel_unlock(chan);
03743 res = generate(chan, tmp, f->datalen, samples);
03744 ast_channel_lock(chan);
03745 chan->generatordata = tmp;
03746 if (res) {
03747 ast_debug(1, "Auto-deactivating generator\n");
03748 ast_deactivate_generator(chan);
03749 }
03750
03751 } else if (f->frametype == AST_FRAME_CNG) {
03752 if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
03753 ast_debug(1, "Generator got CNG, switching to timed mode\n");
03754 ast_settimeout(chan, 50, generator_force, chan);
03755 }
03756 }
03757 }
03758
03759 static inline void queue_dtmf_readq(struct ast_channel *chan, struct ast_frame *f)
03760 {
03761 struct ast_frame *fr = &chan->dtmff;
03762
03763 fr->frametype = AST_FRAME_DTMF_END;
03764 fr->subclass.integer = f->subclass.integer;
03765 fr->len = f->len;
03766
03767
03768
03769
03770
03771 ast_queue_frame(chan, fr);
03772 }
03773
03774
03775
03776
03777 static inline int should_skip_dtmf(struct ast_channel *chan)
03778 {
03779 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) {
03780
03781
03782 return 1;
03783 }
03784
03785 if (!ast_tvzero(chan->dtmf_tv) &&
03786 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
03787
03788
03789 return 1;
03790 }
03791
03792 return 0;
03793 }
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804 static inline int calc_monitor_jump(int samples, int sample_rate, int seek_rate)
03805 {
03806 int diff = sample_rate - seek_rate;
03807
03808 if (diff > 0) {
03809 samples = samples / (float) (sample_rate / seek_rate);
03810 } else if (diff < 0) {
03811 samples = samples * (float) (seek_rate / sample_rate);
03812 }
03813
03814 return samples;
03815 }
03816
03817 static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
03818 {
03819 struct ast_frame *f = NULL;
03820 int blah;
03821 int prestate;
03822 int cause = 0;
03823
03824
03825
03826
03827
03828 if (chan->masq) {
03829 ast_do_masquerade(chan);
03830 return &ast_null_frame;
03831 }
03832
03833
03834 ast_channel_lock(chan);
03835
03836
03837 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
03838 if (chan->generator)
03839 ast_deactivate_generator(chan);
03840
03841
03842
03843
03844
03845
03846
03847
03848
03849
03850 if (chan->_softhangup) {
03851 ast_queue_control(chan, AST_CONTROL_END_OF_Q);
03852 } else {
03853 goto done;
03854 }
03855 } else {
03856 #ifdef AST_DEVMODE
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869 if (chan->fdno == -1) {
03870 ast_log(LOG_ERROR,
03871 "ast_read() on chan '%s' called with no recorded file descriptor.\n",
03872 chan->name);
03873 }
03874 #endif
03875 }
03876
03877 prestate = chan->_state;
03878 if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD) {
03879 enum ast_timer_event res;
03880
03881 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03882
03883 res = ast_timer_get_event(chan->timer);
03884
03885 switch (res) {
03886 case AST_TIMING_EVENT_EXPIRED:
03887 if (ast_timer_ack(chan->timer, 1) < 0) {
03888 ast_log(LOG_ERROR, "Failed to acknoweldge timer in ast_read\n");
03889 goto done;
03890 }
03891
03892 if (chan->timingfunc) {
03893
03894 int (*func)(const void *) = chan->timingfunc;
03895 void *data = chan->timingdata;
03896 int got_ref = 0;
03897 if (data && ast_test_flag(chan, AST_FLAG_TIMINGDATA_IS_AO2_OBJ)) {
03898 ao2_ref(data, 1);
03899 got_ref = 1;
03900 }
03901 chan->fdno = -1;
03902 ast_channel_unlock(chan);
03903 func(data);
03904 if (got_ref) {
03905 ao2_ref(data, -1);
03906 }
03907 } else {
03908 ast_timer_set_rate(chan->timer, 0);
03909 chan->fdno = -1;
03910 ast_channel_unlock(chan);
03911 }
03912
03913
03914 return &ast_null_frame;
03915
03916 case AST_TIMING_EVENT_CONTINUOUS:
03917 if (AST_LIST_EMPTY(&chan->readq) ||
03918 !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
03919 ast_timer_disable_continuous(chan->timer);
03920 }
03921 break;
03922 }
03923
03924 } else if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
03925
03926
03927
03928 void *tmp = chan->generatordata;
03929 chan->generatordata = NULL;
03930 chan->generator->generate(chan, tmp, -1, -1);
03931 chan->generatordata = tmp;
03932 f = &ast_null_frame;
03933 chan->fdno = -1;
03934 goto done;
03935 }
03936
03937
03938
03939 if (chan->alertpipe[0] > -1) {
03940 int flags = fcntl(chan->alertpipe[0], F_GETFL);
03941
03942
03943 if ((flags & O_NONBLOCK) == 0) {
03944 ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", chan->name);
03945 if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
03946 ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
03947 f = &ast_null_frame;
03948 goto done;
03949 }
03950 }
03951 if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) {
03952 if (errno != EINTR && errno != EAGAIN)
03953 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
03954 }
03955 }
03956
03957
03958
03959 if (!AST_LIST_EMPTY(&chan->readq)) {
03960 int skip_dtmf = should_skip_dtmf(chan);
03961
03962 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, f, frame_list) {
03963
03964
03965
03966
03967 if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) {
03968 continue;
03969 }
03970
03971 AST_LIST_REMOVE_CURRENT(frame_list);
03972 break;
03973 }
03974 AST_LIST_TRAVERSE_SAFE_END;
03975
03976 if (!f) {
03977
03978 f = &ast_null_frame;
03979 if (chan->alertpipe[0] > -1) {
03980 int poke = 0;
03981
03982
03983 if (write(chan->alertpipe[1], &poke, sizeof(poke)) != sizeof(poke)) {
03984 ast_log(LOG_ERROR, "Failed to write to alertpipe: %s\n", strerror(errno));
03985 }
03986 }
03987 }
03988
03989
03990
03991 if (f->frametype == AST_FRAME_CONTROL) {
03992 switch (f->subclass.integer) {
03993 case AST_CONTROL_HANGUP:
03994 chan->_softhangup |= AST_SOFTHANGUP_DEV;
03995 cause = f->data.uint32;
03996
03997 case AST_CONTROL_END_OF_Q:
03998 ast_frfree(f);
03999 f = NULL;
04000 break;
04001 default:
04002 break;
04003 }
04004 }
04005 } else {
04006 chan->blocker = pthread_self();
04007 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
04008 if (chan->tech->exception)
04009 f = chan->tech->exception(chan);
04010 else {
04011 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
04012 f = &ast_null_frame;
04013 }
04014
04015 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
04016 } else if (chan->tech && chan->tech->read)
04017 f = chan->tech->read(chan);
04018 else
04019 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
04020 }
04021
04022
04023
04024
04025
04026 chan->fdno = -1;
04027
04028
04029
04030 f = ast_framehook_list_read_event(chan->framehooks, f);
04031
04032 if (f) {
04033 struct ast_frame *readq_tail = AST_LIST_LAST(&chan->readq);
04034 struct ast_control_read_action_payload *read_action_payload;
04035 struct ast_party_connected_line connected;
04036
04037
04038
04039
04040 if (AST_LIST_NEXT(f, frame_list)) {
04041 ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list));
04042 ast_frfree(AST_LIST_NEXT(f, frame_list));
04043 AST_LIST_NEXT(f, frame_list) = NULL;
04044 }
04045
04046 switch (f->frametype) {
04047 case AST_FRAME_CONTROL:
04048 if (f->subclass.integer == AST_CONTROL_ANSWER) {
04049 if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
04050 ast_debug(1, "Ignoring answer on an inbound call!\n");
04051 ast_frfree(f);
04052 f = &ast_null_frame;
04053 } else if (prestate == AST_STATE_UP && ast_bridged_channel(chan)) {
04054 ast_debug(1, "Dropping duplicate answer!\n");
04055 ast_frfree(f);
04056 f = &ast_null_frame;
04057 } else {
04058
04059 ast_setstate(chan, AST_STATE_UP);
04060
04061 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
04062 }
04063 } else if (f->subclass.integer == AST_CONTROL_READ_ACTION) {
04064 read_action_payload = f->data.ptr;
04065 switch (read_action_payload->action) {
04066 case AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO:
04067 ast_party_connected_line_init(&connected);
04068 ast_party_connected_line_copy(&connected, &chan->connected);
04069 if (ast_connected_line_parse_data(read_action_payload->payload,
04070 read_action_payload->payload_size, &connected)) {
04071 ast_party_connected_line_free(&connected);
04072 break;
04073 }
04074 ast_channel_unlock(chan);
04075 if (ast_channel_connected_line_macro(NULL, chan, &connected, 1, 0)) {
04076 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE,
04077 read_action_payload->payload,
04078 read_action_payload->payload_size);
04079 }
04080 ast_party_connected_line_free(&connected);
04081 ast_channel_lock(chan);
04082 break;
04083 }
04084 ast_frfree(f);
04085 f = &ast_null_frame;
04086 }
04087 break;
04088 case AST_FRAME_DTMF_END:
04089 send_dtmf_event(chan, "Received", f->subclass.integer, "No", "Yes");
04090 ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass.integer, chan->name, f->len);
04091
04092 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) || ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
04093 queue_dtmf_readq(chan, f);
04094 ast_frfree(f);
04095 f = &ast_null_frame;
04096 } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
04097 if (!ast_tvzero(chan->dtmf_tv) &&
04098 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
04099
04100 queue_dtmf_readq(chan, f);
04101 ast_frfree(f);
04102 f = &ast_null_frame;
04103 } else {
04104
04105 f->frametype = AST_FRAME_DTMF_BEGIN;
04106 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
04107 chan->emulate_dtmf_digit = f->subclass.integer;
04108 chan->dtmf_tv = ast_tvnow();
04109 if (f->len) {
04110 if (f->len > AST_MIN_DTMF_DURATION)
04111 chan->emulate_dtmf_duration = f->len;
04112 else
04113 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
04114 } else
04115 chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
04116 ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass.integer, chan->emulate_dtmf_duration, chan->name);
04117 }
04118 if (chan->audiohooks) {
04119 struct ast_frame *old_frame = f;
04120
04121
04122
04123 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04124 if (old_frame != f)
04125 ast_frfree(old_frame);
04126 }
04127 } else {
04128 struct timeval now = ast_tvnow();
04129 if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
04130 ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass.integer, chan->name);
04131 ast_clear_flag(chan, AST_FLAG_IN_DTMF);
04132 if (!f->len)
04133 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
04134
04135
04136
04137
04138
04139
04140
04141
04142
04143 if (ast_tvdiff_ms(now, chan->dtmf_tv) < AST_MIN_DTMF_DURATION) {
04144 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
04145 ast_log(LOG_DTMF, "DTMF end '%c' detected to have actual duration %ld on the wire, emulation will be triggered on %s\n", f->subclass.integer, f->len, chan->name);
04146 }
04147 } else if (!f->len) {
04148 ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass.integer, chan->name);
04149 f->len = AST_MIN_DTMF_DURATION;
04150 }
04151 if (f->len < AST_MIN_DTMF_DURATION && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) {
04152 ast_log(LOG_DTMF, "DTMF end '%c' has duration %ld but want minimum %d, emulating on %s\n", f->subclass.integer, f->len, AST_MIN_DTMF_DURATION, chan->name);
04153 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
04154 chan->emulate_dtmf_digit = f->subclass.integer;
04155 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len;
04156 ast_frfree(f);
04157 f = &ast_null_frame;
04158 } else {
04159 ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass.integer, chan->name);
04160 if (f->len < AST_MIN_DTMF_DURATION) {
04161 f->len = AST_MIN_DTMF_DURATION;
04162 }
04163 chan->dtmf_tv = now;
04164 }
04165 if (chan->audiohooks) {
04166 struct ast_frame *old_frame = f;
04167 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04168 if (old_frame != f)
04169 ast_frfree(old_frame);
04170 }
04171 }
04172 break;
04173 case AST_FRAME_DTMF_BEGIN:
04174 send_dtmf_event(chan, "Received", f->subclass.integer, "Yes", "No");
04175 ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass.integer, chan->name);
04176 if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) ||
04177 (!ast_tvzero(chan->dtmf_tv) &&
04178 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
04179 ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass.integer, chan->name);
04180 ast_frfree(f);
04181 f = &ast_null_frame;
04182 } else {
04183 ast_set_flag(chan, AST_FLAG_IN_DTMF);
04184 chan->dtmf_tv = ast_tvnow();
04185 ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass.integer, chan->name);
04186 }
04187 break;
04188 case AST_FRAME_NULL:
04189
04190
04191
04192
04193 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
04194 struct timeval now = ast_tvnow();
04195 if (!chan->emulate_dtmf_duration) {
04196 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
04197 chan->emulate_dtmf_digit = 0;
04198 } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
04199 chan->emulate_dtmf_duration = 0;
04200 ast_frfree(f);
04201 f = &chan->dtmff;
04202 f->frametype = AST_FRAME_DTMF_END;
04203 f->subclass.integer = chan->emulate_dtmf_digit;
04204 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
04205 chan->dtmf_tv = now;
04206 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
04207 chan->emulate_dtmf_digit = 0;
04208 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, chan->name);
04209 if (chan->audiohooks) {
04210 struct ast_frame *old_frame = f;
04211 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04212 if (old_frame != f) {
04213 ast_frfree(old_frame);
04214 }
04215 }
04216 }
04217 }
04218 break;
04219 case AST_FRAME_VOICE:
04220
04221
04222
04223
04224 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) {
04225 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
04226 chan->emulate_dtmf_digit = 0;
04227 }
04228
04229 if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
04230 if (dropaudio)
04231 ast_read_generator_actions(chan, f);
04232 ast_frfree(f);
04233 f = &ast_null_frame;
04234 }
04235
04236 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
04237 struct timeval now = ast_tvnow();
04238 if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
04239 chan->emulate_dtmf_duration = 0;
04240 ast_frfree(f);
04241 f = &chan->dtmff;
04242 f->frametype = AST_FRAME_DTMF_END;
04243 f->subclass.integer = chan->emulate_dtmf_digit;
04244 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
04245 chan->dtmf_tv = now;
04246 if (chan->audiohooks) {
04247 struct ast_frame *old_frame = f;
04248 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04249 if (old_frame != f)
04250 ast_frfree(old_frame);
04251 }
04252 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, chan->name);
04253 } else {
04254
04255 ast_frfree(f);
04256 f = &ast_null_frame;
04257 }
04258 } else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass.codec & chan->nativeformats)) {
04259
04260 char to[200];
04261 ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
04262 chan->name, ast_getformatname(f->subclass.codec), ast_getformatname_multiple(to, sizeof(to), chan->nativeformats));
04263 ast_frfree(f);
04264 f = &ast_null_frame;
04265 } else if ((f->frametype == AST_FRAME_VOICE)) {
04266
04267 if (chan->audiohooks) {
04268 struct ast_frame *old_frame = f;
04269 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04270 if (old_frame != f)
04271 ast_frfree(old_frame);
04272 }
04273 if (chan->monitor && chan->monitor->read_stream ) {
04274
04275 #ifndef MONITOR_CONSTANT_DELAY
04276 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
04277 if (jump >= 0) {
04278 jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
04279 if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
04280 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
04281 chan->insmpl += (chan->outsmpl - chan->insmpl) + f->samples;
04282 } else
04283 chan->insmpl+= f->samples;
04284 #else
04285 int jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
04286 if (jump - MONITOR_DELAY >= 0) {
04287 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
04288 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
04289 chan->insmpl += chan->outsmpl - chan->insmpl;
04290 } else
04291 chan->insmpl += f->samples;
04292 #endif
04293 if (chan->monitor->state == AST_MONITOR_RUNNING) {
04294 if (ast_writestream(chan->monitor->read_stream, f) < 0)
04295 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
04296 }
04297 }
04298
04299 if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL) {
04300 f = &ast_null_frame;
04301 }
04302
04303
04304
04305
04306
04307
04308
04309
04310 if (AST_LIST_NEXT(f, frame_list)) {
04311 if (!readq_tail) {
04312 ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list));
04313 } else {
04314 __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail);
04315 }
04316 ast_frfree(AST_LIST_NEXT(f, frame_list));
04317 AST_LIST_NEXT(f, frame_list) = NULL;
04318 }
04319
04320
04321
04322 ast_read_generator_actions(chan, f);
04323 }
04324 break;
04325 default:
04326
04327 break;
04328 }
04329 } else {
04330
04331 if (!chan->_softhangup) {
04332 chan->_softhangup |= AST_SOFTHANGUP_DEV;
04333 }
04334 if (cause)
04335 chan->hangupcause = cause;
04336 if (chan->generator)
04337 ast_deactivate_generator(chan);
04338
04339 }
04340
04341
04342 if (chan->fin & DEBUGCHAN_FLAG)
04343 ast_frame_dump(chan->name, f, "<<");
04344 chan->fin = FRAMECOUNT_INC(chan->fin);
04345
04346 done:
04347 if (chan->music_state && chan->generator && chan->generator->digit && f && f->frametype == AST_FRAME_DTMF_END)
04348 chan->generator->digit(chan, f->subclass.integer);
04349
04350 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) {
04351
04352 ast_audiohook_detach_list(chan->audiohooks);
04353 chan->audiohooks = NULL;
04354 }
04355 ast_channel_unlock(chan);
04356 return f;
04357 }
04358
04359 int ast_internal_timing_enabled(struct ast_channel *chan)
04360 {
04361 return (ast_opt_internal_timing && chan->timingfd > -1);
04362 }
04363
04364 struct ast_frame *ast_read(struct ast_channel *chan)
04365 {
04366 return __ast_read(chan, 0);
04367 }
04368
04369 struct ast_frame *ast_read_noaudio(struct ast_channel *chan)
04370 {
04371 return __ast_read(chan, 1);
04372 }
04373
04374 int ast_indicate(struct ast_channel *chan, int condition)
04375 {
04376 return ast_indicate_data(chan, condition, NULL, 0);
04377 }
04378
04379 static int attribute_const is_visible_indication(enum ast_control_frame_type condition)
04380 {
04381
04382
04383
04384 switch (condition) {
04385 case AST_CONTROL_PROGRESS:
04386 case AST_CONTROL_PROCEEDING:
04387 case AST_CONTROL_VIDUPDATE:
04388 case AST_CONTROL_SRCUPDATE:
04389 case AST_CONTROL_SRCCHANGE:
04390 case AST_CONTROL_RADIO_KEY:
04391 case AST_CONTROL_RADIO_UNKEY:
04392 case AST_CONTROL_OPTION:
04393 case AST_CONTROL_WINK:
04394 case AST_CONTROL_FLASH:
04395 case AST_CONTROL_OFFHOOK:
04396 case AST_CONTROL_TAKEOFFHOOK:
04397 case AST_CONTROL_ANSWER:
04398 case AST_CONTROL_HANGUP:
04399 case AST_CONTROL_CONNECTED_LINE:
04400 case AST_CONTROL_REDIRECTING:
04401 case AST_CONTROL_TRANSFER:
04402 case AST_CONTROL_T38_PARAMETERS:
04403 case _XXX_AST_CONTROL_T38:
04404 case AST_CONTROL_CC:
04405 case AST_CONTROL_READ_ACTION:
04406 case AST_CONTROL_AOC:
04407 case AST_CONTROL_END_OF_Q:
04408 case AST_CONTROL_UPDATE_RTP_PEER:
04409 break;
04410
04411 case AST_CONTROL_INCOMPLETE:
04412 case AST_CONTROL_CONGESTION:
04413 case AST_CONTROL_BUSY:
04414 case AST_CONTROL_RINGING:
04415 case AST_CONTROL_RING:
04416 case AST_CONTROL_HOLD:
04417
04418 return 1;
04419
04420 case AST_CONTROL_UNHOLD:
04421
04422 break;
04423 }
04424
04425 return 0;
04426 }
04427
04428 int ast_indicate_data(struct ast_channel *chan, int _condition,
04429 const void *data, size_t datalen)
04430 {
04431
04432
04433 enum ast_control_frame_type condition = _condition;
04434 struct ast_tone_zone_sound *ts = NULL;
04435 int res;
04436
04437 struct ast_frame *awesome_frame = NULL;
04438
04439 ast_channel_lock(chan);
04440
04441
04442 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
04443 res = -1;
04444 goto indicate_cleanup;
04445 }
04446
04447 if (!ast_framehook_list_is_empty(chan->framehooks)) {
04448
04449 struct ast_frame frame = {
04450 .frametype = AST_FRAME_CONTROL,
04451 .subclass.integer = condition,
04452 .data.ptr = (void *) data,
04453 .datalen = datalen
04454 };
04455
04456
04457 awesome_frame = ast_frdup(&frame);
04458
04459
04460 if (!(awesome_frame = ast_framehook_list_write_event(chan->framehooks, awesome_frame))
04461 || awesome_frame->frametype != AST_FRAME_CONTROL) {
04462
04463 res = 0;
04464 goto indicate_cleanup;
04465 }
04466
04467 condition = awesome_frame->subclass.integer;
04468 data = awesome_frame->data.ptr;
04469 datalen = awesome_frame->datalen;
04470 }
04471
04472 switch (condition) {
04473 case AST_CONTROL_CONNECTED_LINE:
04474 {
04475 struct ast_party_connected_line connected;
04476
04477 ast_party_connected_line_set_init(&connected, &chan->connected);
04478 res = ast_connected_line_parse_data(data, datalen, &connected);
04479 if (!res) {
04480 ast_channel_set_connected_line(chan, &connected, NULL);
04481 }
04482 ast_party_connected_line_free(&connected);
04483 }
04484 break;
04485
04486 case AST_CONTROL_REDIRECTING:
04487 {
04488 struct ast_party_redirecting redirecting;
04489
04490 ast_party_redirecting_set_init(&redirecting, &chan->redirecting);
04491 res = ast_redirecting_parse_data(data, datalen, &redirecting);
04492 if (!res) {
04493 ast_channel_set_redirecting(chan, &redirecting, NULL);
04494 }
04495 ast_party_redirecting_free(&redirecting);
04496 }
04497 break;
04498
04499 default:
04500 break;
04501 }
04502
04503 if (is_visible_indication(condition)) {
04504
04505 chan->visible_indication = condition;
04506 } else if (condition == AST_CONTROL_UNHOLD || _condition < 0) {
04507
04508 chan->visible_indication = 0;
04509 }
04510
04511 if (chan->tech->indicate) {
04512
04513 res = chan->tech->indicate(chan, condition, data, datalen);
04514 } else {
04515 res = -1;
04516 }
04517
04518 if (!res) {
04519
04520 res = 0;
04521 goto indicate_cleanup;
04522 }
04523
04524
04525
04526
04527
04528
04529
04530 if (_condition < 0) {
04531
04532 ast_playtones_stop(chan);
04533 res = 0;
04534 goto indicate_cleanup;
04535 }
04536
04537
04538 switch (condition) {
04539 case _XXX_AST_CONTROL_T38:
04540
04541 res = -1;
04542 goto indicate_cleanup;
04543 case AST_CONTROL_T38_PARAMETERS:
04544
04545
04546
04547
04548
04549
04550
04551 goto indicate_cleanup;
04552 case AST_CONTROL_RINGING:
04553 ts = ast_get_indication_tone(chan->zone, "ring");
04554
04555
04556
04557
04558
04559
04560
04561 if (chan->_state == AST_STATE_UP) {
04562 res = 0;
04563 }
04564 break;
04565 case AST_CONTROL_BUSY:
04566 ts = ast_get_indication_tone(chan->zone, "busy");
04567 break;
04568 case AST_CONTROL_INCOMPLETE:
04569 case AST_CONTROL_CONGESTION:
04570 ts = ast_get_indication_tone(chan->zone, "congestion");
04571 break;
04572 case AST_CONTROL_PROGRESS:
04573 case AST_CONTROL_PROCEEDING:
04574 case AST_CONTROL_VIDUPDATE:
04575 case AST_CONTROL_SRCUPDATE:
04576 case AST_CONTROL_SRCCHANGE:
04577 case AST_CONTROL_RADIO_KEY:
04578 case AST_CONTROL_RADIO_UNKEY:
04579 case AST_CONTROL_OPTION:
04580 case AST_CONTROL_WINK:
04581 case AST_CONTROL_FLASH:
04582 case AST_CONTROL_OFFHOOK:
04583 case AST_CONTROL_TAKEOFFHOOK:
04584 case AST_CONTROL_ANSWER:
04585 case AST_CONTROL_HANGUP:
04586 case AST_CONTROL_RING:
04587 case AST_CONTROL_HOLD:
04588 case AST_CONTROL_UNHOLD:
04589 case AST_CONTROL_TRANSFER:
04590 case AST_CONTROL_CONNECTED_LINE:
04591 case AST_CONTROL_REDIRECTING:
04592 case AST_CONTROL_CC:
04593 case AST_CONTROL_READ_ACTION:
04594 case AST_CONTROL_AOC:
04595 case AST_CONTROL_END_OF_Q:
04596 case AST_CONTROL_UPDATE_RTP_PEER:
04597
04598 res = 0;
04599 break;
04600 }
04601
04602 if (ts) {
04603
04604 ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
04605 res = ast_playtones_start(chan, 0, ts->data, 1);
04606 ts = ast_tone_zone_sound_unref(ts);
04607 }
04608
04609 if (res) {
04610
04611 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
04612 }
04613
04614 indicate_cleanup:
04615 ast_channel_unlock(chan);
04616 if (awesome_frame) {
04617 ast_frfree(awesome_frame);
04618 }
04619
04620 return res;
04621 }
04622
04623 int ast_recvchar(struct ast_channel *chan, int timeout)
04624 {
04625 int c;
04626 char *buf = ast_recvtext(chan, timeout);
04627 if (buf == NULL)
04628 return -1;
04629 c = *(unsigned char *)buf;
04630 ast_free(buf);
04631 return c;
04632 }
04633
04634 char *ast_recvtext(struct ast_channel *chan, int timeout)
04635 {
04636 int res;
04637 char *buf = NULL;
04638 struct timeval start = ast_tvnow();
04639 int ms;
04640
04641 while ((ms = ast_remaining_ms(start, timeout))) {
04642 struct ast_frame *f;
04643
04644 if (ast_check_hangup(chan)) {
04645 break;
04646 }
04647 res = ast_waitfor(chan, ms);
04648 if (res <= 0) {
04649 break;
04650 }
04651 f = ast_read(chan);
04652 if (f == NULL) {
04653 break;
04654 }
04655 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP) {
04656 ast_frfree(f);
04657 break;
04658 } else if (f->frametype == AST_FRAME_TEXT) {
04659 buf = ast_strndup((char *) f->data.ptr, f->datalen);
04660 ast_frfree(f);
04661 break;
04662 }
04663 ast_frfree(f);
04664 }
04665 return buf;
04666 }
04667
04668 int ast_sendtext(struct ast_channel *chan, const char *text)
04669 {
04670 int res = 0;
04671
04672 ast_channel_lock(chan);
04673
04674 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
04675 ast_channel_unlock(chan);
04676 return -1;
04677 }
04678 CHECK_BLOCKING(chan);
04679 if (chan->tech->send_text)
04680 res = chan->tech->send_text(chan, text);
04681 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04682 ast_channel_unlock(chan);
04683 return res;
04684 }
04685
04686 int ast_senddigit_begin(struct ast_channel *chan, char digit)
04687 {
04688
04689
04690 static const char * const dtmf_tones[] = {
04691 "941+1336",
04692 "697+1209",
04693 "697+1336",
04694 "697+1477",
04695 "770+1209",
04696 "770+1336",
04697 "770+1477",
04698 "852+1209",
04699 "852+1336",
04700 "852+1477",
04701 "697+1633",
04702 "770+1633",
04703 "852+1633",
04704 "941+1633",
04705 "941+1209",
04706 "941+1477"
04707 };
04708
04709 if (!chan->tech->send_digit_begin)
04710 return 0;
04711
04712 ast_channel_lock(chan);
04713 chan->sending_dtmf_digit = digit;
04714 chan->sending_dtmf_tv = ast_tvnow();
04715 ast_channel_unlock(chan);
04716
04717 if (!chan->tech->send_digit_begin(chan, digit))
04718 return 0;
04719
04720 if (digit >= '0' && digit <='9')
04721 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
04722 else if (digit >= 'A' && digit <= 'D')
04723 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
04724 else if (digit == '*')
04725 ast_playtones_start(chan, 0, dtmf_tones[14], 0);
04726 else if (digit == '#')
04727 ast_playtones_start(chan, 0, dtmf_tones[15], 0);
04728 else {
04729
04730 ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
04731 }
04732
04733 return 0;
04734 }
04735
04736 int ast_senddigit_end(struct ast_channel *chan, char digit, unsigned int duration)
04737 {
04738 int res = -1;
04739
04740 ast_channel_lock(chan);
04741 if (chan->sending_dtmf_digit == digit) {
04742 chan->sending_dtmf_digit = 0;
04743 }
04744 ast_channel_unlock(chan);
04745
04746 if (chan->tech->send_digit_end)
04747 res = chan->tech->send_digit_end(chan, digit, duration);
04748
04749 if (res && chan->generator)
04750 ast_playtones_stop(chan);
04751
04752 return 0;
04753 }
04754
04755 int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration)
04756 {
04757 if (chan->tech->send_digit_begin) {
04758 ast_senddigit_begin(chan, digit);
04759 ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04760 }
04761
04762 return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04763 }
04764
04765 int ast_prod(struct ast_channel *chan)
04766 {
04767 struct ast_frame a = { AST_FRAME_VOICE };
04768 char nothing[128];
04769
04770
04771 if (chan->_state != AST_STATE_UP) {
04772 ast_debug(1, "Prodding channel '%s'\n", chan->name);
04773 a.subclass.codec = chan->rawwriteformat;
04774 a.data.ptr = nothing + AST_FRIENDLY_OFFSET;
04775 a.src = "ast_prod";
04776 if (ast_write(chan, &a))
04777 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
04778 }
04779 return 0;
04780 }
04781
04782 int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
04783 {
04784 int res;
04785 if (!chan->tech->write_video)
04786 return 0;
04787 res = ast_write(chan, fr);
04788 if (!res)
04789 res = 1;
04790 return res;
04791 }
04792
04793 struct plc_ds {
04794
04795
04796
04797
04798 int16_t *samples_buf;
04799
04800
04801
04802 size_t num_samples;
04803 plc_state_t plc_state;
04804 };
04805
04806 static void plc_ds_destroy(void *data)
04807 {
04808 struct plc_ds *plc = data;
04809 ast_free(plc->samples_buf);
04810 ast_free(plc);
04811 }
04812
04813 static const struct ast_datastore_info plc_ds_info = {
04814 .type = "plc",
04815 .destroy = plc_ds_destroy,
04816 };
04817
04818 static void adjust_frame_for_plc(struct ast_channel *chan, struct ast_frame *frame, struct ast_datastore *datastore)
04819 {
04820 int num_new_samples = frame->samples;
04821 struct plc_ds *plc = datastore->data;
04822
04823
04824
04825
04826
04827
04828
04829
04830
04831
04832
04833
04834
04835
04836
04837
04838
04839
04840
04841
04842 if (!num_new_samples) {
04843 return;
04844 }
04845
04846
04847
04848
04849
04850 if (plc->num_samples < num_new_samples) {
04851 ast_free(plc->samples_buf);
04852 plc->samples_buf = ast_calloc(1, (num_new_samples * sizeof(*plc->samples_buf)) + (AST_FRIENDLY_OFFSET * 2));
04853 if (!plc->samples_buf) {
04854 ast_channel_datastore_remove(chan, datastore);
04855 ast_datastore_free(datastore);
04856 return;
04857 }
04858 plc->num_samples = num_new_samples;
04859 }
04860
04861 if (frame->datalen == 0) {
04862 plc_fillin(&plc->plc_state, plc->samples_buf + AST_FRIENDLY_OFFSET, frame->samples);
04863 frame->data.ptr = plc->samples_buf + AST_FRIENDLY_OFFSET;
04864 frame->datalen = num_new_samples * 2;
04865 frame->offset = AST_FRIENDLY_OFFSET * 2;
04866 } else {
04867 plc_rx(&plc->plc_state, frame->data.ptr, frame->samples);
04868 }
04869 }
04870
04871 static void apply_plc(struct ast_channel *chan, struct ast_frame *frame)
04872 {
04873 struct ast_datastore *datastore;
04874 struct plc_ds *plc;
04875
04876 datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL);
04877 if (datastore) {
04878 plc = datastore->data;
04879 adjust_frame_for_plc(chan, frame, datastore);
04880 return;
04881 }
04882
04883 datastore = ast_datastore_alloc(&plc_ds_info, NULL);
04884 if (!datastore) {
04885 return;
04886 }
04887 plc = ast_calloc(1, sizeof(*plc));
04888 if (!plc) {
04889 ast_datastore_free(datastore);
04890 return;
04891 }
04892 datastore->data = plc;
04893 ast_channel_datastore_add(chan, datastore);
04894 adjust_frame_for_plc(chan, frame, datastore);
04895 }
04896
04897 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
04898 {
04899 int res = -1;
04900 struct ast_frame *f = NULL;
04901 int count = 0;
04902
04903
04904 while(ast_channel_trylock(chan)) {
04905
04906 if(count++ > 10) {
04907 ast_debug(1, "Deadlock avoided for write to channel '%s'\n", chan->name);
04908 return 0;
04909 }
04910 usleep(1);
04911 }
04912
04913 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
04914 goto done;
04915
04916
04917 while (chan->masq) {
04918 ast_channel_unlock(chan);
04919 ast_do_masquerade(chan);
04920 ast_channel_lock(chan);
04921 }
04922 if (chan->masqr) {
04923 res = 0;
04924 goto done;
04925 }
04926
04927
04928
04929 if (!(fr = ast_framehook_list_write_event(chan->framehooks, fr))) {
04930 res = 0;
04931 goto done;
04932 }
04933
04934 if (chan->generatordata && (!fr->src || strcasecmp(fr->src, "ast_prod"))) {
04935 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) {
04936 ast_deactivate_generator(chan);
04937 } else {
04938 if (fr->frametype == AST_FRAME_DTMF_END) {
04939
04940
04941
04942 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04943 ast_channel_unlock(chan);
04944 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);
04945 ast_channel_lock(chan);
04946 CHECK_BLOCKING(chan);
04947 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_UNHOLD) {
04948
04949 res = (chan->tech->indicate == NULL) ? 0 :
04950 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
04951 }
04952 res = 0;
04953 goto done;
04954 }
04955 }
04956
04957 if (chan->fout & DEBUGCHAN_FLAG)
04958 ast_frame_dump(chan->name, fr, ">>");
04959 CHECK_BLOCKING(chan);
04960 switch (fr->frametype) {
04961 case AST_FRAME_CONTROL:
04962 res = (chan->tech->indicate == NULL) ? 0 :
04963 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
04964 break;
04965 case AST_FRAME_DTMF_BEGIN:
04966 if (chan->audiohooks) {
04967 struct ast_frame *old_frame = fr;
04968 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
04969 if (old_frame != fr)
04970 f = fr;
04971 }
04972 send_dtmf_event(chan, "Sent", fr->subclass.integer, "Yes", "No");
04973 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04974 ast_channel_unlock(chan);
04975 res = ast_senddigit_begin(chan, fr->subclass.integer);
04976 ast_channel_lock(chan);
04977 CHECK_BLOCKING(chan);
04978 break;
04979 case AST_FRAME_DTMF_END:
04980 if (chan->audiohooks) {
04981 struct ast_frame *new_frame = fr;
04982
04983 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
04984 if (new_frame != fr) {
04985 ast_frfree(new_frame);
04986 }
04987 }
04988 send_dtmf_event(chan, "Sent", fr->subclass.integer, "No", "Yes");
04989 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04990 ast_channel_unlock(chan);
04991 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);
04992 ast_channel_lock(chan);
04993 CHECK_BLOCKING(chan);
04994 break;
04995 case AST_FRAME_TEXT:
04996 if (fr->subclass.integer == AST_FORMAT_T140) {
04997 res = (chan->tech->write_text == NULL) ? 0 :
04998 chan->tech->write_text(chan, fr);
04999 } else {
05000 res = (chan->tech->send_text == NULL) ? 0 :
05001 chan->tech->send_text(chan, (char *) fr->data.ptr);
05002 }
05003 break;
05004 case AST_FRAME_HTML:
05005 res = (chan->tech->send_html == NULL) ? 0 :
05006 chan->tech->send_html(chan, fr->subclass.integer, (char *) fr->data.ptr, fr->datalen);
05007 break;
05008 case AST_FRAME_VIDEO:
05009
05010 res = (chan->tech->write_video == NULL) ? 0 :
05011 chan->tech->write_video(chan, fr);
05012 break;
05013 case AST_FRAME_MODEM:
05014 res = (chan->tech->write == NULL) ? 0 :
05015 chan->tech->write(chan, fr);
05016 break;
05017 case AST_FRAME_VOICE:
05018 if (chan->tech->write == NULL)
05019 break;
05020
05021 if (ast_opt_generic_plc && fr->subclass.codec == AST_FORMAT_SLINEAR) {
05022 apply_plc(chan, fr);
05023 }
05024
05025
05026 if (fr->subclass.codec == chan->rawwriteformat) {
05027 f = fr;
05028 } else {
05029 if ((!(fr->subclass.codec & chan->nativeformats)) && (chan->writeformat != fr->subclass.codec)) {
05030 char nf[512];
05031
05032
05033
05034
05035
05036
05037
05038
05039
05040
05041 ast_log(LOG_WARNING, "Codec mismatch on channel %s setting write format to %s from %s native formats %s\n",
05042 chan->name, ast_getformatname(fr->subclass.codec), ast_getformatname(chan->writeformat),
05043 ast_getformatname_multiple(nf, sizeof(nf), chan->nativeformats & AST_FORMAT_AUDIO_MASK));
05044 ast_set_write_format(chan, fr->subclass.codec);
05045 }
05046
05047 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
05048 }
05049
05050 if (!f) {
05051 res = 0;
05052 break;
05053 }
05054
05055 if (chan->audiohooks) {
05056 struct ast_frame *prev = NULL, *new_frame, *cur, *dup;
05057 int freeoldlist = 0;
05058
05059 if (f != fr) {
05060 freeoldlist = 1;
05061 }
05062
05063
05064
05065
05066 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
05067 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur);
05068
05069
05070
05071 if (new_frame != cur) {
05072
05073
05074
05075
05076 if ((dup = ast_frisolate(new_frame))) {
05077 AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list);
05078 if (freeoldlist) {
05079 AST_LIST_NEXT(cur, frame_list) = NULL;
05080 ast_frfree(cur);
05081 }
05082 if (new_frame != dup) {
05083 ast_frfree(new_frame);
05084 }
05085 cur = dup;
05086 }
05087 }
05088
05089
05090
05091 if (prev) {
05092 AST_LIST_NEXT(prev, frame_list) = cur;
05093 } else {
05094 f = cur;
05095 }
05096 prev = cur;
05097 }
05098 }
05099
05100
05101
05102
05103
05104 if (chan->monitor && chan->monitor->write_stream) {
05105 struct ast_frame *cur;
05106
05107 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
05108
05109 #ifndef MONITOR_CONSTANT_DELAY
05110 int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples;
05111 if (jump >= 0) {
05112 jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
05113 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
05114 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
05115 chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples;
05116 } else {
05117 chan->outsmpl += cur->samples;
05118 }
05119 #else
05120 int jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
05121 if (jump - MONITOR_DELAY >= 0) {
05122 if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1)
05123 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
05124 chan->outsmpl += chan->insmpl - chan->outsmpl;
05125 } else {
05126 chan->outsmpl += cur->samples;
05127 }
05128 #endif
05129 if (chan->monitor->state == AST_MONITOR_RUNNING) {
05130 if (ast_writestream(chan->monitor->write_stream, cur) < 0)
05131 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
05132 }
05133 }
05134 }
05135
05136
05137
05138
05139 if ((f != fr) && AST_LIST_NEXT(f, frame_list)) {
05140 struct ast_frame *cur, *next;
05141 unsigned int skip = 0;
05142
05143 for (cur = f, next = AST_LIST_NEXT(cur, frame_list);
05144 cur;
05145 cur = next, next = cur ? AST_LIST_NEXT(cur, frame_list) : NULL) {
05146 if (!skip) {
05147 if ((res = chan->tech->write(chan, cur)) < 0) {
05148 chan->_softhangup |= AST_SOFTHANGUP_DEV;
05149 skip = 1;
05150 } else if (next) {
05151
05152
05153
05154 chan->fout = FRAMECOUNT_INC(chan->fout);
05155 }
05156 }
05157 ast_frfree(cur);
05158 }
05159
05160
05161 f = NULL;
05162 } else {
05163 res = chan->tech->write(chan, f);
05164 }
05165 break;
05166 case AST_FRAME_NULL:
05167 case AST_FRAME_IAX:
05168
05169 res = 0;
05170 break;
05171 default:
05172
05173
05174
05175 res = chan->tech->write(chan, fr);
05176 break;
05177 }
05178
05179 if (f && f != fr)
05180 ast_frfree(f);
05181 ast_clear_flag(chan, AST_FLAG_BLOCKING);
05182
05183
05184 if (res < 0) {
05185 chan->_softhangup |= AST_SOFTHANGUP_DEV;
05186 } else {
05187 chan->fout = FRAMECOUNT_INC(chan->fout);
05188 }
05189 done:
05190 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) {
05191
05192 ast_audiohook_detach_list(chan->audiohooks);
05193 chan->audiohooks = NULL;
05194 }
05195 ast_channel_unlock(chan);
05196 return res;
05197 }
05198
05199 static int set_format(struct ast_channel *chan, format_t fmt, format_t *rawformat, format_t *format,
05200 struct ast_trans_pvt **trans, const int direction)
05201 {
05202 format_t native, native_fmt = ast_best_codec(fmt);
05203 int res;
05204 char from[200], to[200];
05205
05206
05207 fmt &= AST_FORMAT_AUDIO_MASK;
05208
05209 native = chan->nativeformats;
05210
05211 if (!fmt || !native)
05212 return 0;
05213
05214
05215 if (!ast_channel_setoption(chan, direction ? AST_OPTION_FORMAT_WRITE : AST_OPTION_FORMAT_READ, &native_fmt, sizeof(int*), 0)) {
05216 ast_debug(1, "Channel driver natively set channel %s to %s format %s\n", chan->name,
05217 direction ? "write" : "read", ast_getformatname(native_fmt));
05218 chan->nativeformats = *rawformat = *format = native_fmt;
05219 if (*trans) {
05220 ast_translator_free_path(*trans);
05221 }
05222 *trans = NULL;
05223 return 0;
05224 }
05225
05226
05227 if (!direction)
05228
05229 res = ast_translator_best_choice(&fmt, &native);
05230 else
05231
05232 res = ast_translator_best_choice(&native, &fmt);
05233
05234 if (res < 0) {
05235 ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
05236 ast_getformatname_multiple(from, sizeof(from), native),
05237 ast_getformatname_multiple(to, sizeof(to), fmt));
05238 return -1;
05239 }
05240
05241
05242 ast_channel_lock(chan);
05243
05244 if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
05245
05246 ast_channel_unlock(chan);
05247 return 0;
05248 }
05249
05250 *rawformat = native;
05251
05252 *format = fmt;
05253
05254 if (*trans) {
05255 ast_translator_free_path(*trans);
05256 *trans = NULL;
05257 }
05258
05259 if (*format == *rawformat) {
05260
05261
05262
05263
05264
05265 res = 0;
05266 } else {
05267 if (!direction) {
05268
05269 *trans = ast_translator_build_path(*format, *rawformat);
05270 } else {
05271
05272 *trans = ast_translator_build_path(*rawformat, *format);
05273 }
05274 res = *trans ? 0 : -1;
05275 }
05276 ast_channel_unlock(chan);
05277 ast_debug(1, "Set channel %s to %s format %s\n", chan->name,
05278 direction ? "write" : "read", ast_getformatname(fmt));
05279 return res;
05280 }
05281
05282 int ast_set_read_format(struct ast_channel *chan, format_t fmt)
05283 {
05284 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
05285 &chan->readtrans, 0);
05286 }
05287
05288 int ast_set_write_format(struct ast_channel *chan, format_t fmt)
05289 {
05290 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
05291 &chan->writetrans, 1);
05292 }
05293
05294 const char *ast_channel_reason2str(int reason)
05295 {
05296 switch (reason)
05297 {
05298 case 0:
05299 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
05300 case AST_CONTROL_HANGUP:
05301 return "Hangup";
05302 case AST_CONTROL_RING:
05303 return "Local Ring";
05304 case AST_CONTROL_RINGING:
05305 return "Remote end Ringing";
05306 case AST_CONTROL_ANSWER:
05307 return "Remote end has Answered";
05308 case AST_CONTROL_BUSY:
05309 return "Remote end is Busy";
05310 case AST_CONTROL_CONGESTION:
05311 return "Congestion (circuits busy)";
05312 default:
05313 return "Unknown Reason!!";
05314 }
05315 }
05316
05317 static void handle_cause(int cause, int *outstate)
05318 {
05319 if (outstate) {
05320
05321 if (cause == AST_CAUSE_BUSY)
05322 *outstate = AST_CONTROL_BUSY;
05323 else if (cause == AST_CAUSE_CONGESTION)
05324 *outstate = AST_CONTROL_CONGESTION;
05325 else
05326 *outstate = 0;
05327 }
05328 }
05329
05330
05331
05332
05333
05334
05335
05336
05337
05338
05339
05340 static void call_forward_inherit(struct ast_channel *new_chan, struct ast_channel *parent, struct ast_channel *orig)
05341 {
05342 if (!ast_test_flag(parent, AST_FLAG_ZOMBIE) && !ast_check_hangup(parent)) {
05343 struct ast_party_redirecting redirecting;
05344
05345
05346
05347
05348
05349 ast_party_redirecting_init(&redirecting);
05350 ast_channel_lock(orig);
05351 ast_party_redirecting_copy(&redirecting, &orig->redirecting);
05352 ast_channel_unlock(orig);
05353 if (ast_channel_redirecting_macro(orig, parent, &redirecting, 1, 0)) {
05354 ast_channel_update_redirecting(parent, &redirecting, NULL);
05355 }
05356 ast_party_redirecting_free(&redirecting);
05357 }
05358
05359
05360 ast_channel_lock_both(parent, new_chan);
05361 ast_channel_inherit_variables(parent, new_chan);
05362 ast_channel_datastore_inherit(parent, new_chan);
05363 ast_channel_unlock(new_chan);
05364 ast_channel_unlock(parent);
05365 }
05366
05367 struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_channel *orig, int *timeout, format_t format, struct outgoing_helper *oh, int *outstate)
05368 {
05369 char tmpchan[256];
05370 struct ast_channel *new_chan = NULL;
05371 char *data, *type;
05372 int cause = 0;
05373 int res;
05374
05375
05376 ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan));
05377 if ((data = strchr(tmpchan, '/'))) {
05378 *data++ = '\0';
05379 type = tmpchan;
05380 } else {
05381 const char *forward_context;
05382 ast_channel_lock(orig);
05383 forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT");
05384 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context));
05385 ast_channel_unlock(orig);
05386 data = tmpchan;
05387 type = "Local";
05388 }
05389 if (!(new_chan = ast_request(type, format, orig, data, &cause))) {
05390 ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause);
05391 handle_cause(cause, outstate);
05392 ast_hangup(orig);
05393 return NULL;
05394 }
05395
05396
05397 if (oh) {
05398 if (oh->vars) {
05399 ast_set_variables(new_chan, oh->vars);
05400 }
05401 if (oh->parent_channel) {
05402 call_forward_inherit(new_chan, oh->parent_channel, orig);
05403 }
05404 if (oh->account) {
05405 ast_channel_lock(new_chan);
05406 ast_cdr_setaccount(new_chan, oh->account);
05407 ast_channel_unlock(new_chan);
05408 }
05409 } else if (caller) {
05410 call_forward_inherit(new_chan, caller, orig);
05411 }
05412
05413 ast_channel_lock_both(orig, new_chan);
05414 ast_copy_flags(new_chan->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED);
05415 ast_string_field_set(new_chan, accountcode, orig->accountcode);
05416 ast_party_connected_line_copy(&new_chan->connected, &orig->connected);
05417 ast_party_redirecting_copy(&new_chan->redirecting, &orig->redirecting);
05418 ast_channel_unlock(new_chan);
05419 ast_channel_unlock(orig);
05420
05421
05422 res = ast_call(new_chan, data, 0);
05423 if (timeout) {
05424 *timeout = res;
05425 }
05426 if (res) {
05427 ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data);
05428 ast_hangup(orig);
05429 ast_hangup(new_chan);
05430 return NULL;
05431 }
05432 ast_hangup(orig);
05433
05434 return new_chan;
05435 }
05436
05437 struct ast_channel *__ast_request_and_dial(const char *type, format_t format, const struct ast_channel *requestor, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
05438 {
05439 int dummy_outstate;
05440 int cause = 0;
05441 struct ast_channel *chan;
05442 int res = 0;
05443 int last_subclass = 0;
05444 struct ast_party_connected_line connected;
05445
05446 if (outstate)
05447 *outstate = 0;
05448 else
05449 outstate = &dummy_outstate;
05450
05451 chan = ast_request(type, format, requestor, data, &cause);
05452 if (!chan) {
05453 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
05454 handle_cause(cause, outstate);
05455 return NULL;
05456 }
05457
05458 if (oh) {
05459 if (oh->vars) {
05460 ast_set_variables(chan, oh->vars);
05461 }
05462 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) {
05463
05464
05465
05466
05467 cid_num = oh->cid_num;
05468 cid_name = oh->cid_name;
05469 }
05470 if (oh->parent_channel) {
05471
05472 ast_channel_lock_both(oh->parent_channel, chan);
05473 ast_channel_inherit_variables(oh->parent_channel, chan);
05474 ast_channel_datastore_inherit(oh->parent_channel, chan);
05475 ast_channel_unlock(oh->parent_channel);
05476 ast_channel_unlock(chan);
05477 }
05478 if (oh->account) {
05479 ast_channel_lock(chan);
05480 ast_cdr_setaccount(chan, oh->account);
05481 ast_channel_unlock(chan);
05482 }
05483 }
05484
05485
05486
05487
05488
05489
05490
05491
05492
05493 ast_set_callerid(chan, cid_num, cid_name, cid_num);
05494
05495 ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED);
05496 ast_party_connected_line_set_init(&connected, &chan->connected);
05497 if (cid_num) {
05498 connected.id.number.valid = 1;
05499 connected.id.number.str = (char *) cid_num;
05500 connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05501 }
05502 if (cid_name) {
05503 connected.id.name.valid = 1;
05504 connected.id.name.str = (char *) cid_name;
05505 connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05506 }
05507 ast_channel_set_connected_line(chan, &connected, NULL);
05508
05509 if (ast_call(chan, data, 0)) {
05510 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
05511 } else {
05512 struct timeval start = ast_tvnow();
05513 res = 1;
05514 while (timeout && chan->_state != AST_STATE_UP) {
05515 struct ast_frame *f;
05516 int ms = ast_remaining_ms(start, timeout);
05517
05518 res = ast_waitfor(chan, ms);
05519 if (res == 0) {
05520 *outstate = AST_CONTROL_RINGING;
05521 break;
05522 }
05523 if (res < 0)
05524 break;
05525 if (!ast_strlen_zero(chan->call_forward)) {
05526 if (!(chan = ast_call_forward(NULL, chan, NULL, format, oh, outstate))) {
05527 return NULL;
05528 }
05529 continue;
05530 }
05531
05532 f = ast_read(chan);
05533 if (!f) {
05534 *outstate = AST_CONTROL_HANGUP;
05535 res = 0;
05536 break;
05537 }
05538 if (f->frametype == AST_FRAME_CONTROL) {
05539 switch (f->subclass.integer) {
05540 case AST_CONTROL_RINGING:
05541 *outstate = f->subclass.integer;
05542 break;
05543
05544 case AST_CONTROL_BUSY:
05545 ast_cdr_busy(chan->cdr);
05546 *outstate = f->subclass.integer;
05547 timeout = 0;
05548 break;
05549
05550 case AST_CONTROL_INCOMPLETE:
05551 ast_cdr_failed(chan->cdr);
05552 *outstate = AST_CONTROL_CONGESTION;
05553 timeout = 0;
05554 break;
05555
05556 case AST_CONTROL_CONGESTION:
05557 ast_cdr_failed(chan->cdr);
05558 *outstate = f->subclass.integer;
05559 timeout = 0;
05560 break;
05561
05562 case AST_CONTROL_ANSWER:
05563 ast_cdr_answer(chan->cdr);
05564 *outstate = f->subclass.integer;
05565 timeout = 0;
05566 break;
05567
05568
05569 case AST_CONTROL_PROGRESS:
05570 case AST_CONTROL_PROCEEDING:
05571 case AST_CONTROL_HOLD:
05572 case AST_CONTROL_UNHOLD:
05573 case AST_CONTROL_VIDUPDATE:
05574 case AST_CONTROL_SRCUPDATE:
05575 case AST_CONTROL_SRCCHANGE:
05576 case AST_CONTROL_CONNECTED_LINE:
05577 case AST_CONTROL_REDIRECTING:
05578 case AST_CONTROL_CC:
05579 case -1:
05580 break;
05581
05582 default:
05583 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer);
05584 }
05585 last_subclass = f->subclass.integer;
05586 }
05587 ast_frfree(f);
05588 }
05589 }
05590
05591
05592 if (oh) {
05593 if (!ast_strlen_zero(oh->context))
05594 ast_copy_string(chan->context, oh->context, sizeof(chan->context));
05595 if (!ast_strlen_zero(oh->exten))
05596 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
05597 if (oh->priority)
05598 chan->priority = oh->priority;
05599 }
05600 if (chan->_state == AST_STATE_UP)
05601 *outstate = AST_CONTROL_ANSWER;
05602
05603 if (res <= 0) {
05604 ast_channel_lock(chan);
05605 if (AST_CONTROL_RINGING == last_subclass) {
05606 chan->hangupcause = AST_CAUSE_NO_ANSWER;
05607 }
05608 if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) {
05609 ast_cdr_init(chan->cdr, chan);
05610 }
05611 if (chan->cdr) {
05612 char tmp[256];
05613
05614 snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
05615 ast_cdr_setapp(chan->cdr, "Dial", tmp);
05616 ast_cdr_update(chan);
05617 ast_cdr_start(chan->cdr);
05618 ast_cdr_end(chan->cdr);
05619
05620 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) {
05621 ast_cdr_failed(chan->cdr);
05622 }
05623 }
05624 ast_channel_unlock(chan);
05625 ast_hangup(chan);
05626 chan = NULL;
05627 }
05628 return chan;
05629 }
05630
05631 struct ast_channel *ast_request_and_dial(const char *type, format_t format, const struct ast_channel *requestor, void *data, int timeout, int *outstate, const char *cidnum, const char *cidname)
05632 {
05633 return __ast_request_and_dial(type, format, requestor, data, timeout, outstate, cidnum, cidname, NULL);
05634 }
05635
05636 static int set_security_requirements(const struct ast_channel *requestor, struct ast_channel *out)
05637 {
05638 int ops[2][2] = {
05639 {AST_OPTION_SECURE_SIGNALING, 0},
05640 {AST_OPTION_SECURE_MEDIA, 0},
05641 };
05642 int i;
05643 struct ast_channel *r = (struct ast_channel *) requestor;
05644 struct ast_datastore *ds;
05645
05646 if (!requestor || !out) {
05647 return 0;
05648 }
05649
05650 ast_channel_lock(r);
05651 if ((ds = ast_channel_datastore_find(r, &secure_call_info, NULL))) {
05652 struct ast_secure_call_store *encrypt = ds->data;
05653 ops[0][1] = encrypt->signaling;
05654 ops[1][1] = encrypt->media;
05655 } else {
05656 ast_channel_unlock(r);
05657 return 0;
05658 }
05659 ast_channel_unlock(r);
05660
05661 for (i = 0; i < 2; i++) {
05662 if (ops[i][1]) {
05663 if (ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0)) {
05664
05665 return -1;
05666 }
05667 } else {
05668
05669 ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0);
05670 }
05671 }
05672
05673 return 0;
05674 }
05675
05676 struct ast_channel *ast_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
05677 {
05678 struct chanlist *chan;
05679 struct ast_channel *c;
05680 format_t capabilities;
05681 format_t fmt;
05682 int res;
05683 int foo;
05684 format_t videoformat = format & AST_FORMAT_VIDEO_MASK;
05685 format_t textformat = format & AST_FORMAT_TEXT_MASK;
05686
05687 if (!cause)
05688 cause = &foo;
05689 *cause = AST_CAUSE_NOTDEFINED;
05690
05691 if (AST_RWLIST_RDLOCK(&backends)) {
05692 ast_log(LOG_WARNING, "Unable to lock technology backend list\n");
05693 return NULL;
05694 }
05695
05696 AST_RWLIST_TRAVERSE(&backends, chan, list) {
05697 if (strcasecmp(type, chan->tech->type))
05698 continue;
05699
05700 capabilities = chan->tech->capabilities;
05701 fmt = format & AST_FORMAT_AUDIO_MASK;
05702 if (fmt) {
05703
05704
05705
05706 res = ast_translator_best_choice(&fmt, &capabilities);
05707 if (res < 0) {
05708 char tmp1[256], tmp2[256];
05709 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type,
05710 ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities),
05711 ast_getformatname_multiple(tmp2, sizeof(tmp2), format));
05712 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05713 AST_RWLIST_UNLOCK(&backends);
05714 return NULL;
05715 }
05716 }
05717 AST_RWLIST_UNLOCK(&backends);
05718 if (!chan->tech->requester)
05719 return NULL;
05720
05721 if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, requestor, data, cause)))
05722 return NULL;
05723
05724 if (set_security_requirements(requestor, c)) {
05725 ast_log(LOG_WARNING, "Setting security requirements failed\n");
05726 c = ast_channel_release(c);
05727 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05728 return NULL;
05729 }
05730
05731
05732 return c;
05733 }
05734
05735 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
05736 *cause = AST_CAUSE_NOSUCHDRIVER;
05737 AST_RWLIST_UNLOCK(&backends);
05738
05739 return NULL;
05740 }
05741
05742 int ast_call(struct ast_channel *chan, char *addr, int timeout)
05743 {
05744
05745
05746
05747 int res = -1;
05748
05749 ast_channel_lock(chan);
05750 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
05751 if (chan->cdr) {
05752 ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED);
05753 }
05754 if (chan->tech->call)
05755 res = chan->tech->call(chan, addr, timeout);
05756 ast_set_flag(chan, AST_FLAG_OUTGOING);
05757 }
05758 ast_channel_unlock(chan);
05759 return res;
05760 }
05761
05762
05763
05764
05765
05766
05767
05768
05769 int ast_transfer(struct ast_channel *chan, char *dest)
05770 {
05771 int res = -1;
05772
05773
05774 ast_channel_lock(chan);
05775 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
05776 if (chan->tech->transfer) {
05777 res = chan->tech->transfer(chan, dest);
05778 if (!res)
05779 res = 1;
05780 } else
05781 res = 0;
05782 }
05783 ast_channel_unlock(chan);
05784
05785 if (res <= 0) {
05786 return res;
05787 }
05788
05789 for (;;) {
05790 struct ast_frame *fr;
05791
05792 res = ast_waitfor(chan, -1);
05793
05794 if (res < 0 || !(fr = ast_read(chan))) {
05795 res = -1;
05796 break;
05797 }
05798
05799 if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) {
05800 enum ast_control_transfer *message = fr->data.ptr;
05801
05802 if (*message == AST_TRANSFER_SUCCESS) {
05803 res = 1;
05804 } else {
05805 res = -1;
05806 }
05807
05808 ast_frfree(fr);
05809 break;
05810 }
05811
05812 ast_frfree(fr);
05813 }
05814
05815 return res;
05816 }
05817
05818 int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
05819 {
05820 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
05821 }
05822
05823 int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
05824 {
05825 int pos = 0;
05826 int to = ftimeout;
05827
05828 struct ast_silence_generator *silgen = NULL;
05829
05830
05831 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
05832 return -1;
05833 if (!len)
05834 return -1;
05835 for (;;) {
05836 int d;
05837 if (c->stream) {
05838 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
05839 ast_stopstream(c);
05840 if (!silgen && ast_opt_transmit_silence)
05841 silgen = ast_channel_start_silence_generator(c);
05842 usleep(1000);
05843 if (!d)
05844 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
05845 } else {
05846 if (!silgen && ast_opt_transmit_silence)
05847 silgen = ast_channel_start_silence_generator(c);
05848 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
05849 }
05850 if (d < 0) {
05851 ast_channel_stop_silence_generator(c, silgen);
05852 return AST_GETDATA_FAILED;
05853 }
05854 if (d == 0) {
05855 s[pos] = '\0';
05856 ast_channel_stop_silence_generator(c, silgen);
05857 return AST_GETDATA_TIMEOUT;
05858 }
05859 if (d == 1) {
05860 s[pos] = '\0';
05861 ast_channel_stop_silence_generator(c, silgen);
05862 return AST_GETDATA_INTERRUPTED;
05863 }
05864 if (strchr(enders, d) && (pos == 0)) {
05865 s[pos] = '\0';
05866 ast_channel_stop_silence_generator(c, silgen);
05867 return AST_GETDATA_EMPTY_END_TERMINATED;
05868 }
05869 if (!strchr(enders, d)) {
05870 s[pos++] = d;
05871 }
05872 if (strchr(enders, d) || (pos >= len)) {
05873 s[pos] = '\0';
05874 ast_channel_stop_silence_generator(c, silgen);
05875 return AST_GETDATA_COMPLETE;
05876 }
05877 to = timeout;
05878 }
05879
05880 return 0;
05881 }
05882
05883 int ast_channel_supports_html(struct ast_channel *chan)
05884 {
05885 return (chan->tech->send_html) ? 1 : 0;
05886 }
05887
05888 int ast_channel_sendhtml(struct ast_channel *chan, int subclass, const char *data, int datalen)
05889 {
05890 if (chan->tech->send_html)
05891 return chan->tech->send_html(chan, subclass, data, datalen);
05892 return -1;
05893 }
05894
05895 int ast_channel_sendurl(struct ast_channel *chan, const char *url)
05896 {
05897 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
05898 }
05899
05900
05901 static int ast_channel_make_compatible_helper(struct ast_channel *from, struct ast_channel *to)
05902 {
05903 format_t src, dst;
05904 int use_slin;
05905
05906
05907 if (from->tech->bridge && from->tech->bridge == to->tech->bridge &&
05908 !ast_channel_setoption(from, AST_OPTION_MAKE_COMPATIBLE, to, sizeof(struct ast_channel *), 0)) {
05909 return 0;
05910 }
05911
05912 if (from->readformat == to->writeformat && from->writeformat == to->readformat) {
05913
05914 return 0;
05915 }
05916
05917
05918 src = from->nativeformats;
05919 dst = to->nativeformats;
05920
05921
05922 if ((src & AST_FORMAT_AUDIO_MASK) == 0 || (dst & AST_FORMAT_AUDIO_MASK) == 0)
05923 return 0;
05924
05925 if (ast_translator_best_choice(&dst, &src) < 0) {
05926 ast_log(LOG_WARNING, "No path to translate from %s to %s\n", from->name, to->name);
05927 return -1;
05928 }
05929
05930
05931
05932
05933
05934
05935
05936 use_slin = (src == AST_FORMAT_SLINEAR || dst == AST_FORMAT_SLINEAR);
05937 if ((src != dst) && (ast_opt_generic_plc || ast_opt_transcode_via_slin) &&
05938 (ast_translate_path_steps(dst, src) != 1 || use_slin))
05939 dst = AST_FORMAT_SLINEAR;
05940 if (ast_set_read_format(from, dst) < 0) {
05941 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %s\n", from->name, ast_getformatname(dst));
05942 return -1;
05943 }
05944 if (ast_set_write_format(to, dst) < 0) {
05945 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %s\n", to->name, ast_getformatname(dst));
05946 return -1;
05947 }
05948 return 0;
05949 }
05950
05951 int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
05952 {
05953
05954 int rc = 0;
05955
05956
05957 rc = ast_channel_make_compatible_helper(chan, peer);
05958
05959 if (rc < 0)
05960 return rc;
05961
05962
05963 rc = ast_channel_make_compatible_helper(peer, chan);
05964
05965 return rc;
05966 }
05967
05968 static int __ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clonechan, struct ast_datastore *xfer_ds)
05969 {
05970 int res = -1;
05971 struct ast_channel *final_orig, *final_clone, *base;
05972
05973 for (;;) {
05974 final_orig = original;
05975 final_clone = clonechan;
05976
05977 ast_channel_lock_both(original, clonechan);
05978
05979 if (ast_test_flag(original, AST_FLAG_ZOMBIE)
05980 || ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
05981
05982 ast_log(LOG_WARNING,
05983 "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n",
05984 original->name, clonechan->name);
05985 ast_channel_unlock(clonechan);
05986 ast_channel_unlock(original);
05987 return -1;
05988 }
05989
05990
05991
05992
05993
05994
05995 if (original->_bridge
05996 && (original->_bridge != ast_bridged_channel(original))
05997 && (original->_bridge->_bridge != original)) {
05998 final_orig = original->_bridge;
05999 }
06000 if (clonechan->_bridge
06001 && (clonechan->_bridge != ast_bridged_channel(clonechan))
06002 && (clonechan->_bridge->_bridge != clonechan)) {
06003 final_clone = clonechan->_bridge;
06004 }
06005 if (final_clone->tech->get_base_channel
06006 && (base = final_clone->tech->get_base_channel(final_clone))) {
06007 final_clone = base;
06008 }
06009
06010 if ((final_orig != original) || (final_clone != clonechan)) {
06011
06012
06013
06014
06015
06016 if (ast_channel_trylock(final_orig)) {
06017 ast_channel_unlock(clonechan);
06018 ast_channel_unlock(original);
06019
06020
06021 continue;
06022 }
06023 if (ast_channel_trylock(final_clone)) {
06024 ast_channel_unlock(final_orig);
06025 ast_channel_unlock(clonechan);
06026 ast_channel_unlock(original);
06027
06028
06029 continue;
06030 }
06031 ast_channel_unlock(clonechan);
06032 ast_channel_unlock(original);
06033 original = final_orig;
06034 clonechan = final_clone;
06035
06036 if (ast_test_flag(original, AST_FLAG_ZOMBIE)
06037 || ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
06038
06039 ast_log(LOG_WARNING,
06040 "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n",
06041 original->name, clonechan->name);
06042 ast_channel_unlock(clonechan);
06043 ast_channel_unlock(original);
06044 return -1;
06045 }
06046 }
06047 break;
06048 }
06049
06050 if (original == clonechan) {
06051 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
06052 ast_channel_unlock(clonechan);
06053 ast_channel_unlock(original);
06054 return -1;
06055 }
06056
06057 ast_debug(1, "Planning to masquerade channel %s into the structure of %s\n",
06058 clonechan->name, original->name);
06059
06060 if (!original->masqr && !original->masq && !clonechan->masq && !clonechan->masqr) {
06061 original->masq = clonechan;
06062 clonechan->masqr = original;
06063 if (xfer_ds) {
06064 ast_channel_datastore_add(original, xfer_ds);
06065 }
06066 ast_queue_frame(original, &ast_null_frame);
06067 ast_queue_frame(clonechan, &ast_null_frame);
06068 ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", clonechan->name, original->name);
06069 res = 0;
06070 } else if (original->masq) {
06071 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
06072 original->masq->name, original->name);
06073 } else if (original->masqr) {
06074
06075 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
06076 original->name, original->masqr->name);
06077 } else if (clonechan->masq) {
06078 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
06079 clonechan->masq->name, clonechan->name);
06080 } else {
06081 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
06082 clonechan->name, clonechan->masqr->name);
06083 }
06084
06085 ast_channel_unlock(clonechan);
06086 ast_channel_unlock(original);
06087
06088 return res;
06089 }
06090
06091 int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
06092 {
06093 return __ast_channel_masquerade(original, clone, NULL);
06094 }
06095
06096
06097
06098
06099
06100
06101
06102
06103
06104
06105
06106 static void party_connected_line_copy_transfer(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
06107 {
06108 struct ast_party_connected_line connected;
06109
06110 connected = *((struct ast_party_connected_line *) src);
06111 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
06112
06113
06114 if (!connected.id.name.str) {
06115 connected.id.name.str = "";
06116 }
06117 if (!connected.id.number.str) {
06118 connected.id.number.str = "";
06119 }
06120 if (!connected.id.subaddress.str) {
06121 connected.id.subaddress.str = "";
06122 }
06123 if (!connected.id.tag) {
06124 connected.id.tag = "";
06125 }
06126
06127 ast_party_connected_line_copy(dest, &connected);
06128 }
06129
06130
06131 struct xfer_masquerade_ds {
06132
06133 struct ast_party_connected_line target_id;
06134
06135 struct ast_party_connected_line transferee_id;
06136
06137 int target_held;
06138
06139 int transferee_held;
06140 };
06141
06142
06143
06144
06145
06146
06147
06148
06149
06150
06151 static void xfer_ds_destroy(void *data)
06152 {
06153 struct xfer_masquerade_ds *ds = data;
06154
06155 ast_party_connected_line_free(&ds->target_id);
06156 ast_party_connected_line_free(&ds->transferee_id);
06157 ast_free(ds);
06158 }
06159
06160 static const struct ast_datastore_info xfer_ds_info = {
06161 .type = "xfer_colp",
06162 .destroy = xfer_ds_destroy,
06163 };
06164
06165 int ast_channel_transfer_masquerade(
06166 struct ast_channel *target_chan,
06167 const struct ast_party_connected_line *target_id,
06168 int target_held,
06169 struct ast_channel *transferee_chan,
06170 const struct ast_party_connected_line *transferee_id,
06171 int transferee_held)
06172 {
06173 struct ast_datastore *xfer_ds;
06174 struct xfer_masquerade_ds *xfer_colp;
06175 int res;
06176
06177 xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL);
06178 if (!xfer_ds) {
06179 return -1;
06180 }
06181
06182 xfer_colp = ast_calloc(1, sizeof(*xfer_colp));
06183 if (!xfer_colp) {
06184 ast_datastore_free(xfer_ds);
06185 return -1;
06186 }
06187 party_connected_line_copy_transfer(&xfer_colp->target_id, target_id);
06188 xfer_colp->target_held = target_held;
06189 party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id);
06190 xfer_colp->transferee_held = transferee_held;
06191 xfer_ds->data = xfer_colp;
06192
06193 res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds);
06194 if (res) {
06195 ast_datastore_free(xfer_ds);
06196 }
06197 return res;
06198 }
06199
06200
06201
06202
06203
06204 static void __ast_change_name_nolink(struct ast_channel *chan, const char *newname)
06205 {
06206 ast_manager_event(chan, EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
06207 ast_string_field_set(chan, name, newname);
06208 }
06209
06210 void ast_change_name(struct ast_channel *chan, const char *newname)
06211 {
06212
06213 ao2_lock(channels);
06214 ast_channel_lock(chan);
06215 ao2_unlink(channels, chan);
06216 __ast_change_name_nolink(chan, newname);
06217 ao2_link(channels, chan);
06218 ast_channel_unlock(chan);
06219 ao2_unlock(channels);
06220 }
06221
06222 void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
06223 {
06224 struct ast_var_t *current, *newvar;
06225 const char *varname;
06226
06227 AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
06228 int vartype = 0;
06229
06230 varname = ast_var_full_name(current);
06231 if (!varname)
06232 continue;
06233
06234 if (varname[0] == '_') {
06235 vartype = 1;
06236 if (varname[1] == '_')
06237 vartype = 2;
06238 }
06239
06240 switch (vartype) {
06241 case 1:
06242 newvar = ast_var_assign(&varname[1], ast_var_value(current));
06243 if (newvar) {
06244 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
06245 ast_debug(1, "Inheriting variable %s from %s to %s.\n",
06246 ast_var_name(newvar), parent->name, child->name);
06247 }
06248 break;
06249 case 2:
06250 newvar = ast_var_assign(varname, ast_var_value(current));
06251 if (newvar) {
06252 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
06253 ast_debug(1, "Inheriting variable %s from %s to %s.\n",
06254 ast_var_name(newvar), parent->name, child->name);
06255 }
06256 break;
06257 default:
06258 break;
06259 }
06260 }
06261 }
06262
06263
06264
06265
06266
06267
06268
06269
06270
06271
06272 static void clone_variables(struct ast_channel *original, struct ast_channel *clonechan)
06273 {
06274 struct ast_var_t *current, *newvar;
06275
06276
06277 AST_LIST_APPEND_LIST(&original->varshead, &clonechan->varshead, entries);
06278
06279
06280
06281 AST_LIST_TRAVERSE(&original->varshead, current, entries) {
06282 newvar = ast_var_assign(current->name, current->value);
06283 if (newvar)
06284 AST_LIST_INSERT_TAIL(&clonechan->varshead, newvar, entries);
06285 }
06286 }
06287
06288
06289
06290
06291
06292
06293
06294
06295
06296
06297
06298
06299
06300
06301 static const char *oldest_linkedid(const char *a, const char *b)
06302 {
06303 const char *satime, *saseq;
06304 const char *sbtime, *sbseq;
06305 const char *dash;
06306
06307 unsigned int atime, aseq, btime, bseq;
06308
06309 if (ast_strlen_zero(a))
06310 return b;
06311
06312 if (ast_strlen_zero(b))
06313 return a;
06314
06315 satime = a;
06316 sbtime = b;
06317
06318
06319 if ((dash = strrchr(satime, '-'))) {
06320 satime = dash+1;
06321 }
06322 if ((dash = strrchr(sbtime, '-'))) {
06323 sbtime = dash+1;
06324 }
06325
06326
06327 saseq = strchr(satime, '.');
06328 sbseq = strchr(sbtime, '.');
06329 if (!saseq || !sbseq)
06330 return NULL;
06331 saseq++;
06332 sbseq++;
06333
06334
06335 atime = atoi(satime);
06336 btime = atoi(sbtime);
06337 aseq = atoi(saseq);
06338 bseq = atoi(sbseq);
06339
06340
06341 if (atime == btime) {
06342 return (aseq < bseq) ? a : b;
06343 }
06344 else {
06345 return (atime < btime) ? a : b;
06346 }
06347 }
06348
06349
06350
06351 static void ast_channel_change_linkedid(struct ast_channel *chan, const char *linkedid)
06352 {
06353 ast_assert(linkedid != NULL);
06354
06355 if (!strcmp(chan->linkedid, linkedid)) {
06356 return;
06357 }
06358
06359 ast_cel_check_retire_linkedid(chan);
06360 ast_string_field_set(chan, linkedid, linkedid);
06361 ast_cel_linkedid_ref(linkedid);
06362 }
06363
06364
06365
06366
06367
06368 void ast_channel_set_linkgroup(struct ast_channel *chan, struct ast_channel *peer)
06369 {
06370 const char* linkedid=NULL;
06371 struct ast_channel *bridged;
06372
06373 linkedid = oldest_linkedid(chan->linkedid, peer->linkedid);
06374 linkedid = oldest_linkedid(linkedid, chan->uniqueid);
06375 linkedid = oldest_linkedid(linkedid, peer->uniqueid);
06376 if (chan->_bridge) {
06377 bridged = ast_bridged_channel(chan);
06378 if (bridged && bridged != peer) {
06379 linkedid = oldest_linkedid(linkedid, bridged->linkedid);
06380 linkedid = oldest_linkedid(linkedid, bridged->uniqueid);
06381 }
06382 }
06383 if (peer->_bridge) {
06384 bridged = ast_bridged_channel(peer);
06385 if (bridged && bridged != chan) {
06386 linkedid = oldest_linkedid(linkedid, bridged->linkedid);
06387 linkedid = oldest_linkedid(linkedid, bridged->uniqueid);
06388 }
06389 }
06390
06391
06392 linkedid = ast_strdupa(linkedid);
06393
06394 ast_channel_change_linkedid(chan, linkedid);
06395 ast_channel_change_linkedid(peer, linkedid);
06396 if (chan->_bridge) {
06397 bridged = ast_bridged_channel(chan);
06398 if (bridged && bridged != peer) {
06399 ast_channel_change_linkedid(bridged, linkedid);
06400 }
06401 }
06402 if (peer->_bridge) {
06403 bridged = ast_bridged_channel(peer);
06404 if (bridged && bridged != chan) {
06405 ast_channel_change_linkedid(bridged, linkedid);
06406 }
06407 }
06408 }
06409
06410
06411 static void ast_set_owners_and_peers(struct ast_channel *chan1,
06412 struct ast_channel *chan2)
06413 {
06414 if (!ast_strlen_zero(chan1->accountcode) && ast_strlen_zero(chan2->peeraccount)) {
06415 ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n",
06416 chan1->accountcode, chan2->name, chan1->name);
06417 ast_string_field_set(chan2, peeraccount, chan1->accountcode);
06418 }
06419 if (!ast_strlen_zero(chan2->accountcode) && ast_strlen_zero(chan1->peeraccount)) {
06420 ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n",
06421 chan2->accountcode, chan1->name, chan2->name);
06422 ast_string_field_set(chan1, peeraccount, chan2->accountcode);
06423 }
06424 if (!ast_strlen_zero(chan1->peeraccount) && ast_strlen_zero(chan2->accountcode)) {
06425 ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n",
06426 chan1->peeraccount, chan2->name, chan1->name);
06427 ast_string_field_set(chan2, accountcode, chan1->peeraccount);
06428 }
06429 if (!ast_strlen_zero(chan2->peeraccount) && ast_strlen_zero(chan1->accountcode)) {
06430 ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n",
06431 chan2->peeraccount, chan1->name, chan2->name);
06432 ast_string_field_set(chan1, accountcode, chan2->peeraccount);
06433 }
06434 if (0 != strcmp(chan1->accountcode, chan2->peeraccount)) {
06435 ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n",
06436 chan2->peeraccount, chan1->peeraccount, chan2->name, chan1->name);
06437 ast_string_field_set(chan2, peeraccount, chan1->accountcode);
06438 }
06439 if (0 != strcmp(chan2->accountcode, chan1->peeraccount)) {
06440 ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n",
06441 chan1->peeraccount, chan2->peeraccount, chan1->name, chan2->name);
06442 ast_string_field_set(chan1, peeraccount, chan2->accountcode);
06443 }
06444 }
06445
06446
06447
06448
06449 static void report_new_callerid(struct ast_channel *chan)
06450 {
06451 int pres;
06452
06453 pres = ast_party_id_presentation(&chan->caller.id);
06454 ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid",
06455 "Channel: %s\r\n"
06456 "CallerIDNum: %s\r\n"
06457 "CallerIDName: %s\r\n"
06458 "Uniqueid: %s\r\n"
06459 "CID-CallingPres: %d (%s)\r\n",
06460 chan->name,
06461 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
06462 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
06463 chan->uniqueid,
06464 pres,
06465 ast_describe_caller_presentation(pres)
06466 );
06467 }
06468
06469
06470
06471
06472
06473
06474
06475
06476
06477
06478
06479 static void masquerade_colp_transfer(struct ast_channel *transferee, struct xfer_masquerade_ds *colp)
06480 {
06481 struct ast_control_read_action_payload *frame_payload;
06482 int payload_size;
06483 int frame_size;
06484 unsigned char connected_line_data[1024];
06485
06486
06487 if (colp->target_held) {
06488 ast_queue_control(transferee, AST_CONTROL_UNHOLD);
06489 }
06490
06491
06492
06493
06494
06495
06496
06497
06498
06499
06500 payload_size = ast_connected_line_build_data(connected_line_data,
06501 sizeof(connected_line_data), &colp->target_id, NULL);
06502 if (payload_size != -1) {
06503 frame_size = payload_size + sizeof(*frame_payload);
06504 frame_payload = ast_alloca(frame_size);
06505 frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO;
06506 frame_payload->payload_size = payload_size;
06507 memcpy(frame_payload->payload, connected_line_data, payload_size);
06508 ast_queue_control_data(transferee, AST_CONTROL_READ_ACTION, frame_payload,
06509 frame_size);
06510 }
06511
06512
06513
06514
06515
06516
06517 ast_channel_queue_connected_line_update(transferee, &colp->transferee_id, NULL);
06518 }
06519
06520
06521
06522
06523
06524
06525
06526
06527 int ast_do_masquerade(struct ast_channel *original)
06528 {
06529 int x;
06530 int i;
06531 int origstate;
06532 unsigned int orig_disablestatecache;
06533 unsigned int clone_disablestatecache;
06534 int visible_indication;
06535 int moh_is_playing;
06536 int clone_was_zombie = 0;
06537 struct ast_frame *current;
06538 const struct ast_channel_tech *t;
06539 void *t_pvt;
06540 union {
06541 struct ast_party_dialed dialed;
06542 struct ast_party_caller caller;
06543 struct ast_party_connected_line connected;
06544 struct ast_party_redirecting redirecting;
06545 } exchange;
06546 struct ast_channel *clonechan, *chans[2];
06547 struct ast_channel *bridged;
06548 struct ast_cdr *cdr;
06549 struct ast_datastore *xfer_ds;
06550 struct xfer_masquerade_ds *xfer_colp;
06551 format_t rformat;
06552 format_t wformat;
06553 format_t tmp_format;
06554 char newn[AST_CHANNEL_NAME];
06555 char orig[AST_CHANNEL_NAME];
06556 char masqn[AST_CHANNEL_NAME];
06557 char zombn[AST_CHANNEL_NAME];
06558 char clone_sending_dtmf_digit;
06559 struct timeval clone_sending_dtmf_tv;
06560
06561
06562
06563
06564
06565
06566
06567
06568
06569
06570
06571
06572
06573
06574
06575
06576
06577
06578
06579
06580
06581
06582
06583
06584
06585
06586
06587
06588
06589
06590
06591
06592
06593 ao2_lock(channels);
06594
06595
06596
06597
06598
06599 ast_channel_lock(original);
06600
06601 clonechan = original->masq;
06602 if (!clonechan) {
06603
06604
06605
06606
06607 ast_channel_unlock(original);
06608 ao2_unlock(channels);
06609 return 0;
06610 }
06611
06612
06613 ast_channel_ref(original);
06614 ast_channel_ref(clonechan);
06615
06616
06617 ao2_unlink(channels, original);
06618 ao2_unlink(channels, clonechan);
06619
06620
06621 xfer_ds = ast_channel_datastore_find(original, &xfer_ds_info, NULL);
06622 if (xfer_ds) {
06623 ast_channel_datastore_remove(original, xfer_ds);
06624 xfer_colp = xfer_ds->data;
06625 } else {
06626 xfer_colp = NULL;
06627 }
06628
06629 moh_is_playing = ast_test_flag(original, AST_FLAG_MOH);
06630
06631
06632
06633
06634
06635 visible_indication = original->visible_indication;
06636 ast_channel_unlock(original);
06637 ast_indicate(original, -1);
06638
06639
06640
06641
06642
06643 if (xfer_colp && xfer_colp->transferee_held) {
06644 ast_indicate(clonechan, AST_CONTROL_UNHOLD);
06645 }
06646
06647
06648 ast_channel_lock_both(original, clonechan);
06649
06650 ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
06651 clonechan->name, clonechan->_state, original->name, original->_state);
06652
06653 chans[0] = clonechan;
06654 chans[1] = original;
06655 ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans,
06656 "Clone: %s\r\n"
06657 "CloneState: %s\r\n"
06658 "Original: %s\r\n"
06659 "OriginalState: %s\r\n",
06660 clonechan->name, ast_state2str(clonechan->_state), original->name, ast_state2str(original->_state));
06661
06662
06663
06664
06665
06666 rformat = original->readformat;
06667 wformat = original->writeformat;
06668 free_translation(clonechan);
06669 free_translation(original);
06670
06671
06672 clone_sending_dtmf_digit = clonechan->sending_dtmf_digit;
06673 clone_sending_dtmf_tv = clonechan->sending_dtmf_tv;
06674
06675
06676 ast_copy_string(orig, original->name, sizeof(orig));
06677
06678 ast_copy_string(newn, clonechan->name, sizeof(newn));
06679
06680 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
06681
06682
06683 __ast_change_name_nolink(clonechan, masqn);
06684
06685
06686 __ast_change_name_nolink(original, newn);
06687
06688
06689 ast_channel_set_linkgroup(original, clonechan);
06690
06691
06692 t = original->tech;
06693 original->tech = clonechan->tech;
06694 clonechan->tech = t;
06695
06696 t_pvt = original->tech_pvt;
06697 original->tech_pvt = clonechan->tech_pvt;
06698 clonechan->tech_pvt = t_pvt;
06699
06700
06701 cdr = original->cdr;
06702 original->cdr = clonechan->cdr;
06703 clonechan->cdr = cdr;
06704
06705
06706 for (i = 0; i < 2; i++) {
06707 x = original->alertpipe[i];
06708 original->alertpipe[i] = clonechan->alertpipe[i];
06709 clonechan->alertpipe[i] = x;
06710 }
06711
06712
06713
06714
06715
06716
06717
06718
06719
06720
06721
06722
06723 {
06724 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
06725
06726 AST_LIST_HEAD_INIT_NOLOCK(&tmp_readq);
06727 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
06728 AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list);
06729
06730 while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
06731 AST_LIST_INSERT_TAIL(&original->readq, current, frame_list);
06732 if (original->alertpipe[1] > -1) {
06733 int poke = 0;
06734
06735 if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) {
06736 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
06737 }
06738 }
06739 }
06740 }
06741
06742
06743 tmp_format = original->rawreadformat;
06744 original->rawreadformat = clonechan->rawreadformat;
06745 clonechan->rawreadformat = tmp_format;
06746
06747 tmp_format = original->rawwriteformat;
06748 original->rawwriteformat = clonechan->rawwriteformat;
06749 clonechan->rawwriteformat = tmp_format;
06750
06751 clonechan->_softhangup = AST_SOFTHANGUP_DEV;
06752
06753
06754
06755
06756
06757 origstate = original->_state;
06758 original->_state = clonechan->_state;
06759 clonechan->_state = origstate;
06760
06761
06762
06763 orig_disablestatecache = ast_test_flag(original, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06764 clone_disablestatecache = ast_test_flag(clonechan, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06765 if (orig_disablestatecache != clone_disablestatecache) {
06766 if (orig_disablestatecache) {
06767 ast_clear_flag(original, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06768 ast_set_flag(clonechan, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06769 } else {
06770 ast_set_flag(original, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06771 ast_clear_flag(clonechan, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06772 }
06773 }
06774
06775
06776 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
06777 __ast_change_name_nolink(clonechan, zombn);
06778
06779
06780 t_pvt = original->monitor;
06781 original->monitor = clonechan->monitor;
06782 clonechan->monitor = t_pvt;
06783
06784
06785 ast_string_field_set(original, language, clonechan->language);
06786
06787
06788 ast_string_field_set(original, parkinglot, clonechan->parkinglot);
06789
06790
06791 for (x = 0; x < AST_MAX_FDS; x++) {
06792 if (x != AST_GENERATOR_FD)
06793 ast_channel_set_fd(original, x, clonechan->fds[x]);
06794 }
06795
06796 ast_app_group_update(clonechan, original);
06797
06798
06799 if (AST_LIST_FIRST(&clonechan->datastores)) {
06800 struct ast_datastore *ds;
06801
06802
06803
06804 AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) {
06805 if (ds->info->chan_fixup)
06806 ds->info->chan_fixup(ds->data, clonechan, original);
06807 }
06808 AST_LIST_TRAVERSE_SAFE_END;
06809 AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry);
06810 }
06811
06812 ast_autochan_new_channel(clonechan, original);
06813
06814 clone_variables(original, clonechan);
06815
06816 original->adsicpe = clonechan->adsicpe;
06817
06818
06819
06820
06821
06822 ast_set_flag(original, ast_test_flag(clonechan, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING));
06823 original->fdno = clonechan->fdno;
06824
06825
06826
06827
06828
06829
06830
06831
06832 exchange.dialed = original->dialed;
06833 original->dialed = clonechan->dialed;
06834 clonechan->dialed = exchange.dialed;
06835
06836 exchange.caller = original->caller;
06837 original->caller = clonechan->caller;
06838 clonechan->caller = exchange.caller;
06839
06840 exchange.connected = original->connected;
06841 original->connected = clonechan->connected;
06842 clonechan->connected = exchange.connected;
06843
06844 exchange.redirecting = original->redirecting;
06845 original->redirecting = clonechan->redirecting;
06846 clonechan->redirecting = exchange.redirecting;
06847
06848 report_new_callerid(original);
06849
06850
06851 ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd);
06852
06853
06854 original->nativeformats = clonechan->nativeformats;
06855
06856
06857
06858
06859
06860 ast_set_write_format(original, wformat);
06861
06862
06863 ast_set_read_format(original, rformat);
06864
06865
06866 ast_string_field_set(original, musicclass, clonechan->musicclass);
06867
06868
06869 ast_string_field_set(original, accountcode, S_OR(clonechan->accountcode, ""));
06870 if (original->_bridge) {
06871
06872 ast_string_field_set(original->_bridge, peeraccount, S_OR(clonechan->accountcode, ""));
06873 ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL);
06874 }
06875
06876 ast_debug(1, "Putting channel %s in %s/%s formats\n", original->name,
06877 ast_getformatname(wformat), ast_getformatname(rformat));
06878
06879
06880 if (original->tech->fixup && original->tech->fixup(clonechan, original)) {
06881 ast_log(LOG_WARNING, "Channel type '%s' could not fixup channel %s, strange things may happen. (clonechan)\n",
06882 original->tech->type, original->name);
06883 }
06884
06885
06886 if (clonechan->tech->fixup && clonechan->tech->fixup(original, clonechan)) {
06887 ast_log(LOG_WARNING, "Channel type '%s' could not fixup channel %s, strange things may happen. (original)\n",
06888 clonechan->tech->type, clonechan->name);
06889 }
06890
06891
06892
06893
06894
06895
06896
06897
06898
06899
06900 if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
06901 clone_was_zombie = 1;
06902 } else {
06903 ast_set_flag(clonechan, AST_FLAG_ZOMBIE);
06904 ast_queue_frame(clonechan, &ast_null_frame);
06905 }
06906
06907
06908 original->masq = NULL;
06909 clonechan->masqr = NULL;
06910
06911
06912
06913
06914
06915
06916
06917 ast_channel_unlock(original);
06918
06919
06920 if (clonechan->tech->hangup && clonechan->tech->hangup(clonechan)) {
06921 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n");
06922 } else {
06923
06924
06925
06926
06927
06928 clonechan->tech = &ast_kill_tech;
06929 }
06930
06931 ast_channel_unlock(clonechan);
06932
06933 if (clone_sending_dtmf_digit) {
06934
06935
06936
06937
06938 ast_bridge_end_dtmf(original, clone_sending_dtmf_digit, clone_sending_dtmf_tv,
06939 "masquerade");
06940 }
06941
06942
06943
06944
06945
06946
06947
06948
06949
06950
06951 if (visible_indication) {
06952 ast_indicate(original, visible_indication);
06953 }
06954
06955
06956
06957 if (moh_is_playing) {
06958 ast_moh_start(original, NULL, NULL);
06959 }
06960
06961 ast_channel_lock(original);
06962
06963
06964 if (ast_test_flag(original, AST_FLAG_BLOCKING)) {
06965 pthread_kill(original->blocker, SIGURG);
06966 }
06967
06968 ast_debug(1, "Done Masquerading %s (%d)\n", original->name, original->_state);
06969
06970 if ((bridged = ast_bridged_channel(original))) {
06971 ast_channel_ref(bridged);
06972 ast_channel_unlock(original);
06973 ast_indicate(bridged, AST_CONTROL_SRCCHANGE);
06974 ast_channel_unref(bridged);
06975 } else {
06976 ast_channel_unlock(original);
06977 }
06978 ast_indicate(original, AST_CONTROL_SRCCHANGE);
06979
06980 if (xfer_colp) {
06981
06982
06983
06984
06985
06986 masquerade_colp_transfer(original, xfer_colp);
06987 }
06988
06989 if (xfer_ds) {
06990 ast_datastore_free(xfer_ds);
06991 }
06992
06993 if (clone_was_zombie) {
06994 ast_channel_lock(clonechan);
06995 ast_debug(1, "Destroying channel clone '%s'\n", clonechan->name);
06996 ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup",
06997 "Channel: %s\r\n"
06998 "Uniqueid: %s\r\n"
06999 "Cause: %d\r\n"
07000 "Cause-txt: %s\r\n",
07001 clonechan->name,
07002 clonechan->uniqueid,
07003 clonechan->hangupcause,
07004 ast_cause2str(clonechan->hangupcause)
07005 );
07006 ast_channel_unlock(clonechan);
07007
07008
07009
07010
07011
07012 ast_channel_unref(clonechan);
07013 } else {
07014 ao2_link(channels, clonechan);
07015 }
07016
07017 ao2_link(channels, original);
07018 ao2_unlock(channels);
07019
07020
07021 ast_channel_unref(original);
07022 ast_channel_unref(clonechan);
07023
07024 return 0;
07025 }
07026
07027 void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
07028 {
07029 ast_channel_lock(chan);
07030
07031 if (cid_num) {
07032 chan->caller.id.number.valid = 1;
07033 ast_free(chan->caller.id.number.str);
07034 chan->caller.id.number.str = ast_strdup(cid_num);
07035 }
07036 if (cid_name) {
07037 chan->caller.id.name.valid = 1;
07038 ast_free(chan->caller.id.name.str);
07039 chan->caller.id.name.str = ast_strdup(cid_name);
07040 }
07041 if (cid_ani) {
07042 chan->caller.ani.number.valid = 1;
07043 ast_free(chan->caller.ani.number.str);
07044 chan->caller.ani.number.str = ast_strdup(cid_ani);
07045 }
07046 if (chan->cdr) {
07047 ast_cdr_setcid(chan->cdr, chan);
07048 }
07049
07050 report_new_callerid(chan);
07051
07052 ast_channel_unlock(chan);
07053 }
07054
07055 void ast_channel_set_caller(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
07056 {
07057 if (&chan->caller == caller) {
07058
07059 return;
07060 }
07061
07062 ast_channel_lock(chan);
07063 ast_party_caller_set(&chan->caller, caller, update);
07064 ast_channel_unlock(chan);
07065 }
07066
07067 void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
07068 {
07069 const char *pre_set_number;
07070 const char *pre_set_name;
07071
07072 if (&chan->caller == caller) {
07073
07074 return;
07075 }
07076
07077 ast_channel_lock(chan);
07078 pre_set_number =
07079 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL);
07080 pre_set_name = S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL);
07081 ast_party_caller_set(&chan->caller, caller, update);
07082 if (S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)
07083 != pre_set_number
07084 || S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)
07085 != pre_set_name) {
07086
07087 report_new_callerid(chan);
07088 }
07089 if (chan->cdr) {
07090 ast_cdr_setcid(chan->cdr, chan);
07091 }
07092 ast_channel_unlock(chan);
07093 }
07094
07095 int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
07096 {
07097 int oldstate = chan->_state;
07098 char name[AST_CHANNEL_NAME], *dashptr;
07099
07100 if (oldstate == state)
07101 return 0;
07102
07103 ast_copy_string(name, chan->name, sizeof(name));
07104 if ((dashptr = strrchr(name, '-'))) {
07105 *dashptr = '\0';
07106 }
07107
07108 chan->_state = state;
07109
07110
07111
07112
07113 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, (chan->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), name);
07114
07115
07116 ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate",
07117 "Channel: %s\r\n"
07118 "ChannelState: %d\r\n"
07119 "ChannelStateDesc: %s\r\n"
07120 "CallerIDNum: %s\r\n"
07121 "CallerIDName: %s\r\n"
07122 "ConnectedLineNum: %s\r\n"
07123 "ConnectedLineName: %s\r\n"
07124 "Uniqueid: %s\r\n",
07125 chan->name, chan->_state, ast_state2str(chan->_state),
07126 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
07127 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
07128 S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, ""),
07129 S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, ""),
07130 chan->uniqueid);
07131
07132 return 0;
07133 }
07134
07135
07136 struct ast_channel *ast_bridged_channel(struct ast_channel *chan)
07137 {
07138 struct ast_channel *bridged;
07139 bridged = chan->_bridge;
07140 if (bridged && bridged->tech->bridged_channel)
07141 bridged = bridged->tech->bridged_channel(chan, bridged);
07142 return bridged;
07143 }
07144
07145 static void bridge_playfile(struct ast_channel *chan, struct ast_channel *peer, const char *sound, int remain)
07146 {
07147 int min = 0, sec = 0, check;
07148
07149 check = ast_autoservice_start(peer);
07150 if (check)
07151 return;
07152
07153 if (remain > 0) {
07154 if (remain / 60 > 1) {
07155 min = remain / 60;
07156 sec = remain % 60;
07157 } else {
07158 sec = remain;
07159 }
07160 }
07161
07162 if (!strcmp(sound,"timeleft")) {
07163 ast_stream_and_wait(chan, "vm-youhave", "");
07164 if (min) {
07165 ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL);
07166 ast_stream_and_wait(chan, "queue-minutes", "");
07167 }
07168 if (sec) {
07169 ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL);
07170 ast_stream_and_wait(chan, "queue-seconds", "");
07171 }
07172 } else {
07173 ast_stream_and_wait(chan, sound, "");
07174 }
07175
07176 ast_autoservice_stop(peer);
07177 }
07178
07179 static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct ast_channel *c1,
07180 struct ast_bridge_config *config, struct ast_frame **fo,
07181 struct ast_channel **rc)
07182 {
07183
07184 struct ast_channel *cs[3];
07185 struct ast_frame *f;
07186 enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
07187 format_t o0nativeformats;
07188 format_t o1nativeformats;
07189 int watch_c0_dtmf;
07190 int watch_c1_dtmf;
07191 void *pvt0, *pvt1;
07192
07193 int frame_put_in_jb = 0;
07194 int jb_in_use;
07195 int to;
07196
07197 cs[0] = c0;
07198 cs[1] = c1;
07199 pvt0 = c0->tech_pvt;
07200 pvt1 = c1->tech_pvt;
07201 o0nativeformats = c0->nativeformats;
07202 o1nativeformats = c1->nativeformats;
07203 watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
07204 watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
07205
07206
07207 jb_in_use = ast_jb_do_usecheck(c0, c1);
07208 if (jb_in_use)
07209 ast_jb_empty_and_reset(c0, c1);
07210
07211 ast_poll_channel_add(c0, c1);
07212
07213 if (config->feature_timer > 0 && ast_tvzero(config->nexteventts)) {
07214
07215
07216
07217 config->nexteventts = ast_tvadd(ast_tvnow(), ast_samp2tv(config->feature_timer, 1000));
07218 }
07219
07220 for (;;) {
07221 struct ast_channel *who, *other;
07222
07223 if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
07224 (o0nativeformats != c0->nativeformats) ||
07225 (o1nativeformats != c1->nativeformats)) {
07226
07227 res = AST_BRIDGE_RETRY;
07228 break;
07229 }
07230 if (config->nexteventts.tv_sec) {
07231 to = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
07232 if (to <= 0) {
07233 if (config->timelimit && !config->feature_timer && !ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
07234 res = AST_BRIDGE_RETRY;
07235
07236 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
07237 } else if (config->feature_timer) {
07238
07239 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
07240 res = AST_BRIDGE_RETRY;
07241 } else {
07242 res = AST_BRIDGE_COMPLETE;
07243 }
07244 break;
07245 }
07246 } else {
07247
07248
07249
07250
07251 if (!ast_tvzero(config->nexteventts)) {
07252 int diff = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
07253 if (diff <= 0) {
07254 res = AST_BRIDGE_RETRY;
07255 break;
07256 }
07257 }
07258 to = -1;
07259 }
07260
07261
07262 if (jb_in_use)
07263 to = ast_jb_get_when_to_wakeup(c0, c1, to);
07264 who = ast_waitfor_n(cs, 2, &to);
07265 if (!who) {
07266
07267 if (jb_in_use)
07268 ast_jb_get_and_deliver(c0, c1);
07269 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {
07270 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07271 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
07272 }
07273 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07274 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
07275 }
07276 ast_channel_lock_both(c0, c1);
07277 c0->_bridge = c1;
07278 c1->_bridge = c0;
07279 ast_channel_unlock(c0);
07280 ast_channel_unlock(c1);
07281 }
07282 continue;
07283 }
07284 f = ast_read(who);
07285 if (!f) {
07286 *fo = NULL;
07287 *rc = who;
07288 ast_debug(1, "Didn't get a frame from channel: %s\n",who->name);
07289 break;
07290 }
07291
07292 other = (who == c0) ? c1 : c0;
07293
07294 if (jb_in_use)
07295 frame_put_in_jb = !ast_jb_put(other, f);
07296
07297 if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
07298 int bridge_exit = 0;
07299
07300 switch (f->subclass.integer) {
07301 case AST_CONTROL_AOC:
07302 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07303 break;
07304 case AST_CONTROL_REDIRECTING:
07305 if (ast_channel_redirecting_macro(who, other, f, other == c0, 1)) {
07306 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07307 }
07308 break;
07309 case AST_CONTROL_CONNECTED_LINE:
07310 if (ast_channel_connected_line_macro(who, other, f, other == c0, 1)) {
07311 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07312 }
07313 break;
07314 case AST_CONTROL_HOLD:
07315 case AST_CONTROL_UNHOLD:
07316 case AST_CONTROL_VIDUPDATE:
07317 case AST_CONTROL_SRCUPDATE:
07318 case AST_CONTROL_SRCCHANGE:
07319 case AST_CONTROL_T38_PARAMETERS:
07320 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07321 if (jb_in_use) {
07322 ast_jb_empty_and_reset(c0, c1);
07323 }
07324 break;
07325 default:
07326 *fo = f;
07327 *rc = who;
07328 bridge_exit = 1;
07329 ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass.integer, who->name);
07330 break;
07331 }
07332 if (bridge_exit)
07333 break;
07334 }
07335 if ((f->frametype == AST_FRAME_VOICE) ||
07336 (f->frametype == AST_FRAME_DTMF_BEGIN) ||
07337 (f->frametype == AST_FRAME_DTMF) ||
07338 (f->frametype == AST_FRAME_VIDEO) ||
07339 (f->frametype == AST_FRAME_IMAGE) ||
07340 (f->frametype == AST_FRAME_HTML) ||
07341 (f->frametype == AST_FRAME_MODEM) ||
07342 (f->frametype == AST_FRAME_TEXT)) {
07343
07344 int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
07345
07346 if (monitored_source &&
07347 (f->frametype == AST_FRAME_DTMF_END ||
07348 f->frametype == AST_FRAME_DTMF_BEGIN)) {
07349 *fo = f;
07350 *rc = who;
07351 ast_debug(1, "Got DTMF %s on channel (%s)\n",
07352 f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
07353 who->name);
07354
07355 break;
07356 }
07357
07358 if (!frame_put_in_jb)
07359 ast_write(other, f);
07360
07361
07362 if (jb_in_use)
07363 ast_jb_get_and_deliver(c0, c1);
07364 }
07365
07366 ast_frfree(f);
07367
07368 #ifndef HAVE_EPOLL
07369
07370 cs[2] = cs[0];
07371 cs[0] = cs[1];
07372 cs[1] = cs[2];
07373 #endif
07374 }
07375
07376 ast_poll_channel_del(c0, c1);
07377
07378 return res;
07379 }
07380
07381
07382 int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
07383 {
07384
07385 if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge)))
07386 return -1;
07387
07388 return c0->tech->early_bridge(c0, c1);
07389 }
07390
07391
07392
07393
07394
07395
07396
07397 static void manager_bridge_event(int onoff, int type, struct ast_channel *c0, struct ast_channel *c1)
07398 {
07399 struct ast_channel *chans[2] = { c0, c1 };
07400 ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans,
07401 "Bridgestate: %s\r\n"
07402 "Bridgetype: %s\r\n"
07403 "Channel1: %s\r\n"
07404 "Channel2: %s\r\n"
07405 "Uniqueid1: %s\r\n"
07406 "Uniqueid2: %s\r\n"
07407 "CallerID1: %s\r\n"
07408 "CallerID2: %s\r\n",
07409 onoff ? "Link" : "Unlink",
07410 type == 1 ? "core" : "native",
07411 c0->name, c1->name,
07412 c0->uniqueid, c1->uniqueid,
07413 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, ""),
07414 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, ""));
07415 }
07416
07417 static void update_bridge_vars(struct ast_channel *c0, struct ast_channel *c1)
07418 {
07419 const char *c0_name;
07420 const char *c1_name;
07421 const char *c0_pvtid = NULL;
07422 const char *c1_pvtid = NULL;
07423
07424 ast_channel_lock(c1);
07425 c1_name = ast_strdupa(c1->name);
07426 if (c1->tech->get_pvt_uniqueid) {
07427 c1_pvtid = ast_strdupa(c1->tech->get_pvt_uniqueid(c1));
07428 }
07429 ast_channel_unlock(c1);
07430
07431 ast_channel_lock(c0);
07432 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) {
07433 pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name);
07434 }
07435 if (c1_pvtid) {
07436 pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1_pvtid);
07437 }
07438 c0_name = ast_strdupa(c0->name);
07439 if (c0->tech->get_pvt_uniqueid) {
07440 c0_pvtid = ast_strdupa(c0->tech->get_pvt_uniqueid(c0));
07441 }
07442 ast_channel_unlock(c0);
07443
07444 ast_channel_lock(c1);
07445 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) {
07446 pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name);
07447 }
07448 if (c0_pvtid) {
07449 pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0_pvtid);
07450 }
07451 ast_channel_unlock(c1);
07452 }
07453
07454 static void bridge_play_sounds(struct ast_channel *c0, struct ast_channel *c1)
07455 {
07456 const char *s, *sound;
07457
07458
07459
07460 ast_channel_lock(c0);
07461 if ((s = pbx_builtin_getvar_helper(c0, "BRIDGE_PLAY_SOUND"))) {
07462 sound = ast_strdupa(s);
07463 ast_channel_unlock(c0);
07464 bridge_playfile(c0, c1, sound, 0);
07465 pbx_builtin_setvar_helper(c0, "BRIDGE_PLAY_SOUND", NULL);
07466 } else {
07467 ast_channel_unlock(c0);
07468 }
07469
07470 ast_channel_lock(c1);
07471 if ((s = pbx_builtin_getvar_helper(c1, "BRIDGE_PLAY_SOUND"))) {
07472 sound = ast_strdupa(s);
07473 ast_channel_unlock(c1);
07474 bridge_playfile(c1, c0, sound, 0);
07475 pbx_builtin_setvar_helper(c1, "BRIDGE_PLAY_SOUND", NULL);
07476 } else {
07477 ast_channel_unlock(c1);
07478 }
07479 }
07480
07481
07482 enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1,
07483 struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
07484 {
07485 struct ast_channel *chans[2] = { c0, c1 };
07486 enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
07487 format_t o0nativeformats;
07488 format_t o1nativeformats;
07489 long time_left_ms=0;
07490 char caller_warning = 0;
07491 char callee_warning = 0;
07492
07493 *fo = NULL;
07494
07495 if (c0->_bridge) {
07496 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07497 c0->name, c0->_bridge->name);
07498 return -1;
07499 }
07500 if (c1->_bridge) {
07501 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07502 c1->name, c1->_bridge->name);
07503 return -1;
07504 }
07505
07506
07507 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07508 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
07509 return -1;
07510
07511 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
07512 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
07513
07514 if (ast_tvzero(config->start_time)) {
07515 config->start_time = ast_tvnow();
07516 if (config->start_sound) {
07517 if (caller_warning) {
07518 bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000);
07519 }
07520 if (callee_warning) {
07521 bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000);
07522 }
07523 }
07524 }
07525
07526
07527 ast_channel_lock_both(c0, c1);
07528 c0->_bridge = c1;
07529 c1->_bridge = c0;
07530 ast_channel_unlock(c0);
07531 ast_channel_unlock(c1);
07532
07533 ast_set_owners_and_peers(c0, c1);
07534
07535 o0nativeformats = c0->nativeformats;
07536 o1nativeformats = c1->nativeformats;
07537
07538 if (config->feature_timer && !ast_tvzero(config->nexteventts)) {
07539 config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000));
07540 } else if (config->timelimit) {
07541 time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time);
07542 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07543 if ((caller_warning || callee_warning) && config->play_warning) {
07544 long next_warn = config->play_warning;
07545 if (time_left_ms < config->play_warning && config->warning_freq > 0) {
07546
07547 long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq;
07548
07549
07550 next_warn = config->play_warning - warns_passed * config->warning_freq;
07551 }
07552 config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000));
07553 }
07554 } else {
07555 config->nexteventts.tv_sec = 0;
07556 config->nexteventts.tv_usec = 0;
07557 }
07558
07559 if (!c0->tech->send_digit_begin)
07560 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
07561 if (!c1->tech->send_digit_begin)
07562 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
07563 manager_bridge_event(1, 1, c0, c1);
07564
07565
07566 ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07567 ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07568
07569 for (;;) {
07570 struct timeval now = { 0, };
07571 int to;
07572
07573 to = -1;
07574
07575 if (!ast_tvzero(config->nexteventts)) {
07576 now = ast_tvnow();
07577 to = ast_tvdiff_ms(config->nexteventts, now);
07578 if (to <= 0) {
07579 if (!config->timelimit) {
07580 res = AST_BRIDGE_COMPLETE;
07581 break;
07582 }
07583 to = 0;
07584 }
07585 }
07586
07587 if (config->timelimit) {
07588 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
07589 if (time_left_ms < to)
07590 to = time_left_ms;
07591
07592 if (time_left_ms <= 0) {
07593 if (caller_warning && config->end_sound)
07594 bridge_playfile(c0, c1, config->end_sound, 0);
07595 if (callee_warning && config->end_sound)
07596 bridge_playfile(c1, c0, config->end_sound, 0);
07597 *fo = NULL;
07598 res = 0;
07599 ast_test_suite_event_notify("BRIDGE_TIMELIMIT", "Channel1: %s\r\nChannel2: %s", c0->name, c1->name);
07600 break;
07601 }
07602
07603 if (!to) {
07604 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
07605 int t = (time_left_ms + 500) / 1000;
07606 if (caller_warning)
07607 bridge_playfile(c0, c1, config->warning_sound, t);
07608 if (callee_warning)
07609 bridge_playfile(c1, c0, config->warning_sound, t);
07610 }
07611
07612 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) {
07613 config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000));
07614 } else {
07615 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07616 }
07617 }
07618 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
07619 }
07620
07621 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {
07622 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07623 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
07624 }
07625 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07626 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
07627 }
07628 ast_channel_lock_both(c0, c1);
07629 c0->_bridge = c1;
07630 c1->_bridge = c0;
07631 ast_channel_unlock(c0);
07632 ast_channel_unlock(c1);
07633 ast_debug(1, "Unbridge signal received. Ending native bridge.\n");
07634 continue;
07635 }
07636
07637
07638 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07639 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
07640 *fo = NULL;
07641 res = 0;
07642 ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
07643 c0->name, c1->name,
07644 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
07645 ast_check_hangup(c0) ? "Yes" : "No",
07646 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
07647 ast_check_hangup(c1) ? "Yes" : "No");
07648 break;
07649 }
07650
07651 update_bridge_vars(c0, c1);
07652
07653 bridge_play_sounds(c0, c1);
07654
07655 if (c0->tech->bridge &&
07656
07657 (!config->timelimit || to > 1000 || to == 0) &&
07658 (c0->tech->bridge == c1->tech->bridge) &&
07659 !c0->monitor && !c1->monitor &&
07660 !c0->audiohooks && !c1->audiohooks &&
07661 ast_framehook_list_is_empty(c0->framehooks) && ast_framehook_list_is_empty(c1->framehooks) &&
07662 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
07663 int timeoutms = to - 1000 > 0 ? to - 1000 : to;
07664
07665 ast_set_flag(c0, AST_FLAG_NBRIDGE);
07666 ast_set_flag(c1, AST_FLAG_NBRIDGE);
07667 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) {
07668 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
07669 "Channel1: %s\r\n"
07670 "Channel2: %s\r\n"
07671 "Uniqueid1: %s\r\n"
07672 "Uniqueid2: %s\r\n"
07673 "CallerID1: %s\r\n"
07674 "CallerID2: %s\r\n",
07675 c0->name, c1->name,
07676 c0->uniqueid, c1->uniqueid,
07677 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"),
07678 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
07679
07680 ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
07681
07682 ast_clear_flag(c0, AST_FLAG_NBRIDGE);
07683 ast_clear_flag(c1, AST_FLAG_NBRIDGE);
07684
07685 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {
07686 continue;
07687 }
07688
07689 ast_channel_lock_both(c0, c1);
07690 c0->_bridge = NULL;
07691 c1->_bridge = NULL;
07692 ast_channel_unlock(c0);
07693 ast_channel_unlock(c1);
07694 return res;
07695 } else {
07696 ast_clear_flag(c0, AST_FLAG_NBRIDGE);
07697 ast_clear_flag(c1, AST_FLAG_NBRIDGE);
07698 }
07699 switch (res) {
07700 case AST_BRIDGE_RETRY:
07701 if (config->play_warning) {
07702 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
07703 }
07704 continue;
07705 default:
07706 ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name);
07707
07708 case AST_BRIDGE_FAILED_NOWARN:
07709 break;
07710 }
07711 }
07712
07713 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
07714 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
07715 !(c0->generator || c1->generator)) {
07716 if (ast_channel_make_compatible(c0, c1)) {
07717 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
07718 manager_bridge_event(0, 1, c0, c1);
07719 return AST_BRIDGE_FAILED;
07720 }
07721 o0nativeformats = c0->nativeformats;
07722 o1nativeformats = c1->nativeformats;
07723 }
07724
07725 update_bridge_vars(c0, c1);
07726
07727 res = ast_generic_bridge(c0, c1, config, fo, rc);
07728 if (res != AST_BRIDGE_RETRY) {
07729 break;
07730 } else if (config->feature_timer) {
07731
07732 break;
07733 }
07734 }
07735
07736 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
07737 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
07738
07739
07740 ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07741 ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07742
07743 ast_channel_lock_both(c0, c1);
07744 c0->_bridge = NULL;
07745 c1->_bridge = NULL;
07746 ast_channel_unlock(c0);
07747 ast_channel_unlock(c1);
07748
07749 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
07750 "Channel1: %s\r\n"
07751 "Channel2: %s\r\n"
07752 "Uniqueid1: %s\r\n"
07753 "Uniqueid2: %s\r\n"
07754 "CallerID1: %s\r\n"
07755 "CallerID2: %s\r\n",
07756 c0->name, c1->name,
07757 c0->uniqueid, c1->uniqueid,
07758 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"),
07759 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
07760 ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
07761
07762 return res;
07763 }
07764
07765
07766 int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
07767 {
07768 int res;
07769
07770 ast_channel_lock(chan);
07771 if (!chan->tech->setoption) {
07772 errno = ENOSYS;
07773 ast_channel_unlock(chan);
07774 return -1;
07775 }
07776
07777 if (block)
07778 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07779
07780 res = chan->tech->setoption(chan, option, data, datalen);
07781 ast_channel_unlock(chan);
07782
07783 return res;
07784 }
07785
07786 int ast_channel_queryoption(struct ast_channel *chan, int option, void *data, int *datalen, int block)
07787 {
07788 int res;
07789
07790 ast_channel_lock(chan);
07791 if (!chan->tech->queryoption) {
07792 errno = ENOSYS;
07793 ast_channel_unlock(chan);
07794 return -1;
07795 }
07796
07797 if (block)
07798 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07799
07800 res = chan->tech->queryoption(chan, option, data, datalen);
07801 ast_channel_unlock(chan);
07802
07803 return res;
07804 }
07805
07806 struct tonepair_def {
07807 int freq1;
07808 int freq2;
07809 int duration;
07810 int vol;
07811 };
07812
07813 struct tonepair_state {
07814 int fac1;
07815 int fac2;
07816 int v1_1;
07817 int v2_1;
07818 int v3_1;
07819 int v1_2;
07820 int v2_2;
07821 int v3_2;
07822 format_t origwfmt;
07823 int pos;
07824 int duration;
07825 int modulate;
07826 struct ast_frame f;
07827 unsigned char offset[AST_FRIENDLY_OFFSET];
07828 short data[4000];
07829 };
07830
07831 static void tonepair_release(struct ast_channel *chan, void *params)
07832 {
07833 struct tonepair_state *ts = params;
07834
07835 if (chan)
07836 ast_set_write_format(chan, ts->origwfmt);
07837 ast_free(ts);
07838 }
07839
07840 static void *tonepair_alloc(struct ast_channel *chan, void *params)
07841 {
07842 struct tonepair_state *ts;
07843 struct tonepair_def *td = params;
07844
07845 if (!(ts = ast_calloc(1, sizeof(*ts))))
07846 return NULL;
07847 ts->origwfmt = chan->writeformat;
07848 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
07849 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
07850 tonepair_release(NULL, ts);
07851 ts = NULL;
07852 } else {
07853 ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
07854 ts->v1_1 = 0;
07855 ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07856 ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07857 ts->v2_1 = 0;
07858 ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
07859 ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07860 ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07861 ts->duration = td->duration;
07862 ts->modulate = 0;
07863 }
07864
07865 ast_set_flag(chan, AST_FLAG_WRITE_INT);
07866 return ts;
07867 }
07868
07869 static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples)
07870 {
07871 struct tonepair_state *ts = data;
07872 int x;
07873
07874
07875
07876
07877 len = samples * 2;
07878
07879 if (len > sizeof(ts->data) / 2 - 1) {
07880 ast_log(LOG_WARNING, "Can't generate that much data!\n");
07881 return -1;
07882 }
07883 memset(&ts->f, 0, sizeof(ts->f));
07884 for (x=0;x<len/2;x++) {
07885 ts->v1_1 = ts->v2_1;
07886 ts->v2_1 = ts->v3_1;
07887 ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
07888
07889 ts->v1_2 = ts->v2_2;
07890 ts->v2_2 = ts->v3_2;
07891 ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
07892 if (ts->modulate) {
07893 int p;
07894 p = ts->v3_2 - 32768;
07895 if (p < 0) p = -p;
07896 p = ((p * 9) / 10) + 1;
07897 ts->data[x] = (ts->v3_1 * p) >> 15;
07898 } else
07899 ts->data[x] = ts->v3_1 + ts->v3_2;
07900 }
07901 ts->f.frametype = AST_FRAME_VOICE;
07902 ts->f.subclass.codec = AST_FORMAT_SLINEAR;
07903 ts->f.datalen = len;
07904 ts->f.samples = samples;
07905 ts->f.offset = AST_FRIENDLY_OFFSET;
07906 ts->f.data.ptr = ts->data;
07907 ast_write(chan, &ts->f);
07908 ts->pos += x;
07909 if (ts->duration > 0) {
07910 if (ts->pos >= ts->duration * 8)
07911 return -1;
07912 }
07913 return 0;
07914 }
07915
07916 static struct ast_generator tonepair = {
07917 .alloc = tonepair_alloc,
07918 .release = tonepair_release,
07919 .generate = tonepair_generator,
07920 };
07921
07922 int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
07923 {
07924 struct tonepair_def d = { 0, };
07925
07926 d.freq1 = freq1;
07927 d.freq2 = freq2;
07928 d.duration = duration;
07929 d.vol = (vol < 1) ? 8192 : vol;
07930 if (ast_activate_generator(chan, &tonepair, &d))
07931 return -1;
07932 return 0;
07933 }
07934
07935 void ast_tonepair_stop(struct ast_channel *chan)
07936 {
07937 ast_deactivate_generator(chan);
07938 }
07939
07940 int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
07941 {
07942 int res;
07943
07944 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
07945 return res;
07946
07947
07948 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
07949 struct ast_frame *f = ast_read(chan);
07950 if (f)
07951 ast_frfree(f);
07952 else
07953 return -1;
07954 }
07955 return 0;
07956 }
07957
07958 ast_group_t ast_get_group(const char *s)
07959 {
07960 char *piece;
07961 char *c;
07962 int start=0, finish=0, x;
07963 ast_group_t group = 0;
07964
07965 if (ast_strlen_zero(s))
07966 return 0;
07967
07968 c = ast_strdupa(s);
07969
07970 while ((piece = strsep(&c, ","))) {
07971 if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) {
07972
07973 } else if (sscanf(piece, "%30d", &start)) {
07974
07975 finish = start;
07976 } else {
07977 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
07978 continue;
07979 }
07980 for (x = start; x <= finish; x++) {
07981 if ((x > 63) || (x < 0)) {
07982 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
07983 } else
07984 group |= ((ast_group_t) 1 << x);
07985 }
07986 }
07987 return group;
07988 }
07989
07990 static int (*ast_moh_start_ptr)(struct ast_channel *, const char *, const char *) = NULL;
07991 static void (*ast_moh_stop_ptr)(struct ast_channel *) = NULL;
07992 static void (*ast_moh_cleanup_ptr)(struct ast_channel *) = NULL;
07993
07994 void ast_install_music_functions(int (*start_ptr)(struct ast_channel *, const char *, const char *),
07995 void (*stop_ptr)(struct ast_channel *),
07996 void (*cleanup_ptr)(struct ast_channel *))
07997 {
07998 ast_moh_start_ptr = start_ptr;
07999 ast_moh_stop_ptr = stop_ptr;
08000 ast_moh_cleanup_ptr = cleanup_ptr;
08001 }
08002
08003 void ast_uninstall_music_functions(void)
08004 {
08005 ast_moh_start_ptr = NULL;
08006 ast_moh_stop_ptr = NULL;
08007 ast_moh_cleanup_ptr = NULL;
08008 }
08009
08010
08011 int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
08012 {
08013 if (ast_moh_start_ptr)
08014 return ast_moh_start_ptr(chan, mclass, interpclass);
08015
08016 ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default"));
08017
08018 return 0;
08019 }
08020
08021
08022 void ast_moh_stop(struct ast_channel *chan)
08023 {
08024 if (ast_moh_stop_ptr)
08025 ast_moh_stop_ptr(chan);
08026 }
08027
08028 void ast_moh_cleanup(struct ast_channel *chan)
08029 {
08030 if (ast_moh_cleanup_ptr)
08031 ast_moh_cleanup_ptr(chan);
08032 }
08033
08034 static int ast_channel_hash_cb(const void *obj, const int flags)
08035 {
08036 const struct ast_channel *chan = obj;
08037
08038
08039
08040 if (ast_strlen_zero(chan->name)) {
08041 return 0;
08042 }
08043
08044 return ast_str_case_hash(chan->name);
08045 }
08046
08047 int ast_plc_reload(void)
08048 {
08049 struct ast_variable *var;
08050 struct ast_flags config_flags = { 0 };
08051 struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
08052 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
08053 return 0;
08054 for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
08055 if (!strcasecmp(var->name, "genericplc")) {
08056 ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC);
08057 }
08058 }
08059 ast_config_destroy(cfg);
08060 return 0;
08061 }
08062
08063
08064
08065
08066
08067 static int data_channels_provider_handler(const struct ast_data_search *search,
08068 struct ast_data *root)
08069 {
08070 struct ast_channel *c;
08071 struct ast_channel_iterator *iter = NULL;
08072 struct ast_data *data_channel;
08073
08074 for (iter = ast_channel_iterator_all_new();
08075 iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
08076 ast_channel_lock(c);
08077
08078 data_channel = ast_data_add_node(root, "channel");
08079 if (!data_channel) {
08080 ast_channel_unlock(c);
08081 continue;
08082 }
08083
08084 if (ast_channel_data_add_structure(data_channel, c, 1) < 0) {
08085 ast_log(LOG_ERROR, "Unable to add channel structure for channel: %s\n", c->name);
08086 }
08087
08088 ast_channel_unlock(c);
08089
08090 if (!ast_data_search_match(search, data_channel)) {
08091 ast_data_remove_node(root, data_channel);
08092 }
08093 }
08094 if (iter) {
08095 ast_channel_iterator_destroy(iter);
08096 }
08097
08098 return 0;
08099 }
08100
08101
08102
08103
08104
08105 static int data_channeltypes_provider_handler(const struct ast_data_search *search,
08106 struct ast_data *data_root)
08107 {
08108 struct chanlist *cl;
08109 struct ast_data *data_type;
08110
08111 AST_RWLIST_RDLOCK(&backends);
08112 AST_RWLIST_TRAVERSE(&backends, cl, list) {
08113 data_type = ast_data_add_node(data_root, "type");
08114 if (!data_type) {
08115 continue;
08116 }
08117 ast_data_add_str(data_type, "name", cl->tech->type);
08118 ast_data_add_str(data_type, "description", cl->tech->description);
08119 ast_data_add_bool(data_type, "devicestate", cl->tech->devicestate ? 1 : 0);
08120 ast_data_add_bool(data_type, "indications", cl->tech->indicate ? 1 : 0);
08121 ast_data_add_bool(data_type, "transfer", cl->tech->transfer ? 1 : 0);
08122 ast_data_add_bool(data_type, "send_digit_begin", cl->tech->send_digit_begin ? 1 : 0);
08123 ast_data_add_bool(data_type, "send_digit_end", cl->tech->send_digit_end ? 1 : 0);
08124 ast_data_add_bool(data_type, "call", cl->tech->call ? 1 : 0);
08125 ast_data_add_bool(data_type, "hangup", cl->tech->hangup ? 1 : 0);
08126 ast_data_add_bool(data_type, "answer", cl->tech->answer ? 1 : 0);
08127 ast_data_add_bool(data_type, "read", cl->tech->read ? 1 : 0);
08128 ast_data_add_bool(data_type, "write", cl->tech->write ? 1 : 0);
08129 ast_data_add_bool(data_type, "send_text", cl->tech->send_text ? 1 : 0);
08130 ast_data_add_bool(data_type, "send_image", cl->tech->send_image ? 1 : 0);
08131 ast_data_add_bool(data_type, "send_html", cl->tech->send_html ? 1 : 0);
08132 ast_data_add_bool(data_type, "exception", cl->tech->exception ? 1 : 0);
08133 ast_data_add_bool(data_type, "bridge", cl->tech->bridge ? 1 : 0);
08134 ast_data_add_bool(data_type, "early_bridge", cl->tech->early_bridge ? 1 : 0);
08135 ast_data_add_bool(data_type, "fixup", cl->tech->fixup ? 1 : 0);
08136 ast_data_add_bool(data_type, "setoption", cl->tech->setoption ? 1 : 0);
08137 ast_data_add_bool(data_type, "queryoption", cl->tech->queryoption ? 1 : 0);
08138 ast_data_add_bool(data_type, "write_video", cl->tech->write_video ? 1 : 0);
08139 ast_data_add_bool(data_type, "write_text", cl->tech->write_text ? 1 : 0);
08140 ast_data_add_bool(data_type, "bridged_channel", cl->tech->bridged_channel ? 1 : 0);
08141 ast_data_add_bool(data_type, "func_channel_read", cl->tech->func_channel_read ? 1 : 0);
08142 ast_data_add_bool(data_type, "func_channel_write", cl->tech->func_channel_write ? 1 : 0);
08143 ast_data_add_bool(data_type, "get_base_channel", cl->tech->get_base_channel ? 1 : 0);
08144 ast_data_add_bool(data_type, "set_base_channel", cl->tech->set_base_channel ? 1 : 0);
08145 ast_data_add_bool(data_type, "get_pvt_uniqueid", cl->tech->get_pvt_uniqueid ? 1 : 0);
08146 ast_data_add_bool(data_type, "cc_callback", cl->tech->cc_callback ? 1 : 0);
08147
08148 ast_data_add_codecs(data_type, "capabilities", cl->tech->capabilities);
08149
08150 if (!ast_data_search_match(search, data_type)) {
08151 ast_data_remove_node(data_root, data_type);
08152 }
08153 }
08154 AST_RWLIST_UNLOCK(&backends);
08155
08156 return 0;
08157 }
08158
08159
08160
08161
08162
08163 static const struct ast_data_handler channels_provider = {
08164 .version = AST_DATA_HANDLER_VERSION,
08165 .get = data_channels_provider_handler
08166 };
08167
08168
08169
08170
08171
08172 static const struct ast_data_handler channeltypes_provider = {
08173 .version = AST_DATA_HANDLER_VERSION,
08174 .get = data_channeltypes_provider_handler
08175 };
08176
08177 static const struct ast_data_entry channel_providers[] = {
08178 AST_DATA_ENTRY("/asterisk/core/channels", &channels_provider),
08179 AST_DATA_ENTRY("/asterisk/core/channeltypes", &channeltypes_provider),
08180 };
08181
08182 static void channels_shutdown(void)
08183 {
08184 ast_data_unregister(NULL);
08185 ast_cli_unregister_multiple(cli_channel, ARRAY_LEN(cli_channel));
08186 if (channels) {
08187 ao2_ref(channels, -1);
08188 channels = NULL;
08189 }
08190 }
08191
08192 void ast_channels_init(void)
08193 {
08194 channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS,
08195 ast_channel_hash_cb, ast_channel_cmp_cb);
08196
08197 ast_cli_register_multiple(cli_channel, ARRAY_LEN(cli_channel));
08198
08199 ast_data_register_multiple_core(channel_providers, ARRAY_LEN(channel_providers));
08200
08201 ast_plc_reload();
08202
08203 ast_register_atexit(channels_shutdown);
08204 }
08205
08206
08207 char *ast_print_group(char *buf, int buflen, ast_group_t group)
08208 {
08209 unsigned int i;
08210 int first = 1;
08211 char num[3];
08212
08213 buf[0] = '\0';
08214
08215 if (!group)
08216 return buf;
08217
08218 for (i = 0; i <= 63; i++) {
08219 if (group & ((ast_group_t) 1 << i)) {
08220 if (!first) {
08221 strncat(buf, ", ", buflen - strlen(buf) - 1);
08222 } else {
08223 first = 0;
08224 }
08225 snprintf(num, sizeof(num), "%u", i);
08226 strncat(buf, num, buflen - strlen(buf) - 1);
08227 }
08228 }
08229 return buf;
08230 }
08231
08232 void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
08233 {
08234 struct ast_variable *cur;
08235
08236 for (cur = vars; cur; cur = cur->next)
08237 pbx_builtin_setvar_helper(chan, cur->name, cur->value);
08238 }
08239
08240 static void *silence_generator_alloc(struct ast_channel *chan, void *data)
08241 {
08242
08243 return data;
08244 }
08245
08246 static void silence_generator_release(struct ast_channel *chan, void *data)
08247 {
08248
08249 }
08250
08251 static int silence_generator_generate(struct ast_channel *chan, void *data, int len, int samples)
08252 {
08253 short buf[samples];
08254 struct ast_frame frame = {
08255 .frametype = AST_FRAME_VOICE,
08256 .subclass.codec = AST_FORMAT_SLINEAR,
08257 .data.ptr = buf,
08258 .samples = samples,
08259 .datalen = sizeof(buf),
08260 };
08261
08262 memset(buf, 0, sizeof(buf));
08263
08264 if (ast_write(chan, &frame))
08265 return -1;
08266
08267 return 0;
08268 }
08269
08270 static struct ast_generator silence_generator = {
08271 .alloc = silence_generator_alloc,
08272 .release = silence_generator_release,
08273 .generate = silence_generator_generate,
08274 };
08275
08276 struct ast_silence_generator {
08277 int old_write_format;
08278 };
08279
08280 struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan)
08281 {
08282 struct ast_silence_generator *state;
08283
08284 if (!(state = ast_calloc(1, sizeof(*state)))) {
08285 return NULL;
08286 }
08287
08288 state->old_write_format = chan->writeformat;
08289
08290 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
08291 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
08292 ast_free(state);
08293 return NULL;
08294 }
08295
08296 ast_activate_generator(chan, &silence_generator, state);
08297
08298 ast_debug(1, "Started silence generator on '%s'\n", chan->name);
08299
08300 return state;
08301 }
08302
08303 static int internal_deactivate_generator(struct ast_channel *chan, void* generator)
08304 {
08305 ast_channel_lock(chan);
08306
08307 if (!chan->generatordata) {
08308 ast_debug(1, "Trying to stop silence generator when there is no "
08309 "generator on '%s'\n", chan->name);
08310 ast_channel_unlock(chan);
08311 return 0;
08312 }
08313 if (chan->generator != generator) {
08314 ast_debug(1, "Trying to stop silence generator when it is not the current "
08315 "generator on '%s'\n", chan->name);
08316 ast_channel_unlock(chan);
08317 return 0;
08318 }
08319 if (chan->generator && chan->generator->release) {
08320 chan->generator->release(chan, chan->generatordata);
08321 }
08322 chan->generatordata = NULL;
08323 chan->generator = NULL;
08324 ast_channel_set_fd(chan, AST_GENERATOR_FD, -1);
08325 ast_clear_flag(chan, AST_FLAG_WRITE_INT);
08326 ast_settimeout(chan, 0, NULL, NULL);
08327 ast_channel_unlock(chan);
08328
08329 return 1;
08330 }
08331
08332 void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
08333 {
08334 if (!state)
08335 return;
08336
08337 if (internal_deactivate_generator(chan, &silence_generator)) {
08338 ast_debug(1, "Stopped silence generator on '%s'\n", chan->name);
08339
08340 if (ast_set_write_format(chan, state->old_write_format) < 0)
08341 ast_log(LOG_ERROR, "Could not return write format to its original state\n");
08342 }
08343 ast_free(state);
08344 }
08345
08346
08347
08348 const char *channelreloadreason2txt(enum channelreloadreason reason)
08349 {
08350 switch (reason) {
08351 case CHANNEL_MODULE_LOAD:
08352 return "LOAD (Channel module load)";
08353
08354 case CHANNEL_MODULE_RELOAD:
08355 return "RELOAD (Channel module reload)";
08356
08357 case CHANNEL_CLI_RELOAD:
08358 return "CLIRELOAD (Channel module reload by CLI command)";
08359
08360 default:
08361 return "MANAGERRELOAD (Channel module reload by manager)";
08362 }
08363 };
08364
08365
08366
08367
08368
08369
08370
08371
08372
08373 int ast_say_number(struct ast_channel *chan, int num,
08374 const char *ints, const char *language, const char *options)
08375 {
08376 return ast_say_number_full(chan, num, ints, language, options, -1, -1);
08377 }
08378
08379 int ast_say_enumeration(struct ast_channel *chan, int num,
08380 const char *ints, const char *language, const char *options)
08381 {
08382 return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
08383 }
08384
08385 int ast_say_digits(struct ast_channel *chan, int num,
08386 const char *ints, const char *lang)
08387 {
08388 return ast_say_digits_full(chan, num, ints, lang, -1, -1);
08389 }
08390
08391 int ast_say_digit_str(struct ast_channel *chan, const char *str,
08392 const char *ints, const char *lang)
08393 {
08394 return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
08395 }
08396
08397 int ast_say_character_str(struct ast_channel *chan, const char *str,
08398 const char *ints, const char *lang)
08399 {
08400 return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
08401 }
08402
08403 int ast_say_phonetic_str(struct ast_channel *chan, const char *str,
08404 const char *ints, const char *lang)
08405 {
08406 return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
08407 }
08408
08409 int ast_say_digits_full(struct ast_channel *chan, int num,
08410 const char *ints, const char *lang, int audiofd, int ctrlfd)
08411 {
08412 char buf[256];
08413
08414 snprintf(buf, sizeof(buf), "%d", num);
08415
08416 return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
08417 }
08418
08419 void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
08420 {
08421 ast_party_id_copy(&dest->id, &src->id);
08422 ast_party_id_copy(&dest->ani, &src->ani);
08423 dest->ani2 = src->ani2;
08424 }
08425
08426 void ast_connected_line_copy_to_caller(struct ast_party_caller *dest, const struct ast_party_connected_line *src)
08427 {
08428 ast_party_id_copy(&dest->id, &src->id);
08429 ast_party_id_copy(&dest->ani, &src->ani);
08430
08431 dest->ani2 = src->ani2;
08432 }
08433
08434 void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
08435 {
08436 if (&chan->connected == connected) {
08437
08438 return;
08439 }
08440
08441 ast_channel_lock(chan);
08442 ast_party_connected_line_set(&chan->connected, connected, update);
08443 ast_channel_unlock(chan);
08444 }
08445
08446
08447 struct ast_party_name_ies {
08448
08449 int str;
08450
08451 int char_set;
08452
08453 int presentation;
08454
08455 int valid;
08456 };
08457
08458
08459
08460
08461
08462
08463
08464
08465
08466
08467
08468
08469
08470
08471
08472 static int party_name_build_data(unsigned char *data, size_t datalen, const struct ast_party_name *name, const char *label, const struct ast_party_name_ies *ies)
08473 {
08474 size_t length;
08475 size_t pos = 0;
08476
08477
08478
08479
08480
08481 if (name->str) {
08482 length = strlen(name->str);
08483 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08484 ast_log(LOG_WARNING, "No space left for %s name\n", label);
08485 return -1;
08486 }
08487 data[pos++] = ies->str;
08488 data[pos++] = length;
08489 memcpy(data + pos, name->str, length);
08490 pos += length;
08491 }
08492
08493 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08494 ast_log(LOG_WARNING, "No space left for %s name char set\n", label);
08495 return -1;
08496 }
08497 data[pos++] = ies->char_set;
08498 data[pos++] = 1;
08499 data[pos++] = name->char_set;
08500
08501 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08502 ast_log(LOG_WARNING, "No space left for %s name presentation\n", label);
08503 return -1;
08504 }
08505 data[pos++] = ies->presentation;
08506 data[pos++] = 1;
08507 data[pos++] = name->presentation;
08508
08509 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08510 ast_log(LOG_WARNING, "No space left for %s name valid\n", label);
08511 return -1;
08512 }
08513 data[pos++] = ies->valid;
08514 data[pos++] = 1;
08515 data[pos++] = name->valid;
08516
08517 return pos;
08518 }
08519
08520
08521 struct ast_party_number_ies {
08522
08523 int str;
08524
08525 int plan;
08526
08527 int presentation;
08528
08529 int valid;
08530 };
08531
08532
08533
08534
08535
08536
08537
08538
08539
08540
08541
08542
08543
08544
08545
08546 static int party_number_build_data(unsigned char *data, size_t datalen, const struct ast_party_number *number, const char *label, const struct ast_party_number_ies *ies)
08547 {
08548 size_t length;
08549 size_t pos = 0;
08550
08551
08552
08553
08554
08555 if (number->str) {
08556 length = strlen(number->str);
08557 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08558 ast_log(LOG_WARNING, "No space left for %s number\n", label);
08559 return -1;
08560 }
08561 data[pos++] = ies->str;
08562 data[pos++] = length;
08563 memcpy(data + pos, number->str, length);
08564 pos += length;
08565 }
08566
08567 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08568 ast_log(LOG_WARNING, "No space left for %s numbering plan\n", label);
08569 return -1;
08570 }
08571 data[pos++] = ies->plan;
08572 data[pos++] = 1;
08573 data[pos++] = number->plan;
08574
08575 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08576 ast_log(LOG_WARNING, "No space left for %s number presentation\n", label);
08577 return -1;
08578 }
08579 data[pos++] = ies->presentation;
08580 data[pos++] = 1;
08581 data[pos++] = number->presentation;
08582
08583 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08584 ast_log(LOG_WARNING, "No space left for %s number valid\n", label);
08585 return -1;
08586 }
08587 data[pos++] = ies->valid;
08588 data[pos++] = 1;
08589 data[pos++] = number->valid;
08590
08591 return pos;
08592 }
08593
08594
08595 struct ast_party_subaddress_ies {
08596
08597 int str;
08598
08599 int type;
08600
08601 int odd_even_indicator;
08602
08603 int valid;
08604 };
08605
08606
08607
08608
08609
08610
08611
08612
08613
08614
08615
08616
08617
08618
08619
08620 static int party_subaddress_build_data(unsigned char *data, size_t datalen, const struct ast_party_subaddress *subaddress, const char *label, const struct ast_party_subaddress_ies *ies)
08621 {
08622 size_t length;
08623 size_t pos = 0;
08624
08625
08626
08627
08628
08629 if (subaddress->str) {
08630 length = strlen(subaddress->str);
08631 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08632 ast_log(LOG_WARNING, "No space left for %s subaddress\n", label);
08633 return -1;
08634 }
08635 data[pos++] = ies->str;
08636 data[pos++] = length;
08637 memcpy(data + pos, subaddress->str, length);
08638 pos += length;
08639 }
08640
08641 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08642 ast_log(LOG_WARNING, "No space left for %s type of subaddress\n", label);
08643 return -1;
08644 }
08645 data[pos++] = ies->type;
08646 data[pos++] = 1;
08647 data[pos++] = subaddress->type;
08648
08649 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08650 ast_log(LOG_WARNING,
08651 "No space left for %s subaddress odd-even indicator\n", label);
08652 return -1;
08653 }
08654 data[pos++] = ies->odd_even_indicator;
08655 data[pos++] = 1;
08656 data[pos++] = subaddress->odd_even_indicator;
08657
08658 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08659 ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label);
08660 return -1;
08661 }
08662 data[pos++] = ies->valid;
08663 data[pos++] = 1;
08664 data[pos++] = subaddress->valid;
08665
08666 return pos;
08667 }
08668
08669
08670 struct ast_party_id_ies {
08671
08672 struct ast_party_name_ies name;
08673
08674 struct ast_party_number_ies number;
08675
08676 struct ast_party_subaddress_ies subaddress;
08677
08678 int tag;
08679
08680 int combined_presentation;
08681 };
08682
08683
08684
08685
08686
08687
08688
08689
08690
08691
08692
08693
08694
08695
08696
08697
08698 static int party_id_build_data(unsigned char *data, size_t datalen,
08699 const struct ast_party_id *id, const char *label, const struct ast_party_id_ies *ies,
08700 const struct ast_set_party_id *update)
08701 {
08702 size_t length;
08703 size_t pos = 0;
08704 int res;
08705
08706
08707
08708
08709
08710
08711 if (!update || update->name) {
08712 res = party_name_build_data(data + pos, datalen - pos, &id->name, label,
08713 &ies->name);
08714 if (res < 0) {
08715 return -1;
08716 }
08717 pos += res;
08718 }
08719
08720 if (!update || update->number) {
08721 res = party_number_build_data(data + pos, datalen - pos, &id->number, label,
08722 &ies->number);
08723 if (res < 0) {
08724 return -1;
08725 }
08726 pos += res;
08727 }
08728
08729 if (!update || update->subaddress) {
08730 res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress,
08731 label, &ies->subaddress);
08732 if (res < 0) {
08733 return -1;
08734 }
08735 pos += res;
08736 }
08737
08738
08739 if (id->tag) {
08740 length = strlen(id->tag);
08741 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08742 ast_log(LOG_WARNING, "No space left for %s tag\n", label);
08743 return -1;
08744 }
08745 data[pos++] = ies->tag;
08746 data[pos++] = length;
08747 memcpy(data + pos, id->tag, length);
08748 pos += length;
08749 }
08750
08751
08752 if (!update || update->number) {
08753 int presentation;
08754
08755 if (!update || update->name) {
08756 presentation = ast_party_id_presentation(id);
08757 } else {
08758
08759
08760
08761
08762
08763 presentation = id->number.presentation;
08764 }
08765
08766 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08767 ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label);
08768 return -1;
08769 }
08770 data[pos++] = ies->combined_presentation;
08771 data[pos++] = 1;
08772 data[pos++] = presentation;
08773 }
08774
08775 return pos;
08776 }
08777
08778
08779
08780
08781
08782 enum {
08783 AST_CONNECTED_LINE_NUMBER,
08784 AST_CONNECTED_LINE_NAME,
08785 AST_CONNECTED_LINE_NUMBER_PLAN,
08786 AST_CONNECTED_LINE_ID_PRESENTATION,
08787 AST_CONNECTED_LINE_SOURCE,
08788 AST_CONNECTED_LINE_SUBADDRESS,
08789 AST_CONNECTED_LINE_SUBADDRESS_TYPE,
08790 AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
08791 AST_CONNECTED_LINE_SUBADDRESS_VALID,
08792 AST_CONNECTED_LINE_TAG,
08793 AST_CONNECTED_LINE_VERSION,
08794 AST_CONNECTED_LINE_NAME_VALID,
08795 AST_CONNECTED_LINE_NAME_CHAR_SET,
08796 AST_CONNECTED_LINE_NAME_PRESENTATION,
08797 AST_CONNECTED_LINE_NUMBER_VALID,
08798 AST_CONNECTED_LINE_NUMBER_PRESENTATION,
08799 };
08800
08801 int ast_connected_line_build_data(unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
08802 {
08803 int32_t value;
08804 size_t pos = 0;
08805 int res;
08806
08807 static const struct ast_party_id_ies ies = {
08808 .name.str = AST_CONNECTED_LINE_NAME,
08809 .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET,
08810 .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION,
08811 .name.valid = AST_CONNECTED_LINE_NAME_VALID,
08812
08813 .number.str = AST_CONNECTED_LINE_NUMBER,
08814 .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN,
08815 .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION,
08816 .number.valid = AST_CONNECTED_LINE_NUMBER_VALID,
08817
08818 .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS,
08819 .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE,
08820 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
08821 .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID,
08822
08823 .tag = AST_CONNECTED_LINE_TAG,
08824 .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION,
08825 };
08826
08827
08828
08829
08830
08831
08832
08833 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08834 ast_log(LOG_WARNING, "No space left for connected line frame version\n");
08835 return -1;
08836 }
08837 data[pos++] = AST_CONNECTED_LINE_VERSION;
08838 data[pos++] = 1;
08839 data[pos++] = 2;
08840
08841 res = party_id_build_data(data + pos, datalen - pos, &connected->id,
08842 "connected line", &ies, update ? &update->id : NULL);
08843 if (res < 0) {
08844 return -1;
08845 }
08846 pos += res;
08847
08848
08849 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
08850 ast_log(LOG_WARNING, "No space left for connected line source\n");
08851 return -1;
08852 }
08853 data[pos++] = AST_CONNECTED_LINE_SOURCE;
08854 data[pos++] = sizeof(value);
08855 value = htonl(connected->source);
08856 memcpy(data + pos, &value, sizeof(value));
08857 pos += sizeof(value);
08858
08859 return pos;
08860 }
08861
08862 int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, struct ast_party_connected_line *connected)
08863 {
08864 size_t pos;
08865 unsigned char ie_len;
08866 unsigned char ie_id;
08867 int32_t value;
08868 int frame_version = 1;
08869 int combined_presentation = 0;
08870 int got_combined_presentation = 0;
08871
08872 for (pos = 0; pos < datalen; pos += ie_len) {
08873 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
08874 ast_log(LOG_WARNING, "Invalid connected line update\n");
08875 return -1;
08876 }
08877 ie_id = data[pos++];
08878 ie_len = data[pos++];
08879 if (datalen < pos + ie_len) {
08880 ast_log(LOG_WARNING, "Invalid connected line update\n");
08881 return -1;
08882 }
08883
08884 switch (ie_id) {
08885
08886 case AST_CONNECTED_LINE_VERSION:
08887 if (ie_len != 1) {
08888 ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n",
08889 (unsigned) ie_len);
08890 break;
08891 }
08892 frame_version = data[pos];
08893 break;
08894
08895 case AST_CONNECTED_LINE_NAME:
08896 ast_free(connected->id.name.str);
08897 connected->id.name.str = ast_malloc(ie_len + 1);
08898 if (connected->id.name.str) {
08899 memcpy(connected->id.name.str, data + pos, ie_len);
08900 connected->id.name.str[ie_len] = 0;
08901 }
08902 break;
08903 case AST_CONNECTED_LINE_NAME_CHAR_SET:
08904 if (ie_len != 1) {
08905 ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n",
08906 (unsigned) ie_len);
08907 break;
08908 }
08909 connected->id.name.char_set = data[pos];
08910 break;
08911 case AST_CONNECTED_LINE_NAME_PRESENTATION:
08912 if (ie_len != 1) {
08913 ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n",
08914 (unsigned) ie_len);
08915 break;
08916 }
08917 connected->id.name.presentation = data[pos];
08918 break;
08919 case AST_CONNECTED_LINE_NAME_VALID:
08920 if (ie_len != 1) {
08921 ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n",
08922 (unsigned) ie_len);
08923 break;
08924 }
08925 connected->id.name.valid = data[pos];
08926 break;
08927
08928 case AST_CONNECTED_LINE_NUMBER:
08929 ast_free(connected->id.number.str);
08930 connected->id.number.str = ast_malloc(ie_len + 1);
08931 if (connected->id.number.str) {
08932 memcpy(connected->id.number.str, data + pos, ie_len);
08933 connected->id.number.str[ie_len] = 0;
08934 }
08935 break;
08936 case AST_CONNECTED_LINE_NUMBER_PLAN:
08937 if (ie_len != 1) {
08938 ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n",
08939 (unsigned) ie_len);
08940 break;
08941 }
08942 connected->id.number.plan = data[pos];
08943 break;
08944 case AST_CONNECTED_LINE_NUMBER_PRESENTATION:
08945 if (ie_len != 1) {
08946 ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n",
08947 (unsigned) ie_len);
08948 break;
08949 }
08950 connected->id.number.presentation = data[pos];
08951 break;
08952 case AST_CONNECTED_LINE_NUMBER_VALID:
08953 if (ie_len != 1) {
08954 ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n",
08955 (unsigned) ie_len);
08956 break;
08957 }
08958 connected->id.number.valid = data[pos];
08959 break;
08960
08961 case AST_CONNECTED_LINE_ID_PRESENTATION:
08962 if (ie_len != 1) {
08963 ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n",
08964 (unsigned) ie_len);
08965 break;
08966 }
08967 combined_presentation = data[pos];
08968 got_combined_presentation = 1;
08969 break;
08970
08971 case AST_CONNECTED_LINE_SUBADDRESS:
08972 ast_free(connected->id.subaddress.str);
08973 connected->id.subaddress.str = ast_malloc(ie_len + 1);
08974 if (connected->id.subaddress.str) {
08975 memcpy(connected->id.subaddress.str, data + pos, ie_len);
08976 connected->id.subaddress.str[ie_len] = 0;
08977 }
08978 break;
08979 case AST_CONNECTED_LINE_SUBADDRESS_TYPE:
08980 if (ie_len != 1) {
08981 ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n",
08982 (unsigned) ie_len);
08983 break;
08984 }
08985 connected->id.subaddress.type = data[pos];
08986 break;
08987 case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN:
08988 if (ie_len != 1) {
08989 ast_log(LOG_WARNING,
08990 "Invalid connected line subaddress odd-even indicator (%u)\n",
08991 (unsigned) ie_len);
08992 break;
08993 }
08994 connected->id.subaddress.odd_even_indicator = data[pos];
08995 break;
08996 case AST_CONNECTED_LINE_SUBADDRESS_VALID:
08997 if (ie_len != 1) {
08998 ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n",
08999 (unsigned) ie_len);
09000 break;
09001 }
09002 connected->id.subaddress.valid = data[pos];
09003 break;
09004
09005 case AST_CONNECTED_LINE_TAG:
09006 ast_free(connected->id.tag);
09007 connected->id.tag = ast_malloc(ie_len + 1);
09008 if (connected->id.tag) {
09009 memcpy(connected->id.tag, data + pos, ie_len);
09010 connected->id.tag[ie_len] = 0;
09011 }
09012 break;
09013
09014 case AST_CONNECTED_LINE_SOURCE:
09015 if (ie_len != sizeof(value)) {
09016 ast_log(LOG_WARNING, "Invalid connected line source (%u)\n",
09017 (unsigned) ie_len);
09018 break;
09019 }
09020 memcpy(&value, data + pos, sizeof(value));
09021 connected->source = ntohl(value);
09022 break;
09023
09024 default:
09025 ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n",
09026 (unsigned) ie_id, (unsigned) ie_len);
09027 break;
09028 }
09029 }
09030
09031 switch (frame_version) {
09032 case 1:
09033
09034
09035
09036
09037 connected->id.name.valid = 1;
09038 connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09039 connected->id.number.valid = 1;
09040 if (got_combined_presentation) {
09041 connected->id.name.presentation = combined_presentation;
09042 connected->id.number.presentation = combined_presentation;
09043 }
09044 break;
09045 case 2:
09046
09047 break;
09048 default:
09049
09050
09051
09052
09053 ast_log(LOG_DEBUG, "Connected line frame has newer version: %u\n",
09054 (unsigned) frame_version);
09055 break;
09056 }
09057
09058 return 0;
09059 }
09060
09061 void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
09062 {
09063 unsigned char data[1024];
09064 size_t datalen;
09065
09066 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
09067 if (datalen == (size_t) -1) {
09068 return;
09069 }
09070
09071 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
09072 }
09073
09074 void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
09075 {
09076 unsigned char data[1024];
09077 size_t datalen;
09078
09079 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
09080 if (datalen == (size_t) -1) {
09081 return;
09082 }
09083
09084 ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
09085 }
09086
09087 void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09088 {
09089 if (&chan->redirecting == redirecting) {
09090
09091 return;
09092 }
09093
09094 ast_channel_lock(chan);
09095 ast_party_redirecting_set(&chan->redirecting, redirecting, update);
09096 ast_channel_unlock(chan);
09097 }
09098
09099
09100
09101
09102
09103 enum {
09104 AST_REDIRECTING_FROM_NUMBER,
09105 AST_REDIRECTING_FROM_NAME,
09106 AST_REDIRECTING_FROM_NUMBER_PLAN,
09107 AST_REDIRECTING_FROM_ID_PRESENTATION,
09108 AST_REDIRECTING_TO_NUMBER,
09109 AST_REDIRECTING_TO_NAME,
09110 AST_REDIRECTING_TO_NUMBER_PLAN,
09111 AST_REDIRECTING_TO_ID_PRESENTATION,
09112 AST_REDIRECTING_REASON,
09113 AST_REDIRECTING_COUNT,
09114 AST_REDIRECTING_FROM_SUBADDRESS,
09115 AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
09116 AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
09117 AST_REDIRECTING_FROM_SUBADDRESS_VALID,
09118 AST_REDIRECTING_TO_SUBADDRESS,
09119 AST_REDIRECTING_TO_SUBADDRESS_TYPE,
09120 AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
09121 AST_REDIRECTING_TO_SUBADDRESS_VALID,
09122 AST_REDIRECTING_FROM_TAG,
09123 AST_REDIRECTING_TO_TAG,
09124 AST_REDIRECTING_VERSION,
09125 AST_REDIRECTING_FROM_NAME_VALID,
09126 AST_REDIRECTING_FROM_NAME_CHAR_SET,
09127 AST_REDIRECTING_FROM_NAME_PRESENTATION,
09128 AST_REDIRECTING_FROM_NUMBER_VALID,
09129 AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
09130 AST_REDIRECTING_TO_NAME_VALID,
09131 AST_REDIRECTING_TO_NAME_CHAR_SET,
09132 AST_REDIRECTING_TO_NAME_PRESENTATION,
09133 AST_REDIRECTING_TO_NUMBER_VALID,
09134 AST_REDIRECTING_TO_NUMBER_PRESENTATION,
09135 };
09136
09137 int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09138 {
09139 int32_t value;
09140 size_t pos = 0;
09141 int res;
09142
09143 static const struct ast_party_id_ies from_ies = {
09144 .name.str = AST_REDIRECTING_FROM_NAME,
09145 .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET,
09146 .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION,
09147 .name.valid = AST_REDIRECTING_FROM_NAME_VALID,
09148
09149 .number.str = AST_REDIRECTING_FROM_NUMBER,
09150 .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN,
09151 .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
09152 .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID,
09153
09154 .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS,
09155 .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
09156 .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
09157 .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID,
09158
09159 .tag = AST_REDIRECTING_FROM_TAG,
09160 .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION,
09161 };
09162 static const struct ast_party_id_ies to_ies = {
09163 .name.str = AST_REDIRECTING_TO_NAME,
09164 .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET,
09165 .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION,
09166 .name.valid = AST_REDIRECTING_TO_NAME_VALID,
09167
09168 .number.str = AST_REDIRECTING_TO_NUMBER,
09169 .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN,
09170 .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION,
09171 .number.valid = AST_REDIRECTING_TO_NUMBER_VALID,
09172
09173 .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS,
09174 .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE,
09175 .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
09176 .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID,
09177
09178 .tag = AST_REDIRECTING_TO_TAG,
09179 .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION,
09180 };
09181
09182
09183 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
09184 ast_log(LOG_WARNING, "No space left for redirecting frame version\n");
09185 return -1;
09186 }
09187 data[pos++] = AST_REDIRECTING_VERSION;
09188 data[pos++] = 1;
09189 data[pos++] = 2;
09190
09191 res = party_id_build_data(data + pos, datalen - pos, &redirecting->from,
09192 "redirecting-from", &from_ies, update ? &update->from : NULL);
09193 if (res < 0) {
09194 return -1;
09195 }
09196 pos += res;
09197
09198 res = party_id_build_data(data + pos, datalen - pos, &redirecting->to,
09199 "redirecting-to", &to_ies, update ? &update->to : NULL);
09200 if (res < 0) {
09201 return -1;
09202 }
09203 pos += res;
09204
09205
09206 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
09207 ast_log(LOG_WARNING, "No space left for redirecting reason\n");
09208 return -1;
09209 }
09210 data[pos++] = AST_REDIRECTING_REASON;
09211 data[pos++] = sizeof(value);
09212 value = htonl(redirecting->reason);
09213 memcpy(data + pos, &value, sizeof(value));
09214 pos += sizeof(value);
09215
09216
09217 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
09218 ast_log(LOG_WARNING, "No space left for redirecting count\n");
09219 return -1;
09220 }
09221 data[pos++] = AST_REDIRECTING_COUNT;
09222 data[pos++] = sizeof(value);
09223 value = htonl(redirecting->count);
09224 memcpy(data + pos, &value, sizeof(value));
09225 pos += sizeof(value);
09226
09227 return pos;
09228 }
09229
09230 int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct ast_party_redirecting *redirecting)
09231 {
09232 size_t pos;
09233 unsigned char ie_len;
09234 unsigned char ie_id;
09235 int32_t value;
09236 int frame_version = 1;
09237 int from_combined_presentation = 0;
09238 int got_from_combined_presentation = 0;
09239 int to_combined_presentation = 0;
09240 int got_to_combined_presentation = 0;
09241
09242 for (pos = 0; pos < datalen; pos += ie_len) {
09243 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
09244 ast_log(LOG_WARNING, "Invalid redirecting update\n");
09245 return -1;
09246 }
09247 ie_id = data[pos++];
09248 ie_len = data[pos++];
09249 if (datalen < pos + ie_len) {
09250 ast_log(LOG_WARNING, "Invalid redirecting update\n");
09251 return -1;
09252 }
09253
09254 switch (ie_id) {
09255
09256 case AST_REDIRECTING_VERSION:
09257 if (ie_len != 1) {
09258 ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n",
09259 (unsigned) ie_len);
09260 break;
09261 }
09262 frame_version = data[pos];
09263 break;
09264
09265 case AST_REDIRECTING_FROM_NAME:
09266 ast_free(redirecting->from.name.str);
09267 redirecting->from.name.str = ast_malloc(ie_len + 1);
09268 if (redirecting->from.name.str) {
09269 memcpy(redirecting->from.name.str, data + pos, ie_len);
09270 redirecting->from.name.str[ie_len] = 0;
09271 }
09272 break;
09273 case AST_REDIRECTING_FROM_NAME_CHAR_SET:
09274 if (ie_len != 1) {
09275 ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n",
09276 (unsigned) ie_len);
09277 break;
09278 }
09279 redirecting->from.name.char_set = data[pos];
09280 break;
09281 case AST_REDIRECTING_FROM_NAME_PRESENTATION:
09282 if (ie_len != 1) {
09283 ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n",
09284 (unsigned) ie_len);
09285 break;
09286 }
09287 redirecting->from.name.presentation = data[pos];
09288 break;
09289 case AST_REDIRECTING_FROM_NAME_VALID:
09290 if (ie_len != 1) {
09291 ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n",
09292 (unsigned) ie_len);
09293 break;
09294 }
09295 redirecting->from.name.valid = data[pos];
09296 break;
09297
09298 case AST_REDIRECTING_FROM_NUMBER:
09299 ast_free(redirecting->from.number.str);
09300 redirecting->from.number.str = ast_malloc(ie_len + 1);
09301 if (redirecting->from.number.str) {
09302 memcpy(redirecting->from.number.str, data + pos, ie_len);
09303 redirecting->from.number.str[ie_len] = 0;
09304 }
09305 break;
09306 case AST_REDIRECTING_FROM_NUMBER_PLAN:
09307 if (ie_len != 1) {
09308 ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n",
09309 (unsigned) ie_len);
09310 break;
09311 }
09312 redirecting->from.number.plan = data[pos];
09313 break;
09314 case AST_REDIRECTING_FROM_NUMBER_PRESENTATION:
09315 if (ie_len != 1) {
09316 ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n",
09317 (unsigned) ie_len);
09318 break;
09319 }
09320 redirecting->from.number.presentation = data[pos];
09321 break;
09322 case AST_REDIRECTING_FROM_NUMBER_VALID:
09323 if (ie_len != 1) {
09324 ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n",
09325 (unsigned) ie_len);
09326 break;
09327 }
09328 redirecting->from.number.valid = data[pos];
09329 break;
09330
09331 case AST_REDIRECTING_FROM_ID_PRESENTATION:
09332 if (ie_len != 1) {
09333 ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n",
09334 (unsigned) ie_len);
09335 break;
09336 }
09337 from_combined_presentation = data[pos];
09338 got_from_combined_presentation = 1;
09339 break;
09340
09341 case AST_REDIRECTING_FROM_SUBADDRESS:
09342 ast_free(redirecting->from.subaddress.str);
09343 redirecting->from.subaddress.str = ast_malloc(ie_len + 1);
09344 if (redirecting->from.subaddress.str) {
09345 memcpy(redirecting->from.subaddress.str, data + pos, ie_len);
09346 redirecting->from.subaddress.str[ie_len] = 0;
09347 }
09348 break;
09349 case AST_REDIRECTING_FROM_SUBADDRESS_TYPE:
09350 if (ie_len != 1) {
09351 ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n",
09352 (unsigned) ie_len);
09353 break;
09354 }
09355 redirecting->from.subaddress.type = data[pos];
09356 break;
09357 case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN:
09358 if (ie_len != 1) {
09359 ast_log(LOG_WARNING,
09360 "Invalid redirecting-from subaddress odd-even indicator (%u)\n",
09361 (unsigned) ie_len);
09362 break;
09363 }
09364 redirecting->from.subaddress.odd_even_indicator = data[pos];
09365 break;
09366 case AST_REDIRECTING_FROM_SUBADDRESS_VALID:
09367 if (ie_len != 1) {
09368 ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n",
09369 (unsigned) ie_len);
09370 break;
09371 }
09372 redirecting->from.subaddress.valid = data[pos];
09373 break;
09374
09375 case AST_REDIRECTING_FROM_TAG:
09376 ast_free(redirecting->from.tag);
09377 redirecting->from.tag = ast_malloc(ie_len + 1);
09378 if (redirecting->from.tag) {
09379 memcpy(redirecting->from.tag, data + pos, ie_len);
09380 redirecting->from.tag[ie_len] = 0;
09381 }
09382 break;
09383
09384 case AST_REDIRECTING_TO_NAME:
09385 ast_free(redirecting->to.name.str);
09386 redirecting->to.name.str = ast_malloc(ie_len + 1);
09387 if (redirecting->to.name.str) {
09388 memcpy(redirecting->to.name.str, data + pos, ie_len);
09389 redirecting->to.name.str[ie_len] = 0;
09390 }
09391 break;
09392 case AST_REDIRECTING_TO_NAME_CHAR_SET:
09393 if (ie_len != 1) {
09394 ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n",
09395 (unsigned) ie_len);
09396 break;
09397 }
09398 redirecting->to.name.char_set = data[pos];
09399 break;
09400 case AST_REDIRECTING_TO_NAME_PRESENTATION:
09401 if (ie_len != 1) {
09402 ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n",
09403 (unsigned) ie_len);
09404 break;
09405 }
09406 redirecting->to.name.presentation = data[pos];
09407 break;
09408 case AST_REDIRECTING_TO_NAME_VALID:
09409 if (ie_len != 1) {
09410 ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n",
09411 (unsigned) ie_len);
09412 break;
09413 }
09414 redirecting->to.name.valid = data[pos];
09415 break;
09416
09417 case AST_REDIRECTING_TO_NUMBER:
09418 ast_free(redirecting->to.number.str);
09419 redirecting->to.number.str = ast_malloc(ie_len + 1);
09420 if (redirecting->to.number.str) {
09421 memcpy(redirecting->to.number.str, data + pos, ie_len);
09422 redirecting->to.number.str[ie_len] = 0;
09423 }
09424 break;
09425 case AST_REDIRECTING_TO_NUMBER_PLAN:
09426 if (ie_len != 1) {
09427 ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n",
09428 (unsigned) ie_len);
09429 break;
09430 }
09431 redirecting->to.number.plan = data[pos];
09432 break;
09433 case AST_REDIRECTING_TO_NUMBER_PRESENTATION:
09434 if (ie_len != 1) {
09435 ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n",
09436 (unsigned) ie_len);
09437 break;
09438 }
09439 redirecting->to.number.presentation = data[pos];
09440 break;
09441 case AST_REDIRECTING_TO_NUMBER_VALID:
09442 if (ie_len != 1) {
09443 ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n",
09444 (unsigned) ie_len);
09445 break;
09446 }
09447 redirecting->to.number.valid = data[pos];
09448 break;
09449
09450 case AST_REDIRECTING_TO_ID_PRESENTATION:
09451 if (ie_len != 1) {
09452 ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n",
09453 (unsigned) ie_len);
09454 break;
09455 }
09456 to_combined_presentation = data[pos];
09457 got_to_combined_presentation = 1;
09458 break;
09459
09460 case AST_REDIRECTING_TO_SUBADDRESS:
09461 ast_free(redirecting->to.subaddress.str);
09462 redirecting->to.subaddress.str = ast_malloc(ie_len + 1);
09463 if (redirecting->to.subaddress.str) {
09464 memcpy(redirecting->to.subaddress.str, data + pos, ie_len);
09465 redirecting->to.subaddress.str[ie_len] = 0;
09466 }
09467 break;
09468 case AST_REDIRECTING_TO_SUBADDRESS_TYPE:
09469 if (ie_len != 1) {
09470 ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n",
09471 (unsigned) ie_len);
09472 break;
09473 }
09474 redirecting->to.subaddress.type = data[pos];
09475 break;
09476 case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN:
09477 if (ie_len != 1) {
09478 ast_log(LOG_WARNING,
09479 "Invalid redirecting-to subaddress odd-even indicator (%u)\n",
09480 (unsigned) ie_len);
09481 break;
09482 }
09483 redirecting->to.subaddress.odd_even_indicator = data[pos];
09484 break;
09485 case AST_REDIRECTING_TO_SUBADDRESS_VALID:
09486 if (ie_len != 1) {
09487 ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n",
09488 (unsigned) ie_len);
09489 break;
09490 }
09491 redirecting->to.subaddress.valid = data[pos];
09492 break;
09493
09494 case AST_REDIRECTING_TO_TAG:
09495 ast_free(redirecting->to.tag);
09496 redirecting->to.tag = ast_malloc(ie_len + 1);
09497 if (redirecting->to.tag) {
09498 memcpy(redirecting->to.tag, data + pos, ie_len);
09499 redirecting->to.tag[ie_len] = 0;
09500 }
09501 break;
09502
09503 case AST_REDIRECTING_REASON:
09504 if (ie_len != sizeof(value)) {
09505 ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n",
09506 (unsigned) ie_len);
09507 break;
09508 }
09509 memcpy(&value, data + pos, sizeof(value));
09510 redirecting->reason = ntohl(value);
09511 break;
09512
09513 case AST_REDIRECTING_COUNT:
09514 if (ie_len != sizeof(value)) {
09515 ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n",
09516 (unsigned) ie_len);
09517 break;
09518 }
09519 memcpy(&value, data + pos, sizeof(value));
09520 redirecting->count = ntohl(value);
09521 break;
09522
09523 default:
09524 ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n",
09525 (unsigned) ie_id, (unsigned) ie_len);
09526 break;
09527 }
09528 }
09529
09530 switch (frame_version) {
09531 case 1:
09532
09533
09534
09535
09536 redirecting->from.name.valid = 1;
09537 redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09538 redirecting->from.number.valid = 1;
09539 if (got_from_combined_presentation) {
09540 redirecting->from.name.presentation = from_combined_presentation;
09541 redirecting->from.number.presentation = from_combined_presentation;
09542 }
09543
09544 redirecting->to.name.valid = 1;
09545 redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09546 redirecting->to.number.valid = 1;
09547 if (got_to_combined_presentation) {
09548 redirecting->to.name.presentation = to_combined_presentation;
09549 redirecting->to.number.presentation = to_combined_presentation;
09550 }
09551 break;
09552 case 2:
09553
09554 break;
09555 default:
09556
09557
09558
09559
09560 ast_log(LOG_DEBUG, "Redirecting frame has newer version: %u\n",
09561 (unsigned) frame_version);
09562 break;
09563 }
09564
09565 return 0;
09566 }
09567
09568 void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09569 {
09570 unsigned char data[1024];
09571 size_t datalen;
09572
09573 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09574 if (datalen == (size_t) -1) {
09575 return;
09576 }
09577
09578 ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09579 }
09580
09581 void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09582 {
09583 unsigned char data[1024];
09584 size_t datalen;
09585
09586 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09587 if (datalen == (size_t) -1) {
09588 return;
09589 }
09590
09591 ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09592 }
09593
09594 int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int is_caller, int is_frame)
09595 {
09596 const char *macro;
09597 const char *macro_args;
09598 int retval;
09599
09600 ast_channel_lock(macro_chan);
09601 macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09602 ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO");
09603 macro = ast_strdupa(S_OR(macro, ""));
09604 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09605 ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS");
09606 macro_args = ast_strdupa(S_OR(macro_args, ""));
09607
09608 if (ast_strlen_zero(macro)) {
09609 ast_channel_unlock(macro_chan);
09610 return -1;
09611 }
09612
09613 if (is_frame) {
09614 const struct ast_frame *frame = connected_info;
09615
09616 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->connected);
09617 } else {
09618 const struct ast_party_connected_line *connected = connected_info;
09619
09620 ast_party_connected_line_copy(¯o_chan->connected, connected);
09621 }
09622 ast_channel_unlock(macro_chan);
09623
09624 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
09625 if (!retval) {
09626 struct ast_party_connected_line saved_connected;
09627
09628 ast_party_connected_line_init(&saved_connected);
09629 ast_channel_lock(macro_chan);
09630 ast_party_connected_line_copy(&saved_connected, ¯o_chan->connected);
09631 ast_channel_unlock(macro_chan);
09632 ast_channel_update_connected_line(macro_chan, &saved_connected, NULL);
09633 ast_party_connected_line_free(&saved_connected);
09634 }
09635
09636 return retval;
09637 }
09638
09639 int ast_channel_redirecting_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *redirecting_info, int is_caller, int is_frame)
09640 {
09641 const char *macro;
09642 const char *macro_args;
09643 int retval;
09644
09645 ast_channel_lock(macro_chan);
09646 macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09647 ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO");
09648 macro = ast_strdupa(S_OR(macro, ""));
09649 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09650 ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS");
09651 macro_args = ast_strdupa(S_OR(macro_args, ""));
09652
09653 if (ast_strlen_zero(macro)) {
09654 ast_channel_unlock(macro_chan);
09655 return -1;
09656 }
09657
09658 if (is_frame) {
09659 const struct ast_frame *frame = redirecting_info;
09660
09661 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->redirecting);
09662 } else {
09663 const struct ast_party_redirecting *redirecting = redirecting_info;
09664
09665 ast_party_redirecting_copy(¯o_chan->redirecting, redirecting);
09666 }
09667 ast_channel_unlock(macro_chan);
09668
09669 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
09670 if (!retval) {
09671 struct ast_party_redirecting saved_redirecting;
09672
09673 ast_party_redirecting_init(&saved_redirecting);
09674 ast_channel_lock(macro_chan);
09675 ast_party_redirecting_copy(&saved_redirecting, ¯o_chan->redirecting);
09676 ast_channel_unlock(macro_chan);
09677 ast_channel_update_redirecting(macro_chan, &saved_redirecting, NULL);
09678 ast_party_redirecting_free(&saved_redirecting);
09679 }
09680
09681 return retval;
09682 }
09683
09684 static void *channel_cc_params_copy(void *data)
09685 {
09686 const struct ast_cc_config_params *src = data;
09687 struct ast_cc_config_params *dest = ast_cc_config_params_init();
09688 if (!dest) {
09689 return NULL;
09690 }
09691 ast_cc_copy_config_params(dest, src);
09692 return dest;
09693 }
09694
09695 static void channel_cc_params_destroy(void *data)
09696 {
09697 struct ast_cc_config_params *cc_params = data;
09698 ast_cc_config_params_destroy(cc_params);
09699 }
09700
09701 static const struct ast_datastore_info cc_channel_datastore_info = {
09702 .type = "Call Completion",
09703 .duplicate = channel_cc_params_copy,
09704 .destroy = channel_cc_params_destroy,
09705 };
09706
09707 int ast_channel_cc_params_init(struct ast_channel *chan,
09708 const struct ast_cc_config_params *base_params)
09709 {
09710 struct ast_cc_config_params *cc_params;
09711 struct ast_datastore *cc_datastore;
09712
09713 if (!(cc_params = ast_cc_config_params_init())) {
09714 return -1;
09715 }
09716
09717 if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) {
09718 ast_cc_config_params_destroy(cc_params);
09719 return -1;
09720 }
09721
09722 if (base_params) {
09723 ast_cc_copy_config_params(cc_params, base_params);
09724 }
09725 cc_datastore->data = cc_params;
09726 ast_channel_datastore_add(chan, cc_datastore);
09727 return 0;
09728 }
09729
09730 struct ast_cc_config_params *ast_channel_get_cc_config_params(struct ast_channel *chan)
09731 {
09732 struct ast_datastore *cc_datastore;
09733
09734 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09735
09736
09737
09738
09739 if (ast_channel_cc_params_init(chan, NULL)) {
09740 return NULL;
09741 }
09742 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09743
09744 return NULL;
09745 }
09746 }
09747
09748 ast_assert(cc_datastore->data != NULL);
09749 return cc_datastore->data;
09750 }
09751
09752 int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
09753 {
09754 int len = name_buffer_length;
09755 char *dash;
09756 if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) {
09757 return 0;
09758 }
09759
09760
09761 ast_copy_string(device_name, chan->name, name_buffer_length);
09762 if ((dash = strrchr(device_name, '-'))) {
09763 *dash = '\0';
09764 }
09765
09766 return 0;
09767 }
09768
09769 int ast_channel_get_cc_agent_type(struct ast_channel *chan, char *agent_type, size_t size)
09770 {
09771 int len = size;
09772 char *slash;
09773
09774 if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) {
09775 return 0;
09776 }
09777
09778 ast_copy_string(agent_type, chan->name, size);
09779 if ((slash = strchr(agent_type, '/'))) {
09780 *slash = '\0';
09781 }
09782 return 0;
09783 }
09784
09785
09786
09787
09788
09789
09790
09791
09792
09793
09794 #undef ast_channel_alloc
09795 struct ast_channel __attribute__((format(printf, 10, 11)))
09796 *ast_channel_alloc(int needqueue, int state, const char *cid_num,
09797 const char *cid_name, const char *acctcode,
09798 const char *exten, const char *context,
09799 const char *linkedid, const int amaflag,
09800 const char *name_fmt, ...);
09801 struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num,
09802 const char *cid_name, const char *acctcode,
09803 const char *exten, const char *context,
09804 const char *linkedid, const int amaflag,
09805 const char *name_fmt, ...)
09806 {
09807 va_list ap1, ap2;
09808 struct ast_channel *result;
09809
09810
09811 va_start(ap1, name_fmt);
09812 va_start(ap2, name_fmt);
09813 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
09814 linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap1, ap2);
09815 va_end(ap1);
09816 va_end(ap2);
09817
09818 return result;
09819 }