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