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 original->cdr = clonechan->cdr;
06722 clonechan->cdr = cdr;
06723
06724
06725 for (i = 0; i < 2; i++) {
06726 x = original->alertpipe[i];
06727 original->alertpipe[i] = clonechan->alertpipe[i];
06728 clonechan->alertpipe[i] = x;
06729 }
06730
06731
06732
06733
06734
06735
06736
06737
06738
06739
06740
06741
06742 {
06743 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
06744
06745 AST_LIST_HEAD_INIT_NOLOCK(&tmp_readq);
06746 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
06747 AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list);
06748
06749 while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
06750 AST_LIST_INSERT_TAIL(&original->readq, current, frame_list);
06751 if (original->alertpipe[1] > -1) {
06752 int poke = 0;
06753
06754 if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) {
06755 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
06756 }
06757 }
06758 }
06759 }
06760
06761
06762 tmp_format = original->rawreadformat;
06763 original->rawreadformat = clonechan->rawreadformat;
06764 clonechan->rawreadformat = tmp_format;
06765
06766 tmp_format = original->rawwriteformat;
06767 original->rawwriteformat = clonechan->rawwriteformat;
06768 clonechan->rawwriteformat = tmp_format;
06769
06770 clonechan->_softhangup = AST_SOFTHANGUP_DEV;
06771
06772
06773
06774
06775
06776 origstate = original->_state;
06777 original->_state = clonechan->_state;
06778 clonechan->_state = origstate;
06779
06780
06781
06782 orig_disablestatecache = ast_test_flag(original, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06783 clone_disablestatecache = ast_test_flag(clonechan, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06784 if (orig_disablestatecache != clone_disablestatecache) {
06785 if (orig_disablestatecache) {
06786 ast_clear_flag(original, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06787 ast_set_flag(clonechan, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06788 } else {
06789 ast_set_flag(original, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06790 ast_clear_flag(clonechan, AST_FLAG_DISABLE_DEVSTATE_CACHE);
06791 }
06792 }
06793
06794
06795 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
06796 __ast_change_name_nolink(clonechan, zombn);
06797
06798
06799 t_pvt = original->monitor;
06800 original->monitor = clonechan->monitor;
06801 clonechan->monitor = t_pvt;
06802
06803
06804 ast_string_field_set(original, language, clonechan->language);
06805
06806
06807 ast_string_field_set(original, parkinglot, clonechan->parkinglot);
06808
06809
06810 for (x = 0; x < AST_MAX_FDS; x++) {
06811 if (x != AST_GENERATOR_FD)
06812 ast_channel_set_fd(original, x, clonechan->fds[x]);
06813 }
06814
06815 ast_app_group_update(clonechan, original);
06816
06817
06818 if (AST_LIST_FIRST(&clonechan->datastores)) {
06819 struct ast_datastore *ds;
06820
06821
06822
06823 AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) {
06824 if (ds->info->chan_fixup)
06825 ds->info->chan_fixup(ds->data, clonechan, original);
06826 }
06827 AST_LIST_TRAVERSE_SAFE_END;
06828 AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry);
06829 }
06830
06831 ast_autochan_new_channel(clonechan, original);
06832
06833 clone_variables(original, clonechan);
06834
06835 original->adsicpe = clonechan->adsicpe;
06836
06837
06838
06839
06840
06841 ast_set_flag(original, ast_test_flag(clonechan, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING));
06842 original->fdno = clonechan->fdno;
06843
06844
06845
06846
06847
06848
06849
06850
06851 exchange.dialed = original->dialed;
06852 original->dialed = clonechan->dialed;
06853 clonechan->dialed = exchange.dialed;
06854
06855 exchange.caller = original->caller;
06856 original->caller = clonechan->caller;
06857 clonechan->caller = exchange.caller;
06858
06859 exchange.connected = original->connected;
06860 original->connected = clonechan->connected;
06861 clonechan->connected = exchange.connected;
06862
06863 exchange.redirecting = original->redirecting;
06864 original->redirecting = clonechan->redirecting;
06865 clonechan->redirecting = exchange.redirecting;
06866
06867 report_new_callerid(original);
06868
06869
06870 ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd);
06871
06872
06873 original->nativeformats = clonechan->nativeformats;
06874
06875
06876
06877
06878
06879 ast_set_write_format(original, wformat);
06880
06881
06882 ast_set_read_format(original, rformat);
06883
06884
06885 ast_string_field_set(original, musicclass, clonechan->musicclass);
06886
06887
06888 ast_string_field_set(original, accountcode, S_OR(clonechan->accountcode, ""));
06889 if (original->_bridge) {
06890
06891 ast_string_field_set(original->_bridge, peeraccount, S_OR(clonechan->accountcode, ""));
06892 ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL);
06893 }
06894
06895 ast_debug(1, "Putting channel %s in %s/%s formats\n", original->name,
06896 ast_getformatname(wformat), ast_getformatname(rformat));
06897
06898
06899 if (original->tech->fixup && original->tech->fixup(clonechan, original)) {
06900 ast_log(LOG_WARNING, "Channel type '%s' could not fixup channel %s, strange things may happen. (clonechan)\n",
06901 original->tech->type, original->name);
06902 }
06903
06904
06905 if (clonechan->tech->fixup && clonechan->tech->fixup(original, clonechan)) {
06906 ast_log(LOG_WARNING, "Channel type '%s' could not fixup channel %s, strange things may happen. (original)\n",
06907 clonechan->tech->type, clonechan->name);
06908 }
06909
06910
06911
06912
06913
06914
06915
06916
06917
06918
06919 if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
06920 clone_was_zombie = 1;
06921 } else {
06922 ast_set_flag(clonechan, AST_FLAG_ZOMBIE);
06923 ast_queue_frame(clonechan, &ast_null_frame);
06924 }
06925
06926
06927 original->masq = NULL;
06928 clonechan->masqr = NULL;
06929
06930
06931
06932
06933
06934
06935
06936 ast_channel_unlock(original);
06937
06938
06939 if (clonechan->tech->hangup && clonechan->tech->hangup(clonechan)) {
06940 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n");
06941 } else {
06942
06943
06944
06945
06946
06947 clonechan->tech = &ast_kill_tech;
06948 }
06949
06950 ast_channel_unlock(clonechan);
06951
06952 if (clone_sending_dtmf_digit) {
06953
06954
06955
06956
06957 ast_bridge_end_dtmf(original, clone_sending_dtmf_digit, clone_sending_dtmf_tv,
06958 "masquerade");
06959 }
06960
06961
06962
06963
06964
06965
06966
06967
06968
06969
06970 if (visible_indication) {
06971 ast_indicate(original, visible_indication);
06972 }
06973
06974
06975
06976 if (moh_is_playing) {
06977 ast_moh_start(original, NULL, NULL);
06978 }
06979
06980 ast_channel_lock(original);
06981
06982
06983 if (ast_test_flag(original, AST_FLAG_BLOCKING)) {
06984 pthread_kill(original->blocker, SIGURG);
06985 }
06986
06987 ast_debug(1, "Done Masquerading %s (%u)\n", original->name, original->_state);
06988
06989 if ((bridged = ast_bridged_channel(original))) {
06990 ast_channel_ref(bridged);
06991 ast_channel_unlock(original);
06992 ast_indicate(bridged, AST_CONTROL_SRCCHANGE);
06993 ast_channel_unref(bridged);
06994 } else {
06995 ast_channel_unlock(original);
06996 }
06997 ast_indicate(original, AST_CONTROL_SRCCHANGE);
06998
06999 if (xfer_colp) {
07000
07001
07002
07003
07004
07005 masquerade_colp_transfer(original, xfer_colp);
07006 }
07007
07008 if (xfer_ds) {
07009 ast_datastore_free(xfer_ds);
07010 }
07011
07012 if (clone_was_zombie) {
07013 ast_channel_lock(clonechan);
07014 ast_debug(1, "Destroying channel clone '%s'\n", clonechan->name);
07015 ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup",
07016 "Channel: %s\r\n"
07017 "Uniqueid: %s\r\n"
07018 "Cause: %d\r\n"
07019 "Cause-txt: %s\r\n",
07020 clonechan->name,
07021 clonechan->uniqueid,
07022 clonechan->hangupcause,
07023 ast_cause2str(clonechan->hangupcause)
07024 );
07025 ast_channel_unlock(clonechan);
07026
07027
07028
07029
07030
07031 ast_channel_unref(clonechan);
07032 } else {
07033 ao2_link(channels, clonechan);
07034 }
07035
07036 ao2_link(channels, original);
07037 ao2_unlock(channels);
07038
07039
07040 ast_channel_unref(original);
07041 ast_channel_unref(clonechan);
07042
07043 return 0;
07044 }
07045
07046 void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
07047 {
07048 ast_channel_lock(chan);
07049
07050 if (cid_num) {
07051 chan->caller.id.number.valid = 1;
07052 ast_free(chan->caller.id.number.str);
07053 chan->caller.id.number.str = ast_strdup(cid_num);
07054 }
07055 if (cid_name) {
07056 chan->caller.id.name.valid = 1;
07057 ast_free(chan->caller.id.name.str);
07058 chan->caller.id.name.str = ast_strdup(cid_name);
07059 }
07060 if (cid_ani) {
07061 chan->caller.ani.number.valid = 1;
07062 ast_free(chan->caller.ani.number.str);
07063 chan->caller.ani.number.str = ast_strdup(cid_ani);
07064 }
07065 if (chan->cdr) {
07066 ast_cdr_setcid(chan->cdr, chan);
07067 }
07068
07069 report_new_callerid(chan);
07070
07071 ast_channel_unlock(chan);
07072 }
07073
07074 void ast_channel_set_caller(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
07075 {
07076 if (&chan->caller == caller) {
07077
07078 return;
07079 }
07080
07081 ast_channel_lock(chan);
07082 ast_party_caller_set(&chan->caller, caller, update);
07083 ast_channel_unlock(chan);
07084 }
07085
07086 void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
07087 {
07088 const char *pre_set_number;
07089 const char *pre_set_name;
07090
07091 if (&chan->caller == caller) {
07092
07093 return;
07094 }
07095
07096 ast_channel_lock(chan);
07097 pre_set_number =
07098 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL);
07099 pre_set_name = S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL);
07100 ast_party_caller_set(&chan->caller, caller, update);
07101 if (S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)
07102 != pre_set_number
07103 || S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)
07104 != pre_set_name) {
07105
07106 report_new_callerid(chan);
07107 }
07108 if (chan->cdr) {
07109 ast_cdr_setcid(chan->cdr, chan);
07110 }
07111 ast_channel_unlock(chan);
07112 }
07113
07114 int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
07115 {
07116 int oldstate = chan->_state;
07117 char name[AST_CHANNEL_NAME], *dashptr;
07118
07119 if (oldstate == state)
07120 return 0;
07121
07122 ast_copy_string(name, chan->name, sizeof(name));
07123 if ((dashptr = strrchr(name, '-'))) {
07124 *dashptr = '\0';
07125 }
07126
07127 chan->_state = state;
07128
07129
07130
07131
07132 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, (chan->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), name);
07133
07134
07135 ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate",
07136 "Channel: %s\r\n"
07137 "ChannelState: %u\r\n"
07138 "ChannelStateDesc: %s\r\n"
07139 "CallerIDNum: %s\r\n"
07140 "CallerIDName: %s\r\n"
07141 "ConnectedLineNum: %s\r\n"
07142 "ConnectedLineName: %s\r\n"
07143 "Uniqueid: %s\r\n",
07144 chan->name, chan->_state, ast_state2str(chan->_state),
07145 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
07146 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
07147 S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, ""),
07148 S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, ""),
07149 chan->uniqueid);
07150
07151 return 0;
07152 }
07153
07154
07155 struct ast_channel *ast_bridged_channel(struct ast_channel *chan)
07156 {
07157 struct ast_channel *bridged;
07158 bridged = chan->_bridge;
07159 if (bridged && bridged->tech->bridged_channel)
07160 bridged = bridged->tech->bridged_channel(chan, bridged);
07161 return bridged;
07162 }
07163
07164 static void bridge_playfile(struct ast_channel *chan, struct ast_channel *peer, const char *sound, int remain)
07165 {
07166 int min = 0, sec = 0, check;
07167
07168 check = ast_autoservice_start(peer);
07169 if (check)
07170 return;
07171
07172 if (remain > 0) {
07173 if (remain / 60 > 1) {
07174 min = remain / 60;
07175 sec = remain % 60;
07176 } else {
07177 sec = remain;
07178 }
07179 }
07180
07181 if (!strcmp(sound,"timeleft")) {
07182 ast_stream_and_wait(chan, "vm-youhave", "");
07183 if (min) {
07184 ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL);
07185 ast_stream_and_wait(chan, "queue-minutes", "");
07186 }
07187 if (sec) {
07188 ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL);
07189 ast_stream_and_wait(chan, "queue-seconds", "");
07190 }
07191 } else {
07192 ast_stream_and_wait(chan, sound, "");
07193 }
07194
07195 ast_autoservice_stop(peer);
07196 }
07197
07198 static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct ast_channel *c1,
07199 struct ast_bridge_config *config, struct ast_frame **fo,
07200 struct ast_channel **rc)
07201 {
07202
07203 struct ast_channel *cs[3];
07204 struct ast_frame *f;
07205 enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
07206 format_t o0nativeformats;
07207 format_t o1nativeformats;
07208 int watch_c0_dtmf;
07209 int watch_c1_dtmf;
07210 void *pvt0, *pvt1;
07211
07212 int frame_put_in_jb = 0;
07213 int jb_in_use;
07214 int to;
07215
07216 cs[0] = c0;
07217 cs[1] = c1;
07218 pvt0 = c0->tech_pvt;
07219 pvt1 = c1->tech_pvt;
07220 o0nativeformats = c0->nativeformats;
07221 o1nativeformats = c1->nativeformats;
07222 watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
07223 watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
07224
07225
07226 jb_in_use = ast_jb_do_usecheck(c0, c1);
07227 if (jb_in_use)
07228 ast_jb_empty_and_reset(c0, c1);
07229
07230 ast_poll_channel_add(c0, c1);
07231
07232 if (config->feature_timer > 0 && ast_tvzero(config->nexteventts)) {
07233
07234
07235
07236 config->nexteventts = ast_tvadd(ast_tvnow(), ast_samp2tv(config->feature_timer, 1000));
07237 }
07238
07239 for (;;) {
07240 struct ast_channel *who, *other;
07241
07242 if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
07243 (o0nativeformats != c0->nativeformats) ||
07244 (o1nativeformats != c1->nativeformats)) {
07245
07246 res = AST_BRIDGE_RETRY;
07247 break;
07248 }
07249 if (config->nexteventts.tv_sec) {
07250 to = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
07251 if (to <= 0) {
07252 if (config->timelimit && !config->feature_timer && !ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
07253 res = AST_BRIDGE_RETRY;
07254
07255 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
07256 } else if (config->feature_timer) {
07257
07258 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
07259 res = AST_BRIDGE_RETRY;
07260 } else {
07261 res = AST_BRIDGE_COMPLETE;
07262 }
07263 break;
07264 }
07265 } else {
07266
07267
07268
07269
07270 if (!ast_tvzero(config->nexteventts)) {
07271 int diff = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
07272 if (diff <= 0) {
07273 res = AST_BRIDGE_RETRY;
07274 break;
07275 }
07276 }
07277 to = -1;
07278 }
07279
07280
07281 if (jb_in_use)
07282 to = ast_jb_get_when_to_wakeup(c0, c1, to);
07283 who = ast_waitfor_n(cs, 2, &to);
07284 if (!who) {
07285
07286 if (jb_in_use)
07287 ast_jb_get_and_deliver(c0, c1);
07288 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {
07289 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07290 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
07291 }
07292 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07293 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
07294 }
07295 ast_channel_lock_both(c0, c1);
07296 c0->_bridge = c1;
07297 c1->_bridge = c0;
07298 ast_channel_unlock(c0);
07299 ast_channel_unlock(c1);
07300 }
07301 continue;
07302 }
07303 f = ast_read(who);
07304 if (!f) {
07305 *fo = NULL;
07306 *rc = who;
07307 ast_debug(1, "Didn't get a frame from channel: %s\n",who->name);
07308 break;
07309 }
07310
07311 other = (who == c0) ? c1 : c0;
07312
07313 if (jb_in_use)
07314 frame_put_in_jb = !ast_jb_put(other, f);
07315
07316 if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
07317 int bridge_exit = 0;
07318
07319 switch (f->subclass.integer) {
07320 case AST_CONTROL_AOC:
07321 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07322 break;
07323 case AST_CONTROL_REDIRECTING:
07324 if (ast_channel_redirecting_macro(who, other, f, other == c0, 1)) {
07325 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07326 }
07327 break;
07328 case AST_CONTROL_CONNECTED_LINE:
07329 if (ast_channel_connected_line_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_HOLD:
07334 case AST_CONTROL_UNHOLD:
07335 case AST_CONTROL_VIDUPDATE:
07336 case AST_CONTROL_SRCUPDATE:
07337 case AST_CONTROL_SRCCHANGE:
07338 case AST_CONTROL_T38_PARAMETERS:
07339 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07340 if (jb_in_use) {
07341 ast_jb_empty_and_reset(c0, c1);
07342 }
07343 break;
07344 default:
07345 *fo = f;
07346 *rc = who;
07347 bridge_exit = 1;
07348 ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass.integer, who->name);
07349 break;
07350 }
07351 if (bridge_exit)
07352 break;
07353 }
07354 if ((f->frametype == AST_FRAME_VOICE) ||
07355 (f->frametype == AST_FRAME_DTMF_BEGIN) ||
07356 (f->frametype == AST_FRAME_DTMF) ||
07357 (f->frametype == AST_FRAME_VIDEO) ||
07358 (f->frametype == AST_FRAME_IMAGE) ||
07359 (f->frametype == AST_FRAME_HTML) ||
07360 (f->frametype == AST_FRAME_MODEM) ||
07361 (f->frametype == AST_FRAME_TEXT)) {
07362
07363 int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
07364
07365 if (monitored_source &&
07366 (f->frametype == AST_FRAME_DTMF_END ||
07367 f->frametype == AST_FRAME_DTMF_BEGIN)) {
07368 *fo = f;
07369 *rc = who;
07370 ast_debug(1, "Got DTMF %s on channel (%s)\n",
07371 f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
07372 who->name);
07373
07374 break;
07375 }
07376
07377 if (!frame_put_in_jb)
07378 ast_write(other, f);
07379
07380
07381 if (jb_in_use)
07382 ast_jb_get_and_deliver(c0, c1);
07383 }
07384
07385 ast_frfree(f);
07386
07387 #ifndef HAVE_EPOLL
07388
07389 cs[2] = cs[0];
07390 cs[0] = cs[1];
07391 cs[1] = cs[2];
07392 #endif
07393 }
07394
07395 ast_poll_channel_del(c0, c1);
07396
07397 return res;
07398 }
07399
07400
07401 int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
07402 {
07403
07404 if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge)))
07405 return -1;
07406
07407 return c0->tech->early_bridge(c0, c1);
07408 }
07409
07410
07411
07412
07413
07414
07415
07416 static void manager_bridge_event(int onoff, int type, struct ast_channel *c0, struct ast_channel *c1)
07417 {
07418 struct ast_channel *chans[2] = { c0, c1 };
07419 ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans,
07420 "Bridgestate: %s\r\n"
07421 "Bridgetype: %s\r\n"
07422 "Channel1: %s\r\n"
07423 "Channel2: %s\r\n"
07424 "Uniqueid1: %s\r\n"
07425 "Uniqueid2: %s\r\n"
07426 "CallerID1: %s\r\n"
07427 "CallerID2: %s\r\n",
07428 onoff ? "Link" : "Unlink",
07429 type == 1 ? "core" : "native",
07430 c0->name, c1->name,
07431 c0->uniqueid, c1->uniqueid,
07432 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, ""),
07433 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, ""));
07434 }
07435
07436 static void update_bridge_vars(struct ast_channel *c0, struct ast_channel *c1)
07437 {
07438 const char *c0_name;
07439 const char *c1_name;
07440 const char *c0_pvtid = NULL;
07441 const char *c1_pvtid = NULL;
07442
07443 ast_channel_lock(c1);
07444 c1_name = ast_strdupa(c1->name);
07445 if (c1->tech->get_pvt_uniqueid) {
07446 c1_pvtid = ast_strdupa(c1->tech->get_pvt_uniqueid(c1));
07447 }
07448 ast_channel_unlock(c1);
07449
07450 ast_channel_lock(c0);
07451 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) {
07452 pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name);
07453 }
07454 if (c1_pvtid) {
07455 pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1_pvtid);
07456 }
07457 c0_name = ast_strdupa(c0->name);
07458 if (c0->tech->get_pvt_uniqueid) {
07459 c0_pvtid = ast_strdupa(c0->tech->get_pvt_uniqueid(c0));
07460 }
07461 ast_channel_unlock(c0);
07462
07463 ast_channel_lock(c1);
07464 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) {
07465 pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name);
07466 }
07467 if (c0_pvtid) {
07468 pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0_pvtid);
07469 }
07470 ast_channel_unlock(c1);
07471 }
07472
07473 static void bridge_play_sounds(struct ast_channel *c0, struct ast_channel *c1)
07474 {
07475 const char *s, *sound;
07476
07477
07478
07479 ast_channel_lock(c0);
07480 if ((s = pbx_builtin_getvar_helper(c0, "BRIDGE_PLAY_SOUND"))) {
07481 sound = ast_strdupa(s);
07482 ast_channel_unlock(c0);
07483 bridge_playfile(c0, c1, sound, 0);
07484 pbx_builtin_setvar_helper(c0, "BRIDGE_PLAY_SOUND", NULL);
07485 } else {
07486 ast_channel_unlock(c0);
07487 }
07488
07489 ast_channel_lock(c1);
07490 if ((s = pbx_builtin_getvar_helper(c1, "BRIDGE_PLAY_SOUND"))) {
07491 sound = ast_strdupa(s);
07492 ast_channel_unlock(c1);
07493 bridge_playfile(c1, c0, sound, 0);
07494 pbx_builtin_setvar_helper(c1, "BRIDGE_PLAY_SOUND", NULL);
07495 } else {
07496 ast_channel_unlock(c1);
07497 }
07498 }
07499
07500
07501 enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1,
07502 struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
07503 {
07504 struct ast_channel *chans[2] = { c0, c1 };
07505 enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
07506 format_t o0nativeformats;
07507 format_t o1nativeformats;
07508 long time_left_ms=0;
07509 char caller_warning = 0;
07510 char callee_warning = 0;
07511
07512 *fo = NULL;
07513
07514 if (c0->_bridge) {
07515 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07516 c0->name, c0->_bridge->name);
07517 return -1;
07518 }
07519 if (c1->_bridge) {
07520 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07521 c1->name, c1->_bridge->name);
07522 return -1;
07523 }
07524
07525
07526 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07527 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
07528 return -1;
07529
07530 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
07531 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
07532
07533 if (ast_tvzero(config->start_time)) {
07534 config->start_time = ast_tvnow();
07535 if (config->start_sound) {
07536 if (caller_warning) {
07537 bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000);
07538 }
07539 if (callee_warning) {
07540 bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000);
07541 }
07542 }
07543 }
07544
07545
07546 ast_channel_lock_both(c0, c1);
07547 c0->_bridge = c1;
07548 c1->_bridge = c0;
07549 ast_channel_unlock(c0);
07550 ast_channel_unlock(c1);
07551
07552 ast_set_owners_and_peers(c0, c1);
07553
07554 o0nativeformats = c0->nativeformats;
07555 o1nativeformats = c1->nativeformats;
07556
07557 if (config->feature_timer && !ast_tvzero(config->nexteventts)) {
07558 config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000));
07559 } else if (config->timelimit) {
07560 time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time);
07561 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07562 if ((caller_warning || callee_warning) && config->play_warning) {
07563 long next_warn = config->play_warning;
07564 if (time_left_ms < config->play_warning && config->warning_freq > 0) {
07565
07566 long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq;
07567
07568
07569 next_warn = config->play_warning - warns_passed * config->warning_freq;
07570 }
07571 config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000));
07572 }
07573 } else {
07574 config->nexteventts.tv_sec = 0;
07575 config->nexteventts.tv_usec = 0;
07576 }
07577
07578 if (!c0->tech->send_digit_begin)
07579 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
07580 if (!c1->tech->send_digit_begin)
07581 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
07582 manager_bridge_event(1, 1, c0, c1);
07583
07584
07585 ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07586 ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07587
07588 for (;;) {
07589 struct timeval now = { 0, };
07590 int to;
07591
07592 to = -1;
07593
07594 if (!ast_tvzero(config->nexteventts)) {
07595 now = ast_tvnow();
07596 to = ast_tvdiff_ms(config->nexteventts, now);
07597 if (to <= 0) {
07598 if (!config->timelimit) {
07599 res = AST_BRIDGE_COMPLETE;
07600 break;
07601 }
07602 to = 0;
07603 }
07604 }
07605
07606 if (config->timelimit) {
07607 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
07608 if (time_left_ms < 0) {
07609 time_left_ms = 0;
07610 }
07611
07612 if (time_left_ms < to) {
07613 to = time_left_ms;
07614 }
07615
07616 if (time_left_ms <= 0) {
07617 if (caller_warning && config->end_sound)
07618 bridge_playfile(c0, c1, config->end_sound, 0);
07619 if (callee_warning && config->end_sound)
07620 bridge_playfile(c1, c0, config->end_sound, 0);
07621 *fo = NULL;
07622 res = AST_BRIDGE_COMPLETE;
07623 ast_test_suite_event_notify("BRIDGE_TIMELIMIT", "Channel1: %s\r\nChannel2: %s", c0->name, c1->name);
07624 break;
07625 }
07626
07627 if (!to) {
07628 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
07629 int t = (time_left_ms + 500) / 1000;
07630 if (caller_warning)
07631 bridge_playfile(c0, c1, config->warning_sound, t);
07632 if (callee_warning)
07633 bridge_playfile(c1, c0, config->warning_sound, t);
07634 }
07635
07636 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) {
07637 config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000));
07638 } else {
07639 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07640 }
07641 }
07642 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
07643 }
07644
07645 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {
07646 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07647 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
07648 }
07649 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07650 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
07651 }
07652 ast_channel_lock_both(c0, c1);
07653 c0->_bridge = c1;
07654 c1->_bridge = c0;
07655 ast_channel_unlock(c0);
07656 ast_channel_unlock(c1);
07657 ast_debug(1, "Unbridge signal received. Ending native bridge.\n");
07658 continue;
07659 }
07660
07661
07662 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07663 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
07664 *fo = NULL;
07665 res = AST_BRIDGE_COMPLETE;
07666 ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
07667 c0->name, c1->name,
07668 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
07669 ast_check_hangup(c0) ? "Yes" : "No",
07670 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
07671 ast_check_hangup(c1) ? "Yes" : "No");
07672 break;
07673 }
07674
07675 update_bridge_vars(c0, c1);
07676
07677 bridge_play_sounds(c0, c1);
07678
07679 if (c0->tech->bridge &&
07680
07681 (!config->timelimit || to > 1000 || to == -1) &&
07682 (c0->tech->bridge == c1->tech->bridge) &&
07683 !c0->monitor && !c1->monitor &&
07684 !c0->audiohooks && !c1->audiohooks &&
07685 ast_framehook_list_is_empty(c0->framehooks) && ast_framehook_list_is_empty(c1->framehooks) &&
07686 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
07687 int timeoutms = to - 1000 > 0 ? to - 1000 : to;
07688
07689 ast_set_flag(c0, AST_FLAG_NBRIDGE);
07690 ast_set_flag(c1, AST_FLAG_NBRIDGE);
07691 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) {
07692 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
07693 "Channel1: %s\r\n"
07694 "Channel2: %s\r\n"
07695 "Uniqueid1: %s\r\n"
07696 "Uniqueid2: %s\r\n"
07697 "CallerID1: %s\r\n"
07698 "CallerID2: %s\r\n",
07699 c0->name, c1->name,
07700 c0->uniqueid, c1->uniqueid,
07701 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"),
07702 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
07703
07704 ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
07705
07706 ast_clear_flag(c0, AST_FLAG_NBRIDGE);
07707 ast_clear_flag(c1, AST_FLAG_NBRIDGE);
07708
07709 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {
07710 continue;
07711 }
07712
07713 ast_channel_lock_both(c0, c1);
07714 c0->_bridge = NULL;
07715 c1->_bridge = NULL;
07716 ast_channel_unlock(c0);
07717 ast_channel_unlock(c1);
07718 return res;
07719 } else {
07720 ast_clear_flag(c0, AST_FLAG_NBRIDGE);
07721 ast_clear_flag(c1, AST_FLAG_NBRIDGE);
07722 }
07723 switch (res) {
07724 case AST_BRIDGE_RETRY:
07725 if (config->play_warning) {
07726 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
07727 }
07728 continue;
07729 default:
07730 ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name);
07731
07732 case AST_BRIDGE_FAILED_NOWARN:
07733 break;
07734 }
07735 }
07736
07737 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
07738 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
07739 !(c0->generator || c1->generator)) {
07740 if (ast_channel_make_compatible(c0, c1)) {
07741 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
07742 manager_bridge_event(0, 1, c0, c1);
07743 return AST_BRIDGE_FAILED;
07744 }
07745 o0nativeformats = c0->nativeformats;
07746 o1nativeformats = c1->nativeformats;
07747 }
07748
07749 update_bridge_vars(c0, c1);
07750
07751 res = ast_generic_bridge(c0, c1, config, fo, rc);
07752 if (res != AST_BRIDGE_RETRY) {
07753 break;
07754 } else if (config->feature_timer) {
07755
07756 break;
07757 }
07758 }
07759
07760 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
07761 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
07762
07763
07764 ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07765 ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07766
07767 ast_channel_lock_both(c0, c1);
07768 c0->_bridge = NULL;
07769 c1->_bridge = NULL;
07770 ast_channel_unlock(c0);
07771 ast_channel_unlock(c1);
07772
07773 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
07774 "Channel1: %s\r\n"
07775 "Channel2: %s\r\n"
07776 "Uniqueid1: %s\r\n"
07777 "Uniqueid2: %s\r\n"
07778 "CallerID1: %s\r\n"
07779 "CallerID2: %s\r\n",
07780 c0->name, c1->name,
07781 c0->uniqueid, c1->uniqueid,
07782 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"),
07783 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
07784 ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
07785
07786 return res;
07787 }
07788
07789
07790 int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
07791 {
07792 int res;
07793
07794 ast_channel_lock(chan);
07795 if (!chan->tech->setoption) {
07796 errno = ENOSYS;
07797 ast_channel_unlock(chan);
07798 return -1;
07799 }
07800
07801 if (block)
07802 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07803
07804 res = chan->tech->setoption(chan, option, data, datalen);
07805 ast_channel_unlock(chan);
07806
07807 return res;
07808 }
07809
07810 int ast_channel_queryoption(struct ast_channel *chan, int option, void *data, int *datalen, int block)
07811 {
07812 int res;
07813
07814 ast_channel_lock(chan);
07815 if (!chan->tech->queryoption) {
07816 errno = ENOSYS;
07817 ast_channel_unlock(chan);
07818 return -1;
07819 }
07820
07821 if (block)
07822 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07823
07824 res = chan->tech->queryoption(chan, option, data, datalen);
07825 ast_channel_unlock(chan);
07826
07827 return res;
07828 }
07829
07830 struct tonepair_def {
07831 int freq1;
07832 int freq2;
07833 int duration;
07834 int vol;
07835 };
07836
07837 struct tonepair_state {
07838 int fac1;
07839 int fac2;
07840 int v1_1;
07841 int v2_1;
07842 int v3_1;
07843 int v1_2;
07844 int v2_2;
07845 int v3_2;
07846 format_t origwfmt;
07847 int pos;
07848 int duration;
07849 int modulate;
07850 struct ast_frame f;
07851 unsigned char offset[AST_FRIENDLY_OFFSET];
07852 short data[4000];
07853 };
07854
07855 static void tonepair_release(struct ast_channel *chan, void *params)
07856 {
07857 struct tonepair_state *ts = params;
07858
07859 if (chan)
07860 ast_set_write_format(chan, ts->origwfmt);
07861 ast_free(ts);
07862 }
07863
07864 static void *tonepair_alloc(struct ast_channel *chan, void *params)
07865 {
07866 struct tonepair_state *ts;
07867 struct tonepair_def *td = params;
07868
07869 if (!(ts = ast_calloc(1, sizeof(*ts))))
07870 return NULL;
07871 ts->origwfmt = chan->writeformat;
07872 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
07873 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
07874 tonepair_release(NULL, ts);
07875 ts = NULL;
07876 } else {
07877 ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
07878 ts->v1_1 = 0;
07879 ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07880 ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07881 ts->v2_1 = 0;
07882 ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
07883 ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07884 ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07885 ts->duration = td->duration;
07886 ts->modulate = 0;
07887 }
07888
07889 ast_set_flag(chan, AST_FLAG_WRITE_INT);
07890 return ts;
07891 }
07892
07893 static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples)
07894 {
07895 struct tonepair_state *ts = data;
07896 int x;
07897
07898
07899
07900
07901 len = samples * 2;
07902
07903 if (len > sizeof(ts->data) / 2 - 1) {
07904 ast_log(LOG_WARNING, "Can't generate that much data!\n");
07905 return -1;
07906 }
07907 memset(&ts->f, 0, sizeof(ts->f));
07908 for (x=0;x<len/2;x++) {
07909 ts->v1_1 = ts->v2_1;
07910 ts->v2_1 = ts->v3_1;
07911 ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
07912
07913 ts->v1_2 = ts->v2_2;
07914 ts->v2_2 = ts->v3_2;
07915 ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
07916 if (ts->modulate) {
07917 int p;
07918 p = ts->v3_2 - 32768;
07919 if (p < 0) p = -p;
07920 p = ((p * 9) / 10) + 1;
07921 ts->data[x] = (ts->v3_1 * p) >> 15;
07922 } else
07923 ts->data[x] = ts->v3_1 + ts->v3_2;
07924 }
07925 ts->f.frametype = AST_FRAME_VOICE;
07926 ts->f.subclass.codec = AST_FORMAT_SLINEAR;
07927 ts->f.datalen = len;
07928 ts->f.samples = samples;
07929 ts->f.offset = AST_FRIENDLY_OFFSET;
07930 ts->f.data.ptr = ts->data;
07931 ast_write(chan, &ts->f);
07932 ts->pos += x;
07933 if (ts->duration > 0) {
07934 if (ts->pos >= ts->duration * 8)
07935 return -1;
07936 }
07937 return 0;
07938 }
07939
07940 static struct ast_generator tonepair = {
07941 .alloc = tonepair_alloc,
07942 .release = tonepair_release,
07943 .generate = tonepair_generator,
07944 };
07945
07946 int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
07947 {
07948 struct tonepair_def d = { 0, };
07949
07950 d.freq1 = freq1;
07951 d.freq2 = freq2;
07952 d.duration = duration;
07953 d.vol = (vol < 1) ? 8192 : vol;
07954 if (ast_activate_generator(chan, &tonepair, &d))
07955 return -1;
07956 return 0;
07957 }
07958
07959 void ast_tonepair_stop(struct ast_channel *chan)
07960 {
07961 ast_deactivate_generator(chan);
07962 }
07963
07964 int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
07965 {
07966 int res;
07967
07968 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
07969 return res;
07970
07971
07972 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
07973 struct ast_frame *f = ast_read(chan);
07974 if (f)
07975 ast_frfree(f);
07976 else
07977 return -1;
07978 }
07979 return 0;
07980 }
07981
07982 ast_group_t ast_get_group(const char *s)
07983 {
07984 char *piece;
07985 char *c;
07986 int start=0, finish=0, x;
07987 ast_group_t group = 0;
07988
07989 if (ast_strlen_zero(s))
07990 return 0;
07991
07992 c = ast_strdupa(s);
07993
07994 while ((piece = strsep(&c, ","))) {
07995 if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) {
07996
07997 } else if (sscanf(piece, "%30d", &start)) {
07998
07999 finish = start;
08000 } else {
08001 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
08002 continue;
08003 }
08004 for (x = start; x <= finish; x++) {
08005 if ((x > 63) || (x < 0)) {
08006 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
08007 } else
08008 group |= ((ast_group_t) 1 << x);
08009 }
08010 }
08011 return group;
08012 }
08013
08014 static int (*ast_moh_start_ptr)(struct ast_channel *, const char *, const char *) = NULL;
08015 static void (*ast_moh_stop_ptr)(struct ast_channel *) = NULL;
08016 static void (*ast_moh_cleanup_ptr)(struct ast_channel *) = NULL;
08017
08018 void ast_install_music_functions(int (*start_ptr)(struct ast_channel *, const char *, const char *),
08019 void (*stop_ptr)(struct ast_channel *),
08020 void (*cleanup_ptr)(struct ast_channel *))
08021 {
08022 ast_moh_start_ptr = start_ptr;
08023 ast_moh_stop_ptr = stop_ptr;
08024 ast_moh_cleanup_ptr = cleanup_ptr;
08025 }
08026
08027 void ast_uninstall_music_functions(void)
08028 {
08029 ast_moh_start_ptr = NULL;
08030 ast_moh_stop_ptr = NULL;
08031 ast_moh_cleanup_ptr = NULL;
08032 }
08033
08034
08035 int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
08036 {
08037 if (ast_moh_start_ptr)
08038 return ast_moh_start_ptr(chan, mclass, interpclass);
08039
08040 ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default"));
08041
08042 return 0;
08043 }
08044
08045
08046 void ast_moh_stop(struct ast_channel *chan)
08047 {
08048 if (ast_moh_stop_ptr)
08049 ast_moh_stop_ptr(chan);
08050 }
08051
08052 void ast_moh_cleanup(struct ast_channel *chan)
08053 {
08054 if (ast_moh_cleanup_ptr)
08055 ast_moh_cleanup_ptr(chan);
08056 }
08057
08058 static int ast_channel_hash_cb(const void *obj, const int flags)
08059 {
08060 const struct ast_channel *chan = obj;
08061
08062
08063
08064 if (ast_strlen_zero(chan->name)) {
08065 return 0;
08066 }
08067
08068 return ast_str_case_hash(chan->name);
08069 }
08070
08071 int ast_plc_reload(void)
08072 {
08073 struct ast_variable *var;
08074 struct ast_flags config_flags = { 0 };
08075 struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
08076 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
08077 return 0;
08078 for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
08079 if (!strcasecmp(var->name, "genericplc")) {
08080 ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC);
08081 }
08082 }
08083 ast_config_destroy(cfg);
08084 return 0;
08085 }
08086
08087
08088
08089
08090
08091 static int data_channels_provider_handler(const struct ast_data_search *search,
08092 struct ast_data *root)
08093 {
08094 struct ast_channel *c;
08095 struct ast_channel_iterator *iter = NULL;
08096 struct ast_data *data_channel;
08097
08098 for (iter = ast_channel_iterator_all_new();
08099 iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
08100 ast_channel_lock(c);
08101
08102 data_channel = ast_data_add_node(root, "channel");
08103 if (!data_channel) {
08104 ast_channel_unlock(c);
08105 continue;
08106 }
08107
08108 if (ast_channel_data_add_structure(data_channel, c, 1) < 0) {
08109 ast_log(LOG_ERROR, "Unable to add channel structure for channel: %s\n", c->name);
08110 }
08111
08112 ast_channel_unlock(c);
08113
08114 if (!ast_data_search_match(search, data_channel)) {
08115 ast_data_remove_node(root, data_channel);
08116 }
08117 }
08118 if (iter) {
08119 ast_channel_iterator_destroy(iter);
08120 }
08121
08122 return 0;
08123 }
08124
08125
08126
08127
08128
08129 static int data_channeltypes_provider_handler(const struct ast_data_search *search,
08130 struct ast_data *data_root)
08131 {
08132 struct chanlist *cl;
08133 struct ast_data *data_type;
08134
08135 AST_RWLIST_RDLOCK(&backends);
08136 AST_RWLIST_TRAVERSE(&backends, cl, list) {
08137 data_type = ast_data_add_node(data_root, "type");
08138 if (!data_type) {
08139 continue;
08140 }
08141 ast_data_add_str(data_type, "name", cl->tech->type);
08142 ast_data_add_str(data_type, "description", cl->tech->description);
08143 ast_data_add_bool(data_type, "devicestate", cl->tech->devicestate ? 1 : 0);
08144 ast_data_add_bool(data_type, "indications", cl->tech->indicate ? 1 : 0);
08145 ast_data_add_bool(data_type, "transfer", cl->tech->transfer ? 1 : 0);
08146 ast_data_add_bool(data_type, "send_digit_begin", cl->tech->send_digit_begin ? 1 : 0);
08147 ast_data_add_bool(data_type, "send_digit_end", cl->tech->send_digit_end ? 1 : 0);
08148 ast_data_add_bool(data_type, "call", cl->tech->call ? 1 : 0);
08149 ast_data_add_bool(data_type, "hangup", cl->tech->hangup ? 1 : 0);
08150 ast_data_add_bool(data_type, "answer", cl->tech->answer ? 1 : 0);
08151 ast_data_add_bool(data_type, "read", cl->tech->read ? 1 : 0);
08152 ast_data_add_bool(data_type, "write", cl->tech->write ? 1 : 0);
08153 ast_data_add_bool(data_type, "send_text", cl->tech->send_text ? 1 : 0);
08154 ast_data_add_bool(data_type, "send_image", cl->tech->send_image ? 1 : 0);
08155 ast_data_add_bool(data_type, "send_html", cl->tech->send_html ? 1 : 0);
08156 ast_data_add_bool(data_type, "exception", cl->tech->exception ? 1 : 0);
08157 ast_data_add_bool(data_type, "bridge", cl->tech->bridge ? 1 : 0);
08158 ast_data_add_bool(data_type, "early_bridge", cl->tech->early_bridge ? 1 : 0);
08159 ast_data_add_bool(data_type, "fixup", cl->tech->fixup ? 1 : 0);
08160 ast_data_add_bool(data_type, "setoption", cl->tech->setoption ? 1 : 0);
08161 ast_data_add_bool(data_type, "queryoption", cl->tech->queryoption ? 1 : 0);
08162 ast_data_add_bool(data_type, "write_video", cl->tech->write_video ? 1 : 0);
08163 ast_data_add_bool(data_type, "write_text", cl->tech->write_text ? 1 : 0);
08164 ast_data_add_bool(data_type, "bridged_channel", cl->tech->bridged_channel ? 1 : 0);
08165 ast_data_add_bool(data_type, "func_channel_read", cl->tech->func_channel_read ? 1 : 0);
08166 ast_data_add_bool(data_type, "func_channel_write", cl->tech->func_channel_write ? 1 : 0);
08167 ast_data_add_bool(data_type, "get_base_channel", cl->tech->get_base_channel ? 1 : 0);
08168 ast_data_add_bool(data_type, "set_base_channel", cl->tech->set_base_channel ? 1 : 0);
08169 ast_data_add_bool(data_type, "get_pvt_uniqueid", cl->tech->get_pvt_uniqueid ? 1 : 0);
08170 ast_data_add_bool(data_type, "cc_callback", cl->tech->cc_callback ? 1 : 0);
08171
08172 ast_data_add_codecs(data_type, "capabilities", cl->tech->capabilities);
08173
08174 if (!ast_data_search_match(search, data_type)) {
08175 ast_data_remove_node(data_root, data_type);
08176 }
08177 }
08178 AST_RWLIST_UNLOCK(&backends);
08179
08180 return 0;
08181 }
08182
08183
08184
08185
08186
08187 static const struct ast_data_handler channels_provider = {
08188 .version = AST_DATA_HANDLER_VERSION,
08189 .get = data_channels_provider_handler
08190 };
08191
08192
08193
08194
08195
08196 static const struct ast_data_handler channeltypes_provider = {
08197 .version = AST_DATA_HANDLER_VERSION,
08198 .get = data_channeltypes_provider_handler
08199 };
08200
08201 static const struct ast_data_entry channel_providers[] = {
08202 AST_DATA_ENTRY("/asterisk/core/channels", &channels_provider),
08203 AST_DATA_ENTRY("/asterisk/core/channeltypes", &channeltypes_provider),
08204 };
08205
08206 static void channels_shutdown(void)
08207 {
08208 ast_data_unregister(NULL);
08209 ast_cli_unregister_multiple(cli_channel, ARRAY_LEN(cli_channel));
08210 if (channels) {
08211 ao2_ref(channels, -1);
08212 channels = NULL;
08213 }
08214 }
08215
08216 void ast_channels_init(void)
08217 {
08218 channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS,
08219 ast_channel_hash_cb, ast_channel_cmp_cb);
08220
08221 ast_cli_register_multiple(cli_channel, ARRAY_LEN(cli_channel));
08222
08223 ast_data_register_multiple_core(channel_providers, ARRAY_LEN(channel_providers));
08224
08225 ast_plc_reload();
08226
08227 ast_register_atexit(channels_shutdown);
08228 }
08229
08230
08231 char *ast_print_group(char *buf, int buflen, ast_group_t group)
08232 {
08233 unsigned int i;
08234 int first = 1;
08235 char num[3];
08236
08237 buf[0] = '\0';
08238
08239 if (!group)
08240 return buf;
08241
08242 for (i = 0; i <= 63; i++) {
08243 if (group & ((ast_group_t) 1 << i)) {
08244 if (!first) {
08245 strncat(buf, ", ", buflen - strlen(buf) - 1);
08246 } else {
08247 first = 0;
08248 }
08249 snprintf(num, sizeof(num), "%u", i);
08250 strncat(buf, num, buflen - strlen(buf) - 1);
08251 }
08252 }
08253 return buf;
08254 }
08255
08256 void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
08257 {
08258 struct ast_variable *cur;
08259
08260 for (cur = vars; cur; cur = cur->next)
08261 pbx_builtin_setvar_helper(chan, cur->name, cur->value);
08262 }
08263
08264 static void *silence_generator_alloc(struct ast_channel *chan, void *data)
08265 {
08266
08267 return data;
08268 }
08269
08270 static void silence_generator_release(struct ast_channel *chan, void *data)
08271 {
08272
08273 }
08274
08275 static int silence_generator_generate(struct ast_channel *chan, void *data, int len, int samples)
08276 {
08277 short buf[samples];
08278 struct ast_frame frame = {
08279 .frametype = AST_FRAME_VOICE,
08280 .subclass.codec = AST_FORMAT_SLINEAR,
08281 .data.ptr = buf,
08282 .samples = samples,
08283 .datalen = sizeof(buf),
08284 };
08285
08286 memset(buf, 0, sizeof(buf));
08287
08288 if (ast_write(chan, &frame))
08289 return -1;
08290
08291 return 0;
08292 }
08293
08294 static struct ast_generator silence_generator = {
08295 .alloc = silence_generator_alloc,
08296 .release = silence_generator_release,
08297 .generate = silence_generator_generate,
08298 };
08299
08300 struct ast_silence_generator {
08301 int old_write_format;
08302 };
08303
08304 struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan)
08305 {
08306 struct ast_silence_generator *state;
08307
08308 if (!(state = ast_calloc(1, sizeof(*state)))) {
08309 return NULL;
08310 }
08311
08312 state->old_write_format = chan->writeformat;
08313
08314 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
08315 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
08316 ast_free(state);
08317 return NULL;
08318 }
08319
08320 ast_activate_generator(chan, &silence_generator, state);
08321
08322 ast_debug(1, "Started silence generator on '%s'\n", chan->name);
08323
08324 return state;
08325 }
08326
08327 static int deactivate_silence_generator(struct ast_channel *chan)
08328 {
08329 ast_channel_lock(chan);
08330
08331 if (!chan->generatordata) {
08332 ast_debug(1, "Trying to stop silence generator when there is no generator on '%s'\n",
08333 chan->name);
08334 ast_channel_unlock(chan);
08335 return 0;
08336 }
08337 if (chan->generator != &silence_generator) {
08338 ast_debug(1, "Trying to stop silence generator when it is not the current generator on '%s'\n",
08339 chan->name);
08340 ast_channel_unlock(chan);
08341 return 0;
08342 }
08343 deactivate_generator_nolock(chan);
08344
08345 ast_channel_unlock(chan);
08346
08347 return 1;
08348 }
08349
08350 void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
08351 {
08352 if (!state) {
08353 return;
08354 }
08355
08356 if (deactivate_silence_generator(chan)) {
08357 ast_debug(1, "Stopped silence generator on '%s'\n", chan->name);
08358
08359 if (ast_set_write_format(chan, state->old_write_format) < 0)
08360 ast_log(LOG_ERROR, "Could not return write format to its original state\n");
08361 }
08362 ast_free(state);
08363 }
08364
08365
08366
08367 const char *channelreloadreason2txt(enum channelreloadreason reason)
08368 {
08369 switch (reason) {
08370 case CHANNEL_MODULE_LOAD:
08371 return "LOAD (Channel module load)";
08372
08373 case CHANNEL_MODULE_RELOAD:
08374 return "RELOAD (Channel module reload)";
08375
08376 case CHANNEL_CLI_RELOAD:
08377 return "CLIRELOAD (Channel module reload by CLI command)";
08378
08379 default:
08380 return "MANAGERRELOAD (Channel module reload by manager)";
08381 }
08382 };
08383
08384
08385
08386
08387
08388
08389
08390
08391
08392 int ast_say_number(struct ast_channel *chan, int num,
08393 const char *ints, const char *language, const char *options)
08394 {
08395 return ast_say_number_full(chan, num, ints, language, options, -1, -1);
08396 }
08397
08398 int ast_say_enumeration(struct ast_channel *chan, int num,
08399 const char *ints, const char *language, const char *options)
08400 {
08401 return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
08402 }
08403
08404 int ast_say_digits(struct ast_channel *chan, int num,
08405 const char *ints, const char *lang)
08406 {
08407 return ast_say_digits_full(chan, num, ints, lang, -1, -1);
08408 }
08409
08410 int ast_say_digit_str(struct ast_channel *chan, const char *str,
08411 const char *ints, const char *lang)
08412 {
08413 return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
08414 }
08415
08416 int ast_say_character_str(struct ast_channel *chan, const char *str,
08417 const char *ints, const char *lang)
08418 {
08419 return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
08420 }
08421
08422 int ast_say_phonetic_str(struct ast_channel *chan, const char *str,
08423 const char *ints, const char *lang)
08424 {
08425 return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
08426 }
08427
08428 int ast_say_digits_full(struct ast_channel *chan, int num,
08429 const char *ints, const char *lang, int audiofd, int ctrlfd)
08430 {
08431 char buf[256];
08432
08433 snprintf(buf, sizeof(buf), "%d", num);
08434
08435 return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
08436 }
08437
08438 void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
08439 {
08440 ast_party_id_copy(&dest->id, &src->id);
08441 ast_party_id_copy(&dest->ani, &src->ani);
08442 dest->ani2 = src->ani2;
08443 }
08444
08445 void ast_connected_line_copy_to_caller(struct ast_party_caller *dest, const struct ast_party_connected_line *src)
08446 {
08447 ast_party_id_copy(&dest->id, &src->id);
08448 ast_party_id_copy(&dest->ani, &src->ani);
08449
08450 dest->ani2 = src->ani2;
08451 }
08452
08453 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)
08454 {
08455 if (&chan->connected == connected) {
08456
08457 return;
08458 }
08459
08460 ast_channel_lock(chan);
08461 ast_party_connected_line_set(&chan->connected, connected, update);
08462 ast_channel_unlock(chan);
08463 }
08464
08465
08466 struct ast_party_name_ies {
08467
08468 int str;
08469
08470 int char_set;
08471
08472 int presentation;
08473
08474 int valid;
08475 };
08476
08477
08478
08479
08480
08481
08482
08483
08484
08485
08486
08487
08488
08489
08490
08491 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)
08492 {
08493 size_t length;
08494 size_t pos = 0;
08495
08496
08497
08498
08499
08500 if (name->str) {
08501 length = strlen(name->str);
08502 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08503 ast_log(LOG_WARNING, "No space left for %s name\n", label);
08504 return -1;
08505 }
08506 data[pos++] = ies->str;
08507 data[pos++] = length;
08508 memcpy(data + pos, name->str, length);
08509 pos += length;
08510 }
08511
08512 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08513 ast_log(LOG_WARNING, "No space left for %s name char set\n", label);
08514 return -1;
08515 }
08516 data[pos++] = ies->char_set;
08517 data[pos++] = 1;
08518 data[pos++] = name->char_set;
08519
08520 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08521 ast_log(LOG_WARNING, "No space left for %s name presentation\n", label);
08522 return -1;
08523 }
08524 data[pos++] = ies->presentation;
08525 data[pos++] = 1;
08526 data[pos++] = name->presentation;
08527
08528 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08529 ast_log(LOG_WARNING, "No space left for %s name valid\n", label);
08530 return -1;
08531 }
08532 data[pos++] = ies->valid;
08533 data[pos++] = 1;
08534 data[pos++] = name->valid;
08535
08536 return pos;
08537 }
08538
08539
08540 struct ast_party_number_ies {
08541
08542 int str;
08543
08544 int plan;
08545
08546 int presentation;
08547
08548 int valid;
08549 };
08550
08551
08552
08553
08554
08555
08556
08557
08558
08559
08560
08561
08562
08563
08564
08565 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)
08566 {
08567 size_t length;
08568 size_t pos = 0;
08569
08570
08571
08572
08573
08574 if (number->str) {
08575 length = strlen(number->str);
08576 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08577 ast_log(LOG_WARNING, "No space left for %s number\n", label);
08578 return -1;
08579 }
08580 data[pos++] = ies->str;
08581 data[pos++] = length;
08582 memcpy(data + pos, number->str, length);
08583 pos += length;
08584 }
08585
08586 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08587 ast_log(LOG_WARNING, "No space left for %s numbering plan\n", label);
08588 return -1;
08589 }
08590 data[pos++] = ies->plan;
08591 data[pos++] = 1;
08592 data[pos++] = number->plan;
08593
08594 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08595 ast_log(LOG_WARNING, "No space left for %s number presentation\n", label);
08596 return -1;
08597 }
08598 data[pos++] = ies->presentation;
08599 data[pos++] = 1;
08600 data[pos++] = number->presentation;
08601
08602 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08603 ast_log(LOG_WARNING, "No space left for %s number valid\n", label);
08604 return -1;
08605 }
08606 data[pos++] = ies->valid;
08607 data[pos++] = 1;
08608 data[pos++] = number->valid;
08609
08610 return pos;
08611 }
08612
08613
08614 struct ast_party_subaddress_ies {
08615
08616 int str;
08617
08618 int type;
08619
08620 int odd_even_indicator;
08621
08622 int valid;
08623 };
08624
08625
08626
08627
08628
08629
08630
08631
08632
08633
08634
08635
08636
08637
08638
08639 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)
08640 {
08641 size_t length;
08642 size_t pos = 0;
08643
08644
08645
08646
08647
08648 if (subaddress->str) {
08649 length = strlen(subaddress->str);
08650 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08651 ast_log(LOG_WARNING, "No space left for %s subaddress\n", label);
08652 return -1;
08653 }
08654 data[pos++] = ies->str;
08655 data[pos++] = length;
08656 memcpy(data + pos, subaddress->str, length);
08657 pos += length;
08658 }
08659
08660 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08661 ast_log(LOG_WARNING, "No space left for %s type of subaddress\n", label);
08662 return -1;
08663 }
08664 data[pos++] = ies->type;
08665 data[pos++] = 1;
08666 data[pos++] = subaddress->type;
08667
08668 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08669 ast_log(LOG_WARNING,
08670 "No space left for %s subaddress odd-even indicator\n", label);
08671 return -1;
08672 }
08673 data[pos++] = ies->odd_even_indicator;
08674 data[pos++] = 1;
08675 data[pos++] = subaddress->odd_even_indicator;
08676
08677 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08678 ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label);
08679 return -1;
08680 }
08681 data[pos++] = ies->valid;
08682 data[pos++] = 1;
08683 data[pos++] = subaddress->valid;
08684
08685 return pos;
08686 }
08687
08688
08689 struct ast_party_id_ies {
08690
08691 struct ast_party_name_ies name;
08692
08693 struct ast_party_number_ies number;
08694
08695 struct ast_party_subaddress_ies subaddress;
08696
08697 int tag;
08698
08699 int combined_presentation;
08700 };
08701
08702
08703
08704
08705
08706
08707
08708
08709
08710
08711
08712
08713
08714
08715
08716
08717 static int party_id_build_data(unsigned char *data, size_t datalen,
08718 const struct ast_party_id *id, const char *label, const struct ast_party_id_ies *ies,
08719 const struct ast_set_party_id *update)
08720 {
08721 size_t length;
08722 size_t pos = 0;
08723 int res;
08724
08725
08726
08727
08728
08729
08730 if (!update || update->name) {
08731 res = party_name_build_data(data + pos, datalen - pos, &id->name, label,
08732 &ies->name);
08733 if (res < 0) {
08734 return -1;
08735 }
08736 pos += res;
08737 }
08738
08739 if (!update || update->number) {
08740 res = party_number_build_data(data + pos, datalen - pos, &id->number, label,
08741 &ies->number);
08742 if (res < 0) {
08743 return -1;
08744 }
08745 pos += res;
08746 }
08747
08748 if (!update || update->subaddress) {
08749 res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress,
08750 label, &ies->subaddress);
08751 if (res < 0) {
08752 return -1;
08753 }
08754 pos += res;
08755 }
08756
08757
08758 if (id->tag) {
08759 length = strlen(id->tag);
08760 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08761 ast_log(LOG_WARNING, "No space left for %s tag\n", label);
08762 return -1;
08763 }
08764 data[pos++] = ies->tag;
08765 data[pos++] = length;
08766 memcpy(data + pos, id->tag, length);
08767 pos += length;
08768 }
08769
08770
08771 if (!update || update->number) {
08772 int presentation;
08773
08774 if (!update || update->name) {
08775 presentation = ast_party_id_presentation(id);
08776 } else {
08777
08778
08779
08780
08781
08782 presentation = id->number.presentation;
08783 }
08784
08785 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08786 ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label);
08787 return -1;
08788 }
08789 data[pos++] = ies->combined_presentation;
08790 data[pos++] = 1;
08791 data[pos++] = presentation;
08792 }
08793
08794 return pos;
08795 }
08796
08797
08798
08799
08800
08801 enum {
08802 AST_CONNECTED_LINE_NUMBER,
08803 AST_CONNECTED_LINE_NAME,
08804 AST_CONNECTED_LINE_NUMBER_PLAN,
08805 AST_CONNECTED_LINE_ID_PRESENTATION,
08806 AST_CONNECTED_LINE_SOURCE,
08807 AST_CONNECTED_LINE_SUBADDRESS,
08808 AST_CONNECTED_LINE_SUBADDRESS_TYPE,
08809 AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
08810 AST_CONNECTED_LINE_SUBADDRESS_VALID,
08811 AST_CONNECTED_LINE_TAG,
08812 AST_CONNECTED_LINE_VERSION,
08813 AST_CONNECTED_LINE_NAME_VALID,
08814 AST_CONNECTED_LINE_NAME_CHAR_SET,
08815 AST_CONNECTED_LINE_NAME_PRESENTATION,
08816 AST_CONNECTED_LINE_NUMBER_VALID,
08817 AST_CONNECTED_LINE_NUMBER_PRESENTATION,
08818 };
08819
08820 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)
08821 {
08822 int32_t value;
08823 size_t pos = 0;
08824 int res;
08825
08826 static const struct ast_party_id_ies ies = {
08827 .name.str = AST_CONNECTED_LINE_NAME,
08828 .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET,
08829 .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION,
08830 .name.valid = AST_CONNECTED_LINE_NAME_VALID,
08831
08832 .number.str = AST_CONNECTED_LINE_NUMBER,
08833 .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN,
08834 .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION,
08835 .number.valid = AST_CONNECTED_LINE_NUMBER_VALID,
08836
08837 .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS,
08838 .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE,
08839 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
08840 .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID,
08841
08842 .tag = AST_CONNECTED_LINE_TAG,
08843 .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION,
08844 };
08845
08846
08847
08848
08849
08850
08851
08852 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08853 ast_log(LOG_WARNING, "No space left for connected line frame version\n");
08854 return -1;
08855 }
08856 data[pos++] = AST_CONNECTED_LINE_VERSION;
08857 data[pos++] = 1;
08858 data[pos++] = 2;
08859
08860 res = party_id_build_data(data + pos, datalen - pos, &connected->id,
08861 "connected line", &ies, update ? &update->id : NULL);
08862 if (res < 0) {
08863 return -1;
08864 }
08865 pos += res;
08866
08867
08868 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
08869 ast_log(LOG_WARNING, "No space left for connected line source\n");
08870 return -1;
08871 }
08872 data[pos++] = AST_CONNECTED_LINE_SOURCE;
08873 data[pos++] = sizeof(value);
08874 value = htonl(connected->source);
08875 memcpy(data + pos, &value, sizeof(value));
08876 pos += sizeof(value);
08877
08878 return pos;
08879 }
08880
08881 int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, struct ast_party_connected_line *connected)
08882 {
08883 size_t pos;
08884 unsigned char ie_len;
08885 unsigned char ie_id;
08886 int32_t value;
08887 int frame_version = 1;
08888 int combined_presentation = 0;
08889 int got_combined_presentation = 0;
08890
08891 for (pos = 0; pos < datalen; pos += ie_len) {
08892 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
08893 ast_log(LOG_WARNING, "Invalid connected line update\n");
08894 return -1;
08895 }
08896 ie_id = data[pos++];
08897 ie_len = data[pos++];
08898 if (datalen < pos + ie_len) {
08899 ast_log(LOG_WARNING, "Invalid connected line update\n");
08900 return -1;
08901 }
08902
08903 switch (ie_id) {
08904
08905 case AST_CONNECTED_LINE_VERSION:
08906 if (ie_len != 1) {
08907 ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n",
08908 (unsigned) ie_len);
08909 break;
08910 }
08911 frame_version = data[pos];
08912 break;
08913
08914 case AST_CONNECTED_LINE_NAME:
08915 ast_free(connected->id.name.str);
08916 connected->id.name.str = ast_malloc(ie_len + 1);
08917 if (connected->id.name.str) {
08918 memcpy(connected->id.name.str, data + pos, ie_len);
08919 connected->id.name.str[ie_len] = 0;
08920 }
08921 break;
08922 case AST_CONNECTED_LINE_NAME_CHAR_SET:
08923 if (ie_len != 1) {
08924 ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n",
08925 (unsigned) ie_len);
08926 break;
08927 }
08928 connected->id.name.char_set = data[pos];
08929 break;
08930 case AST_CONNECTED_LINE_NAME_PRESENTATION:
08931 if (ie_len != 1) {
08932 ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n",
08933 (unsigned) ie_len);
08934 break;
08935 }
08936 connected->id.name.presentation = data[pos];
08937 break;
08938 case AST_CONNECTED_LINE_NAME_VALID:
08939 if (ie_len != 1) {
08940 ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n",
08941 (unsigned) ie_len);
08942 break;
08943 }
08944 connected->id.name.valid = data[pos];
08945 break;
08946
08947 case AST_CONNECTED_LINE_NUMBER:
08948 ast_free(connected->id.number.str);
08949 connected->id.number.str = ast_malloc(ie_len + 1);
08950 if (connected->id.number.str) {
08951 memcpy(connected->id.number.str, data + pos, ie_len);
08952 connected->id.number.str[ie_len] = 0;
08953 }
08954 break;
08955 case AST_CONNECTED_LINE_NUMBER_PLAN:
08956 if (ie_len != 1) {
08957 ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n",
08958 (unsigned) ie_len);
08959 break;
08960 }
08961 connected->id.number.plan = data[pos];
08962 break;
08963 case AST_CONNECTED_LINE_NUMBER_PRESENTATION:
08964 if (ie_len != 1) {
08965 ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n",
08966 (unsigned) ie_len);
08967 break;
08968 }
08969 connected->id.number.presentation = data[pos];
08970 break;
08971 case AST_CONNECTED_LINE_NUMBER_VALID:
08972 if (ie_len != 1) {
08973 ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n",
08974 (unsigned) ie_len);
08975 break;
08976 }
08977 connected->id.number.valid = data[pos];
08978 break;
08979
08980 case AST_CONNECTED_LINE_ID_PRESENTATION:
08981 if (ie_len != 1) {
08982 ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n",
08983 (unsigned) ie_len);
08984 break;
08985 }
08986 combined_presentation = data[pos];
08987 got_combined_presentation = 1;
08988 break;
08989
08990 case AST_CONNECTED_LINE_SUBADDRESS:
08991 ast_free(connected->id.subaddress.str);
08992 connected->id.subaddress.str = ast_malloc(ie_len + 1);
08993 if (connected->id.subaddress.str) {
08994 memcpy(connected->id.subaddress.str, data + pos, ie_len);
08995 connected->id.subaddress.str[ie_len] = 0;
08996 }
08997 break;
08998 case AST_CONNECTED_LINE_SUBADDRESS_TYPE:
08999 if (ie_len != 1) {
09000 ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n",
09001 (unsigned) ie_len);
09002 break;
09003 }
09004 connected->id.subaddress.type = data[pos];
09005 break;
09006 case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN:
09007 if (ie_len != 1) {
09008 ast_log(LOG_WARNING,
09009 "Invalid connected line subaddress odd-even indicator (%u)\n",
09010 (unsigned) ie_len);
09011 break;
09012 }
09013 connected->id.subaddress.odd_even_indicator = data[pos];
09014 break;
09015 case AST_CONNECTED_LINE_SUBADDRESS_VALID:
09016 if (ie_len != 1) {
09017 ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n",
09018 (unsigned) ie_len);
09019 break;
09020 }
09021 connected->id.subaddress.valid = data[pos];
09022 break;
09023
09024 case AST_CONNECTED_LINE_TAG:
09025 ast_free(connected->id.tag);
09026 connected->id.tag = ast_malloc(ie_len + 1);
09027 if (connected->id.tag) {
09028 memcpy(connected->id.tag, data + pos, ie_len);
09029 connected->id.tag[ie_len] = 0;
09030 }
09031 break;
09032
09033 case AST_CONNECTED_LINE_SOURCE:
09034 if (ie_len != sizeof(value)) {
09035 ast_log(LOG_WARNING, "Invalid connected line source (%u)\n",
09036 (unsigned) ie_len);
09037 break;
09038 }
09039 memcpy(&value, data + pos, sizeof(value));
09040 connected->source = ntohl(value);
09041 break;
09042
09043 default:
09044 ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n",
09045 (unsigned) ie_id, (unsigned) ie_len);
09046 break;
09047 }
09048 }
09049
09050 switch (frame_version) {
09051 case 1:
09052
09053
09054
09055
09056 connected->id.name.valid = 1;
09057 connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09058 connected->id.number.valid = 1;
09059 if (got_combined_presentation) {
09060 connected->id.name.presentation = combined_presentation;
09061 connected->id.number.presentation = combined_presentation;
09062 }
09063 break;
09064 case 2:
09065
09066 break;
09067 default:
09068
09069
09070
09071
09072 ast_log(LOG_DEBUG, "Connected line frame has newer version: %u\n",
09073 (unsigned) frame_version);
09074 break;
09075 }
09076
09077 return 0;
09078 }
09079
09080 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)
09081 {
09082 unsigned char data[1024];
09083 size_t datalen;
09084
09085 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
09086 if (datalen == (size_t) -1) {
09087 return;
09088 }
09089
09090 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
09091 }
09092
09093 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)
09094 {
09095 unsigned char data[1024];
09096 size_t datalen;
09097
09098 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
09099 if (datalen == (size_t) -1) {
09100 return;
09101 }
09102
09103 ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
09104 }
09105
09106 void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09107 {
09108 if (&chan->redirecting == redirecting) {
09109
09110 return;
09111 }
09112
09113 ast_channel_lock(chan);
09114 ast_party_redirecting_set(&chan->redirecting, redirecting, update);
09115 ast_channel_unlock(chan);
09116 }
09117
09118
09119
09120
09121
09122 enum {
09123 AST_REDIRECTING_FROM_NUMBER,
09124 AST_REDIRECTING_FROM_NAME,
09125 AST_REDIRECTING_FROM_NUMBER_PLAN,
09126 AST_REDIRECTING_FROM_ID_PRESENTATION,
09127 AST_REDIRECTING_TO_NUMBER,
09128 AST_REDIRECTING_TO_NAME,
09129 AST_REDIRECTING_TO_NUMBER_PLAN,
09130 AST_REDIRECTING_TO_ID_PRESENTATION,
09131 AST_REDIRECTING_REASON,
09132 AST_REDIRECTING_COUNT,
09133 AST_REDIRECTING_FROM_SUBADDRESS,
09134 AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
09135 AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
09136 AST_REDIRECTING_FROM_SUBADDRESS_VALID,
09137 AST_REDIRECTING_TO_SUBADDRESS,
09138 AST_REDIRECTING_TO_SUBADDRESS_TYPE,
09139 AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
09140 AST_REDIRECTING_TO_SUBADDRESS_VALID,
09141 AST_REDIRECTING_FROM_TAG,
09142 AST_REDIRECTING_TO_TAG,
09143 AST_REDIRECTING_VERSION,
09144 AST_REDIRECTING_FROM_NAME_VALID,
09145 AST_REDIRECTING_FROM_NAME_CHAR_SET,
09146 AST_REDIRECTING_FROM_NAME_PRESENTATION,
09147 AST_REDIRECTING_FROM_NUMBER_VALID,
09148 AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
09149 AST_REDIRECTING_TO_NAME_VALID,
09150 AST_REDIRECTING_TO_NAME_CHAR_SET,
09151 AST_REDIRECTING_TO_NAME_PRESENTATION,
09152 AST_REDIRECTING_TO_NUMBER_VALID,
09153 AST_REDIRECTING_TO_NUMBER_PRESENTATION,
09154 };
09155
09156 int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09157 {
09158 int32_t value;
09159 size_t pos = 0;
09160 int res;
09161
09162 static const struct ast_party_id_ies from_ies = {
09163 .name.str = AST_REDIRECTING_FROM_NAME,
09164 .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET,
09165 .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION,
09166 .name.valid = AST_REDIRECTING_FROM_NAME_VALID,
09167
09168 .number.str = AST_REDIRECTING_FROM_NUMBER,
09169 .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN,
09170 .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
09171 .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID,
09172
09173 .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS,
09174 .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
09175 .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
09176 .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID,
09177
09178 .tag = AST_REDIRECTING_FROM_TAG,
09179 .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION,
09180 };
09181 static const struct ast_party_id_ies to_ies = {
09182 .name.str = AST_REDIRECTING_TO_NAME,
09183 .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET,
09184 .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION,
09185 .name.valid = AST_REDIRECTING_TO_NAME_VALID,
09186
09187 .number.str = AST_REDIRECTING_TO_NUMBER,
09188 .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN,
09189 .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION,
09190 .number.valid = AST_REDIRECTING_TO_NUMBER_VALID,
09191
09192 .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS,
09193 .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE,
09194 .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
09195 .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID,
09196
09197 .tag = AST_REDIRECTING_TO_TAG,
09198 .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION,
09199 };
09200
09201
09202 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
09203 ast_log(LOG_WARNING, "No space left for redirecting frame version\n");
09204 return -1;
09205 }
09206 data[pos++] = AST_REDIRECTING_VERSION;
09207 data[pos++] = 1;
09208 data[pos++] = 2;
09209
09210 res = party_id_build_data(data + pos, datalen - pos, &redirecting->from,
09211 "redirecting-from", &from_ies, update ? &update->from : NULL);
09212 if (res < 0) {
09213 return -1;
09214 }
09215 pos += res;
09216
09217 res = party_id_build_data(data + pos, datalen - pos, &redirecting->to,
09218 "redirecting-to", &to_ies, update ? &update->to : NULL);
09219 if (res < 0) {
09220 return -1;
09221 }
09222 pos += res;
09223
09224
09225 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
09226 ast_log(LOG_WARNING, "No space left for redirecting reason\n");
09227 return -1;
09228 }
09229 data[pos++] = AST_REDIRECTING_REASON;
09230 data[pos++] = sizeof(value);
09231 value = htonl(redirecting->reason);
09232 memcpy(data + pos, &value, sizeof(value));
09233 pos += sizeof(value);
09234
09235
09236 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
09237 ast_log(LOG_WARNING, "No space left for redirecting count\n");
09238 return -1;
09239 }
09240 data[pos++] = AST_REDIRECTING_COUNT;
09241 data[pos++] = sizeof(value);
09242 value = htonl(redirecting->count);
09243 memcpy(data + pos, &value, sizeof(value));
09244 pos += sizeof(value);
09245
09246 return pos;
09247 }
09248
09249 int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct ast_party_redirecting *redirecting)
09250 {
09251 size_t pos;
09252 unsigned char ie_len;
09253 unsigned char ie_id;
09254 int32_t value;
09255 int frame_version = 1;
09256 int from_combined_presentation = 0;
09257 int got_from_combined_presentation = 0;
09258 int to_combined_presentation = 0;
09259 int got_to_combined_presentation = 0;
09260
09261 for (pos = 0; pos < datalen; pos += ie_len) {
09262 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
09263 ast_log(LOG_WARNING, "Invalid redirecting update\n");
09264 return -1;
09265 }
09266 ie_id = data[pos++];
09267 ie_len = data[pos++];
09268 if (datalen < pos + ie_len) {
09269 ast_log(LOG_WARNING, "Invalid redirecting update\n");
09270 return -1;
09271 }
09272
09273 switch (ie_id) {
09274
09275 case AST_REDIRECTING_VERSION:
09276 if (ie_len != 1) {
09277 ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n",
09278 (unsigned) ie_len);
09279 break;
09280 }
09281 frame_version = data[pos];
09282 break;
09283
09284 case AST_REDIRECTING_FROM_NAME:
09285 ast_free(redirecting->from.name.str);
09286 redirecting->from.name.str = ast_malloc(ie_len + 1);
09287 if (redirecting->from.name.str) {
09288 memcpy(redirecting->from.name.str, data + pos, ie_len);
09289 redirecting->from.name.str[ie_len] = 0;
09290 }
09291 break;
09292 case AST_REDIRECTING_FROM_NAME_CHAR_SET:
09293 if (ie_len != 1) {
09294 ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n",
09295 (unsigned) ie_len);
09296 break;
09297 }
09298 redirecting->from.name.char_set = data[pos];
09299 break;
09300 case AST_REDIRECTING_FROM_NAME_PRESENTATION:
09301 if (ie_len != 1) {
09302 ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n",
09303 (unsigned) ie_len);
09304 break;
09305 }
09306 redirecting->from.name.presentation = data[pos];
09307 break;
09308 case AST_REDIRECTING_FROM_NAME_VALID:
09309 if (ie_len != 1) {
09310 ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n",
09311 (unsigned) ie_len);
09312 break;
09313 }
09314 redirecting->from.name.valid = data[pos];
09315 break;
09316
09317 case AST_REDIRECTING_FROM_NUMBER:
09318 ast_free(redirecting->from.number.str);
09319 redirecting->from.number.str = ast_malloc(ie_len + 1);
09320 if (redirecting->from.number.str) {
09321 memcpy(redirecting->from.number.str, data + pos, ie_len);
09322 redirecting->from.number.str[ie_len] = 0;
09323 }
09324 break;
09325 case AST_REDIRECTING_FROM_NUMBER_PLAN:
09326 if (ie_len != 1) {
09327 ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n",
09328 (unsigned) ie_len);
09329 break;
09330 }
09331 redirecting->from.number.plan = data[pos];
09332 break;
09333 case AST_REDIRECTING_FROM_NUMBER_PRESENTATION:
09334 if (ie_len != 1) {
09335 ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n",
09336 (unsigned) ie_len);
09337 break;
09338 }
09339 redirecting->from.number.presentation = data[pos];
09340 break;
09341 case AST_REDIRECTING_FROM_NUMBER_VALID:
09342 if (ie_len != 1) {
09343 ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n",
09344 (unsigned) ie_len);
09345 break;
09346 }
09347 redirecting->from.number.valid = data[pos];
09348 break;
09349
09350 case AST_REDIRECTING_FROM_ID_PRESENTATION:
09351 if (ie_len != 1) {
09352 ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n",
09353 (unsigned) ie_len);
09354 break;
09355 }
09356 from_combined_presentation = data[pos];
09357 got_from_combined_presentation = 1;
09358 break;
09359
09360 case AST_REDIRECTING_FROM_SUBADDRESS:
09361 ast_free(redirecting->from.subaddress.str);
09362 redirecting->from.subaddress.str = ast_malloc(ie_len + 1);
09363 if (redirecting->from.subaddress.str) {
09364 memcpy(redirecting->from.subaddress.str, data + pos, ie_len);
09365 redirecting->from.subaddress.str[ie_len] = 0;
09366 }
09367 break;
09368 case AST_REDIRECTING_FROM_SUBADDRESS_TYPE:
09369 if (ie_len != 1) {
09370 ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n",
09371 (unsigned) ie_len);
09372 break;
09373 }
09374 redirecting->from.subaddress.type = data[pos];
09375 break;
09376 case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN:
09377 if (ie_len != 1) {
09378 ast_log(LOG_WARNING,
09379 "Invalid redirecting-from subaddress odd-even indicator (%u)\n",
09380 (unsigned) ie_len);
09381 break;
09382 }
09383 redirecting->from.subaddress.odd_even_indicator = data[pos];
09384 break;
09385 case AST_REDIRECTING_FROM_SUBADDRESS_VALID:
09386 if (ie_len != 1) {
09387 ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n",
09388 (unsigned) ie_len);
09389 break;
09390 }
09391 redirecting->from.subaddress.valid = data[pos];
09392 break;
09393
09394 case AST_REDIRECTING_FROM_TAG:
09395 ast_free(redirecting->from.tag);
09396 redirecting->from.tag = ast_malloc(ie_len + 1);
09397 if (redirecting->from.tag) {
09398 memcpy(redirecting->from.tag, data + pos, ie_len);
09399 redirecting->from.tag[ie_len] = 0;
09400 }
09401 break;
09402
09403 case AST_REDIRECTING_TO_NAME:
09404 ast_free(redirecting->to.name.str);
09405 redirecting->to.name.str = ast_malloc(ie_len + 1);
09406 if (redirecting->to.name.str) {
09407 memcpy(redirecting->to.name.str, data + pos, ie_len);
09408 redirecting->to.name.str[ie_len] = 0;
09409 }
09410 break;
09411 case AST_REDIRECTING_TO_NAME_CHAR_SET:
09412 if (ie_len != 1) {
09413 ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n",
09414 (unsigned) ie_len);
09415 break;
09416 }
09417 redirecting->to.name.char_set = data[pos];
09418 break;
09419 case AST_REDIRECTING_TO_NAME_PRESENTATION:
09420 if (ie_len != 1) {
09421 ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n",
09422 (unsigned) ie_len);
09423 break;
09424 }
09425 redirecting->to.name.presentation = data[pos];
09426 break;
09427 case AST_REDIRECTING_TO_NAME_VALID:
09428 if (ie_len != 1) {
09429 ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n",
09430 (unsigned) ie_len);
09431 break;
09432 }
09433 redirecting->to.name.valid = data[pos];
09434 break;
09435
09436 case AST_REDIRECTING_TO_NUMBER:
09437 ast_free(redirecting->to.number.str);
09438 redirecting->to.number.str = ast_malloc(ie_len + 1);
09439 if (redirecting->to.number.str) {
09440 memcpy(redirecting->to.number.str, data + pos, ie_len);
09441 redirecting->to.number.str[ie_len] = 0;
09442 }
09443 break;
09444 case AST_REDIRECTING_TO_NUMBER_PLAN:
09445 if (ie_len != 1) {
09446 ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n",
09447 (unsigned) ie_len);
09448 break;
09449 }
09450 redirecting->to.number.plan = data[pos];
09451 break;
09452 case AST_REDIRECTING_TO_NUMBER_PRESENTATION:
09453 if (ie_len != 1) {
09454 ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n",
09455 (unsigned) ie_len);
09456 break;
09457 }
09458 redirecting->to.number.presentation = data[pos];
09459 break;
09460 case AST_REDIRECTING_TO_NUMBER_VALID:
09461 if (ie_len != 1) {
09462 ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n",
09463 (unsigned) ie_len);
09464 break;
09465 }
09466 redirecting->to.number.valid = data[pos];
09467 break;
09468
09469 case AST_REDIRECTING_TO_ID_PRESENTATION:
09470 if (ie_len != 1) {
09471 ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n",
09472 (unsigned) ie_len);
09473 break;
09474 }
09475 to_combined_presentation = data[pos];
09476 got_to_combined_presentation = 1;
09477 break;
09478
09479 case AST_REDIRECTING_TO_SUBADDRESS:
09480 ast_free(redirecting->to.subaddress.str);
09481 redirecting->to.subaddress.str = ast_malloc(ie_len + 1);
09482 if (redirecting->to.subaddress.str) {
09483 memcpy(redirecting->to.subaddress.str, data + pos, ie_len);
09484 redirecting->to.subaddress.str[ie_len] = 0;
09485 }
09486 break;
09487 case AST_REDIRECTING_TO_SUBADDRESS_TYPE:
09488 if (ie_len != 1) {
09489 ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n",
09490 (unsigned) ie_len);
09491 break;
09492 }
09493 redirecting->to.subaddress.type = data[pos];
09494 break;
09495 case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN:
09496 if (ie_len != 1) {
09497 ast_log(LOG_WARNING,
09498 "Invalid redirecting-to subaddress odd-even indicator (%u)\n",
09499 (unsigned) ie_len);
09500 break;
09501 }
09502 redirecting->to.subaddress.odd_even_indicator = data[pos];
09503 break;
09504 case AST_REDIRECTING_TO_SUBADDRESS_VALID:
09505 if (ie_len != 1) {
09506 ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n",
09507 (unsigned) ie_len);
09508 break;
09509 }
09510 redirecting->to.subaddress.valid = data[pos];
09511 break;
09512
09513 case AST_REDIRECTING_TO_TAG:
09514 ast_free(redirecting->to.tag);
09515 redirecting->to.tag = ast_malloc(ie_len + 1);
09516 if (redirecting->to.tag) {
09517 memcpy(redirecting->to.tag, data + pos, ie_len);
09518 redirecting->to.tag[ie_len] = 0;
09519 }
09520 break;
09521
09522 case AST_REDIRECTING_REASON:
09523 if (ie_len != sizeof(value)) {
09524 ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n",
09525 (unsigned) ie_len);
09526 break;
09527 }
09528 memcpy(&value, data + pos, sizeof(value));
09529 redirecting->reason = ntohl(value);
09530 break;
09531
09532 case AST_REDIRECTING_COUNT:
09533 if (ie_len != sizeof(value)) {
09534 ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n",
09535 (unsigned) ie_len);
09536 break;
09537 }
09538 memcpy(&value, data + pos, sizeof(value));
09539 redirecting->count = ntohl(value);
09540 break;
09541
09542 default:
09543 ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n",
09544 (unsigned) ie_id, (unsigned) ie_len);
09545 break;
09546 }
09547 }
09548
09549 switch (frame_version) {
09550 case 1:
09551
09552
09553
09554
09555 redirecting->from.name.valid = 1;
09556 redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09557 redirecting->from.number.valid = 1;
09558 if (got_from_combined_presentation) {
09559 redirecting->from.name.presentation = from_combined_presentation;
09560 redirecting->from.number.presentation = from_combined_presentation;
09561 }
09562
09563 redirecting->to.name.valid = 1;
09564 redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09565 redirecting->to.number.valid = 1;
09566 if (got_to_combined_presentation) {
09567 redirecting->to.name.presentation = to_combined_presentation;
09568 redirecting->to.number.presentation = to_combined_presentation;
09569 }
09570 break;
09571 case 2:
09572
09573 break;
09574 default:
09575
09576
09577
09578
09579 ast_log(LOG_DEBUG, "Redirecting frame has newer version: %u\n",
09580 (unsigned) frame_version);
09581 break;
09582 }
09583
09584 return 0;
09585 }
09586
09587 void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09588 {
09589 unsigned char data[1024];
09590 size_t datalen;
09591
09592 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09593 if (datalen == (size_t) -1) {
09594 return;
09595 }
09596
09597 ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09598 }
09599
09600 void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09601 {
09602 unsigned char data[1024];
09603 size_t datalen;
09604
09605 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09606 if (datalen == (size_t) -1) {
09607 return;
09608 }
09609
09610 ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09611 }
09612
09613 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)
09614 {
09615 const char *macro;
09616 const char *macro_args;
09617 int retval;
09618
09619 ast_channel_lock(macro_chan);
09620 macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09621 ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO");
09622 macro = ast_strdupa(S_OR(macro, ""));
09623 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09624 ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS");
09625 macro_args = ast_strdupa(S_OR(macro_args, ""));
09626
09627 if (ast_strlen_zero(macro)) {
09628 ast_channel_unlock(macro_chan);
09629 return -1;
09630 }
09631
09632 if (is_frame) {
09633 const struct ast_frame *frame = connected_info;
09634
09635 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->connected);
09636 } else {
09637 const struct ast_party_connected_line *connected = connected_info;
09638
09639 ast_party_connected_line_copy(¯o_chan->connected, connected);
09640 }
09641 ast_channel_unlock(macro_chan);
09642
09643 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
09644 if (!retval) {
09645 struct ast_party_connected_line saved_connected;
09646
09647 ast_party_connected_line_init(&saved_connected);
09648 ast_channel_lock(macro_chan);
09649 ast_party_connected_line_copy(&saved_connected, ¯o_chan->connected);
09650 ast_channel_unlock(macro_chan);
09651 ast_channel_update_connected_line(macro_chan, &saved_connected, NULL);
09652 ast_party_connected_line_free(&saved_connected);
09653 }
09654
09655 return retval;
09656 }
09657
09658 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)
09659 {
09660 const char *macro;
09661 const char *macro_args;
09662 int retval;
09663
09664 ast_channel_lock(macro_chan);
09665 macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09666 ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO");
09667 macro = ast_strdupa(S_OR(macro, ""));
09668 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09669 ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS");
09670 macro_args = ast_strdupa(S_OR(macro_args, ""));
09671
09672 if (ast_strlen_zero(macro)) {
09673 ast_channel_unlock(macro_chan);
09674 return -1;
09675 }
09676
09677 if (is_frame) {
09678 const struct ast_frame *frame = redirecting_info;
09679
09680 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->redirecting);
09681 } else {
09682 const struct ast_party_redirecting *redirecting = redirecting_info;
09683
09684 ast_party_redirecting_copy(¯o_chan->redirecting, redirecting);
09685 }
09686 ast_channel_unlock(macro_chan);
09687
09688 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
09689 if (!retval) {
09690 struct ast_party_redirecting saved_redirecting;
09691
09692 ast_party_redirecting_init(&saved_redirecting);
09693 ast_channel_lock(macro_chan);
09694 ast_party_redirecting_copy(&saved_redirecting, ¯o_chan->redirecting);
09695 ast_channel_unlock(macro_chan);
09696 ast_channel_update_redirecting(macro_chan, &saved_redirecting, NULL);
09697 ast_party_redirecting_free(&saved_redirecting);
09698 }
09699
09700 return retval;
09701 }
09702
09703 static void *channel_cc_params_copy(void *data)
09704 {
09705 const struct ast_cc_config_params *src = data;
09706 struct ast_cc_config_params *dest = ast_cc_config_params_init();
09707 if (!dest) {
09708 return NULL;
09709 }
09710 ast_cc_copy_config_params(dest, src);
09711 return dest;
09712 }
09713
09714 static void channel_cc_params_destroy(void *data)
09715 {
09716 struct ast_cc_config_params *cc_params = data;
09717 ast_cc_config_params_destroy(cc_params);
09718 }
09719
09720 static const struct ast_datastore_info cc_channel_datastore_info = {
09721 .type = "Call Completion",
09722 .duplicate = channel_cc_params_copy,
09723 .destroy = channel_cc_params_destroy,
09724 };
09725
09726 int ast_channel_cc_params_init(struct ast_channel *chan,
09727 const struct ast_cc_config_params *base_params)
09728 {
09729 struct ast_cc_config_params *cc_params;
09730 struct ast_datastore *cc_datastore;
09731
09732 if (!(cc_params = ast_cc_config_params_init())) {
09733 return -1;
09734 }
09735
09736 if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) {
09737 ast_cc_config_params_destroy(cc_params);
09738 return -1;
09739 }
09740
09741 if (base_params) {
09742 ast_cc_copy_config_params(cc_params, base_params);
09743 }
09744 cc_datastore->data = cc_params;
09745 ast_channel_datastore_add(chan, cc_datastore);
09746 return 0;
09747 }
09748
09749 struct ast_cc_config_params *ast_channel_get_cc_config_params(struct ast_channel *chan)
09750 {
09751 struct ast_datastore *cc_datastore;
09752
09753 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09754
09755
09756
09757
09758 if (ast_channel_cc_params_init(chan, NULL)) {
09759 return NULL;
09760 }
09761 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09762
09763 return NULL;
09764 }
09765 }
09766
09767 ast_assert(cc_datastore->data != NULL);
09768 return cc_datastore->data;
09769 }
09770
09771 int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
09772 {
09773 int len = name_buffer_length;
09774 char *dash;
09775 if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) {
09776 return 0;
09777 }
09778
09779
09780 ast_copy_string(device_name, chan->name, name_buffer_length);
09781 if ((dash = strrchr(device_name, '-'))) {
09782 *dash = '\0';
09783 }
09784
09785 return 0;
09786 }
09787
09788 int ast_channel_get_cc_agent_type(struct ast_channel *chan, char *agent_type, size_t size)
09789 {
09790 int len = size;
09791 char *slash;
09792
09793 if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) {
09794 return 0;
09795 }
09796
09797 ast_copy_string(agent_type, chan->name, size);
09798 if ((slash = strchr(agent_type, '/'))) {
09799 *slash = '\0';
09800 }
09801 return 0;
09802 }
09803
09804
09805
09806
09807
09808
09809
09810
09811
09812
09813 #undef ast_channel_alloc
09814 struct ast_channel __attribute__((format(printf, 10, 11)))
09815 *ast_channel_alloc(int needqueue, int state, const char *cid_num,
09816 const char *cid_name, const char *acctcode,
09817 const char *exten, const char *context,
09818 const char *linkedid, const int amaflag,
09819 const char *name_fmt, ...);
09820 struct ast_channel *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 {
09826 va_list ap1, ap2;
09827 struct ast_channel *result;
09828
09829
09830 va_start(ap1, name_fmt);
09831 va_start(ap2, name_fmt);
09832 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
09833 linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap1, ap2);
09834 va_end(ap1);
09835 va_end(ap2);
09836
09837 return result;
09838 }