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: 305923 $")
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 void ast_channel_clear_softhangup(struct ast_channel *chan, int flag)
02603 {
02604 ast_channel_lock(chan);
02605
02606 chan->_softhangup &= ~flag;
02607
02608 if (!chan->_softhangup) {
02609 struct ast_frame *fr;
02610
02611
02612
02613
02614
02615
02616 fr = AST_LIST_LAST(&chan->readq);
02617 if (fr && fr->frametype == AST_FRAME_CONTROL &&
02618 fr->subclass.integer == AST_CONTROL_END_OF_Q) {
02619 AST_LIST_REMOVE(&chan->readq, fr, frame_list);
02620 ast_frfree(fr);
02621 }
02622 }
02623
02624 ast_channel_unlock(chan);
02625 }
02626
02627
02628 int ast_softhangup_nolock(struct ast_channel *chan, int cause)
02629 {
02630 ast_debug(1, "Soft-Hanging up channel '%s'\n", chan->name);
02631
02632 chan->_softhangup |= cause;
02633 ast_queue_frame(chan, &ast_null_frame);
02634
02635 if (ast_test_flag(chan, AST_FLAG_BLOCKING))
02636 pthread_kill(chan->blocker, SIGURG);
02637 return 0;
02638 }
02639
02640
02641 int ast_softhangup(struct ast_channel *chan, int cause)
02642 {
02643 int res;
02644
02645 ast_channel_lock(chan);
02646 res = ast_softhangup_nolock(chan, cause);
02647 ast_channel_unlock(chan);
02648
02649 return res;
02650 }
02651
02652 static void free_translation(struct ast_channel *clonechan)
02653 {
02654 if (clonechan->writetrans)
02655 ast_translator_free_path(clonechan->writetrans);
02656 if (clonechan->readtrans)
02657 ast_translator_free_path(clonechan->readtrans);
02658 clonechan->writetrans = NULL;
02659 clonechan->readtrans = NULL;
02660 clonechan->rawwriteformat = clonechan->nativeformats;
02661 clonechan->rawreadformat = clonechan->nativeformats;
02662 }
02663
02664 void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
02665 {
02666 struct ast_channel *bridge;
02667
02668 ast_channel_lock(chan);
02669 if (force || ast_strlen_zero(chan->hangupsource)) {
02670 ast_string_field_set(chan, hangupsource, source);
02671 }
02672 bridge = ast_bridged_channel(chan);
02673 ast_channel_unlock(chan);
02674
02675 if (bridge && (force || ast_strlen_zero(bridge->hangupsource))) {
02676 ast_channel_lock(bridge);
02677 ast_string_field_set(chan, hangupsource, source);
02678 ast_channel_unlock(bridge);
02679 }
02680 }
02681
02682
02683 int ast_hangup(struct ast_channel *chan)
02684 {
02685 int res = 0;
02686 char extra_str[64];
02687
02688
02689
02690 ast_channel_lock(chan);
02691
02692 if (chan->audiohooks) {
02693 ast_audiohook_detach_list(chan->audiohooks);
02694 chan->audiohooks = NULL;
02695 }
02696
02697 ast_framehook_list_destroy(chan);
02698
02699 ast_autoservice_stop(chan);
02700
02701 if (chan->masq) {
02702 ast_channel_unlock(chan);
02703 if (ast_do_masquerade(chan)) {
02704 ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02705 }
02706 ast_channel_lock(chan);
02707 }
02708
02709 if (chan->masq) {
02710 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
02711 ast_channel_unlock(chan);
02712 return 0;
02713 }
02714
02715
02716 if (chan->masqr) {
02717 ast_set_flag(chan, AST_FLAG_ZOMBIE);
02718 ast_channel_unlock(chan);
02719 return 0;
02720 }
02721 ast_channel_unlock(chan);
02722
02723 ao2_unlink(channels, chan);
02724
02725 ast_channel_lock(chan);
02726 free_translation(chan);
02727
02728 if (chan->stream) {
02729 ast_closestream(chan->stream);
02730 chan->stream = NULL;
02731 }
02732
02733 if (chan->vstream) {
02734 ast_closestream(chan->vstream);
02735 chan->vstream = NULL;
02736 }
02737 if (chan->sched) {
02738 sched_context_destroy(chan->sched);
02739 chan->sched = NULL;
02740 }
02741
02742 if (chan->generatordata)
02743 if (chan->generator && chan->generator->release)
02744 chan->generator->release(chan, chan->generatordata);
02745 chan->generatordata = NULL;
02746 chan->generator = NULL;
02747
02748 snprintf(extra_str, sizeof(extra_str), "%d,%s,%s", chan->hangupcause, chan->hangupsource, S_OR(pbx_builtin_getvar_helper(chan, "DIALSTATUS"), ""));
02749 ast_cel_report_event(chan, AST_CEL_HANGUP, NULL, extra_str, NULL);
02750
02751 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
02752 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
02753 "is blocked by thread %ld in procedure %s! Expect a failure\n",
02754 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
02755 ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0);
02756 }
02757 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
02758 ast_debug(1, "Hanging up channel '%s'\n", chan->name);
02759 if (chan->tech->hangup)
02760 res = chan->tech->hangup(chan);
02761 } else {
02762 ast_debug(1, "Hanging up zombie '%s'\n", chan->name);
02763 }
02764
02765 ast_channel_unlock(chan);
02766 ast_cc_offer(chan);
02767 ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup",
02768 "Channel: %s\r\n"
02769 "Uniqueid: %s\r\n"
02770 "CallerIDNum: %s\r\n"
02771 "CallerIDName: %s\r\n"
02772 "Cause: %d\r\n"
02773 "Cause-txt: %s\r\n",
02774 chan->name,
02775 chan->uniqueid,
02776 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"),
02777 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"),
02778 chan->hangupcause,
02779 ast_cause2str(chan->hangupcause)
02780 );
02781
02782 if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) &&
02783 !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) &&
02784 (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) {
02785 ast_channel_lock(chan);
02786
02787 ast_cdr_end(chan->cdr);
02788 ast_cdr_detach(chan->cdr);
02789 chan->cdr = NULL;
02790 ast_channel_unlock(chan);
02791 }
02792
02793 chan = ast_channel_release(chan);
02794
02795 return res;
02796 }
02797
02798 int ast_raw_answer(struct ast_channel *chan, int cdr_answer)
02799 {
02800 int res = 0;
02801
02802 ast_channel_lock(chan);
02803
02804
02805 if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
02806 ast_channel_unlock(chan);
02807 return 0;
02808 }
02809
02810
02811 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02812 ast_channel_unlock(chan);
02813 return -1;
02814 }
02815
02816 ast_channel_unlock(chan);
02817
02818 switch (chan->_state) {
02819 case AST_STATE_RINGING:
02820 case AST_STATE_RING:
02821 ast_channel_lock(chan);
02822 if (chan->tech->answer) {
02823 res = chan->tech->answer(chan);
02824 }
02825 ast_setstate(chan, AST_STATE_UP);
02826 if (cdr_answer) {
02827 ast_cdr_answer(chan->cdr);
02828 }
02829 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
02830 ast_channel_unlock(chan);
02831 break;
02832 case AST_STATE_UP:
02833 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
02834
02835
02836
02837 if (cdr_answer) {
02838 ast_cdr_answer(chan->cdr);
02839 }
02840 break;
02841 default:
02842 break;
02843 }
02844
02845 ast_indicate(chan, -1);
02846
02847 return res;
02848 }
02849
02850 int __ast_answer(struct ast_channel *chan, unsigned int delay, int cdr_answer)
02851 {
02852 int res = 0;
02853 enum ast_channel_state old_state;
02854
02855 old_state = chan->_state;
02856 if ((res = ast_raw_answer(chan, cdr_answer))) {
02857 return res;
02858 }
02859
02860 switch (old_state) {
02861 case AST_STATE_RINGING:
02862 case AST_STATE_RING:
02863
02864
02865
02866 do {
02867 AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
02868 struct ast_frame *cur, *new;
02869 int ms = MAX(delay, 500);
02870 unsigned int done = 0;
02871
02872 AST_LIST_HEAD_INIT_NOLOCK(&frames);
02873
02874 for (;;) {
02875 ms = ast_waitfor(chan, ms);
02876 if (ms < 0) {
02877 ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", chan->name, strerror(errno));
02878 res = -1;
02879 break;
02880 }
02881 if (ms == 0) {
02882 ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", chan->name, MAX(delay, 500));
02883 break;
02884 }
02885 cur = ast_read(chan);
02886 if (!cur || ((cur->frametype == AST_FRAME_CONTROL) &&
02887 (cur->subclass.integer == AST_CONTROL_HANGUP))) {
02888 if (cur) {
02889 ast_frfree(cur);
02890 }
02891 res = -1;
02892 ast_debug(2, "Hangup of channel %s detected in answer routine\n", chan->name);
02893 break;
02894 }
02895
02896 if ((new = ast_frisolate(cur)) != cur) {
02897 ast_frfree(cur);
02898 }
02899
02900 AST_LIST_INSERT_HEAD(&frames, new, frame_list);
02901
02902
02903
02904
02905
02906 if (delay) {
02907 continue;
02908 }
02909
02910 switch (new->frametype) {
02911
02912 case AST_FRAME_VOICE:
02913 case AST_FRAME_VIDEO:
02914 case AST_FRAME_TEXT:
02915 case AST_FRAME_DTMF_BEGIN:
02916 case AST_FRAME_DTMF_END:
02917 case AST_FRAME_IMAGE:
02918 case AST_FRAME_HTML:
02919 case AST_FRAME_MODEM:
02920 done = 1;
02921 break;
02922 case AST_FRAME_CONTROL:
02923 case AST_FRAME_IAX:
02924 case AST_FRAME_NULL:
02925 case AST_FRAME_CNG:
02926 break;
02927 }
02928
02929 if (done) {
02930 break;
02931 }
02932 }
02933
02934 if (res == 0) {
02935 ast_channel_lock(chan);
02936 while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) {
02937 ast_queue_frame_head(chan, cur);
02938 ast_frfree(cur);
02939 }
02940 ast_channel_unlock(chan);
02941 }
02942 } while (0);
02943 break;
02944 default:
02945 break;
02946 }
02947
02948 return res;
02949 }
02950
02951 int ast_answer(struct ast_channel *chan)
02952 {
02953 return __ast_answer(chan, 0, 1);
02954 }
02955
02956 void ast_deactivate_generator(struct ast_channel *chan)
02957 {
02958 ast_channel_lock(chan);
02959 if (chan->generatordata) {
02960 if (chan->generator && chan->generator->release)
02961 chan->generator->release(chan, chan->generatordata);
02962 chan->generatordata = NULL;
02963 chan->generator = NULL;
02964 ast_channel_set_fd(chan, AST_GENERATOR_FD, -1);
02965 ast_clear_flag(chan, AST_FLAG_WRITE_INT);
02966 ast_settimeout(chan, 0, NULL, NULL);
02967 }
02968 ast_channel_unlock(chan);
02969 }
02970
02971 static int generator_force(const void *data)
02972 {
02973
02974 void *tmp;
02975 int res;
02976 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
02977 struct ast_channel *chan = (struct ast_channel *)data;
02978
02979 ast_channel_lock(chan);
02980 tmp = chan->generatordata;
02981 chan->generatordata = NULL;
02982 if (chan->generator)
02983 generate = chan->generator->generate;
02984 ast_channel_unlock(chan);
02985
02986 if (!tmp || !generate)
02987 return 0;
02988
02989 res = generate(chan, tmp, 0, ast_format_rate(chan->writeformat & AST_FORMAT_AUDIO_MASK) / 50);
02990
02991 chan->generatordata = tmp;
02992
02993 if (res) {
02994 ast_debug(1, "Auto-deactivating generator\n");
02995 ast_deactivate_generator(chan);
02996 }
02997
02998 return 0;
02999 }
03000
03001 int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
03002 {
03003 int res = 0;
03004
03005 ast_channel_lock(chan);
03006 if (chan->generatordata) {
03007 if (chan->generator && chan->generator->release)
03008 chan->generator->release(chan, chan->generatordata);
03009 chan->generatordata = NULL;
03010 }
03011 if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
03012 res = -1;
03013 }
03014 if (!res) {
03015 ast_settimeout(chan, 50, generator_force, chan);
03016 chan->generator = gen;
03017 }
03018 ast_channel_unlock(chan);
03019
03020 ast_prod(chan);
03021
03022 return res;
03023 }
03024
03025
03026 int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
03027 {
03028 int winner = -1;
03029 ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
03030 return winner;
03031 }
03032
03033
03034 #ifdef HAVE_EPOLL
03035 static struct ast_channel *ast_waitfor_nandfds_classic(struct ast_channel **c, int n, int *fds, int nfds,
03036 int *exception, int *outfd, int *ms)
03037 #else
03038 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
03039 int *exception, int *outfd, int *ms)
03040 #endif
03041 {
03042 struct timeval start = { 0 , 0 };
03043 struct pollfd *pfds = NULL;
03044 int res;
03045 long rms;
03046 int x, y, max;
03047 int sz;
03048 struct timeval now = { 0, 0 };
03049 struct timeval whentohangup = { 0, 0 }, diff;
03050 struct ast_channel *winner = NULL;
03051 struct fdmap {
03052 int chan;
03053 int fdno;
03054 } *fdmap = NULL;
03055
03056 if ((sz = n * AST_MAX_FDS + nfds)) {
03057 pfds = alloca(sizeof(*pfds) * sz);
03058 fdmap = alloca(sizeof(*fdmap) * sz);
03059 }
03060
03061 if (outfd)
03062 *outfd = -99999;
03063 if (exception)
03064 *exception = 0;
03065
03066
03067 for (x = 0; x < n; x++) {
03068 if (c[x]->masq && ast_do_masquerade(c[x])) {
03069 ast_log(LOG_WARNING, "Masquerade failed\n");
03070 *ms = -1;
03071 return NULL;
03072 }
03073
03074 ast_channel_lock(c[x]);
03075 if (!ast_tvzero(c[x]->whentohangup)) {
03076 if (ast_tvzero(whentohangup))
03077 now = ast_tvnow();
03078 diff = ast_tvsub(c[x]->whentohangup, now);
03079 if (diff.tv_sec < 0 || ast_tvzero(diff)) {
03080
03081 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03082 ast_channel_unlock(c[x]);
03083 return c[x];
03084 }
03085 if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0)
03086 whentohangup = diff;
03087 }
03088 ast_channel_unlock(c[x]);
03089 }
03090
03091 rms = *ms;
03092
03093 if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX / 1000) {
03094 rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000;
03095 if (*ms >= 0 && *ms < rms) {
03096 rms = *ms;
03097 }
03098 } else if (!ast_tvzero(whentohangup) && rms < 0) {
03099
03100 rms = INT_MAX;
03101 }
03102
03103
03104
03105
03106
03107 max = 0;
03108 for (x = 0; x < n; x++) {
03109 for (y = 0; y < AST_MAX_FDS; y++) {
03110 fdmap[max].fdno = y;
03111 fdmap[max].chan = x;
03112 max += ast_add_fd(&pfds[max], c[x]->fds[y]);
03113 }
03114 CHECK_BLOCKING(c[x]);
03115 }
03116
03117 for (x = 0; x < nfds; x++) {
03118 fdmap[max].chan = -1;
03119 max += ast_add_fd(&pfds[max], fds[x]);
03120 }
03121
03122 if (*ms > 0)
03123 start = ast_tvnow();
03124
03125 if (sizeof(int) == 4) {
03126 do {
03127 int kbrms = rms;
03128 if (kbrms > 600000)
03129 kbrms = 600000;
03130 res = ast_poll(pfds, max, kbrms);
03131 if (!res)
03132 rms -= kbrms;
03133 } while (!res && (rms > 0));
03134 } else {
03135 res = ast_poll(pfds, max, rms);
03136 }
03137 for (x = 0; x < n; x++)
03138 ast_clear_flag(c[x], AST_FLAG_BLOCKING);
03139 if (res < 0) {
03140 if (errno != EINTR)
03141 *ms = -1;
03142 return NULL;
03143 }
03144 if (!ast_tvzero(whentohangup)) {
03145 now = ast_tvnow();
03146 for (x = 0; x < n; x++) {
03147 if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) {
03148 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03149 if (winner == NULL)
03150 winner = c[x];
03151 }
03152 }
03153 }
03154 if (res == 0) {
03155 *ms = 0;
03156 return winner;
03157 }
03158
03159
03160
03161
03162
03163 for (x = 0; x < max; x++) {
03164 res = pfds[x].revents;
03165 if (res == 0)
03166 continue;
03167 if (fdmap[x].chan >= 0) {
03168 winner = c[fdmap[x].chan];
03169 if (res & POLLPRI)
03170 ast_set_flag(winner, AST_FLAG_EXCEPTION);
03171 else
03172 ast_clear_flag(winner, AST_FLAG_EXCEPTION);
03173 winner->fdno = fdmap[x].fdno;
03174 } else {
03175 if (outfd)
03176 *outfd = pfds[x].fd;
03177 if (exception)
03178 *exception = (res & POLLPRI) ? -1 : 0;
03179 winner = NULL;
03180 }
03181 }
03182 if (*ms > 0) {
03183 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03184 if (*ms < 0)
03185 *ms = 0;
03186 }
03187 return winner;
03188 }
03189
03190 #ifdef HAVE_EPOLL
03191 static struct ast_channel *ast_waitfor_nandfds_simple(struct ast_channel *chan, int *ms)
03192 {
03193 struct timeval start = { 0 , 0 };
03194 int res = 0;
03195 struct epoll_event ev[1];
03196 long diff, rms = *ms;
03197 struct ast_channel *winner = NULL;
03198 struct ast_epoll_data *aed = NULL;
03199
03200
03201
03202 if (chan->masq && ast_do_masquerade(chan)) {
03203 ast_log(LOG_WARNING, "Failed to perform masquerade on %s\n", chan->name);
03204 *ms = -1;
03205 return NULL;
03206 }
03207
03208 ast_channel_lock(chan);
03209
03210 if (!ast_tvzero(chan->whentohangup)) {
03211 if ((diff = ast_tvdiff_ms(chan->whentohangup, ast_tvnow())) < 0) {
03212
03213 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03214 ast_channel_unlock(chan);
03215 return NULL;
03216 }
03217
03218 if (rms > diff)
03219 rms = diff;
03220 }
03221
03222 ast_channel_unlock(chan);
03223
03224
03225 CHECK_BLOCKING(chan);
03226
03227 if (*ms > 0)
03228 start = ast_tvnow();
03229
03230
03231 res = epoll_wait(chan->epfd, ev, 1, rms);
03232
03233
03234 ast_clear_flag(chan, AST_FLAG_BLOCKING);
03235
03236
03237 if (res < 0) {
03238 if (errno != EINTR)
03239 *ms = -1;
03240 return NULL;
03241 }
03242
03243
03244 if (!ast_tvzero(chan->whentohangup)) {
03245 if (ast_tvdiff_ms(ast_tvnow(), chan->whentohangup) >= 0) {
03246 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03247 winner = chan;
03248 }
03249 }
03250
03251
03252 if (!res) {
03253 *ms = 0;
03254 return winner;
03255 }
03256
03257
03258 aed = ev[0].data.ptr;
03259 chan->fdno = aed->which;
03260 if (ev[0].events & EPOLLPRI)
03261 ast_set_flag(chan, AST_FLAG_EXCEPTION);
03262 else
03263 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03264
03265 if (*ms > 0) {
03266 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03267 if (*ms < 0)
03268 *ms = 0;
03269 }
03270
03271 return chan;
03272 }
03273
03274 static struct ast_channel *ast_waitfor_nandfds_complex(struct ast_channel **c, int n, int *ms)
03275 {
03276 struct timeval start = { 0 , 0 };
03277 int res = 0, i;
03278 struct epoll_event ev[25] = { { 0, } };
03279 struct timeval now = { 0, 0 };
03280 long whentohangup = 0, diff = 0, rms = *ms;
03281 struct ast_channel *winner = NULL;
03282
03283 for (i = 0; i < n; i++) {
03284 if (c[i]->masq && ast_do_masquerade(c[i])) {
03285 ast_log(LOG_WARNING, "Masquerade failed\n");
03286 *ms = -1;
03287 return NULL;
03288 }
03289
03290 ast_channel_lock(c[i]);
03291 if (!ast_tvzero(c[i]->whentohangup)) {
03292 if (whentohangup == 0)
03293 now = ast_tvnow();
03294 if ((diff = ast_tvdiff_ms(c[i]->whentohangup, now)) < 0) {
03295 c[i]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03296 ast_channel_unlock(c[i]);
03297 return c[i];
03298 }
03299 if (!whentohangup || whentohangup > diff)
03300 whentohangup = diff;
03301 }
03302 ast_channel_unlock(c[i]);
03303 CHECK_BLOCKING(c[i]);
03304 }
03305
03306 rms = *ms;
03307 if (whentohangup) {
03308 rms = whentohangup;
03309 if (*ms >= 0 && *ms < rms)
03310 rms = *ms;
03311 }
03312
03313 if (*ms > 0)
03314 start = ast_tvnow();
03315
03316 res = epoll_wait(c[0]->epfd, ev, 25, rms);
03317
03318 for (i = 0; i < n; i++)
03319 ast_clear_flag(c[i], AST_FLAG_BLOCKING);
03320
03321 if (res < 0) {
03322 if (errno != EINTR)
03323 *ms = -1;
03324 return NULL;
03325 }
03326
03327 if (whentohangup) {
03328 now = ast_tvnow();
03329 for (i = 0; i < n; i++) {
03330 if (!ast_tvzero(c[i]->whentohangup) && ast_tvdiff_ms(now, c[i]->whentohangup) >= 0) {
03331 c[i]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03332 if (!winner)
03333 winner = c[i];
03334 }
03335 }
03336 }
03337
03338 if (!res) {
03339 *ms = 0;
03340 return winner;
03341 }
03342
03343 for (i = 0; i < res; i++) {
03344 struct ast_epoll_data *aed = ev[i].data.ptr;
03345
03346 if (!ev[i].events || !aed)
03347 continue;
03348
03349 winner = aed->chan;
03350 if (ev[i].events & EPOLLPRI)
03351 ast_set_flag(winner, AST_FLAG_EXCEPTION);
03352 else
03353 ast_clear_flag(winner, AST_FLAG_EXCEPTION);
03354 winner->fdno = aed->which;
03355 }
03356
03357 if (*ms > 0) {
03358 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03359 if (*ms < 0)
03360 *ms = 0;
03361 }
03362
03363 return winner;
03364 }
03365
03366 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
03367 int *exception, int *outfd, int *ms)
03368 {
03369
03370 if (outfd)
03371 *outfd = -99999;
03372 if (exception)
03373 *exception = 0;
03374
03375
03376 if (!n || nfds || c[0]->epfd == -1)
03377 return ast_waitfor_nandfds_classic(c, n, fds, nfds, exception, outfd, ms);
03378 else if (!nfds && n == 1)
03379 return ast_waitfor_nandfds_simple(c[0], ms);
03380 else
03381 return ast_waitfor_nandfds_complex(c, n, ms);
03382 }
03383 #endif
03384
03385 struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
03386 {
03387 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
03388 }
03389
03390 int ast_waitfor(struct ast_channel *c, int ms)
03391 {
03392 int oldms = ms;
03393
03394 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
03395 if ((ms < 0) && (oldms < 0))
03396 ms = 0;
03397 return ms;
03398 }
03399
03400
03401 int ast_waitfordigit(struct ast_channel *c, int ms)
03402 {
03403 return ast_waitfordigit_full(c, ms, -1, -1);
03404 }
03405
03406 int ast_settimeout(struct ast_channel *c, unsigned int rate, int (*func)(const void *data), void *data)
03407 {
03408 int res;
03409 unsigned int real_rate = rate, max_rate;
03410
03411 ast_channel_lock(c);
03412
03413 if (c->timingfd == -1) {
03414 ast_channel_unlock(c);
03415 return -1;
03416 }
03417
03418 if (!func) {
03419 rate = 0;
03420 data = NULL;
03421 }
03422
03423 if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) {
03424 real_rate = max_rate;
03425 }
03426
03427 ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate);
03428
03429 res = ast_timer_set_rate(c->timer, real_rate);
03430
03431 c->timingfunc = func;
03432 c->timingdata = data;
03433
03434 ast_channel_unlock(c);
03435
03436 return res;
03437 }
03438
03439 int ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
03440 {
03441
03442 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03443 return -1;
03444
03445
03446 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
03447
03448
03449
03450 while (ms) {
03451 struct ast_channel *rchan;
03452 int outfd=-1;
03453
03454 errno = 0;
03455 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
03456
03457 if (!rchan && outfd < 0 && ms) {
03458 if (errno == 0 || errno == EINTR)
03459 continue;
03460 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
03461 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03462 return -1;
03463 } else if (outfd > -1) {
03464
03465 ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n");
03466 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03467 return 1;
03468 } else if (rchan) {
03469 int res;
03470 struct ast_frame *f = ast_read(c);
03471 if (!f)
03472 return -1;
03473
03474 switch (f->frametype) {
03475 case AST_FRAME_DTMF_BEGIN:
03476 break;
03477 case AST_FRAME_DTMF_END:
03478 res = f->subclass.integer;
03479 ast_frfree(f);
03480 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03481 return res;
03482 case AST_FRAME_CONTROL:
03483 switch (f->subclass.integer) {
03484 case AST_CONTROL_HANGUP:
03485 ast_frfree(f);
03486 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03487 return -1;
03488 case AST_CONTROL_RINGING:
03489 case AST_CONTROL_ANSWER:
03490 case AST_CONTROL_SRCUPDATE:
03491 case AST_CONTROL_SRCCHANGE:
03492 case AST_CONTROL_CONNECTED_LINE:
03493 case AST_CONTROL_REDIRECTING:
03494 case -1:
03495
03496 break;
03497 default:
03498 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer);
03499 break;
03500 }
03501 break;
03502 case AST_FRAME_VOICE:
03503
03504 if (audiofd > -1) {
03505 if (write(audiofd, f->data.ptr, f->datalen) < 0) {
03506 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
03507 }
03508 }
03509 default:
03510
03511 break;
03512 }
03513 ast_frfree(f);
03514 }
03515 }
03516
03517 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03518
03519 return 0;
03520 }
03521
03522 static void send_dtmf_event(struct ast_channel *chan, const char *direction, const char digit, const char *begin, const char *end)
03523 {
03524 ast_manager_event(chan, EVENT_FLAG_DTMF,
03525 "DTMF",
03526 "Channel: %s\r\n"
03527 "Uniqueid: %s\r\n"
03528 "Digit: %c\r\n"
03529 "Direction: %s\r\n"
03530 "Begin: %s\r\n"
03531 "End: %s\r\n",
03532 chan->name, chan->uniqueid, digit, direction, begin, end);
03533 }
03534
03535 static void ast_read_generator_actions(struct ast_channel *chan, struct ast_frame *f)
03536 {
03537 if (chan->generator && chan->generator->generate && chan->generatordata && !ast_internal_timing_enabled(chan)) {
03538 void *tmp = chan->generatordata;
03539 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = chan->generator->generate;
03540 int res;
03541 int samples;
03542
03543 if (chan->timingfunc) {
03544 ast_debug(1, "Generator got voice, switching to phase locked mode\n");
03545 ast_settimeout(chan, 0, NULL, NULL);
03546 }
03547
03548 chan->generatordata = NULL;
03549
03550 if (f->subclass.codec != chan->writeformat) {
03551 float factor;
03552 factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass.codec));
03553 samples = (int) ( ((float) f->samples) * factor );
03554 } else {
03555 samples = f->samples;
03556 }
03557
03558
03559
03560
03561
03562
03563
03564
03565
03566 ast_channel_unlock(chan);
03567 res = generate(chan, tmp, f->datalen, samples);
03568 ast_channel_lock(chan);
03569 chan->generatordata = tmp;
03570 if (res) {
03571 ast_debug(1, "Auto-deactivating generator\n");
03572 ast_deactivate_generator(chan);
03573 }
03574
03575 } else if (f->frametype == AST_FRAME_CNG) {
03576 if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
03577 ast_debug(1, "Generator got CNG, switching to timed mode\n");
03578 ast_settimeout(chan, 50, generator_force, chan);
03579 }
03580 }
03581 }
03582
03583 static inline void queue_dtmf_readq(struct ast_channel *chan, struct ast_frame *f)
03584 {
03585 struct ast_frame *fr = &chan->dtmff;
03586
03587 fr->frametype = AST_FRAME_DTMF_END;
03588 fr->subclass.integer = f->subclass.integer;
03589 fr->len = f->len;
03590
03591
03592
03593
03594
03595 ast_queue_frame(chan, fr);
03596 }
03597
03598
03599
03600
03601 static inline int should_skip_dtmf(struct ast_channel *chan)
03602 {
03603 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) {
03604
03605
03606 return 1;
03607 }
03608
03609 if (!ast_tvzero(chan->dtmf_tv) &&
03610 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
03611
03612
03613 return 1;
03614 }
03615
03616 return 0;
03617 }
03618
03619
03620
03621
03622
03623
03624
03625
03626
03627
03628 static inline int calc_monitor_jump(int samples, int sample_rate, int seek_rate)
03629 {
03630 int diff = sample_rate - seek_rate;
03631
03632 if (diff > 0) {
03633 samples = samples / (float) (sample_rate / seek_rate);
03634 } else if (diff < 0) {
03635 samples = samples * (float) (seek_rate / sample_rate);
03636 }
03637
03638 return samples;
03639 }
03640
03641 static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
03642 {
03643 struct ast_frame *f = NULL;
03644 int blah;
03645 int prestate;
03646 int cause = 0;
03647
03648
03649
03650
03651
03652 if (chan->masq) {
03653 if (ast_do_masquerade(chan))
03654 ast_log(LOG_WARNING, "Failed to perform masquerade\n");
03655 else
03656 f = &ast_null_frame;
03657 return f;
03658 }
03659
03660
03661 ast_channel_lock(chan);
03662
03663
03664 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
03665 if (chan->generator)
03666 ast_deactivate_generator(chan);
03667
03668
03669
03670
03671
03672
03673
03674
03675
03676
03677 if (chan->_softhangup) {
03678 ast_queue_control(chan, AST_CONTROL_END_OF_Q);
03679 } else {
03680 goto done;
03681 }
03682 }
03683
03684 #ifdef AST_DEVMODE
03685
03686
03687
03688
03689
03690
03691
03692
03693 if (chan->fdno == -1) {
03694 ast_log(LOG_ERROR,
03695 "ast_read() on chan '%s' called with no recorded file descriptor.\n",
03696 chan->name);
03697 }
03698 #endif
03699
03700 prestate = chan->_state;
03701
03702
03703
03704 if (chan->alertpipe[0] > -1) {
03705 int flags = fcntl(chan->alertpipe[0], F_GETFL);
03706
03707
03708 if ((flags & O_NONBLOCK) == 0) {
03709 ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", chan->name);
03710 if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
03711 ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
03712 f = &ast_null_frame;
03713 goto done;
03714 }
03715 }
03716 if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) {
03717 if (errno != EINTR && errno != EAGAIN)
03718 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
03719 }
03720 }
03721
03722 if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD) {
03723 enum ast_timer_event res;
03724
03725 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03726
03727 res = ast_timer_get_event(chan->timer);
03728
03729 switch (res) {
03730 case AST_TIMING_EVENT_EXPIRED:
03731 ast_timer_ack(chan->timer, 1);
03732
03733 if (chan->timingfunc) {
03734
03735 int (*func)(const void *) = chan->timingfunc;
03736 void *data = chan->timingdata;
03737 chan->fdno = -1;
03738 ast_channel_unlock(chan);
03739 func(data);
03740 } else {
03741 ast_timer_set_rate(chan->timer, 0);
03742 chan->fdno = -1;
03743 ast_channel_unlock(chan);
03744 }
03745
03746
03747 return &ast_null_frame;
03748
03749 case AST_TIMING_EVENT_CONTINUOUS:
03750 if (AST_LIST_EMPTY(&chan->readq) ||
03751 !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
03752 ast_timer_disable_continuous(chan->timer);
03753 }
03754 break;
03755 }
03756
03757 } else if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
03758
03759
03760
03761 void *tmp = chan->generatordata;
03762 chan->generatordata = NULL;
03763 chan->generator->generate(chan, tmp, -1, -1);
03764 chan->generatordata = tmp;
03765 f = &ast_null_frame;
03766 chan->fdno = -1;
03767 goto done;
03768 }
03769
03770
03771 if (!AST_LIST_EMPTY(&chan->readq)) {
03772 int skip_dtmf = should_skip_dtmf(chan);
03773
03774 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, f, frame_list) {
03775
03776
03777
03778
03779 if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) {
03780 continue;
03781 }
03782
03783 AST_LIST_REMOVE_CURRENT(frame_list);
03784 break;
03785 }
03786 AST_LIST_TRAVERSE_SAFE_END;
03787
03788 if (!f) {
03789
03790 f = &ast_null_frame;
03791 if (chan->alertpipe[0] > -1) {
03792 int poke = 0;
03793
03794
03795 if (write(chan->alertpipe[1], &poke, sizeof(poke)) != sizeof(poke)) {
03796 ast_log(LOG_ERROR, "Failed to write to alertpipe: %s\n", strerror(errno));
03797 }
03798 }
03799 }
03800
03801
03802
03803 if (f->frametype == AST_FRAME_CONTROL) {
03804 switch (f->subclass.integer) {
03805 case AST_CONTROL_HANGUP:
03806 chan->_softhangup |= AST_SOFTHANGUP_DEV;
03807 cause = f->data.uint32;
03808
03809 case AST_CONTROL_END_OF_Q:
03810 ast_frfree(f);
03811 f = NULL;
03812 break;
03813 default:
03814 break;
03815 }
03816 }
03817 } else {
03818 chan->blocker = pthread_self();
03819 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
03820 if (chan->tech->exception)
03821 f = chan->tech->exception(chan);
03822 else {
03823 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
03824 f = &ast_null_frame;
03825 }
03826
03827 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03828 } else if (chan->tech->read)
03829 f = chan->tech->read(chan);
03830 else
03831 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
03832 }
03833
03834
03835
03836
03837
03838 chan->fdno = -1;
03839
03840
03841
03842 f = ast_framehook_list_read_event(chan->framehooks, f);
03843
03844 if (f) {
03845 struct ast_frame *readq_tail = AST_LIST_LAST(&chan->readq);
03846 struct ast_control_read_action_payload *read_action_payload;
03847 struct ast_party_connected_line connected;
03848
03849
03850
03851
03852 if (AST_LIST_NEXT(f, frame_list)) {
03853 ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list));
03854 ast_frfree(AST_LIST_NEXT(f, frame_list));
03855 AST_LIST_NEXT(f, frame_list) = NULL;
03856 }
03857
03858 switch (f->frametype) {
03859 case AST_FRAME_CONTROL:
03860 if (f->subclass.integer == AST_CONTROL_ANSWER) {
03861 if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
03862 ast_debug(1, "Ignoring answer on an inbound call!\n");
03863 ast_frfree(f);
03864 f = &ast_null_frame;
03865 } else if (prestate == AST_STATE_UP && ast_bridged_channel(chan)) {
03866 ast_debug(1, "Dropping duplicate answer!\n");
03867 ast_frfree(f);
03868 f = &ast_null_frame;
03869 } else {
03870
03871 ast_setstate(chan, AST_STATE_UP);
03872
03873 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
03874 }
03875 } else if (f->subclass.integer == AST_CONTROL_READ_ACTION) {
03876 read_action_payload = f->data.ptr;
03877 switch (read_action_payload->action) {
03878 case AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO:
03879 ast_party_connected_line_init(&connected);
03880 ast_party_connected_line_copy(&connected, &chan->connected);
03881 if (ast_connected_line_parse_data(read_action_payload->payload,
03882 read_action_payload->payload_size, &connected)) {
03883 ast_party_connected_line_free(&connected);
03884 break;
03885 }
03886 if (ast_channel_connected_line_macro(NULL, chan, &connected, 1, 0)) {
03887 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE,
03888 read_action_payload->payload,
03889 read_action_payload->payload_size);
03890 }
03891 ast_party_connected_line_free(&connected);
03892 break;
03893 }
03894 ast_frfree(f);
03895 f = &ast_null_frame;
03896 }
03897 break;
03898 case AST_FRAME_DTMF_END:
03899 send_dtmf_event(chan, "Received", f->subclass.integer, "No", "Yes");
03900 ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass.integer, chan->name, f->len);
03901
03902 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) || ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
03903 queue_dtmf_readq(chan, f);
03904 ast_frfree(f);
03905 f = &ast_null_frame;
03906 } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
03907 if (!ast_tvzero(chan->dtmf_tv) &&
03908 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
03909
03910 queue_dtmf_readq(chan, f);
03911 ast_frfree(f);
03912 f = &ast_null_frame;
03913 } else {
03914
03915 f->frametype = AST_FRAME_DTMF_BEGIN;
03916 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
03917 chan->emulate_dtmf_digit = f->subclass.integer;
03918 chan->dtmf_tv = ast_tvnow();
03919 if (f->len) {
03920 if (f->len > AST_MIN_DTMF_DURATION)
03921 chan->emulate_dtmf_duration = f->len;
03922 else
03923 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
03924 } else
03925 chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
03926 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);
03927 }
03928 if (chan->audiohooks) {
03929 struct ast_frame *old_frame = f;
03930
03931
03932
03933 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
03934 if (old_frame != f)
03935 ast_frfree(old_frame);
03936 }
03937 } else {
03938 struct timeval now = ast_tvnow();
03939 if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
03940 ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass.integer, chan->name);
03941 ast_clear_flag(chan, AST_FLAG_IN_DTMF);
03942 if (!f->len)
03943 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
03944
03945
03946
03947
03948
03949
03950
03951
03952
03953 if (ast_tvdiff_ms(now, chan->dtmf_tv) < AST_MIN_DTMF_DURATION) {
03954 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
03955 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);
03956 }
03957 } else if (!f->len) {
03958 ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass.integer, chan->name);
03959 f->len = AST_MIN_DTMF_DURATION;
03960 }
03961 if (f->len < AST_MIN_DTMF_DURATION && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) {
03962 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);
03963 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
03964 chan->emulate_dtmf_digit = f->subclass.integer;
03965 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len;
03966 ast_frfree(f);
03967 f = &ast_null_frame;
03968 } else {
03969 ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass.integer, chan->name);
03970 if (f->len < AST_MIN_DTMF_DURATION) {
03971 f->len = AST_MIN_DTMF_DURATION;
03972 }
03973 chan->dtmf_tv = now;
03974 }
03975 if (chan->audiohooks) {
03976 struct ast_frame *old_frame = f;
03977 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
03978 if (old_frame != f)
03979 ast_frfree(old_frame);
03980 }
03981 }
03982 break;
03983 case AST_FRAME_DTMF_BEGIN:
03984 send_dtmf_event(chan, "Received", f->subclass.integer, "Yes", "No");
03985 ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass.integer, chan->name);
03986 if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) ||
03987 (!ast_tvzero(chan->dtmf_tv) &&
03988 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
03989 ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass.integer, chan->name);
03990 ast_frfree(f);
03991 f = &ast_null_frame;
03992 } else {
03993 ast_set_flag(chan, AST_FLAG_IN_DTMF);
03994 chan->dtmf_tv = ast_tvnow();
03995 ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass.integer, chan->name);
03996 }
03997 break;
03998 case AST_FRAME_NULL:
03999
04000
04001
04002
04003 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
04004 struct timeval now = ast_tvnow();
04005 if (!chan->emulate_dtmf_duration) {
04006 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
04007 chan->emulate_dtmf_digit = 0;
04008 } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
04009 chan->emulate_dtmf_duration = 0;
04010 ast_frfree(f);
04011 f = &chan->dtmff;
04012 f->frametype = AST_FRAME_DTMF_END;
04013 f->subclass.integer = chan->emulate_dtmf_digit;
04014 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
04015 chan->dtmf_tv = now;
04016 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
04017 chan->emulate_dtmf_digit = 0;
04018 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, chan->name);
04019 if (chan->audiohooks) {
04020 struct ast_frame *old_frame = f;
04021 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04022 if (old_frame != f) {
04023 ast_frfree(old_frame);
04024 }
04025 }
04026 }
04027 }
04028 break;
04029 case AST_FRAME_VOICE:
04030
04031
04032
04033
04034 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) {
04035 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
04036 chan->emulate_dtmf_digit = 0;
04037 }
04038
04039 if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
04040 if (dropaudio)
04041 ast_read_generator_actions(chan, f);
04042 ast_frfree(f);
04043 f = &ast_null_frame;
04044 }
04045
04046 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
04047 struct timeval now = ast_tvnow();
04048 if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
04049 chan->emulate_dtmf_duration = 0;
04050 ast_frfree(f);
04051 f = &chan->dtmff;
04052 f->frametype = AST_FRAME_DTMF_END;
04053 f->subclass.integer = chan->emulate_dtmf_digit;
04054 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
04055 chan->dtmf_tv = now;
04056 if (chan->audiohooks) {
04057 struct ast_frame *old_frame = f;
04058 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04059 if (old_frame != f)
04060 ast_frfree(old_frame);
04061 }
04062 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, chan->name);
04063 } else {
04064
04065 ast_frfree(f);
04066 f = &ast_null_frame;
04067 }
04068 } else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass.codec & chan->nativeformats)) {
04069
04070 char to[200];
04071 ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
04072 chan->name, ast_getformatname(f->subclass.codec), ast_getformatname_multiple(to, sizeof(to), chan->nativeformats));
04073 ast_frfree(f);
04074 f = &ast_null_frame;
04075 } else if ((f->frametype == AST_FRAME_VOICE)) {
04076
04077 if (chan->audiohooks) {
04078 struct ast_frame *old_frame = f;
04079 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04080 if (old_frame != f)
04081 ast_frfree(old_frame);
04082 }
04083 if (chan->monitor && chan->monitor->read_stream ) {
04084
04085 #ifndef MONITOR_CONSTANT_DELAY
04086 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
04087 if (jump >= 0) {
04088 jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
04089 if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
04090 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
04091 chan->insmpl += (chan->outsmpl - chan->insmpl) + f->samples;
04092 } else
04093 chan->insmpl+= f->samples;
04094 #else
04095 int jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
04096 if (jump - MONITOR_DELAY >= 0) {
04097 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
04098 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
04099 chan->insmpl += chan->outsmpl - chan->insmpl;
04100 } else
04101 chan->insmpl += f->samples;
04102 #endif
04103 if (chan->monitor->state == AST_MONITOR_RUNNING) {
04104 if (ast_writestream(chan->monitor->read_stream, f) < 0)
04105 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
04106 }
04107 }
04108
04109 if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL) {
04110 f = &ast_null_frame;
04111 }
04112
04113
04114
04115
04116
04117
04118
04119
04120 if (AST_LIST_NEXT(f, frame_list)) {
04121 if (!readq_tail) {
04122 ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list));
04123 } else {
04124 __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail);
04125 }
04126 ast_frfree(AST_LIST_NEXT(f, frame_list));
04127 AST_LIST_NEXT(f, frame_list) = NULL;
04128 }
04129
04130
04131
04132 ast_read_generator_actions(chan, f);
04133 }
04134 break;
04135 default:
04136
04137 break;
04138 }
04139 } else {
04140
04141 if (!chan->_softhangup) {
04142 chan->_softhangup |= AST_SOFTHANGUP_DEV;
04143 }
04144 if (cause)
04145 chan->hangupcause = cause;
04146 if (chan->generator)
04147 ast_deactivate_generator(chan);
04148
04149 }
04150
04151
04152 if (chan->fin & DEBUGCHAN_FLAG)
04153 ast_frame_dump(chan->name, f, "<<");
04154 chan->fin = FRAMECOUNT_INC(chan->fin);
04155
04156 done:
04157 if (chan->music_state && chan->generator && chan->generator->digit && f && f->frametype == AST_FRAME_DTMF_END)
04158 chan->generator->digit(chan, f->subclass.integer);
04159
04160 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) {
04161
04162 ast_audiohook_detach_list(chan->audiohooks);
04163 chan->audiohooks = NULL;
04164 }
04165 ast_channel_unlock(chan);
04166 return f;
04167 }
04168
04169 int ast_internal_timing_enabled(struct ast_channel *chan)
04170 {
04171 return (ast_opt_internal_timing && chan->timingfd > -1);
04172 }
04173
04174 struct ast_frame *ast_read(struct ast_channel *chan)
04175 {
04176 return __ast_read(chan, 0);
04177 }
04178
04179 struct ast_frame *ast_read_noaudio(struct ast_channel *chan)
04180 {
04181 return __ast_read(chan, 1);
04182 }
04183
04184 int ast_indicate(struct ast_channel *chan, int condition)
04185 {
04186 return ast_indicate_data(chan, condition, NULL, 0);
04187 }
04188
04189 static int attribute_const is_visible_indication(enum ast_control_frame_type condition)
04190 {
04191
04192
04193
04194 switch (condition) {
04195 case AST_CONTROL_PROGRESS:
04196 case AST_CONTROL_PROCEEDING:
04197 case AST_CONTROL_VIDUPDATE:
04198 case AST_CONTROL_SRCUPDATE:
04199 case AST_CONTROL_SRCCHANGE:
04200 case AST_CONTROL_RADIO_KEY:
04201 case AST_CONTROL_RADIO_UNKEY:
04202 case AST_CONTROL_OPTION:
04203 case AST_CONTROL_WINK:
04204 case AST_CONTROL_FLASH:
04205 case AST_CONTROL_OFFHOOK:
04206 case AST_CONTROL_TAKEOFFHOOK:
04207 case AST_CONTROL_ANSWER:
04208 case AST_CONTROL_HANGUP:
04209 case AST_CONTROL_CONNECTED_LINE:
04210 case AST_CONTROL_REDIRECTING:
04211 case AST_CONTROL_TRANSFER:
04212 case AST_CONTROL_T38_PARAMETERS:
04213 case _XXX_AST_CONTROL_T38:
04214 case AST_CONTROL_CC:
04215 case AST_CONTROL_READ_ACTION:
04216 case AST_CONTROL_AOC:
04217 case AST_CONTROL_END_OF_Q:
04218 break;
04219
04220 case AST_CONTROL_CONGESTION:
04221 case AST_CONTROL_BUSY:
04222 case AST_CONTROL_RINGING:
04223 case AST_CONTROL_RING:
04224 case AST_CONTROL_HOLD:
04225
04226 return 1;
04227
04228 case AST_CONTROL_UNHOLD:
04229
04230 break;
04231 }
04232
04233 return 0;
04234 }
04235
04236 int ast_indicate_data(struct ast_channel *chan, int _condition,
04237 const void *data, size_t datalen)
04238 {
04239
04240
04241 enum ast_control_frame_type condition = _condition;
04242 struct ast_tone_zone_sound *ts = NULL;
04243 int res;
04244
04245 struct ast_frame *awesome_frame = NULL;
04246
04247 ast_channel_lock(chan);
04248
04249
04250 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
04251 res = -1;
04252 goto indicate_cleanup;
04253 }
04254
04255 if (!ast_framehook_list_is_empty(chan->framehooks)) {
04256
04257 struct ast_frame frame = {
04258 .frametype = AST_FRAME_CONTROL,
04259 .subclass.integer = condition,
04260 .data.ptr = (void *) data,
04261 .datalen = datalen
04262 };
04263
04264
04265 awesome_frame = ast_frdup(&frame);
04266
04267
04268 if (!(awesome_frame = ast_framehook_list_read_event(chan->framehooks, &frame))) {
04269 res = 0;
04270 goto indicate_cleanup;
04271 }
04272
04273 condition = awesome_frame->subclass.integer;
04274 data = awesome_frame->data.ptr;
04275 datalen = awesome_frame->datalen;
04276 }
04277
04278 switch (condition) {
04279 case AST_CONTROL_CONNECTED_LINE:
04280 {
04281 struct ast_party_connected_line connected;
04282
04283 ast_party_connected_line_set_init(&connected, &chan->connected);
04284 res = ast_connected_line_parse_data(data, datalen, &connected);
04285 if (!res) {
04286 ast_channel_set_connected_line(chan, &connected, NULL);
04287 }
04288 ast_party_connected_line_free(&connected);
04289 }
04290 break;
04291
04292 case AST_CONTROL_REDIRECTING:
04293 {
04294 struct ast_party_redirecting redirecting;
04295
04296 ast_party_redirecting_set_init(&redirecting, &chan->redirecting);
04297 res = ast_redirecting_parse_data(data, datalen, &redirecting);
04298 if (!res) {
04299 ast_channel_set_redirecting(chan, &redirecting, NULL);
04300 }
04301 ast_party_redirecting_free(&redirecting);
04302 }
04303 break;
04304
04305 default:
04306 break;
04307 }
04308
04309 if (is_visible_indication(condition)) {
04310
04311 chan->visible_indication = condition;
04312 } else if (condition == AST_CONTROL_UNHOLD || _condition < 0) {
04313
04314 chan->visible_indication = 0;
04315 }
04316
04317 if (chan->tech->indicate) {
04318
04319 res = chan->tech->indicate(chan, condition, data, datalen);
04320 } else {
04321 res = -1;
04322 }
04323
04324 if (!res) {
04325
04326 res = 0;
04327 goto indicate_cleanup;
04328 }
04329
04330
04331
04332
04333
04334
04335
04336 if (_condition < 0) {
04337
04338 ast_playtones_stop(chan);
04339 res = 0;
04340 goto indicate_cleanup;
04341 }
04342
04343
04344 switch (condition) {
04345 case _XXX_AST_CONTROL_T38:
04346
04347 res = -1;
04348 goto indicate_cleanup;
04349 case AST_CONTROL_T38_PARAMETERS:
04350
04351
04352
04353
04354
04355
04356
04357 goto indicate_cleanup;
04358 case AST_CONTROL_RINGING:
04359 ts = ast_get_indication_tone(chan->zone, "ring");
04360
04361
04362
04363
04364
04365
04366
04367 if (chan->_state == AST_STATE_UP) {
04368 res = 0;
04369 }
04370 break;
04371 case AST_CONTROL_BUSY:
04372 ts = ast_get_indication_tone(chan->zone, "busy");
04373 break;
04374 case AST_CONTROL_CONGESTION:
04375 ts = ast_get_indication_tone(chan->zone, "congestion");
04376 break;
04377 case AST_CONTROL_PROGRESS:
04378 case AST_CONTROL_PROCEEDING:
04379 case AST_CONTROL_VIDUPDATE:
04380 case AST_CONTROL_SRCUPDATE:
04381 case AST_CONTROL_SRCCHANGE:
04382 case AST_CONTROL_RADIO_KEY:
04383 case AST_CONTROL_RADIO_UNKEY:
04384 case AST_CONTROL_OPTION:
04385 case AST_CONTROL_WINK:
04386 case AST_CONTROL_FLASH:
04387 case AST_CONTROL_OFFHOOK:
04388 case AST_CONTROL_TAKEOFFHOOK:
04389 case AST_CONTROL_ANSWER:
04390 case AST_CONTROL_HANGUP:
04391 case AST_CONTROL_RING:
04392 case AST_CONTROL_HOLD:
04393 case AST_CONTROL_UNHOLD:
04394 case AST_CONTROL_TRANSFER:
04395 case AST_CONTROL_CONNECTED_LINE:
04396 case AST_CONTROL_REDIRECTING:
04397 case AST_CONTROL_CC:
04398 case AST_CONTROL_READ_ACTION:
04399 case AST_CONTROL_AOC:
04400 case AST_CONTROL_END_OF_Q:
04401
04402 res = 0;
04403 break;
04404 }
04405
04406 if (ts) {
04407
04408 ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
04409 res = ast_playtones_start(chan, 0, ts->data, 1);
04410 ts = ast_tone_zone_sound_unref(ts);
04411 }
04412
04413 if (res) {
04414
04415 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
04416 }
04417
04418 indicate_cleanup:
04419 ast_channel_unlock(chan);
04420 if (awesome_frame) {
04421 ast_frfree(awesome_frame);
04422 }
04423
04424 return res;
04425 }
04426
04427 int ast_recvchar(struct ast_channel *chan, int timeout)
04428 {
04429 int c;
04430 char *buf = ast_recvtext(chan, timeout);
04431 if (buf == NULL)
04432 return -1;
04433 c = *(unsigned char *)buf;
04434 ast_free(buf);
04435 return c;
04436 }
04437
04438 char *ast_recvtext(struct ast_channel *chan, int timeout)
04439 {
04440 int res, done = 0;
04441 char *buf = NULL;
04442
04443 while (!done) {
04444 struct ast_frame *f;
04445 if (ast_check_hangup(chan))
04446 break;
04447 res = ast_waitfor(chan, timeout);
04448 if (res <= 0)
04449 break;
04450 timeout = res;
04451 f = ast_read(chan);
04452 if (f == NULL)
04453 break;
04454 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP)
04455 done = 1;
04456 else if (f->frametype == AST_FRAME_TEXT) {
04457 buf = ast_strndup((char *) f->data.ptr, f->datalen);
04458 done = 1;
04459 }
04460 ast_frfree(f);
04461 }
04462 return buf;
04463 }
04464
04465 int ast_sendtext(struct ast_channel *chan, const char *text)
04466 {
04467 int res = 0;
04468
04469 ast_channel_lock(chan);
04470
04471 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
04472 ast_channel_unlock(chan);
04473 return -1;
04474 }
04475 CHECK_BLOCKING(chan);
04476 if (chan->tech->send_text)
04477 res = chan->tech->send_text(chan, text);
04478 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04479 ast_channel_unlock(chan);
04480 return res;
04481 }
04482
04483 int ast_senddigit_begin(struct ast_channel *chan, char digit)
04484 {
04485
04486
04487 static const char * const dtmf_tones[] = {
04488 "941+1336",
04489 "697+1209",
04490 "697+1336",
04491 "697+1477",
04492 "770+1209",
04493 "770+1336",
04494 "770+1477",
04495 "852+1209",
04496 "852+1336",
04497 "852+1477",
04498 "697+1633",
04499 "770+1633",
04500 "852+1633",
04501 "941+1633",
04502 "941+1209",
04503 "941+1477"
04504 };
04505
04506 if (!chan->tech->send_digit_begin)
04507 return 0;
04508
04509 if (!chan->tech->send_digit_begin(chan, digit))
04510 return 0;
04511
04512 if (digit >= '0' && digit <='9')
04513 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
04514 else if (digit >= 'A' && digit <= 'D')
04515 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
04516 else if (digit == '*')
04517 ast_playtones_start(chan, 0, dtmf_tones[14], 0);
04518 else if (digit == '#')
04519 ast_playtones_start(chan, 0, dtmf_tones[15], 0);
04520 else {
04521
04522 ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
04523 }
04524
04525 return 0;
04526 }
04527
04528 int ast_senddigit_end(struct ast_channel *chan, char digit, unsigned int duration)
04529 {
04530 int res = -1;
04531
04532 if (chan->tech->send_digit_end)
04533 res = chan->tech->send_digit_end(chan, digit, duration);
04534
04535 if (res && chan->generator)
04536 ast_playtones_stop(chan);
04537
04538 return 0;
04539 }
04540
04541 int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration)
04542 {
04543 if (chan->tech->send_digit_begin) {
04544 ast_senddigit_begin(chan, digit);
04545 ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04546 }
04547
04548 return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04549 }
04550
04551 int ast_prod(struct ast_channel *chan)
04552 {
04553 struct ast_frame a = { AST_FRAME_VOICE };
04554 char nothing[128];
04555
04556
04557 if (chan->_state != AST_STATE_UP) {
04558 ast_debug(1, "Prodding channel '%s'\n", chan->name);
04559 a.subclass.codec = chan->rawwriteformat;
04560 a.data.ptr = nothing + AST_FRIENDLY_OFFSET;
04561 a.src = "ast_prod";
04562 if (ast_write(chan, &a))
04563 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
04564 }
04565 return 0;
04566 }
04567
04568 int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
04569 {
04570 int res;
04571 if (!chan->tech->write_video)
04572 return 0;
04573 res = ast_write(chan, fr);
04574 if (!res)
04575 res = 1;
04576 return res;
04577 }
04578
04579 struct plc_ds {
04580
04581
04582
04583
04584 int16_t *samples_buf;
04585
04586
04587
04588 size_t num_samples;
04589 plc_state_t plc_state;
04590 };
04591
04592 static void plc_ds_destroy(void *data)
04593 {
04594 struct plc_ds *plc = data;
04595 ast_free(plc->samples_buf);
04596 ast_free(plc);
04597 }
04598
04599 static struct ast_datastore_info plc_ds_info = {
04600 .type = "plc",
04601 .destroy = plc_ds_destroy,
04602 };
04603
04604 static void adjust_frame_for_plc(struct ast_channel *chan, struct ast_frame *frame, struct ast_datastore *datastore)
04605 {
04606 int num_new_samples = frame->samples;
04607 struct plc_ds *plc = datastore->data;
04608
04609
04610
04611
04612
04613
04614
04615
04616
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627
04628 if (!num_new_samples) {
04629 return;
04630 }
04631
04632
04633
04634
04635
04636 if (plc->num_samples < num_new_samples) {
04637 ast_free(plc->samples_buf);
04638 plc->samples_buf = ast_calloc(1, (num_new_samples * sizeof(*plc->samples_buf)) + (AST_FRIENDLY_OFFSET * 2));
04639 if (!plc->samples_buf) {
04640 ast_channel_datastore_remove(chan, datastore);
04641 ast_datastore_free(datastore);
04642 return;
04643 }
04644 plc->num_samples = num_new_samples;
04645 }
04646
04647 if (frame->datalen == 0) {
04648 plc_fillin(&plc->plc_state, plc->samples_buf + AST_FRIENDLY_OFFSET, frame->samples);
04649 frame->data.ptr = plc->samples_buf + AST_FRIENDLY_OFFSET;
04650 frame->datalen = num_new_samples * 2;
04651 frame->offset = AST_FRIENDLY_OFFSET * 2;
04652 } else {
04653 plc_rx(&plc->plc_state, frame->data.ptr, frame->samples);
04654 }
04655 }
04656
04657 static void apply_plc(struct ast_channel *chan, struct ast_frame *frame)
04658 {
04659 struct ast_datastore *datastore;
04660 struct plc_ds *plc;
04661
04662 datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL);
04663 if (datastore) {
04664 plc = datastore->data;
04665 adjust_frame_for_plc(chan, frame, datastore);
04666 return;
04667 }
04668
04669 datastore = ast_datastore_alloc(&plc_ds_info, NULL);
04670 if (!datastore) {
04671 return;
04672 }
04673 plc = ast_calloc(1, sizeof(*plc));
04674 if (!plc) {
04675 ast_datastore_free(datastore);
04676 return;
04677 }
04678 datastore->data = plc;
04679 ast_channel_datastore_add(chan, datastore);
04680 adjust_frame_for_plc(chan, frame, datastore);
04681 }
04682
04683 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
04684 {
04685 int res = -1;
04686 struct ast_frame *f = NULL;
04687 int count = 0;
04688
04689
04690 while(ast_channel_trylock(chan)) {
04691
04692 if(count++ > 10) {
04693 ast_debug(1, "Deadlock avoided for write to channel '%s'\n", chan->name);
04694 return 0;
04695 }
04696 usleep(1);
04697 }
04698
04699 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
04700 goto done;
04701
04702
04703 if (chan->masq) {
04704 ast_channel_unlock(chan);
04705 if (ast_do_masquerade(chan)) {
04706 ast_log(LOG_WARNING, "Failed to perform masquerade\n");
04707 return res;
04708 }
04709 ast_channel_lock(chan);
04710 }
04711 if (chan->masqr) {
04712 res = 0;
04713 goto done;
04714 }
04715
04716
04717
04718 if (!(fr = ast_framehook_list_write_event(chan->framehooks, fr))) {
04719 res = 0;
04720 goto done;
04721 }
04722
04723 if (chan->generatordata && (!fr->src || strcasecmp(fr->src, "ast_prod"))) {
04724 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) {
04725 ast_deactivate_generator(chan);
04726 } else {
04727 if (fr->frametype == AST_FRAME_DTMF_END) {
04728
04729
04730
04731 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04732 ast_channel_unlock(chan);
04733 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);
04734 ast_channel_lock(chan);
04735 CHECK_BLOCKING(chan);
04736 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_UNHOLD) {
04737
04738 res = (chan->tech->indicate == NULL) ? 0 :
04739 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
04740 }
04741 res = 0;
04742 goto done;
04743 }
04744 }
04745
04746 if (chan->fout & DEBUGCHAN_FLAG)
04747 ast_frame_dump(chan->name, fr, ">>");
04748 CHECK_BLOCKING(chan);
04749 switch (fr->frametype) {
04750 case AST_FRAME_CONTROL:
04751 res = (chan->tech->indicate == NULL) ? 0 :
04752 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
04753 break;
04754 case AST_FRAME_DTMF_BEGIN:
04755 if (chan->audiohooks) {
04756 struct ast_frame *old_frame = fr;
04757 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
04758 if (old_frame != fr)
04759 f = fr;
04760 }
04761 send_dtmf_event(chan, "Sent", fr->subclass.integer, "Yes", "No");
04762 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04763 ast_channel_unlock(chan);
04764 res = ast_senddigit_begin(chan, fr->subclass.integer);
04765 ast_channel_lock(chan);
04766 CHECK_BLOCKING(chan);
04767 break;
04768 case AST_FRAME_DTMF_END:
04769 if (chan->audiohooks) {
04770 struct ast_frame *new_frame = fr;
04771
04772 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
04773 if (new_frame != fr) {
04774 ast_frfree(new_frame);
04775 }
04776 }
04777 send_dtmf_event(chan, "Sent", fr->subclass.integer, "No", "Yes");
04778 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04779 ast_channel_unlock(chan);
04780 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);
04781 ast_channel_lock(chan);
04782 CHECK_BLOCKING(chan);
04783 break;
04784 case AST_FRAME_TEXT:
04785 if (fr->subclass.integer == AST_FORMAT_T140) {
04786 res = (chan->tech->write_text == NULL) ? 0 :
04787 chan->tech->write_text(chan, fr);
04788 } else {
04789 res = (chan->tech->send_text == NULL) ? 0 :
04790 chan->tech->send_text(chan, (char *) fr->data.ptr);
04791 }
04792 break;
04793 case AST_FRAME_HTML:
04794 res = (chan->tech->send_html == NULL) ? 0 :
04795 chan->tech->send_html(chan, fr->subclass.integer, (char *) fr->data.ptr, fr->datalen);
04796 break;
04797 case AST_FRAME_VIDEO:
04798
04799 res = (chan->tech->write_video == NULL) ? 0 :
04800 chan->tech->write_video(chan, fr);
04801 break;
04802 case AST_FRAME_MODEM:
04803 res = (chan->tech->write == NULL) ? 0 :
04804 chan->tech->write(chan, fr);
04805 break;
04806 case AST_FRAME_VOICE:
04807 if (chan->tech->write == NULL)
04808 break;
04809
04810 if (ast_opt_generic_plc && fr->subclass.codec == AST_FORMAT_SLINEAR) {
04811 apply_plc(chan, fr);
04812 }
04813
04814
04815 if (fr->subclass.codec == chan->rawwriteformat)
04816 f = fr;
04817 else
04818 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
04819
04820 if (!f) {
04821 res = 0;
04822 break;
04823 }
04824
04825 if (chan->audiohooks) {
04826 struct ast_frame *prev = NULL, *new_frame, *cur, *dup;
04827 int freeoldlist = 0;
04828
04829 if (f != fr) {
04830 freeoldlist = 1;
04831 }
04832
04833
04834
04835
04836 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
04837 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur);
04838
04839
04840
04841 if (new_frame != cur) {
04842
04843
04844
04845
04846 if ((dup = ast_frisolate(new_frame))) {
04847 AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list);
04848 if (freeoldlist) {
04849 AST_LIST_NEXT(cur, frame_list) = NULL;
04850 ast_frfree(cur);
04851 }
04852 if (new_frame != dup) {
04853 ast_frfree(new_frame);
04854 }
04855 cur = dup;
04856 }
04857 }
04858
04859
04860
04861 if (prev) {
04862 AST_LIST_NEXT(prev, frame_list) = cur;
04863 } else {
04864 f = cur;
04865 }
04866 prev = cur;
04867 }
04868 }
04869
04870
04871
04872
04873
04874 if (chan->monitor && chan->monitor->write_stream) {
04875 struct ast_frame *cur;
04876
04877 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
04878
04879 #ifndef MONITOR_CONSTANT_DELAY
04880 int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples;
04881 if (jump >= 0) {
04882 jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
04883 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
04884 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
04885 chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples;
04886 } else {
04887 chan->outsmpl += cur->samples;
04888 }
04889 #else
04890 int jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
04891 if (jump - MONITOR_DELAY >= 0) {
04892 if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1)
04893 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
04894 chan->outsmpl += chan->insmpl - chan->outsmpl;
04895 } else {
04896 chan->outsmpl += cur->samples;
04897 }
04898 #endif
04899 if (chan->monitor->state == AST_MONITOR_RUNNING) {
04900 if (ast_writestream(chan->monitor->write_stream, cur) < 0)
04901 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
04902 }
04903 }
04904 }
04905
04906
04907
04908
04909 if ((f != fr) && AST_LIST_NEXT(f, frame_list)) {
04910 struct ast_frame *cur, *next;
04911 unsigned int skip = 0;
04912
04913 for (cur = f, next = AST_LIST_NEXT(cur, frame_list);
04914 cur;
04915 cur = next, next = cur ? AST_LIST_NEXT(cur, frame_list) : NULL) {
04916 if (!skip) {
04917 if ((res = chan->tech->write(chan, cur)) < 0) {
04918 chan->_softhangup |= AST_SOFTHANGUP_DEV;
04919 skip = 1;
04920 } else if (next) {
04921
04922
04923
04924 chan->fout = FRAMECOUNT_INC(chan->fout);
04925 }
04926 }
04927 ast_frfree(cur);
04928 }
04929
04930
04931 f = NULL;
04932 } else {
04933 res = chan->tech->write(chan, f);
04934 }
04935 break;
04936 case AST_FRAME_NULL:
04937 case AST_FRAME_IAX:
04938
04939 res = 0;
04940 break;
04941 default:
04942
04943
04944
04945 res = chan->tech->write(chan, fr);
04946 break;
04947 }
04948
04949 if (f && f != fr)
04950 ast_frfree(f);
04951 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04952
04953
04954 if (res < 0) {
04955 chan->_softhangup |= AST_SOFTHANGUP_DEV;
04956 } else {
04957 chan->fout = FRAMECOUNT_INC(chan->fout);
04958 }
04959 done:
04960 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) {
04961
04962 ast_audiohook_detach_list(chan->audiohooks);
04963 chan->audiohooks = NULL;
04964 }
04965 ast_channel_unlock(chan);
04966 return res;
04967 }
04968
04969 static int set_format(struct ast_channel *chan, format_t fmt, format_t *rawformat, format_t *format,
04970 struct ast_trans_pvt **trans, const int direction)
04971 {
04972 format_t native, native_fmt = ast_best_codec(fmt);
04973 int res;
04974 char from[200], to[200];
04975
04976
04977 fmt &= AST_FORMAT_AUDIO_MASK;
04978
04979 native = chan->nativeformats;
04980
04981 if (!fmt || !native)
04982 return 0;
04983
04984
04985 if (!ast_channel_setoption(chan, direction ? AST_OPTION_FORMAT_WRITE : AST_OPTION_FORMAT_READ, &native_fmt, sizeof(int*), 0)) {
04986 ast_debug(1, "Channel driver natively set channel %s to %s format %s\n", chan->name,
04987 direction ? "write" : "read", ast_getformatname(native_fmt));
04988 chan->nativeformats = *rawformat = *format = native_fmt;
04989 if (*trans) {
04990 ast_translator_free_path(*trans);
04991 }
04992 *trans = NULL;
04993 return 0;
04994 }
04995
04996
04997 if (!direction)
04998
04999 res = ast_translator_best_choice(&fmt, &native);
05000 else
05001
05002 res = ast_translator_best_choice(&native, &fmt);
05003
05004 if (res < 0) {
05005 ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
05006 ast_getformatname_multiple(from, sizeof(from), native),
05007 ast_getformatname_multiple(to, sizeof(to), fmt));
05008 return -1;
05009 }
05010
05011
05012 ast_channel_lock(chan);
05013
05014 if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
05015
05016 ast_channel_unlock(chan);
05017 return 0;
05018 }
05019
05020 *rawformat = native;
05021
05022 *format = fmt;
05023
05024 if (*trans) {
05025 ast_translator_free_path(*trans);
05026 *trans = NULL;
05027 }
05028
05029 if (*format == *rawformat) {
05030
05031
05032
05033
05034
05035 res = 0;
05036 } else {
05037 if (!direction) {
05038
05039 *trans = ast_translator_build_path(*format, *rawformat);
05040 } else {
05041
05042 *trans = ast_translator_build_path(*rawformat, *format);
05043 }
05044 res = *trans ? 0 : -1;
05045 }
05046 ast_channel_unlock(chan);
05047 ast_debug(1, "Set channel %s to %s format %s\n", chan->name,
05048 direction ? "write" : "read", ast_getformatname(fmt));
05049 return res;
05050 }
05051
05052 int ast_set_read_format(struct ast_channel *chan, format_t fmt)
05053 {
05054 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
05055 &chan->readtrans, 0);
05056 }
05057
05058 int ast_set_write_format(struct ast_channel *chan, format_t fmt)
05059 {
05060 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
05061 &chan->writetrans, 1);
05062 }
05063
05064 const char *ast_channel_reason2str(int reason)
05065 {
05066 switch (reason)
05067 {
05068 case 0:
05069 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
05070 case AST_CONTROL_HANGUP:
05071 return "Hangup";
05072 case AST_CONTROL_RING:
05073 return "Local Ring";
05074 case AST_CONTROL_RINGING:
05075 return "Remote end Ringing";
05076 case AST_CONTROL_ANSWER:
05077 return "Remote end has Answered";
05078 case AST_CONTROL_BUSY:
05079 return "Remote end is Busy";
05080 case AST_CONTROL_CONGESTION:
05081 return "Congestion (circuits busy)";
05082 default:
05083 return "Unknown Reason!!";
05084 }
05085 }
05086
05087 static void handle_cause(int cause, int *outstate)
05088 {
05089 if (outstate) {
05090
05091 if (cause == AST_CAUSE_BUSY)
05092 *outstate = AST_CONTROL_BUSY;
05093 else if (cause == AST_CAUSE_CONGESTION)
05094 *outstate = AST_CONTROL_CONGESTION;
05095 else
05096 *outstate = 0;
05097 }
05098 }
05099
05100 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)
05101 {
05102 char tmpchan[256];
05103 struct ast_channel *new = NULL;
05104 struct ast_party_redirecting *apr = &orig->redirecting;
05105 char *data, *type;
05106 int cause = 0;
05107 int res;
05108
05109
05110 ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan));
05111 if ((data = strchr(tmpchan, '/'))) {
05112 *data++ = '\0';
05113 type = tmpchan;
05114 } else {
05115 const char *forward_context;
05116 ast_channel_lock(orig);
05117 forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT");
05118 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context));
05119 ast_channel_unlock(orig);
05120 data = tmpchan;
05121 type = "Local";
05122 }
05123 if (!(new = ast_request(type, format, orig, data, &cause))) {
05124 ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause);
05125 handle_cause(cause, outstate);
05126 ast_hangup(orig);
05127 return NULL;
05128 }
05129
05130 ast_channel_set_redirecting(new, apr, NULL);
05131
05132
05133 if (oh) {
05134 if (oh->vars) {
05135 ast_set_variables(new, oh->vars);
05136 }
05137 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) {
05138 ast_set_callerid(new, oh->cid_num, oh->cid_name, oh->cid_num);
05139 }
05140 if (oh->parent_channel) {
05141 ast_channel_update_redirecting(oh->parent_channel, apr, NULL);
05142 ast_channel_inherit_variables(oh->parent_channel, new);
05143 ast_channel_datastore_inherit(oh->parent_channel, new);
05144 }
05145 if (oh->account) {
05146 ast_cdr_setaccount(new, oh->account);
05147 }
05148 } else if (caller) {
05149 ast_channel_update_redirecting(caller, apr, NULL);
05150 ast_channel_inherit_variables(caller, new);
05151 ast_channel_datastore_inherit(caller, new);
05152 }
05153
05154 ast_channel_lock(orig);
05155 while (ast_channel_trylock(new)) {
05156 CHANNEL_DEADLOCK_AVOIDANCE(orig);
05157 }
05158 ast_copy_flags(new->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED);
05159 ast_string_field_set(new, accountcode, orig->accountcode);
05160 ast_party_caller_copy(&new->caller, &orig->caller);
05161 ast_party_connected_line_copy(&new->connected, &orig->connected);
05162 ast_channel_unlock(new);
05163 ast_channel_unlock(orig);
05164
05165
05166 res = ast_call(new, data, 0);
05167 if (timeout) {
05168 *timeout = res;
05169 }
05170 if (res) {
05171 ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data);
05172 ast_hangup(orig);
05173 ast_hangup(new);
05174 return NULL;
05175 }
05176 ast_hangup(orig);
05177
05178 return new;
05179 }
05180
05181 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)
05182 {
05183 int dummy_outstate;
05184 int cause = 0;
05185 struct ast_channel *chan;
05186 int res = 0;
05187 int last_subclass = 0;
05188 struct ast_party_connected_line connected;
05189
05190 if (outstate)
05191 *outstate = 0;
05192 else
05193 outstate = &dummy_outstate;
05194
05195 chan = ast_request(type, format, requestor, data, &cause);
05196 if (!chan) {
05197 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
05198 handle_cause(cause, outstate);
05199 return NULL;
05200 }
05201
05202 if (oh) {
05203 if (oh->vars)
05204 ast_set_variables(chan, oh->vars);
05205
05206 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
05207 ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
05208 if (oh->parent_channel) {
05209 ast_channel_inherit_variables(oh->parent_channel, chan);
05210 ast_channel_datastore_inherit(oh->parent_channel, chan);
05211 }
05212 if (oh->account)
05213 ast_cdr_setaccount(chan, oh->account);
05214 }
05215
05216 ast_set_callerid(chan, cid_num, cid_name, cid_num);
05217 ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED);
05218 ast_party_connected_line_set_init(&connected, &chan->connected);
05219 if (cid_num) {
05220 connected.id.number.valid = 1;
05221 connected.id.number.str = (char *) cid_num;
05222 connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05223 }
05224 if (cid_name) {
05225 connected.id.name.valid = 1;
05226 connected.id.name.str = (char *) cid_name;
05227 connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05228 }
05229 ast_channel_set_connected_line(chan, &connected, NULL);
05230
05231 if (ast_call(chan, data, 0)) {
05232 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
05233 } else {
05234 res = 1;
05235 while (timeout && chan->_state != AST_STATE_UP) {
05236 struct ast_frame *f;
05237 res = ast_waitfor(chan, timeout);
05238 if (res == 0) {
05239 *outstate = AST_CONTROL_RINGING;
05240 break;
05241 }
05242 if (res < 0)
05243 break;
05244 if (timeout > -1)
05245 timeout = res;
05246 if (!ast_strlen_zero(chan->call_forward)) {
05247 if (!(chan = ast_call_forward(NULL, chan, NULL, format, oh, outstate))) {
05248 return NULL;
05249 }
05250 continue;
05251 }
05252
05253 f = ast_read(chan);
05254 if (!f) {
05255 *outstate = AST_CONTROL_HANGUP;
05256 res = 0;
05257 break;
05258 }
05259 if (f->frametype == AST_FRAME_CONTROL) {
05260 switch (f->subclass.integer) {
05261 case AST_CONTROL_RINGING:
05262 *outstate = f->subclass.integer;
05263 break;
05264
05265 case AST_CONTROL_BUSY:
05266 ast_cdr_busy(chan->cdr);
05267 *outstate = f->subclass.integer;
05268 timeout = 0;
05269 break;
05270
05271 case AST_CONTROL_CONGESTION:
05272 ast_cdr_failed(chan->cdr);
05273 *outstate = f->subclass.integer;
05274 timeout = 0;
05275 break;
05276
05277 case AST_CONTROL_ANSWER:
05278 ast_cdr_answer(chan->cdr);
05279 *outstate = f->subclass.integer;
05280 timeout = 0;
05281 break;
05282
05283
05284 case AST_CONTROL_PROGRESS:
05285 case AST_CONTROL_PROCEEDING:
05286 case AST_CONTROL_HOLD:
05287 case AST_CONTROL_UNHOLD:
05288 case AST_CONTROL_VIDUPDATE:
05289 case AST_CONTROL_SRCUPDATE:
05290 case AST_CONTROL_SRCCHANGE:
05291 case AST_CONTROL_CONNECTED_LINE:
05292 case AST_CONTROL_REDIRECTING:
05293 case AST_CONTROL_CC:
05294 case -1:
05295 break;
05296
05297 default:
05298 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer);
05299 }
05300 last_subclass = f->subclass.integer;
05301 }
05302 ast_frfree(f);
05303 }
05304 }
05305
05306
05307 if (oh) {
05308 if (!ast_strlen_zero(oh->context))
05309 ast_copy_string(chan->context, oh->context, sizeof(chan->context));
05310 if (!ast_strlen_zero(oh->exten))
05311 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
05312 if (oh->priority)
05313 chan->priority = oh->priority;
05314 }
05315 if (chan->_state == AST_STATE_UP)
05316 *outstate = AST_CONTROL_ANSWER;
05317
05318 if (res <= 0) {
05319 if ( AST_CONTROL_RINGING == last_subclass )
05320 chan->hangupcause = AST_CAUSE_NO_ANSWER;
05321 if (!chan->cdr && (chan->cdr = ast_cdr_alloc()))
05322 ast_cdr_init(chan->cdr, chan);
05323 if (chan->cdr) {
05324 char tmp[256];
05325 snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
05326 ast_cdr_setapp(chan->cdr,"Dial",tmp);
05327 ast_cdr_update(chan);
05328 ast_cdr_start(chan->cdr);
05329 ast_cdr_end(chan->cdr);
05330
05331 if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
05332 ast_cdr_failed(chan->cdr);
05333 }
05334 ast_hangup(chan);
05335 chan = NULL;
05336 }
05337 return chan;
05338 }
05339
05340 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)
05341 {
05342 return __ast_request_and_dial(type, format, requestor, data, timeout, outstate, cidnum, cidname, NULL);
05343 }
05344
05345 static int set_security_requirements(const struct ast_channel *requestor, struct ast_channel *out)
05346 {
05347 int ops[2][2] = {
05348 {AST_OPTION_SECURE_SIGNALING, 0},
05349 {AST_OPTION_SECURE_MEDIA, 0},
05350 };
05351 int i;
05352 struct ast_channel *r = (struct ast_channel *) requestor;
05353 struct ast_datastore *ds;
05354
05355 if (!requestor || !out) {
05356 return 0;
05357 }
05358
05359 ast_channel_lock(r);
05360 if ((ds = ast_channel_datastore_find(r, &secure_call_info, NULL))) {
05361 struct ast_secure_call_store *encrypt = ds->data;
05362 ops[0][1] = encrypt->signaling;
05363 ops[1][1] = encrypt->media;
05364 } else {
05365 ast_channel_unlock(r);
05366 return 0;
05367 }
05368 ast_channel_unlock(r);
05369
05370 for (i = 0; i < 2; i++) {
05371 if (ops[i][1]) {
05372 if (ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0)) {
05373
05374 return -1;
05375 }
05376 } else {
05377
05378 ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0);
05379 }
05380 }
05381
05382 return 0;
05383 }
05384
05385 struct ast_channel *ast_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
05386 {
05387 struct chanlist *chan;
05388 struct ast_channel *c;
05389 format_t capabilities;
05390 format_t fmt;
05391 int res;
05392 int foo;
05393 format_t videoformat = format & AST_FORMAT_VIDEO_MASK;
05394 format_t textformat = format & AST_FORMAT_TEXT_MASK;
05395
05396 if (!cause)
05397 cause = &foo;
05398 *cause = AST_CAUSE_NOTDEFINED;
05399
05400 if (AST_RWLIST_RDLOCK(&backends)) {
05401 ast_log(LOG_WARNING, "Unable to lock technology backend list\n");
05402 return NULL;
05403 }
05404
05405 AST_RWLIST_TRAVERSE(&backends, chan, list) {
05406 if (strcasecmp(type, chan->tech->type))
05407 continue;
05408
05409 capabilities = chan->tech->capabilities;
05410 fmt = format & AST_FORMAT_AUDIO_MASK;
05411 if (fmt) {
05412
05413
05414
05415 res = ast_translator_best_choice(&fmt, &capabilities);
05416 if (res < 0) {
05417 char tmp1[256], tmp2[256];
05418 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type,
05419 ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities),
05420 ast_getformatname_multiple(tmp2, sizeof(tmp2), format));
05421 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05422 AST_RWLIST_UNLOCK(&backends);
05423 return NULL;
05424 }
05425 }
05426 AST_RWLIST_UNLOCK(&backends);
05427 if (!chan->tech->requester)
05428 return NULL;
05429
05430 if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, requestor, data, cause)))
05431 return NULL;
05432
05433 if (set_security_requirements(requestor, c)) {
05434 ast_log(LOG_WARNING, "Setting security requirements failed\n");
05435 c = ast_channel_release(c);
05436 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05437 return NULL;
05438 }
05439
05440
05441 return c;
05442 }
05443
05444 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
05445 *cause = AST_CAUSE_NOSUCHDRIVER;
05446 AST_RWLIST_UNLOCK(&backends);
05447
05448 return NULL;
05449 }
05450
05451 int ast_call(struct ast_channel *chan, char *addr, int timeout)
05452 {
05453
05454
05455
05456 int res = -1;
05457
05458 ast_channel_lock(chan);
05459 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
05460 if (chan->cdr) {
05461 ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED);
05462 }
05463 if (chan->tech->call)
05464 res = chan->tech->call(chan, addr, timeout);
05465 ast_set_flag(chan, AST_FLAG_OUTGOING);
05466 }
05467 ast_channel_unlock(chan);
05468 return res;
05469 }
05470
05471
05472
05473
05474
05475
05476
05477
05478 int ast_transfer(struct ast_channel *chan, char *dest)
05479 {
05480 int res = -1;
05481
05482
05483 ast_channel_lock(chan);
05484 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
05485 if (chan->tech->transfer) {
05486 res = chan->tech->transfer(chan, dest);
05487 if (!res)
05488 res = 1;
05489 } else
05490 res = 0;
05491 }
05492 ast_channel_unlock(chan);
05493
05494 if (res <= 0) {
05495 return res;
05496 }
05497
05498 for (;;) {
05499 struct ast_frame *fr;
05500
05501 res = ast_waitfor(chan, -1);
05502
05503 if (res < 0 || !(fr = ast_read(chan))) {
05504 res = -1;
05505 break;
05506 }
05507
05508 if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) {
05509 enum ast_control_transfer *message = fr->data.ptr;
05510
05511 if (*message == AST_TRANSFER_SUCCESS) {
05512 res = 1;
05513 } else {
05514 res = -1;
05515 }
05516
05517 ast_frfree(fr);
05518 break;
05519 }
05520
05521 ast_frfree(fr);
05522 }
05523
05524 return res;
05525 }
05526
05527 int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
05528 {
05529 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
05530 }
05531
05532 int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
05533 {
05534 int pos = 0;
05535 int to = ftimeout;
05536
05537 struct ast_silence_generator *silgen = NULL;
05538
05539
05540 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
05541 return -1;
05542 if (!len)
05543 return -1;
05544 for (;;) {
05545 int d;
05546 if (c->stream) {
05547 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
05548 ast_stopstream(c);
05549 if (!silgen && ast_opt_transmit_silence)
05550 silgen = ast_channel_start_silence_generator(c);
05551 usleep(1000);
05552 if (!d)
05553 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
05554 } else {
05555 if (!silgen && ast_opt_transmit_silence)
05556 silgen = ast_channel_start_silence_generator(c);
05557 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
05558 }
05559 if (d < 0) {
05560 ast_channel_stop_silence_generator(c, silgen);
05561 return AST_GETDATA_FAILED;
05562 }
05563 if (d == 0) {
05564 s[pos] = '\0';
05565 ast_channel_stop_silence_generator(c, silgen);
05566 return AST_GETDATA_TIMEOUT;
05567 }
05568 if (d == 1) {
05569 s[pos] = '\0';
05570 ast_channel_stop_silence_generator(c, silgen);
05571 return AST_GETDATA_INTERRUPTED;
05572 }
05573 if (strchr(enders, d) && (pos == 0)) {
05574 s[pos] = '\0';
05575 ast_channel_stop_silence_generator(c, silgen);
05576 return AST_GETDATA_EMPTY_END_TERMINATED;
05577 }
05578 if (!strchr(enders, d)) {
05579 s[pos++] = d;
05580 }
05581 if (strchr(enders, d) || (pos >= len)) {
05582 s[pos] = '\0';
05583 ast_channel_stop_silence_generator(c, silgen);
05584 return AST_GETDATA_COMPLETE;
05585 }
05586 to = timeout;
05587 }
05588
05589 return 0;
05590 }
05591
05592 int ast_channel_supports_html(struct ast_channel *chan)
05593 {
05594 return (chan->tech->send_html) ? 1 : 0;
05595 }
05596
05597 int ast_channel_sendhtml(struct ast_channel *chan, int subclass, const char *data, int datalen)
05598 {
05599 if (chan->tech->send_html)
05600 return chan->tech->send_html(chan, subclass, data, datalen);
05601 return -1;
05602 }
05603
05604 int ast_channel_sendurl(struct ast_channel *chan, const char *url)
05605 {
05606 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
05607 }
05608
05609
05610 static int ast_channel_make_compatible_helper(struct ast_channel *from, struct ast_channel *to)
05611 {
05612 format_t src, dst;
05613 int use_slin;
05614
05615
05616 if (from->tech->bridge && from->tech->bridge == to->tech->bridge &&
05617 !ast_channel_setoption(from, AST_OPTION_MAKE_COMPATIBLE, to, sizeof(struct ast_channel *), 0)) {
05618 return 0;
05619 }
05620
05621 if (from->readformat == to->writeformat && from->writeformat == to->readformat) {
05622
05623 return 0;
05624 }
05625
05626
05627 src = from->nativeformats;
05628 dst = to->nativeformats;
05629
05630
05631 if ((src & AST_FORMAT_AUDIO_MASK) == 0 || (dst & AST_FORMAT_AUDIO_MASK) == 0)
05632 return 0;
05633
05634 if (ast_translator_best_choice(&dst, &src) < 0) {
05635 ast_log(LOG_WARNING, "No path to translate from %s to %s\n", from->name, to->name);
05636 return -1;
05637 }
05638
05639
05640
05641
05642
05643
05644
05645 use_slin = (src == AST_FORMAT_SLINEAR || dst == AST_FORMAT_SLINEAR);
05646 if ((src != dst) && (ast_opt_generic_plc || ast_opt_transcode_via_slin) &&
05647 (ast_translate_path_steps(dst, src) != 1 || use_slin))
05648 dst = AST_FORMAT_SLINEAR;
05649 if (ast_set_read_format(from, dst) < 0) {
05650 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %s\n", from->name, ast_getformatname(dst));
05651 return -1;
05652 }
05653 if (ast_set_write_format(to, dst) < 0) {
05654 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %s\n", to->name, ast_getformatname(dst));
05655 return -1;
05656 }
05657 return 0;
05658 }
05659
05660 int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
05661 {
05662
05663 int rc = 0;
05664
05665
05666 rc = ast_channel_make_compatible_helper(chan, peer);
05667
05668 if (rc < 0)
05669 return rc;
05670
05671
05672 rc = ast_channel_make_compatible_helper(peer, chan);
05673
05674 return rc;
05675 }
05676
05677 static int __ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clonechan, struct ast_datastore *xfer_ds)
05678 {
05679 int res = -1;
05680 struct ast_channel *final_orig, *final_clone, *base;
05681
05682 retrymasq:
05683 final_orig = original;
05684 final_clone = clonechan;
05685
05686 ast_channel_lock(original);
05687 while (ast_channel_trylock(clonechan)) {
05688 ast_channel_unlock(original);
05689 usleep(1);
05690 ast_channel_lock(original);
05691 }
05692
05693
05694
05695 if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original))
05696 final_orig = original->_bridge;
05697
05698 if (clonechan->_bridge && (clonechan->_bridge != ast_bridged_channel(clonechan)) && (clonechan->_bridge->_bridge != clonechan))
05699 final_clone = clonechan->_bridge;
05700
05701 if (final_clone->tech->get_base_channel && (base = final_clone->tech->get_base_channel(final_clone))) {
05702 final_clone = base;
05703 }
05704
05705 if ((final_orig != original) || (final_clone != clonechan)) {
05706
05707
05708
05709 if (ast_channel_trylock(final_orig)) {
05710 ast_channel_unlock(clonechan);
05711 ast_channel_unlock(original);
05712 goto retrymasq;
05713 }
05714 if (ast_channel_trylock(final_clone)) {
05715 ast_channel_unlock(final_orig);
05716 ast_channel_unlock(clonechan);
05717 ast_channel_unlock(original);
05718 goto retrymasq;
05719 }
05720 ast_channel_unlock(clonechan);
05721 ast_channel_unlock(original);
05722 original = final_orig;
05723 clonechan = final_clone;
05724 }
05725
05726 if (original == clonechan) {
05727 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
05728 ast_channel_unlock(clonechan);
05729 ast_channel_unlock(original);
05730 return -1;
05731 }
05732
05733 ast_debug(1, "Planning to masquerade channel %s into the structure of %s\n",
05734 clonechan->name, original->name);
05735
05736 if (!original->masqr && !original->masq && !clonechan->masq && !clonechan->masqr) {
05737 original->masq = clonechan;
05738 clonechan->masqr = original;
05739 if (xfer_ds) {
05740 ast_channel_datastore_add(original, xfer_ds);
05741 }
05742 ast_queue_frame(original, &ast_null_frame);
05743 ast_queue_frame(clonechan, &ast_null_frame);
05744 ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", clonechan->name, original->name);
05745 res = 0;
05746 } else if (original->masq) {
05747 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05748 original->masq->name, original->name);
05749 } else if (original->masqr) {
05750
05751 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05752 original->name, original->masqr->name);
05753 } else if (clonechan->masq) {
05754 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05755 clonechan->masq->name, clonechan->name);
05756 } else {
05757 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05758 clonechan->name, clonechan->masqr->name);
05759 }
05760
05761 ast_channel_unlock(clonechan);
05762 ast_channel_unlock(original);
05763
05764 return res;
05765 }
05766
05767 int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
05768 {
05769 return __ast_channel_masquerade(original, clone, NULL);
05770 }
05771
05772
05773
05774
05775
05776
05777
05778
05779
05780
05781
05782 static void party_connected_line_copy_transfer(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
05783 {
05784 struct ast_party_connected_line connected;
05785
05786 connected = *((struct ast_party_connected_line *) src);
05787 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
05788
05789
05790 if (!connected.id.name.str) {
05791 connected.id.name.str = "";
05792 }
05793 if (!connected.id.number.str) {
05794 connected.id.number.str = "";
05795 }
05796 if (!connected.id.subaddress.str) {
05797 connected.id.subaddress.str = "";
05798 }
05799 if (!connected.id.tag) {
05800 connected.id.tag = "";
05801 }
05802
05803 ast_party_connected_line_copy(dest, &connected);
05804 }
05805
05806
05807 struct xfer_masquerade_ds {
05808
05809 struct ast_party_connected_line target_id;
05810
05811 struct ast_party_connected_line transferee_id;
05812
05813 int target_held;
05814
05815 int transferee_held;
05816 };
05817
05818
05819
05820
05821
05822
05823
05824
05825
05826
05827 static void xfer_ds_destroy(void *data)
05828 {
05829 struct xfer_masquerade_ds *ds = data;
05830
05831 ast_party_connected_line_free(&ds->target_id);
05832 ast_party_connected_line_free(&ds->transferee_id);
05833 ast_free(ds);
05834 }
05835
05836 static const struct ast_datastore_info xfer_ds_info = {
05837 .type = "xfer_colp",
05838 .destroy = xfer_ds_destroy,
05839 };
05840
05841 int ast_channel_transfer_masquerade(
05842 struct ast_channel *target_chan,
05843 const struct ast_party_connected_line *target_id,
05844 int target_held,
05845 struct ast_channel *transferee_chan,
05846 const struct ast_party_connected_line *transferee_id,
05847 int transferee_held)
05848 {
05849 struct ast_datastore *xfer_ds;
05850 struct xfer_masquerade_ds *xfer_colp;
05851 int res;
05852
05853 xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL);
05854 if (!xfer_ds) {
05855 return -1;
05856 }
05857
05858 xfer_colp = ast_calloc(1, sizeof(*xfer_colp));
05859 if (!xfer_colp) {
05860 ast_datastore_free(xfer_ds);
05861 return -1;
05862 }
05863 party_connected_line_copy_transfer(&xfer_colp->target_id, target_id);
05864 xfer_colp->target_held = target_held;
05865 party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id);
05866 xfer_colp->transferee_held = transferee_held;
05867 xfer_ds->data = xfer_colp;
05868
05869 res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds);
05870 if (res) {
05871 ast_datastore_free(xfer_ds);
05872 }
05873 return res;
05874 }
05875
05876
05877
05878
05879
05880 static void __ast_change_name_nolink(struct ast_channel *chan, const char *newname)
05881 {
05882 ast_manager_event(chan, EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
05883 ast_string_field_set(chan, name, newname);
05884 }
05885
05886 void ast_change_name(struct ast_channel *chan, const char *newname)
05887 {
05888
05889 ao2_unlink(channels, chan);
05890 ast_channel_lock(chan);
05891 __ast_change_name_nolink(chan, newname);
05892 ast_channel_unlock(chan);
05893 ao2_link(channels, chan);
05894 }
05895
05896 void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
05897 {
05898 struct ast_var_t *current, *newvar;
05899 const char *varname;
05900
05901 AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
05902 int vartype = 0;
05903
05904 varname = ast_var_full_name(current);
05905 if (!varname)
05906 continue;
05907
05908 if (varname[0] == '_') {
05909 vartype = 1;
05910 if (varname[1] == '_')
05911 vartype = 2;
05912 }
05913
05914 switch (vartype) {
05915 case 1:
05916 newvar = ast_var_assign(&varname[1], ast_var_value(current));
05917 if (newvar) {
05918 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
05919 ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
05920 }
05921 break;
05922 case 2:
05923 newvar = ast_var_assign(varname, ast_var_value(current));
05924 if (newvar) {
05925 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
05926 ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
05927 }
05928 break;
05929 default:
05930 ast_debug(1, "Not copying variable %s.\n", ast_var_name(current));
05931 break;
05932 }
05933 }
05934 }
05935
05936
05937
05938
05939
05940
05941
05942
05943
05944
05945 static void clone_variables(struct ast_channel *original, struct ast_channel *clonechan)
05946 {
05947 struct ast_var_t *current, *newvar;
05948
05949
05950 if (AST_LIST_FIRST(&clonechan->varshead))
05951 AST_LIST_APPEND_LIST(&original->varshead, &clonechan->varshead, entries);
05952
05953
05954
05955 AST_LIST_TRAVERSE(&original->varshead, current, entries) {
05956 newvar = ast_var_assign(current->name, current->value);
05957 if (newvar)
05958 AST_LIST_INSERT_TAIL(&clonechan->varshead, newvar, entries);
05959 }
05960 }
05961
05962
05963
05964
05965
05966
05967
05968
05969
05970
05971
05972
05973
05974
05975 static const char *oldest_linkedid(const char *a, const char *b)
05976 {
05977 const char *satime, *saseq;
05978 const char *sbtime, *sbseq;
05979 const char *dash;
05980
05981 unsigned int atime, aseq, btime, bseq;
05982
05983 if (ast_strlen_zero(a))
05984 return b;
05985
05986 if (ast_strlen_zero(b))
05987 return a;
05988
05989 satime = a;
05990 sbtime = b;
05991
05992
05993 if ((dash = strrchr(satime, '-'))) {
05994 satime = dash+1;
05995 }
05996 if ((dash = strrchr(sbtime, '-'))) {
05997 sbtime = dash+1;
05998 }
05999
06000
06001 saseq = strchr(satime, '.');
06002 sbseq = strchr(sbtime, '.');
06003 if (!saseq || !sbseq)
06004 return NULL;
06005 saseq++;
06006 sbseq++;
06007
06008
06009 atime = atoi(satime);
06010 btime = atoi(sbtime);
06011 aseq = atoi(saseq);
06012 bseq = atoi(sbseq);
06013
06014
06015 if (atime == btime) {
06016 return (aseq < bseq) ? a : b;
06017 }
06018 else {
06019 return (atime < btime) ? a : b;
06020 }
06021 }
06022
06023
06024
06025 static void ast_channel_change_linkedid(struct ast_channel *chan, const char *linkedid)
06026 {
06027
06028 if (!ast_strlen_zero(chan->linkedid) && 0 != strcmp(chan->linkedid, linkedid)) {
06029 ast_cel_check_retire_linkedid(chan);
06030 }
06031
06032 ast_string_field_set(chan, linkedid, linkedid);
06033 }
06034
06035
06036
06037
06038
06039
06040 void ast_channel_set_linkgroup(struct ast_channel *chan, struct ast_channel *peer)
06041 {
06042 const char* linkedid=NULL;
06043 struct ast_channel *bridged;
06044
06045 linkedid = oldest_linkedid(chan->linkedid, peer->linkedid);
06046 linkedid = oldest_linkedid(linkedid, chan->uniqueid);
06047 linkedid = oldest_linkedid(linkedid, peer->uniqueid);
06048 if (chan->_bridge) {
06049 bridged = ast_bridged_channel(chan);
06050 if (bridged != peer) {
06051 linkedid = oldest_linkedid(linkedid, bridged->linkedid);
06052 linkedid = oldest_linkedid(linkedid, bridged->uniqueid);
06053 }
06054 }
06055 if (peer->_bridge) {
06056 bridged = ast_bridged_channel(peer);
06057 if (bridged != chan) {
06058 linkedid = oldest_linkedid(linkedid, bridged->linkedid);
06059 linkedid = oldest_linkedid(linkedid, bridged->uniqueid);
06060 }
06061 }
06062
06063
06064 linkedid = ast_strdupa(linkedid);
06065
06066 ast_channel_change_linkedid(chan, linkedid);
06067 ast_channel_change_linkedid(peer, linkedid);
06068 if (chan->_bridge) {
06069 bridged = ast_bridged_channel(chan);
06070 if (bridged != peer) {
06071 ast_channel_change_linkedid(bridged, linkedid);
06072 }
06073 }
06074 if (peer->_bridge) {
06075 bridged = ast_bridged_channel(peer);
06076 if (bridged != chan) {
06077 ast_channel_change_linkedid(bridged, linkedid);
06078 }
06079 }
06080 }
06081
06082
06083 static void ast_set_owners_and_peers(struct ast_channel *chan1,
06084 struct ast_channel *chan2)
06085 {
06086 if (!ast_strlen_zero(chan1->accountcode) && ast_strlen_zero(chan2->peeraccount)) {
06087 ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n",
06088 chan1->accountcode, chan2->name, chan1->name);
06089 ast_string_field_set(chan2, peeraccount, chan1->accountcode);
06090 }
06091 if (!ast_strlen_zero(chan2->accountcode) && ast_strlen_zero(chan1->peeraccount)) {
06092 ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n",
06093 chan2->accountcode, chan1->name, chan2->name);
06094 ast_string_field_set(chan1, peeraccount, chan2->accountcode);
06095 }
06096 if (!ast_strlen_zero(chan1->peeraccount) && ast_strlen_zero(chan2->accountcode)) {
06097 ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n",
06098 chan1->peeraccount, chan2->name, chan1->name);
06099 ast_string_field_set(chan2, accountcode, chan1->peeraccount);
06100 }
06101 if (!ast_strlen_zero(chan2->peeraccount) && ast_strlen_zero(chan1->accountcode)) {
06102 ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n",
06103 chan2->peeraccount, chan1->name, chan2->name);
06104 ast_string_field_set(chan1, accountcode, chan2->peeraccount);
06105 }
06106 if (0 != strcmp(chan1->accountcode, chan2->peeraccount)) {
06107 ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n",
06108 chan2->peeraccount, chan1->peeraccount, chan2->name, chan1->name);
06109 ast_string_field_set(chan2, peeraccount, chan1->accountcode);
06110 }
06111 if (0 != strcmp(chan2->accountcode, chan1->peeraccount)) {
06112 ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n",
06113 chan1->peeraccount, chan2->peeraccount, chan1->name, chan2->name);
06114 ast_string_field_set(chan1, peeraccount, chan2->accountcode);
06115 }
06116 }
06117
06118
06119
06120
06121 static void report_new_callerid(struct ast_channel *chan)
06122 {
06123 int pres;
06124
06125 pres = ast_party_id_presentation(&chan->caller.id);
06126 ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid",
06127 "Channel: %s\r\n"
06128 "CallerIDNum: %s\r\n"
06129 "CallerIDName: %s\r\n"
06130 "Uniqueid: %s\r\n"
06131 "CID-CallingPres: %d (%s)\r\n",
06132 chan->name,
06133 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
06134 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
06135 chan->uniqueid,
06136 pres,
06137 ast_describe_caller_presentation(pres)
06138 );
06139 }
06140
06141
06142
06143
06144
06145
06146
06147
06148
06149
06150
06151 static void masquerade_colp_transfer(struct ast_channel *transferee, struct xfer_masquerade_ds *colp)
06152 {
06153 struct ast_control_read_action_payload *frame_payload;
06154 int payload_size;
06155 int frame_size;
06156 unsigned char connected_line_data[1024];
06157
06158
06159 if (colp->target_held) {
06160 ast_queue_control(transferee, AST_CONTROL_UNHOLD);
06161 }
06162
06163
06164
06165
06166
06167
06168
06169
06170
06171
06172 payload_size = ast_connected_line_build_data(connected_line_data,
06173 sizeof(connected_line_data), &colp->target_id, NULL);
06174 if (payload_size != -1) {
06175 frame_size = payload_size + sizeof(*frame_payload);
06176 frame_payload = alloca(frame_size);
06177 frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO;
06178 frame_payload->payload_size = payload_size;
06179 memcpy(frame_payload->payload, connected_line_data, payload_size);
06180 ast_queue_control_data(transferee, AST_CONTROL_READ_ACTION, frame_payload,
06181 frame_size);
06182 }
06183
06184
06185
06186
06187
06188
06189 ast_channel_queue_connected_line_update(transferee, &colp->transferee_id, NULL);
06190 }
06191
06192
06193
06194
06195
06196
06197
06198
06199 int ast_do_masquerade(struct ast_channel *original)
06200 {
06201 format_t x;
06202 int i;
06203 int res=0;
06204 int origstate;
06205 int visible_indication;
06206 struct ast_frame *current;
06207 const struct ast_channel_tech *t;
06208 void *t_pvt;
06209 union {
06210 struct ast_party_dialed dialed;
06211 struct ast_party_caller caller;
06212 struct ast_party_connected_line connected;
06213 struct ast_party_redirecting redirecting;
06214 } exchange;
06215 struct ast_channel *clonechan, *chans[2];
06216 struct ast_channel *bridged;
06217 struct ast_cdr *cdr;
06218 struct ast_datastore *xfer_ds;
06219 struct xfer_masquerade_ds *xfer_colp;
06220 format_t rformat = original->readformat;
06221 format_t wformat = original->writeformat;
06222 char newn[AST_CHANNEL_NAME];
06223 char orig[AST_CHANNEL_NAME];
06224 char masqn[AST_CHANNEL_NAME];
06225 char zombn[AST_CHANNEL_NAME];
06226
06227
06228
06229
06230
06231
06232
06233
06234
06235
06236
06237
06238
06239
06240
06241 ao2_lock(channels);
06242
06243
06244 ast_channel_lock(original);
06245
06246
06247
06248
06249
06250
06251 if (!original->masq) {
06252 ast_channel_unlock(original);
06253 ao2_unlock(channels);
06254 return 0;
06255 }
06256
06257
06258 clonechan = original->masq;
06259
06260
06261
06262
06263
06264 while (ast_channel_trylock(clonechan)) {
06265 CHANNEL_DEADLOCK_AVOIDANCE(original);
06266 }
06267
06268
06269 xfer_ds = ast_channel_datastore_find(original, &xfer_ds_info, NULL);
06270 if (xfer_ds) {
06271 ast_channel_datastore_remove(original, xfer_ds);
06272 xfer_colp = xfer_ds->data;
06273 } else {
06274 xfer_colp = NULL;
06275 }
06276
06277
06278
06279
06280
06281 if (xfer_colp && xfer_colp->transferee_held) {
06282 ast_indicate(clonechan, AST_CONTROL_UNHOLD);
06283 }
06284
06285
06286 original->masq = NULL;
06287 clonechan->masqr = NULL;
06288
06289
06290 ao2_unlink(channels, original);
06291 ao2_unlink(channels, clonechan);
06292
06293 ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
06294 clonechan->name, clonechan->_state, original->name, original->_state);
06295
06296
06297
06298
06299
06300 visible_indication = original->visible_indication;
06301 ast_indicate(original, -1);
06302
06303 chans[0] = clonechan;
06304 chans[1] = original;
06305 ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans,
06306 "Clone: %s\r\n"
06307 "CloneState: %s\r\n"
06308 "Original: %s\r\n"
06309 "OriginalState: %s\r\n",
06310 clonechan->name, ast_state2str(clonechan->_state), original->name, ast_state2str(original->_state));
06311
06312
06313
06314 free_translation(clonechan);
06315 free_translation(original);
06316
06317
06318 ast_copy_string(orig, original->name, sizeof(orig));
06319
06320 ast_copy_string(newn, clonechan->name, sizeof(newn));
06321
06322 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
06323
06324
06325 __ast_change_name_nolink(clonechan, masqn);
06326
06327
06328 __ast_change_name_nolink(original, newn);
06329
06330
06331 ast_channel_set_linkgroup(original, clonechan);
06332
06333
06334 t = original->tech;
06335 original->tech = clonechan->tech;
06336 clonechan->tech = t;
06337
06338
06339 cdr = original->cdr;
06340 original->cdr = clonechan->cdr;
06341 clonechan->cdr = cdr;
06342
06343 t_pvt = original->tech_pvt;
06344 original->tech_pvt = clonechan->tech_pvt;
06345 clonechan->tech_pvt = t_pvt;
06346
06347
06348 for (i = 0; i < 2; i++) {
06349 x = original->alertpipe[i];
06350 original->alertpipe[i] = clonechan->alertpipe[i];
06351 clonechan->alertpipe[i] = x;
06352 }
06353
06354
06355
06356
06357
06358
06359
06360
06361
06362
06363
06364
06365 {
06366 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
06367 AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
06368
06369 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
06370 AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list);
06371
06372 while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
06373 AST_LIST_INSERT_TAIL(&original->readq, current, frame_list);
06374 if (original->alertpipe[1] > -1) {
06375 int poke = 0;
06376
06377 if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) {
06378 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
06379 }
06380 }
06381 }
06382 }
06383
06384
06385 x = original->rawreadformat;
06386 original->rawreadformat = clonechan->rawreadformat;
06387 clonechan->rawreadformat = x;
06388 x = original->rawwriteformat;
06389 original->rawwriteformat = clonechan->rawwriteformat;
06390 clonechan->rawwriteformat = x;
06391
06392 clonechan->_softhangup = AST_SOFTHANGUP_DEV;
06393
06394
06395
06396
06397
06398 origstate = original->_state;
06399 original->_state = clonechan->_state;
06400 clonechan->_state = origstate;
06401
06402 if (clonechan->tech->fixup && clonechan->tech->fixup(original, clonechan)) {
06403 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clonechan->name);
06404 }
06405
06406
06407 if (clonechan->tech->hangup && clonechan->tech->hangup(clonechan)) {
06408 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n");
06409 res = -1;
06410 goto done;
06411 }
06412
06413
06414 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
06415 __ast_change_name_nolink(clonechan, zombn);
06416
06417
06418 t_pvt = original->monitor;
06419 original->monitor = clonechan->monitor;
06420 clonechan->monitor = t_pvt;
06421
06422
06423 ast_string_field_set(original, language, clonechan->language);
06424
06425 for (x = 0; x < AST_MAX_FDS; x++) {
06426 if (x != AST_GENERATOR_FD)
06427 ast_channel_set_fd(original, x, clonechan->fds[x]);
06428 }
06429
06430 ast_app_group_update(clonechan, original);
06431
06432
06433 if (AST_LIST_FIRST(&clonechan->datastores)) {
06434 struct ast_datastore *ds;
06435
06436
06437
06438 AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) {
06439 if (ds->info->chan_fixup)
06440 ds->info->chan_fixup(ds->data, clonechan, original);
06441 }
06442 AST_LIST_TRAVERSE_SAFE_END;
06443 AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry);
06444 }
06445
06446 ast_autochan_new_channel(clonechan, original);
06447
06448 clone_variables(original, clonechan);
06449
06450 original->adsicpe = clonechan->adsicpe;
06451
06452
06453
06454
06455
06456 ast_set_flag(original, ast_test_flag(clonechan, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING));
06457 original->fdno = clonechan->fdno;
06458
06459
06460
06461
06462
06463
06464
06465
06466 exchange.dialed = original->dialed;
06467 original->dialed = clonechan->dialed;
06468 clonechan->dialed = exchange.dialed;
06469
06470 exchange.caller = original->caller;
06471 original->caller = clonechan->caller;
06472 clonechan->caller = exchange.caller;
06473
06474 exchange.connected = original->connected;
06475 original->connected = clonechan->connected;
06476 clonechan->connected = exchange.connected;
06477
06478 exchange.redirecting = original->redirecting;
06479 original->redirecting = clonechan->redirecting;
06480 clonechan->redirecting = exchange.redirecting;
06481
06482 report_new_callerid(original);
06483
06484
06485 ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd);
06486
06487
06488 original->nativeformats = clonechan->nativeformats;
06489
06490
06491
06492
06493
06494 ast_set_write_format(original, wformat);
06495
06496
06497 ast_set_read_format(original, rformat);
06498
06499
06500 ast_string_field_set(original, musicclass, clonechan->musicclass);
06501
06502
06503 ast_string_field_set(original, accountcode, S_OR(clonechan->accountcode, ""));
06504 if (original->_bridge) {
06505
06506 ast_string_field_set(original->_bridge, peeraccount, S_OR(clonechan->accountcode, ""));
06507 ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL);
06508 }
06509
06510 ast_debug(1, "Putting channel %s in %s/%s formats\n", original->name,
06511 ast_getformatname(wformat), ast_getformatname(rformat));
06512
06513
06514
06515 if (original->tech->fixup) {
06516 if (original->tech->fixup(clonechan, original)) {
06517 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
06518 original->tech->type, original->name);
06519 res = -1;
06520 goto done;
06521 }
06522 } else
06523 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n",
06524 original->tech->type, original->name);
06525
06526
06527
06528
06529
06530
06531
06532
06533
06534 if (visible_indication) {
06535 ast_indicate(original, visible_indication);
06536 }
06537
06538
06539
06540
06541 if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
06542 ast_debug(1, "Destroying channel clone '%s'\n", clonechan->name);
06543 ast_channel_unlock(clonechan);
06544 ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup",
06545 "Channel: %s\r\n"
06546 "Uniqueid: %s\r\n"
06547 "Cause: %d\r\n"
06548 "Cause-txt: %s\r\n",
06549 clonechan->name,
06550 clonechan->uniqueid,
06551 clonechan->hangupcause,
06552 ast_cause2str(clonechan->hangupcause)
06553 );
06554 clonechan = ast_channel_release(clonechan);
06555 } else {
06556 ast_debug(1, "Released clone lock on '%s'\n", clonechan->name);
06557 ast_set_flag(clonechan, AST_FLAG_ZOMBIE);
06558 ast_queue_frame(clonechan, &ast_null_frame);
06559 }
06560
06561
06562 if (ast_test_flag(original, AST_FLAG_BLOCKING))
06563 pthread_kill(original->blocker, SIGURG);
06564 ast_debug(1, "Done Masquerading %s (%d)\n", original->name, original->_state);
06565
06566 if ((bridged = ast_bridged_channel(original))) {
06567 ast_channel_lock(bridged);
06568 ast_indicate(bridged, AST_CONTROL_SRCCHANGE);
06569 ast_channel_unlock(bridged);
06570 }
06571 ast_indicate(original, AST_CONTROL_SRCCHANGE);
06572
06573 if (xfer_colp) {
06574
06575
06576
06577
06578
06579 masquerade_colp_transfer(original, xfer_colp);
06580 }
06581
06582 done:
06583 if (xfer_ds) {
06584 ast_datastore_free(xfer_ds);
06585 }
06586
06587 if (clonechan) {
06588 ast_channel_unlock(original);
06589 ast_channel_unlock(clonechan);
06590 ao2_link(channels, clonechan);
06591 ao2_link(channels, original);
06592 } else {
06593 ast_channel_unlock(original);
06594 ao2_link(channels, original);
06595 }
06596
06597 ao2_unlock(channels);
06598
06599 return res;
06600 }
06601
06602 void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
06603 {
06604 ast_channel_lock(chan);
06605
06606 if (cid_num) {
06607 chan->caller.id.number.valid = 1;
06608 ast_free(chan->caller.id.number.str);
06609 chan->caller.id.number.str = ast_strdup(cid_num);
06610 }
06611 if (cid_name) {
06612 chan->caller.id.name.valid = 1;
06613 ast_free(chan->caller.id.name.str);
06614 chan->caller.id.name.str = ast_strdup(cid_name);
06615 }
06616 if (cid_ani) {
06617 chan->caller.ani.number.valid = 1;
06618 ast_free(chan->caller.ani.number.str);
06619 chan->caller.ani.number.str = ast_strdup(cid_ani);
06620 }
06621 if (chan->cdr) {
06622 ast_cdr_setcid(chan->cdr, chan);
06623 }
06624
06625 report_new_callerid(chan);
06626
06627 ast_channel_unlock(chan);
06628 }
06629
06630 void ast_channel_set_caller(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
06631 {
06632 if (&chan->caller == caller) {
06633
06634 return;
06635 }
06636
06637 ast_channel_lock(chan);
06638 ast_party_caller_set(&chan->caller, caller, update);
06639 ast_channel_unlock(chan);
06640 }
06641
06642 void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
06643 {
06644 struct ast_party_caller pre_set;
06645
06646 if (&chan->caller == caller) {
06647
06648 return;
06649 }
06650
06651 ast_channel_lock(chan);
06652 pre_set = chan->caller;
06653 ast_party_caller_set(&chan->caller, caller, update);
06654 if (S_COR(pre_set.id.number.valid, pre_set.id.number.str, NULL)
06655 != S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)
06656 || S_COR(pre_set.id.name.valid, pre_set.id.name.str, NULL)
06657 != S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)) {
06658
06659 report_new_callerid(chan);
06660 }
06661 if (chan->cdr) {
06662 ast_cdr_setcid(chan->cdr, chan);
06663 }
06664 ast_channel_unlock(chan);
06665 }
06666
06667 int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
06668 {
06669 int oldstate = chan->_state;
06670 char name[AST_CHANNEL_NAME], *dashptr;
06671
06672 if (oldstate == state)
06673 return 0;
06674
06675 ast_copy_string(name, chan->name, sizeof(name));
06676 if ((dashptr = strrchr(name, '-'))) {
06677 *dashptr = '\0';
06678 }
06679
06680 chan->_state = state;
06681
06682
06683
06684
06685 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name);
06686
06687
06688 ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate",
06689 "Channel: %s\r\n"
06690 "ChannelState: %d\r\n"
06691 "ChannelStateDesc: %s\r\n"
06692 "CallerIDNum: %s\r\n"
06693 "CallerIDName: %s\r\n"
06694 "Uniqueid: %s\r\n",
06695 chan->name, chan->_state, ast_state2str(chan->_state),
06696 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
06697 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
06698 chan->uniqueid);
06699
06700 return 0;
06701 }
06702
06703
06704 struct ast_channel *ast_bridged_channel(struct ast_channel *chan)
06705 {
06706 struct ast_channel *bridged;
06707 bridged = chan->_bridge;
06708 if (bridged && bridged->tech->bridged_channel)
06709 bridged = bridged->tech->bridged_channel(chan, bridged);
06710 return bridged;
06711 }
06712
06713 static void bridge_playfile(struct ast_channel *chan, struct ast_channel *peer, const char *sound, int remain)
06714 {
06715 int min = 0, sec = 0, check;
06716
06717 check = ast_autoservice_start(peer);
06718 if (check)
06719 return;
06720
06721 if (remain > 0) {
06722 if (remain / 60 > 1) {
06723 min = remain / 60;
06724 sec = remain % 60;
06725 } else {
06726 sec = remain;
06727 }
06728 }
06729
06730 if (!strcmp(sound,"timeleft")) {
06731 ast_stream_and_wait(chan, "vm-youhave", "");
06732 if (min) {
06733 ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL);
06734 ast_stream_and_wait(chan, "queue-minutes", "");
06735 }
06736 if (sec) {
06737 ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL);
06738 ast_stream_and_wait(chan, "queue-seconds", "");
06739 }
06740 } else {
06741 ast_stream_and_wait(chan, sound, "");
06742 }
06743
06744 ast_autoservice_stop(peer);
06745 }
06746
06747 static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct ast_channel *c1,
06748 struct ast_bridge_config *config, struct ast_frame **fo,
06749 struct ast_channel **rc)
06750 {
06751
06752 struct ast_channel *cs[3];
06753 struct ast_frame *f;
06754 enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
06755 format_t o0nativeformats;
06756 format_t o1nativeformats;
06757 int watch_c0_dtmf;
06758 int watch_c1_dtmf;
06759 void *pvt0, *pvt1;
06760
06761 int frame_put_in_jb = 0;
06762 int jb_in_use;
06763 int to;
06764
06765 cs[0] = c0;
06766 cs[1] = c1;
06767 pvt0 = c0->tech_pvt;
06768 pvt1 = c1->tech_pvt;
06769 o0nativeformats = c0->nativeformats;
06770 o1nativeformats = c1->nativeformats;
06771 watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
06772 watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
06773
06774
06775 jb_in_use = ast_jb_do_usecheck(c0, c1);
06776 if (jb_in_use)
06777 ast_jb_empty_and_reset(c0, c1);
06778
06779 ast_poll_channel_add(c0, c1);
06780
06781 if (config->feature_timer > 0 && ast_tvzero(config->nexteventts)) {
06782
06783
06784
06785 config->nexteventts = ast_tvadd(ast_tvnow(), ast_samp2tv(config->feature_timer, 1000));
06786 }
06787
06788 for (;;) {
06789 struct ast_channel *who, *other;
06790
06791 if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
06792 (o0nativeformats != c0->nativeformats) ||
06793 (o1nativeformats != c1->nativeformats)) {
06794
06795 res = AST_BRIDGE_RETRY;
06796 break;
06797 }
06798 if (config->nexteventts.tv_sec) {
06799 to = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
06800 if (to <= 0) {
06801 if (config->timelimit && !config->feature_timer && !ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
06802 res = AST_BRIDGE_RETRY;
06803
06804 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
06805 } else if (config->feature_timer) {
06806
06807 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
06808 res = AST_BRIDGE_RETRY;
06809 } else {
06810 res = AST_BRIDGE_COMPLETE;
06811 }
06812 break;
06813 }
06814 } else {
06815
06816
06817
06818
06819 if (!ast_tvzero(config->nexteventts)) {
06820 int diff = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
06821 if (diff <= 0) {
06822 res = AST_BRIDGE_RETRY;
06823 break;
06824 }
06825 }
06826 to = -1;
06827 }
06828
06829
06830 if (jb_in_use)
06831 to = ast_jb_get_when_to_wakeup(c0, c1, to);
06832 who = ast_waitfor_n(cs, 2, &to);
06833 if (!who) {
06834
06835 if (jb_in_use)
06836 ast_jb_get_and_deliver(c0, c1);
06837 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {
06838 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
06839 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
06840 }
06841 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
06842 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
06843 }
06844 c0->_bridge = c1;
06845 c1->_bridge = c0;
06846 }
06847 continue;
06848 }
06849 f = ast_read(who);
06850 if (!f) {
06851 *fo = NULL;
06852 *rc = who;
06853 ast_debug(1, "Didn't get a frame from channel: %s\n",who->name);
06854 break;
06855 }
06856
06857 other = (who == c0) ? c1 : c0;
06858
06859 if (jb_in_use)
06860 frame_put_in_jb = !ast_jb_put(other, f);
06861
06862 if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
06863 int bridge_exit = 0;
06864
06865 switch (f->subclass.integer) {
06866 case AST_CONTROL_AOC:
06867 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
06868 break;
06869 case AST_CONTROL_REDIRECTING:
06870 if (ast_channel_redirecting_macro(who, other, f, other == c0, 1)) {
06871 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
06872 }
06873 break;
06874 case AST_CONTROL_CONNECTED_LINE:
06875 if (ast_channel_connected_line_macro(who, other, f, other == c0, 1)) {
06876 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
06877 }
06878 break;
06879 case AST_CONTROL_HOLD:
06880 case AST_CONTROL_UNHOLD:
06881 case AST_CONTROL_VIDUPDATE:
06882 case AST_CONTROL_SRCUPDATE:
06883 case AST_CONTROL_SRCCHANGE:
06884 case AST_CONTROL_T38_PARAMETERS:
06885 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
06886 if (jb_in_use) {
06887 ast_jb_empty_and_reset(c0, c1);
06888 }
06889 break;
06890 default:
06891 *fo = f;
06892 *rc = who;
06893 bridge_exit = 1;
06894 ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass.integer, who->name);
06895 break;
06896 }
06897 if (bridge_exit)
06898 break;
06899 }
06900 if ((f->frametype == AST_FRAME_VOICE) ||
06901 (f->frametype == AST_FRAME_DTMF_BEGIN) ||
06902 (f->frametype == AST_FRAME_DTMF) ||
06903 (f->frametype == AST_FRAME_VIDEO) ||
06904 (f->frametype == AST_FRAME_IMAGE) ||
06905 (f->frametype == AST_FRAME_HTML) ||
06906 (f->frametype == AST_FRAME_MODEM) ||
06907 (f->frametype == AST_FRAME_TEXT)) {
06908
06909 int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
06910
06911 if (monitored_source &&
06912 (f->frametype == AST_FRAME_DTMF_END ||
06913 f->frametype == AST_FRAME_DTMF_BEGIN)) {
06914 *fo = f;
06915 *rc = who;
06916 ast_debug(1, "Got DTMF %s on channel (%s)\n",
06917 f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
06918 who->name);
06919
06920 break;
06921 }
06922
06923 if (!frame_put_in_jb)
06924 ast_write(other, f);
06925
06926
06927 if (jb_in_use)
06928 ast_jb_get_and_deliver(c0, c1);
06929 }
06930
06931 ast_frfree(f);
06932
06933 #ifndef HAVE_EPOLL
06934
06935 cs[2] = cs[0];
06936 cs[0] = cs[1];
06937 cs[1] = cs[2];
06938 #endif
06939 }
06940
06941 ast_poll_channel_del(c0, c1);
06942
06943 return res;
06944 }
06945
06946
06947 int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
06948 {
06949
06950 if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge)))
06951 return -1;
06952
06953 return c0->tech->early_bridge(c0, c1);
06954 }
06955
06956
06957
06958
06959
06960
06961
06962 static void manager_bridge_event(int onoff, int type, struct ast_channel *c0, struct ast_channel *c1)
06963 {
06964 struct ast_channel *chans[2] = { c0, c1 };
06965 ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans,
06966 "Bridgestate: %s\r\n"
06967 "Bridgetype: %s\r\n"
06968 "Channel1: %s\r\n"
06969 "Channel2: %s\r\n"
06970 "Uniqueid1: %s\r\n"
06971 "Uniqueid2: %s\r\n"
06972 "CallerID1: %s\r\n"
06973 "CallerID2: %s\r\n",
06974 onoff ? "Link" : "Unlink",
06975 type == 1 ? "core" : "native",
06976 c0->name, c1->name,
06977 c0->uniqueid, c1->uniqueid,
06978 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, ""),
06979 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, ""));
06980 }
06981
06982 static void update_bridge_vars(struct ast_channel *c0, struct ast_channel *c1)
06983 {
06984 const char *c0_name;
06985 const char *c1_name;
06986 const char *c0_pvtid = NULL;
06987 const char *c1_pvtid = NULL;
06988
06989 ast_channel_lock(c1);
06990 c1_name = ast_strdupa(c1->name);
06991 if (c1->tech->get_pvt_uniqueid) {
06992 c1_pvtid = ast_strdupa(c1->tech->get_pvt_uniqueid(c1));
06993 }
06994 ast_channel_unlock(c1);
06995
06996 ast_channel_lock(c0);
06997 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) {
06998 pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name);
06999 }
07000 if (c1_pvtid) {
07001 pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1_pvtid);
07002 }
07003 c0_name = ast_strdupa(c0->name);
07004 if (c0->tech->get_pvt_uniqueid) {
07005 c0_pvtid = ast_strdupa(c0->tech->get_pvt_uniqueid(c0));
07006 }
07007 ast_channel_unlock(c0);
07008
07009 ast_channel_lock(c1);
07010 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) {
07011 pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name);
07012 }
07013 if (c0_pvtid) {
07014 pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0_pvtid);
07015 }
07016 ast_channel_unlock(c1);
07017 }
07018
07019 static void bridge_play_sounds(struct ast_channel *c0, struct ast_channel *c1)
07020 {
07021 const char *s, *sound;
07022
07023
07024
07025 ast_channel_lock(c0);
07026 if ((s = pbx_builtin_getvar_helper(c0, "BRIDGE_PLAY_SOUND"))) {
07027 sound = ast_strdupa(s);
07028 ast_channel_unlock(c0);
07029 bridge_playfile(c0, c1, sound, 0);
07030 pbx_builtin_setvar_helper(c0, "BRIDGE_PLAY_SOUND", NULL);
07031 } else {
07032 ast_channel_unlock(c0);
07033 }
07034
07035 ast_channel_lock(c1);
07036 if ((s = pbx_builtin_getvar_helper(c1, "BRIDGE_PLAY_SOUND"))) {
07037 sound = ast_strdupa(s);
07038 ast_channel_unlock(c1);
07039 bridge_playfile(c1, c0, sound, 0);
07040 pbx_builtin_setvar_helper(c1, "BRIDGE_PLAY_SOUND", NULL);
07041 } else {
07042 ast_channel_unlock(c1);
07043 }
07044 }
07045
07046
07047 enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1,
07048 struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
07049 {
07050 struct ast_channel *chans[2] = { c0, c1 };
07051 enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
07052 format_t o0nativeformats;
07053 format_t o1nativeformats;
07054 long time_left_ms=0;
07055 char caller_warning = 0;
07056 char callee_warning = 0;
07057
07058 if (c0->_bridge) {
07059 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07060 c0->name, c0->_bridge->name);
07061 return -1;
07062 }
07063 if (c1->_bridge) {
07064 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07065 c1->name, c1->_bridge->name);
07066 return -1;
07067 }
07068
07069
07070 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07071 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
07072 return -1;
07073
07074 *fo = NULL;
07075
07076 if (ast_tvzero(config->start_time)) {
07077 config->start_time = ast_tvnow();
07078 if (config->start_sound) {
07079 if (caller_warning) {
07080 bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000);
07081 }
07082 if (callee_warning) {
07083 bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000);
07084 }
07085 }
07086 }
07087
07088
07089 c0->_bridge = c1;
07090 c1->_bridge = c0;
07091
07092 ast_set_owners_and_peers(c0, c1);
07093
07094 o0nativeformats = c0->nativeformats;
07095 o1nativeformats = c1->nativeformats;
07096
07097 if (config->feature_timer && !ast_tvzero(config->nexteventts)) {
07098 config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000));
07099 } else if (config->timelimit) {
07100 time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time);
07101 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
07102 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
07103 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07104 if ((caller_warning || callee_warning) && config->play_warning) {
07105 long next_warn = config->play_warning;
07106 if (time_left_ms < config->play_warning) {
07107
07108 long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq;
07109
07110
07111 next_warn = config->play_warning - warns_passed * config->warning_freq;
07112 }
07113 config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000));
07114 }
07115 } else {
07116 config->nexteventts.tv_sec = 0;
07117 config->nexteventts.tv_usec = 0;
07118 }
07119
07120 if (!c0->tech->send_digit_begin)
07121 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
07122 if (!c1->tech->send_digit_begin)
07123 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
07124 manager_bridge_event(1, 1, c0, c1);
07125
07126
07127 ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07128 ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07129
07130 for (;;) {
07131 struct timeval now = { 0, };
07132 int to;
07133
07134 to = -1;
07135
07136 if (!ast_tvzero(config->nexteventts)) {
07137 now = ast_tvnow();
07138 to = ast_tvdiff_ms(config->nexteventts, now);
07139 if (to <= 0) {
07140 if (!config->timelimit) {
07141 res = AST_BRIDGE_COMPLETE;
07142 break;
07143 }
07144 to = 0;
07145 }
07146 }
07147
07148 if (config->timelimit) {
07149 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
07150 if (time_left_ms < to)
07151 to = time_left_ms;
07152
07153 if (time_left_ms <= 0) {
07154 if (caller_warning && config->end_sound)
07155 bridge_playfile(c0, c1, config->end_sound, 0);
07156 if (callee_warning && config->end_sound)
07157 bridge_playfile(c1, c0, config->end_sound, 0);
07158 *fo = NULL;
07159 res = 0;
07160 break;
07161 }
07162
07163 if (!to) {
07164 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
07165 int t = (time_left_ms + 500) / 1000;
07166 if (caller_warning)
07167 bridge_playfile(c0, c1, config->warning_sound, t);
07168 if (callee_warning)
07169 bridge_playfile(c1, c0, config->warning_sound, t);
07170 }
07171
07172 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) {
07173 config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000));
07174 } else {
07175 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07176 }
07177 }
07178 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
07179 }
07180
07181 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {
07182 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07183 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
07184 }
07185 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07186 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
07187 }
07188 c0->_bridge = c1;
07189 c1->_bridge = c0;
07190 ast_debug(1, "Unbridge signal received. Ending native bridge.\n");
07191 continue;
07192 }
07193
07194
07195 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07196 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
07197 *fo = NULL;
07198 res = 0;
07199 ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
07200 c0->name, c1->name,
07201 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
07202 ast_check_hangup(c0) ? "Yes" : "No",
07203 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
07204 ast_check_hangup(c1) ? "Yes" : "No");
07205 break;
07206 }
07207
07208 update_bridge_vars(c0, c1);
07209
07210 bridge_play_sounds(c0, c1);
07211
07212 if (c0->tech->bridge &&
07213
07214 (!config->timelimit || to > 1000 || to == 0) &&
07215 (c0->tech->bridge == c1->tech->bridge) &&
07216 !c0->monitor && !c1->monitor &&
07217 !c0->audiohooks && !c1->audiohooks &&
07218 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
07219 int timeoutms = to - 1000 > 0 ? to - 1000 : to;
07220
07221 ast_set_flag(c0, AST_FLAG_NBRIDGE);
07222 ast_set_flag(c1, AST_FLAG_NBRIDGE);
07223 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) {
07224 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
07225 "Channel1: %s\r\n"
07226 "Channel2: %s\r\n"
07227 "Uniqueid1: %s\r\n"
07228 "Uniqueid2: %s\r\n"
07229 "CallerID1: %s\r\n"
07230 "CallerID2: %s\r\n",
07231 c0->name, c1->name,
07232 c0->uniqueid, c1->uniqueid,
07233 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"),
07234 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
07235
07236 ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
07237
07238 ast_clear_flag(c0, AST_FLAG_NBRIDGE);
07239 ast_clear_flag(c1, AST_FLAG_NBRIDGE);
07240
07241 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {
07242 continue;
07243 }
07244
07245 c0->_bridge = NULL;
07246 c1->_bridge = NULL;
07247 return res;
07248 } else {
07249 ast_clear_flag(c0, AST_FLAG_NBRIDGE);
07250 ast_clear_flag(c1, AST_FLAG_NBRIDGE);
07251 }
07252 switch (res) {
07253 case AST_BRIDGE_RETRY:
07254 if (config->play_warning) {
07255 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
07256 }
07257 continue;
07258 default:
07259 ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name);
07260
07261 case AST_BRIDGE_FAILED_NOWARN:
07262 break;
07263 }
07264 }
07265
07266 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
07267 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
07268 !(c0->generator || c1->generator)) {
07269 if (ast_channel_make_compatible(c0, c1)) {
07270 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
07271 manager_bridge_event(0, 1, c0, c1);
07272 return AST_BRIDGE_FAILED;
07273 }
07274 o0nativeformats = c0->nativeformats;
07275 o1nativeformats = c1->nativeformats;
07276 }
07277
07278 update_bridge_vars(c0, c1);
07279
07280 res = ast_generic_bridge(c0, c1, config, fo, rc);
07281 if (res != AST_BRIDGE_RETRY) {
07282 break;
07283 } else if (config->feature_timer) {
07284
07285 break;
07286 }
07287 }
07288
07289 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
07290 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
07291
07292
07293 ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07294 ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07295
07296 c0->_bridge = NULL;
07297 c1->_bridge = NULL;
07298
07299 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
07300 "Channel1: %s\r\n"
07301 "Channel2: %s\r\n"
07302 "Uniqueid1: %s\r\n"
07303 "Uniqueid2: %s\r\n"
07304 "CallerID1: %s\r\n"
07305 "CallerID2: %s\r\n",
07306 c0->name, c1->name,
07307 c0->uniqueid, c1->uniqueid,
07308 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"),
07309 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
07310 ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
07311
07312 return res;
07313 }
07314
07315
07316 int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
07317 {
07318 if (!chan->tech->setoption) {
07319 errno = ENOSYS;
07320 return -1;
07321 }
07322
07323 if (block)
07324 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07325
07326 return chan->tech->setoption(chan, option, data, datalen);
07327 }
07328
07329 int ast_channel_queryoption(struct ast_channel *chan, int option, void *data, int *datalen, int block)
07330 {
07331 if (!chan->tech->queryoption) {
07332 errno = ENOSYS;
07333 return -1;
07334 }
07335
07336 if (block)
07337 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07338
07339 return chan->tech->queryoption(chan, option, data, datalen);
07340 }
07341
07342 struct tonepair_def {
07343 int freq1;
07344 int freq2;
07345 int duration;
07346 int vol;
07347 };
07348
07349 struct tonepair_state {
07350 int fac1;
07351 int fac2;
07352 int v1_1;
07353 int v2_1;
07354 int v3_1;
07355 int v1_2;
07356 int v2_2;
07357 int v3_2;
07358 format_t origwfmt;
07359 int pos;
07360 int duration;
07361 int modulate;
07362 struct ast_frame f;
07363 unsigned char offset[AST_FRIENDLY_OFFSET];
07364 short data[4000];
07365 };
07366
07367 static void tonepair_release(struct ast_channel *chan, void *params)
07368 {
07369 struct tonepair_state *ts = params;
07370
07371 if (chan)
07372 ast_set_write_format(chan, ts->origwfmt);
07373 ast_free(ts);
07374 }
07375
07376 static void *tonepair_alloc(struct ast_channel *chan, void *params)
07377 {
07378 struct tonepair_state *ts;
07379 struct tonepair_def *td = params;
07380
07381 if (!(ts = ast_calloc(1, sizeof(*ts))))
07382 return NULL;
07383 ts->origwfmt = chan->writeformat;
07384 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
07385 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
07386 tonepair_release(NULL, ts);
07387 ts = NULL;
07388 } else {
07389 ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
07390 ts->v1_1 = 0;
07391 ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07392 ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07393 ts->v2_1 = 0;
07394 ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
07395 ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07396 ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07397 ts->duration = td->duration;
07398 ts->modulate = 0;
07399 }
07400
07401 ast_set_flag(chan, AST_FLAG_WRITE_INT);
07402 return ts;
07403 }
07404
07405 static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples)
07406 {
07407 struct tonepair_state *ts = data;
07408 int x;
07409
07410
07411
07412
07413 len = samples * 2;
07414
07415 if (len > sizeof(ts->data) / 2 - 1) {
07416 ast_log(LOG_WARNING, "Can't generate that much data!\n");
07417 return -1;
07418 }
07419 memset(&ts->f, 0, sizeof(ts->f));
07420 for (x=0;x<len/2;x++) {
07421 ts->v1_1 = ts->v2_1;
07422 ts->v2_1 = ts->v3_1;
07423 ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
07424
07425 ts->v1_2 = ts->v2_2;
07426 ts->v2_2 = ts->v3_2;
07427 ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
07428 if (ts->modulate) {
07429 int p;
07430 p = ts->v3_2 - 32768;
07431 if (p < 0) p = -p;
07432 p = ((p * 9) / 10) + 1;
07433 ts->data[x] = (ts->v3_1 * p) >> 15;
07434 } else
07435 ts->data[x] = ts->v3_1 + ts->v3_2;
07436 }
07437 ts->f.frametype = AST_FRAME_VOICE;
07438 ts->f.subclass.codec = AST_FORMAT_SLINEAR;
07439 ts->f.datalen = len;
07440 ts->f.samples = samples;
07441 ts->f.offset = AST_FRIENDLY_OFFSET;
07442 ts->f.data.ptr = ts->data;
07443 ast_write(chan, &ts->f);
07444 ts->pos += x;
07445 if (ts->duration > 0) {
07446 if (ts->pos >= ts->duration * 8)
07447 return -1;
07448 }
07449 return 0;
07450 }
07451
07452 static struct ast_generator tonepair = {
07453 alloc: tonepair_alloc,
07454 release: tonepair_release,
07455 generate: tonepair_generator,
07456 };
07457
07458 int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
07459 {
07460 struct tonepair_def d = { 0, };
07461
07462 d.freq1 = freq1;
07463 d.freq2 = freq2;
07464 d.duration = duration;
07465 d.vol = (vol < 1) ? 8192 : vol;
07466 if (ast_activate_generator(chan, &tonepair, &d))
07467 return -1;
07468 return 0;
07469 }
07470
07471 void ast_tonepair_stop(struct ast_channel *chan)
07472 {
07473 ast_deactivate_generator(chan);
07474 }
07475
07476 int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
07477 {
07478 int res;
07479
07480 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
07481 return res;
07482
07483
07484 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
07485 struct ast_frame *f = ast_read(chan);
07486 if (f)
07487 ast_frfree(f);
07488 else
07489 return -1;
07490 }
07491 return 0;
07492 }
07493
07494 ast_group_t ast_get_group(const char *s)
07495 {
07496 char *piece;
07497 char *c;
07498 int start=0, finish=0, x;
07499 ast_group_t group = 0;
07500
07501 if (ast_strlen_zero(s))
07502 return 0;
07503
07504 c = ast_strdupa(s);
07505
07506 while ((piece = strsep(&c, ","))) {
07507 if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) {
07508
07509 } else if (sscanf(piece, "%30d", &start)) {
07510
07511 finish = start;
07512 } else {
07513 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
07514 continue;
07515 }
07516 for (x = start; x <= finish; x++) {
07517 if ((x > 63) || (x < 0)) {
07518 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
07519 } else
07520 group |= ((ast_group_t) 1 << x);
07521 }
07522 }
07523 return group;
07524 }
07525
07526 static int (*ast_moh_start_ptr)(struct ast_channel *, const char *, const char *) = NULL;
07527 static void (*ast_moh_stop_ptr)(struct ast_channel *) = NULL;
07528 static void (*ast_moh_cleanup_ptr)(struct ast_channel *) = NULL;
07529
07530 void ast_install_music_functions(int (*start_ptr)(struct ast_channel *, const char *, const char *),
07531 void (*stop_ptr)(struct ast_channel *),
07532 void (*cleanup_ptr)(struct ast_channel *))
07533 {
07534 ast_moh_start_ptr = start_ptr;
07535 ast_moh_stop_ptr = stop_ptr;
07536 ast_moh_cleanup_ptr = cleanup_ptr;
07537 }
07538
07539 void ast_uninstall_music_functions(void)
07540 {
07541 ast_moh_start_ptr = NULL;
07542 ast_moh_stop_ptr = NULL;
07543 ast_moh_cleanup_ptr = NULL;
07544 }
07545
07546
07547 int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
07548 {
07549 if (ast_moh_start_ptr)
07550 return ast_moh_start_ptr(chan, mclass, interpclass);
07551
07552 ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default"));
07553
07554 return 0;
07555 }
07556
07557
07558 void ast_moh_stop(struct ast_channel *chan)
07559 {
07560 if (ast_moh_stop_ptr)
07561 ast_moh_stop_ptr(chan);
07562 }
07563
07564 void ast_moh_cleanup(struct ast_channel *chan)
07565 {
07566 if (ast_moh_cleanup_ptr)
07567 ast_moh_cleanup_ptr(chan);
07568 }
07569
07570 static int ast_channel_hash_cb(const void *obj, const int flags)
07571 {
07572 const struct ast_channel *chan = obj;
07573
07574
07575
07576 if (ast_strlen_zero(chan->name)) {
07577 return 0;
07578 }
07579
07580 return ast_str_case_hash(chan->name);
07581 }
07582
07583 int ast_plc_reload(void)
07584 {
07585 struct ast_variable *var;
07586 struct ast_flags config_flags = { 0 };
07587 struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
07588 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
07589 return 0;
07590 for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
07591 if (!strcasecmp(var->name, "genericplc")) {
07592 ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC);
07593 }
07594 }
07595 ast_config_destroy(cfg);
07596 return 0;
07597 }
07598
07599
07600
07601
07602
07603 static int data_channels_provider_handler(const struct ast_data_search *search,
07604 struct ast_data *root)
07605 {
07606 struct ast_channel *c;
07607 struct ast_channel_iterator *iter = NULL;
07608 struct ast_data *data_channel;
07609
07610 for (iter = ast_channel_iterator_all_new();
07611 iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
07612 ast_channel_lock(c);
07613
07614 data_channel = ast_data_add_node(root, "channel");
07615 if (!data_channel) {
07616 ast_channel_unlock(c);
07617 continue;
07618 }
07619
07620 if (ast_channel_data_add_structure(data_channel, c, 1) < 0) {
07621 ast_log(LOG_ERROR, "Unable to add channel structure for channel: %s\n", c->name);
07622 }
07623
07624 ast_channel_unlock(c);
07625
07626 if (!ast_data_search_match(search, data_channel)) {
07627 ast_data_remove_node(root, data_channel);
07628 }
07629 }
07630 if (iter) {
07631 ast_channel_iterator_destroy(iter);
07632 }
07633
07634 return 0;
07635 }
07636
07637
07638
07639
07640
07641 static int data_channeltypes_provider_handler(const struct ast_data_search *search,
07642 struct ast_data *data_root)
07643 {
07644 struct chanlist *cl;
07645 struct ast_data *data_type;
07646
07647 AST_RWLIST_RDLOCK(&backends);
07648 AST_RWLIST_TRAVERSE(&backends, cl, list) {
07649 data_type = ast_data_add_node(data_root, "type");
07650 if (!data_type) {
07651 continue;
07652 }
07653 ast_data_add_str(data_type, "name", cl->tech->type);
07654 ast_data_add_str(data_type, "description", cl->tech->description);
07655 ast_data_add_bool(data_type, "devicestate", cl->tech->devicestate ? 1 : 0);
07656 ast_data_add_bool(data_type, "indications", cl->tech->indicate ? 1 : 0);
07657 ast_data_add_bool(data_type, "transfer", cl->tech->transfer ? 1 : 0);
07658 ast_data_add_bool(data_type, "send_digit_begin", cl->tech->send_digit_begin ? 1 : 0);
07659 ast_data_add_bool(data_type, "send_digit_end", cl->tech->send_digit_end ? 1 : 0);
07660 ast_data_add_bool(data_type, "call", cl->tech->call ? 1 : 0);
07661 ast_data_add_bool(data_type, "hangup", cl->tech->hangup ? 1 : 0);
07662 ast_data_add_bool(data_type, "answer", cl->tech->answer ? 1 : 0);
07663 ast_data_add_bool(data_type, "read", cl->tech->read ? 1 : 0);
07664 ast_data_add_bool(data_type, "write", cl->tech->write ? 1 : 0);
07665 ast_data_add_bool(data_type, "send_text", cl->tech->send_text ? 1 : 0);
07666 ast_data_add_bool(data_type, "send_image", cl->tech->send_image ? 1 : 0);
07667 ast_data_add_bool(data_type, "send_html", cl->tech->send_html ? 1 : 0);
07668 ast_data_add_bool(data_type, "exception", cl->tech->exception ? 1 : 0);
07669 ast_data_add_bool(data_type, "bridge", cl->tech->bridge ? 1 : 0);
07670 ast_data_add_bool(data_type, "early_bridge", cl->tech->early_bridge ? 1 : 0);
07671 ast_data_add_bool(data_type, "fixup", cl->tech->fixup ? 1 : 0);
07672 ast_data_add_bool(data_type, "setoption", cl->tech->setoption ? 1 : 0);
07673 ast_data_add_bool(data_type, "queryoption", cl->tech->queryoption ? 1 : 0);
07674 ast_data_add_bool(data_type, "write_video", cl->tech->write_video ? 1 : 0);
07675 ast_data_add_bool(data_type, "write_text", cl->tech->write_text ? 1 : 0);
07676 ast_data_add_bool(data_type, "bridged_channel", cl->tech->bridged_channel ? 1 : 0);
07677 ast_data_add_bool(data_type, "func_channel_read", cl->tech->func_channel_read ? 1 : 0);
07678 ast_data_add_bool(data_type, "func_channel_write", cl->tech->func_channel_write ? 1 : 0);
07679 ast_data_add_bool(data_type, "get_base_channel", cl->tech->get_base_channel ? 1 : 0);
07680 ast_data_add_bool(data_type, "set_base_channel", cl->tech->set_base_channel ? 1 : 0);
07681 ast_data_add_bool(data_type, "get_pvt_uniqueid", cl->tech->get_pvt_uniqueid ? 1 : 0);
07682 ast_data_add_bool(data_type, "cc_callback", cl->tech->cc_callback ? 1 : 0);
07683
07684 ast_data_add_codecs(data_type, "capabilities", cl->tech->capabilities);
07685
07686 if (!ast_data_search_match(search, data_type)) {
07687 ast_data_remove_node(data_root, data_type);
07688 }
07689 }
07690 AST_RWLIST_UNLOCK(&backends);
07691
07692 return 0;
07693 }
07694
07695
07696
07697
07698
07699 static const struct ast_data_handler channels_provider = {
07700 .version = AST_DATA_HANDLER_VERSION,
07701 .get = data_channels_provider_handler
07702 };
07703
07704
07705
07706
07707
07708 static const struct ast_data_handler channeltypes_provider = {
07709 .version = AST_DATA_HANDLER_VERSION,
07710 .get = data_channeltypes_provider_handler
07711 };
07712
07713 static const struct ast_data_entry channel_providers[] = {
07714 AST_DATA_ENTRY("/asterisk/core/channels", &channels_provider),
07715 AST_DATA_ENTRY("/asterisk/core/channeltypes", &channeltypes_provider),
07716 };
07717
07718 void ast_channels_init(void)
07719 {
07720 channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS,
07721 ast_channel_hash_cb, ast_channel_cmp_cb);
07722
07723 ast_cli_register_multiple(cli_channel, ARRAY_LEN(cli_channel));
07724
07725 ast_data_register_multiple_core(channel_providers, ARRAY_LEN(channel_providers));
07726
07727 ast_plc_reload();
07728 }
07729
07730
07731 char *ast_print_group(char *buf, int buflen, ast_group_t group)
07732 {
07733 unsigned int i;
07734 int first = 1;
07735 char num[3];
07736
07737 buf[0] = '\0';
07738
07739 if (!group)
07740 return buf;
07741
07742 for (i = 0; i <= 63; i++) {
07743 if (group & ((ast_group_t) 1 << i)) {
07744 if (!first) {
07745 strncat(buf, ", ", buflen - strlen(buf) - 1);
07746 } else {
07747 first = 0;
07748 }
07749 snprintf(num, sizeof(num), "%u", i);
07750 strncat(buf, num, buflen - strlen(buf) - 1);
07751 }
07752 }
07753 return buf;
07754 }
07755
07756 void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
07757 {
07758 struct ast_variable *cur;
07759
07760 for (cur = vars; cur; cur = cur->next)
07761 pbx_builtin_setvar_helper(chan, cur->name, cur->value);
07762 }
07763
07764 static void *silence_generator_alloc(struct ast_channel *chan, void *data)
07765 {
07766
07767 return data;
07768 }
07769
07770 static void silence_generator_release(struct ast_channel *chan, void *data)
07771 {
07772
07773 }
07774
07775 static int silence_generator_generate(struct ast_channel *chan, void *data, int len, int samples)
07776 {
07777 short buf[samples];
07778 struct ast_frame frame = {
07779 .frametype = AST_FRAME_VOICE,
07780 .subclass.codec = AST_FORMAT_SLINEAR,
07781 .data.ptr = buf,
07782 .samples = samples,
07783 .datalen = sizeof(buf),
07784 };
07785
07786 memset(buf, 0, sizeof(buf));
07787
07788 if (ast_write(chan, &frame))
07789 return -1;
07790
07791 return 0;
07792 }
07793
07794 static struct ast_generator silence_generator = {
07795 .alloc = silence_generator_alloc,
07796 .release = silence_generator_release,
07797 .generate = silence_generator_generate,
07798 };
07799
07800 struct ast_silence_generator {
07801 int old_write_format;
07802 };
07803
07804 struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan)
07805 {
07806 struct ast_silence_generator *state;
07807
07808 if (!(state = ast_calloc(1, sizeof(*state)))) {
07809 return NULL;
07810 }
07811
07812 state->old_write_format = chan->writeformat;
07813
07814 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
07815 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
07816 ast_free(state);
07817 return NULL;
07818 }
07819
07820 ast_activate_generator(chan, &silence_generator, state);
07821
07822 ast_debug(1, "Started silence generator on '%s'\n", chan->name);
07823
07824 return state;
07825 }
07826
07827 void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
07828 {
07829 if (!state)
07830 return;
07831
07832 ast_deactivate_generator(chan);
07833
07834 ast_debug(1, "Stopped silence generator on '%s'\n", chan->name);
07835
07836 if (ast_set_write_format(chan, state->old_write_format) < 0)
07837 ast_log(LOG_ERROR, "Could not return write format to its original state\n");
07838
07839 ast_free(state);
07840 }
07841
07842
07843
07844 const char *channelreloadreason2txt(enum channelreloadreason reason)
07845 {
07846 switch (reason) {
07847 case CHANNEL_MODULE_LOAD:
07848 return "LOAD (Channel module load)";
07849
07850 case CHANNEL_MODULE_RELOAD:
07851 return "RELOAD (Channel module reload)";
07852
07853 case CHANNEL_CLI_RELOAD:
07854 return "CLIRELOAD (Channel module reload by CLI command)";
07855
07856 default:
07857 return "MANAGERRELOAD (Channel module reload by manager)";
07858 }
07859 };
07860
07861
07862
07863
07864
07865
07866
07867
07868
07869 int ast_say_number(struct ast_channel *chan, int num,
07870 const char *ints, const char *language, const char *options)
07871 {
07872 return ast_say_number_full(chan, num, ints, language, options, -1, -1);
07873 }
07874
07875 int ast_say_enumeration(struct ast_channel *chan, int num,
07876 const char *ints, const char *language, const char *options)
07877 {
07878 return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
07879 }
07880
07881 int ast_say_digits(struct ast_channel *chan, int num,
07882 const char *ints, const char *lang)
07883 {
07884 return ast_say_digits_full(chan, num, ints, lang, -1, -1);
07885 }
07886
07887 int ast_say_digit_str(struct ast_channel *chan, const char *str,
07888 const char *ints, const char *lang)
07889 {
07890 return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
07891 }
07892
07893 int ast_say_character_str(struct ast_channel *chan, const char *str,
07894 const char *ints, const char *lang)
07895 {
07896 return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
07897 }
07898
07899 int ast_say_phonetic_str(struct ast_channel *chan, const char *str,
07900 const char *ints, const char *lang)
07901 {
07902 return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
07903 }
07904
07905 int ast_say_digits_full(struct ast_channel *chan, int num,
07906 const char *ints, const char *lang, int audiofd, int ctrlfd)
07907 {
07908 char buf[256];
07909
07910 snprintf(buf, sizeof(buf), "%d", num);
07911
07912 return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
07913 }
07914
07915 void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
07916 {
07917 ast_party_id_copy(&dest->id, &src->id);
07918 ast_party_id_copy(&dest->ani, &src->ani);
07919 dest->ani2 = src->ani2;
07920 }
07921
07922 void ast_connected_line_copy_to_caller(struct ast_party_caller *dest, const struct ast_party_connected_line *src)
07923 {
07924 ast_party_id_copy(&dest->id, &src->id);
07925 ast_party_id_copy(&dest->ani, &src->ani);
07926
07927 dest->ani2 = src->ani2;
07928 }
07929
07930 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)
07931 {
07932 if (&chan->connected == connected) {
07933
07934 return;
07935 }
07936
07937 ast_channel_lock(chan);
07938 ast_party_connected_line_set(&chan->connected, connected, update);
07939 ast_channel_unlock(chan);
07940 }
07941
07942
07943 struct ast_party_name_ies {
07944
07945 int str;
07946
07947 int char_set;
07948
07949 int presentation;
07950
07951 int valid;
07952 };
07953
07954
07955
07956
07957
07958
07959
07960
07961
07962
07963
07964
07965
07966
07967
07968 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)
07969 {
07970 size_t length;
07971 size_t pos = 0;
07972
07973
07974
07975
07976
07977 if (name->str) {
07978 length = strlen(name->str);
07979 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
07980 ast_log(LOG_WARNING, "No space left for %s name\n", label);
07981 return -1;
07982 }
07983 data[pos++] = ies->str;
07984 data[pos++] = length;
07985 memcpy(data + pos, name->str, length);
07986 pos += length;
07987 }
07988
07989 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
07990 ast_log(LOG_WARNING, "No space left for %s name char set\n", label);
07991 return -1;
07992 }
07993 data[pos++] = ies->char_set;
07994 data[pos++] = 1;
07995 data[pos++] = name->char_set;
07996
07997 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
07998 ast_log(LOG_WARNING, "No space left for %s name presentation\n", label);
07999 return -1;
08000 }
08001 data[pos++] = ies->presentation;
08002 data[pos++] = 1;
08003 data[pos++] = name->presentation;
08004
08005 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08006 ast_log(LOG_WARNING, "No space left for %s name valid\n", label);
08007 return -1;
08008 }
08009 data[pos++] = ies->valid;
08010 data[pos++] = 1;
08011 data[pos++] = name->valid;
08012
08013 return pos;
08014 }
08015
08016
08017 struct ast_party_number_ies {
08018
08019 int str;
08020
08021 int plan;
08022
08023 int presentation;
08024
08025 int valid;
08026 };
08027
08028
08029
08030
08031
08032
08033
08034
08035
08036
08037
08038
08039
08040
08041
08042 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)
08043 {
08044 size_t length;
08045 size_t pos = 0;
08046
08047
08048
08049
08050
08051 if (number->str) {
08052 length = strlen(number->str);
08053 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08054 ast_log(LOG_WARNING, "No space left for %s number\n", label);
08055 return -1;
08056 }
08057 data[pos++] = ies->str;
08058 data[pos++] = length;
08059 memcpy(data + pos, number->str, length);
08060 pos += length;
08061 }
08062
08063 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08064 ast_log(LOG_WARNING, "No space left for %s numbering plan\n", label);
08065 return -1;
08066 }
08067 data[pos++] = ies->plan;
08068 data[pos++] = 1;
08069 data[pos++] = number->plan;
08070
08071 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08072 ast_log(LOG_WARNING, "No space left for %s number presentation\n", label);
08073 return -1;
08074 }
08075 data[pos++] = ies->presentation;
08076 data[pos++] = 1;
08077 data[pos++] = number->presentation;
08078
08079 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08080 ast_log(LOG_WARNING, "No space left for %s number valid\n", label);
08081 return -1;
08082 }
08083 data[pos++] = ies->valid;
08084 data[pos++] = 1;
08085 data[pos++] = number->valid;
08086
08087 return pos;
08088 }
08089
08090
08091 struct ast_party_subaddress_ies {
08092
08093 int str;
08094
08095 int type;
08096
08097 int odd_even_indicator;
08098
08099 int valid;
08100 };
08101
08102
08103
08104
08105
08106
08107
08108
08109
08110
08111
08112
08113
08114
08115
08116 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)
08117 {
08118 size_t length;
08119 size_t pos = 0;
08120
08121
08122
08123
08124
08125 if (subaddress->str) {
08126 length = strlen(subaddress->str);
08127 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08128 ast_log(LOG_WARNING, "No space left for %s subaddress\n", label);
08129 return -1;
08130 }
08131 data[pos++] = ies->str;
08132 data[pos++] = length;
08133 memcpy(data + pos, subaddress->str, length);
08134 pos += length;
08135 }
08136
08137 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08138 ast_log(LOG_WARNING, "No space left for %s type of subaddress\n", label);
08139 return -1;
08140 }
08141 data[pos++] = ies->type;
08142 data[pos++] = 1;
08143 data[pos++] = subaddress->type;
08144
08145 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08146 ast_log(LOG_WARNING,
08147 "No space left for %s subaddress odd-even indicator\n", label);
08148 return -1;
08149 }
08150 data[pos++] = ies->odd_even_indicator;
08151 data[pos++] = 1;
08152 data[pos++] = subaddress->odd_even_indicator;
08153
08154 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08155 ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label);
08156 return -1;
08157 }
08158 data[pos++] = ies->valid;
08159 data[pos++] = 1;
08160 data[pos++] = subaddress->valid;
08161
08162 return pos;
08163 }
08164
08165
08166 struct ast_party_id_ies {
08167
08168 struct ast_party_name_ies name;
08169
08170 struct ast_party_number_ies number;
08171
08172 struct ast_party_subaddress_ies subaddress;
08173
08174 int tag;
08175
08176 int combined_presentation;
08177 };
08178
08179
08180
08181
08182
08183
08184
08185
08186
08187
08188
08189
08190
08191
08192
08193
08194 static int party_id_build_data(unsigned char *data, size_t datalen,
08195 const struct ast_party_id *id, const char *label, const struct ast_party_id_ies *ies,
08196 const struct ast_set_party_id *update)
08197 {
08198 size_t length;
08199 size_t pos = 0;
08200 int res;
08201
08202
08203
08204
08205
08206
08207 if (!update || update->name) {
08208 res = party_name_build_data(data + pos, datalen - pos, &id->name, label,
08209 &ies->name);
08210 if (res < 0) {
08211 return -1;
08212 }
08213 pos += res;
08214 }
08215
08216 if (!update || update->number) {
08217 res = party_number_build_data(data + pos, datalen - pos, &id->number, label,
08218 &ies->number);
08219 if (res < 0) {
08220 return -1;
08221 }
08222 pos += res;
08223 }
08224
08225 if (!update || update->subaddress) {
08226 res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress,
08227 label, &ies->subaddress);
08228 if (res < 0) {
08229 return -1;
08230 }
08231 pos += res;
08232 }
08233
08234
08235 if (id->tag) {
08236 length = strlen(id->tag);
08237 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08238 ast_log(LOG_WARNING, "No space left for %s tag\n", label);
08239 return -1;
08240 }
08241 data[pos++] = ies->tag;
08242 data[pos++] = length;
08243 memcpy(data + pos, id->tag, length);
08244 pos += length;
08245 }
08246
08247
08248 if (!update || update->number) {
08249 int presentation;
08250
08251 if (!update || update->name) {
08252 presentation = ast_party_id_presentation(id);
08253 } else {
08254
08255
08256
08257
08258
08259 presentation = id->number.presentation;
08260 }
08261
08262 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08263 ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label);
08264 return -1;
08265 }
08266 data[pos++] = ies->combined_presentation;
08267 data[pos++] = 1;
08268 data[pos++] = presentation;
08269 }
08270
08271 return pos;
08272 }
08273
08274
08275
08276
08277
08278 enum {
08279 AST_CONNECTED_LINE_NUMBER,
08280 AST_CONNECTED_LINE_NAME,
08281 AST_CONNECTED_LINE_NUMBER_PLAN,
08282 AST_CONNECTED_LINE_ID_PRESENTATION,
08283 AST_CONNECTED_LINE_SOURCE,
08284 AST_CONNECTED_LINE_SUBADDRESS,
08285 AST_CONNECTED_LINE_SUBADDRESS_TYPE,
08286 AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
08287 AST_CONNECTED_LINE_SUBADDRESS_VALID,
08288 AST_CONNECTED_LINE_TAG,
08289 AST_CONNECTED_LINE_VERSION,
08290 AST_CONNECTED_LINE_NAME_VALID,
08291 AST_CONNECTED_LINE_NAME_CHAR_SET,
08292 AST_CONNECTED_LINE_NAME_PRESENTATION,
08293 AST_CONNECTED_LINE_NUMBER_VALID,
08294 AST_CONNECTED_LINE_NUMBER_PRESENTATION,
08295 };
08296
08297 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)
08298 {
08299 int32_t value;
08300 size_t pos = 0;
08301 int res;
08302
08303 static const struct ast_party_id_ies ies = {
08304 .name.str = AST_CONNECTED_LINE_NAME,
08305 .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET,
08306 .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION,
08307 .name.valid = AST_CONNECTED_LINE_NAME_VALID,
08308
08309 .number.str = AST_CONNECTED_LINE_NUMBER,
08310 .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN,
08311 .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION,
08312 .number.valid = AST_CONNECTED_LINE_NUMBER_VALID,
08313
08314 .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS,
08315 .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE,
08316 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
08317 .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID,
08318
08319 .tag = AST_CONNECTED_LINE_TAG,
08320 .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION,
08321 };
08322
08323
08324
08325
08326
08327
08328
08329 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08330 ast_log(LOG_WARNING, "No space left for connected line frame version\n");
08331 return -1;
08332 }
08333 data[pos++] = AST_CONNECTED_LINE_VERSION;
08334 data[pos++] = 1;
08335 data[pos++] = 2;
08336
08337 res = party_id_build_data(data + pos, datalen - pos, &connected->id,
08338 "connected line", &ies, update ? &update->id : NULL);
08339 if (res < 0) {
08340 return -1;
08341 }
08342 pos += res;
08343
08344
08345 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
08346 ast_log(LOG_WARNING, "No space left for connected line source\n");
08347 return -1;
08348 }
08349 data[pos++] = AST_CONNECTED_LINE_SOURCE;
08350 data[pos++] = sizeof(value);
08351 value = htonl(connected->source);
08352 memcpy(data + pos, &value, sizeof(value));
08353 pos += sizeof(value);
08354
08355 return pos;
08356 }
08357
08358 int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, struct ast_party_connected_line *connected)
08359 {
08360 size_t pos;
08361 unsigned char ie_len;
08362 unsigned char ie_id;
08363 int32_t value;
08364 int frame_version = 1;
08365 int combined_presentation = 0;
08366 int got_combined_presentation = 0;
08367
08368 for (pos = 0; pos < datalen; pos += ie_len) {
08369 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
08370 ast_log(LOG_WARNING, "Invalid connected line update\n");
08371 return -1;
08372 }
08373 ie_id = data[pos++];
08374 ie_len = data[pos++];
08375 if (datalen < pos + ie_len) {
08376 ast_log(LOG_WARNING, "Invalid connected line update\n");
08377 return -1;
08378 }
08379
08380 switch (ie_id) {
08381
08382 case AST_CONNECTED_LINE_VERSION:
08383 if (ie_len != 1) {
08384 ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n",
08385 (unsigned) ie_len);
08386 break;
08387 }
08388 frame_version = data[pos];
08389 break;
08390
08391 case AST_CONNECTED_LINE_NAME:
08392 ast_free(connected->id.name.str);
08393 connected->id.name.str = ast_malloc(ie_len + 1);
08394 if (connected->id.name.str) {
08395 memcpy(connected->id.name.str, data + pos, ie_len);
08396 connected->id.name.str[ie_len] = 0;
08397 }
08398 break;
08399 case AST_CONNECTED_LINE_NAME_CHAR_SET:
08400 if (ie_len != 1) {
08401 ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n",
08402 (unsigned) ie_len);
08403 break;
08404 }
08405 connected->id.name.char_set = data[pos];
08406 break;
08407 case AST_CONNECTED_LINE_NAME_PRESENTATION:
08408 if (ie_len != 1) {
08409 ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n",
08410 (unsigned) ie_len);
08411 break;
08412 }
08413 connected->id.name.presentation = data[pos];
08414 break;
08415 case AST_CONNECTED_LINE_NAME_VALID:
08416 if (ie_len != 1) {
08417 ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n",
08418 (unsigned) ie_len);
08419 break;
08420 }
08421 connected->id.name.valid = data[pos];
08422 break;
08423
08424 case AST_CONNECTED_LINE_NUMBER:
08425 ast_free(connected->id.number.str);
08426 connected->id.number.str = ast_malloc(ie_len + 1);
08427 if (connected->id.number.str) {
08428 memcpy(connected->id.number.str, data + pos, ie_len);
08429 connected->id.number.str[ie_len] = 0;
08430 }
08431 break;
08432 case AST_CONNECTED_LINE_NUMBER_PLAN:
08433 if (ie_len != 1) {
08434 ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n",
08435 (unsigned) ie_len);
08436 break;
08437 }
08438 connected->id.number.plan = data[pos];
08439 break;
08440 case AST_CONNECTED_LINE_NUMBER_PRESENTATION:
08441 if (ie_len != 1) {
08442 ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n",
08443 (unsigned) ie_len);
08444 break;
08445 }
08446 connected->id.number.presentation = data[pos];
08447 break;
08448 case AST_CONNECTED_LINE_NUMBER_VALID:
08449 if (ie_len != 1) {
08450 ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n",
08451 (unsigned) ie_len);
08452 break;
08453 }
08454 connected->id.number.valid = data[pos];
08455 break;
08456
08457 case AST_CONNECTED_LINE_ID_PRESENTATION:
08458 if (ie_len != 1) {
08459 ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n",
08460 (unsigned) ie_len);
08461 break;
08462 }
08463 combined_presentation = data[pos];
08464 got_combined_presentation = 1;
08465 break;
08466
08467 case AST_CONNECTED_LINE_SUBADDRESS:
08468 ast_free(connected->id.subaddress.str);
08469 connected->id.subaddress.str = ast_malloc(ie_len + 1);
08470 if (connected->id.subaddress.str) {
08471 memcpy(connected->id.subaddress.str, data + pos, ie_len);
08472 connected->id.subaddress.str[ie_len] = 0;
08473 }
08474 break;
08475 case AST_CONNECTED_LINE_SUBADDRESS_TYPE:
08476 if (ie_len != 1) {
08477 ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n",
08478 (unsigned) ie_len);
08479 break;
08480 }
08481 connected->id.subaddress.type = data[pos];
08482 break;
08483 case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN:
08484 if (ie_len != 1) {
08485 ast_log(LOG_WARNING,
08486 "Invalid connected line subaddress odd-even indicator (%u)\n",
08487 (unsigned) ie_len);
08488 break;
08489 }
08490 connected->id.subaddress.odd_even_indicator = data[pos];
08491 break;
08492 case AST_CONNECTED_LINE_SUBADDRESS_VALID:
08493 if (ie_len != 1) {
08494 ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n",
08495 (unsigned) ie_len);
08496 break;
08497 }
08498 connected->id.subaddress.valid = data[pos];
08499 break;
08500
08501 case AST_CONNECTED_LINE_TAG:
08502 ast_free(connected->id.tag);
08503 connected->id.tag = ast_malloc(ie_len + 1);
08504 if (connected->id.tag) {
08505 memcpy(connected->id.tag, data + pos, ie_len);
08506 connected->id.tag[ie_len] = 0;
08507 }
08508 break;
08509
08510 case AST_CONNECTED_LINE_SOURCE:
08511 if (ie_len != sizeof(value)) {
08512 ast_log(LOG_WARNING, "Invalid connected line source (%u)\n",
08513 (unsigned) ie_len);
08514 break;
08515 }
08516 memcpy(&value, data + pos, sizeof(value));
08517 connected->source = ntohl(value);
08518 break;
08519
08520 default:
08521 ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n",
08522 (unsigned) ie_id, (unsigned) ie_len);
08523 break;
08524 }
08525 }
08526
08527 switch (frame_version) {
08528 case 1:
08529
08530
08531
08532
08533 connected->id.name.valid = 1;
08534 connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
08535 connected->id.number.valid = 1;
08536 if (got_combined_presentation) {
08537 connected->id.name.presentation = combined_presentation;
08538 connected->id.number.presentation = combined_presentation;
08539 }
08540 break;
08541 case 2:
08542
08543 break;
08544 default:
08545
08546
08547
08548
08549 ast_log(LOG_DEBUG, "Connected line frame has newer version: %u\n",
08550 (unsigned) frame_version);
08551 break;
08552 }
08553
08554 return 0;
08555 }
08556
08557 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)
08558 {
08559 unsigned char data[1024];
08560 size_t datalen;
08561
08562 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
08563 if (datalen == (size_t) -1) {
08564 return;
08565 }
08566
08567 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
08568 }
08569
08570 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)
08571 {
08572 unsigned char data[1024];
08573 size_t datalen;
08574
08575 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
08576 if (datalen == (size_t) -1) {
08577 return;
08578 }
08579
08580 ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
08581 }
08582
08583 void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
08584 {
08585 if (&chan->redirecting == redirecting) {
08586
08587 return;
08588 }
08589
08590 ast_channel_lock(chan);
08591 ast_party_redirecting_set(&chan->redirecting, redirecting, update);
08592 ast_channel_unlock(chan);
08593 }
08594
08595
08596
08597
08598
08599 enum {
08600 AST_REDIRECTING_FROM_NUMBER,
08601 AST_REDIRECTING_FROM_NAME,
08602 AST_REDIRECTING_FROM_NUMBER_PLAN,
08603 AST_REDIRECTING_FROM_ID_PRESENTATION,
08604 AST_REDIRECTING_TO_NUMBER,
08605 AST_REDIRECTING_TO_NAME,
08606 AST_REDIRECTING_TO_NUMBER_PLAN,
08607 AST_REDIRECTING_TO_ID_PRESENTATION,
08608 AST_REDIRECTING_REASON,
08609 AST_REDIRECTING_COUNT,
08610 AST_REDIRECTING_FROM_SUBADDRESS,
08611 AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
08612 AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
08613 AST_REDIRECTING_FROM_SUBADDRESS_VALID,
08614 AST_REDIRECTING_TO_SUBADDRESS,
08615 AST_REDIRECTING_TO_SUBADDRESS_TYPE,
08616 AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
08617 AST_REDIRECTING_TO_SUBADDRESS_VALID,
08618 AST_REDIRECTING_FROM_TAG,
08619 AST_REDIRECTING_TO_TAG,
08620 AST_REDIRECTING_VERSION,
08621 AST_REDIRECTING_FROM_NAME_VALID,
08622 AST_REDIRECTING_FROM_NAME_CHAR_SET,
08623 AST_REDIRECTING_FROM_NAME_PRESENTATION,
08624 AST_REDIRECTING_FROM_NUMBER_VALID,
08625 AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
08626 AST_REDIRECTING_TO_NAME_VALID,
08627 AST_REDIRECTING_TO_NAME_CHAR_SET,
08628 AST_REDIRECTING_TO_NAME_PRESENTATION,
08629 AST_REDIRECTING_TO_NUMBER_VALID,
08630 AST_REDIRECTING_TO_NUMBER_PRESENTATION,
08631 };
08632
08633 int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
08634 {
08635 int32_t value;
08636 size_t pos = 0;
08637 int res;
08638
08639 static const struct ast_party_id_ies from_ies = {
08640 .name.str = AST_REDIRECTING_FROM_NAME,
08641 .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET,
08642 .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION,
08643 .name.valid = AST_REDIRECTING_FROM_NAME_VALID,
08644
08645 .number.str = AST_REDIRECTING_FROM_NUMBER,
08646 .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN,
08647 .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
08648 .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID,
08649
08650 .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS,
08651 .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
08652 .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
08653 .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID,
08654
08655 .tag = AST_REDIRECTING_FROM_TAG,
08656 .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION,
08657 };
08658 static const struct ast_party_id_ies to_ies = {
08659 .name.str = AST_REDIRECTING_TO_NAME,
08660 .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET,
08661 .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION,
08662 .name.valid = AST_REDIRECTING_TO_NAME_VALID,
08663
08664 .number.str = AST_REDIRECTING_TO_NUMBER,
08665 .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN,
08666 .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION,
08667 .number.valid = AST_REDIRECTING_TO_NUMBER_VALID,
08668
08669 .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS,
08670 .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE,
08671 .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
08672 .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID,
08673
08674 .tag = AST_REDIRECTING_TO_TAG,
08675 .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION,
08676 };
08677
08678
08679 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08680 ast_log(LOG_WARNING, "No space left for redirecting frame version\n");
08681 return -1;
08682 }
08683 data[pos++] = AST_REDIRECTING_VERSION;
08684 data[pos++] = 1;
08685 data[pos++] = 2;
08686
08687 res = party_id_build_data(data + pos, datalen - pos, &redirecting->from,
08688 "redirecting-from", &from_ies, update ? &update->from : NULL);
08689 if (res < 0) {
08690 return -1;
08691 }
08692 pos += res;
08693
08694 res = party_id_build_data(data + pos, datalen - pos, &redirecting->to,
08695 "redirecting-to", &to_ies, update ? &update->to : NULL);
08696 if (res < 0) {
08697 return -1;
08698 }
08699 pos += res;
08700
08701
08702 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
08703 ast_log(LOG_WARNING, "No space left for redirecting reason\n");
08704 return -1;
08705 }
08706 data[pos++] = AST_REDIRECTING_REASON;
08707 data[pos++] = sizeof(value);
08708 value = htonl(redirecting->reason);
08709 memcpy(data + pos, &value, sizeof(value));
08710 pos += sizeof(value);
08711
08712
08713 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
08714 ast_log(LOG_WARNING, "No space left for redirecting count\n");
08715 return -1;
08716 }
08717 data[pos++] = AST_REDIRECTING_COUNT;
08718 data[pos++] = sizeof(value);
08719 value = htonl(redirecting->count);
08720 memcpy(data + pos, &value, sizeof(value));
08721 pos += sizeof(value);
08722
08723 return pos;
08724 }
08725
08726 int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct ast_party_redirecting *redirecting)
08727 {
08728 size_t pos;
08729 unsigned char ie_len;
08730 unsigned char ie_id;
08731 int32_t value;
08732 int frame_version = 1;
08733 int from_combined_presentation = 0;
08734 int got_from_combined_presentation = 0;
08735 int to_combined_presentation = 0;
08736 int got_to_combined_presentation = 0;
08737
08738 for (pos = 0; pos < datalen; pos += ie_len) {
08739 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
08740 ast_log(LOG_WARNING, "Invalid redirecting update\n");
08741 return -1;
08742 }
08743 ie_id = data[pos++];
08744 ie_len = data[pos++];
08745 if (datalen < pos + ie_len) {
08746 ast_log(LOG_WARNING, "Invalid redirecting update\n");
08747 return -1;
08748 }
08749
08750 switch (ie_id) {
08751
08752 case AST_REDIRECTING_VERSION:
08753 if (ie_len != 1) {
08754 ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n",
08755 (unsigned) ie_len);
08756 break;
08757 }
08758 frame_version = data[pos];
08759 break;
08760
08761 case AST_REDIRECTING_FROM_NAME:
08762 ast_free(redirecting->from.name.str);
08763 redirecting->from.name.str = ast_malloc(ie_len + 1);
08764 if (redirecting->from.name.str) {
08765 memcpy(redirecting->from.name.str, data + pos, ie_len);
08766 redirecting->from.name.str[ie_len] = 0;
08767 }
08768 break;
08769 case AST_REDIRECTING_FROM_NAME_CHAR_SET:
08770 if (ie_len != 1) {
08771 ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n",
08772 (unsigned) ie_len);
08773 break;
08774 }
08775 redirecting->from.name.char_set = data[pos];
08776 break;
08777 case AST_REDIRECTING_FROM_NAME_PRESENTATION:
08778 if (ie_len != 1) {
08779 ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n",
08780 (unsigned) ie_len);
08781 break;
08782 }
08783 redirecting->from.name.presentation = data[pos];
08784 break;
08785 case AST_REDIRECTING_FROM_NAME_VALID:
08786 if (ie_len != 1) {
08787 ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n",
08788 (unsigned) ie_len);
08789 break;
08790 }
08791 redirecting->from.name.valid = data[pos];
08792 break;
08793
08794 case AST_REDIRECTING_FROM_NUMBER:
08795 ast_free(redirecting->from.number.str);
08796 redirecting->from.number.str = ast_malloc(ie_len + 1);
08797 if (redirecting->from.number.str) {
08798 memcpy(redirecting->from.number.str, data + pos, ie_len);
08799 redirecting->from.number.str[ie_len] = 0;
08800 }
08801 break;
08802 case AST_REDIRECTING_FROM_NUMBER_PLAN:
08803 if (ie_len != 1) {
08804 ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n",
08805 (unsigned) ie_len);
08806 break;
08807 }
08808 redirecting->from.number.plan = data[pos];
08809 break;
08810 case AST_REDIRECTING_FROM_NUMBER_PRESENTATION:
08811 if (ie_len != 1) {
08812 ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n",
08813 (unsigned) ie_len);
08814 break;
08815 }
08816 redirecting->from.number.presentation = data[pos];
08817 break;
08818 case AST_REDIRECTING_FROM_NUMBER_VALID:
08819 if (ie_len != 1) {
08820 ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n",
08821 (unsigned) ie_len);
08822 break;
08823 }
08824 redirecting->from.number.valid = data[pos];
08825 break;
08826
08827 case AST_REDIRECTING_FROM_ID_PRESENTATION:
08828 if (ie_len != 1) {
08829 ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n",
08830 (unsigned) ie_len);
08831 break;
08832 }
08833 from_combined_presentation = data[pos];
08834 got_from_combined_presentation = 1;
08835 break;
08836
08837 case AST_REDIRECTING_FROM_SUBADDRESS:
08838 ast_free(redirecting->from.subaddress.str);
08839 redirecting->from.subaddress.str = ast_malloc(ie_len + 1);
08840 if (redirecting->from.subaddress.str) {
08841 memcpy(redirecting->from.subaddress.str, data + pos, ie_len);
08842 redirecting->from.subaddress.str[ie_len] = 0;
08843 }
08844 break;
08845 case AST_REDIRECTING_FROM_SUBADDRESS_TYPE:
08846 if (ie_len != 1) {
08847 ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n",
08848 (unsigned) ie_len);
08849 break;
08850 }
08851 redirecting->from.subaddress.type = data[pos];
08852 break;
08853 case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN:
08854 if (ie_len != 1) {
08855 ast_log(LOG_WARNING,
08856 "Invalid redirecting-from subaddress odd-even indicator (%u)\n",
08857 (unsigned) ie_len);
08858 break;
08859 }
08860 redirecting->from.subaddress.odd_even_indicator = data[pos];
08861 break;
08862 case AST_REDIRECTING_FROM_SUBADDRESS_VALID:
08863 if (ie_len != 1) {
08864 ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n",
08865 (unsigned) ie_len);
08866 break;
08867 }
08868 redirecting->from.subaddress.valid = data[pos];
08869 break;
08870
08871 case AST_REDIRECTING_FROM_TAG:
08872 ast_free(redirecting->from.tag);
08873 redirecting->from.tag = ast_malloc(ie_len + 1);
08874 if (redirecting->from.tag) {
08875 memcpy(redirecting->from.tag, data + pos, ie_len);
08876 redirecting->from.tag[ie_len] = 0;
08877 }
08878 break;
08879
08880 case AST_REDIRECTING_TO_NAME:
08881 ast_free(redirecting->to.name.str);
08882 redirecting->to.name.str = ast_malloc(ie_len + 1);
08883 if (redirecting->to.name.str) {
08884 memcpy(redirecting->to.name.str, data + pos, ie_len);
08885 redirecting->to.name.str[ie_len] = 0;
08886 }
08887 break;
08888 case AST_REDIRECTING_TO_NAME_CHAR_SET:
08889 if (ie_len != 1) {
08890 ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n",
08891 (unsigned) ie_len);
08892 break;
08893 }
08894 redirecting->to.name.char_set = data[pos];
08895 break;
08896 case AST_REDIRECTING_TO_NAME_PRESENTATION:
08897 if (ie_len != 1) {
08898 ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n",
08899 (unsigned) ie_len);
08900 break;
08901 }
08902 redirecting->to.name.presentation = data[pos];
08903 break;
08904 case AST_REDIRECTING_TO_NAME_VALID:
08905 if (ie_len != 1) {
08906 ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n",
08907 (unsigned) ie_len);
08908 break;
08909 }
08910 redirecting->to.name.valid = data[pos];
08911 break;
08912
08913 case AST_REDIRECTING_TO_NUMBER:
08914 ast_free(redirecting->to.number.str);
08915 redirecting->to.number.str = ast_malloc(ie_len + 1);
08916 if (redirecting->to.number.str) {
08917 memcpy(redirecting->to.number.str, data + pos, ie_len);
08918 redirecting->to.number.str[ie_len] = 0;
08919 }
08920 break;
08921 case AST_REDIRECTING_TO_NUMBER_PLAN:
08922 if (ie_len != 1) {
08923 ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n",
08924 (unsigned) ie_len);
08925 break;
08926 }
08927 redirecting->to.number.plan = data[pos];
08928 break;
08929 case AST_REDIRECTING_TO_NUMBER_PRESENTATION:
08930 if (ie_len != 1) {
08931 ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n",
08932 (unsigned) ie_len);
08933 break;
08934 }
08935 redirecting->to.number.presentation = data[pos];
08936 break;
08937 case AST_REDIRECTING_TO_NUMBER_VALID:
08938 if (ie_len != 1) {
08939 ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n",
08940 (unsigned) ie_len);
08941 break;
08942 }
08943 redirecting->to.number.valid = data[pos];
08944 break;
08945
08946 case AST_REDIRECTING_TO_ID_PRESENTATION:
08947 if (ie_len != 1) {
08948 ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n",
08949 (unsigned) ie_len);
08950 break;
08951 }
08952 to_combined_presentation = data[pos];
08953 got_to_combined_presentation = 1;
08954 break;
08955
08956 case AST_REDIRECTING_TO_SUBADDRESS:
08957 ast_free(redirecting->to.subaddress.str);
08958 redirecting->to.subaddress.str = ast_malloc(ie_len + 1);
08959 if (redirecting->to.subaddress.str) {
08960 memcpy(redirecting->to.subaddress.str, data + pos, ie_len);
08961 redirecting->to.subaddress.str[ie_len] = 0;
08962 }
08963 break;
08964 case AST_REDIRECTING_TO_SUBADDRESS_TYPE:
08965 if (ie_len != 1) {
08966 ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n",
08967 (unsigned) ie_len);
08968 break;
08969 }
08970 redirecting->to.subaddress.type = data[pos];
08971 break;
08972 case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN:
08973 if (ie_len != 1) {
08974 ast_log(LOG_WARNING,
08975 "Invalid redirecting-to subaddress odd-even indicator (%u)\n",
08976 (unsigned) ie_len);
08977 break;
08978 }
08979 redirecting->to.subaddress.odd_even_indicator = data[pos];
08980 break;
08981 case AST_REDIRECTING_TO_SUBADDRESS_VALID:
08982 if (ie_len != 1) {
08983 ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n",
08984 (unsigned) ie_len);
08985 break;
08986 }
08987 redirecting->to.subaddress.valid = data[pos];
08988 break;
08989
08990 case AST_REDIRECTING_TO_TAG:
08991 ast_free(redirecting->to.tag);
08992 redirecting->to.tag = ast_malloc(ie_len + 1);
08993 if (redirecting->to.tag) {
08994 memcpy(redirecting->to.tag, data + pos, ie_len);
08995 redirecting->to.tag[ie_len] = 0;
08996 }
08997 break;
08998
08999 case AST_REDIRECTING_REASON:
09000 if (ie_len != sizeof(value)) {
09001 ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n",
09002 (unsigned) ie_len);
09003 break;
09004 }
09005 memcpy(&value, data + pos, sizeof(value));
09006 redirecting->reason = ntohl(value);
09007 break;
09008
09009 case AST_REDIRECTING_COUNT:
09010 if (ie_len != sizeof(value)) {
09011 ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n",
09012 (unsigned) ie_len);
09013 break;
09014 }
09015 memcpy(&value, data + pos, sizeof(value));
09016 redirecting->count = ntohl(value);
09017 break;
09018
09019 default:
09020 ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n",
09021 (unsigned) ie_id, (unsigned) ie_len);
09022 break;
09023 }
09024 }
09025
09026 switch (frame_version) {
09027 case 1:
09028
09029
09030
09031
09032 redirecting->from.name.valid = 1;
09033 redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09034 redirecting->from.number.valid = 1;
09035 if (got_from_combined_presentation) {
09036 redirecting->from.name.presentation = from_combined_presentation;
09037 redirecting->from.number.presentation = from_combined_presentation;
09038 }
09039
09040 redirecting->to.name.valid = 1;
09041 redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09042 redirecting->to.number.valid = 1;
09043 if (got_to_combined_presentation) {
09044 redirecting->to.name.presentation = to_combined_presentation;
09045 redirecting->to.number.presentation = to_combined_presentation;
09046 }
09047 break;
09048 case 2:
09049
09050 break;
09051 default:
09052
09053
09054
09055
09056 ast_log(LOG_DEBUG, "Redirecting frame has newer version: %u\n",
09057 (unsigned) frame_version);
09058 break;
09059 }
09060
09061 return 0;
09062 }
09063
09064 void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09065 {
09066 unsigned char data[1024];
09067 size_t datalen;
09068
09069 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09070 if (datalen == (size_t) -1) {
09071 return;
09072 }
09073
09074 ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09075 }
09076
09077 void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09078 {
09079 unsigned char data[1024];
09080 size_t datalen;
09081
09082 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09083 if (datalen == (size_t) -1) {
09084 return;
09085 }
09086
09087 ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09088 }
09089
09090 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)
09091 {
09092 const char *macro;
09093 const char *macro_args;
09094 int retval;
09095
09096 ast_channel_lock(macro_chan);
09097 macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09098 ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO");
09099 macro = ast_strdupa(S_OR(macro, ""));
09100 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09101 ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS");
09102 macro_args = ast_strdupa(S_OR(macro_args, ""));
09103
09104 if (ast_strlen_zero(macro)) {
09105 ast_channel_unlock(macro_chan);
09106 return -1;
09107 }
09108
09109 if (is_frame) {
09110 const struct ast_frame *frame = connected_info;
09111
09112 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->connected);
09113 } else {
09114 const struct ast_party_connected_line *connected = connected_info;
09115
09116 ast_party_connected_line_copy(¯o_chan->connected, connected);
09117 }
09118 ast_channel_unlock(macro_chan);
09119
09120 if (!(retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args))) {
09121 ast_channel_lock(macro_chan);
09122 ast_channel_update_connected_line(macro_chan, ¯o_chan->connected, NULL);
09123 ast_channel_unlock(macro_chan);
09124 }
09125
09126 return retval;
09127 }
09128
09129 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)
09130 {
09131 const char *macro;
09132 const char *macro_args;
09133 int retval;
09134
09135 ast_channel_lock(macro_chan);
09136 macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09137 ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO");
09138 macro = ast_strdupa(S_OR(macro, ""));
09139 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09140 ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS");
09141 macro_args = ast_strdupa(S_OR(macro_args, ""));
09142
09143 if (ast_strlen_zero(macro)) {
09144 ast_channel_unlock(macro_chan);
09145 return -1;
09146 }
09147
09148 if (is_frame) {
09149 const struct ast_frame *frame = redirecting_info;
09150
09151 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->redirecting);
09152 } else {
09153 const struct ast_party_redirecting *redirecting = redirecting_info;
09154
09155 ast_party_redirecting_copy(¯o_chan->redirecting, redirecting);
09156 }
09157 ast_channel_unlock(macro_chan);
09158
09159 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
09160 if (!retval) {
09161 ast_channel_lock(macro_chan);
09162 ast_channel_update_redirecting(macro_chan, ¯o_chan->redirecting, NULL);
09163 ast_channel_unlock(macro_chan);
09164 }
09165
09166 return retval;
09167 }
09168
09169 static void *channel_cc_params_copy(void *data)
09170 {
09171 const struct ast_cc_config_params *src = data;
09172 struct ast_cc_config_params *dest = ast_cc_config_params_init();
09173 if (!dest) {
09174 return NULL;
09175 }
09176 ast_cc_copy_config_params(dest, src);
09177 return dest;
09178 }
09179
09180 static void channel_cc_params_destroy(void *data)
09181 {
09182 struct ast_cc_config_params *cc_params = data;
09183 ast_cc_config_params_destroy(cc_params);
09184 }
09185
09186 static const struct ast_datastore_info cc_channel_datastore_info = {
09187 .type = "Call Completion",
09188 .duplicate = channel_cc_params_copy,
09189 .destroy = channel_cc_params_destroy,
09190 };
09191
09192 int ast_channel_cc_params_init(struct ast_channel *chan,
09193 const struct ast_cc_config_params *base_params)
09194 {
09195 struct ast_cc_config_params *cc_params;
09196 struct ast_datastore *cc_datastore;
09197
09198 if (!(cc_params = ast_cc_config_params_init())) {
09199 return -1;
09200 }
09201
09202 if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) {
09203 ast_cc_config_params_destroy(cc_params);
09204 return -1;
09205 }
09206
09207 if (base_params) {
09208 ast_cc_copy_config_params(cc_params, base_params);
09209 }
09210 cc_datastore->data = cc_params;
09211 ast_channel_datastore_add(chan, cc_datastore);
09212 return 0;
09213 }
09214
09215 struct ast_cc_config_params *ast_channel_get_cc_config_params(struct ast_channel *chan)
09216 {
09217 struct ast_datastore *cc_datastore;
09218
09219 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09220
09221
09222
09223
09224 if (ast_channel_cc_params_init(chan, NULL)) {
09225 return NULL;
09226 }
09227 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09228
09229 return NULL;
09230 }
09231 }
09232
09233 ast_assert(cc_datastore->data != NULL);
09234 return cc_datastore->data;
09235 }
09236
09237 int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
09238 {
09239 int len = name_buffer_length;
09240 char *dash;
09241 if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) {
09242 return 0;
09243 }
09244
09245
09246 ast_copy_string(device_name, chan->name, name_buffer_length);
09247 if ((dash = strrchr(device_name, '-'))) {
09248 *dash = '\0';
09249 }
09250
09251 return 0;
09252 }
09253
09254 int ast_channel_get_cc_agent_type(struct ast_channel *chan, char *agent_type, size_t size)
09255 {
09256 int len = size;
09257 char *slash;
09258
09259 if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) {
09260 return 0;
09261 }
09262
09263 ast_copy_string(agent_type, chan->name, size);
09264 if ((slash = strchr(agent_type, '/'))) {
09265 *slash = '\0';
09266 }
09267 return 0;
09268 }
09269
09270
09271
09272
09273
09274
09275
09276
09277
09278
09279 #undef ast_channel_alloc
09280 struct ast_channel __attribute__((format(printf, 10, 11)))
09281 *ast_channel_alloc(int needqueue, int state, const char *cid_num,
09282 const char *cid_name, const char *acctcode,
09283 const char *exten, const char *context,
09284 const char *linkedid, const int amaflag,
09285 const char *name_fmt, ...);
09286 struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num,
09287 const char *cid_name, const char *acctcode,
09288 const char *exten, const char *context,
09289 const char *linkedid, const int amaflag,
09290 const char *name_fmt, ...)
09291 {
09292 va_list ap1, ap2;
09293 struct ast_channel *result;
09294
09295
09296 va_start(ap1, name_fmt);
09297 va_start(ap2, name_fmt);
09298 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
09299 linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap1, ap2);
09300 va_end(ap1);
09301 va_end(ap2);
09302
09303 return result;
09304 }