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