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