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