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