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