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: 423006 $")
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 (%u)", 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 = %u): %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 %u 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 static void deactivate_generator_nolock(struct ast_channel *chan)
03092 {
03093 if (chan->generatordata) {
03094 struct ast_generator *generator = chan->generator;
03095
03096 if (generator && generator->release) {
03097 generator->release(chan, chan->generatordata);
03098 }
03099 chan->generatordata = NULL;
03100 chan->generator = NULL;
03101 ast_channel_set_fd(chan, AST_GENERATOR_FD, -1);
03102 ast_clear_flag(chan, AST_FLAG_WRITE_INT);
03103 ast_settimeout(chan, 0, NULL, NULL);
03104 }
03105 }
03106
03107 void ast_deactivate_generator(struct ast_channel *chan)
03108 {
03109 ast_channel_lock(chan);
03110 deactivate_generator_nolock(chan);
03111 ast_channel_unlock(chan);
03112 }
03113
03114 static int generator_force(const void *data)
03115 {
03116
03117 void *tmp;
03118 int res;
03119 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
03120 struct ast_channel *chan = (struct ast_channel *)data;
03121
03122 ast_channel_lock(chan);
03123 tmp = chan->generatordata;
03124 chan->generatordata = NULL;
03125 if (chan->generator)
03126 generate = chan->generator->generate;
03127 ast_channel_unlock(chan);
03128
03129 if (!tmp || !generate)
03130 return 0;
03131
03132 res = generate(chan, tmp, 0, ast_format_rate(chan->writeformat & AST_FORMAT_AUDIO_MASK) / 50);
03133
03134 ast_channel_lock(chan);
03135 if (chan->generator && generate == chan->generator->generate) {
03136 chan->generatordata = tmp;
03137 }
03138 ast_channel_unlock(chan);
03139
03140 if (res) {
03141 ast_debug(1, "Auto-deactivating generator\n");
03142 ast_deactivate_generator(chan);
03143 }
03144
03145 return 0;
03146 }
03147
03148 int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
03149 {
03150 int res = 0;
03151
03152 ast_channel_lock(chan);
03153 if (chan->generatordata) {
03154 struct ast_generator *generator_old = chan->generator;
03155
03156 if (generator_old && generator_old->release) {
03157 generator_old->release(chan, chan->generatordata);
03158 }
03159 chan->generatordata = NULL;
03160 }
03161 if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
03162 res = -1;
03163 }
03164 if (!res) {
03165 ast_settimeout(chan, 50, generator_force, chan);
03166 chan->generator = gen;
03167 }
03168 ast_channel_unlock(chan);
03169
03170 ast_prod(chan);
03171
03172 return res;
03173 }
03174
03175
03176 int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
03177 {
03178 int winner = -1;
03179 ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
03180 return winner;
03181 }
03182
03183
03184 #ifdef HAVE_EPOLL
03185 static struct ast_channel *ast_waitfor_nandfds_classic(struct ast_channel **c, int n, int *fds, int nfds,
03186 int *exception, int *outfd, int *ms)
03187 #else
03188 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
03189 int *exception, int *outfd, int *ms)
03190 #endif
03191 {
03192 struct timeval start = { 0 , 0 };
03193 struct pollfd *pfds = NULL;
03194 int res;
03195 long rms;
03196 int x, y, max;
03197 int sz;
03198 struct timeval now = { 0, 0 };
03199 struct timeval whentohangup = { 0, 0 }, diff;
03200 struct ast_channel *winner = NULL;
03201 struct fdmap {
03202 int chan;
03203 int fdno;
03204 } *fdmap = NULL;
03205
03206 if (outfd)
03207 *outfd = -99999;
03208 if (exception)
03209 *exception = 0;
03210
03211 if ((sz = n * AST_MAX_FDS + nfds)) {
03212 pfds = ast_alloca(sizeof(*pfds) * sz);
03213 fdmap = ast_alloca(sizeof(*fdmap) * sz);
03214 } else {
03215
03216 return NULL;
03217 }
03218
03219
03220 for (x = 0; x < n; x++) {
03221 while (c[x]->masq) {
03222 ast_do_masquerade(c[x]);
03223 }
03224
03225 ast_channel_lock(c[x]);
03226 if (!ast_tvzero(c[x]->whentohangup)) {
03227 if (ast_tvzero(whentohangup))
03228 now = ast_tvnow();
03229 diff = ast_tvsub(c[x]->whentohangup, now);
03230 if (diff.tv_sec < 0 || ast_tvzero(diff)) {
03231 ast_test_suite_event_notify("HANGUP_TIME", "Channel: %s", c[x]->name);
03232
03233 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03234 ast_channel_unlock(c[x]);
03235 return c[x];
03236 }
03237 if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0)
03238 whentohangup = diff;
03239 }
03240 ast_channel_unlock(c[x]);
03241 }
03242
03243 rms = *ms;
03244
03245 if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX / 1000) {
03246 rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000;
03247 if (*ms >= 0 && *ms < rms) {
03248 rms = *ms;
03249 }
03250 } else if (!ast_tvzero(whentohangup) && rms < 0) {
03251
03252 rms = INT_MAX;
03253 }
03254
03255
03256
03257
03258
03259 max = 0;
03260 for (x = 0; x < n; x++) {
03261 for (y = 0; y < AST_MAX_FDS; y++) {
03262 fdmap[max].fdno = y;
03263 fdmap[max].chan = x;
03264 max += ast_add_fd(&pfds[max], c[x]->fds[y]);
03265 }
03266 CHECK_BLOCKING(c[x]);
03267 }
03268
03269 for (x = 0; x < nfds; x++) {
03270 fdmap[max].chan = -1;
03271 max += ast_add_fd(&pfds[max], fds[x]);
03272 }
03273
03274 if (*ms > 0)
03275 start = ast_tvnow();
03276
03277 if (sizeof(int) == 4) {
03278 do {
03279 int kbrms = rms;
03280 if (kbrms > 600000)
03281 kbrms = 600000;
03282 res = ast_poll(pfds, max, kbrms);
03283 if (!res)
03284 rms -= kbrms;
03285 } while (!res && (rms > 0));
03286 } else {
03287 res = ast_poll(pfds, max, rms);
03288 }
03289 for (x = 0; x < n; x++)
03290 ast_clear_flag(c[x], AST_FLAG_BLOCKING);
03291 if (res < 0) {
03292 if (errno != EINTR)
03293 *ms = -1;
03294 return NULL;
03295 }
03296 if (!ast_tvzero(whentohangup)) {
03297 now = ast_tvnow();
03298 for (x = 0; x < n; x++) {
03299 if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) {
03300 ast_test_suite_event_notify("HANGUP_TIME", "Channel: %s", c[x]->name);
03301 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03302 if (winner == NULL)
03303 winner = c[x];
03304 }
03305 }
03306 }
03307 if (res == 0) {
03308 *ms = 0;
03309 return winner;
03310 }
03311
03312
03313
03314
03315
03316 for (x = 0; x < max; x++) {
03317 res = pfds[x].revents;
03318 if (res == 0)
03319 continue;
03320 if (fdmap[x].chan >= 0) {
03321 winner = c[fdmap[x].chan];
03322 if (res & POLLPRI)
03323 ast_set_flag(winner, AST_FLAG_EXCEPTION);
03324 else
03325 ast_clear_flag(winner, AST_FLAG_EXCEPTION);
03326 winner->fdno = fdmap[x].fdno;
03327 } else {
03328 if (outfd)
03329 *outfd = pfds[x].fd;
03330 if (exception)
03331 *exception = (res & POLLPRI) ? -1 : 0;
03332 winner = NULL;
03333 }
03334 }
03335 if (*ms > 0) {
03336 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03337 if (*ms < 0)
03338 *ms = 0;
03339 }
03340 return winner;
03341 }
03342
03343 #ifdef HAVE_EPOLL
03344 static struct ast_channel *ast_waitfor_nandfds_simple(struct ast_channel *chan, int *ms)
03345 {
03346 struct timeval start = { 0 , 0 };
03347 int res = 0;
03348 struct epoll_event ev[1];
03349 long diff, rms = *ms;
03350 struct ast_channel *winner = NULL;
03351 struct ast_epoll_data *aed = NULL;
03352
03353
03354
03355 while (chan->masq) {
03356 ast_do_masquerade(chan);
03357 }
03358
03359 ast_channel_lock(chan);
03360
03361 if (!ast_tvzero(chan->whentohangup)) {
03362 if ((diff = ast_tvdiff_ms(chan->whentohangup, ast_tvnow())) < 0) {
03363
03364 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03365 ast_channel_unlock(chan);
03366 return NULL;
03367 }
03368
03369 if (rms > diff)
03370 rms = diff;
03371 }
03372
03373 ast_channel_unlock(chan);
03374
03375
03376 CHECK_BLOCKING(chan);
03377
03378 if (*ms > 0)
03379 start = ast_tvnow();
03380
03381
03382 res = epoll_wait(chan->epfd, ev, 1, rms);
03383
03384
03385 ast_clear_flag(chan, AST_FLAG_BLOCKING);
03386
03387
03388 if (res < 0) {
03389 if (errno != EINTR)
03390 *ms = -1;
03391 return NULL;
03392 }
03393
03394
03395 if (!ast_tvzero(chan->whentohangup)) {
03396 if (ast_tvdiff_ms(ast_tvnow(), chan->whentohangup) >= 0) {
03397 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03398 winner = chan;
03399 }
03400 }
03401
03402
03403 if (!res) {
03404 *ms = 0;
03405 return winner;
03406 }
03407
03408
03409 aed = ev[0].data.ptr;
03410 chan->fdno = aed->which;
03411 if (ev[0].events & EPOLLPRI)
03412 ast_set_flag(chan, AST_FLAG_EXCEPTION);
03413 else
03414 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03415
03416 if (*ms > 0) {
03417 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03418 if (*ms < 0)
03419 *ms = 0;
03420 }
03421
03422 return chan;
03423 }
03424
03425 static struct ast_channel *ast_waitfor_nandfds_complex(struct ast_channel **c, int n, int *ms)
03426 {
03427 struct timeval start = { 0 , 0 };
03428 int res = 0, i;
03429 struct epoll_event ev[25] = { { 0, } };
03430 struct timeval now = { 0, 0 };
03431 long whentohangup = 0, diff = 0, rms = *ms;
03432 struct ast_channel *winner = NULL;
03433
03434 for (i = 0; i < n; i++) {
03435 while (c[i]->masq) {
03436 ast_do_masquerade(c[i]);
03437 }
03438
03439 ast_channel_lock(c[i]);
03440 if (!ast_tvzero(c[i]->whentohangup)) {
03441 if (whentohangup == 0)
03442 now = ast_tvnow();
03443 if ((diff = ast_tvdiff_ms(c[i]->whentohangup, now)) < 0) {
03444 c[i]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03445 ast_channel_unlock(c[i]);
03446 return c[i];
03447 }
03448 if (!whentohangup || whentohangup > diff)
03449 whentohangup = diff;
03450 }
03451 ast_channel_unlock(c[i]);
03452 CHECK_BLOCKING(c[i]);
03453 }
03454
03455 rms = *ms;
03456 if (whentohangup) {
03457 rms = whentohangup;
03458 if (*ms >= 0 && *ms < rms)
03459 rms = *ms;
03460 }
03461
03462 if (*ms > 0)
03463 start = ast_tvnow();
03464
03465 res = epoll_wait(c[0]->epfd, ev, 25, rms);
03466
03467 for (i = 0; i < n; i++)
03468 ast_clear_flag(c[i], AST_FLAG_BLOCKING);
03469
03470 if (res < 0) {
03471 if (errno != EINTR)
03472 *ms = -1;
03473 return NULL;
03474 }
03475
03476 if (whentohangup) {
03477 now = ast_tvnow();
03478 for (i = 0; i < n; i++) {
03479 if (!ast_tvzero(c[i]->whentohangup) && ast_tvdiff_ms(now, c[i]->whentohangup) >= 0) {
03480 c[i]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03481 if (!winner)
03482 winner = c[i];
03483 }
03484 }
03485 }
03486
03487 if (!res) {
03488 *ms = 0;
03489 return winner;
03490 }
03491
03492 for (i = 0; i < res; i++) {
03493 struct ast_epoll_data *aed = ev[i].data.ptr;
03494
03495 if (!ev[i].events || !aed)
03496 continue;
03497
03498 winner = aed->chan;
03499 if (ev[i].events & EPOLLPRI)
03500 ast_set_flag(winner, AST_FLAG_EXCEPTION);
03501 else
03502 ast_clear_flag(winner, AST_FLAG_EXCEPTION);
03503 winner->fdno = aed->which;
03504 }
03505
03506 if (*ms > 0) {
03507 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03508 if (*ms < 0)
03509 *ms = 0;
03510 }
03511
03512 return winner;
03513 }
03514
03515 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
03516 int *exception, int *outfd, int *ms)
03517 {
03518
03519 if (outfd)
03520 *outfd = -99999;
03521 if (exception)
03522 *exception = 0;
03523
03524
03525 if (!n || nfds || c[0]->epfd == -1)
03526 return ast_waitfor_nandfds_classic(c, n, fds, nfds, exception, outfd, ms);
03527 else if (!nfds && n == 1)
03528 return ast_waitfor_nandfds_simple(c[0], ms);
03529 else
03530 return ast_waitfor_nandfds_complex(c, n, ms);
03531 }
03532 #endif
03533
03534 struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
03535 {
03536 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
03537 }
03538
03539 int ast_waitfor(struct ast_channel *c, int ms)
03540 {
03541 if (ms < 0) {
03542 do {
03543 ms = 100000;
03544 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
03545 } while (!ms);
03546 } else {
03547 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
03548 }
03549 return ms;
03550 }
03551
03552 int ast_waitfordigit(struct ast_channel *c, int ms)
03553 {
03554 return ast_waitfordigit_full(c, ms, -1, -1);
03555 }
03556
03557 int ast_settimeout(struct ast_channel *c, unsigned int rate, int (*func)(const void *data), void *data)
03558 {
03559 return ast_settimeout_full(c, rate, func, data, 0);
03560 }
03561
03562 int ast_settimeout_full(struct ast_channel *c, unsigned int rate, int (*func)(const void *data), void *data, unsigned int is_ao2_obj)
03563 {
03564 int res;
03565 unsigned int real_rate = rate, max_rate;
03566
03567 ast_channel_lock(c);
03568
03569 if (c->timingfd == -1) {
03570 ast_channel_unlock(c);
03571 return -1;
03572 }
03573
03574 if (!func) {
03575 rate = 0;
03576 data = NULL;
03577 }
03578
03579 if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) {
03580 real_rate = max_rate;
03581 }
03582
03583 ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate);
03584
03585 res = ast_timer_set_rate(c->timer, real_rate);
03586
03587 if (c->timingdata && ast_test_flag(c, AST_FLAG_TIMINGDATA_IS_AO2_OBJ)) {
03588 ao2_ref(c->timingdata, -1);
03589 }
03590
03591 c->timingfunc = func;
03592 c->timingdata = data;
03593
03594 if (data && is_ao2_obj) {
03595 ao2_ref(data, 1);
03596 ast_set_flag(c, AST_FLAG_TIMINGDATA_IS_AO2_OBJ);
03597 } else {
03598 ast_clear_flag(c, AST_FLAG_TIMINGDATA_IS_AO2_OBJ);
03599 }
03600
03601 if (func == NULL && rate == 0 && c->fdno == AST_TIMING_FD) {
03602
03603
03604
03605
03606
03607
03608 c->fdno = -1;
03609 }
03610
03611 ast_channel_unlock(c);
03612
03613 return res;
03614 }
03615
03616 int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, int cmdfd)
03617 {
03618 struct timeval start = ast_tvnow();
03619 int ms;
03620
03621
03622 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03623 return -1;
03624
03625
03626 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
03627
03628
03629
03630
03631 while ((ms = ast_remaining_ms(start, timeout_ms))) {
03632 struct ast_channel *rchan;
03633 int outfd = -1;
03634
03635 errno = 0;
03636
03637
03638
03639 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
03640
03641 if (!rchan && outfd < 0 && ms) {
03642 if (errno == 0 || errno == EINTR)
03643 continue;
03644 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
03645 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03646 return -1;
03647 } else if (outfd > -1) {
03648
03649 ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n");
03650 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03651 return 1;
03652 } else if (rchan) {
03653 int res;
03654 struct ast_frame *f = ast_read(c);
03655 if (!f)
03656 return -1;
03657
03658 switch (f->frametype) {
03659 case AST_FRAME_DTMF_BEGIN:
03660 break;
03661 case AST_FRAME_DTMF_END:
03662 res = f->subclass.integer;
03663 ast_frfree(f);
03664 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03665 return res;
03666 case AST_FRAME_CONTROL:
03667 switch (f->subclass.integer) {
03668 case AST_CONTROL_HANGUP:
03669 ast_frfree(f);
03670 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03671 return -1;
03672 case AST_CONTROL_RINGING:
03673 case AST_CONTROL_ANSWER:
03674 case AST_CONTROL_SRCUPDATE:
03675 case AST_CONTROL_SRCCHANGE:
03676 case AST_CONTROL_CONNECTED_LINE:
03677 case AST_CONTROL_REDIRECTING:
03678 case AST_CONTROL_UPDATE_RTP_PEER:
03679 case AST_CONTROL_HOLD:
03680 case AST_CONTROL_UNHOLD:
03681 case -1:
03682
03683 break;
03684 default:
03685 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer);
03686 break;
03687 }
03688 break;
03689 case AST_FRAME_VOICE:
03690
03691 if (audiofd > -1) {
03692 if (write(audiofd, f->data.ptr, f->datalen) < 0) {
03693 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
03694 }
03695 }
03696 default:
03697
03698 break;
03699 }
03700 ast_frfree(f);
03701 }
03702 }
03703
03704 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03705
03706 return 0;
03707 }
03708
03709 static void send_dtmf_event(struct ast_channel *chan, const char *direction, const char digit, const char *begin, const char *end)
03710 {
03711 ast_manager_event(chan, EVENT_FLAG_DTMF,
03712 "DTMF",
03713 "Channel: %s\r\n"
03714 "Uniqueid: %s\r\n"
03715 "Digit: %c\r\n"
03716 "Direction: %s\r\n"
03717 "Begin: %s\r\n"
03718 "End: %s\r\n",
03719 chan->name, chan->uniqueid, digit, direction, begin, end);
03720 }
03721
03722 static void ast_read_generator_actions(struct ast_channel *chan, struct ast_frame *f)
03723 {
03724 struct ast_generator *generator;
03725 void *gendata;
03726 int res;
03727 int samples;
03728
03729 generator = chan->generator;
03730 if (!generator
03731 || !generator->generate
03732 || f->frametype != AST_FRAME_VOICE
03733 || !chan->generatordata
03734 || chan->timingfunc) {
03735 return;
03736 }
03737
03738
03739
03740
03741
03742
03743 if (f->subclass.codec != chan->writeformat) {
03744 float factor;
03745
03746 factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass.codec));
03747 samples = (int) (((float) f->samples) * factor);
03748 } else {
03749 samples = f->samples;
03750 }
03751
03752 gendata = chan->generatordata;
03753 chan->generatordata = NULL;
03754
03755
03756
03757
03758
03759
03760
03761
03762
03763
03764
03765
03766 ast_channel_unlock(chan);
03767 res = generator->generate(chan, gendata, f->datalen, samples);
03768 ast_channel_lock(chan);
03769 if (generator == chan->generator) {
03770 chan->generatordata = gendata;
03771 if (res) {
03772 ast_debug(1, "Auto-deactivating generator\n");
03773 ast_deactivate_generator(chan);
03774 }
03775 }
03776 }
03777
03778 static inline void queue_dtmf_readq(struct ast_channel *chan, struct ast_frame *f)
03779 {
03780 struct ast_frame *fr = &chan->dtmff;
03781
03782 fr->frametype = AST_FRAME_DTMF_END;
03783 fr->subclass.integer = f->subclass.integer;
03784 fr->len = f->len;
03785
03786
03787
03788
03789
03790 ast_queue_frame(chan, fr);
03791 }
03792
03793
03794
03795
03796 static inline int should_skip_dtmf(struct ast_channel *chan)
03797 {
03798 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) {
03799
03800
03801 return 1;
03802 }
03803
03804 if (!ast_tvzero(chan->dtmf_tv) &&
03805 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
03806
03807
03808 return 1;
03809 }
03810
03811 return 0;
03812 }
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823 static inline int calc_monitor_jump(int samples, int sample_rate, int seek_rate)
03824 {
03825 int diff = sample_rate - seek_rate;
03826
03827 if (diff > 0) {
03828 samples = samples / (float) (sample_rate / seek_rate);
03829 } else if (diff < 0) {
03830 samples = samples * (float) (seek_rate / sample_rate);
03831 }
03832
03833 return samples;
03834 }
03835
03836 static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
03837 {
03838 struct ast_frame *f = NULL;
03839 int blah;
03840 int prestate;
03841 int cause = 0;
03842
03843
03844
03845
03846
03847 if (chan->masq) {
03848 ast_do_masquerade(chan);
03849 return &ast_null_frame;
03850 }
03851
03852
03853 ast_channel_lock(chan);
03854
03855
03856 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
03857 if (chan->generator)
03858 ast_deactivate_generator(chan);
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869 if (chan->_softhangup) {
03870 ast_queue_control(chan, AST_CONTROL_END_OF_Q);
03871 } else {
03872 goto done;
03873 }
03874 } else {
03875 #ifdef AST_DEVMODE
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888 if (chan->fdno == -1) {
03889 ast_log(LOG_ERROR,
03890 "ast_read() on chan '%s' called with no recorded file descriptor.\n",
03891 chan->name);
03892 }
03893 #endif
03894 }
03895
03896 prestate = chan->_state;
03897 if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD) {
03898 enum ast_timer_event res;
03899
03900 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03901
03902 res = ast_timer_get_event(chan->timer);
03903
03904 switch (res) {
03905 case AST_TIMING_EVENT_EXPIRED:
03906 if (ast_timer_ack(chan->timer, 1) < 0) {
03907 ast_log(LOG_ERROR, "Failed to acknoweldge timer in ast_read\n");
03908 goto done;
03909 }
03910
03911 if (chan->timingfunc) {
03912
03913 int (*func)(const void *) = chan->timingfunc;
03914 void *data = chan->timingdata;
03915 int got_ref = 0;
03916 if (data && ast_test_flag(chan, AST_FLAG_TIMINGDATA_IS_AO2_OBJ)) {
03917 ao2_ref(data, 1);
03918 got_ref = 1;
03919 }
03920 chan->fdno = -1;
03921 ast_channel_unlock(chan);
03922 func(data);
03923 if (got_ref) {
03924 ao2_ref(data, -1);
03925 }
03926 } else {
03927 ast_timer_set_rate(chan->timer, 0);
03928 chan->fdno = -1;
03929 ast_channel_unlock(chan);
03930 }
03931
03932
03933 return &ast_null_frame;
03934
03935 case AST_TIMING_EVENT_CONTINUOUS:
03936 if (AST_LIST_EMPTY(&chan->readq) ||
03937 !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
03938 ast_timer_disable_continuous(chan->timer);
03939 }
03940 break;
03941 }
03942
03943 } else if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
03944
03945
03946
03947 void *tmp = chan->generatordata;
03948 chan->generatordata = NULL;
03949 chan->generator->generate(chan, tmp, -1, -1);
03950 chan->generatordata = tmp;
03951 f = &ast_null_frame;
03952 chan->fdno = -1;
03953 goto done;
03954 }
03955
03956
03957
03958 if (chan->alertpipe[0] > -1) {
03959 int flags = fcntl(chan->alertpipe[0], F_GETFL);
03960
03961
03962 if ((flags & O_NONBLOCK) == 0) {
03963 ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", chan->name);
03964 if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
03965 ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
03966 f = &ast_null_frame;
03967 goto done;
03968 }
03969 }
03970 if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) {
03971 if (errno != EINTR && errno != EAGAIN)
03972 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
03973 }
03974 }
03975
03976
03977
03978 if (!AST_LIST_EMPTY(&chan->readq)) {
03979 int skip_dtmf = should_skip_dtmf(chan);
03980
03981 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, f, frame_list) {
03982
03983
03984
03985
03986 if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) {
03987 continue;
03988 }
03989
03990 AST_LIST_REMOVE_CURRENT(frame_list);
03991 break;
03992 }
03993 AST_LIST_TRAVERSE_SAFE_END;
03994
03995 if (!f) {
03996
03997 f = &ast_null_frame;
03998 if (chan->alertpipe[0] > -1) {
03999 int poke = 0;
04000
04001
04002 if (write(chan->alertpipe[1], &poke, sizeof(poke)) != sizeof(poke)) {
04003 ast_log(LOG_ERROR, "Failed to write to alertpipe: %s\n", strerror(errno));
04004 }
04005 }
04006 }
04007
04008
04009
04010 if (f->frametype == AST_FRAME_CONTROL) {
04011 switch (f->subclass.integer) {
04012 case AST_CONTROL_HANGUP:
04013 chan->_softhangup |= AST_SOFTHANGUP_DEV;
04014 cause = f->data.uint32;
04015
04016 case AST_CONTROL_END_OF_Q:
04017 ast_frfree(f);
04018 f = NULL;
04019 break;
04020 default:
04021 break;
04022 }
04023 }
04024 } else {
04025 chan->blocker = pthread_self();
04026 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
04027 if (chan->tech->exception)
04028 f = chan->tech->exception(chan);
04029 else {
04030 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
04031 f = &ast_null_frame;
04032 }
04033
04034 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
04035 } else if (chan->tech && chan->tech->read)
04036 f = chan->tech->read(chan);
04037 else
04038 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
04039 }
04040
04041
04042
04043
04044
04045 chan->fdno = -1;
04046
04047
04048
04049 f = ast_framehook_list_read_event(chan->framehooks, f);
04050
04051 if (f) {
04052 struct ast_frame *readq_tail = AST_LIST_LAST(&chan->readq);
04053 struct ast_control_read_action_payload *read_action_payload;
04054 struct ast_party_connected_line connected;
04055
04056
04057
04058
04059 if (AST_LIST_NEXT(f, frame_list)) {
04060 ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list));
04061 ast_frfree(AST_LIST_NEXT(f, frame_list));
04062 AST_LIST_NEXT(f, frame_list) = NULL;
04063 }
04064
04065 switch (f->frametype) {
04066 case AST_FRAME_CONTROL:
04067 if (f->subclass.integer == AST_CONTROL_ANSWER) {
04068 if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
04069 ast_debug(1, "Ignoring answer on an inbound call!\n");
04070 ast_frfree(f);
04071 f = &ast_null_frame;
04072 } else if (prestate == AST_STATE_UP && ast_bridged_channel(chan)) {
04073 ast_debug(1, "Dropping duplicate answer!\n");
04074 ast_frfree(f);
04075 f = &ast_null_frame;
04076 } else {
04077
04078 ast_setstate(chan, AST_STATE_UP);
04079
04080 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
04081 }
04082 } else if (f->subclass.integer == AST_CONTROL_READ_ACTION) {
04083 read_action_payload = f->data.ptr;
04084 switch (read_action_payload->action) {
04085 case AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO:
04086 ast_party_connected_line_init(&connected);
04087 ast_party_connected_line_copy(&connected, &chan->connected);
04088 if (ast_connected_line_parse_data(read_action_payload->payload,
04089 read_action_payload->payload_size, &connected)) {
04090 ast_party_connected_line_free(&connected);
04091 break;
04092 }
04093 ast_channel_unlock(chan);
04094 if (ast_channel_connected_line_macro(NULL, chan, &connected, 1, 0)) {
04095 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE,
04096 read_action_payload->payload,
04097 read_action_payload->payload_size);
04098 }
04099 ast_party_connected_line_free(&connected);
04100 ast_channel_lock(chan);
04101 break;
04102 }
04103 ast_frfree(f);
04104 f = &ast_null_frame;
04105 }
04106 break;
04107 case AST_FRAME_DTMF_END:
04108 send_dtmf_event(chan, "Received", f->subclass.integer, "No", "Yes");
04109 ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass.integer, chan->name, f->len);
04110
04111 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) || ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
04112 queue_dtmf_readq(chan, f);
04113 ast_frfree(f);
04114 f = &ast_null_frame;
04115 } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
04116 if (!ast_tvzero(chan->dtmf_tv) &&
04117 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
04118
04119 queue_dtmf_readq(chan, f);
04120 ast_frfree(f);
04121 f = &ast_null_frame;
04122 } else {
04123
04124 f->frametype = AST_FRAME_DTMF_BEGIN;
04125 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
04126 chan->emulate_dtmf_digit = f->subclass.integer;
04127 chan->dtmf_tv = ast_tvnow();
04128 if (f->len) {
04129 if (f->len > AST_MIN_DTMF_DURATION)
04130 chan->emulate_dtmf_duration = f->len;
04131 else
04132 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
04133 } else
04134 chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
04135 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);
04136 }
04137 if (chan->audiohooks) {
04138 struct ast_frame *old_frame = f;
04139
04140
04141
04142 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04143 if (old_frame != f)
04144 ast_frfree(old_frame);
04145 }
04146 } else {
04147 struct timeval now = ast_tvnow();
04148 if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
04149 ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass.integer, chan->name);
04150 ast_clear_flag(chan, AST_FLAG_IN_DTMF);
04151 if (!f->len)
04152 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162 if (ast_tvdiff_ms(now, chan->dtmf_tv) < AST_MIN_DTMF_DURATION) {
04163 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
04164 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);
04165 }
04166 } else if (!f->len) {
04167 ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass.integer, chan->name);
04168 f->len = AST_MIN_DTMF_DURATION;
04169 }
04170 if (f->len < AST_MIN_DTMF_DURATION && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) {
04171 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);
04172 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
04173 chan->emulate_dtmf_digit = f->subclass.integer;
04174 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len;
04175 ast_frfree(f);
04176 f = &ast_null_frame;
04177 } else {
04178 ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass.integer, chan->name);
04179 if (f->len < AST_MIN_DTMF_DURATION) {
04180 f->len = AST_MIN_DTMF_DURATION;
04181 }
04182 chan->dtmf_tv = now;
04183 }
04184 if (chan->audiohooks) {
04185 struct ast_frame *old_frame = f;
04186 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04187 if (old_frame != f)
04188 ast_frfree(old_frame);
04189 }
04190 }
04191 break;
04192 case AST_FRAME_DTMF_BEGIN:
04193 send_dtmf_event(chan, "Received", f->subclass.integer, "Yes", "No");
04194 ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass.integer, chan->name);
04195 if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) ||
04196 (!ast_tvzero(chan->dtmf_tv) &&
04197 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
04198 ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass.integer, chan->name);
04199 ast_frfree(f);
04200 f = &ast_null_frame;
04201 } else {
04202 ast_set_flag(chan, AST_FLAG_IN_DTMF);
04203 chan->dtmf_tv = ast_tvnow();
04204 ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass.integer, chan->name);
04205 }
04206 break;
04207 case AST_FRAME_NULL:
04208
04209
04210
04211
04212 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
04213 struct timeval now = ast_tvnow();
04214 if (!chan->emulate_dtmf_duration) {
04215 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
04216 chan->emulate_dtmf_digit = 0;
04217 } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
04218 chan->emulate_dtmf_duration = 0;
04219 ast_frfree(f);
04220 f = &chan->dtmff;
04221 f->frametype = AST_FRAME_DTMF_END;
04222 f->subclass.integer = chan->emulate_dtmf_digit;
04223 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
04224 chan->dtmf_tv = now;
04225 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
04226 chan->emulate_dtmf_digit = 0;
04227 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, chan->name);
04228 if (chan->audiohooks) {
04229 struct ast_frame *old_frame = f;
04230 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04231 if (old_frame != f) {
04232 ast_frfree(old_frame);
04233 }
04234 }
04235 }
04236 }
04237 break;
04238 case AST_FRAME_VOICE:
04239
04240
04241
04242
04243 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) {
04244 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
04245 chan->emulate_dtmf_digit = 0;
04246 }
04247
04248 if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
04249 if (dropaudio)
04250 ast_read_generator_actions(chan, f);
04251 ast_frfree(f);
04252 f = &ast_null_frame;
04253 }
04254
04255 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
04256 struct timeval now = ast_tvnow();
04257 if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
04258 chan->emulate_dtmf_duration = 0;
04259 ast_frfree(f);
04260 f = &chan->dtmff;
04261 f->frametype = AST_FRAME_DTMF_END;
04262 f->subclass.integer = chan->emulate_dtmf_digit;
04263 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
04264 chan->dtmf_tv = now;
04265 if (chan->audiohooks) {
04266 struct ast_frame *old_frame = f;
04267 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04268 if (old_frame != f)
04269 ast_frfree(old_frame);
04270 }
04271 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, chan->name);
04272 } else {
04273
04274 ast_frfree(f);
04275 f = &ast_null_frame;
04276 }
04277 } else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass.codec & chan->nativeformats)) {
04278
04279 char to[200];
04280 ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
04281 chan->name, ast_getformatname(f->subclass.codec), ast_getformatname_multiple(to, sizeof(to), chan->nativeformats));
04282 ast_frfree(f);
04283 f = &ast_null_frame;
04284 } else if ((f->frametype == AST_FRAME_VOICE)) {
04285
04286 if (chan->audiohooks) {
04287 struct ast_frame *old_frame = f;
04288 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04289 if (old_frame != f)
04290 ast_frfree(old_frame);
04291 }
04292 if (chan->monitor && chan->monitor->read_stream ) {
04293
04294 #ifndef MONITOR_CONSTANT_DELAY
04295 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
04296 if (jump >= 0) {
04297 jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
04298 if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
04299 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
04300 chan->insmpl += (chan->outsmpl - chan->insmpl) + f->samples;
04301 } else
04302 chan->insmpl+= f->samples;
04303 #else
04304 int jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
04305 if (jump - MONITOR_DELAY >= 0) {
04306 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
04307 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
04308 chan->insmpl += chan->outsmpl - chan->insmpl;
04309 } else
04310 chan->insmpl += f->samples;
04311 #endif
04312 if (chan->monitor->state == AST_MONITOR_RUNNING) {
04313 if (ast_writestream(chan->monitor->read_stream, f) < 0)
04314 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
04315 }
04316 }
04317
04318 if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL) {
04319 f = &ast_null_frame;
04320 }
04321
04322
04323
04324
04325
04326
04327
04328
04329 if (AST_LIST_NEXT(f, frame_list)) {
04330 if (!readq_tail) {
04331 ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list));
04332 } else {
04333 __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail);
04334 }
04335 ast_frfree(AST_LIST_NEXT(f, frame_list));
04336 AST_LIST_NEXT(f, frame_list) = NULL;
04337 }
04338
04339
04340
04341 ast_read_generator_actions(chan, f);
04342 }
04343 break;
04344 default:
04345
04346 break;
04347 }
04348 } else {
04349
04350 if (!chan->_softhangup) {
04351 chan->_softhangup |= AST_SOFTHANGUP_DEV;
04352 }
04353 if (cause)
04354 chan->hangupcause = cause;
04355 if (chan->generator)
04356 ast_deactivate_generator(chan);
04357
04358 }
04359
04360
04361 if (chan->fin & DEBUGCHAN_FLAG)
04362 ast_frame_dump(chan->name, f, "<<");
04363 chan->fin = FRAMECOUNT_INC(chan->fin);
04364
04365 done:
04366 if (chan->music_state && chan->generator && chan->generator->digit && f && f->frametype == AST_FRAME_DTMF_END)
04367 chan->generator->digit(chan, f->subclass.integer);
04368
04369 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) {
04370
04371 ast_audiohook_detach_list(chan->audiohooks);
04372 chan->audiohooks = NULL;
04373 }
04374 ast_channel_unlock(chan);
04375 return f;
04376 }
04377
04378 int ast_internal_timing_enabled(struct ast_channel *chan)
04379 {
04380 return chan->timingfd > -1;
04381 }
04382
04383 struct ast_frame *ast_read(struct ast_channel *chan)
04384 {
04385 return __ast_read(chan, 0);
04386 }
04387
04388 struct ast_frame *ast_read_noaudio(struct ast_channel *chan)
04389 {
04390 return __ast_read(chan, 1);
04391 }
04392
04393 int ast_indicate(struct ast_channel *chan, int condition)
04394 {
04395 return ast_indicate_data(chan, condition, NULL, 0);
04396 }
04397
04398 static int attribute_const is_visible_indication(enum ast_control_frame_type condition)
04399 {
04400
04401
04402
04403 switch (condition) {
04404 case AST_CONTROL_PROGRESS:
04405 case AST_CONTROL_PROCEEDING:
04406 case AST_CONTROL_VIDUPDATE:
04407 case AST_CONTROL_SRCUPDATE:
04408 case AST_CONTROL_SRCCHANGE:
04409 case AST_CONTROL_RADIO_KEY:
04410 case AST_CONTROL_RADIO_UNKEY:
04411 case AST_CONTROL_OPTION:
04412 case AST_CONTROL_WINK:
04413 case AST_CONTROL_FLASH:
04414 case AST_CONTROL_OFFHOOK:
04415 case AST_CONTROL_TAKEOFFHOOK:
04416 case AST_CONTROL_ANSWER:
04417 case AST_CONTROL_HANGUP:
04418 case AST_CONTROL_CONNECTED_LINE:
04419 case AST_CONTROL_REDIRECTING:
04420 case AST_CONTROL_TRANSFER:
04421 case AST_CONTROL_T38_PARAMETERS:
04422 case _XXX_AST_CONTROL_T38:
04423 case AST_CONTROL_CC:
04424 case AST_CONTROL_READ_ACTION:
04425 case AST_CONTROL_AOC:
04426 case AST_CONTROL_END_OF_Q:
04427 case AST_CONTROL_UPDATE_RTP_PEER:
04428 break;
04429
04430 case AST_CONTROL_INCOMPLETE:
04431 case AST_CONTROL_CONGESTION:
04432 case AST_CONTROL_BUSY:
04433 case AST_CONTROL_RINGING:
04434 case AST_CONTROL_RING:
04435 case AST_CONTROL_HOLD:
04436
04437 return 1;
04438
04439 case AST_CONTROL_UNHOLD:
04440
04441 break;
04442 }
04443
04444 return 0;
04445 }
04446
04447 int ast_indicate_data(struct ast_channel *chan, int _condition,
04448 const void *data, size_t datalen)
04449 {
04450
04451
04452 enum ast_control_frame_type condition = _condition;
04453 struct ast_tone_zone_sound *ts = NULL;
04454 int res;
04455
04456 struct ast_frame *awesome_frame = NULL;
04457
04458 ast_channel_lock(chan);
04459
04460
04461 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
04462 res = -1;
04463 goto indicate_cleanup;
04464 }
04465
04466 if (!ast_framehook_list_is_empty(chan->framehooks)) {
04467
04468 struct ast_frame frame = {
04469 .frametype = AST_FRAME_CONTROL,
04470 .subclass.integer = condition,
04471 .data.ptr = (void *) data,
04472 .datalen = datalen
04473 };
04474
04475
04476 awesome_frame = ast_frdup(&frame);
04477
04478
04479 if (!(awesome_frame = ast_framehook_list_write_event(chan->framehooks, awesome_frame))
04480 || awesome_frame->frametype != AST_FRAME_CONTROL) {
04481
04482 res = 0;
04483 goto indicate_cleanup;
04484 }
04485
04486 condition = awesome_frame->subclass.integer;
04487 data = awesome_frame->data.ptr;
04488 datalen = awesome_frame->datalen;
04489 }
04490
04491 switch (condition) {
04492 case AST_CONTROL_CONNECTED_LINE:
04493 {
04494 struct ast_party_connected_line connected;
04495
04496 ast_party_connected_line_set_init(&connected, &chan->connected);
04497 res = ast_connected_line_parse_data(data, datalen, &connected);
04498 if (!res) {
04499 ast_channel_set_connected_line(chan, &connected, NULL);
04500 }
04501 ast_party_connected_line_free(&connected);
04502 }
04503 break;
04504
04505 case AST_CONTROL_REDIRECTING:
04506 {
04507 struct ast_party_redirecting redirecting;
04508
04509 ast_party_redirecting_set_init(&redirecting, &chan->redirecting);
04510 res = ast_redirecting_parse_data(data, datalen, &redirecting);
04511 if (!res) {
04512 ast_channel_set_redirecting(chan, &redirecting, NULL);
04513 }
04514 ast_party_redirecting_free(&redirecting);
04515 }
04516 break;
04517
04518 default:
04519 break;
04520 }
04521
04522 if (is_visible_indication(condition)) {
04523
04524 chan->visible_indication = condition;
04525 } else if (condition == AST_CONTROL_UNHOLD || _condition < 0) {
04526
04527 chan->visible_indication = 0;
04528 }
04529
04530 if (chan->tech->indicate) {
04531
04532 res = chan->tech->indicate(chan, condition, data, datalen);
04533 } else {
04534 res = -1;
04535 }
04536
04537 if (!res) {
04538
04539 res = 0;
04540 goto indicate_cleanup;
04541 }
04542
04543
04544
04545
04546
04547
04548
04549 if (_condition < 0) {
04550
04551 ast_playtones_stop(chan);
04552 res = 0;
04553 goto indicate_cleanup;
04554 }
04555
04556
04557 switch (condition) {
04558 case _XXX_AST_CONTROL_T38:
04559
04560 res = -1;
04561 goto indicate_cleanup;
04562 case AST_CONTROL_T38_PARAMETERS:
04563
04564
04565
04566
04567
04568
04569
04570 goto indicate_cleanup;
04571 case AST_CONTROL_RINGING:
04572 ts = ast_get_indication_tone(chan->zone, "ring");
04573
04574
04575
04576
04577
04578
04579
04580 if (chan->_state == AST_STATE_UP) {
04581 res = 0;
04582 }
04583 break;
04584 case AST_CONTROL_BUSY:
04585 ts = ast_get_indication_tone(chan->zone, "busy");
04586 break;
04587 case AST_CONTROL_INCOMPLETE:
04588 case AST_CONTROL_CONGESTION:
04589 ts = ast_get_indication_tone(chan->zone, "congestion");
04590 break;
04591 case AST_CONTROL_PROGRESS:
04592 case AST_CONTROL_PROCEEDING:
04593 case AST_CONTROL_VIDUPDATE:
04594 case AST_CONTROL_SRCUPDATE:
04595 case AST_CONTROL_SRCCHANGE:
04596 case AST_CONTROL_RADIO_KEY:
04597 case AST_CONTROL_RADIO_UNKEY:
04598 case AST_CONTROL_OPTION:
04599 case AST_CONTROL_WINK:
04600 case AST_CONTROL_FLASH:
04601 case AST_CONTROL_OFFHOOK:
04602 case AST_CONTROL_TAKEOFFHOOK:
04603 case AST_CONTROL_ANSWER:
04604 case AST_CONTROL_HANGUP:
04605 case AST_CONTROL_RING:
04606 case AST_CONTROL_HOLD:
04607 case AST_CONTROL_UNHOLD:
04608 case AST_CONTROL_TRANSFER:
04609 case AST_CONTROL_CONNECTED_LINE:
04610 case AST_CONTROL_REDIRECTING:
04611 case AST_CONTROL_CC:
04612 case AST_CONTROL_READ_ACTION:
04613 case AST_CONTROL_AOC:
04614 case AST_CONTROL_END_OF_Q:
04615 case AST_CONTROL_UPDATE_RTP_PEER:
04616
04617 res = 0;
04618 break;
04619 }
04620
04621 if (ts) {
04622
04623 ast_debug(1, "Driver for channel '%s' does not support indication %u, emulating it\n", chan->name, condition);
04624 res = ast_playtones_start(chan, 0, ts->data, 1);
04625 ts = ast_tone_zone_sound_unref(ts);
04626 }
04627
04628 if (res) {
04629
04630 ast_log(LOG_WARNING, "Unable to handle indication %u for '%s'\n", condition, chan->name);
04631 }
04632
04633 indicate_cleanup:
04634 ast_channel_unlock(chan);
04635 if (awesome_frame) {
04636 ast_frfree(awesome_frame);
04637 }
04638
04639 return res;
04640 }
04641
04642 int ast_recvchar(struct ast_channel *chan, int timeout)
04643 {
04644 int c;
04645 char *buf = ast_recvtext(chan, timeout);
04646 if (buf == NULL)
04647 return -1;
04648 c = *(unsigned char *)buf;
04649 ast_free(buf);
04650 return c;
04651 }
04652
04653 char *ast_recvtext(struct ast_channel *chan, int timeout)
04654 {
04655 int res;
04656 char *buf = NULL;
04657 struct timeval start = ast_tvnow();
04658 int ms;
04659
04660 while ((ms = ast_remaining_ms(start, timeout))) {
04661 struct ast_frame *f;
04662
04663 if (ast_check_hangup(chan)) {
04664 break;
04665 }
04666 res = ast_waitfor(chan, ms);
04667 if (res <= 0) {
04668 break;
04669 }
04670 f = ast_read(chan);
04671 if (f == NULL) {
04672 break;
04673 }
04674 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP) {
04675 ast_frfree(f);
04676 break;
04677 } else if (f->frametype == AST_FRAME_TEXT) {
04678 buf = ast_strndup((char *) f->data.ptr, f->datalen);
04679 ast_frfree(f);
04680 break;
04681 }
04682 ast_frfree(f);
04683 }
04684 return buf;
04685 }
04686
04687 int ast_sendtext(struct ast_channel *chan, const char *text)
04688 {
04689 int res = 0;
04690
04691 ast_channel_lock(chan);
04692
04693 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
04694 ast_channel_unlock(chan);
04695 return -1;
04696 }
04697 CHECK_BLOCKING(chan);
04698 if (chan->tech->send_text)
04699 res = chan->tech->send_text(chan, text);
04700 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04701 ast_channel_unlock(chan);
04702 return res;
04703 }
04704
04705 int ast_senddigit_begin(struct ast_channel *chan, char digit)
04706 {
04707
04708
04709 static const char * const dtmf_tones[] = {
04710 "941+1336",
04711 "697+1209",
04712 "697+1336",
04713 "697+1477",
04714 "770+1209",
04715 "770+1336",
04716 "770+1477",
04717 "852+1209",
04718 "852+1336",
04719 "852+1477",
04720 "697+1633",
04721 "770+1633",
04722 "852+1633",
04723 "941+1633",
04724 "941+1209",
04725 "941+1477"
04726 };
04727
04728 if (!chan->tech->send_digit_begin)
04729 return 0;
04730
04731 ast_channel_lock(chan);
04732 chan->sending_dtmf_digit = digit;
04733 chan->sending_dtmf_tv = ast_tvnow();
04734 ast_channel_unlock(chan);
04735
04736 if (!chan->tech->send_digit_begin(chan, digit))
04737 return 0;
04738
04739 if (digit >= '0' && digit <='9')
04740 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
04741 else if (digit >= 'A' && digit <= 'D')
04742 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
04743 else if (digit == '*')
04744 ast_playtones_start(chan, 0, dtmf_tones[14], 0);
04745 else if (digit == '#')
04746 ast_playtones_start(chan, 0, dtmf_tones[15], 0);
04747 else {
04748
04749 ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
04750 }
04751
04752 return 0;
04753 }
04754
04755 int ast_senddigit_end(struct ast_channel *chan, char digit, unsigned int duration)
04756 {
04757 int res = -1;
04758
04759 ast_channel_lock(chan);
04760 if (chan->sending_dtmf_digit == digit) {
04761 chan->sending_dtmf_digit = 0;
04762 }
04763 ast_channel_unlock(chan);
04764
04765 if (chan->tech->send_digit_end)
04766 res = chan->tech->send_digit_end(chan, digit, duration);
04767
04768 if (res && chan->generator)
04769 ast_playtones_stop(chan);
04770
04771 return 0;
04772 }
04773
04774 int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration)
04775 {
04776 if (chan->tech->send_digit_begin) {
04777 ast_senddigit_begin(chan, digit);
04778 ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04779 }
04780
04781 return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04782 }
04783
04784 int ast_prod(struct ast_channel *chan)
04785 {
04786 struct ast_frame a = { AST_FRAME_VOICE };
04787 char nothing[128];
04788
04789
04790 if (chan->_state != AST_STATE_UP) {
04791 ast_debug(1, "Prodding channel '%s'\n", chan->name);
04792 a.subclass.codec = chan->rawwriteformat;
04793 a.data.ptr = nothing + AST_FRIENDLY_OFFSET;
04794 a.src = "ast_prod";
04795 if (ast_write(chan, &a))
04796 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
04797 }
04798 return 0;
04799 }
04800
04801 int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
04802 {
04803 int res;
04804 if (!chan->tech->write_video)
04805 return 0;
04806 res = ast_write(chan, fr);
04807 if (!res)
04808 res = 1;
04809 return res;
04810 }
04811
04812 struct plc_ds {
04813
04814
04815
04816
04817 int16_t *samples_buf;
04818
04819
04820
04821 size_t num_samples;
04822 plc_state_t plc_state;
04823 };
04824
04825 static void plc_ds_destroy(void *data)
04826 {
04827 struct plc_ds *plc = data;
04828 ast_free(plc->samples_buf);
04829 ast_free(plc);
04830 }
04831
04832 static const struct ast_datastore_info plc_ds_info = {
04833 .type = "plc",
04834 .destroy = plc_ds_destroy,
04835 };
04836
04837 static void adjust_frame_for_plc(struct ast_channel *chan, struct ast_frame *frame, struct ast_datastore *datastore)
04838 {
04839 int num_new_samples = frame->samples;
04840 struct plc_ds *plc = datastore->data;
04841
04842
04843
04844
04845
04846
04847
04848
04849
04850
04851
04852
04853
04854
04855
04856
04857
04858
04859
04860
04861 if (!num_new_samples) {
04862 return;
04863 }
04864
04865
04866
04867
04868
04869 if (plc->num_samples < num_new_samples) {
04870 ast_free(plc->samples_buf);
04871 plc->samples_buf = ast_calloc(1, (num_new_samples * sizeof(*plc->samples_buf)) + (AST_FRIENDLY_OFFSET * 2));
04872 if (!plc->samples_buf) {
04873 ast_channel_datastore_remove(chan, datastore);
04874 ast_datastore_free(datastore);
04875 return;
04876 }
04877 plc->num_samples = num_new_samples;
04878 }
04879
04880 if (frame->datalen == 0) {
04881 plc_fillin(&plc->plc_state, plc->samples_buf + AST_FRIENDLY_OFFSET, frame->samples);
04882 frame->data.ptr = plc->samples_buf + AST_FRIENDLY_OFFSET;
04883 frame->datalen = num_new_samples * 2;
04884 frame->offset = AST_FRIENDLY_OFFSET * 2;
04885 } else {
04886 plc_rx(&plc->plc_state, frame->data.ptr, frame->samples);
04887 }
04888 }
04889
04890 static void apply_plc(struct ast_channel *chan, struct ast_frame *frame)
04891 {
04892 struct ast_datastore *datastore;
04893 struct plc_ds *plc;
04894
04895 datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL);
04896 if (datastore) {
04897 plc = datastore->data;
04898 adjust_frame_for_plc(chan, frame, datastore);
04899 return;
04900 }
04901
04902 datastore = ast_datastore_alloc(&plc_ds_info, NULL);
04903 if (!datastore) {
04904 return;
04905 }
04906 plc = ast_calloc(1, sizeof(*plc));
04907 if (!plc) {
04908 ast_datastore_free(datastore);
04909 return;
04910 }
04911 datastore->data = plc;
04912 ast_channel_datastore_add(chan, datastore);
04913 adjust_frame_for_plc(chan, frame, datastore);
04914 }
04915
04916 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
04917 {
04918 int res = -1;
04919 struct ast_frame *f = NULL;
04920 int count = 0;
04921
04922
04923 while(ast_channel_trylock(chan)) {
04924
04925 if(count++ > 10) {
04926 ast_debug(1, "Deadlock avoided for write to channel '%s'\n", chan->name);
04927 return 0;
04928 }
04929 usleep(1);
04930 }
04931
04932 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
04933 goto done;
04934
04935
04936 while (chan->masq) {
04937 ast_channel_unlock(chan);
04938 ast_do_masquerade(chan);
04939 ast_channel_lock(chan);
04940 }
04941 if (chan->masqr) {
04942 res = 0;
04943 goto done;
04944 }
04945
04946
04947
04948 if (!(fr = ast_framehook_list_write_event(chan->framehooks, fr))) {
04949 res = 0;
04950 goto done;
04951 }
04952
04953 if (chan->generatordata && (!fr->src || strcasecmp(fr->src, "ast_prod"))) {
04954 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) {
04955 ast_deactivate_generator(chan);
04956 } else {
04957 if (fr->frametype == AST_FRAME_DTMF_END) {
04958
04959
04960
04961 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04962 ast_channel_unlock(chan);
04963 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);
04964 ast_channel_lock(chan);
04965 CHECK_BLOCKING(chan);
04966 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_UNHOLD) {
04967
04968 res = (chan->tech->indicate == NULL) ? 0 :
04969 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
04970 }
04971 res = 0;
04972 goto done;
04973 }
04974 }
04975
04976 if (chan->fout & DEBUGCHAN_FLAG)
04977 ast_frame_dump(chan->name, fr, ">>");
04978 CHECK_BLOCKING(chan);
04979 switch (fr->frametype) {
04980 case AST_FRAME_CONTROL:
04981 res = (chan->tech->indicate == NULL) ? 0 :
04982 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
04983 break;
04984 case AST_FRAME_DTMF_BEGIN:
04985 if (chan->audiohooks) {
04986 struct ast_frame *old_frame = fr;
04987 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
04988 if (old_frame != fr)
04989 f = fr;
04990 }
04991 send_dtmf_event(chan, "Sent", fr->subclass.integer, "Yes", "No");
04992 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04993 ast_channel_unlock(chan);
04994 res = ast_senddigit_begin(chan, fr->subclass.integer);
04995 ast_channel_lock(chan);
04996 CHECK_BLOCKING(chan);
04997 break;
04998 case AST_FRAME_DTMF_END:
04999 if (chan->audiohooks) {
05000 struct ast_frame *new_frame = fr;
05001
05002 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
05003 if (new_frame != fr) {
05004 ast_frfree(new_frame);
05005 }
05006 }
05007 send_dtmf_event(chan, "Sent", fr->subclass.integer, "No", "Yes");
05008 ast_clear_flag(chan, AST_FLAG_BLOCKING);
05009 ast_channel_unlock(chan);
05010 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);
05011 ast_channel_lock(chan);
05012 CHECK_BLOCKING(chan);
05013 break;
05014 case AST_FRAME_TEXT:
05015 if (fr->subclass.integer == AST_FORMAT_T140) {
05016 res = (chan->tech->write_text == NULL) ? 0 :
05017 chan->tech->write_text(chan, fr);
05018 } else {
05019 res = (chan->tech->send_text == NULL) ? 0 :
05020 chan->tech->send_text(chan, (char *) fr->data.ptr);
05021 }
05022 break;
05023 case AST_FRAME_HTML:
05024 res = (chan->tech->send_html == NULL) ? 0 :
05025 chan->tech->send_html(chan, fr->subclass.integer, (char *) fr->data.ptr, fr->datalen);
05026 break;
05027 case AST_FRAME_VIDEO:
05028
05029 res = (chan->tech->write_video == NULL) ? 0 :
05030 chan->tech->write_video(chan, fr);
05031 break;
05032 case AST_FRAME_MODEM:
05033 res = (chan->tech->write == NULL) ? 0 :
05034 chan->tech->write(chan, fr);
05035 break;
05036 case AST_FRAME_VOICE:
05037 if (chan->tech->write == NULL)
05038 break;
05039
05040 if (ast_opt_generic_plc && fr->subclass.codec == AST_FORMAT_SLINEAR) {
05041 apply_plc(chan, fr);
05042 }
05043
05044
05045 if (fr->subclass.codec == chan->rawwriteformat) {
05046 f = fr;
05047 } else {
05048 if ((!(fr->subclass.codec & chan->nativeformats)) && (chan->writeformat != fr->subclass.codec)) {
05049 char nf[512];
05050
05051
05052
05053
05054
05055
05056
05057
05058
05059
05060 ast_log(LOG_WARNING, "Codec mismatch on channel %s setting write format to %s from %s native formats %s\n",
05061 chan->name, ast_getformatname(fr->subclass.codec), ast_getformatname(chan->writeformat),
05062 ast_getformatname_multiple(nf, sizeof(nf), chan->nativeformats & AST_FORMAT_AUDIO_MASK));
05063 ast_set_write_format(chan, fr->subclass.codec);
05064 }
05065
05066 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
05067 }
05068
05069 if (!f) {
05070 res = 0;
05071 break;
05072 }
05073
05074 if (chan->audiohooks) {
05075 struct ast_frame *prev = NULL, *new_frame, *cur, *dup;
05076 int freeoldlist = 0;
05077
05078 if (f != fr) {
05079 freeoldlist = 1;
05080 }
05081
05082
05083
05084
05085 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
05086 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur);
05087
05088
05089
05090 if (new_frame != cur) {
05091
05092
05093
05094
05095 if ((dup = ast_frisolate(new_frame))) {
05096 AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list);
05097 if (freeoldlist) {
05098 AST_LIST_NEXT(cur, frame_list) = NULL;
05099 ast_frfree(cur);
05100 }
05101 if (new_frame != dup) {
05102 ast_frfree(new_frame);
05103 }
05104 cur = dup;
05105 }
05106 }
05107
05108
05109
05110 if (prev) {
05111 AST_LIST_NEXT(prev, frame_list) = cur;
05112 } else {
05113 f = cur;
05114 }
05115 prev = cur;
05116 }
05117 }
05118
05119
05120
05121
05122
05123 if (chan->monitor && chan->monitor->write_stream) {
05124 struct ast_frame *cur;
05125
05126 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
05127
05128 #ifndef MONITOR_CONSTANT_DELAY
05129 int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples;
05130 if (jump >= 0) {
05131 jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
05132 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
05133 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
05134 chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples;
05135 } else {
05136 chan->outsmpl += cur->samples;
05137 }
05138 #else
05139 int jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
05140 if (jump - MONITOR_DELAY >= 0) {
05141 if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1)
05142 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
05143 chan->outsmpl += chan->insmpl - chan->outsmpl;
05144 } else {
05145 chan->outsmpl += cur->samples;
05146 }
05147 #endif
05148 if (chan->monitor->state == AST_MONITOR_RUNNING) {
05149 if (ast_writestream(chan->monitor->write_stream, cur) < 0)
05150 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
05151 }
05152 }
05153 }
05154
05155
05156
05157
05158 if ((f != fr) && AST_LIST_NEXT(f, frame_list)) {
05159 struct ast_frame *cur, *next;
05160 unsigned int skip = 0;
05161
05162 for (cur = f, next = AST_LIST_NEXT(cur, frame_list);
05163 cur;
05164 cur = next, next = cur ? AST_LIST_NEXT(cur, frame_list) : NULL) {
05165 if (!skip) {
05166 if ((res = chan->tech->write(chan, cur)) < 0) {
05167 chan->_softhangup |= AST_SOFTHANGUP_DEV;
05168 skip = 1;
05169 } else if (next) {
05170
05171
05172
05173 chan->fout = FRAMECOUNT_INC(chan->fout);
05174 }
05175 }
05176 ast_frfree(cur);
05177 }
05178
05179
05180 f = NULL;
05181 } else {
05182 res = chan->tech->write(chan, f);
05183 }
05184 break;
05185 case AST_FRAME_NULL:
05186 case AST_FRAME_IAX:
05187
05188 res = 0;
05189 break;
05190 default:
05191
05192
05193
05194 res = chan->tech->write(chan, fr);
05195 break;
05196 }
05197
05198 if (f && f != fr)
05199 ast_frfree(f);
05200 ast_clear_flag(chan, AST_FLAG_BLOCKING);
05201
05202
05203 if (res < 0) {
05204 chan->_softhangup |= AST_SOFTHANGUP_DEV;
05205 } else {
05206 chan->fout = FRAMECOUNT_INC(chan->fout);
05207 }
05208 done:
05209 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) {
05210
05211 ast_audiohook_detach_list(chan->audiohooks);
05212 chan->audiohooks = NULL;
05213 }
05214 ast_channel_unlock(chan);
05215 return res;
05216 }
05217
05218 static int set_format(struct ast_channel *chan, format_t fmt, format_t *rawformat, format_t *format,
05219 struct ast_trans_pvt **trans, const int direction)
05220 {
05221 format_t native, native_fmt = ast_best_codec(fmt);
05222 int res;
05223 char from[200], to[200];
05224
05225
05226 fmt &= AST_FORMAT_AUDIO_MASK;
05227
05228 native = chan->nativeformats;
05229
05230 if (!fmt || !native)
05231 return 0;
05232
05233
05234 if (!ast_channel_setoption(chan, direction ? AST_OPTION_FORMAT_WRITE : AST_OPTION_FORMAT_READ, &native_fmt, sizeof(int*), 0)) {
05235 ast_debug(1, "Channel driver natively set channel %s to %s format %s\n", chan->name,
05236 direction ? "write" : "read", ast_getformatname(native_fmt));
05237 chan->nativeformats = *rawformat = *format = native_fmt;
05238 if (*trans) {
05239 ast_translator_free_path(*trans);
05240 }
05241 *trans = NULL;
05242 return 0;
05243 }
05244
05245
05246 if (!direction)
05247
05248 res = ast_translator_best_choice(&fmt, &native);
05249 else
05250
05251 res = ast_translator_best_choice(&native, &fmt);
05252
05253 if (res < 0) {
05254 ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
05255 ast_getformatname_multiple(from, sizeof(from), native),
05256 ast_getformatname_multiple(to, sizeof(to), fmt));
05257 return -1;
05258 }
05259
05260
05261 ast_channel_lock(chan);
05262
05263 if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
05264
05265 ast_channel_unlock(chan);
05266 return 0;
05267 }
05268
05269 *rawformat = native;
05270
05271 *format = fmt;
05272
05273 if (*trans) {
05274 ast_translator_free_path(*trans);
05275 *trans = NULL;
05276 }
05277
05278 if (*format == *rawformat) {
05279
05280
05281
05282
05283
05284 res = 0;
05285 } else {
05286 if (!direction) {
05287
05288 *trans = ast_translator_build_path(*format, *rawformat);
05289 } else {
05290
05291 *trans = ast_translator_build_path(*rawformat, *format);
05292 }
05293 res = *trans ? 0 : -1;
05294 }
05295 ast_channel_unlock(chan);
05296 ast_debug(1, "Set channel %s to %s format %s\n", chan->name,
05297 direction ? "write" : "read", ast_getformatname(fmt));
05298 return res;
05299 }
05300
05301 int ast_set_read_format(struct ast_channel *chan, format_t fmt)
05302 {
05303 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
05304 &chan->readtrans, 0);
05305 }
05306
05307 int ast_set_write_format(struct ast_channel *chan, format_t fmt)
05308 {
05309 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
05310 &chan->writetrans, 1);
05311 }
05312
05313 const char *ast_channel_reason2str(int reason)
05314 {
05315 switch (reason)
05316 {
05317 case 0:
05318 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
05319 case AST_CONTROL_HANGUP:
05320 return "Hangup";
05321 case AST_CONTROL_RING:
05322 return "Local Ring";
05323 case AST_CONTROL_RINGING:
05324 return "Remote end Ringing";
05325 case AST_CONTROL_ANSWER:
05326 return "Remote end has Answered";
05327 case AST_CONTROL_BUSY:
05328 return "Remote end is Busy";
05329 case AST_CONTROL_CONGESTION:
05330 return "Congestion (circuits busy)";
05331 default:
05332 return "Unknown Reason!!";
05333 }
05334 }
05335
05336 static void handle_cause(int cause, int *outstate)
05337 {
05338 if (outstate) {
05339
05340 if (cause == AST_CAUSE_BUSY)
05341 *outstate = AST_CONTROL_BUSY;
05342 else if (cause == AST_CAUSE_CONGESTION)
05343 *outstate = AST_CONTROL_CONGESTION;
05344 else
05345 *outstate = 0;
05346 }
05347 }
05348
05349
05350
05351
05352
05353
05354
05355
05356
05357
05358
05359 static void call_forward_inherit(struct ast_channel *new_chan, struct ast_channel *parent, struct ast_channel *orig)
05360 {
05361 if (!ast_test_flag(parent, AST_FLAG_ZOMBIE) && !ast_check_hangup(parent)) {
05362 struct ast_party_redirecting redirecting;
05363
05364
05365
05366
05367
05368 ast_party_redirecting_init(&redirecting);
05369 ast_channel_lock(orig);
05370 ast_party_redirecting_copy(&redirecting, &orig->redirecting);
05371 ast_channel_unlock(orig);
05372 if (ast_channel_redirecting_macro(orig, parent, &redirecting, 1, 0)) {
05373 ast_channel_update_redirecting(parent, &redirecting, NULL);
05374 }
05375 ast_party_redirecting_free(&redirecting);
05376 }
05377
05378
05379 ast_channel_lock_both(parent, new_chan);
05380 ast_channel_inherit_variables(parent, new_chan);
05381 ast_channel_datastore_inherit(parent, new_chan);
05382 ast_channel_unlock(new_chan);
05383 ast_channel_unlock(parent);
05384 }
05385
05386 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)
05387 {
05388 char tmpchan[256];
05389 struct ast_channel *new_chan = NULL;
05390 char *data, *type;
05391 int cause = 0;
05392 int res;
05393
05394
05395 ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan));
05396 if ((data = strchr(tmpchan, '/'))) {
05397 *data++ = '\0';
05398 type = tmpchan;
05399 } else {
05400 const char *forward_context;
05401 ast_channel_lock(orig);
05402 forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT");
05403 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context));
05404 ast_channel_unlock(orig);
05405 data = tmpchan;
05406 type = "Local";
05407 }
05408 if (!(new_chan = ast_request(type, format, orig, data, &cause))) {
05409 ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause);
05410 handle_cause(cause, outstate);
05411 ast_hangup(orig);
05412 return NULL;
05413 }
05414
05415
05416 if (oh) {
05417 if (oh->vars) {
05418 ast_set_variables(new_chan, oh->vars);
05419 }
05420 if (oh->parent_channel) {
05421 call_forward_inherit(new_chan, oh->parent_channel, orig);
05422 }
05423 if (oh->account) {
05424 ast_channel_lock(new_chan);
05425 ast_cdr_setaccount(new_chan, oh->account);
05426 ast_channel_unlock(new_chan);
05427 }
05428 } else if (caller) {
05429 call_forward_inherit(new_chan, caller, orig);
05430 }
05431
05432 ast_channel_lock_both(orig, new_chan);
05433 ast_copy_flags(new_chan->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED);
05434 ast_string_field_set(new_chan, accountcode, orig->accountcode);
05435 ast_party_connected_line_copy(&new_chan->connected, &orig->connected);
05436 ast_party_redirecting_copy(&new_chan->redirecting, &orig->redirecting);
05437 ast_channel_unlock(new_chan);
05438 ast_channel_unlock(orig);
05439
05440
05441 res = ast_call(new_chan, data, 0);
05442 if (timeout) {
05443 *timeout = res;
05444 }
05445 if (res) {
05446 ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data);
05447 ast_hangup(orig);
05448 ast_hangup(new_chan);
05449 return NULL;
05450 }
05451 ast_hangup(orig);
05452
05453 return new_chan;
05454 }
05455
05456 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)
05457 {
05458 int dummy_outstate;
05459 int cause = 0;
05460 struct ast_channel *chan;
05461 int res = 0;
05462 int last_subclass = 0;
05463 struct ast_party_connected_line connected;
05464
05465 if (outstate)
05466 *outstate = 0;
05467 else
05468 outstate = &dummy_outstate;
05469
05470 chan = ast_request(type, format, requestor, data, &cause);
05471 if (!chan) {
05472 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
05473 handle_cause(cause, outstate);
05474 return NULL;
05475 }
05476
05477 if (oh) {
05478 if (oh->vars) {
05479 ast_set_variables(chan, oh->vars);
05480 }
05481 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) {
05482
05483
05484
05485
05486 cid_num = oh->cid_num;
05487 cid_name = oh->cid_name;
05488 }
05489 if (oh->parent_channel) {
05490
05491 ast_channel_lock_both(oh->parent_channel, chan);
05492 ast_channel_inherit_variables(oh->parent_channel, chan);
05493 ast_channel_datastore_inherit(oh->parent_channel, chan);
05494 ast_channel_unlock(oh->parent_channel);
05495 ast_channel_unlock(chan);
05496 }
05497 if (oh->account) {
05498 ast_channel_lock(chan);
05499 ast_cdr_setaccount(chan, oh->account);
05500 ast_channel_unlock(chan);
05501 }
05502 }
05503
05504
05505
05506
05507
05508
05509
05510
05511
05512 ast_set_callerid(chan, cid_num, cid_name, cid_num);
05513
05514 ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED);
05515 ast_party_connected_line_set_init(&connected, &chan->connected);
05516 if (cid_num) {
05517 connected.id.number.valid = 1;
05518 connected.id.number.str = (char *) cid_num;
05519 connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05520 }
05521 if (cid_name) {
05522 connected.id.name.valid = 1;
05523 connected.id.name.str = (char *) cid_name;
05524 connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05525 }
05526 ast_channel_set_connected_line(chan, &connected, NULL);
05527
05528 if (ast_call(chan, data, 0)) {
05529 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
05530 } else {
05531 struct timeval start = ast_tvnow();
05532 res = 1;
05533 while (timeout && chan->_state != AST_STATE_UP) {
05534 struct ast_frame *f;
05535 int ms = ast_remaining_ms(start, timeout);
05536
05537 res = ast_waitfor(chan, ms);
05538 if (res == 0) {
05539 *outstate = AST_CONTROL_RINGING;
05540 break;
05541 }
05542 if (res < 0)
05543 break;
05544 if (!ast_strlen_zero(chan->call_forward)) {
05545 if (!(chan = ast_call_forward(NULL, chan, NULL, format, oh, outstate))) {
05546 return NULL;
05547 }
05548 continue;
05549 }
05550
05551 f = ast_read(chan);
05552 if (!f) {
05553 *outstate = AST_CONTROL_HANGUP;
05554 res = 0;
05555 break;
05556 }
05557 if (f->frametype == AST_FRAME_CONTROL) {
05558 switch (f->subclass.integer) {
05559 case AST_CONTROL_RINGING:
05560 *outstate = f->subclass.integer;
05561 break;
05562
05563 case AST_CONTROL_BUSY:
05564 ast_cdr_busy(chan->cdr);
05565 *outstate = f->subclass.integer;
05566 timeout = 0;
05567 break;
05568
05569 case AST_CONTROL_INCOMPLETE:
05570 ast_cdr_failed(chan->cdr);
05571 *outstate = AST_CONTROL_CONGESTION;
05572 timeout = 0;
05573 break;
05574
05575 case AST_CONTROL_CONGESTION:
05576 ast_cdr_failed(chan->cdr);
05577 *outstate = f->subclass.integer;
05578 timeout = 0;
05579 break;
05580
05581 case AST_CONTROL_ANSWER:
05582 ast_cdr_answer(chan->cdr);
05583 *outstate = f->subclass.integer;
05584 timeout = 0;
05585 break;
05586
05587
05588 case AST_CONTROL_PROGRESS:
05589 case AST_CONTROL_PROCEEDING:
05590 case AST_CONTROL_HOLD:
05591 case AST_CONTROL_UNHOLD:
05592 case AST_CONTROL_VIDUPDATE:
05593 case AST_CONTROL_SRCUPDATE:
05594 case AST_CONTROL_SRCCHANGE:
05595 case AST_CONTROL_CONNECTED_LINE:
05596 case AST_CONTROL_REDIRECTING:
05597 case AST_CONTROL_CC:
05598 case -1:
05599 break;
05600
05601 default:
05602 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer);
05603 }
05604 last_subclass = f->subclass.integer;
05605 }
05606 ast_frfree(f);
05607 }
05608 }
05609
05610
05611 if (oh) {
05612 if (!ast_strlen_zero(oh->context))
05613 ast_copy_string(chan->context, oh->context, sizeof(chan->context));
05614 if (!ast_strlen_zero(oh->exten))
05615 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
05616 if (oh->priority)
05617 chan->priority = oh->priority;
05618 }
05619 if (chan->_state == AST_STATE_UP)
05620 *outstate = AST_CONTROL_ANSWER;
05621
05622 if (res <= 0) {
05623 ast_channel_lock(chan);
05624 if (AST_CONTROL_RINGING == last_subclass) {
05625 chan->hangupcause = AST_CAUSE_NO_ANSWER;
05626 }
05627 if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) {
05628 ast_cdr_init(chan->cdr, chan);
05629 }
05630 if (chan->cdr) {
05631 char tmp[256];
05632
05633 snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
05634 ast_cdr_setapp(chan->cdr, "Dial", tmp);
05635 ast_cdr_update(chan);
05636 ast_cdr_start(chan->cdr);
05637 ast_cdr_end(chan->cdr);
05638
05639 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) {
05640 ast_cdr_failed(chan->cdr);
05641 }
05642 }
05643 ast_channel_unlock(chan);
05644 ast_hangup(chan);
05645 chan = NULL;
05646 }
05647 return chan;
05648 }
05649
05650 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)
05651 {
05652 return __ast_request_and_dial(type, format, requestor, data, timeout, outstate, cidnum, cidname, NULL);
05653 }
05654
05655 static int set_security_requirements(const struct ast_channel *requestor, struct ast_channel *out)
05656 {
05657 int ops[2][2] = {
05658 {AST_OPTION_SECURE_SIGNALING, 0},
05659 {AST_OPTION_SECURE_MEDIA, 0},
05660 };
05661 int i;
05662 struct ast_channel *r = (struct ast_channel *) requestor;
05663 struct ast_datastore *ds;
05664
05665 if (!requestor || !out) {
05666 return 0;
05667 }
05668
05669 ast_channel_lock(r);
05670 if ((ds = ast_channel_datastore_find(r, &secure_call_info, NULL))) {
05671 struct ast_secure_call_store *encrypt = ds->data;
05672 ops[0][1] = encrypt->signaling;
05673 ops[1][1] = encrypt->media;
05674 } else {
05675 ast_channel_unlock(r);
05676 return 0;
05677 }
05678 ast_channel_unlock(r);
05679
05680 for (i = 0; i < 2; i++) {
05681 if (ops[i][1]) {
05682 if (ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0)) {
05683
05684 return -1;
05685 }
05686 } else {
05687
05688 ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0);
05689 }
05690 }
05691
05692 return 0;
05693 }
05694
05695 struct ast_channel *ast_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
05696 {
05697 struct chanlist *chan;
05698 struct ast_channel *c;
05699 format_t capabilities;
05700 format_t fmt;
05701 int res;
05702 int foo;
05703 format_t videoformat = format & AST_FORMAT_VIDEO_MASK;
05704 format_t textformat = format & AST_FORMAT_TEXT_MASK;
05705
05706 if (!cause)
05707 cause = &foo;
05708 *cause = AST_CAUSE_NOTDEFINED;
05709
05710 if (AST_RWLIST_RDLOCK(&backends)) {
05711 ast_log(LOG_WARNING, "Unable to lock technology backend list\n");
05712 return NULL;
05713 }
05714
05715 AST_RWLIST_TRAVERSE(&backends, chan, list) {
05716 if (strcasecmp(type, chan->tech->type))
05717 continue;
05718
05719 capabilities = chan->tech->capabilities;
05720 fmt = format & AST_FORMAT_AUDIO_MASK;
05721 if (fmt) {
05722
05723
05724
05725 res = ast_translator_best_choice(&fmt, &capabilities);
05726 if (res < 0) {
05727 char tmp1[256], tmp2[256];
05728 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type,
05729 ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities),
05730 ast_getformatname_multiple(tmp2, sizeof(tmp2), format));
05731 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05732 AST_RWLIST_UNLOCK(&backends);
05733 return NULL;
05734 }
05735 }
05736 AST_RWLIST_UNLOCK(&backends);
05737 if (!chan->tech->requester)
05738 return NULL;
05739
05740 if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, requestor, data, cause)))
05741 return NULL;
05742
05743 if (set_security_requirements(requestor, c)) {
05744 ast_log(LOG_WARNING, "Setting security requirements failed\n");
05745 c = ast_channel_release(c);
05746 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05747 return NULL;
05748 }
05749
05750
05751 return c;
05752 }
05753
05754 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
05755 *cause = AST_CAUSE_NOSUCHDRIVER;
05756 AST_RWLIST_UNLOCK(&backends);
05757
05758 return NULL;
05759 }
05760
05761 int ast_call(struct ast_channel *chan, char *addr, int timeout)
05762 {
05763
05764
05765
05766 int res = -1;
05767
05768 ast_channel_lock(chan);
05769 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
05770 if (chan->cdr) {
05771 ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED);
05772 }
05773 if (chan->tech->call)
05774 res = chan->tech->call(chan, addr, timeout);
05775 ast_set_flag(chan, AST_FLAG_OUTGOING);
05776 }
05777 ast_channel_unlock(chan);
05778 return res;
05779 }
05780
05781
05782
05783
05784
05785
05786
05787
05788 int ast_transfer(struct ast_channel *chan, char *dest)
05789 {
05790 int res = -1;
05791
05792
05793 ast_channel_lock(chan);
05794 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
05795 if (chan->tech->transfer) {
05796 res = chan->tech->transfer(chan, dest);
05797 if (!res)
05798 res = 1;
05799 } else
05800 res = 0;
05801 }
05802 ast_channel_unlock(chan);
05803
05804 if (res <= 0) {
05805 return res;
05806 }
05807
05808 for (;;) {
05809 struct ast_frame *fr;
05810
05811 res = ast_waitfor(chan, -1);
05812
05813 if (res < 0 || !(fr = ast_read(chan))) {
05814 res = -1;
05815 break;
05816 }
05817
05818 if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) {
05819 enum ast_control_transfer *message = fr->data.ptr;
05820
05821 if (*message == AST_TRANSFER_SUCCESS) {
05822 res = 1;
05823 } else {
05824 res = -1;
05825 }
05826
05827 ast_frfree(fr);
05828 break;
05829 }
05830
05831 ast_frfree(fr);
05832 }
05833
05834 return res;
05835 }
05836
05837 int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
05838 {
05839 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
05840 }
05841
05842 int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
05843 {
05844 int pos = 0;
05845 int to = ftimeout;
05846
05847 struct ast_silence_generator *silgen = NULL;
05848
05849
05850 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
05851 return -1;
05852 if (!len)
05853 return -1;
05854 for (;;) {
05855 int d;
05856 if (c->stream) {
05857 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
05858 ast_stopstream(c);
05859 if (!silgen && ast_opt_transmit_silence)
05860 silgen = ast_channel_start_silence_generator(c);
05861 usleep(1000);
05862 if (!d)
05863 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
05864 } else {
05865 if (!silgen && ast_opt_transmit_silence)
05866 silgen = ast_channel_start_silence_generator(c);
05867 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
05868 }
05869 if (d < 0) {
05870 ast_channel_stop_silence_generator(c, silgen);
05871 return AST_GETDATA_FAILED;
05872 }
05873 if (d == 0) {
05874 s[pos] = '\0';
05875 ast_channel_stop_silence_generator(c, silgen);
05876 return AST_GETDATA_TIMEOUT;
05877 }
05878 if (d == 1) {
05879 s[pos] = '\0';
05880 ast_channel_stop_silence_generator(c, silgen);
05881 return AST_GETDATA_INTERRUPTED;
05882 }
05883 if (strchr(enders, d) && (pos == 0)) {
05884 s[pos] = '\0';
05885 ast_channel_stop_silence_generator(c, silgen);
05886 return AST_GETDATA_EMPTY_END_TERMINATED;
05887 }
05888 if (!strchr(enders, d)) {
05889 s[pos++] = d;
05890 }
05891 if (strchr(enders, d) || (pos >= len)) {
05892 s[pos] = '\0';
05893 ast_channel_stop_silence_generator(c, silgen);
05894 return AST_GETDATA_COMPLETE;
05895 }
05896 to = timeout;
05897 }
05898
05899 return 0;
05900 }
05901
05902 int ast_channel_supports_html(struct ast_channel *chan)
05903 {
05904 return (chan->tech->send_html) ? 1 : 0;
05905 }
05906
05907 int ast_channel_sendhtml(struct ast_channel *chan, int subclass, const char *data, int datalen)
05908 {
05909 if (chan->tech->send_html)
05910 return chan->tech->send_html(chan, subclass, data, datalen);
05911 return -1;
05912 }
05913
05914 int ast_channel_sendurl(struct ast_channel *chan, const char *url)
05915 {
05916 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
05917 }
05918
05919
05920 static int ast_channel_make_compatible_helper(struct ast_channel *from, struct ast_channel *to)
05921 {
05922 format_t src, dst;
05923 int use_slin;
05924
05925
05926 if (from->tech->bridge && from->tech->bridge == to->tech->bridge &&
05927 !ast_channel_setoption(from, AST_OPTION_MAKE_COMPATIBLE, to, sizeof(struct ast_channel *), 0)) {
05928 return 0;
05929 }
05930
05931 if (from->readformat == to->writeformat && from->writeformat == to->readformat) {
05932
05933 return 0;
05934 }
05935
05936
05937 src = from->nativeformats;
05938 dst = to->nativeformats;
05939
05940
05941 if ((src & AST_FORMAT_AUDIO_MASK) == 0 || (dst & AST_FORMAT_AUDIO_MASK) == 0)
05942 return 0;
05943
05944 if (ast_translator_best_choice(&dst, &src) < 0) {
05945 ast_log(LOG_WARNING, "No path to translate from %s to %s\n", from->name, to->name);
05946 return -1;
05947 }
05948
05949
05950
05951
05952
05953
05954
05955 use_slin = (src == AST_FORMAT_SLINEAR || dst == AST_FORMAT_SLINEAR);
05956 if ((src != dst) && (ast_opt_generic_plc || ast_opt_transcode_via_slin) &&
05957 (ast_translate_path_steps(dst, src) != 1 || use_slin))
05958 dst = AST_FORMAT_SLINEAR;
05959 if (ast_set_read_format(from, dst) < 0) {
05960 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %s\n", from->name, ast_getformatname(dst));
05961 return -1;
05962 }
05963 if (ast_set_write_format(to, dst) < 0) {
05964 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %s\n", to->name, ast_getformatname(dst));
05965 return -1;
05966 }
05967 return 0;
05968 }
05969
05970 int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
05971 {
05972
05973 int rc = 0;
05974
05975
05976 rc = ast_channel_make_compatible_helper(chan, peer);
05977
05978 if (rc < 0)
05979 return rc;
05980
05981
05982 rc = ast_channel_make_compatible_helper(peer, chan);
05983
05984 return rc;
05985 }
05986
05987 static int __ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clonechan, struct ast_datastore *xfer_ds)
05988 {
05989 int res = -1;
05990 struct ast_channel *final_orig, *final_clone, *base;
05991
05992 for (;;) {
05993 final_orig = original;
05994 final_clone = clonechan;
05995
05996 ast_channel_lock_both(original, clonechan);
05997
05998 if (ast_test_flag(original, AST_FLAG_ZOMBIE)
05999 || ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
06000
06001 ast_log(LOG_WARNING,
06002 "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n",
06003 original->name, clonechan->name);
06004 ast_channel_unlock(clonechan);
06005 ast_channel_unlock(original);
06006 return -1;
06007 }
06008
06009
06010
06011
06012
06013
06014 if (original->_bridge
06015 && (original->_bridge != ast_bridged_channel(original))
06016 && (original->_bridge->_bridge != original)) {
06017 final_orig = original->_bridge;
06018 }
06019 if (clonechan->_bridge
06020 && (clonechan->_bridge != ast_bridged_channel(clonechan))
06021 && (clonechan->_bridge->_bridge != clonechan)) {
06022 final_clone = clonechan->_bridge;
06023 }
06024 if (final_clone->tech->get_base_channel
06025 && (base = final_clone->tech->get_base_channel(final_clone))) {
06026 final_clone = base;
06027 }
06028
06029 if ((final_orig != original) || (final_clone != clonechan)) {
06030
06031
06032
06033
06034
06035 if (ast_channel_trylock(final_orig)) {
06036 ast_channel_unlock(clonechan);
06037 ast_channel_unlock(original);
06038
06039
06040 continue;
06041 }
06042 if (ast_channel_trylock(final_clone)) {
06043 ast_channel_unlock(final_orig);
06044 ast_channel_unlock(clonechan);
06045 ast_channel_unlock(original);
06046
06047
06048 continue;
06049 }
06050 ast_channel_unlock(clonechan);
06051 ast_channel_unlock(original);
06052 original = final_orig;
06053 clonechan = final_clone;
06054
06055 if (ast_test_flag(original, AST_FLAG_ZOMBIE)
06056 || ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
06057
06058 ast_log(LOG_WARNING,
06059 "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n",
06060 original->name, clonechan->name);
06061 ast_channel_unlock(clonechan);
06062 ast_channel_unlock(original);
06063 return -1;
06064 }
06065 }
06066 break;
06067 }
06068
06069 if (original == clonechan) {
06070 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
06071 ast_channel_unlock(clonechan);
06072 ast_channel_unlock(original);
06073 return -1;
06074 }
06075
06076 ast_debug(1, "Planning to masquerade channel %s into the structure of %s\n",
06077 clonechan->name, original->name);
06078
06079 if (!original->masqr && !original->masq && !clonechan->masq && !clonechan->masqr) {
06080 original->masq = clonechan;
06081 clonechan->masqr = original;
06082 if (xfer_ds) {
06083 ast_channel_datastore_add(original, xfer_ds);
06084 }
06085 ast_queue_frame(original, &ast_null_frame);
06086 ast_queue_frame(clonechan, &ast_null_frame);
06087 ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", clonechan->name, original->name);
06088 res = 0;
06089 } else if (original->masq) {
06090 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
06091 original->masq->name, original->name);
06092 } else if (original->masqr) {
06093
06094 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
06095 original->name, original->masqr->name);
06096 } else if (clonechan->masq) {
06097 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
06098 clonechan->masq->name, clonechan->name);
06099 } else {
06100 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
06101 clonechan->name, clonechan->masqr->name);
06102 }
06103
06104 ast_channel_unlock(clonechan);
06105 ast_channel_unlock(original);
06106
06107 return res;
06108 }
06109
06110 int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
06111 {
06112 return __ast_channel_masquerade(original, clone, NULL);
06113 }
06114
06115
06116
06117
06118
06119
06120
06121
06122
06123
06124
06125 static void party_connected_line_copy_transfer(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
06126 {
06127 struct ast_party_connected_line connected;
06128
06129 connected = *((struct ast_party_connected_line *) src);
06130 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
06131
06132
06133 if (!connected.id.name.str) {
06134 connected.id.name.str = "";
06135 }
06136 if (!connected.id.number.str) {
06137 connected.id.number.str = "";
06138 }
06139 if (!connected.id.subaddress.str) {
06140 connected.id.subaddress.str = "";
06141 }
06142 if (!connected.id.tag) {
06143 connected.id.tag = "";
06144 }
06145
06146 ast_party_connected_line_copy(dest, &connected);
06147 }
06148
06149
06150 struct xfer_masquerade_ds {
06151
06152 struct ast_party_connected_line target_id;
06153
06154 struct ast_party_connected_line transferee_id;
06155
06156 int target_held;
06157
06158 int transferee_held;
06159 };
06160
06161
06162
06163
06164
06165
06166
06167
06168
06169
06170 static void xfer_ds_destroy(void *data)
06171 {
06172 struct xfer_masquerade_ds *ds = data;
06173
06174 ast_party_connected_line_free(&ds->target_id);
06175 ast_party_connected_line_free(&ds->transferee_id);
06176 ast_free(ds);
06177 }
06178
06179 static const struct ast_datastore_info xfer_ds_info = {
06180 .type = "xfer_colp",
06181 .destroy = xfer_ds_destroy,
06182 };
06183
06184 int ast_channel_transfer_masquerade(
06185 struct ast_channel *target_chan,
06186 const struct ast_party_connected_line *target_id,
06187 int target_held,
06188 struct ast_channel *transferee_chan,
06189 const struct ast_party_connected_line *transferee_id,
06190 int transferee_held)
06191 {
06192 struct ast_datastore *xfer_ds;
06193 struct xfer_masquerade_ds *xfer_colp;
06194 int res;
06195
06196 xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL);
06197 if (!xfer_ds) {
06198 return -1;
06199 }
06200
06201 xfer_colp = ast_calloc(1, sizeof(*xfer_colp));
06202 if (!xfer_colp) {
06203 ast_datastore_free(xfer_ds);
06204 return -1;
06205 }
06206 party_connected_line_copy_transfer(&xfer_colp->target_id, target_id);
06207 xfer_colp->target_held = target_held;
06208 party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id);
06209 xfer_colp->transferee_held = transferee_held;
06210 xfer_ds->data = xfer_colp;
06211
06212 res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds);
06213 if (res) {
06214 ast_datastore_free(xfer_ds);
06215 }
06216 return res;
06217 }
06218
06219
06220
06221
06222
06223 static void __ast_change_name_nolink(struct ast_channel *chan, const char *newname)
06224 {
06225 ast_manager_event(chan, EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
06226 ast_string_field_set(chan, name, newname);
06227 }
06228
06229 void ast_change_name(struct ast_channel *chan, const char *newname)
06230 {
06231
06232 ao2_lock(channels);
06233 ast_channel_lock(chan);
06234 ao2_unlink(channels, chan);
06235 __ast_change_name_nolink(chan, newname);
06236 ao2_link(channels, chan);
06237 ast_channel_unlock(chan);
06238 ao2_unlock(channels);
06239 }
06240
06241 void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
06242 {
06243 struct ast_var_t *current, *newvar;
06244 const char *varname;
06245
06246 AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
06247 int vartype = 0;
06248
06249 varname = ast_var_full_name(current);
06250 if (!varname)
06251 continue;
06252
06253 if (varname[0] == '_') {
06254 vartype = 1;
06255 if (varname[1] == '_')
06256 vartype = 2;
06257 }
06258
06259 switch (vartype) {
06260 case 1:
06261 newvar = ast_var_assign(&varname[1], ast_var_value(current));
06262 if (newvar) {
06263 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
06264 ast_debug(1, "Inheriting variable %s from %s to %s.\n",
06265 ast_var_name(newvar), parent->name, child->name);
06266 }
06267 break;
06268 case 2:
06269 newvar = ast_var_assign(varname, ast_var_value(current));
06270 if (newvar) {
06271 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
06272 ast_debug(1, "Inheriting variable %s from %s to %s.\n",
06273 ast_var_name(newvar), parent->name, child->name);
06274 }
06275 break;
06276 default:
06277 break;
06278 }
06279 }
06280 }
06281
06282
06283
06284
06285
06286
06287
06288
06289
06290
06291 static void clone_variables(struct ast_channel *original, struct ast_channel *clonechan)
06292 {
06293 struct ast_var_t *current, *newvar;
06294
06295
06296 AST_LIST_APPEND_LIST(&original->varshead, &clonechan->varshead, entries);
06297
06298
06299
06300 AST_LIST_TRAVERSE(&original->varshead, current, entries) {
06301 newvar = ast_var_assign(current->name, current->value);
06302 if (newvar)
06303 AST_LIST_INSERT_TAIL(&clonechan->varshead, newvar, entries);
06304 }
06305 }
06306
06307
06308
06309
06310
06311
06312
06313
06314
06315
06316
06317
06318
06319
06320 static const char *oldest_linkedid(const char *a, const char *b)
06321 {
06322 const char *satime, *saseq;
06323 const char *sbtime, *sbseq;
06324 const char *dash;
06325
06326 unsigned int atime, aseq, btime, bseq;
06327
06328 if (ast_strlen_zero(a))
06329 return b;
06330
06331 if (ast_strlen_zero(b))
06332 return a;
06333
06334 satime = a;
06335 sbtime = b;
06336
06337
06338 if ((dash = strrchr(satime, '-'))) {
06339 satime = dash+1;
06340 }
06341 if ((dash = strrchr(sbtime, '-'))) {
06342 sbtime = dash+1;
06343 }
06344
06345
06346 saseq = strchr(satime, '.');
06347 sbseq = strchr(sbtime, '.');
06348 if (!saseq || !sbseq)
06349 return NULL;
06350 saseq++;
06351 sbseq++;
06352
06353
06354 atime = atoi(satime);
06355 btime = atoi(sbtime);
06356 aseq = atoi(saseq);
06357 bseq = atoi(sbseq);
06358
06359
06360 if (atime == btime) {
06361 return (aseq < bseq) ? a : b;
06362 }
06363 else {
06364 return (atime < btime) ? a : b;
06365 }
06366 }
06367
06368
06369
06370 static void ast_channel_change_linkedid(struct ast_channel *chan, const char *linkedid)
06371 {
06372 ast_assert(linkedid != NULL);
06373
06374 if (!strcmp(chan->linkedid, linkedid)) {
06375 return;
06376 }
06377
06378 ast_cel_check_retire_linkedid(chan);
06379 ast_string_field_set(chan, linkedid, linkedid);
06380 ast_cel_linkedid_ref(linkedid);
06381 }
06382
06383
06384
06385
06386
06387 void ast_channel_set_linkgroup(struct ast_channel *chan, struct ast_channel *peer)
06388 {
06389 const char* linkedid=NULL;
06390 struct ast_channel *bridged;
06391
06392 linkedid = oldest_linkedid(chan->linkedid, peer->linkedid);
06393 linkedid = oldest_linkedid(linkedid, chan->uniqueid);
06394 linkedid = oldest_linkedid(linkedid, peer->uniqueid);
06395 if (chan->_bridge) {
06396 bridged = ast_bridged_channel(chan);
06397 if (bridged && bridged != peer) {
06398 linkedid = oldest_linkedid(linkedid, bridged->linkedid);
06399 linkedid = oldest_linkedid(linkedid, bridged->uniqueid);
06400 }
06401 }
06402 if (peer->_bridge) {
06403 bridged = ast_bridged_channel(peer);
06404 if (bridged && bridged != chan) {
06405 linkedid = oldest_linkedid(linkedid, bridged->linkedid);
06406 linkedid = oldest_linkedid(linkedid, bridged->uniqueid);
06407 }
06408 }
06409
06410
06411 linkedid = ast_strdupa(linkedid);
06412
06413 ast_channel_change_linkedid(chan, linkedid);
06414 ast_channel_change_linkedid(peer, linkedid);
06415 if (chan->_bridge) {
06416 bridged = ast_bridged_channel(chan);
06417 if (bridged && bridged != peer) {
06418 ast_channel_change_linkedid(bridged, linkedid);
06419 }
06420 }
06421 if (peer->_bridge) {
06422 bridged = ast_bridged_channel(peer);
06423 if (bridged && bridged != chan) {
06424 ast_channel_change_linkedid(bridged, linkedid);
06425 }
06426 }
06427 }
06428
06429
06430 static void ast_set_owners_and_peers(struct ast_channel *chan1,
06431 struct ast_channel *chan2)
06432 {
06433 if (!ast_strlen_zero(chan1->accountcode) && ast_strlen_zero(chan2->peeraccount)) {
06434 ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n",
06435 chan1->accountcode, chan2->name, chan1->name);
06436 ast_string_field_set(chan2, peeraccount, chan1->accountcode);
06437 }
06438 if (!ast_strlen_zero(chan2->accountcode) && ast_strlen_zero(chan1->peeraccount)) {
06439 ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n",
06440 chan2->accountcode, chan1->name, chan2->name);
06441 ast_string_field_set(chan1, peeraccount, chan2->accountcode);
06442 }
06443 if (!ast_strlen_zero(chan1->peeraccount) && ast_strlen_zero(chan2->accountcode)) {
06444 ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n",
06445 chan1->peeraccount, chan2->name, chan1->name);
06446 ast_string_field_set(chan2, accountcode, chan1->peeraccount);
06447 }
06448 if (!ast_strlen_zero(chan2->peeraccount) && ast_strlen_zero(chan1->accountcode)) {
06449 ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n",
06450 chan2->peeraccount, chan1->name, chan2->name);
06451 ast_string_field_set(chan1, accountcode, chan2->peeraccount);
06452 }
06453 if (0 != strcmp(chan1->accountcode, chan2->peeraccount)) {
06454 ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n",
06455 chan2->peeraccount, chan1->peeraccount, chan2->name, chan1->name);
06456 ast_string_field_set(chan2, peeraccount, chan1->accountcode);
06457 }
06458 if (0 != strcmp(chan2->accountcode, chan1->peeraccount)) {
06459 ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n",
06460 chan1->peeraccount, chan2->peeraccount, chan1->name, chan2->name);
06461 ast_string_field_set(chan1, peeraccount, chan2->accountcode);
06462 }
06463 }
06464
06465
06466
06467
06468 static void report_new_callerid(struct ast_channel *chan)
06469 {
06470 int pres;
06471
06472 pres = ast_party_id_presentation(&chan->caller.id);
06473 ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid",
06474 "Channel: %s\r\n"
06475 "CallerIDNum: %s\r\n"
06476 "CallerIDName: %s\r\n"
06477 "Uniqueid: %s\r\n"
06478 "CID-CallingPres: %d (%s)\r\n",
06479 chan->name,
06480 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
06481 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
06482 chan->uniqueid,
06483 pres,
06484 ast_describe_caller_presentation(pres)
06485 );
06486 }
06487
06488
06489
06490
06491
06492
06493
06494
06495
06496
06497
06498 static void masquerade_colp_transfer(struct ast_channel *transferee, struct xfer_masquerade_ds *colp)
06499 {
06500 struct ast_control_read_action_payload *frame_payload;
06501 int payload_size;
06502 int frame_size;
06503 unsigned char connected_line_data[1024];
06504
06505
06506 if (colp->target_held) {
06507 ast_queue_control(transferee, AST_CONTROL_UNHOLD);
06508 }
06509
06510
06511
06512
06513
06514
06515
06516
06517
06518
06519 payload_size = ast_connected_line_build_data(connected_line_data,
06520 sizeof(connected_line_data), &colp->target_id, NULL);
06521 if (payload_size != -1) {
06522 frame_size = payload_size + sizeof(*frame_payload);
06523 frame_payload = ast_alloca(frame_size);
06524 frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO;
06525 frame_payload->payload_size = payload_size;
06526 memcpy(frame_payload->payload, connected_line_data, payload_size);
06527 ast_queue_control_data(transferee, AST_CONTROL_READ_ACTION, frame_payload,
06528 frame_size);
06529 }
06530
06531
06532
06533
06534
06535
06536 ast_channel_queue_connected_line_update(transferee, &colp->transferee_id, NULL);
06537 }
06538
06539
06540
06541
06542
06543
06544
06545
06546 int ast_do_masquerade(struct ast_channel *original)
06547 {
06548 int x;
06549 int i;
06550 int origstate;
06551 unsigned int orig_disablestatecache;
06552 unsigned int clone_disablestatecache;
06553 int visible_indication;
06554 int moh_is_playing;
06555 int clone_was_zombie = 0;
06556 struct ast_frame *current;
06557 const struct ast_channel_tech *t;
06558 void *t_pvt;
06559 union {
06560 struct ast_party_dialed dialed;
06561 struct ast_party_caller caller;
06562 struct ast_party_connected_line connected;
06563 struct ast_party_redirecting redirecting;
06564 } exchange;
06565 struct ast_channel *clonechan, *chans[2];
06566 struct ast_channel *bridged;
06567 struct ast_cdr *cdr;
06568 struct ast_datastore *xfer_ds;
06569 struct xfer_masquerade_ds *xfer_colp;
06570 format_t rformat;
06571 format_t wformat;
06572 format_t tmp_format;
06573 char newn[AST_CHANNEL_NAME];
06574 char orig[AST_CHANNEL_NAME];
06575 char masqn[AST_CHANNEL_NAME];
06576 char zombn[AST_CHANNEL_NAME];
06577 char clone_sending_dtmf_digit;
06578 struct timeval clone_sending_dtmf_tv;
06579
06580
06581
06582
06583
06584
06585
06586
06587
06588
06589
06590
06591
06592
06593
06594
06595
06596
06597
06598
06599
06600
06601
06602
06603
06604
06605
06606
06607
06608
06609
06610
06611
06612 ao2_lock(channels);
06613
06614
06615
06616
06617
06618 ast_channel_lock(original);
06619
06620 clonechan = original->masq;
06621 if (!clonechan) {
06622
06623
06624
06625
06626 ast_channel_unlock(original);
06627 ao2_unlock(channels);
06628 return 0;
06629 }
06630
06631
06632 ast_channel_ref(original);
06633 ast_channel_ref(clonechan);
06634
06635
06636 ao2_unlink(channels, original);
06637 ao2_unlink(channels, clonechan);
06638
06639
06640 xfer_ds = ast_channel_datastore_find(original, &xfer_ds_info, NULL);
06641 if (xfer_ds) {
06642 ast_channel_datastore_remove(original, xfer_ds);
06643 xfer_colp = xfer_ds->data;
06644 } else {
06645 xfer_colp = NULL;
06646 }
06647
06648 moh_is_playing = ast_test_flag(original, AST_FLAG_MOH);
06649
06650
06651
06652
06653
06654 visible_indication = original->visible_indication;
06655 ast_channel_unlock(original);
06656 ast_indicate(original, -1);
06657
06658
06659
06660
06661
06662 if (xfer_colp && xfer_colp->transferee_held) {
06663 ast_indicate(clonechan, AST_CONTROL_UNHOLD);
06664 }
06665
06666
06667 ast_channel_lock_both(original, clonechan);
06668
06669 ast_debug(4, "Actually Masquerading %s(%u) into the structure of %s(%u)\n",
06670 clonechan->name, clonechan->_state, original->name, original->_state);
06671
06672 chans[0] = clonechan;
06673 chans[1] = original;
06674 ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans,
06675 "Clone: %s\r\n"
06676 "CloneState: %s\r\n"
06677 "Original: %s\r\n"
06678 "OriginalState: %s\r\n",
06679 clonechan->name, ast_state2str(clonechan->_state), original->name, ast_state2str(original->_state));
06680
06681
06682
06683
06684
06685 rformat = original->readformat;
06686 wformat = original->writeformat;
06687 free_translation(clonechan);
06688 free_translation(original);
06689
06690
06691 clone_sending_dtmf_digit = clonechan->sending_dtmf_digit;
06692 clone_sending_dtmf_tv = clonechan->sending_dtmf_tv;
06693
06694
06695 ast_copy_string(orig, original->name, sizeof(orig));
06696
06697 ast_copy_string(newn, clonechan->name, sizeof(newn));
06698
06699 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
06700
06701
06702 __ast_change_name_nolink(clonechan, masqn);
06703
06704
06705 __ast_change_name_nolink(original, newn);
06706
06707
06708 ast_channel_set_linkgroup(original, clonechan);
06709
06710
06711 t = original->tech;
06712 original->tech = clonechan->tech;
06713 clonechan->tech = t;
06714
06715 t_pvt = original->tech_pvt;
06716 original->tech_pvt = clonechan->tech_pvt;
06717 clonechan->tech_pvt = t_pvt;
06718
06719
06720 cdr = original->cdr;
06721
06722 ast_copy_string(clonechan->cdr->uniqueid, cdr->uniqueid, sizeof(cdr->uniqueid));
06723 original->cdr = clonechan->cdr;
06724 clonechan->cdr = cdr;
06725
06726
06727 for (i = 0; i < 2; i++) {
06728 x = original->alertpipe[i];
06729 original->alertpipe[i] = clonechan->alertpipe[i];
06730 clonechan->alertpipe[i] = x;
06731 }
06732
06733
06734
06735
06736
06737
06738
06739
06740
06741
06742
06743
06744 {
06745 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
06746
06747 AST_LIST_HEAD_INIT_NOLOCK(&tmp_readq);
06748 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
06749 AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list);
06750
06751 while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
06752 AST_LIST_INSERT_TAIL(&original->readq, current, frame_list);
06753 if (original->alertpipe[1] > -1) {
06754 int poke = 0;
06755
06756 if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) {
06757 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
06758 }
06759 }
06760 }
06761 }
06762
06763
06764 tmp_format = original->rawreadformat;
06765 original->rawreadformat = clonechan->rawreadformat;
06766 clonechan->rawreadformat = tmp_format;
06767
06768 tmp_format = original->rawwriteformat;
06769 original->rawwriteformat = clonechan->rawwriteformat;
06770 clonechan->rawwriteformat = tmp_format;
06771
06772 clonechan->_softhangup = AST_SOFTHANGUP_DEV;
06773
06774
06775
06776
06777
06778 origstate = original->_state;
06779 original->_state = clonechan->_state;
06780 clonechan->_state = origstate;
06781
06782
06783
06784 orig_disablestatecache = ast_test_flag(original, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06785 clone_disablestatecache = ast_test_flag(clonechan, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06786 if (orig_disablestatecache != clone_disablestatecache) {
06787 if (orig_disablestatecache) {
06788 ast_clear_flag(original, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06789 ast_set_flag(clonechan, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06790 } else {
06791 ast_set_flag(original, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06792 ast_clear_flag(clonechan, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06793 }
06794 }
06795
06796
06797 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
06798 __ast_change_name_nolink(clonechan, zombn);
06799
06800
06801 t_pvt = original->monitor;
06802 original->monitor = clonechan->monitor;
06803 clonechan->monitor = t_pvt;
06804
06805
06806 ast_string_field_set(original, language, clonechan->language);
06807
06808
06809 ast_string_field_set(original, parkinglot, clonechan->parkinglot);
06810
06811
06812 for (x = 0; x < AST_MAX_FDS; x++) {
06813 if (x != AST_GENERATOR_FD)
06814 ast_channel_set_fd(original, x, clonechan->fds[x]);
06815 }
06816
06817 ast_app_group_update(clonechan, original);
06818
06819
06820 if (AST_LIST_FIRST(&clonechan->datastores)) {
06821 struct ast_datastore *ds;
06822
06823
06824
06825 AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) {
06826 if (ds->info->chan_fixup)
06827 ds->info->chan_fixup(ds->data, clonechan, original);
06828 }
06829 AST_LIST_TRAVERSE_SAFE_END;
06830 AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry);
06831 }
06832
06833 ast_autochan_new_channel(clonechan, original);
06834
06835 clone_variables(original, clonechan);
06836
06837 original->adsicpe = clonechan->adsicpe;
06838
06839
06840
06841
06842
06843 ast_set_flag(original, ast_test_flag(clonechan, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING));
06844 original->fdno = clonechan->fdno;
06845
06846
06847
06848
06849
06850
06851
06852
06853 exchange.dialed = original->dialed;
06854 original->dialed = clonechan->dialed;
06855 clonechan->dialed = exchange.dialed;
06856
06857 exchange.caller = original->caller;
06858 original->caller = clonechan->caller;
06859 clonechan->caller = exchange.caller;
06860
06861 exchange.connected = original->connected;
06862 original->connected = clonechan->connected;
06863 clonechan->connected = exchange.connected;
06864
06865 exchange.redirecting = original->redirecting;
06866 original->redirecting = clonechan->redirecting;
06867 clonechan->redirecting = exchange.redirecting;
06868
06869 report_new_callerid(original);
06870
06871
06872 ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd);
06873
06874
06875 original->nativeformats = clonechan->nativeformats;
06876
06877
06878
06879
06880
06881 ast_set_write_format(original, wformat);
06882
06883
06884 ast_set_read_format(original, rformat);
06885
06886
06887 ast_string_field_set(original, musicclass, clonechan->musicclass);
06888
06889
06890 original->whentohangup = clonechan->whentohangup;
06891
06892
06893 ast_string_field_set(original, accountcode, S_OR(clonechan->accountcode, ""));
06894 if (original->_bridge) {
06895
06896 ast_string_field_set(original->_bridge, peeraccount, S_OR(clonechan->accountcode, ""));
06897 ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL);
06898 }
06899
06900 ast_debug(1, "Putting channel %s in %s/%s formats\n", original->name,
06901 ast_getformatname(wformat), ast_getformatname(rformat));
06902
06903
06904 if (original->tech->fixup && original->tech->fixup(clonechan, original)) {
06905 ast_log(LOG_WARNING, "Channel type '%s' could not fixup channel %s, strange things may happen. (clonechan)\n",
06906 original->tech->type, original->name);
06907 }
06908
06909
06910 if (clonechan->tech->fixup && clonechan->tech->fixup(original, clonechan)) {
06911 ast_log(LOG_WARNING, "Channel type '%s' could not fixup channel %s, strange things may happen. (original)\n",
06912 clonechan->tech->type, clonechan->name);
06913 }
06914
06915
06916
06917
06918
06919
06920
06921
06922
06923
06924 if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
06925 clone_was_zombie = 1;
06926 } else {
06927 ast_set_flag(clonechan, AST_FLAG_ZOMBIE);
06928 ast_queue_frame(clonechan, &ast_null_frame);
06929 }
06930
06931
06932 original->masq = NULL;
06933 clonechan->masqr = NULL;
06934
06935
06936
06937
06938
06939
06940
06941 ast_channel_unlock(original);
06942
06943
06944 if (clonechan->tech->hangup && clonechan->tech->hangup(clonechan)) {
06945 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n");
06946 } else {
06947
06948
06949
06950
06951
06952 clonechan->tech = &ast_kill_tech;
06953 }
06954
06955 ast_channel_unlock(clonechan);
06956
06957 if (clone_sending_dtmf_digit) {
06958
06959
06960
06961
06962 ast_bridge_end_dtmf(original, clone_sending_dtmf_digit, clone_sending_dtmf_tv,
06963 "masquerade");
06964 }
06965
06966
06967
06968
06969
06970
06971
06972
06973
06974
06975 if (visible_indication) {
06976 ast_indicate(original, visible_indication);
06977 }
06978
06979
06980
06981 if (moh_is_playing) {
06982 ast_moh_start(original, NULL, NULL);
06983 }
06984
06985 ast_channel_lock(original);
06986
06987
06988 if (ast_test_flag(original, AST_FLAG_BLOCKING)) {
06989 pthread_kill(original->blocker, SIGURG);
06990 }
06991
06992 ast_debug(1, "Done Masquerading %s (%u)\n", original->name, original->_state);
06993
06994 if ((bridged = ast_bridged_channel(original))) {
06995 ast_channel_ref(bridged);
06996 ast_channel_unlock(original);
06997 ast_indicate(bridged, AST_CONTROL_SRCCHANGE);
06998 ast_channel_unref(bridged);
06999 } else {
07000 ast_channel_unlock(original);
07001 }
07002 ast_indicate(original, AST_CONTROL_SRCCHANGE);
07003
07004 if (xfer_colp) {
07005
07006
07007
07008
07009
07010 masquerade_colp_transfer(original, xfer_colp);
07011 }
07012
07013 if (xfer_ds) {
07014 ast_datastore_free(xfer_ds);
07015 }
07016
07017 if (clone_was_zombie) {
07018 ast_channel_lock(clonechan);
07019 ast_debug(1, "Destroying channel clone '%s'\n", clonechan->name);
07020 ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup",
07021 "Channel: %s\r\n"
07022 "Uniqueid: %s\r\n"
07023 "Cause: %d\r\n"
07024 "Cause-txt: %s\r\n",
07025 clonechan->name,
07026 clonechan->uniqueid,
07027 clonechan->hangupcause,
07028 ast_cause2str(clonechan->hangupcause)
07029 );
07030 ast_channel_unlock(clonechan);
07031
07032
07033
07034
07035
07036 ast_channel_unref(clonechan);
07037 } else {
07038 ao2_link(channels, clonechan);
07039 }
07040
07041 ao2_link(channels, original);
07042 ao2_unlock(channels);
07043
07044
07045 ast_channel_unref(original);
07046 ast_channel_unref(clonechan);
07047
07048 return 0;
07049 }
07050
07051 void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
07052 {
07053 ast_channel_lock(chan);
07054
07055 if (cid_num) {
07056 chan->caller.id.number.valid = 1;
07057 ast_free(chan->caller.id.number.str);
07058 chan->caller.id.number.str = ast_strdup(cid_num);
07059 }
07060 if (cid_name) {
07061 chan->caller.id.name.valid = 1;
07062 ast_free(chan->caller.id.name.str);
07063 chan->caller.id.name.str = ast_strdup(cid_name);
07064 }
07065 if (cid_ani) {
07066 chan->caller.ani.number.valid = 1;
07067 ast_free(chan->caller.ani.number.str);
07068 chan->caller.ani.number.str = ast_strdup(cid_ani);
07069 }
07070 if (chan->cdr) {
07071 ast_cdr_setcid(chan->cdr, chan);
07072 }
07073
07074 report_new_callerid(chan);
07075
07076 ast_channel_unlock(chan);
07077 }
07078
07079 void ast_channel_set_caller(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
07080 {
07081 if (&chan->caller == caller) {
07082
07083 return;
07084 }
07085
07086 ast_channel_lock(chan);
07087 ast_party_caller_set(&chan->caller, caller, update);
07088 ast_channel_unlock(chan);
07089 }
07090
07091 void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
07092 {
07093 const char *pre_set_number;
07094 const char *pre_set_name;
07095
07096 if (&chan->caller == caller) {
07097
07098 return;
07099 }
07100
07101 ast_channel_lock(chan);
07102 pre_set_number =
07103 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL);
07104 pre_set_name = S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL);
07105 ast_party_caller_set(&chan->caller, caller, update);
07106 if (S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)
07107 != pre_set_number
07108 || S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)
07109 != pre_set_name) {
07110
07111 report_new_callerid(chan);
07112 }
07113 if (chan->cdr) {
07114 ast_cdr_setcid(chan->cdr, chan);
07115 }
07116 ast_channel_unlock(chan);
07117 }
07118
07119 int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
07120 {
07121 int oldstate = chan->_state;
07122 char name[AST_CHANNEL_NAME], *dashptr;
07123
07124 if (oldstate == state)
07125 return 0;
07126
07127 ast_copy_string(name, chan->name, sizeof(name));
07128 if ((dashptr = strrchr(name, '-'))) {
07129 *dashptr = '\0';
07130 }
07131
07132 chan->_state = state;
07133
07134
07135
07136
07137 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, (chan->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), name);
07138
07139
07140 ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate",
07141 "Channel: %s\r\n"
07142 "ChannelState: %u\r\n"
07143 "ChannelStateDesc: %s\r\n"
07144 "CallerIDNum: %s\r\n"
07145 "CallerIDName: %s\r\n"
07146 "ConnectedLineNum: %s\r\n"
07147 "ConnectedLineName: %s\r\n"
07148 "Uniqueid: %s\r\n",
07149 chan->name, chan->_state, ast_state2str(chan->_state),
07150 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
07151 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
07152 S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, ""),
07153 S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, ""),
07154 chan->uniqueid);
07155
07156 return 0;
07157 }
07158
07159
07160 struct ast_channel *ast_bridged_channel(struct ast_channel *chan)
07161 {
07162 struct ast_channel *bridged;
07163 bridged = chan->_bridge;
07164 if (bridged && bridged->tech->bridged_channel)
07165 bridged = bridged->tech->bridged_channel(chan, bridged);
07166 return bridged;
07167 }
07168
07169 static void bridge_playfile(struct ast_channel *chan, struct ast_channel *peer, const char *sound, int remain)
07170 {
07171 int min = 0, sec = 0, check;
07172
07173 check = ast_autoservice_start(peer);
07174 if (check)
07175 return;
07176
07177 if (remain > 0) {
07178 if (remain / 60 > 1) {
07179 min = remain / 60;
07180 sec = remain % 60;
07181 } else {
07182 sec = remain;
07183 }
07184 }
07185
07186 if (!strcmp(sound,"timeleft")) {
07187 ast_stream_and_wait(chan, "vm-youhave", "");
07188 if (min) {
07189 ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL);
07190 ast_stream_and_wait(chan, "queue-minutes", "");
07191 }
07192 if (sec) {
07193 ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL);
07194 ast_stream_and_wait(chan, "queue-seconds", "");
07195 }
07196 } else {
07197 ast_stream_and_wait(chan, sound, "");
07198 }
07199
07200 ast_autoservice_stop(peer);
07201 }
07202
07203 static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct ast_channel *c1,
07204 struct ast_bridge_config *config, struct ast_frame **fo,
07205 struct ast_channel **rc)
07206 {
07207
07208 struct ast_channel *cs[3];
07209 struct ast_frame *f;
07210 enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
07211 format_t o0nativeformats;
07212 format_t o1nativeformats;
07213 int watch_c0_dtmf;
07214 int watch_c1_dtmf;
07215 void *pvt0, *pvt1;
07216
07217 int frame_put_in_jb = 0;
07218 int jb_in_use;
07219 int to;
07220
07221 cs[0] = c0;
07222 cs[1] = c1;
07223 pvt0 = c0->tech_pvt;
07224 pvt1 = c1->tech_pvt;
07225 o0nativeformats = c0->nativeformats;
07226 o1nativeformats = c1->nativeformats;
07227 watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
07228 watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
07229
07230
07231 jb_in_use = ast_jb_do_usecheck(c0, c1);
07232 if (jb_in_use)
07233 ast_jb_empty_and_reset(c0, c1);
07234
07235 ast_poll_channel_add(c0, c1);
07236
07237 if (config->feature_timer > 0 && ast_tvzero(config->nexteventts)) {
07238
07239
07240
07241 config->nexteventts = ast_tvadd(ast_tvnow(), ast_samp2tv(config->feature_timer, 1000));
07242 }
07243
07244 for (;;) {
07245 struct ast_channel *who, *other;
07246
07247 if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
07248 (o0nativeformats != c0->nativeformats) ||
07249 (o1nativeformats != c1->nativeformats)) {
07250
07251 res = AST_BRIDGE_RETRY;
07252 break;
07253 }
07254 if (config->nexteventts.tv_sec) {
07255 to = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
07256 if (to <= 0) {
07257 if (config->timelimit && !config->feature_timer && !ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
07258 res = AST_BRIDGE_RETRY;
07259
07260 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
07261 } else if (config->feature_timer) {
07262
07263 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
07264 res = AST_BRIDGE_RETRY;
07265 } else {
07266 res = AST_BRIDGE_COMPLETE;
07267 }
07268 break;
07269 }
07270 } else {
07271
07272
07273
07274
07275 if (!ast_tvzero(config->nexteventts)) {
07276 int diff = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
07277 if (diff <= 0) {
07278 res = AST_BRIDGE_RETRY;
07279 break;
07280 }
07281 }
07282 to = -1;
07283 }
07284
07285
07286 if (jb_in_use)
07287 to = ast_jb_get_when_to_wakeup(c0, c1, to);
07288 who = ast_waitfor_n(cs, 2, &to);
07289 if (!who) {
07290
07291 if (jb_in_use)
07292 ast_jb_get_and_deliver(c0, c1);
07293 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {
07294 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07295 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
07296 }
07297 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07298 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
07299 }
07300 ast_channel_lock_both(c0, c1);
07301 c0->_bridge = c1;
07302 c1->_bridge = c0;
07303 ast_channel_unlock(c0);
07304 ast_channel_unlock(c1);
07305 }
07306 continue;
07307 }
07308 f = ast_read(who);
07309 if (!f) {
07310 *fo = NULL;
07311 *rc = who;
07312 ast_debug(1, "Didn't get a frame from channel: %s\n",who->name);
07313 break;
07314 }
07315
07316 other = (who == c0) ? c1 : c0;
07317
07318 if (jb_in_use)
07319 frame_put_in_jb = !ast_jb_put(other, f);
07320
07321 if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
07322 int bridge_exit = 0;
07323
07324 switch (f->subclass.integer) {
07325 case AST_CONTROL_AOC:
07326 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07327 break;
07328 case AST_CONTROL_REDIRECTING:
07329 if (ast_channel_redirecting_macro(who, other, f, other == c0, 1)) {
07330 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07331 }
07332 break;
07333 case AST_CONTROL_CONNECTED_LINE:
07334 if (ast_channel_connected_line_macro(who, other, f, other == c0, 1)) {
07335 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07336 }
07337 break;
07338 case AST_CONTROL_HOLD:
07339 case AST_CONTROL_UNHOLD:
07340 case AST_CONTROL_VIDUPDATE:
07341 case AST_CONTROL_SRCUPDATE:
07342 case AST_CONTROL_SRCCHANGE:
07343 case AST_CONTROL_T38_PARAMETERS:
07344 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07345 if (jb_in_use) {
07346 ast_jb_empty_and_reset(c0, c1);
07347 }
07348 break;
07349 default:
07350 *fo = f;
07351 *rc = who;
07352 bridge_exit = 1;
07353 ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass.integer, who->name);
07354 break;
07355 }
07356 if (bridge_exit)
07357 break;
07358 }
07359 if ((f->frametype == AST_FRAME_VOICE) ||
07360 (f->frametype == AST_FRAME_DTMF_BEGIN) ||
07361 (f->frametype == AST_FRAME_DTMF) ||
07362 (f->frametype == AST_FRAME_VIDEO) ||
07363 (f->frametype == AST_FRAME_IMAGE) ||
07364 (f->frametype == AST_FRAME_HTML) ||
07365 (f->frametype == AST_FRAME_MODEM) ||
07366 (f->frametype == AST_FRAME_TEXT)) {
07367
07368 int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
07369
07370 if (monitored_source &&
07371 (f->frametype == AST_FRAME_DTMF_END ||
07372 f->frametype == AST_FRAME_DTMF_BEGIN)) {
07373 *fo = f;
07374 *rc = who;
07375 ast_debug(1, "Got DTMF %s on channel (%s)\n",
07376 f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
07377 who->name);
07378
07379 break;
07380 }
07381
07382 if (!frame_put_in_jb)
07383 ast_write(other, f);
07384
07385
07386 if (jb_in_use)
07387 ast_jb_get_and_deliver(c0, c1);
07388 }
07389
07390 ast_frfree(f);
07391
07392 #ifndef HAVE_EPOLL
07393
07394 cs[2] = cs[0];
07395 cs[0] = cs[1];
07396 cs[1] = cs[2];
07397 #endif
07398 }
07399
07400 ast_poll_channel_del(c0, c1);
07401
07402 return res;
07403 }
07404
07405
07406 int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
07407 {
07408
07409 if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge)))
07410 return -1;
07411
07412 return c0->tech->early_bridge(c0, c1);
07413 }
07414
07415
07416
07417
07418
07419
07420
07421 static void manager_bridge_event(int onoff, int type, struct ast_channel *c0, struct ast_channel *c1)
07422 {
07423 struct ast_channel *chans[2] = { c0, c1 };
07424 ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans,
07425 "Bridgestate: %s\r\n"
07426 "Bridgetype: %s\r\n"
07427 "Channel1: %s\r\n"
07428 "Channel2: %s\r\n"
07429 "Uniqueid1: %s\r\n"
07430 "Uniqueid2: %s\r\n"
07431 "CallerID1: %s\r\n"
07432 "CallerID2: %s\r\n",
07433 onoff ? "Link" : "Unlink",
07434 type == 1 ? "core" : "native",
07435 c0->name, c1->name,
07436 c0->uniqueid, c1->uniqueid,
07437 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, ""),
07438 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, ""));
07439 }
07440
07441 static void update_bridge_vars(struct ast_channel *c0, struct ast_channel *c1)
07442 {
07443 const char *c0_name;
07444 const char *c1_name;
07445 const char *c0_pvtid = NULL;
07446 const char *c1_pvtid = NULL;
07447
07448 ast_channel_lock(c1);
07449 c1_name = ast_strdupa(c1->name);
07450 if (c1->tech->get_pvt_uniqueid) {
07451 c1_pvtid = ast_strdupa(c1->tech->get_pvt_uniqueid(c1));
07452 }
07453 ast_channel_unlock(c1);
07454
07455 ast_channel_lock(c0);
07456 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) {
07457 pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name);
07458 }
07459 if (c1_pvtid) {
07460 pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1_pvtid);
07461 }
07462 c0_name = ast_strdupa(c0->name);
07463 if (c0->tech->get_pvt_uniqueid) {
07464 c0_pvtid = ast_strdupa(c0->tech->get_pvt_uniqueid(c0));
07465 }
07466 ast_channel_unlock(c0);
07467
07468 ast_channel_lock(c1);
07469 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) {
07470 pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name);
07471 }
07472 if (c0_pvtid) {
07473 pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0_pvtid);
07474 }
07475 ast_channel_unlock(c1);
07476 }
07477
07478 static void bridge_play_sounds(struct ast_channel *c0, struct ast_channel *c1)
07479 {
07480 const char *s, *sound;
07481
07482
07483
07484 ast_channel_lock(c0);
07485 if ((s = pbx_builtin_getvar_helper(c0, "BRIDGE_PLAY_SOUND"))) {
07486 sound = ast_strdupa(s);
07487 ast_channel_unlock(c0);
07488 bridge_playfile(c0, c1, sound, 0);
07489 pbx_builtin_setvar_helper(c0, "BRIDGE_PLAY_SOUND", NULL);
07490 } else {
07491 ast_channel_unlock(c0);
07492 }
07493
07494 ast_channel_lock(c1);
07495 if ((s = pbx_builtin_getvar_helper(c1, "BRIDGE_PLAY_SOUND"))) {
07496 sound = ast_strdupa(s);
07497 ast_channel_unlock(c1);
07498 bridge_playfile(c1, c0, sound, 0);
07499 pbx_builtin_setvar_helper(c1, "BRIDGE_PLAY_SOUND", NULL);
07500 } else {
07501 ast_channel_unlock(c1);
07502 }
07503 }
07504
07505
07506 enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1,
07507 struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
07508 {
07509 struct ast_channel *chans[2] = { c0, c1 };
07510 enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
07511 format_t o0nativeformats;
07512 format_t o1nativeformats;
07513 long time_left_ms=0;
07514 char caller_warning = 0;
07515 char callee_warning = 0;
07516
07517 *fo = NULL;
07518
07519 if (c0->_bridge) {
07520 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07521 c0->name, c0->_bridge->name);
07522 return -1;
07523 }
07524 if (c1->_bridge) {
07525 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07526 c1->name, c1->_bridge->name);
07527 return -1;
07528 }
07529
07530
07531 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07532 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
07533 return -1;
07534
07535 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
07536 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
07537
07538 if (ast_tvzero(config->start_time)) {
07539 config->start_time = ast_tvnow();
07540 if (config->start_sound) {
07541 if (caller_warning) {
07542 bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000);
07543 }
07544 if (callee_warning) {
07545 bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000);
07546 }
07547 }
07548 }
07549
07550
07551 ast_channel_lock_both(c0, c1);
07552 c0->_bridge = c1;
07553 c1->_bridge = c0;
07554 ast_channel_unlock(c0);
07555 ast_channel_unlock(c1);
07556
07557 ast_set_owners_and_peers(c0, c1);
07558
07559 o0nativeformats = c0->nativeformats;
07560 o1nativeformats = c1->nativeformats;
07561
07562 if (config->feature_timer && !ast_tvzero(config->nexteventts)) {
07563 config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000));
07564 } else if (config->timelimit) {
07565 time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time);
07566 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07567 if ((caller_warning || callee_warning) && config->play_warning) {
07568 long next_warn = config->play_warning;
07569 if (time_left_ms < config->play_warning && config->warning_freq > 0) {
07570
07571 long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq;
07572
07573
07574 next_warn = config->play_warning - warns_passed * config->warning_freq;
07575 }
07576 config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000));
07577 }
07578 } else {
07579 config->nexteventts.tv_sec = 0;
07580 config->nexteventts.tv_usec = 0;
07581 }
07582
07583 if (!c0->tech->send_digit_begin)
07584 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
07585 if (!c1->tech->send_digit_begin)
07586 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
07587 manager_bridge_event(1, 1, c0, c1);
07588
07589
07590 ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07591 ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07592
07593 for (;;) {
07594 struct timeval now = { 0, };
07595 int to;
07596
07597 to = -1;
07598
07599 if (!ast_tvzero(config->nexteventts)) {
07600 now = ast_tvnow();
07601 to = ast_tvdiff_ms(config->nexteventts, now);
07602 if (to <= 0) {
07603 if (!config->timelimit) {
07604 res = AST_BRIDGE_COMPLETE;
07605 break;
07606 }
07607 to = 0;
07608 }
07609 }
07610
07611 if (config->timelimit) {
07612 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
07613 if (time_left_ms < 0) {
07614 time_left_ms = 0;
07615 }
07616
07617 if (time_left_ms < to) {
07618 to = time_left_ms;
07619 }
07620
07621 if (time_left_ms <= 0) {
07622 if (caller_warning && config->end_sound)
07623 bridge_playfile(c0, c1, config->end_sound, 0);
07624 if (callee_warning && config->end_sound)
07625 bridge_playfile(c1, c0, config->end_sound, 0);
07626 *fo = NULL;
07627 res = AST_BRIDGE_COMPLETE;
07628 ast_test_suite_event_notify("BRIDGE_TIMELIMIT", "Channel1: %s\r\nChannel2: %s", c0->name, c1->name);
07629 break;
07630 }
07631
07632 if (!to) {
07633 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
07634 int t = (time_left_ms + 500) / 1000;
07635 if (caller_warning)
07636 bridge_playfile(c0, c1, config->warning_sound, t);
07637 if (callee_warning)
07638 bridge_playfile(c1, c0, config->warning_sound, t);
07639 }
07640
07641 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) {
07642 config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000));
07643 } else {
07644 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07645 }
07646 }
07647 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
07648 }
07649
07650 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {
07651 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07652 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
07653 }
07654 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07655 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
07656 }
07657 ast_channel_lock_both(c0, c1);
07658 c0->_bridge = c1;
07659 c1->_bridge = c0;
07660 ast_channel_unlock(c0);
07661 ast_channel_unlock(c1);
07662 ast_debug(1, "Unbridge signal received. Ending native bridge.\n");
07663 continue;
07664 }
07665
07666
07667 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07668 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
07669 *fo = NULL;
07670 res = AST_BRIDGE_COMPLETE;
07671 ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
07672 c0->name, c1->name,
07673 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
07674 ast_check_hangup(c0) ? "Yes" : "No",
07675 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
07676 ast_check_hangup(c1) ? "Yes" : "No");
07677 break;
07678 }
07679
07680 update_bridge_vars(c0, c1);
07681
07682 bridge_play_sounds(c0, c1);
07683
07684 if (c0->tech->bridge &&
07685
07686 (!config->timelimit || to > 1000 || to == -1) &&
07687 (c0->tech->bridge == c1->tech->bridge) &&
07688 !c0->monitor && !c1->monitor &&
07689 !c0->audiohooks && !c1->audiohooks &&
07690 ast_framehook_list_is_empty(c0->framehooks) && ast_framehook_list_is_empty(c1->framehooks) &&
07691 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
07692 int timeoutms = to - 1000 > 0 ? to - 1000 : to;
07693
07694 ast_set_flag(c0, AST_FLAG_NBRIDGE);
07695 ast_set_flag(c1, AST_FLAG_NBRIDGE);
07696 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) {
07697 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
07698 "Channel1: %s\r\n"
07699 "Channel2: %s\r\n"
07700 "Uniqueid1: %s\r\n"
07701 "Uniqueid2: %s\r\n"
07702 "CallerID1: %s\r\n"
07703 "CallerID2: %s\r\n",
07704 c0->name, c1->name,
07705 c0->uniqueid, c1->uniqueid,
07706 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"),
07707 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
07708
07709 ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
07710
07711 ast_clear_flag(c0, AST_FLAG_NBRIDGE);
07712 ast_clear_flag(c1, AST_FLAG_NBRIDGE);
07713
07714 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {
07715 continue;
07716 }
07717
07718 ast_channel_lock_both(c0, c1);
07719 c0->_bridge = NULL;
07720 c1->_bridge = NULL;
07721 ast_channel_unlock(c0);
07722 ast_channel_unlock(c1);
07723 return res;
07724 } else {
07725 ast_clear_flag(c0, AST_FLAG_NBRIDGE);
07726 ast_clear_flag(c1, AST_FLAG_NBRIDGE);
07727 }
07728 switch (res) {
07729 case AST_BRIDGE_RETRY:
07730 if (config->play_warning) {
07731 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
07732 }
07733 continue;
07734 default:
07735 ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name);
07736
07737 case AST_BRIDGE_FAILED_NOWARN:
07738 break;
07739 }
07740 }
07741
07742 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
07743 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
07744 !(c0->generator || c1->generator)) {
07745 if (ast_channel_make_compatible(c0, c1)) {
07746 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
07747 manager_bridge_event(0, 1, c0, c1);
07748 return AST_BRIDGE_FAILED;
07749 }
07750 o0nativeformats = c0->nativeformats;
07751 o1nativeformats = c1->nativeformats;
07752 }
07753
07754 update_bridge_vars(c0, c1);
07755
07756 res = ast_generic_bridge(c0, c1, config, fo, rc);
07757 if (res != AST_BRIDGE_RETRY) {
07758 break;
07759 } else if (config->feature_timer) {
07760
07761 break;
07762 }
07763 }
07764
07765 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
07766 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
07767
07768
07769 ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07770 ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07771
07772 ast_channel_lock_both(c0, c1);
07773 c0->_bridge = NULL;
07774 c1->_bridge = NULL;
07775 ast_channel_unlock(c0);
07776 ast_channel_unlock(c1);
07777
07778 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
07779 "Channel1: %s\r\n"
07780 "Channel2: %s\r\n"
07781 "Uniqueid1: %s\r\n"
07782 "Uniqueid2: %s\r\n"
07783 "CallerID1: %s\r\n"
07784 "CallerID2: %s\r\n",
07785 c0->name, c1->name,
07786 c0->uniqueid, c1->uniqueid,
07787 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"),
07788 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
07789 ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
07790
07791 return res;
07792 }
07793
07794
07795 int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
07796 {
07797 int res;
07798
07799 ast_channel_lock(chan);
07800 if (!chan->tech->setoption) {
07801 errno = ENOSYS;
07802 ast_channel_unlock(chan);
07803 return -1;
07804 }
07805
07806 if (block)
07807 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07808
07809 res = chan->tech->setoption(chan, option, data, datalen);
07810 ast_channel_unlock(chan);
07811
07812 return res;
07813 }
07814
07815 int ast_channel_queryoption(struct ast_channel *chan, int option, void *data, int *datalen, int block)
07816 {
07817 int res;
07818
07819 ast_channel_lock(chan);
07820 if (!chan->tech->queryoption) {
07821 errno = ENOSYS;
07822 ast_channel_unlock(chan);
07823 return -1;
07824 }
07825
07826 if (block)
07827 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07828
07829 res = chan->tech->queryoption(chan, option, data, datalen);
07830 ast_channel_unlock(chan);
07831
07832 return res;
07833 }
07834
07835 struct tonepair_def {
07836 int freq1;
07837 int freq2;
07838 int duration;
07839 int vol;
07840 };
07841
07842 struct tonepair_state {
07843 int fac1;
07844 int fac2;
07845 int v1_1;
07846 int v2_1;
07847 int v3_1;
07848 int v1_2;
07849 int v2_2;
07850 int v3_2;
07851 format_t origwfmt;
07852 int pos;
07853 int duration;
07854 int modulate;
07855 struct ast_frame f;
07856 unsigned char offset[AST_FRIENDLY_OFFSET];
07857 short data[4000];
07858 };
07859
07860 static void tonepair_release(struct ast_channel *chan, void *params)
07861 {
07862 struct tonepair_state *ts = params;
07863
07864 if (chan)
07865 ast_set_write_format(chan, ts->origwfmt);
07866 ast_free(ts);
07867 }
07868
07869 static void *tonepair_alloc(struct ast_channel *chan, void *params)
07870 {
07871 struct tonepair_state *ts;
07872 struct tonepair_def *td = params;
07873
07874 if (!(ts = ast_calloc(1, sizeof(*ts))))
07875 return NULL;
07876 ts->origwfmt = chan->writeformat;
07877 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
07878 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
07879 tonepair_release(NULL, ts);
07880 ts = NULL;
07881 } else {
07882 ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
07883 ts->v1_1 = 0;
07884 ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07885 ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07886 ts->v2_1 = 0;
07887 ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
07888 ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07889 ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07890 ts->duration = td->duration;
07891 ts->modulate = 0;
07892 }
07893
07894 ast_set_flag(chan, AST_FLAG_WRITE_INT);
07895 return ts;
07896 }
07897
07898 static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples)
07899 {
07900 struct tonepair_state *ts = data;
07901 int x;
07902
07903
07904
07905
07906 len = samples * 2;
07907
07908 if (len > sizeof(ts->data) / 2 - 1) {
07909 ast_log(LOG_WARNING, "Can't generate that much data!\n");
07910 return -1;
07911 }
07912 memset(&ts->f, 0, sizeof(ts->f));
07913 for (x=0;x<len/2;x++) {
07914 ts->v1_1 = ts->v2_1;
07915 ts->v2_1 = ts->v3_1;
07916 ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
07917
07918 ts->v1_2 = ts->v2_2;
07919 ts->v2_2 = ts->v3_2;
07920 ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
07921 if (ts->modulate) {
07922 int p;
07923 p = ts->v3_2 - 32768;
07924 if (p < 0) p = -p;
07925 p = ((p * 9) / 10) + 1;
07926 ts->data[x] = (ts->v3_1 * p) >> 15;
07927 } else
07928 ts->data[x] = ts->v3_1 + ts->v3_2;
07929 }
07930 ts->f.frametype = AST_FRAME_VOICE;
07931 ts->f.subclass.codec = AST_FORMAT_SLINEAR;
07932 ts->f.datalen = len;
07933 ts->f.samples = samples;
07934 ts->f.offset = AST_FRIENDLY_OFFSET;
07935 ts->f.data.ptr = ts->data;
07936 ast_write(chan, &ts->f);
07937 ts->pos += x;
07938 if (ts->duration > 0) {
07939 if (ts->pos >= ts->duration * 8)
07940 return -1;
07941 }
07942 return 0;
07943 }
07944
07945 static struct ast_generator tonepair = {
07946 .alloc = tonepair_alloc,
07947 .release = tonepair_release,
07948 .generate = tonepair_generator,
07949 };
07950
07951 int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
07952 {
07953 struct tonepair_def d = { 0, };
07954
07955 d.freq1 = freq1;
07956 d.freq2 = freq2;
07957 d.duration = duration;
07958 d.vol = (vol < 1) ? 8192 : vol;
07959 if (ast_activate_generator(chan, &tonepair, &d))
07960 return -1;
07961 return 0;
07962 }
07963
07964 void ast_tonepair_stop(struct ast_channel *chan)
07965 {
07966 ast_deactivate_generator(chan);
07967 }
07968
07969 int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
07970 {
07971 int res;
07972
07973 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
07974 return res;
07975
07976
07977 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
07978 struct ast_frame *f = ast_read(chan);
07979 if (f)
07980 ast_frfree(f);
07981 else
07982 return -1;
07983 }
07984 return 0;
07985 }
07986
07987 ast_group_t ast_get_group(const char *s)
07988 {
07989 char *piece;
07990 char *c;
07991 int start=0, finish=0, x;
07992 ast_group_t group = 0;
07993
07994 if (ast_strlen_zero(s))
07995 return 0;
07996
07997 c = ast_strdupa(s);
07998
07999 while ((piece = strsep(&c, ","))) {
08000 if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) {
08001
08002 } else if (sscanf(piece, "%30d", &start)) {
08003
08004 finish = start;
08005 } else {
08006 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
08007 continue;
08008 }
08009 for (x = start; x <= finish; x++) {
08010 if ((x > 63) || (x < 0)) {
08011 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
08012 } else
08013 group |= ((ast_group_t) 1 << x);
08014 }
08015 }
08016 return group;
08017 }
08018
08019 static int (*ast_moh_start_ptr)(struct ast_channel *, const char *, const char *) = NULL;
08020 static void (*ast_moh_stop_ptr)(struct ast_channel *) = NULL;
08021 static void (*ast_moh_cleanup_ptr)(struct ast_channel *) = NULL;
08022
08023 void ast_install_music_functions(int (*start_ptr)(struct ast_channel *, const char *, const char *),
08024 void (*stop_ptr)(struct ast_channel *),
08025 void (*cleanup_ptr)(struct ast_channel *))
08026 {
08027 ast_moh_start_ptr = start_ptr;
08028 ast_moh_stop_ptr = stop_ptr;
08029 ast_moh_cleanup_ptr = cleanup_ptr;
08030 }
08031
08032 void ast_uninstall_music_functions(void)
08033 {
08034 ast_moh_start_ptr = NULL;
08035 ast_moh_stop_ptr = NULL;
08036 ast_moh_cleanup_ptr = NULL;
08037 }
08038
08039
08040 int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
08041 {
08042 if (ast_moh_start_ptr)
08043 return ast_moh_start_ptr(chan, mclass, interpclass);
08044
08045 ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default"));
08046
08047 return 0;
08048 }
08049
08050
08051 void ast_moh_stop(struct ast_channel *chan)
08052 {
08053 if (ast_moh_stop_ptr)
08054 ast_moh_stop_ptr(chan);
08055 }
08056
08057 void ast_moh_cleanup(struct ast_channel *chan)
08058 {
08059 if (ast_moh_cleanup_ptr)
08060 ast_moh_cleanup_ptr(chan);
08061 }
08062
08063 static int ast_channel_hash_cb(const void *obj, const int flags)
08064 {
08065 const struct ast_channel *chan = obj;
08066
08067
08068
08069 if (ast_strlen_zero(chan->name)) {
08070 return 0;
08071 }
08072
08073 return ast_str_case_hash(chan->name);
08074 }
08075
08076 int ast_plc_reload(void)
08077 {
08078 struct ast_variable *var;
08079 struct ast_flags config_flags = { 0 };
08080 struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
08081 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
08082 return 0;
08083 for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
08084 if (!strcasecmp(var->name, "genericplc")) {
08085 ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC);
08086 }
08087 }
08088 ast_config_destroy(cfg);
08089 return 0;
08090 }
08091
08092
08093
08094
08095
08096 static int data_channels_provider_handler(const struct ast_data_search *search,
08097 struct ast_data *root)
08098 {
08099 struct ast_channel *c;
08100 struct ast_channel_iterator *iter = NULL;
08101 struct ast_data *data_channel;
08102
08103 for (iter = ast_channel_iterator_all_new();
08104 iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
08105 ast_channel_lock(c);
08106
08107 data_channel = ast_data_add_node(root, "channel");
08108 if (!data_channel) {
08109 ast_channel_unlock(c);
08110 continue;
08111 }
08112
08113 if (ast_channel_data_add_structure(data_channel, c, 1) < 0) {
08114 ast_log(LOG_ERROR, "Unable to add channel structure for channel: %s\n", c->name);
08115 }
08116
08117 ast_channel_unlock(c);
08118
08119 if (!ast_data_search_match(search, data_channel)) {
08120 ast_data_remove_node(root, data_channel);
08121 }
08122 }
08123 if (iter) {
08124 ast_channel_iterator_destroy(iter);
08125 }
08126
08127 return 0;
08128 }
08129
08130
08131
08132
08133
08134 static int data_channeltypes_provider_handler(const struct ast_data_search *search,
08135 struct ast_data *data_root)
08136 {
08137 struct chanlist *cl;
08138 struct ast_data *data_type;
08139
08140 AST_RWLIST_RDLOCK(&backends);
08141 AST_RWLIST_TRAVERSE(&backends, cl, list) {
08142 data_type = ast_data_add_node(data_root, "type");
08143 if (!data_type) {
08144 continue;
08145 }
08146 ast_data_add_str(data_type, "name", cl->tech->type);
08147 ast_data_add_str(data_type, "description", cl->tech->description);
08148 ast_data_add_bool(data_type, "devicestate", cl->tech->devicestate ? 1 : 0);
08149 ast_data_add_bool(data_type, "indications", cl->tech->indicate ? 1 : 0);
08150 ast_data_add_bool(data_type, "transfer", cl->tech->transfer ? 1 : 0);
08151 ast_data_add_bool(data_type, "send_digit_begin", cl->tech->send_digit_begin ? 1 : 0);
08152 ast_data_add_bool(data_type, "send_digit_end", cl->tech->send_digit_end ? 1 : 0);
08153 ast_data_add_bool(data_type, "call", cl->tech->call ? 1 : 0);
08154 ast_data_add_bool(data_type, "hangup", cl->tech->hangup ? 1 : 0);
08155 ast_data_add_bool(data_type, "answer", cl->tech->answer ? 1 : 0);
08156 ast_data_add_bool(data_type, "read", cl->tech->read ? 1 : 0);
08157 ast_data_add_bool(data_type, "write", cl->tech->write ? 1 : 0);
08158 ast_data_add_bool(data_type, "send_text", cl->tech->send_text ? 1 : 0);
08159 ast_data_add_bool(data_type, "send_image", cl->tech->send_image ? 1 : 0);
08160 ast_data_add_bool(data_type, "send_html", cl->tech->send_html ? 1 : 0);
08161 ast_data_add_bool(data_type, "exception", cl->tech->exception ? 1 : 0);
08162 ast_data_add_bool(data_type, "bridge", cl->tech->bridge ? 1 : 0);
08163 ast_data_add_bool(data_type, "early_bridge", cl->tech->early_bridge ? 1 : 0);
08164 ast_data_add_bool(data_type, "fixup", cl->tech->fixup ? 1 : 0);
08165 ast_data_add_bool(data_type, "setoption", cl->tech->setoption ? 1 : 0);
08166 ast_data_add_bool(data_type, "queryoption", cl->tech->queryoption ? 1 : 0);
08167 ast_data_add_bool(data_type, "write_video", cl->tech->write_video ? 1 : 0);
08168 ast_data_add_bool(data_type, "write_text", cl->tech->write_text ? 1 : 0);
08169 ast_data_add_bool(data_type, "bridged_channel", cl->tech->bridged_channel ? 1 : 0);
08170 ast_data_add_bool(data_type, "func_channel_read", cl->tech->func_channel_read ? 1 : 0);
08171 ast_data_add_bool(data_type, "func_channel_write", cl->tech->func_channel_write ? 1 : 0);
08172 ast_data_add_bool(data_type, "get_base_channel", cl->tech->get_base_channel ? 1 : 0);
08173 ast_data_add_bool(data_type, "set_base_channel", cl->tech->set_base_channel ? 1 : 0);
08174 ast_data_add_bool(data_type, "get_pvt_uniqueid", cl->tech->get_pvt_uniqueid ? 1 : 0);
08175 ast_data_add_bool(data_type, "cc_callback", cl->tech->cc_callback ? 1 : 0);
08176
08177 ast_data_add_codecs(data_type, "capabilities", cl->tech->capabilities);
08178
08179 if (!ast_data_search_match(search, data_type)) {
08180 ast_data_remove_node(data_root, data_type);
08181 }
08182 }
08183 AST_RWLIST_UNLOCK(&backends);
08184
08185 return 0;
08186 }
08187
08188
08189
08190
08191
08192 static const struct ast_data_handler channels_provider = {
08193 .version = AST_DATA_HANDLER_VERSION,
08194 .get = data_channels_provider_handler
08195 };
08196
08197
08198
08199
08200
08201 static const struct ast_data_handler channeltypes_provider = {
08202 .version = AST_DATA_HANDLER_VERSION,
08203 .get = data_channeltypes_provider_handler
08204 };
08205
08206 static const struct ast_data_entry channel_providers[] = {
08207 AST_DATA_ENTRY("/asterisk/core/channels", &channels_provider),
08208 AST_DATA_ENTRY("/asterisk/core/channeltypes", &channeltypes_provider),
08209 };
08210
08211 static void channels_shutdown(void)
08212 {
08213 ast_data_unregister(NULL);
08214 ast_cli_unregister_multiple(cli_channel, ARRAY_LEN(cli_channel));
08215 if (channels) {
08216 ao2_ref(channels, -1);
08217 channels = NULL;
08218 }
08219 }
08220
08221 void ast_channels_init(void)
08222 {
08223 channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS,
08224 ast_channel_hash_cb, ast_channel_cmp_cb);
08225
08226 ast_cli_register_multiple(cli_channel, ARRAY_LEN(cli_channel));
08227
08228 ast_data_register_multiple_core(channel_providers, ARRAY_LEN(channel_providers));
08229
08230 ast_plc_reload();
08231
08232 ast_register_atexit(channels_shutdown);
08233 }
08234
08235
08236 char *ast_print_group(char *buf, int buflen, ast_group_t group)
08237 {
08238 unsigned int i;
08239 int first = 1;
08240 char num[3];
08241
08242 buf[0] = '\0';
08243
08244 if (!group)
08245 return buf;
08246
08247 for (i = 0; i <= 63; i++) {
08248 if (group & ((ast_group_t) 1 << i)) {
08249 if (!first) {
08250 strncat(buf, ", ", buflen - strlen(buf) - 1);
08251 } else {
08252 first = 0;
08253 }
08254 snprintf(num, sizeof(num), "%u", i);
08255 strncat(buf, num, buflen - strlen(buf) - 1);
08256 }
08257 }
08258 return buf;
08259 }
08260
08261 void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
08262 {
08263 struct ast_variable *cur;
08264
08265 for (cur = vars; cur; cur = cur->next)
08266 pbx_builtin_setvar_helper(chan, cur->name, cur->value);
08267 }
08268
08269 static void *silence_generator_alloc(struct ast_channel *chan, void *data)
08270 {
08271
08272 return data;
08273 }
08274
08275 static void silence_generator_release(struct ast_channel *chan, void *data)
08276 {
08277
08278 }
08279
08280 static int silence_generator_generate(struct ast_channel *chan, void *data, int len, int samples)
08281 {
08282 short buf[samples];
08283 struct ast_frame frame = {
08284 .frametype = AST_FRAME_VOICE,
08285 .subclass.codec = AST_FORMAT_SLINEAR,
08286 .data.ptr = buf,
08287 .samples = samples,
08288 .datalen = sizeof(buf),
08289 };
08290
08291 memset(buf, 0, sizeof(buf));
08292
08293 if (ast_write(chan, &frame))
08294 return -1;
08295
08296 return 0;
08297 }
08298
08299 static struct ast_generator silence_generator = {
08300 .alloc = silence_generator_alloc,
08301 .release = silence_generator_release,
08302 .generate = silence_generator_generate,
08303 };
08304
08305 struct ast_silence_generator {
08306 int old_write_format;
08307 };
08308
08309 struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan)
08310 {
08311 struct ast_silence_generator *state;
08312
08313 if (!(state = ast_calloc(1, sizeof(*state)))) {
08314 return NULL;
08315 }
08316
08317 state->old_write_format = chan->writeformat;
08318
08319 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
08320 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
08321 ast_free(state);
08322 return NULL;
08323 }
08324
08325 ast_activate_generator(chan, &silence_generator, state);
08326
08327 ast_debug(1, "Started silence generator on '%s'\n", chan->name);
08328
08329 return state;
08330 }
08331
08332 static int deactivate_silence_generator(struct ast_channel *chan)
08333 {
08334 ast_channel_lock(chan);
08335
08336 if (!chan->generatordata) {
08337 ast_debug(1, "Trying to stop silence generator when there is no generator on '%s'\n",
08338 chan->name);
08339 ast_channel_unlock(chan);
08340 return 0;
08341 }
08342 if (chan->generator != &silence_generator) {
08343 ast_debug(1, "Trying to stop silence generator when it is not the current generator on '%s'\n",
08344 chan->name);
08345 ast_channel_unlock(chan);
08346 return 0;
08347 }
08348 deactivate_generator_nolock(chan);
08349
08350 ast_channel_unlock(chan);
08351
08352 return 1;
08353 }
08354
08355 void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
08356 {
08357 if (!state) {
08358 return;
08359 }
08360
08361 if (deactivate_silence_generator(chan)) {
08362 ast_debug(1, "Stopped silence generator on '%s'\n", chan->name);
08363
08364 if (ast_set_write_format(chan, state->old_write_format) < 0)
08365 ast_log(LOG_ERROR, "Could not return write format to its original state\n");
08366 }
08367 ast_free(state);
08368 }
08369
08370
08371
08372 const char *channelreloadreason2txt(enum channelreloadreason reason)
08373 {
08374 switch (reason) {
08375 case CHANNEL_MODULE_LOAD:
08376 return "LOAD (Channel module load)";
08377
08378 case CHANNEL_MODULE_RELOAD:
08379 return "RELOAD (Channel module reload)";
08380
08381 case CHANNEL_CLI_RELOAD:
08382 return "CLIRELOAD (Channel module reload by CLI command)";
08383
08384 default:
08385 return "MANAGERRELOAD (Channel module reload by manager)";
08386 }
08387 };
08388
08389
08390
08391
08392
08393
08394
08395
08396
08397 int ast_say_number(struct ast_channel *chan, int num,
08398 const char *ints, const char *language, const char *options)
08399 {
08400 return ast_say_number_full(chan, num, ints, language, options, -1, -1);
08401 }
08402
08403 int ast_say_enumeration(struct ast_channel *chan, int num,
08404 const char *ints, const char *language, const char *options)
08405 {
08406 return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
08407 }
08408
08409 int ast_say_digits(struct ast_channel *chan, int num,
08410 const char *ints, const char *lang)
08411 {
08412 return ast_say_digits_full(chan, num, ints, lang, -1, -1);
08413 }
08414
08415 int ast_say_digit_str(struct ast_channel *chan, const char *str,
08416 const char *ints, const char *lang)
08417 {
08418 return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
08419 }
08420
08421 int ast_say_character_str(struct ast_channel *chan, const char *str,
08422 const char *ints, const char *lang)
08423 {
08424 return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
08425 }
08426
08427 int ast_say_phonetic_str(struct ast_channel *chan, const char *str,
08428 const char *ints, const char *lang)
08429 {
08430 return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
08431 }
08432
08433 int ast_say_digits_full(struct ast_channel *chan, int num,
08434 const char *ints, const char *lang, int audiofd, int ctrlfd)
08435 {
08436 char buf[256];
08437
08438 snprintf(buf, sizeof(buf), "%d", num);
08439
08440 return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
08441 }
08442
08443 void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
08444 {
08445 ast_party_id_copy(&dest->id, &src->id);
08446 ast_party_id_copy(&dest->ani, &src->ani);
08447 dest->ani2 = src->ani2;
08448 }
08449
08450 void ast_connected_line_copy_to_caller(struct ast_party_caller *dest, const struct ast_party_connected_line *src)
08451 {
08452 ast_party_id_copy(&dest->id, &src->id);
08453 ast_party_id_copy(&dest->ani, &src->ani);
08454
08455 dest->ani2 = src->ani2;
08456 }
08457
08458 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)
08459 {
08460 if (&chan->connected == connected) {
08461
08462 return;
08463 }
08464
08465 ast_channel_lock(chan);
08466 ast_party_connected_line_set(&chan->connected, connected, update);
08467 ast_channel_unlock(chan);
08468 }
08469
08470
08471 struct ast_party_name_ies {
08472
08473 int str;
08474
08475 int char_set;
08476
08477 int presentation;
08478
08479 int valid;
08480 };
08481
08482
08483
08484
08485
08486
08487
08488
08489
08490
08491
08492
08493
08494
08495
08496 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)
08497 {
08498 size_t length;
08499 size_t pos = 0;
08500
08501
08502
08503
08504
08505 if (name->str) {
08506 length = strlen(name->str);
08507 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08508 ast_log(LOG_WARNING, "No space left for %s name\n", label);
08509 return -1;
08510 }
08511 data[pos++] = ies->str;
08512 data[pos++] = length;
08513 memcpy(data + pos, name->str, length);
08514 pos += length;
08515 }
08516
08517 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08518 ast_log(LOG_WARNING, "No space left for %s name char set\n", label);
08519 return -1;
08520 }
08521 data[pos++] = ies->char_set;
08522 data[pos++] = 1;
08523 data[pos++] = name->char_set;
08524
08525 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08526 ast_log(LOG_WARNING, "No space left for %s name presentation\n", label);
08527 return -1;
08528 }
08529 data[pos++] = ies->presentation;
08530 data[pos++] = 1;
08531 data[pos++] = name->presentation;
08532
08533 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08534 ast_log(LOG_WARNING, "No space left for %s name valid\n", label);
08535 return -1;
08536 }
08537 data[pos++] = ies->valid;
08538 data[pos++] = 1;
08539 data[pos++] = name->valid;
08540
08541 return pos;
08542 }
08543
08544
08545 struct ast_party_number_ies {
08546
08547 int str;
08548
08549 int plan;
08550
08551 int presentation;
08552
08553 int valid;
08554 };
08555
08556
08557
08558
08559
08560
08561
08562
08563
08564
08565
08566
08567
08568
08569
08570 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)
08571 {
08572 size_t length;
08573 size_t pos = 0;
08574
08575
08576
08577
08578
08579 if (number->str) {
08580 length = strlen(number->str);
08581 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08582 ast_log(LOG_WARNING, "No space left for %s number\n", label);
08583 return -1;
08584 }
08585 data[pos++] = ies->str;
08586 data[pos++] = length;
08587 memcpy(data + pos, number->str, length);
08588 pos += length;
08589 }
08590
08591 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08592 ast_log(LOG_WARNING, "No space left for %s numbering plan\n", label);
08593 return -1;
08594 }
08595 data[pos++] = ies->plan;
08596 data[pos++] = 1;
08597 data[pos++] = number->plan;
08598
08599 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08600 ast_log(LOG_WARNING, "No space left for %s number presentation\n", label);
08601 return -1;
08602 }
08603 data[pos++] = ies->presentation;
08604 data[pos++] = 1;
08605 data[pos++] = number->presentation;
08606
08607 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08608 ast_log(LOG_WARNING, "No space left for %s number valid\n", label);
08609 return -1;
08610 }
08611 data[pos++] = ies->valid;
08612 data[pos++] = 1;
08613 data[pos++] = number->valid;
08614
08615 return pos;
08616 }
08617
08618
08619 struct ast_party_subaddress_ies {
08620
08621 int str;
08622
08623 int type;
08624
08625 int odd_even_indicator;
08626
08627 int valid;
08628 };
08629
08630
08631
08632
08633
08634
08635
08636
08637
08638
08639
08640
08641
08642
08643
08644 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)
08645 {
08646 size_t length;
08647 size_t pos = 0;
08648
08649
08650
08651
08652
08653 if (subaddress->str) {
08654 length = strlen(subaddress->str);
08655 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08656 ast_log(LOG_WARNING, "No space left for %s subaddress\n", label);
08657 return -1;
08658 }
08659 data[pos++] = ies->str;
08660 data[pos++] = length;
08661 memcpy(data + pos, subaddress->str, length);
08662 pos += length;
08663 }
08664
08665 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08666 ast_log(LOG_WARNING, "No space left for %s type of subaddress\n", label);
08667 return -1;
08668 }
08669 data[pos++] = ies->type;
08670 data[pos++] = 1;
08671 data[pos++] = subaddress->type;
08672
08673 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08674 ast_log(LOG_WARNING,
08675 "No space left for %s subaddress odd-even indicator\n", label);
08676 return -1;
08677 }
08678 data[pos++] = ies->odd_even_indicator;
08679 data[pos++] = 1;
08680 data[pos++] = subaddress->odd_even_indicator;
08681
08682 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08683 ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label);
08684 return -1;
08685 }
08686 data[pos++] = ies->valid;
08687 data[pos++] = 1;
08688 data[pos++] = subaddress->valid;
08689
08690 return pos;
08691 }
08692
08693
08694 struct ast_party_id_ies {
08695
08696 struct ast_party_name_ies name;
08697
08698 struct ast_party_number_ies number;
08699
08700 struct ast_party_subaddress_ies subaddress;
08701
08702 int tag;
08703
08704 int combined_presentation;
08705 };
08706
08707
08708
08709
08710
08711
08712
08713
08714
08715
08716
08717
08718
08719
08720
08721
08722 static int party_id_build_data(unsigned char *data, size_t datalen,
08723 const struct ast_party_id *id, const char *label, const struct ast_party_id_ies *ies,
08724 const struct ast_set_party_id *update)
08725 {
08726 size_t length;
08727 size_t pos = 0;
08728 int res;
08729
08730
08731
08732
08733
08734
08735 if (!update || update->name) {
08736 res = party_name_build_data(data + pos, datalen - pos, &id->name, label,
08737 &ies->name);
08738 if (res < 0) {
08739 return -1;
08740 }
08741 pos += res;
08742 }
08743
08744 if (!update || update->number) {
08745 res = party_number_build_data(data + pos, datalen - pos, &id->number, label,
08746 &ies->number);
08747 if (res < 0) {
08748 return -1;
08749 }
08750 pos += res;
08751 }
08752
08753 if (!update || update->subaddress) {
08754 res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress,
08755 label, &ies->subaddress);
08756 if (res < 0) {
08757 return -1;
08758 }
08759 pos += res;
08760 }
08761
08762
08763 if (id->tag) {
08764 length = strlen(id->tag);
08765 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08766 ast_log(LOG_WARNING, "No space left for %s tag\n", label);
08767 return -1;
08768 }
08769 data[pos++] = ies->tag;
08770 data[pos++] = length;
08771 memcpy(data + pos, id->tag, length);
08772 pos += length;
08773 }
08774
08775
08776 if (!update || update->number) {
08777 int presentation;
08778
08779 if (!update || update->name) {
08780 presentation = ast_party_id_presentation(id);
08781 } else {
08782
08783
08784
08785
08786
08787 presentation = id->number.presentation;
08788 }
08789
08790 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08791 ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label);
08792 return -1;
08793 }
08794 data[pos++] = ies->combined_presentation;
08795 data[pos++] = 1;
08796 data[pos++] = presentation;
08797 }
08798
08799 return pos;
08800 }
08801
08802
08803
08804
08805
08806 enum {
08807 AST_CONNECTED_LINE_NUMBER,
08808 AST_CONNECTED_LINE_NAME,
08809 AST_CONNECTED_LINE_NUMBER_PLAN,
08810 AST_CONNECTED_LINE_ID_PRESENTATION,
08811 AST_CONNECTED_LINE_SOURCE,
08812 AST_CONNECTED_LINE_SUBADDRESS,
08813 AST_CONNECTED_LINE_SUBADDRESS_TYPE,
08814 AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
08815 AST_CONNECTED_LINE_SUBADDRESS_VALID,
08816 AST_CONNECTED_LINE_TAG,
08817 AST_CONNECTED_LINE_VERSION,
08818 AST_CONNECTED_LINE_NAME_VALID,
08819 AST_CONNECTED_LINE_NAME_CHAR_SET,
08820 AST_CONNECTED_LINE_NAME_PRESENTATION,
08821 AST_CONNECTED_LINE_NUMBER_VALID,
08822 AST_CONNECTED_LINE_NUMBER_PRESENTATION,
08823 };
08824
08825 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)
08826 {
08827 int32_t value;
08828 size_t pos = 0;
08829 int res;
08830
08831 static const struct ast_party_id_ies ies = {
08832 .name.str = AST_CONNECTED_LINE_NAME,
08833 .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET,
08834 .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION,
08835 .name.valid = AST_CONNECTED_LINE_NAME_VALID,
08836
08837 .number.str = AST_CONNECTED_LINE_NUMBER,
08838 .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN,
08839 .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION,
08840 .number.valid = AST_CONNECTED_LINE_NUMBER_VALID,
08841
08842 .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS,
08843 .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE,
08844 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
08845 .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID,
08846
08847 .tag = AST_CONNECTED_LINE_TAG,
08848 .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION,
08849 };
08850
08851
08852
08853
08854
08855
08856
08857 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08858 ast_log(LOG_WARNING, "No space left for connected line frame version\n");
08859 return -1;
08860 }
08861 data[pos++] = AST_CONNECTED_LINE_VERSION;
08862 data[pos++] = 1;
08863 data[pos++] = 2;
08864
08865 res = party_id_build_data(data + pos, datalen - pos, &connected->id,
08866 "connected line", &ies, update ? &update->id : NULL);
08867 if (res < 0) {
08868 return -1;
08869 }
08870 pos += res;
08871
08872
08873 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
08874 ast_log(LOG_WARNING, "No space left for connected line source\n");
08875 return -1;
08876 }
08877 data[pos++] = AST_CONNECTED_LINE_SOURCE;
08878 data[pos++] = sizeof(value);
08879 value = htonl(connected->source);
08880 memcpy(data + pos, &value, sizeof(value));
08881 pos += sizeof(value);
08882
08883 return pos;
08884 }
08885
08886 int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, struct ast_party_connected_line *connected)
08887 {
08888 size_t pos;
08889 unsigned char ie_len;
08890 unsigned char ie_id;
08891 int32_t value;
08892 int frame_version = 1;
08893 int combined_presentation = 0;
08894 int got_combined_presentation = 0;
08895
08896 for (pos = 0; pos < datalen; pos += ie_len) {
08897 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
08898 ast_log(LOG_WARNING, "Invalid connected line update\n");
08899 return -1;
08900 }
08901 ie_id = data[pos++];
08902 ie_len = data[pos++];
08903 if (datalen < pos + ie_len) {
08904 ast_log(LOG_WARNING, "Invalid connected line update\n");
08905 return -1;
08906 }
08907
08908 switch (ie_id) {
08909
08910 case AST_CONNECTED_LINE_VERSION:
08911 if (ie_len != 1) {
08912 ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n",
08913 (unsigned) ie_len);
08914 break;
08915 }
08916 frame_version = data[pos];
08917 break;
08918
08919 case AST_CONNECTED_LINE_NAME:
08920 ast_free(connected->id.name.str);
08921 connected->id.name.str = ast_malloc(ie_len + 1);
08922 if (connected->id.name.str) {
08923 memcpy(connected->id.name.str, data + pos, ie_len);
08924 connected->id.name.str[ie_len] = 0;
08925 }
08926 break;
08927 case AST_CONNECTED_LINE_NAME_CHAR_SET:
08928 if (ie_len != 1) {
08929 ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n",
08930 (unsigned) ie_len);
08931 break;
08932 }
08933 connected->id.name.char_set = data[pos];
08934 break;
08935 case AST_CONNECTED_LINE_NAME_PRESENTATION:
08936 if (ie_len != 1) {
08937 ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n",
08938 (unsigned) ie_len);
08939 break;
08940 }
08941 connected->id.name.presentation = data[pos];
08942 break;
08943 case AST_CONNECTED_LINE_NAME_VALID:
08944 if (ie_len != 1) {
08945 ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n",
08946 (unsigned) ie_len);
08947 break;
08948 }
08949 connected->id.name.valid = data[pos];
08950 break;
08951
08952 case AST_CONNECTED_LINE_NUMBER:
08953 ast_free(connected->id.number.str);
08954 connected->id.number.str = ast_malloc(ie_len + 1);
08955 if (connected->id.number.str) {
08956 memcpy(connected->id.number.str, data + pos, ie_len);
08957 connected->id.number.str[ie_len] = 0;
08958 }
08959 break;
08960 case AST_CONNECTED_LINE_NUMBER_PLAN:
08961 if (ie_len != 1) {
08962 ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n",
08963 (unsigned) ie_len);
08964 break;
08965 }
08966 connected->id.number.plan = data[pos];
08967 break;
08968 case AST_CONNECTED_LINE_NUMBER_PRESENTATION:
08969 if (ie_len != 1) {
08970 ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n",
08971 (unsigned) ie_len);
08972 break;
08973 }
08974 connected->id.number.presentation = data[pos];
08975 break;
08976 case AST_CONNECTED_LINE_NUMBER_VALID:
08977 if (ie_len != 1) {
08978 ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n",
08979 (unsigned) ie_len);
08980 break;
08981 }
08982 connected->id.number.valid = data[pos];
08983 break;
08984
08985 case AST_CONNECTED_LINE_ID_PRESENTATION:
08986 if (ie_len != 1) {
08987 ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n",
08988 (unsigned) ie_len);
08989 break;
08990 }
08991 combined_presentation = data[pos];
08992 got_combined_presentation = 1;
08993 break;
08994
08995 case AST_CONNECTED_LINE_SUBADDRESS:
08996 ast_free(connected->id.subaddress.str);
08997 connected->id.subaddress.str = ast_malloc(ie_len + 1);
08998 if (connected->id.subaddress.str) {
08999 memcpy(connected->id.subaddress.str, data + pos, ie_len);
09000 connected->id.subaddress.str[ie_len] = 0;
09001 }
09002 break;
09003 case AST_CONNECTED_LINE_SUBADDRESS_TYPE:
09004 if (ie_len != 1) {
09005 ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n",
09006 (unsigned) ie_len);
09007 break;
09008 }
09009 connected->id.subaddress.type = data[pos];
09010 break;
09011 case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN:
09012 if (ie_len != 1) {
09013 ast_log(LOG_WARNING,
09014 "Invalid connected line subaddress odd-even indicator (%u)\n",
09015 (unsigned) ie_len);
09016 break;
09017 }
09018 connected->id.subaddress.odd_even_indicator = data[pos];
09019 break;
09020 case AST_CONNECTED_LINE_SUBADDRESS_VALID:
09021 if (ie_len != 1) {
09022 ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n",
09023 (unsigned) ie_len);
09024 break;
09025 }
09026 connected->id.subaddress.valid = data[pos];
09027 break;
09028
09029 case AST_CONNECTED_LINE_TAG:
09030 ast_free(connected->id.tag);
09031 connected->id.tag = ast_malloc(ie_len + 1);
09032 if (connected->id.tag) {
09033 memcpy(connected->id.tag, data + pos, ie_len);
09034 connected->id.tag[ie_len] = 0;
09035 }
09036 break;
09037
09038 case AST_CONNECTED_LINE_SOURCE:
09039 if (ie_len != sizeof(value)) {
09040 ast_log(LOG_WARNING, "Invalid connected line source (%u)\n",
09041 (unsigned) ie_len);
09042 break;
09043 }
09044 memcpy(&value, data + pos, sizeof(value));
09045 connected->source = ntohl(value);
09046 break;
09047
09048 default:
09049 ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n",
09050 (unsigned) ie_id, (unsigned) ie_len);
09051 break;
09052 }
09053 }
09054
09055 switch (frame_version) {
09056 case 1:
09057
09058
09059
09060
09061 connected->id.name.valid = 1;
09062 connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09063 connected->id.number.valid = 1;
09064 if (got_combined_presentation) {
09065 connected->id.name.presentation = combined_presentation;
09066 connected->id.number.presentation = combined_presentation;
09067 }
09068 break;
09069 case 2:
09070
09071 break;
09072 default:
09073
09074
09075
09076
09077 ast_log(LOG_DEBUG, "Connected line frame has newer version: %u\n",
09078 (unsigned) frame_version);
09079 break;
09080 }
09081
09082 return 0;
09083 }
09084
09085 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)
09086 {
09087 unsigned char data[1024];
09088 size_t datalen;
09089
09090 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
09091 if (datalen == (size_t) -1) {
09092 return;
09093 }
09094
09095 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
09096 }
09097
09098 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)
09099 {
09100 unsigned char data[1024];
09101 size_t datalen;
09102
09103 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
09104 if (datalen == (size_t) -1) {
09105 return;
09106 }
09107
09108 ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
09109 }
09110
09111 void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09112 {
09113 if (&chan->redirecting == redirecting) {
09114
09115 return;
09116 }
09117
09118 ast_channel_lock(chan);
09119 ast_party_redirecting_set(&chan->redirecting, redirecting, update);
09120 ast_channel_unlock(chan);
09121 }
09122
09123
09124
09125
09126
09127 enum {
09128 AST_REDIRECTING_FROM_NUMBER,
09129 AST_REDIRECTING_FROM_NAME,
09130 AST_REDIRECTING_FROM_NUMBER_PLAN,
09131 AST_REDIRECTING_FROM_ID_PRESENTATION,
09132 AST_REDIRECTING_TO_NUMBER,
09133 AST_REDIRECTING_TO_NAME,
09134 AST_REDIRECTING_TO_NUMBER_PLAN,
09135 AST_REDIRECTING_TO_ID_PRESENTATION,
09136 AST_REDIRECTING_REASON,
09137 AST_REDIRECTING_COUNT,
09138 AST_REDIRECTING_FROM_SUBADDRESS,
09139 AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
09140 AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
09141 AST_REDIRECTING_FROM_SUBADDRESS_VALID,
09142 AST_REDIRECTING_TO_SUBADDRESS,
09143 AST_REDIRECTING_TO_SUBADDRESS_TYPE,
09144 AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
09145 AST_REDIRECTING_TO_SUBADDRESS_VALID,
09146 AST_REDIRECTING_FROM_TAG,
09147 AST_REDIRECTING_TO_TAG,
09148 AST_REDIRECTING_VERSION,
09149 AST_REDIRECTING_FROM_NAME_VALID,
09150 AST_REDIRECTING_FROM_NAME_CHAR_SET,
09151 AST_REDIRECTING_FROM_NAME_PRESENTATION,
09152 AST_REDIRECTING_FROM_NUMBER_VALID,
09153 AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
09154 AST_REDIRECTING_TO_NAME_VALID,
09155 AST_REDIRECTING_TO_NAME_CHAR_SET,
09156 AST_REDIRECTING_TO_NAME_PRESENTATION,
09157 AST_REDIRECTING_TO_NUMBER_VALID,
09158 AST_REDIRECTING_TO_NUMBER_PRESENTATION,
09159 };
09160
09161 int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09162 {
09163 int32_t value;
09164 size_t pos = 0;
09165 int res;
09166
09167 static const struct ast_party_id_ies from_ies = {
09168 .name.str = AST_REDIRECTING_FROM_NAME,
09169 .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET,
09170 .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION,
09171 .name.valid = AST_REDIRECTING_FROM_NAME_VALID,
09172
09173 .number.str = AST_REDIRECTING_FROM_NUMBER,
09174 .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN,
09175 .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
09176 .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID,
09177
09178 .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS,
09179 .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
09180 .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
09181 .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID,
09182
09183 .tag = AST_REDIRECTING_FROM_TAG,
09184 .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION,
09185 };
09186 static const struct ast_party_id_ies to_ies = {
09187 .name.str = AST_REDIRECTING_TO_NAME,
09188 .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET,
09189 .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION,
09190 .name.valid = AST_REDIRECTING_TO_NAME_VALID,
09191
09192 .number.str = AST_REDIRECTING_TO_NUMBER,
09193 .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN,
09194 .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION,
09195 .number.valid = AST_REDIRECTING_TO_NUMBER_VALID,
09196
09197 .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS,
09198 .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE,
09199 .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
09200 .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID,
09201
09202 .tag = AST_REDIRECTING_TO_TAG,
09203 .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION,
09204 };
09205
09206
09207 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
09208 ast_log(LOG_WARNING, "No space left for redirecting frame version\n");
09209 return -1;
09210 }
09211 data[pos++] = AST_REDIRECTING_VERSION;
09212 data[pos++] = 1;
09213 data[pos++] = 2;
09214
09215 res = party_id_build_data(data + pos, datalen - pos, &redirecting->from,
09216 "redirecting-from", &from_ies, update ? &update->from : NULL);
09217 if (res < 0) {
09218 return -1;
09219 }
09220 pos += res;
09221
09222 res = party_id_build_data(data + pos, datalen - pos, &redirecting->to,
09223 "redirecting-to", &to_ies, update ? &update->to : NULL);
09224 if (res < 0) {
09225 return -1;
09226 }
09227 pos += res;
09228
09229
09230 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
09231 ast_log(LOG_WARNING, "No space left for redirecting reason\n");
09232 return -1;
09233 }
09234 data[pos++] = AST_REDIRECTING_REASON;
09235 data[pos++] = sizeof(value);
09236 value = htonl(redirecting->reason);
09237 memcpy(data + pos, &value, sizeof(value));
09238 pos += sizeof(value);
09239
09240
09241 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
09242 ast_log(LOG_WARNING, "No space left for redirecting count\n");
09243 return -1;
09244 }
09245 data[pos++] = AST_REDIRECTING_COUNT;
09246 data[pos++] = sizeof(value);
09247 value = htonl(redirecting->count);
09248 memcpy(data + pos, &value, sizeof(value));
09249 pos += sizeof(value);
09250
09251 return pos;
09252 }
09253
09254 int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct ast_party_redirecting *redirecting)
09255 {
09256 size_t pos;
09257 unsigned char ie_len;
09258 unsigned char ie_id;
09259 int32_t value;
09260 int frame_version = 1;
09261 int from_combined_presentation = 0;
09262 int got_from_combined_presentation = 0;
09263 int to_combined_presentation = 0;
09264 int got_to_combined_presentation = 0;
09265
09266 for (pos = 0; pos < datalen; pos += ie_len) {
09267 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
09268 ast_log(LOG_WARNING, "Invalid redirecting update\n");
09269 return -1;
09270 }
09271 ie_id = data[pos++];
09272 ie_len = data[pos++];
09273 if (datalen < pos + ie_len) {
09274 ast_log(LOG_WARNING, "Invalid redirecting update\n");
09275 return -1;
09276 }
09277
09278 switch (ie_id) {
09279
09280 case AST_REDIRECTING_VERSION:
09281 if (ie_len != 1) {
09282 ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n",
09283 (unsigned) ie_len);
09284 break;
09285 }
09286 frame_version = data[pos];
09287 break;
09288
09289 case AST_REDIRECTING_FROM_NAME:
09290 ast_free(redirecting->from.name.str);
09291 redirecting->from.name.str = ast_malloc(ie_len + 1);
09292 if (redirecting->from.name.str) {
09293 memcpy(redirecting->from.name.str, data + pos, ie_len);
09294 redirecting->from.name.str[ie_len] = 0;
09295 }
09296 break;
09297 case AST_REDIRECTING_FROM_NAME_CHAR_SET:
09298 if (ie_len != 1) {
09299 ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n",
09300 (unsigned) ie_len);
09301 break;
09302 }
09303 redirecting->from.name.char_set = data[pos];
09304 break;
09305 case AST_REDIRECTING_FROM_NAME_PRESENTATION:
09306 if (ie_len != 1) {
09307 ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n",
09308 (unsigned) ie_len);
09309 break;
09310 }
09311 redirecting->from.name.presentation = data[pos];
09312 break;
09313 case AST_REDIRECTING_FROM_NAME_VALID:
09314 if (ie_len != 1) {
09315 ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n",
09316 (unsigned) ie_len);
09317 break;
09318 }
09319 redirecting->from.name.valid = data[pos];
09320 break;
09321
09322 case AST_REDIRECTING_FROM_NUMBER:
09323 ast_free(redirecting->from.number.str);
09324 redirecting->from.number.str = ast_malloc(ie_len + 1);
09325 if (redirecting->from.number.str) {
09326 memcpy(redirecting->from.number.str, data + pos, ie_len);
09327 redirecting->from.number.str[ie_len] = 0;
09328 }
09329 break;
09330 case AST_REDIRECTING_FROM_NUMBER_PLAN:
09331 if (ie_len != 1) {
09332 ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n",
09333 (unsigned) ie_len);
09334 break;
09335 }
09336 redirecting->from.number.plan = data[pos];
09337 break;
09338 case AST_REDIRECTING_FROM_NUMBER_PRESENTATION:
09339 if (ie_len != 1) {
09340 ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n",
09341 (unsigned) ie_len);
09342 break;
09343 }
09344 redirecting->from.number.presentation = data[pos];
09345 break;
09346 case AST_REDIRECTING_FROM_NUMBER_VALID:
09347 if (ie_len != 1) {
09348 ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n",
09349 (unsigned) ie_len);
09350 break;
09351 }
09352 redirecting->from.number.valid = data[pos];
09353 break;
09354
09355 case AST_REDIRECTING_FROM_ID_PRESENTATION:
09356 if (ie_len != 1) {
09357 ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n",
09358 (unsigned) ie_len);
09359 break;
09360 }
09361 from_combined_presentation = data[pos];
09362 got_from_combined_presentation = 1;
09363 break;
09364
09365 case AST_REDIRECTING_FROM_SUBADDRESS:
09366 ast_free(redirecting->from.subaddress.str);
09367 redirecting->from.subaddress.str = ast_malloc(ie_len + 1);
09368 if (redirecting->from.subaddress.str) {
09369 memcpy(redirecting->from.subaddress.str, data + pos, ie_len);
09370 redirecting->from.subaddress.str[ie_len] = 0;
09371 }
09372 break;
09373 case AST_REDIRECTING_FROM_SUBADDRESS_TYPE:
09374 if (ie_len != 1) {
09375 ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n",
09376 (unsigned) ie_len);
09377 break;
09378 }
09379 redirecting->from.subaddress.type = data[pos];
09380 break;
09381 case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN:
09382 if (ie_len != 1) {
09383 ast_log(LOG_WARNING,
09384 "Invalid redirecting-from subaddress odd-even indicator (%u)\n",
09385 (unsigned) ie_len);
09386 break;
09387 }
09388 redirecting->from.subaddress.odd_even_indicator = data[pos];
09389 break;
09390 case AST_REDIRECTING_FROM_SUBADDRESS_VALID:
09391 if (ie_len != 1) {
09392 ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n",
09393 (unsigned) ie_len);
09394 break;
09395 }
09396 redirecting->from.subaddress.valid = data[pos];
09397 break;
09398
09399 case AST_REDIRECTING_FROM_TAG:
09400 ast_free(redirecting->from.tag);
09401 redirecting->from.tag = ast_malloc(ie_len + 1);
09402 if (redirecting->from.tag) {
09403 memcpy(redirecting->from.tag, data + pos, ie_len);
09404 redirecting->from.tag[ie_len] = 0;
09405 }
09406 break;
09407
09408 case AST_REDIRECTING_TO_NAME:
09409 ast_free(redirecting->to.name.str);
09410 redirecting->to.name.str = ast_malloc(ie_len + 1);
09411 if (redirecting->to.name.str) {
09412 memcpy(redirecting->to.name.str, data + pos, ie_len);
09413 redirecting->to.name.str[ie_len] = 0;
09414 }
09415 break;
09416 case AST_REDIRECTING_TO_NAME_CHAR_SET:
09417 if (ie_len != 1) {
09418 ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n",
09419 (unsigned) ie_len);
09420 break;
09421 }
09422 redirecting->to.name.char_set = data[pos];
09423 break;
09424 case AST_REDIRECTING_TO_NAME_PRESENTATION:
09425 if (ie_len != 1) {
09426 ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n",
09427 (unsigned) ie_len);
09428 break;
09429 }
09430 redirecting->to.name.presentation = data[pos];
09431 break;
09432 case AST_REDIRECTING_TO_NAME_VALID:
09433 if (ie_len != 1) {
09434 ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n",
09435 (unsigned) ie_len);
09436 break;
09437 }
09438 redirecting->to.name.valid = data[pos];
09439 break;
09440
09441 case AST_REDIRECTING_TO_NUMBER:
09442 ast_free(redirecting->to.number.str);
09443 redirecting->to.number.str = ast_malloc(ie_len + 1);
09444 if (redirecting->to.number.str) {
09445 memcpy(redirecting->to.number.str, data + pos, ie_len);
09446 redirecting->to.number.str[ie_len] = 0;
09447 }
09448 break;
09449 case AST_REDIRECTING_TO_NUMBER_PLAN:
09450 if (ie_len != 1) {
09451 ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n",
09452 (unsigned) ie_len);
09453 break;
09454 }
09455 redirecting->to.number.plan = data[pos];
09456 break;
09457 case AST_REDIRECTING_TO_NUMBER_PRESENTATION:
09458 if (ie_len != 1) {
09459 ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n",
09460 (unsigned) ie_len);
09461 break;
09462 }
09463 redirecting->to.number.presentation = data[pos];
09464 break;
09465 case AST_REDIRECTING_TO_NUMBER_VALID:
09466 if (ie_len != 1) {
09467 ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n",
09468 (unsigned) ie_len);
09469 break;
09470 }
09471 redirecting->to.number.valid = data[pos];
09472 break;
09473
09474 case AST_REDIRECTING_TO_ID_PRESENTATION:
09475 if (ie_len != 1) {
09476 ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n",
09477 (unsigned) ie_len);
09478 break;
09479 }
09480 to_combined_presentation = data[pos];
09481 got_to_combined_presentation = 1;
09482 break;
09483
09484 case AST_REDIRECTING_TO_SUBADDRESS:
09485 ast_free(redirecting->to.subaddress.str);
09486 redirecting->to.subaddress.str = ast_malloc(ie_len + 1);
09487 if (redirecting->to.subaddress.str) {
09488 memcpy(redirecting->to.subaddress.str, data + pos, ie_len);
09489 redirecting->to.subaddress.str[ie_len] = 0;
09490 }
09491 break;
09492 case AST_REDIRECTING_TO_SUBADDRESS_TYPE:
09493 if (ie_len != 1) {
09494 ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n",
09495 (unsigned) ie_len);
09496 break;
09497 }
09498 redirecting->to.subaddress.type = data[pos];
09499 break;
09500 case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN:
09501 if (ie_len != 1) {
09502 ast_log(LOG_WARNING,
09503 "Invalid redirecting-to subaddress odd-even indicator (%u)\n",
09504 (unsigned) ie_len);
09505 break;
09506 }
09507 redirecting->to.subaddress.odd_even_indicator = data[pos];
09508 break;
09509 case AST_REDIRECTING_TO_SUBADDRESS_VALID:
09510 if (ie_len != 1) {
09511 ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n",
09512 (unsigned) ie_len);
09513 break;
09514 }
09515 redirecting->to.subaddress.valid = data[pos];
09516 break;
09517
09518 case AST_REDIRECTING_TO_TAG:
09519 ast_free(redirecting->to.tag);
09520 redirecting->to.tag = ast_malloc(ie_len + 1);
09521 if (redirecting->to.tag) {
09522 memcpy(redirecting->to.tag, data + pos, ie_len);
09523 redirecting->to.tag[ie_len] = 0;
09524 }
09525 break;
09526
09527 case AST_REDIRECTING_REASON:
09528 if (ie_len != sizeof(value)) {
09529 ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n",
09530 (unsigned) ie_len);
09531 break;
09532 }
09533 memcpy(&value, data + pos, sizeof(value));
09534 redirecting->reason = ntohl(value);
09535 break;
09536
09537 case AST_REDIRECTING_COUNT:
09538 if (ie_len != sizeof(value)) {
09539 ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n",
09540 (unsigned) ie_len);
09541 break;
09542 }
09543 memcpy(&value, data + pos, sizeof(value));
09544 redirecting->count = ntohl(value);
09545 break;
09546
09547 default:
09548 ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n",
09549 (unsigned) ie_id, (unsigned) ie_len);
09550 break;
09551 }
09552 }
09553
09554 switch (frame_version) {
09555 case 1:
09556
09557
09558
09559
09560 redirecting->from.name.valid = 1;
09561 redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09562 redirecting->from.number.valid = 1;
09563 if (got_from_combined_presentation) {
09564 redirecting->from.name.presentation = from_combined_presentation;
09565 redirecting->from.number.presentation = from_combined_presentation;
09566 }
09567
09568 redirecting->to.name.valid = 1;
09569 redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09570 redirecting->to.number.valid = 1;
09571 if (got_to_combined_presentation) {
09572 redirecting->to.name.presentation = to_combined_presentation;
09573 redirecting->to.number.presentation = to_combined_presentation;
09574 }
09575 break;
09576 case 2:
09577
09578 break;
09579 default:
09580
09581
09582
09583
09584 ast_log(LOG_DEBUG, "Redirecting frame has newer version: %u\n",
09585 (unsigned) frame_version);
09586 break;
09587 }
09588
09589 return 0;
09590 }
09591
09592 void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09593 {
09594 unsigned char data[1024];
09595 size_t datalen;
09596
09597 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09598 if (datalen == (size_t) -1) {
09599 return;
09600 }
09601
09602 ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09603 }
09604
09605 void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09606 {
09607 unsigned char data[1024];
09608 size_t datalen;
09609
09610 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09611 if (datalen == (size_t) -1) {
09612 return;
09613 }
09614
09615 ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09616 }
09617
09618 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)
09619 {
09620 const char *macro;
09621 const char *macro_args;
09622 int retval;
09623
09624 ast_channel_lock(macro_chan);
09625 macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09626 ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO");
09627 macro = ast_strdupa(S_OR(macro, ""));
09628 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09629 ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS");
09630 macro_args = ast_strdupa(S_OR(macro_args, ""));
09631
09632 if (ast_strlen_zero(macro)) {
09633 ast_channel_unlock(macro_chan);
09634 return -1;
09635 }
09636
09637 if (is_frame) {
09638 const struct ast_frame *frame = connected_info;
09639
09640 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->connected);
09641 } else {
09642 const struct ast_party_connected_line *connected = connected_info;
09643
09644 ast_party_connected_line_copy(¯o_chan->connected, connected);
09645 }
09646 ast_channel_unlock(macro_chan);
09647
09648 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
09649 if (!retval) {
09650 struct ast_party_connected_line saved_connected;
09651
09652 ast_party_connected_line_init(&saved_connected);
09653 ast_channel_lock(macro_chan);
09654 ast_party_connected_line_copy(&saved_connected, ¯o_chan->connected);
09655 ast_channel_unlock(macro_chan);
09656 ast_channel_update_connected_line(macro_chan, &saved_connected, NULL);
09657 ast_party_connected_line_free(&saved_connected);
09658 }
09659
09660 return retval;
09661 }
09662
09663 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)
09664 {
09665 const char *macro;
09666 const char *macro_args;
09667 int retval;
09668
09669 ast_channel_lock(macro_chan);
09670 macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09671 ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO");
09672 macro = ast_strdupa(S_OR(macro, ""));
09673 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09674 ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS");
09675 macro_args = ast_strdupa(S_OR(macro_args, ""));
09676
09677 if (ast_strlen_zero(macro)) {
09678 ast_channel_unlock(macro_chan);
09679 return -1;
09680 }
09681
09682 if (is_frame) {
09683 const struct ast_frame *frame = redirecting_info;
09684
09685 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->redirecting);
09686 } else {
09687 const struct ast_party_redirecting *redirecting = redirecting_info;
09688
09689 ast_party_redirecting_copy(¯o_chan->redirecting, redirecting);
09690 }
09691 ast_channel_unlock(macro_chan);
09692
09693 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
09694 if (!retval) {
09695 struct ast_party_redirecting saved_redirecting;
09696
09697 ast_party_redirecting_init(&saved_redirecting);
09698 ast_channel_lock(macro_chan);
09699 ast_party_redirecting_copy(&saved_redirecting, ¯o_chan->redirecting);
09700 ast_channel_unlock(macro_chan);
09701 ast_channel_update_redirecting(macro_chan, &saved_redirecting, NULL);
09702 ast_party_redirecting_free(&saved_redirecting);
09703 }
09704
09705 return retval;
09706 }
09707
09708 static void *channel_cc_params_copy(void *data)
09709 {
09710 const struct ast_cc_config_params *src = data;
09711 struct ast_cc_config_params *dest = ast_cc_config_params_init();
09712 if (!dest) {
09713 return NULL;
09714 }
09715 ast_cc_copy_config_params(dest, src);
09716 return dest;
09717 }
09718
09719 static void channel_cc_params_destroy(void *data)
09720 {
09721 struct ast_cc_config_params *cc_params = data;
09722 ast_cc_config_params_destroy(cc_params);
09723 }
09724
09725 static const struct ast_datastore_info cc_channel_datastore_info = {
09726 .type = "Call Completion",
09727 .duplicate = channel_cc_params_copy,
09728 .destroy = channel_cc_params_destroy,
09729 };
09730
09731 int ast_channel_cc_params_init(struct ast_channel *chan,
09732 const struct ast_cc_config_params *base_params)
09733 {
09734 struct ast_cc_config_params *cc_params;
09735 struct ast_datastore *cc_datastore;
09736
09737 if (!(cc_params = ast_cc_config_params_init())) {
09738 return -1;
09739 }
09740
09741 if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) {
09742 ast_cc_config_params_destroy(cc_params);
09743 return -1;
09744 }
09745
09746 if (base_params) {
09747 ast_cc_copy_config_params(cc_params, base_params);
09748 }
09749 cc_datastore->data = cc_params;
09750 ast_channel_datastore_add(chan, cc_datastore);
09751 return 0;
09752 }
09753
09754 struct ast_cc_config_params *ast_channel_get_cc_config_params(struct ast_channel *chan)
09755 {
09756 struct ast_datastore *cc_datastore;
09757
09758 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09759
09760
09761
09762
09763 if (ast_channel_cc_params_init(chan, NULL)) {
09764 return NULL;
09765 }
09766 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09767
09768 return NULL;
09769 }
09770 }
09771
09772 ast_assert(cc_datastore->data != NULL);
09773 return cc_datastore->data;
09774 }
09775
09776 int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
09777 {
09778 int len = name_buffer_length;
09779 char *dash;
09780 if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) {
09781 return 0;
09782 }
09783
09784
09785 ast_copy_string(device_name, chan->name, name_buffer_length);
09786 if ((dash = strrchr(device_name, '-'))) {
09787 *dash = '\0';
09788 }
09789
09790 return 0;
09791 }
09792
09793 int ast_channel_get_cc_agent_type(struct ast_channel *chan, char *agent_type, size_t size)
09794 {
09795 int len = size;
09796 char *slash;
09797
09798 if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) {
09799 return 0;
09800 }
09801
09802 ast_copy_string(agent_type, chan->name, size);
09803 if ((slash = strchr(agent_type, '/'))) {
09804 *slash = '\0';
09805 }
09806 return 0;
09807 }
09808
09809
09810
09811
09812
09813
09814
09815
09816
09817
09818 #undef ast_channel_alloc
09819 struct ast_channel __attribute__((format(printf, 10, 11)))
09820 *ast_channel_alloc(int needqueue, int state, const char *cid_num,
09821 const char *cid_name, const char *acctcode,
09822 const char *exten, const char *context,
09823 const char *linkedid, const int amaflag,
09824 const char *name_fmt, ...);
09825 struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num,
09826 const char *cid_name, const char *acctcode,
09827 const char *exten, const char *context,
09828 const char *linkedid, const int amaflag,
09829 const char *name_fmt, ...)
09830 {
09831 va_list ap1, ap2;
09832 struct ast_channel *result;
09833
09834
09835 va_start(ap1, name_fmt);
09836 va_start(ap2, name_fmt);
09837 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
09838 linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap1, ap2);
09839 va_end(ap1);
09840 va_end(ap2);
09841
09842 return result;
09843 }