Bug Summary

File:main/channel.c
Location:line 7388, column 3
Description:String copy function overflows destination buffer

Annotated Source Code

1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 1999 - 2006, Digium, Inc.
5 *
6 * Mark Spencer <markster@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*! \file
20 *
21 * \brief Channel Management
22 *
23 * \author Mark Spencer <markster@digium.com>
24 */
25
26/*** MODULEINFO
27 <support_level>core</support_level>
28 ***/
29
30#include "asterisk.h"
31
32ASTERISK_REGISTER_FILE()static void __attribute__((constructor)) __register_file_version
(void) { __ast_register_file("channel.c"); } static void __attribute__
((destructor)) __unregister_file_version(void) { __ast_unregister_file
("channel.c"); }
33
34#include "asterisk/_private.h"
35
36#include <sys/time.h>
37#include <signal.h>
38#include <math.h>
39
40#include "asterisk/paths.h" /* use ast_config_AST_SYSTEM_NAME */
41
42#include "asterisk/pbx.h"
43#include "asterisk/frame.h"
44#include "asterisk/mod_format.h"
45#include "asterisk/sched.h"
46#include "asterisk/channel.h"
47#include "asterisk/musiconhold.h"
48#include "asterisk/say.h"
49#include "asterisk/file.h"
50#include "asterisk/cli.h"
51#include "asterisk/translate.h"
52#include "asterisk/manager.h"
53#include "asterisk/chanvars.h"
54#include "asterisk/linkedlists.h"
55#include "asterisk/indications.h"
56#include "asterisk/causes.h"
57#include "asterisk/callerid.h"
58#include "asterisk/utils.h"
59#include "asterisk/lock.h"
60#include "asterisk/app.h"
61#include "asterisk/transcap.h"
62#include "asterisk/devicestate.h"
63#include "asterisk/threadstorage.h"
64#include "asterisk/slinfactory.h"
65#include "asterisk/audiohook.h"
66#include "asterisk/framehook.h"
67#include "asterisk/timing.h"
68#include "asterisk/autochan.h"
69#include "asterisk/stringfields.h"
70#include "asterisk/global_datastores.h"
71#include "asterisk/data.h"
72#include "asterisk/channel_internal.h"
73#include "asterisk/features.h"
74#include "asterisk/bridge.h"
75#include "asterisk/test.h"
76#include "asterisk/stasis_channels.h"
77#include "asterisk/max_forwards.h"
78
79/*** DOCUMENTATION
80 ***/
81
82#ifdef HAVE_EPOLL
83#include <sys/epoll.h>
84#endif
85
86#if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
87#if defined(HAVE_PRI)
88#include "libpri.h"
89#endif /* defined(HAVE_PRI) */
90#endif /* defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED) */
91
92struct ast_epoll_data {
93 struct ast_channel *chan;
94 int which;
95};
96
97/* uncomment if you have problems with 'monitoring' synchronized files */
98#if 0
99#define MONITOR_CONSTANT_DELAY
100#define MONITOR_DELAY 150 * 8 /*!< 150 ms of MONITORING DELAY */
101#endif
102
103static int chancount;
104
105unsigned long global_fin, global_fout;
106
107AST_THREADSTORAGE(state2str_threadbuf)static void __init_state2str_threadbuf(void); static struct ast_threadstorage
state2str_threadbuf = { .once = 0, .key_init = __init_state2str_threadbuf
, .custom_init = ((void*)0), }; static void __init_state2str_threadbuf
(void) { pthread_key_create(&(state2str_threadbuf).key, free
); }
;
108#define STATE2STR_BUFSIZE32 32
109
110/*! Default amount of time to use when emulating a digit as a begin and end
111 * 100ms */
112#define AST_DEFAULT_EMULATE_DTMF_DURATION100 100
113
114#define DEFAULT_AMA_FLAGSAST_AMA_DOCUMENTATION AST_AMA_DOCUMENTATION
115
116/*! Minimum amount of time between the end of the last digit and the beginning
117 * of a new one - 45ms */
118#define AST_MIN_DTMF_GAP45 45
119
120/*! \brief List of channel drivers */
121struct chanlist {
122 const struct ast_channel_tech *tech;
123 AST_LIST_ENTRY(chanlist)struct { struct chanlist *next; } list;
124};
125
126/*! \brief the list of registered channel types */
127static AST_RWLIST_HEAD_STATIC(backends, chanlist)struct backends { struct chanlist *first; struct chanlist *last
; ast_rwlock_t lock; } backends = { .first = ((void*)0), .last
= ((void*)0), .lock = { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
}, ((void*)0), 1 }, }
;
128
129#ifdef LOW_MEMORY
130#define NUM_CHANNEL_BUCKETS1567 61
131#else
132#define NUM_CHANNEL_BUCKETS1567 1567
133#endif
134
135/*! \brief All active channels on the system */
136static struct ao2_container *channels;
137
138/*! \brief map AST_CAUSE's to readable string representations
139 *
140 * \ref causes.h
141*/
142struct causes_map {
143 int cause;
144 const char *name;
145 const char *desc;
146};
147
148static const struct causes_map causes[] = {
149 { AST_CAUSE_UNALLOCATED1, "UNALLOCATED", "Unallocated (unassigned) number" },
150 { AST_CAUSE_NO_ROUTE_TRANSIT_NET2, "NO_ROUTE_TRANSIT_NET", "No route to specified transmit network" },
151 { AST_CAUSE_NO_ROUTE_DESTINATION3, "NO_ROUTE_DESTINATION", "No route to destination" },
152 { AST_CAUSE_MISDIALLED_TRUNK_PREFIX5, "MISDIALLED_TRUNK_PREFIX", "Misdialed trunk prefix" },
153 { AST_CAUSE_CHANNEL_UNACCEPTABLE6, "CHANNEL_UNACCEPTABLE", "Channel unacceptable" },
154 { AST_CAUSE_CALL_AWARDED_DELIVERED7, "CALL_AWARDED_DELIVERED", "Call awarded and being delivered in an established channel" },
155 { AST_CAUSE_PRE_EMPTED8, "PRE_EMPTED", "Pre-empted" },
156 { AST_CAUSE_NUMBER_PORTED_NOT_HERE14, "NUMBER_PORTED_NOT_HERE", "Number ported elsewhere" },
157 { AST_CAUSE_NORMAL_CLEARING16, "NORMAL_CLEARING", "Normal Clearing" },
158 { AST_CAUSE_USER_BUSY17, "USER_BUSY", "User busy" },
159 { AST_CAUSE_NO_USER_RESPONSE18, "NO_USER_RESPONSE", "No user responding" },
160 { AST_CAUSE_NO_ANSWER19, "NO_ANSWER", "User alerting, no answer" },
161 { AST_CAUSE_SUBSCRIBER_ABSENT20, "SUBSCRIBER_ABSENT", "Subscriber absent" },
162 { AST_CAUSE_CALL_REJECTED21, "CALL_REJECTED", "Call Rejected" },
163 { AST_CAUSE_NUMBER_CHANGED22, "NUMBER_CHANGED", "Number changed" },
164 { AST_CAUSE_REDIRECTED_TO_NEW_DESTINATION23, "REDIRECTED_TO_NEW_DESTINATION", "Redirected to new destination" },
165 { AST_CAUSE_ANSWERED_ELSEWHERE26, "ANSWERED_ELSEWHERE", "Answered elsewhere" },
166 { AST_CAUSE_DESTINATION_OUT_OF_ORDER27, "DESTINATION_OUT_OF_ORDER", "Destination out of order" },
167 { AST_CAUSE_INVALID_NUMBER_FORMAT28, "INVALID_NUMBER_FORMAT", "Invalid number format" },
168 { AST_CAUSE_FACILITY_REJECTED29, "FACILITY_REJECTED", "Facility rejected" },
169 { AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY30, "RESPONSE_TO_STATUS_ENQUIRY", "Response to STATus ENQuiry" },
170 { AST_CAUSE_NORMAL_UNSPECIFIED31, "NORMAL_UNSPECIFIED", "Normal, unspecified" },
171 { AST_CAUSE_NORMAL_CIRCUIT_CONGESTION34, "NORMAL_CIRCUIT_CONGESTION", "Circuit/channel congestion" },
172 { AST_CAUSE_NETWORK_OUT_OF_ORDER38, "NETWORK_OUT_OF_ORDER", "Network out of order" },
173 { AST_CAUSE_NORMAL_TEMPORARY_FAILURE41, "NORMAL_TEMPORARY_FAILURE", "Temporary failure" },
174 { AST_CAUSE_SWITCH_CONGESTION42, "SWITCH_CONGESTION", "Switching equipment congestion" },
175 { AST_CAUSE_ACCESS_INFO_DISCARDED43, "ACCESS_INFO_DISCARDED", "Access information discarded" },
176 { AST_CAUSE_REQUESTED_CHAN_UNAVAIL44, "REQUESTED_CHAN_UNAVAIL", "Requested channel not available" },
177 { AST_CAUSE_FACILITY_NOT_SUBSCRIBED50, "FACILITY_NOT_SUBSCRIBED", "Facility not subscribed" },
178 { AST_CAUSE_OUTGOING_CALL_BARRED52, "OUTGOING_CALL_BARRED", "Outgoing call barred" },
179 { AST_CAUSE_INCOMING_CALL_BARRED54, "INCOMING_CALL_BARRED", "Incoming call barred" },
180 { AST_CAUSE_BEARERCAPABILITY_NOTAUTH57, "BEARERCAPABILITY_NOTAUTH", "Bearer capability not authorized" },
181 { AST_CAUSE_BEARERCAPABILITY_NOTAVAIL58, "BEARERCAPABILITY_NOTAVAIL", "Bearer capability not available" },
182 { AST_CAUSE_BEARERCAPABILITY_NOTIMPL65, "BEARERCAPABILITY_NOTIMPL", "Bearer capability not implemented" },
183 { AST_CAUSE_CHAN_NOT_IMPLEMENTED66, "CHAN_NOT_IMPLEMENTED", "Channel not implemented" },
184 { AST_CAUSE_FACILITY_NOT_IMPLEMENTED69, "FACILITY_NOT_IMPLEMENTED", "Facility not implemented" },
185 { AST_CAUSE_INVALID_CALL_REFERENCE81, "INVALID_CALL_REFERENCE", "Invalid call reference value" },
186 { AST_CAUSE_INCOMPATIBLE_DESTINATION88, "INCOMPATIBLE_DESTINATION", "Incompatible destination" },
187 { AST_CAUSE_INVALID_MSG_UNSPECIFIED95, "INVALID_MSG_UNSPECIFIED", "Invalid message unspecified" },
188 { AST_CAUSE_MANDATORY_IE_MISSING96, "MANDATORY_IE_MISSING", "Mandatory information element is missing" },
189 { AST_CAUSE_MESSAGE_TYPE_NONEXIST97, "MESSAGE_TYPE_NONEXIST", "Message type nonexist." },
190 { AST_CAUSE_WRONG_MESSAGE98, "WRONG_MESSAGE", "Wrong message" },
191 { AST_CAUSE_IE_NONEXIST99, "IE_NONEXIST", "Info. element nonexist or not implemented" },
192 { AST_CAUSE_INVALID_IE_CONTENTS100, "INVALID_IE_CONTENTS", "Invalid information element contents" },
193 { AST_CAUSE_WRONG_CALL_STATE101, "WRONG_CALL_STATE", "Message not compatible with call state" },
194 { AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE102, "RECOVERY_ON_TIMER_EXPIRE", "Recover on timer expiry" },
195 { AST_CAUSE_MANDATORY_IE_LENGTH_ERROR103, "MANDATORY_IE_LENGTH_ERROR", "Mandatory IE length error" },
196 { AST_CAUSE_PROTOCOL_ERROR111, "PROTOCOL_ERROR", "Protocol error, unspecified" },
197 { AST_CAUSE_INTERWORKING127, "INTERWORKING", "Interworking, unspecified" },
198};
199
200struct ast_variable *ast_channeltype_list(void)
201{
202 struct chanlist *cl;
203 struct ast_variable *var = NULL((void*)0), *prev = NULL((void*)0);
204
205 AST_RWLIST_RDLOCK(&backends)__ast_rwlock_rdlock("channel.c", 205, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
206 AST_RWLIST_TRAVERSE(&backends, cl, list)for((cl) = (&backends)->first; (cl); (cl) = (cl)->list
.next)
{
207 if (prev) {
208 if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description, "")))
209 prev = prev->next;
210 } else {
211 var = ast_variable_new(cl->tech->type, cl->tech->description, "");
212 prev = var;
213 }
214 }
215 AST_RWLIST_UNLOCK(&backends)__ast_rwlock_unlock("channel.c", 215, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
216
217 return var;
218}
219
220#if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
221static const char *party_number_ton2str(int ton)
222{
223#if defined(HAVE_PRI)
224 switch ((ton >> 4) & 0x07) {
225 case PRI_TON_INTERNATIONAL:
226 return "International";
227 case PRI_TON_NATIONAL:
228 return "National";
229 case PRI_TON_NET_SPECIFIC:
230 return "Network Specific";
231 case PRI_TON_SUBSCRIBER:
232 return "Subscriber";
233 case PRI_TON_ABBREVIATED:
234 return "Abbreviated";
235 case PRI_TON_RESERVED:
236 return "Reserved";
237 case PRI_TON_UNKNOWN:
238 default:
239 break;
240 }
241#endif /* defined(HAVE_PRI) */
242 return "Unknown";
243}
244#endif /* defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED) */
245
246#if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
247static const char *party_number_plan2str(int plan)
248{
249#if defined(HAVE_PRI)
250 switch (plan & 0x0F) {
251 default:
252 case PRI_NPI_UNKNOWN:
253 break;
254 case PRI_NPI_E163_E164:
255 return "Public (E.163/E.164)";
256 case PRI_NPI_X121:
257 return "Data (X.121)";
258 case PRI_NPI_F69:
259 return "Telex (F.69)";
260 case PRI_NPI_NATIONAL:
261 return "National Standard";
262 case PRI_NPI_PRIVATE:
263 return "Private";
264 case PRI_NPI_RESERVED:
265 return "Reserved";
266 }
267#endif /* defined(HAVE_PRI) */
268 return "Unknown";
269}
270#endif /* defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED) */
271
272/*! \brief Show channel types - CLI command */
273static char *handle_cli_core_show_channeltypes(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
274{
275#define FORMAT "%-15.15s %-40.40s %-13.13s %-13.13s %-13.13s %-13.13s\n"
276 struct chanlist *cl;
277 int count_chan = 0;
278
279 switch (cmd) {
280 case CLI_INIT:
281 e->command = "core show channeltypes";
282 e->usage =
283 "Usage: core show channeltypes\n"
284 " Lists available channel types registered in your\n"
285 " Asterisk server.\n";
286 return NULL((void*)0);
287 case CLI_GENERATE:
288 return NULL((void*)0);
289 }
290
291 if (a->argc != 3)
292 return CLI_SHOWUSAGE(char *)1;
293
294 ast_cli(a->fd, FORMAT, "Type", "Description", "Devicestate", "Presencestate", "Indications", "Transfer");
295 ast_cli(a->fd, FORMAT, "-------------", "-------------", "-------------", "-------------", "-------------", "-------------");
296
297 AST_RWLIST_RDLOCK(&backends)__ast_rwlock_rdlock("channel.c", 297, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
298 AST_RWLIST_TRAVERSE(&backends, cl, list)for((cl) = (&backends)->first; (cl); (cl) = (cl)->list
.next)
{
299 ast_cli(a->fd, FORMAT, cl->tech->type, cl->tech->description,
300 (cl->tech->devicestate) ? "yes" : "no",
301 (cl->tech->presencestate) ? "yes" : "no",
302 (cl->tech->indicate) ? "yes" : "no",
303 (cl->tech->transfer) ? "yes" : "no");
304 count_chan++;
305 }
306 AST_RWLIST_UNLOCK(&backends)__ast_rwlock_unlock("channel.c", 306, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
307
308 ast_cli(a->fd, "----------\n%d channel drivers registered.\n", count_chan);
309
310 return CLI_SUCCESS(char *)0;
311
312#undef FORMAT
313}
314
315static char *complete_channeltypes(struct ast_cli_args *a)
316{
317 struct chanlist *cl;
318 int which = 0;
319 int wordlen;
320 char *ret = NULL((void*)0);
321
322 if (a->pos != 3)
323 return NULL((void*)0);
324
325 wordlen = strlen(a->word);
326
327 AST_RWLIST_RDLOCK(&backends)__ast_rwlock_rdlock("channel.c", 327, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
328 AST_RWLIST_TRAVERSE(&backends, cl, list)for((cl) = (&backends)->first; (cl); (cl) = (cl)->list
.next)
{
329 if (!strncasecmp(a->word, cl->tech->type, wordlen) && ++which > a->n) {
330 ret = ast_strdup(cl->tech->type)_ast_strdup((cl->tech->type), "channel.c", 330, __PRETTY_FUNCTION__
)
;
331 break;
332 }
333 }
334 AST_RWLIST_UNLOCK(&backends)__ast_rwlock_unlock("channel.c", 334, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
335
336 return ret;
337}
338
339/*! \brief Show details about a channel driver - CLI command */
340static char *handle_cli_core_show_channeltype(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
341{
342 struct chanlist *cl = NULL((void*)0);
343 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN)({ struct ast_str *__ast_str_buf; __ast_str_buf = __builtin_alloca
(sizeof(*__ast_str_buf) + 384); __ast_str_buf->len = 384; __ast_str_buf
->used = 0; __ast_str_buf->ts = ((struct ast_threadstorage
*)2); __ast_str_buf->str[0] = '\0'; (__ast_str_buf); })
;
344
345 switch (cmd) {
346 case CLI_INIT:
347 e->command = "core show channeltype";
348 e->usage =
349 "Usage: core show channeltype <name>\n"
350 " Show details about the specified channel type, <name>.\n";
351 return NULL((void*)0);
352 case CLI_GENERATE:
353 return complete_channeltypes(a);
354 }
355
356 if (a->argc != 4)
357 return CLI_SHOWUSAGE(char *)1;
358
359 AST_RWLIST_RDLOCK(&backends)__ast_rwlock_rdlock("channel.c", 359, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
360
361 AST_RWLIST_TRAVERSE(&backends, cl, list)for((cl) = (&backends)->first; (cl); (cl) = (cl)->list
.next)
{
362 if (!strncasecmp(cl->tech->type, a->argv[3], strlen(cl->tech->type)))
363 break;
364 }
365
366
367 if (!cl) {
368 ast_cli(a->fd, "\n%s is not a registered channel driver.\n", a->argv[3]);
369 AST_RWLIST_UNLOCK(&backends)__ast_rwlock_unlock("channel.c", 369, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
370 return CLI_FAILURE(char *)2;
371 }
372
373 ast_cli(a->fd,
374 "-- Info about channel driver: %s --\n"
375 " Device State: %s\n"
376 "Presence State: %s\n"
377 " Indication: %s\n"
378 " Transfer : %s\n"
379 " Capabilities: %s\n"
380 " Digit Begin: %s\n"
381 " Digit End: %s\n"
382 " Send HTML : %s\n"
383 " Image Support: %s\n"
384 " Text Support: %s\n",
385 cl->tech->type,
386 (cl->tech->devicestate) ? "yes" : "no",
387 (cl->tech->presencestate) ? "yes" : "no",
388 (cl->tech->indicate) ? "yes" : "no",
389 (cl->tech->transfer) ? "yes" : "no",
390 ast_format_cap_get_names(cl->tech->capabilities, &codec_buf),
391 (cl->tech->send_digit_begin) ? "yes" : "no",
392 (cl->tech->send_digit_end) ? "yes" : "no",
393 (cl->tech->send_html) ? "yes" : "no",
394 (cl->tech->send_image) ? "yes" : "no",
395 (cl->tech->send_text) ? "yes" : "no"
396
397 );
398
399 AST_RWLIST_UNLOCK(&backends)__ast_rwlock_unlock("channel.c", 399, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
400
401 return CLI_SUCCESS(char *)0;
402}
403
404static struct ast_cli_entry cli_channel[] = {
405 AST_CLI_DEFINE(handle_cli_core_show_channeltypes, "List available channel types"){ .handler = handle_cli_core_show_channeltypes, .summary = "List available channel types"
}
,
406 AST_CLI_DEFINE(handle_cli_core_show_channeltype, "Give more details on that channel type"){ .handler = handle_cli_core_show_channeltype, .summary = "Give more details on that channel type"
}
407};
408
409static struct ast_frame *kill_read(struct ast_channel *chan)
410{
411 /* Hangup channel. */
412 return NULL((void*)0);
413}
414
415static struct ast_frame *kill_exception(struct ast_channel *chan)
416{
417 /* Hangup channel. */
418 return NULL((void*)0);
419}
420
421static int kill_write(struct ast_channel *chan, struct ast_frame *frame)
422{
423 /* Hangup channel. */
424 return -1;
425}
426
427static int kill_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
428{
429 /* No problem fixing up the channel. */
430 return 0;
431}
432
433static int kill_hangup(struct ast_channel *chan)
434{
435 ast_channel_tech_pvt_set(chan, NULL((void*)0));
436 return 0;
437}
438
439/*!
440 * \brief Kill the channel channel driver technology descriptor.
441 *
442 * \details
443 * The purpose of this channel technology is to encourage the
444 * channel to hangup as quickly as possible.
445 *
446 * \note Used by DTMF atxfer and zombie channels.
447 */
448const struct ast_channel_tech ast_kill_tech = {
449 .type = "Kill",
450 .description = "Kill channel (should not see this)",
451 .read = kill_read,
452 .exception = kill_exception,
453 .write = kill_write,
454 .fixup = kill_fixup,
455 .hangup = kill_hangup,
456};
457
458/*! \brief Checks to see if a channel is needing hang up */
459int ast_check_hangup(struct ast_channel *chan)
460{
461 if (ast_channel_softhangup_internal_flag(chan)) /* yes if soft hangup flag set */
462 return 1;
463 if (ast_tvzero(*ast_channel_whentohangup(chan))) /* no if no hangup scheduled */
464 return 0;
465 if (ast_tvdiff_ms(*ast_channel_whentohangup(chan), ast_tvnow()) > 0) /* no if hangup time has not come yet. */
466 return 0;
467 ast_debug(4, "Hangup time has come: %" PRIi64 "\n", ast_tvdiff_ms(*ast_channel_whentohangup(chan), ast_tvnow()))do { if ((option_debug >= (4) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (4)))) { ast_log(0,
"channel.c", 467, __PRETTY_FUNCTION__, "Hangup time has come: %"
"l" "i" "\n", ast_tvdiff_ms(*ast_channel_whentohangup(chan),
ast_tvnow())); } } while (0)
;
468 ast_test_suite_event_notify("HANGUP_TIME", "Channel: %s", ast_channel_name(chan));
469 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_TIMEOUT); /* record event */
470 return 1;
471}
472
473int ast_check_hangup_locked(struct ast_channel *chan)
474{
475 int res;
476 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 476, "chan")
;
477 res = ast_check_hangup(chan);
478 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 478, "chan"
)
;
479 return res;
480}
481
482void ast_channel_softhangup_withcause_locked(struct ast_channel *chan, int causecode)
483{
484 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 484, "chan")
;
485
486 if (causecode > 0) {
487 ast_debug(1, "Setting hangupcause of channel %s to %d (is %d now)\n",do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 488, __PRETTY_FUNCTION__, "Setting hangupcause of channel %s to %d (is %d now)\n"
, ast_channel_name(chan), causecode, ast_channel_hangupcause(
chan)); } } while (0)
488 ast_channel_name(chan), causecode, ast_channel_hangupcause(chan))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 488, __PRETTY_FUNCTION__, "Setting hangupcause of channel %s to %d (is %d now)\n"
, ast_channel_name(chan), causecode, ast_channel_hangupcause(
chan)); } } while (0)
;
489
490 ast_channel_hangupcause_set(chan, causecode);
491 }
492
493 ast_softhangup_nolock(chan, AST_SOFTHANGUP_EXPLICIT);
494
495 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 495, "chan"
)
;
496}
497
498static int ast_channel_softhangup_cb(void *obj, void *arg, int flags)
499{
500 struct ast_channel *chan = obj;
501
502 ast_softhangup(chan, AST_SOFTHANGUP_SHUTDOWN);
503
504 return 0;
505}
506
507void ast_softhangup_all(void)
508{
509 ao2_callback(channels, OBJ_NODATA | OBJ_MULTIPLE, ast_channel_softhangup_cb, NULL)__ao2_callback((channels), (OBJ_NODATA | OBJ_MULTIPLE), (ast_channel_softhangup_cb
), (((void*)0)), "", "channel.c", 509, __PRETTY_FUNCTION__)
;
510}
511
512/*! \brief returns number of active/allocated channels */
513int ast_active_channels(void)
514{
515 return channels ? ao2_container_count(channels) : 0;
516}
517
518int ast_undestroyed_channels(void)
519{
520 return ast_atomic_fetchadd_int(&chancount, 0);
521}
522
523/*! \brief Set when to hangup channel */
524void ast_channel_setwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
525{
526 if (ast_tvzero(offset)) {
527 ast_channel_whentohangup_set(chan, &offset);
528 } else {
529 struct timeval tv = ast_tvadd(offset, ast_tvnow());
530 ast_channel_whentohangup_set(chan, &tv);
531 }
532 ast_queue_frame(chan, &ast_null_frame);
533 return;
534}
535
536void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
537{
538 struct timeval when = { offset, };
539 ast_channel_setwhentohangup_tv(chan, when);
540}
541
542/*! \brief Compare a offset with when to hangup channel */
543int ast_channel_cmpwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
544{
545 struct timeval whentohangup;
546
547 if (ast_tvzero(*ast_channel_whentohangup(chan)))
548 return ast_tvzero(offset) ? 0 : -1;
549
550 if (ast_tvzero(offset))
551 return 1;
552
553 whentohangup = ast_tvadd(offset, ast_tvnow());
554
555 return ast_tvdiff_ms(whentohangup, *ast_channel_whentohangup(chan));
556}
557
558int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset)
559{
560 struct timeval when = { offset, };
561 return ast_channel_cmpwhentohangup_tv(chan, when);
562}
563
564/*! \brief Register a new telephony channel in Asterisk */
565int ast_channel_register(const struct ast_channel_tech *tech)
566{
567 struct chanlist *chan;
568
569 AST_RWLIST_WRLOCK(&backends)__ast_rwlock_wrlock("channel.c", 569, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
570
571 AST_RWLIST_TRAVERSE(&backends, chan, list)for((chan) = (&backends)->first; (chan); (chan) = (chan
)->list.next)
{
572 if (!strcasecmp(tech->type, chan->tech->type)) {
573 ast_log(LOG_WARNING3, "channel.c", 573, __PRETTY_FUNCTION__, "Already have a handler for type '%s'\n", tech->type);
574 AST_RWLIST_UNLOCK(&backends)__ast_rwlock_unlock("channel.c", 574, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
575 return -1;
576 }
577 }
578
579 if (!(chan = ast_calloc(1, sizeof(*chan))_ast_calloc((1), (sizeof(*chan)), "channel.c", 579, __PRETTY_FUNCTION__
)
)) {
580 AST_RWLIST_UNLOCK(&backends)__ast_rwlock_unlock("channel.c", 580, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
581 return -1;
582 }
583 chan->tech = tech;
584 AST_RWLIST_INSERT_HEAD(&backends, chan, list)do { (chan)->list.next = (&backends)->first; (&
backends)->first = (chan); if (!(&backends)->last) (
&backends)->last = (chan); } while (0)
;
585
586 ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description)do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 586, __PRETTY_FUNCTION__, "Registered handler for '%s' (%s)\n"
, chan->tech->type, chan->tech->description); } }
while (0)
;
587
588 ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description)do { if (((2) <= ast_verb_sys_level) ) { __ast_verbose("channel.c"
, 588, __PRETTY_FUNCTION__, 2, "Registered channel type '%s' (%s)\n"
, chan->tech->type, chan->tech->description); } }
while (0)
;
589
590 AST_RWLIST_UNLOCK(&backends)__ast_rwlock_unlock("channel.c", 590, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
591
592 return 0;
593}
594
595/*! \brief Unregister channel driver */
596void ast_channel_unregister(const struct ast_channel_tech *tech)
597{
598 struct chanlist *chan;
599
600 ast_debug(1, "Unregistering channel type '%s'\n", tech->type)do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 600, __PRETTY_FUNCTION__, "Unregistering channel type '%s'\n"
, tech->type); } } while (0)
;
601
602 AST_RWLIST_WRLOCK(&backends)__ast_rwlock_wrlock("channel.c", 602, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
603
604 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list){ typeof((&backends)) __list_head = &backends; typeof
(__list_head->first) __list_next; typeof(__list_head->first
) __list_prev = ((void*)0); typeof(__list_head->first) __list_current
; for ((chan) = __list_head->first, __list_current = (chan
), __list_next = (chan) ? (chan)->list.next : ((void*)0); (
chan); __list_prev = __list_current, (chan) = __list_next, __list_current
= (chan), __list_next = (chan) ? (chan)->list.next : ((void
*)0), (void) __list_prev )
{
605 if (chan->tech == tech) {
606 AST_LIST_REMOVE_CURRENT(list)do { __list_current->list.next = ((void*)0); __list_current
= __list_prev; if (__list_prev) { __list_prev->list.next =
__list_next; } else { __list_head->first = __list_next; }
if (!__list_next) { __list_head->last = __list_prev; } } while
(0)
;
607 ast_freefree(chan);
608 ast_verb(2, "Unregistered channel type '%s'\n", tech->type)do { if (((2) <= ast_verb_sys_level) ) { __ast_verbose("channel.c"
, 608, __PRETTY_FUNCTION__, 2, "Unregistered channel type '%s'\n"
, tech->type); } } while (0)
;
609 break;
610 }
611 }
612 AST_LIST_TRAVERSE_SAFE_END};
613
614 AST_RWLIST_UNLOCK(&backends)__ast_rwlock_unlock("channel.c", 614, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
615}
616
617/*! \brief Get handle to channel driver based on name */
618const struct ast_channel_tech *ast_get_channel_tech(const char *name)
619{
620 struct chanlist *chanls;
621 const struct ast_channel_tech *ret = NULL((void*)0);
622
623 AST_RWLIST_RDLOCK(&backends)__ast_rwlock_rdlock("channel.c", 623, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
624
625 AST_RWLIST_TRAVERSE(&backends, chanls, list)for((chanls) = (&backends)->first; (chanls); (chanls) =
(chanls)->list.next)
{
626 if (!strcasecmp(name, chanls->tech->type)) {
627 ret = chanls->tech;
628 break;
629 }
630 }
631
632 AST_RWLIST_UNLOCK(&backends)__ast_rwlock_unlock("channel.c", 632, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
633
634 return ret;
635}
636
637/*! \brief Gives the string form of a given hangup cause */
638const char *ast_cause2str(int cause)
639{
640 int x;
641
642 for (x = 0; x < ARRAY_LEN(causes)(size_t) (sizeof(causes) / sizeof(0[causes])); x++) {
643 if (causes[x].cause == cause)
644 return causes[x].desc;
645 }
646
647 return "Unknown";
648}
649
650/*! \brief Convert a symbolic hangup cause to number */
651int ast_str2cause(const char *name)
652{
653 int x;
654
655 for (x = 0; x < ARRAY_LEN(causes)(size_t) (sizeof(causes) / sizeof(0[causes])); x++)
656 if (!strncasecmp(causes[x].name, name, strlen(causes[x].name)))
657 return causes[x].cause;
658
659 return -1;
660}
661
662static struct stasis_message *create_channel_snapshot_message(struct ast_channel *channel)
663{
664 RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup)_raii_cleanup_block_t _raii_cleanup_snapshot __attribute__((cleanup
(_raii_cleanup_block),unused)) = ((void*)0); __attribute__((__blocks__
(byref))) struct ast_channel_snapshot * snapshot = ((void*)0)
; _raii_cleanup_snapshot = ^{ {(void)__ao2_cleanup_debug((snapshot
), "", "channel.c", 664, __PRETTY_FUNCTION__);} }
;
665
666 if (!ast_channel_snapshot_type()) {
667 return NULL((void*)0);
668 }
669
670 ast_channel_lock(channel)__ao2_lock(channel, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 670, "channel")
;
671 snapshot = ast_channel_snapshot_create(channel);
672 ast_channel_unlock(channel)__ao2_unlock(channel, "channel.c", __PRETTY_FUNCTION__, 672, "channel"
)
;
673 if (!snapshot) {
674 return NULL((void*)0);
675 }
676
677 return stasis_message_create(ast_channel_snapshot_type(), snapshot);
678}
679
680static void publish_cache_clear(struct ast_channel *chan)
681{
682 RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup)_raii_cleanup_block_t _raii_cleanup_message __attribute__((cleanup
(_raii_cleanup_block),unused)) = ((void*)0); __attribute__((__blocks__
(byref))) struct stasis_message * message = ((void*)0); _raii_cleanup_message
= ^{ {(void)__ao2_cleanup_debug((message), "", "channel.c", 682
, __PRETTY_FUNCTION__);} }
;
683 RAII_VAR(struct stasis_message *, clear_msg, NULL, ao2_cleanup)_raii_cleanup_block_t _raii_cleanup_clear_msg __attribute__((
cleanup(_raii_cleanup_block),unused)) = ((void*)0); __attribute__
((__blocks__(byref))) struct stasis_message * clear_msg = ((void
*)0); _raii_cleanup_clear_msg = ^{ {(void)__ao2_cleanup_debug
((clear_msg), "", "channel.c", 683, __PRETTY_FUNCTION__);} }
;
684
685 clear_msg = create_channel_snapshot_message(chan);
686 if (!clear_msg) {
687 return;
688 }
689
690 message = stasis_cache_clear_create(clear_msg);
691 stasis_publish(ast_channel_topic(chan), message);
692}
693
694/*! \brief Gives the string form of a given channel state.
695 *
696 * \note This function is not reentrant.
697 *
698 * \param state
699 */
700const char *ast_state2str(enum ast_channel_state state)
701{
702 char *buf;
703
704 switch (state) {
705 case AST_STATE_DOWN:
706 return "Down";
707 case AST_STATE_RESERVED:
708 return "Rsrvd";
709 case AST_STATE_OFFHOOK:
710 return "OffHook";
711 case AST_STATE_DIALING:
712 return "Dialing";
713 case AST_STATE_RING:
714 return "Ring";
715 case AST_STATE_RINGING:
716 return "Ringing";
717 case AST_STATE_UP:
718 return "Up";
719 case AST_STATE_BUSY:
720 return "Busy";
721 case AST_STATE_DIALING_OFFHOOK:
722 return "Dialing Offhook";
723 case AST_STATE_PRERING:
724 return "Pre-ring";
725 case AST_STATE_MUTE:
726 return "Mute";
727 default:
728 if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE32)))
729 return "Unknown";
730 snprintf(buf, STATE2STR_BUFSIZE32, "Unknown (%u)", state);
731 return buf;
732 }
733}
734
735/*! \brief Gives the string form of a given transfer capability */
736char *ast_transfercapability2str(int transfercapability)
737{
738 switch (transfercapability) {
739 case AST_TRANS_CAP_SPEECH0x0:
740 return "SPEECH";
741 case AST_TRANS_CAP_DIGITAL0x08:
742 return "DIGITAL";
743 case AST_TRANS_CAP_RESTRICTED_DIGITAL0x09:
744 return "RESTRICTED_DIGITAL";
745 case AST_TRANS_CAP_3_1K_AUDIO0x10:
746 return "3K1AUDIO";
747 case AST_TRANS_CAP_DIGITAL_W_TONES0x11:
748 return "DIGITAL_W_TONES";
749 case AST_TRANS_CAP_VIDEO0x18:
750 return "VIDEO";
751 default:
752 return "UNKNOWN";
753 }
754}
755
756/*! \brief Channel technology used to extract a channel from a running application. The
757 * channel created with this technology will be immediately hung up - most external
758 * applications won't ever want to see this.
759 */
760static const struct ast_channel_tech surrogate_tech = {
761 .type = "Surrogate",
762 .description = "Surrogate channel used to pull channel from an application",
763 .properties = AST_CHAN_TP_INTERNAL,
764};
765
766static const struct ast_channel_tech null_tech = {
767 .type = "NULL",
768 .description = "Null channel (should not see this)",
769};
770
771static void ast_channel_destructor(void *obj);
772static void ast_dummy_channel_destructor(void *obj);
773
774/*! \brief Create a new channel structure */
775static struct ast_channel * attribute_malloc__attribute__((malloc)) __attribute__((format(printf, 15, 0)))
776__ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char *cid_name,
777 const char *acctcode, const char *exten, const char *context, const struct ast_assigned_ids *assignedids,
778 const struct ast_channel *requestor, enum ama_flags amaflag, struct ast_endpoint *endpoint,
779 const char *file, int line,
780 const char *function, const char *name_fmt, va_list ap)
781{
782 struct ast_channel *tmp;
783 struct varshead *headp;
784 char *tech = "", *tech2 = NULL((void*)0);
785 struct ast_format_cap *nativeformats;
786 struct ast_sched_context *schedctx;
787 struct ast_timer *timer;
788 struct timeval now;
789 const struct ast_channel_tech *channel_tech;
790
791 /* If shutting down, don't allocate any new channels */
792 if (ast_shutting_down()) {
793 ast_log(LOG_WARNING3, "channel.c", 793, __PRETTY_FUNCTION__, "Channel allocation failed: Refusing due to active shutdown\n");
794 return NULL((void*)0);
795 }
796
797 tmp = __ast_channel_internal_alloc(ast_channel_destructor, assignedids, requestor,
798 file, line, function);
799 if (!tmp) {
800 /* Channel structure allocation failure. */
801 return NULL((void*)0);
802 }
803
804 ast_channel_stage_snapshot(tmp);
805
806 if (!(nativeformats = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)__ast_format_cap_alloc((AST_FORMAT_CAP_FLAG_DEFAULT), "ast_format_cap_alloc"
, "channel.c", 806, __PRETTY_FUNCTION__)
)) {
807 /* format capabilities structure allocation failure */
808 return ast_channel_unref(tmp)({ __ao2_ref((tmp), (-1), "", "channel.c", 808, __PRETTY_FUNCTION__
); (struct ast_channel *) (((void*)0)); })
;
809 }
810 ast_format_cap_append(nativeformats, ast_format_none, 0)__ast_format_cap_append((nativeformats), (ast_format_none), (
0), "ast_format_cap_append", "channel.c", 810, __PRETTY_FUNCTION__
)
;
811 ast_channel_nativeformats_set(tmp, nativeformats);
812 ao2_ref(nativeformats, -1)__ao2_ref((nativeformats), (-1), "", "channel.c", 812, __PRETTY_FUNCTION__
)
;
813
814 ast_channel_set_rawwriteformat(tmp, ast_format_none);
815 ast_channel_set_rawreadformat(tmp, ast_format_none);
816 ast_channel_set_writeformat(tmp, ast_format_none);
817 ast_channel_set_readformat(tmp, ast_format_none);
818
819 /*
820 * Init file descriptors to unopened state so
821 * the destructor can know not to close them.
822 */
823 ast_channel_timingfd_set(tmp, -1);
824 ast_channel_internal_alertpipe_clear(tmp);
825 ast_channel_internal_fd_clear_all(tmp);
826
827#ifdef HAVE_EPOLL
828 ast_channel_epfd_set(tmp, epoll_create(25));
829#endif
830
831 if (!(schedctx = ast_sched_context_create())) {
832 ast_log(LOG_WARNING3, "channel.c", 832, __PRETTY_FUNCTION__, "Channel allocation failed: Unable to create schedule context\n");
833 return ast_channel_unref(tmp)({ __ao2_ref((tmp), (-1), "", "channel.c", 833, __PRETTY_FUNCTION__
); (struct ast_channel *) (((void*)0)); })
;
834 }
835 ast_channel_sched_set(tmp, schedctx);
836
837 ast_party_dialed_init(ast_channel_dialed(tmp));
838 ast_party_caller_init(ast_channel_caller(tmp));
839 ast_party_connected_line_init(ast_channel_connected(tmp));
840 ast_party_connected_line_init(ast_channel_connected_indicated(tmp));
841 ast_party_redirecting_init(ast_channel_redirecting(tmp));
842
843 if (cid_name) {
844 ast_channel_caller(tmp)->id.name.valid = 1;
845 ast_channel_caller(tmp)->id.name.str = ast_strdup(cid_name)_ast_strdup((cid_name), "channel.c", 845, __PRETTY_FUNCTION__
)
;
846 if (!ast_channel_caller(tmp)->id.name.str) {
847 return ast_channel_unref(tmp)({ __ao2_ref((tmp), (-1), "", "channel.c", 847, __PRETTY_FUNCTION__
); (struct ast_channel *) (((void*)0)); })
;
848 }
849 }
850 if (cid_num) {
851 ast_channel_caller(tmp)->id.number.valid = 1;
852 ast_channel_caller(tmp)->id.number.str = ast_strdup(cid_num)_ast_strdup((cid_num), "channel.c", 852, __PRETTY_FUNCTION__);
853 if (!ast_channel_caller(tmp)->id.number.str) {
854 return ast_channel_unref(tmp)({ __ao2_ref((tmp), (-1), "", "channel.c", 854, __PRETTY_FUNCTION__
); (struct ast_channel *) (((void*)0)); })
;
855 }
856 }
857
858 if ((timer = ast_timer_open())) {
859 ast_channel_timer_set(tmp, timer);
860 if (strcmp(ast_timer_get_name(ast_channel_timer(tmp)), "timerfd")) {
861 needqueue = 0;
862 }
863 ast_channel_timingfd_set(tmp, ast_timer_fd(ast_channel_timer(tmp)));
864 }
865
866 if (needqueue && ast_channel_internal_alertpipe_init(tmp)) {
867 return ast_channel_unref(tmp)({ __ao2_ref((tmp), (-1), "", "channel.c", 867, __PRETTY_FUNCTION__
); (struct ast_channel *) (((void*)0)); })
;
868 }
869
870 /* Always watch the alertpipe */
871 ast_channel_set_fd(tmp, AST_ALERT_FD(11 -1), ast_channel_internal_alert_readfd(tmp));
872 /* And timing pipe */
873 ast_channel_set_fd(tmp, AST_TIMING_FD(11 -2), ast_channel_timingfd(tmp));
874
875 /* Initial state */
876 ast_channel_state_set(tmp, state);
877 ast_channel_hold_state_set(tmp, AST_CONTROL_UNHOLD);
878
879 ast_channel_streamid_set(tmp, -1);
880 ast_channel_vstreamid_set(tmp, -1);
881
882 ast_channel_fin_set(tmp, global_fin);
883 ast_channel_fout_set(tmp, global_fout);
884
885 now = ast_tvnow();
886 ast_channel_creationtime_set(tmp, &now);
887
888 ast_channel_internal_setup_topics(tmp);
889
890 if (!ast_strlen_zero(name_fmt)_ast_strlen_zero(name_fmt, "channel.c", __PRETTY_FUNCTION__, 890
)
) {
891 char *slash, *slash2;
892 /* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call.
893 * And they all use slightly different formats for their name string.
894 * This means, to set the name here, we have to accept variable args, and call the string_field_build from here.
895 * This means, that the stringfields must have a routine that takes the va_lists directly, and
896 * uses them to build the string, instead of forming the va_lists internally from the vararg ... list.
897 * This new function was written so this can be accomplished.
898 */
899 ast_channel_name_build_va(tmp, name_fmt, ap);
900 tech = ast_strdupa(ast_channel_name(tmp))(__extension__ ({ const char *__old = (ast_channel_name(tmp))
; size_t __len = strlen(__old) + 1; char *__new = __builtin_alloca
(__len); memcpy (__new, __old, __len); __new; }))
;
901 if ((slash = strchr(tech, '/')(__extension__ (__builtin_constant_p ('/') && !__builtin_constant_p
(tech) && ('/') == '\0' ? (char *) __rawmemchr (tech
, '/') : __builtin_strchr (tech, '/')))
)) {
902 if ((slash2 = strchr(slash + 1, '/')(__extension__ (__builtin_constant_p ('/') && !__builtin_constant_p
(slash + 1) && ('/') == '\0' ? (char *) __rawmemchr (
slash + 1, '/') : __builtin_strchr (slash + 1, '/')))
)) {
903 tech2 = slash + 1;
904 *slash2 = '\0';
905 }
906 *slash = '\0';
907 }
908 } else {
909 /*
910 * Start the string with '-' so it becomes an empty string
911 * in the destructor.
912 */
913 ast_channel_name_set(tmp, "-**Unknown**");
914 }
915
916 if (amaflag != AST_AMA_NONE) {
917 ast_channel_amaflags_set(tmp, amaflag);
918 } else {
919 ast_channel_amaflags_set(tmp, DEFAULT_AMA_FLAGSAST_AMA_DOCUMENTATION);
920 }
921
922 if (!ast_strlen_zero(acctcode)_ast_strlen_zero(acctcode, "channel.c", __PRETTY_FUNCTION__, 922
)
) {
923 ast_channel_accountcode_set(tmp, acctcode);
924 }
925 ast_channel_language_set(tmp, ast_defaultlanguage);
926
927 ast_channel_context_set(tmp, S_OR(context, "default")({typeof(&((context)[0])) __x = (context); _ast_strlen_zero
(__x, "channel.c", __PRETTY_FUNCTION__, 927) ? ("default") : __x
;})
);
928 ast_channel_exten_set(tmp, S_OR(exten, "s")({typeof(&((exten)[0])) __x = (exten); _ast_strlen_zero(__x
, "channel.c", __PRETTY_FUNCTION__, 928) ? ("s") : __x;})
);
929 ast_channel_priority_set(tmp, 1);
930
931 headp = ast_channel_varshead(tmp);
932 AST_LIST_HEAD_INIT_NOLOCK(headp){ (headp)->first = ((void*)0); (headp)->last = ((void*)
0); }
;
933
934 ast_pbx_hangup_handler_init(tmp);
935 AST_LIST_HEAD_INIT_NOLOCK(ast_channel_datastores(tmp)){ (ast_channel_datastores(tmp))->first = ((void*)0); (ast_channel_datastores
(tmp))->last = ((void*)0); }
;
936 AST_LIST_HEAD_INIT_NOLOCK(ast_channel_autochans(tmp)){ (ast_channel_autochans(tmp))->first = ((void*)0); (ast_channel_autochans
(tmp))->last = ((void*)0); }
;
937
938 channel_tech = ast_get_channel_tech(tech);
939 if (!channel_tech && !ast_strlen_zero(tech2)_ast_strlen_zero(tech2, "channel.c", __PRETTY_FUNCTION__, 939
)
) {
940 channel_tech = ast_get_channel_tech(tech2);
941 }
942 if (channel_tech) {
943 ast_channel_tech_set(tmp, channel_tech);
944 } else {
945 ast_channel_tech_set(tmp, &null_tech);
946 }
947
948 ast_channel_internal_finalize(tmp);
949
950 ast_atomic_fetchadd_int(&chancount, +1);
951
952 /* You might scream "locking inversion" at seeing this but it is actually perfectly fine.
953 * Since the channel was just created nothing can know about it yet or even acquire it.
954 */
955 ast_channel_lock(tmp)__ao2_lock(tmp, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 955, "tmp")
;
956
957 ao2_link(channels, tmp)__ao2_link((channels), (tmp), 0, "", "channel.c", 957, __PRETTY_FUNCTION__
)
;
958
959 if (endpoint) {
960 ast_endpoint_add_channel(endpoint, tmp);
961 }
962
963 /*
964 * And now, since the channel structure is built, and has its name, let
965 * the world know of its existance
966 */
967 ast_channel_stage_snapshot_done(tmp);
968 return tmp;
969}
970
971struct ast_channel *__ast_channel_alloc(int needqueue, int state, const char *cid_num,
972 const char *cid_name, const char *acctcode,
973 const char *exten, const char *context, const struct ast_assigned_ids *assignedids,
974 const struct ast_channel *requestor, enum ama_flags amaflag,
975 struct ast_endpoint *endpoint,
976 const char *file, int line, const char *function,
977 const char *name_fmt, ...)
978{
979 va_list ap;
980 struct ast_channel *result;
981
982 va_start(ap, name_fmt)__builtin_va_start(ap, name_fmt);
983 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
984 assignedids, requestor, amaflag, endpoint, file, line, function, name_fmt, ap);
985 va_end(ap)__builtin_va_end(ap);
986
987 return result;
988}
989
990/* only do the minimum amount of work needed here to make a channel
991 * structure that can be used to expand channel vars */
992struct ast_channel *__ast_dummy_channel_alloc(const char *file, int line, const char *function)
993{
994 struct ast_channel *tmp;
995 struct varshead *headp;
996
997 tmp = __ast_channel_internal_alloc(ast_dummy_channel_destructor, NULL((void*)0), NULL((void*)0),
998 file, line, function);
999 if (!tmp) {
1000 /* Dummy channel structure allocation failure. */
1001 return NULL((void*)0);
1002 }
1003
1004 ast_pbx_hangup_handler_init(tmp);
1005 AST_LIST_HEAD_INIT_NOLOCK(ast_channel_datastores(tmp)){ (ast_channel_datastores(tmp))->first = ((void*)0); (ast_channel_datastores
(tmp))->last = ((void*)0); }
;
1006
1007 /*
1008 * Init file descriptors to unopened state just in case
1009 * autoservice is called on the channel or something tries to
1010 * read a frame from it.
1011 */
1012 ast_channel_timingfd_set(tmp, -1);
1013 ast_channel_internal_alertpipe_clear(tmp);
1014 ast_channel_internal_fd_clear_all(tmp);
1015#ifdef HAVE_EPOLL
1016 ast_channel_epfd_set(tmp, -1);
1017#endif
1018
1019 ast_channel_hold_state_set(tmp, AST_CONTROL_UNHOLD);
1020
1021 ast_channel_internal_setup_topics(tmp);
1022
1023 headp = ast_channel_varshead(tmp);
1024 AST_LIST_HEAD_INIT_NOLOCK(headp){ (headp)->first = ((void*)0); (headp)->last = ((void*)
0); }
;
1025
1026 return tmp;
1027}
1028
1029static int __ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, int head, struct ast_frame *after)
1030{
1031 struct ast_frame *f;
1032 struct ast_frame *cur;
1033 unsigned int new_frames = 0;
1034 unsigned int new_voice_frames = 0;
1035 unsigned int queued_frames = 0;
1036 unsigned int queued_voice_frames = 0;
1037 AST_LIST_HEAD_NOLOCK(,ast_frame)struct { struct ast_frame *first; struct ast_frame *last; } frames;
1038
1039 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 1039, "chan")
;
1040
1041 /*
1042 * Check the last frame on the queue if we are queuing the new
1043 * frames after it.
1044 */
1045 cur = AST_LIST_LAST(ast_channel_readq(chan))((ast_channel_readq(chan))->last);
1046 if (cur && cur->frametype == AST_FRAME_CONTROL && !head && (!after || after == cur)) {
1047 switch (cur->subclass.integer) {
1048 case AST_CONTROL_END_OF_Q:
1049 if (fin->frametype == AST_FRAME_CONTROL
1050 && fin->subclass.integer == AST_CONTROL_HANGUP) {
1051 /*
1052 * Destroy the end-of-Q marker frame so we can queue the hangup
1053 * frame in its place.
1054 */
1055 AST_LIST_REMOVE(ast_channel_readq(chan), cur, frame_list)({ __typeof(cur) __elm = (cur); if (__elm) { if ((ast_channel_readq
(chan))->first == __elm) { (ast_channel_readq(chan))->first
= __elm->frame_list.next; __elm->frame_list.next = ((void
*)0); if ((ast_channel_readq(chan))->last == __elm) { (ast_channel_readq
(chan))->last = ((void*)0); } } else { typeof(cur) __prev =
(ast_channel_readq(chan))->first; while (__prev &&
__prev->frame_list.next != __elm) { __prev = __prev->frame_list
.next; } if (__prev) { __prev->frame_list.next = __elm->
frame_list.next; __elm->frame_list.next = ((void*)0); if (
(ast_channel_readq(chan))->last == __elm) { (ast_channel_readq
(chan))->last = __prev; } } else { __elm = ((void*)0); } }
} __elm; })
;
1056 ast_frfree(cur)ast_frame_free(cur, 1);
1057
1058 /*
1059 * This has degenerated to a normal queue append anyway. Since
1060 * we just destroyed the last frame in the queue we must make
1061 * sure that "after" is NULL or bad things will happen.
1062 */
1063 after = NULL((void*)0);
1064 break;
1065 }
1066 /* Fall through */
1067 case AST_CONTROL_HANGUP:
1068 /* Don't queue anything. */
1069 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 1069, "chan"
)
;
1070 return 0;
1071 default:
1072 break;
1073 }
1074 }
1075
1076 /* Build copies of all the new frames and count them */
1077 AST_LIST_HEAD_INIT_NOLOCK(&frames){ (&frames)->first = ((void*)0); (&frames)->last
= ((void*)0); }
;
1078 for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)((cur)->frame_list.next)) {
1079 if (!(f = ast_frdup(cur))) {
1080 if (AST_LIST_FIRST(&frames)((&frames)->first)) {
1081 ast_frfree(AST_LIST_FIRST(&frames))ast_frame_free(((&frames)->first), 1);
1082 }
1083 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 1083, "chan"
)
;
1084 return -1;
1085 }
1086
1087 AST_LIST_INSERT_TAIL(&frames, f, frame_list)do { if (!(&frames)->first) { (&frames)->first =
(f); (&frames)->last = (f); } else { (&frames)->
last->frame_list.next = (f); (&frames)->last = (f);
} } while (0)
;
1088 new_frames++;
1089 if (f->frametype == AST_FRAME_VOICE) {
1090 new_voice_frames++;
1091 }
1092 }
1093
1094 /* Count how many frames exist on the queue */
1095 AST_LIST_TRAVERSE(ast_channel_readq(chan), cur, frame_list)for((cur) = (ast_channel_readq(chan))->first; (cur); (cur)
= (cur)->frame_list.next)
{
1096 queued_frames++;
1097 if (cur->frametype == AST_FRAME_VOICE) {
1098 queued_voice_frames++;
1099 }
1100 }
1101
1102 if ((queued_frames + new_frames > 128 || queued_voice_frames + new_voice_frames > 96)) {
1103 int count = 0;
1104 ast_log(LOG_WARNING3, "channel.c", 1104, __PRETTY_FUNCTION__, "Exceptionally long %squeue length queuing to %s\n", queued_frames + new_frames > 128 ? "" : "voice ", ast_channel_name(chan));
1105 AST_LIST_TRAVERSE_SAFE_BEGIN(ast_channel_readq(chan), cur, frame_list){ typeof((ast_channel_readq(chan))) __list_head = ast_channel_readq
(chan); typeof(__list_head->first) __list_next; typeof(__list_head
->first) __list_prev = ((void*)0); typeof(__list_head->
first) __list_current; for ((cur) = __list_head->first, __list_current
= (cur), __list_next = (cur) ? (cur)->frame_list.next : (
(void*)0); (cur); __list_prev = __list_current, (cur) = __list_next
, __list_current = (cur), __list_next = (cur) ? (cur)->frame_list
.next : ((void*)0), (void) __list_prev )
{
1106 /* Save the most recent frame */
1107 if (!AST_LIST_NEXT(cur, frame_list)((cur)->frame_list.next)) {
1108 break;
1109 } else if (cur->frametype == AST_FRAME_VOICE || cur->frametype == AST_FRAME_VIDEO || cur->frametype == AST_FRAME_NULL) {
1110 if (++count > 64) {
1111 break;
1112 }
1113 AST_LIST_REMOVE_CURRENT(frame_list)do { __list_current->frame_list.next = ((void*)0); __list_current
= __list_prev; if (__list_prev) { __list_prev->frame_list
.next = __list_next; } else { __list_head->first = __list_next
; } if (!__list_next) { __list_head->last = __list_prev; }
} while (0)
;
1114 ast_frfree(cur)ast_frame_free(cur, 1);
1115 }
1116 }
1117 AST_LIST_TRAVERSE_SAFE_END};
1118 }
1119
1120 if (after) {
1121 AST_LIST_INSERT_LIST_AFTER(ast_channel_readq(chan), &frames, after, frame_list)do { (&frames)->last->frame_list.next = (after)->
frame_list.next; (after)->frame_list.next = (&frames)->
first; if ((ast_channel_readq(chan))->last == after) { (ast_channel_readq
(chan))->last = (&frames)->last; } (&frames)->
first = ((void*)0); (&frames)->last = ((void*)0); } while
(0)
;
1122 } else {
1123 if (head) {
1124 AST_LIST_APPEND_LIST(&frames, ast_channel_readq(chan), frame_list)do { if (!(ast_channel_readq(chan))->first) { break; } if (
!(&frames)->first) { (&frames)->first = (ast_channel_readq
(chan))->first; (&frames)->last = (ast_channel_readq
(chan))->last; } else { (&frames)->last->frame_list
.next = (ast_channel_readq(chan))->first; (&frames)->
last = (ast_channel_readq(chan))->last; } (ast_channel_readq
(chan))->first = ((void*)0); (ast_channel_readq(chan))->
last = ((void*)0); } while (0)
;
1125 AST_LIST_HEAD_INIT_NOLOCK(ast_channel_readq(chan)){ (ast_channel_readq(chan))->first = ((void*)0); (ast_channel_readq
(chan))->last = ((void*)0); }
;
1126 }
1127 AST_LIST_APPEND_LIST(ast_channel_readq(chan), &frames, frame_list)do { if (!(&frames)->first) { break; } if (!(ast_channel_readq
(chan))->first) { (ast_channel_readq(chan))->first = (&
frames)->first; (ast_channel_readq(chan))->last = (&
frames)->last; } else { (ast_channel_readq(chan))->last
->frame_list.next = (&frames)->first; (ast_channel_readq
(chan))->last = (&frames)->last; } (&frames)->
first = ((void*)0); (&frames)->last = ((void*)0); } while
(0)
;
1128 }
1129
1130 if (ast_channel_alert_writable(chan)) {
1131 if (ast_channel_alert_write(chan)) {
1132 ast_log(LOG_WARNING3, "channel.c", 1132, __PRETTY_FUNCTION__, "Unable to write to alert pipe on %s (qlen = %u): %s!\n",
1133 ast_channel_name(chan), queued_frames, strerror(errno(*__errno_location ())));
1134 }
1135 } else if (ast_channel_timingfd(chan) > -1) {
1136 ast_timer_enable_continuous(ast_channel_timer(chan));
1137 } else if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_BLOCKING)); })
) {
1138 pthread_kill(ast_channel_blocker(chan), SIGURG23);
1139 }
1140
1141 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 1141, "chan"
)
;
1142
1143 return 0;
1144}
1145
1146int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
1147{
1148 return __ast_queue_frame(chan, fin, 0, NULL((void*)0));
1149}
1150
1151int ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *fin)
1152{
1153 return __ast_queue_frame(chan, fin, 1, NULL((void*)0));
1154}
1155
1156/*! \brief Queue a hangup frame for channel */
1157int ast_queue_hangup(struct ast_channel *chan)
1158{
1159 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
1160 int res;
1161
1162 /* Yeah, let's not change a lock-critical value without locking */
1163 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 1163, "chan")
;
1164 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
1165 ast_channel_publish_blob(chan, ast_channel_hangup_request_type(), NULL((void*)0));
1166
1167 res = ast_queue_frame(chan, &f);
1168 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 1168, "chan"
)
;
1169 return res;
1170}
1171
1172/*! \brief Queue a hangup frame for channel */
1173int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
1174{
1175 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref)_raii_cleanup_block_t _raii_cleanup_blob __attribute__((cleanup
(_raii_cleanup_block),unused)) = ((void*)0); __attribute__((__blocks__
(byref))) struct ast_json * blob = ((void*)0); _raii_cleanup_blob
= ^{ {(void)ast_json_unref(blob);} }
;
1176 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
1177 int res;
1178
1179 if (cause >= 0) {
1180 f.data.uint32 = cause;
1181 }
1182
1183 /* Yeah, let's not change a lock-critical value without locking */
1184 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 1184, "chan")
;
1185 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
1186 if (cause < 0) {
1187 f.data.uint32 = ast_channel_hangupcause(chan);
1188 }
1189 blob = ast_json_pack("{s: i}",
1190 "cause", cause);
1191 ast_channel_publish_blob(chan, ast_channel_hangup_request_type(), blob);
1192
1193 res = ast_queue_frame(chan, &f);
1194 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 1194, "chan"
)
;
1195 return res;
1196}
1197
1198int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
1199{
1200 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HOLD };
1201 struct ast_json *blob = NULL((void*)0);
1202 int res;
1203
1204 if (!ast_strlen_zero(musicclass)_ast_strlen_zero(musicclass, "channel.c", __PRETTY_FUNCTION__
, 1204)
) {
1205 f.data.ptr = (void *) musicclass;
1206 f.datalen = strlen(musicclass) + 1;
1207
1208 blob = ast_json_pack("{s: s}",
1209 "musicclass", musicclass);
1210 }
1211
1212 ast_channel_publish_cached_blob(chan, ast_channel_hold_type(), blob);
1213
1214 res = ast_queue_frame(chan, &f);
1215
1216 ast_json_unref(blob);
1217
1218 return res;
1219}
1220
1221int ast_queue_unhold(struct ast_channel *chan)
1222{
1223 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_UNHOLD };
1224 int res;
1225
1226 ast_channel_publish_cached_blob(chan, ast_channel_unhold_type(), NULL((void*)0));
1227
1228 res = ast_queue_frame(chan, &f);
1229
1230 return res;
1231}
1232
1233/*! \brief Queue a control frame */
1234int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
1235{
1236 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control };
1237 return ast_queue_frame(chan, &f);
1238}
1239
1240/*! \brief Queue a control frame with payload */
1241int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control,
1242 const void *data, size_t datalen)
1243{
1244 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control, .data.ptr = (void *) data, .datalen = datalen };
1245 return ast_queue_frame(chan, &f);
1246}
1247
1248/*! \brief Set defer DTMF flag on channel */
1249int ast_channel_defer_dtmf(struct ast_channel *chan)
1250{
1251 int pre = 0;
1252
1253 if (chan) {
1254 pre = ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_DEFER_DTMF)); })
;
1255 ast_set_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags |= (AST_FLAG_DEFER_DTMF)); } while(0)
;
1256 }
1257 return pre;
1258}
1259
1260/*! \brief Unset defer DTMF flag on channel */
1261void ast_channel_undefer_dtmf(struct ast_channel *chan)
1262{
1263 if (chan)
1264 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags &= ~(AST_FLAG_DEFER_DTMF)); } while(0)
;
1265}
1266
1267struct ast_channel *ast_channel_callback(ao2_callback_data_fn *cb_fn, void *arg,
1268 void *data, int ao2_flags)
1269{
1270 return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data)__ao2_callback_data((channels), (ao2_flags), (cb_fn), (arg), (
data), "", "channel.c", 1270, __PRETTY_FUNCTION__)
;
1271}
1272
1273static int ast_channel_by_name_cb(void *obj, void *arg, void *data, int flags)
1274{
1275 struct ast_channel *chan = obj;
1276 const char *name = arg;
1277 size_t name_len = *(size_t *) data;
1278 int ret = CMP_MATCH;
1279
1280 if (ast_strlen_zero(name)_ast_strlen_zero(name, "channel.c", __PRETTY_FUNCTION__, 1280
)
) {
1281 ast_log(LOG_ERROR4, "channel.c", 1281, __PRETTY_FUNCTION__, "BUG! Must supply a channel name or partial name to match!\n");
1282 return CMP_STOP;
1283 }
1284
1285 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 1285, "chan")
;
1286 if ((!name_len && strcasecmp(ast_channel_name(chan), name))
1287 || (name_len && strncasecmp(ast_channel_name(chan), name, name_len))) {
1288 ret = 0; /* name match failed, keep looking */
1289 }
1290 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 1290, "chan"
)
;
1291
1292 return ret;
1293}
1294
1295static int ast_channel_by_exten_cb(void *obj, void *arg, void *data, int flags)
1296{
1297 struct ast_channel *chan = obj;
1298 char *context = arg;
1299 char *exten = data;
1300 int ret = CMP_MATCH;
1301
1302 if (ast_strlen_zero(exten)_ast_strlen_zero(exten, "channel.c", __PRETTY_FUNCTION__, 1302
)
|| ast_strlen_zero(context)_ast_strlen_zero(context, "channel.c", __PRETTY_FUNCTION__, 1302
)
) {
1303 ast_log(LOG_ERROR4, "channel.c", 1303, __PRETTY_FUNCTION__, "BUG! Must have a context and extension to match!\n");
1304 return CMP_STOP;
1305 }
1306
1307 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 1307, "chan")
;
1308 if (strcasecmp(ast_channel_context(chan), context) && strcasecmp(ast_channel_macrocontext(chan), context)) {
1309 ret = 0; /* Context match failed, continue */
1310 } else if (strcasecmp(ast_channel_exten(chan), exten) && strcasecmp(ast_channel_macroexten(chan), exten)) {
1311 ret = 0; /* Extension match failed, continue */
1312 }
1313 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 1313, "chan"
)
;
1314
1315 return ret;
1316}
1317
1318static int ast_channel_by_uniqueid_cb(void *obj, void *arg, void *data, int flags)
1319{
1320 struct ast_channel *chan = obj;
1321 char *uniqueid = arg;
1322 size_t id_len = *(size_t *) data;
1323 int ret = CMP_MATCH;
1324
1325 if (ast_strlen_zero(uniqueid)_ast_strlen_zero(uniqueid, "channel.c", __PRETTY_FUNCTION__, 1325
)
) {
1326 ast_log(LOG_ERROR4, "channel.c", 1326, __PRETTY_FUNCTION__, "BUG! Must supply a uniqueid or partial uniqueid to match!\n");
1327 return CMP_STOP;
1328 }
1329
1330 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 1330, "chan")
;
1331 if ((!id_len && strcasecmp(ast_channel_uniqueid(chan), uniqueid))
1332 || (id_len && strncasecmp(ast_channel_uniqueid(chan), uniqueid, id_len))) {
1333 ret = 0; /* uniqueid match failed, keep looking */
1334 }
1335 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 1335, "chan"
)
;
1336
1337 return ret;
1338}
1339
1340struct ast_channel_iterator {
1341 /* storage for non-dynamically allocated iterator */
1342 struct ao2_iterator simple_iterator;
1343 /* pointer to the actual iterator (simple_iterator or a dynamically
1344 * allocated iterator)
1345 */
1346 struct ao2_iterator *active_iterator;
1347};
1348
1349struct ast_channel_iterator *ast_channel_iterator_destroy(struct ast_channel_iterator *i)
1350{
1351 ao2_iterator_destroy(i->active_iterator);
1352 ast_freefree(i);
1353
1354 return NULL((void*)0);
1355}
1356
1357struct ast_channel_iterator *ast_channel_iterator_by_exten_new(const char *exten, const char *context)
1358{
1359 struct ast_channel_iterator *i;
1360 char *l_exten = (char *) exten;
1361 char *l_context = (char *) context;
1362
1363 if (!(i = ast_calloc(1, sizeof(*i))_ast_calloc((1), (sizeof(*i)), "channel.c", 1363, __PRETTY_FUNCTION__
)
)) {
1364 return NULL((void*)0);
1365 }
1366
1367 i->active_iterator = (void *) ast_channel_callback(ast_channel_by_exten_cb,
1368 l_context, l_exten, OBJ_MULTIPLE);
1369 if (!i->active_iterator) {
1370 ast_freefree(i);
1371 return NULL((void*)0);
1372 }
1373
1374 return i;
1375}
1376
1377struct ast_channel_iterator *ast_channel_iterator_by_name_new(const char *name, size_t name_len)
1378{
1379 struct ast_channel_iterator *i;
1380 char *l_name = (char *) name;
1381
1382 if (!(i = ast_calloc(1, sizeof(*i))_ast_calloc((1), (sizeof(*i)), "channel.c", 1382, __PRETTY_FUNCTION__
)
)) {
1383 return NULL((void*)0);
1384 }
1385
1386 i->active_iterator = (void *) ast_channel_callback(ast_channel_by_name_cb,
1387 l_name, &name_len,
1388 OBJ_MULTIPLE | (name_len == 0 /* match the whole word, so optimize */ ? OBJ_KEYOBJ_SEARCH_KEY : 0));
1389 if (!i->active_iterator) {
1390 ast_freefree(i);
1391 return NULL((void*)0);
1392 }
1393
1394 return i;
1395}
1396
1397struct ast_channel_iterator *ast_channel_iterator_all_new(void)
1398{
1399 struct ast_channel_iterator *i;
1400
1401 if (!(i = ast_calloc(1, sizeof(*i))_ast_calloc((1), (sizeof(*i)), "channel.c", 1401, __PRETTY_FUNCTION__
)
)) {
1402 return NULL((void*)0);
1403 }
1404
1405 i->simple_iterator = ao2_iterator_init(channels, 0);
1406 i->active_iterator = &i->simple_iterator;
1407
1408 return i;
1409}
1410
1411struct ast_channel *ast_channel_iterator_next(struct ast_channel_iterator *i)
1412{
1413 return ao2_iterator_next(i->active_iterator)__ao2_iterator_next((i->active_iterator), "", "channel.c",
1413, __PRETTY_FUNCTION__)
;
1414}
1415
1416/* Legacy function, not currently used for lookups, but we need a cmp_fn */
1417static int ast_channel_cmp_cb(void *obj, void *arg, int flags)
1418{
1419 ast_log(LOG_ERROR4, "channel.c", 1419, __PRETTY_FUNCTION__, "BUG! Should never be called!\n");
1420 return CMP_STOP;
1421}
1422
1423struct ast_channel *ast_channel_get_by_name_prefix(const char *name, size_t name_len)
1424{
1425 struct ast_channel *chan;
1426 char *l_name = (char *) name;
1427
1428 chan = ast_channel_callback(ast_channel_by_name_cb, l_name, &name_len,
1429 (name_len == 0) /* optimize if it is a complete name match */ ? OBJ_KEYOBJ_SEARCH_KEY : 0);
1430 if (chan) {
1431 return chan;
1432 }
1433
1434 if (ast_strlen_zero(l_name)_ast_strlen_zero(l_name, "channel.c", __PRETTY_FUNCTION__, 1434
)
) {
1435 /* We didn't have a name to search for so quit. */
1436 return NULL((void*)0);
1437 }
1438
1439 /* Now try a search for uniqueid. */
1440 return ast_channel_callback(ast_channel_by_uniqueid_cb, l_name, &name_len, 0);
1441}
1442
1443struct ast_channel *ast_channel_get_by_name(const char *name)
1444{
1445 return ast_channel_get_by_name_prefix(name, 0);
1446}
1447
1448struct ast_channel *ast_channel_get_by_exten(const char *exten, const char *context)
1449{
1450 char *l_exten = (char *) exten;
1451 char *l_context = (char *) context;
1452
1453 return ast_channel_callback(ast_channel_by_exten_cb, l_context, l_exten, 0);
1454}
1455
1456int ast_is_deferrable_frame(const struct ast_frame *frame)
1457{
1458 /* Do not add a default entry in this switch statement. Each new
1459 * frame type should be addressed directly as to whether it should
1460 * be queued up or not.
1461 */
1462 switch (frame->frametype) {
1463 case AST_FRAME_BRIDGE_ACTION:
1464 case AST_FRAME_BRIDGE_ACTION_SYNC:
1465 case AST_FRAME_CONTROL:
1466 case AST_FRAME_TEXT:
1467 case AST_FRAME_IMAGE:
1468 case AST_FRAME_HTML:
1469 return 1;
1470
1471 case AST_FRAME_DTMF_END:
1472 case AST_FRAME_DTMF_BEGIN:
1473 case AST_FRAME_VOICE:
1474 case AST_FRAME_VIDEO:
1475 case AST_FRAME_NULL:
1476 case AST_FRAME_IAX:
1477 case AST_FRAME_CNG:
1478 case AST_FRAME_MODEM:
1479 return 0;
1480 }
1481 return 0;
1482}
1483
1484/*! \brief Wait, look for hangups and condition arg */
1485int ast_safe_sleep_conditional(struct ast_channel *chan, int timeout_ms, int (*cond)(void*), void *data)
1486{
1487 struct ast_frame *f;
1488 struct ast_silence_generator *silgen = NULL((void*)0);
1489 int res = 0;
1490 struct timeval start;
1491 int ms;
1492 AST_LIST_HEAD_NOLOCK(, ast_frame)struct { struct ast_frame *first; struct ast_frame *last; } deferred_frames;
1493
1494 AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames){ (&deferred_frames)->first = ((void*)0); (&deferred_frames
)->last = ((void*)0); }
;
1495
1496 /* If no other generator is present, start silencegen while waiting */
1497 if (ast_opt_transmit_silence({ typeof ((&ast_options)->flags) __p = (&ast_options
)->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (void
) (&__p == &__x); ((&ast_options)->flags &
(AST_OPT_FLAG_TRANSMIT_SILENCE)); })
&& !ast_channel_generatordata(chan)) {
1498 silgen = ast_channel_start_silence_generator(chan);
1499 }
1500
1501 start = ast_tvnow();
1502 while ((ms = ast_remaining_ms(start, timeout_ms))) {
1503 struct ast_frame *dup_f = NULL((void*)0);
1504
1505 if (cond && ((*cond)(data) == 0)) {
1506 break;
1507 }
1508 ms = ast_waitfor(chan, ms);
1509 if (ms < 0) {
1510 res = -1;
1511 break;
1512 }
1513 if (ms > 0) {
1514 f = ast_read(chan);
1515 if (!f) {
1516 res = -1;
1517 break;
1518 }
1519
1520 if (!ast_is_deferrable_frame(f)) {
1521 ast_frfree(f)ast_frame_free(f, 1);
1522 continue;
1523 }
1524
1525 if ((dup_f = ast_frisolate(f))) {
1526 if (dup_f != f) {
1527 ast_frfree(f)ast_frame_free(f, 1);
1528 }
1529 AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list)do { (dup_f)->frame_list.next = (&deferred_frames)->
first; (&deferred_frames)->first = (dup_f); if (!(&
deferred_frames)->last) (&deferred_frames)->last = (
dup_f); } while (0)
;
1530 }
1531 }
1532 }
1533
1534 /* stop silgen if present */
1535 if (silgen) {
1536 ast_channel_stop_silence_generator(chan, silgen);
1537 }
1538
1539 /* We need to free all the deferred frames, but we only need to
1540 * queue the deferred frames if there was no error and no
1541 * hangup was received
1542 */
1543 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 1543, "chan")
;
1544 while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list)({ typeof((&deferred_frames)->first) __cur = (&deferred_frames
)->first; if (__cur) { (&deferred_frames)->first = __cur
->frame_list.next; __cur->frame_list.next = ((void*)0);
if ((&deferred_frames)->last == __cur) (&deferred_frames
)->last = ((void*)0); } __cur; })
)) {
1545 if (!res) {
1546 ast_queue_frame_head(chan, f);
1547 }
1548 ast_frfree(f)ast_frame_free(f, 1);
1549 }
1550 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 1550, "chan"
)
;
1551
1552 return res;
1553}
1554
1555/*! \brief Wait, look for hangups */
1556int ast_safe_sleep(struct ast_channel *chan, int ms)
1557{
1558 return ast_safe_sleep_conditional(chan, ms, NULL((void*)0), NULL((void*)0));
1559}
1560
1561struct ast_channel *ast_channel_release(struct ast_channel *chan)
1562{
1563 /* Safe, even if already unlinked. */
1564 ao2_unlink(channels, chan)__ao2_unlink((channels), (chan), 0, "", "channel.c", 1564, __PRETTY_FUNCTION__
)
;
1565 return ast_channel_unref(chan)({ __ao2_ref((chan), (-1), "", "channel.c", 1565, __PRETTY_FUNCTION__
); (struct ast_channel *) (((void*)0)); })
;
1566}
1567
1568void ast_party_name_init(struct ast_party_name *init)
1569{
1570 init->str = NULL((void*)0);
1571 init->char_set = AST_PARTY_CHAR_SET_ISO8859_1;
1572 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED(0x00 | 0x00);
1573 init->valid = 0;
1574}
1575
1576void ast_party_name_copy(struct ast_party_name *dest, const struct ast_party_name *src)
1577{
1578 if (dest == src) {
1579 /* Don't copy to self */
1580 return;
1581 }
1582
1583 ast_freefree(dest->str);
1584 dest->str = ast_strdup(src->str)_ast_strdup((src->str), "channel.c", 1584, __PRETTY_FUNCTION__
)
;
1585 dest->char_set = src->char_set;
1586 dest->presentation = src->presentation;
1587 dest->valid = src->valid;
1588}
1589
1590void ast_party_name_set_init(struct ast_party_name *init, const struct ast_party_name *guide)
1591{
1592 init->str = NULL((void*)0);
1593 init->char_set = guide->char_set;
1594 init->presentation = guide->presentation;
1595 init->valid = guide->valid;
1596}
1597
1598void ast_party_name_set(struct ast_party_name *dest, const struct ast_party_name *src)
1599{
1600 if (dest == src) {
1601 /* Don't set to self */
1602 return;
1603 }
1604
1605 if (src->str && src->str != dest->str) {
1606 ast_freefree(dest->str);
1607 dest->str = ast_strdup(src->str)_ast_strdup((src->str), "channel.c", 1607, __PRETTY_FUNCTION__
)
;
1608 }
1609
1610 dest->char_set = src->char_set;
1611 dest->presentation = src->presentation;
1612 dest->valid = src->valid;
1613}
1614
1615void ast_party_name_free(struct ast_party_name *doomed)
1616{
1617 ast_freefree(doomed->str);
1618 doomed->str = NULL((void*)0);
1619}
1620
1621void ast_party_number_init(struct ast_party_number *init)
1622{
1623 init->str = NULL((void*)0);
1624 init->plan = 0;/* Unknown */
1625 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED(0x00 | 0x00);
1626 init->valid = 0;
1627}
1628
1629void ast_party_number_copy(struct ast_party_number *dest, const struct ast_party_number *src)
1630{
1631 if (dest == src) {
1632 /* Don't copy to self */
1633 return;
1634 }
1635
1636 ast_freefree(dest->str);
1637 dest->str = ast_strdup(src->str)_ast_strdup((src->str), "channel.c", 1637, __PRETTY_FUNCTION__
)
;
1638 dest->plan = src->plan;
1639 dest->presentation = src->presentation;
1640 dest->valid = src->valid;
1641}
1642
1643void ast_party_number_set_init(struct ast_party_number *init, const struct ast_party_number *guide)
1644{
1645 init->str = NULL((void*)0);
1646 init->plan = guide->plan;
1647 init->presentation = guide->presentation;
1648 init->valid = guide->valid;
1649}
1650
1651void ast_party_number_set(struct ast_party_number *dest, const struct ast_party_number *src)
1652{
1653 if (dest == src) {
1654 /* Don't set to self */
1655 return;
1656 }
1657
1658 if (src->str && src->str != dest->str) {
1659 ast_freefree(dest->str);
1660 dest->str = ast_strdup(src->str)_ast_strdup((src->str), "channel.c", 1660, __PRETTY_FUNCTION__
)
;
1661 }
1662
1663 dest->plan = src->plan;
1664 dest->presentation = src->presentation;
1665 dest->valid = src->valid;
1666}
1667
1668void ast_party_number_free(struct ast_party_number *doomed)
1669{
1670 ast_freefree(doomed->str);
1671 doomed->str = NULL((void*)0);
1672}
1673
1674void ast_party_subaddress_init(struct ast_party_subaddress *init)
1675{
1676 init->str = NULL((void*)0);
1677 init->type = 0;
1678 init->odd_even_indicator = 0;
1679 init->valid = 0;
1680}
1681
1682void ast_party_subaddress_copy(struct ast_party_subaddress *dest, const struct ast_party_subaddress *src)
1683{
1684 if (dest == src) {
1685 /* Don't copy to self */
1686 return;
1687 }
1688
1689 ast_freefree(dest->str);
1690 dest->str = ast_strdup(src->str)_ast_strdup((src->str), "channel.c", 1690, __PRETTY_FUNCTION__
)
;
1691 dest->type = src->type;
1692 dest->odd_even_indicator = src->odd_even_indicator;
1693 dest->valid = src->valid;
1694}
1695
1696void ast_party_subaddress_set_init(struct ast_party_subaddress *init, const struct ast_party_subaddress *guide)
1697{
1698 init->str = NULL((void*)0);
1699 init->type = guide->type;
1700 init->odd_even_indicator = guide->odd_even_indicator;
1701 init->valid = guide->valid;
1702}
1703
1704void ast_party_subaddress_set(struct ast_party_subaddress *dest, const struct ast_party_subaddress *src)
1705{
1706 if (dest == src) {
1707 /* Don't set to self */
1708 return;
1709 }
1710
1711 if (src->str && src->str != dest->str) {
1712 ast_freefree(dest->str);
1713 dest->str = ast_strdup(src->str)_ast_strdup((src->str), "channel.c", 1713, __PRETTY_FUNCTION__
)
;
1714 }
1715
1716 dest->type = src->type;
1717 dest->odd_even_indicator = src->odd_even_indicator;
1718 dest->valid = src->valid;
1719}
1720
1721void ast_party_subaddress_free(struct ast_party_subaddress *doomed)
1722{
1723 ast_freefree(doomed->str);
1724 doomed->str = NULL((void*)0);
1725}
1726
1727void ast_set_party_id_all(struct ast_set_party_id *update_id)
1728{
1729 update_id->name = 1;
1730 update_id->number = 1;
1731 update_id->subaddress = 1;
1732}
1733
1734void ast_party_id_init(struct ast_party_id *init)
1735{
1736 ast_party_name_init(&init->name);
1737 ast_party_number_init(&init->number);
1738 ast_party_subaddress_init(&init->subaddress);
1739 init->tag = NULL((void*)0);
1740}
1741
1742void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
1743{
1744 if (dest == src) {
1745 /* Don't copy to self */
1746 return;
1747 }
1748
1749 ast_party_name_copy(&dest->name, &src->name);
1750 ast_party_number_copy(&dest->number, &src->number);
1751 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
1752
1753 ast_freefree(dest->tag);
1754 dest->tag = ast_strdup(src->tag)_ast_strdup((src->tag), "channel.c", 1754, __PRETTY_FUNCTION__
)
;
1755}
1756
1757void ast_party_id_set_init(struct ast_party_id *init, const struct ast_party_id *guide)
1758{
1759 ast_party_name_set_init(&init->name, &guide->name);
1760 ast_party_number_set_init(&init->number, &guide->number);
1761 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
1762 init->tag = NULL((void*)0);
1763}
1764
1765void ast_party_id_set(struct ast_party_id *dest, const struct ast_party_id *src, const struct ast_set_party_id *update)
1766{
1767 if (dest == src) {
1768 /* Don't set to self */
1769 return;
1770 }
1771
1772 if (!update || update->name) {
1773 ast_party_name_set(&dest->name, &src->name);
1774 }
1775 if (!update || update->number) {
1776 ast_party_number_set(&dest->number, &src->number);
1777 }
1778 if (!update || update->subaddress) {
1779 ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
1780 }
1781
1782 if (src->tag && src->tag != dest->tag) {
1783 ast_freefree(dest->tag);
1784 dest->tag = ast_strdup(src->tag)_ast_strdup((src->tag), "channel.c", 1784, __PRETTY_FUNCTION__
)
;
1785 }
1786}
1787
1788void ast_party_id_free(struct ast_party_id *doomed)
1789{
1790 ast_party_name_free(&doomed->name);
1791 ast_party_number_free(&doomed->number);
1792 ast_party_subaddress_free(&doomed->subaddress);
1793
1794 ast_freefree(doomed->tag);
1795 doomed->tag = NULL((void*)0);
1796}
1797
1798int ast_party_id_presentation(const struct ast_party_id *id)
1799{
1800 int number_priority;
1801 int number_value;
1802 int number_screening;
1803 int name_priority;
1804 int name_value;
1805
1806 /* Determine name presentation priority. */
1807 if (!id->name.valid) {
1808 name_value = AST_PRES_UNAVAILABLE0x40;
1809 name_priority = 3;
1810 } else {
1811 name_value = id->name.presentation & AST_PRES_RESTRICTION0x60;
1812 switch (name_value) {
1813 case AST_PRES_RESTRICTED0x20:
1814 name_priority = 0;
1815 break;
1816 case AST_PRES_ALLOWED0x00:
1817 name_priority = 1;
1818 break;
1819 case AST_PRES_UNAVAILABLE0x40:
1820 name_priority = 2;
1821 break;
1822 default:
1823 name_value = AST_PRES_UNAVAILABLE0x40;
1824 name_priority = 3;
1825 break;
1826 }
1827 }
1828
1829 /* Determine number presentation priority. */
1830 if (!id->number.valid) {
1831 number_screening = AST_PRES_USER_NUMBER_UNSCREENED0x00;
1832 number_value = AST_PRES_UNAVAILABLE0x40;
1833 number_priority = 3;
1834 } else {
1835 number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE0x03;
1836 number_value = id->number.presentation & AST_PRES_RESTRICTION0x60;
1837 switch (number_value) {
1838 case AST_PRES_RESTRICTED0x20:
1839 number_priority = 0;
1840 break;
1841 case AST_PRES_ALLOWED0x00:
1842 number_priority = 1;
1843 break;
1844 case AST_PRES_UNAVAILABLE0x40:
1845 number_priority = 2;
1846 break;
1847 default:
1848 number_screening = AST_PRES_USER_NUMBER_UNSCREENED0x00;
1849 number_value = AST_PRES_UNAVAILABLE0x40;
1850 number_priority = 3;
1851 break;
1852 }
1853 }
1854
1855 /* Select the wining presentation value. */
1856 if (name_priority < number_priority) {
1857 number_value = name_value;
1858 }
1859 if (number_value == AST_PRES_UNAVAILABLE0x40) {
1860 return AST_PRES_NUMBER_NOT_AVAILABLE(0x40 | 0x03);
1861 }
1862
1863 return number_value | number_screening;
1864}
1865
1866void ast_party_id_invalidate(struct ast_party_id *id)
1867{
1868 id->name.valid = 0;
1869 id->number.valid = 0;
1870 id->subaddress.valid = 0;
1871}
1872
1873void ast_party_id_reset(struct ast_party_id *id)
1874{
1875 ast_party_id_free(id);
1876 ast_party_id_init(id);
1877}
1878
1879struct ast_party_id ast_party_id_merge(struct ast_party_id *base, struct ast_party_id *overlay)
1880{
1881 struct ast_party_id merged;
1882
1883 merged = *base;
1884 if (overlay->name.valid) {
1885 merged.name = overlay->name;
1886 }
1887 if (overlay->number.valid) {
1888 merged.number = overlay->number;
1889 }
1890 if (overlay->subaddress.valid) {
1891 merged.subaddress = overlay->subaddress;
1892 }
1893 /* Note the actual structure is returned and not a pointer to it! */
1894 return merged;
1895}
1896
1897void ast_party_id_merge_copy(struct ast_party_id *dest, struct ast_party_id *base, struct ast_party_id *overlay)
1898{
1899 struct ast_party_id merged;
1900
1901 merged = ast_party_id_merge(base, overlay);
1902 ast_party_id_copy(dest, &merged);
1903}
1904
1905void ast_party_dialed_init(struct ast_party_dialed *init)
1906{
1907 init->number.str = NULL((void*)0);
1908 init->number.plan = 0;/* Unknown */
1909 ast_party_subaddress_init(&init->subaddress);
1910 init->transit_network_select = 0;
1911}
1912
1913void ast_party_dialed_copy(struct ast_party_dialed *dest, const struct ast_party_dialed *src)
1914{
1915 if (dest == src) {
1916 /* Don't copy to self */
1917 return;
1918 }
1919
1920 ast_freefree(dest->number.str);
1921 dest->number.str = ast_strdup(src->number.str)_ast_strdup((src->number.str), "channel.c", 1921, __PRETTY_FUNCTION__
)
;
1922 dest->number.plan = src->number.plan;
1923 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
1924 dest->transit_network_select = src->transit_network_select;
1925}
1926
1927void ast_party_dialed_set_init(struct ast_party_dialed *init, const struct ast_party_dialed *guide)
1928{
1929 init->number.str = NULL((void*)0);
1930 init->number.plan = guide->number.plan;
1931 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
1932 init->transit_network_select = guide->transit_network_select;
1933}
1934
1935void ast_party_dialed_set(struct ast_party_dialed *dest, const struct ast_party_dialed *src)
1936{
1937 if (src->number.str && src->number.str != dest->number.str) {
1938 ast_freefree(dest->number.str);
1939 dest->number.str = ast_strdup(src->number.str)_ast_strdup((src->number.str), "channel.c", 1939, __PRETTY_FUNCTION__
)
;
1940 }
1941 dest->number.plan = src->number.plan;
1942
1943 ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
1944
1945 dest->transit_network_select = src->transit_network_select;
1946}
1947
1948void ast_party_dialed_free(struct ast_party_dialed *doomed)
1949{
1950 ast_freefree(doomed->number.str);
1951 doomed->number.str = NULL((void*)0);
1952 ast_party_subaddress_free(&doomed->subaddress);
1953}
1954
1955void ast_party_caller_init(struct ast_party_caller *init)
1956{
1957 ast_party_id_init(&init->id);
1958 ast_party_id_init(&init->ani);
1959 ast_party_id_init(&init->priv);
1960 init->ani2 = 0;
1961}
1962
1963void ast_party_caller_copy(struct ast_party_caller *dest, const struct ast_party_caller *src)
1964{
1965 if (dest == src) {
1966 /* Don't copy to self */
1967 return;
1968 }
1969
1970 ast_party_id_copy(&dest->id, &src->id);
1971 ast_party_id_copy(&dest->ani, &src->ani);
1972 ast_party_id_copy(&dest->priv, &src->priv);
1973 dest->ani2 = src->ani2;
1974}
1975
1976void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
1977{
1978 ast_party_id_set_init(&init->id, &guide->id);
1979 ast_party_id_set_init(&init->ani, &guide->ani);
1980 ast_party_id_set_init(&init->priv, &guide->priv);
1981 init->ani2 = guide->ani2;
1982}
1983
1984void ast_party_caller_set(struct ast_party_caller *dest, const struct ast_party_caller *src, const struct ast_set_party_caller *update)
1985{
1986 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL((void*)0));
1987 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL((void*)0));
1988 ast_party_id_set(&dest->priv, &src->priv, update ? &update->priv : NULL((void*)0));
1989 dest->ani2 = src->ani2;
1990}
1991
1992void ast_party_caller_free(struct ast_party_caller *doomed)
1993{
1994 ast_party_id_free(&doomed->id);
1995 ast_party_id_free(&doomed->ani);
1996 ast_party_id_free(&doomed->priv);
1997}
1998
1999void ast_party_connected_line_init(struct ast_party_connected_line *init)
2000{
2001 ast_party_id_init(&init->id);
2002 ast_party_id_init(&init->ani);
2003 ast_party_id_init(&init->priv);
2004 init->ani2 = 0;
2005 init->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
2006}
2007
2008void ast_party_connected_line_copy(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
2009{
2010 if (dest == src) {
2011 /* Don't copy to self */
2012 return;
2013 }
2014
2015 ast_party_id_copy(&dest->id, &src->id);
2016 ast_party_id_copy(&dest->ani, &src->ani);
2017 ast_party_id_copy(&dest->priv, &src->priv);
2018 dest->ani2 = src->ani2;
2019 dest->source = src->source;
2020}
2021
2022void ast_party_connected_line_set_init(struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
2023{
2024 ast_party_id_set_init(&init->id, &guide->id);
2025 ast_party_id_set_init(&init->ani, &guide->ani);
2026 ast_party_id_set_init(&init->priv, &guide->priv);
2027 init->ani2 = guide->ani2;
2028 init->source = guide->source;
2029}
2030
2031void 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)
2032{
2033 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL((void*)0));
2034 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL((void*)0));
2035 ast_party_id_set(&dest->priv, &src->priv, update ? &update->priv : NULL((void*)0));
2036 dest->ani2 = src->ani2;
2037 dest->source = src->source;
2038}
2039
2040void ast_party_connected_line_collect_caller(struct ast_party_connected_line *connected, struct ast_party_caller *caller)
2041{
2042 connected->id = caller->id;
2043 connected->ani = caller->ani;
2044 connected->priv = caller->priv;
2045 connected->ani2 = caller->ani2;
2046 connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
2047}
2048
2049void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
2050{
2051 ast_party_id_free(&doomed->id);
2052 ast_party_id_free(&doomed->ani);
2053 ast_party_id_free(&doomed->priv);
2054}
2055
2056void ast_party_redirecting_reason_init(struct ast_party_redirecting_reason *init)
2057{
2058 init->str = NULL((void*)0);
2059 init->code = AST_REDIRECTING_REASON_UNKNOWN;
2060}
2061
2062void ast_party_redirecting_reason_copy(struct ast_party_redirecting_reason *dest, const struct ast_party_redirecting_reason *src)
2063{
2064 if (dest == src) {
2065 return;
2066 }
2067
2068 ast_freefree(dest->str);
2069 dest->str = ast_strdup(src->str)_ast_strdup((src->str), "channel.c", 2069, __PRETTY_FUNCTION__
)
;
2070 dest->code = src->code;
2071}
2072
2073void ast_party_redirecting_reason_set_init(struct ast_party_redirecting_reason *init, const struct ast_party_redirecting_reason *guide)
2074{
2075 init->str = NULL((void*)0);
2076 init->code = guide->code;
2077}
2078
2079void ast_party_redirecting_reason_set(struct ast_party_redirecting_reason *dest, const struct ast_party_redirecting_reason *src)
2080{
2081 if (dest == src) {
2082 return;
2083 }
2084
2085 if (src->str && src->str != dest->str) {
2086 ast_freefree(dest->str);
2087 dest->str = ast_strdup(src->str)_ast_strdup((src->str), "channel.c", 2087, __PRETTY_FUNCTION__
)
;
2088 }
2089
2090 dest->code = src->code;
2091}
2092
2093void ast_party_redirecting_reason_free(struct ast_party_redirecting_reason *doomed)
2094{
2095 ast_freefree(doomed->str);
2096}
2097
2098
2099void ast_party_redirecting_init(struct ast_party_redirecting *init)
2100{
2101 ast_party_id_init(&init->orig);
2102 ast_party_id_init(&init->from);
2103 ast_party_id_init(&init->to);
2104 ast_party_id_init(&init->priv_orig);
2105 ast_party_id_init(&init->priv_from);
2106 ast_party_id_init(&init->priv_to);
2107 ast_party_redirecting_reason_init(&init->reason);
2108 ast_party_redirecting_reason_init(&init->orig_reason);
2109 init->count = 0;
2110}
2111
2112void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
2113{
2114 if (dest == src) {
2115 /* Don't copy to self */
2116 return;
2117 }
2118
2119 ast_party_id_copy(&dest->orig, &src->orig);
2120 ast_party_id_copy(&dest->from, &src->from);
2121 ast_party_id_copy(&dest->to, &src->to);
2122 ast_party_id_copy(&dest->priv_orig, &src->priv_orig);
2123 ast_party_id_copy(&dest->priv_from, &src->priv_from);
2124 ast_party_id_copy(&dest->priv_to, &src->priv_to);
2125 ast_party_redirecting_reason_copy(&dest->reason, &src->reason);
2126 ast_party_redirecting_reason_copy(&dest->orig_reason, &src->orig_reason);
2127 dest->count = src->count;
2128}
2129
2130void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const struct ast_party_redirecting *guide)
2131{
2132 ast_party_id_set_init(&init->orig, &guide->orig);
2133 ast_party_id_set_init(&init->from, &guide->from);
2134 ast_party_id_set_init(&init->to, &guide->to);
2135 ast_party_id_set_init(&init->priv_orig, &guide->priv_orig);
2136 ast_party_id_set_init(&init->priv_from, &guide->priv_from);
2137 ast_party_id_set_init(&init->priv_to, &guide->priv_to);
2138 ast_party_redirecting_reason_set_init(&init->reason, &guide->reason);
2139 ast_party_redirecting_reason_set_init(&init->orig_reason, &guide->orig_reason);
2140 init->count = guide->count;
2141}
2142
2143void ast_party_redirecting_set(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src, const struct ast_set_party_redirecting *update)
2144{
2145 ast_party_id_set(&dest->orig, &src->orig, update ? &update->orig : NULL((void*)0));
2146 ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL((void*)0));
2147 ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL((void*)0));
2148 ast_party_id_set(&dest->priv_orig, &src->priv_orig, update ? &update->priv_orig : NULL((void*)0));
2149 ast_party_id_set(&dest->priv_from, &src->priv_from, update ? &update->priv_from : NULL((void*)0));
2150 ast_party_id_set(&dest->priv_to, &src->priv_to, update ? &update->priv_to : NULL((void*)0));
2151 ast_party_redirecting_reason_set(&dest->reason, &src->reason);
2152 ast_party_redirecting_reason_set(&dest->orig_reason, &src->orig_reason);
2153 dest->count = src->count;
2154}
2155
2156void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
2157{
2158 ast_party_id_free(&doomed->orig);
2159 ast_party_id_free(&doomed->from);
2160 ast_party_id_free(&doomed->to);
2161 ast_party_id_free(&doomed->priv_orig);
2162 ast_party_id_free(&doomed->priv_from);
2163 ast_party_id_free(&doomed->priv_to);
2164 ast_party_redirecting_reason_free(&doomed->reason);
2165 ast_party_redirecting_reason_free(&doomed->orig_reason);
2166}
2167
2168/*! \brief Free a channel structure */
2169static void ast_channel_destructor(void *obj)
2170{
2171 struct ast_channel *chan = obj;
2172#ifdef HAVE_EPOLL
2173 int i;
2174#endif
2175 struct ast_var_t *vardata;
2176 struct ast_frame *f;
2177 struct varshead *headp;
2178 struct ast_datastore *datastore;
2179 char device_name[AST_CHANNEL_NAME80];
2180 ast_callid callid;
2181
2182 /* Stop monitoring */
2183 if (ast_channel_monitor(chan)) {
2184 ast_channel_monitor(chan)->stop(chan, 0);
2185 }
2186
2187 /* If there is native format music-on-hold state, free it */
2188 if (ast_channel_music_state(chan)) {
2189 ast_moh_cleanup(chan);
2190 }
2191
2192 ast_pbx_hangup_handler_destroy(chan);
2193
2194 /* Things that may possibly raise Stasis messages shouldn't occur after this point */
2195 ast_set_flag(ast_channel_flags(chan), AST_FLAG_DEAD)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags |= (AST_FLAG_DEAD)); } while(0)
;
2196
2197 if (ast_channel_internal_is_finalized(chan)) {
2198 /* A channel snapshot should not be in the process of being staged now. */
2199 ast_assert(!ast_test_flag(ast_channel_flags(chan), AST_FLAG_SNAPSHOT_STAGE))_ast_assert(!({ typeof ((ast_channel_flags(chan))->flags) __p
= (ast_channel_flags(chan))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(chan))->flags & (AST_FLAG_SNAPSHOT_STAGE)); }), "!ast_test_flag(ast_channel_flags(chan), AST_FLAG_SNAPSHOT_STAGE)"
, "channel.c", 2199, __PRETTY_FUNCTION__)
;
2200
2201 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2201, "chan")
;
2202 ast_channel_publish_snapshot(chan);
2203 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2203, "chan"
)
;
2204 publish_cache_clear(chan);
2205 }
2206
2207 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2207, "chan")
;
2208
2209 /* Get rid of each of the data stores on the channel */
2210 while ((datastore = AST_LIST_REMOVE_HEAD(ast_channel_datastores(chan), entry)({ typeof((ast_channel_datastores(chan))->first) __cur = (
ast_channel_datastores(chan))->first; if (__cur) { (ast_channel_datastores
(chan))->first = __cur->entry.next; __cur->entry.next
= ((void*)0); if ((ast_channel_datastores(chan))->last ==
__cur) (ast_channel_datastores(chan))->last = ((void*)0);
} __cur; })
))
2211 /* Free the data store */
2212 ast_datastore_free(datastore);
2213
2214 /* While the channel is locked, take the reference to its callid while we tear down the call. */
2215 callid = ast_channel_callid(chan);
2216 ast_channel_callid_cleanup(chan);
2217
2218 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2218, "chan"
)
;
2219
2220 /* Lock and unlock the channel just to be sure nobody has it locked still
2221 due to a reference that was stored in a datastore. (i.e. app_chanspy) */
2222 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2222, "chan")
;
2223 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2223, "chan"
)
;
2224
2225 if (ast_channel_tech_pvt(chan)) {
2226 ast_log_callid(LOG_WARNING3, "channel.c", 2226, __PRETTY_FUNCTION__, callid, "Channel '%s' may not have been hung up properly\n", ast_channel_name(chan));
2227 ast_freefree(ast_channel_tech_pvt(chan));
2228 }
2229
2230 if (ast_channel_sched(chan)) {
2231 ast_sched_context_destroy(ast_channel_sched(chan));
2232 }
2233
2234 if (ast_channel_internal_is_finalized(chan)) {
2235 char *dashptr;
2236
2237 ast_copy_string(device_name, ast_channel_name(chan), sizeof(device_name));
2238 if ((dashptr = strrchr(device_name, '-'))) {
2239 *dashptr = '\0';
2240 }
2241 } else {
2242 device_name[0] = '\0';
2243 }
2244
2245 /* Free translators */
2246 if (ast_channel_readtrans(chan))
2247 ast_translator_free_path(ast_channel_readtrans(chan));
2248 if (ast_channel_writetrans(chan))
2249 ast_translator_free_path(ast_channel_writetrans(chan));
2250 if (ast_channel_pbx(chan))
2251 ast_log_callid(LOG_WARNING3, "channel.c", 2251, __PRETTY_FUNCTION__, callid, "PBX may not have been terminated properly on '%s'\n", ast_channel_name(chan));
2252
2253 /* Free formats */
2254 ast_channel_set_oldwriteformat(chan, NULL((void*)0));
2255 ast_channel_set_rawreadformat(chan, NULL((void*)0));
2256 ast_channel_set_rawwriteformat(chan, NULL((void*)0));
2257 ast_channel_set_readformat(chan, NULL((void*)0));
2258 ast_channel_set_writeformat(chan, NULL((void*)0));
2259
2260 ast_party_dialed_free(ast_channel_dialed(chan));
2261 ast_party_caller_free(ast_channel_caller(chan));
2262 ast_party_connected_line_free(ast_channel_connected(chan));
2263 ast_party_connected_line_free(ast_channel_connected_indicated(chan));
2264 ast_party_redirecting_free(ast_channel_redirecting(chan));
2265
2266 /* Close pipes if appropriate */
2267 ast_channel_internal_alertpipe_close(chan);
2268 if (ast_channel_timer(chan)) {
2269 ast_timer_close(ast_channel_timer(chan));
2270 ast_channel_timer_set(chan, NULL((void*)0));
2271 }
2272#ifdef HAVE_EPOLL
2273 for (i = 0; i < AST_MAX_FDS11; i++) {
2274 if (ast_channel_internal_epfd_data(chan, i)) {
2275 ast_freefree(ast_channel_internal_epfd_data(chan, i));
2276 }
2277 }
2278 close(ast_channel_epfd(chan));
2279#endif
2280 while ((f = AST_LIST_REMOVE_HEAD(ast_channel_readq(chan), frame_list)({ typeof((ast_channel_readq(chan))->first) __cur = (ast_channel_readq
(chan))->first; if (__cur) { (ast_channel_readq(chan))->
first = __cur->frame_list.next; __cur->frame_list.next =
((void*)0); if ((ast_channel_readq(chan))->last == __cur)
(ast_channel_readq(chan))->last = ((void*)0); } __cur; })
))
2281 ast_frfree(f)ast_frame_free(f, 1);
2282
2283 /* loop over the variables list, freeing all data and deleting list items */
2284 /* no need to lock the list, as the channel is already locked */
2285 headp = ast_channel_varshead(chan);
2286 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)({ typeof((headp)->first) __cur = (headp)->first; if (__cur
) { (headp)->first = __cur->entries.next; __cur->entries
.next = ((void*)0); if ((headp)->last == __cur) (headp)->
last = ((void*)0); } __cur; })
))
2287 ast_var_delete(vardata);
2288
2289 ast_app_group_discard(chan);
2290
2291 /* Destroy the jitterbuffer */
2292 ast_jb_destroy(chan);
2293
2294 if (ast_channel_cdr(chan)) {
2295 ast_cdr_free(ast_channel_cdr(chan));
2296 ast_channel_cdr_set(chan, NULL((void*)0));
2297 }
2298
2299 if (ast_channel_zone(chan)) {
2300 ast_channel_zone_set(chan, ast_tone_zone_unref(ast_channel_zone(chan)));
2301 }
2302
2303 ast_channel_internal_cleanup(chan);
2304
2305 if (device_name[0]) {
2306 /*
2307 * We have a device name to notify of a new state.
2308 *
2309 * Queue an unknown state, because, while we know that this particular
2310 * instance is dead, we don't know the state of all other possible
2311 * instances.
2312 */
2313 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_DISABLE_DEVSTATE_CACHE)); })
? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), device_name);
2314 }
2315
2316 ast_channel_nativeformats_set(chan, NULL((void*)0));
2317
2318 ast_channel_named_callgroups_set(chan, NULL((void*)0));
2319 ast_channel_named_pickupgroups_set(chan, NULL((void*)0));
2320
2321 ast_atomic_fetchadd_int(&chancount, -1);
2322}
2323
2324/*! \brief Free a dummy channel structure */
2325static void ast_dummy_channel_destructor(void *obj)
2326{
2327 struct ast_channel *chan = obj;
2328 struct ast_datastore *datastore;
2329 struct ast_var_t *vardata;
2330 struct varshead *headp;
2331
2332 ast_pbx_hangup_handler_destroy(chan);
2333
2334 /* Get rid of each of the data stores on the channel */
2335 while ((datastore = AST_LIST_REMOVE_HEAD(ast_channel_datastores(chan), entry)({ typeof((ast_channel_datastores(chan))->first) __cur = (
ast_channel_datastores(chan))->first; if (__cur) { (ast_channel_datastores
(chan))->first = __cur->entry.next; __cur->entry.next
= ((void*)0); if ((ast_channel_datastores(chan))->last ==
__cur) (ast_channel_datastores(chan))->last = ((void*)0);
} __cur; })
)) {
2336 /* Free the data store */
2337 ast_datastore_free(datastore);
2338 }
2339
2340 ast_party_dialed_free(ast_channel_dialed(chan));
2341 ast_party_caller_free(ast_channel_caller(chan));
2342 ast_party_connected_line_free(ast_channel_connected(chan));
2343 ast_party_connected_line_free(ast_channel_connected_indicated(chan));
2344 ast_party_redirecting_free(ast_channel_redirecting(chan));
2345
2346 /* loop over the variables list, freeing all data and deleting list items */
2347 /* no need to lock the list, as the channel is already locked */
2348 headp = ast_channel_varshead(chan);
2349 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)({ typeof((headp)->first) __cur = (headp)->first; if (__cur
) { (headp)->first = __cur->entries.next; __cur->entries
.next = ((void*)0); if ((headp)->last == __cur) (headp)->
last = ((void*)0); } __cur; })
))
2350 ast_var_delete(vardata);
2351
2352 if (ast_channel_cdr(chan)) {
2353 ast_cdr_free(ast_channel_cdr(chan));
2354 ast_channel_cdr_set(chan, NULL((void*)0));
2355 }
2356
2357 ast_channel_internal_cleanup(chan);
2358}
2359
2360struct ast_datastore *ast_channel_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
2361{
2362 return ast_datastore_alloc(info, uid)__ast_datastore_alloc(info, uid, "channel.c", 2362, __PRETTY_FUNCTION__
)
;
2363}
2364
2365int ast_channel_datastore_free(struct ast_datastore *datastore)
2366{
2367 return ast_datastore_free(datastore);
2368}
2369
2370int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
2371{
2372 struct ast_datastore *datastore = NULL((void*)0), *datastore2;
2373
2374 AST_LIST_TRAVERSE(ast_channel_datastores(from), datastore, entry)for((datastore) = (ast_channel_datastores(from))->first; (
datastore); (datastore) = (datastore)->entry.next)
{
2375 if (datastore->inheritance > 0) {
2376 datastore2 = ast_datastore_alloc(datastore->info, datastore->uid)__ast_datastore_alloc(datastore->info, datastore->uid, "channel.c"
, 2376, __PRETTY_FUNCTION__)
;
2377 if (datastore2) {
2378 datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL((void*)0);
2379 datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER2147483647 ? DATASTORE_INHERIT_FOREVER2147483647 : datastore->inheritance - 1;
2380 AST_LIST_INSERT_TAIL(ast_channel_datastores(to), datastore2, entry)do { if (!(ast_channel_datastores(to))->first) { (ast_channel_datastores
(to))->first = (datastore2); (ast_channel_datastores(to))->
last = (datastore2); } else { (ast_channel_datastores(to))->
last->entry.next = (datastore2); (ast_channel_datastores(to
))->last = (datastore2); } } while (0)
;
2381 }
2382 }
2383 }
2384 return 0;
2385}
2386
2387int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
2388{
2389 int res = 0;
2390
2391 AST_LIST_INSERT_HEAD(ast_channel_datastores(chan), datastore, entry)do { (datastore)->entry.next = (ast_channel_datastores(chan
))->first; (ast_channel_datastores(chan))->first = (datastore
); if (!(ast_channel_datastores(chan))->last) (ast_channel_datastores
(chan))->last = (datastore); } while (0)
;
2392
2393 return res;
2394}
2395
2396int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
2397{
2398 return AST_LIST_REMOVE(ast_channel_datastores(chan), datastore, entry)({ __typeof(datastore) __elm = (datastore); if (__elm) { if (
(ast_channel_datastores(chan))->first == __elm) { (ast_channel_datastores
(chan))->first = __elm->entry.next; __elm->entry.next
= ((void*)0); if ((ast_channel_datastores(chan))->last ==
__elm) { (ast_channel_datastores(chan))->last = ((void*)0
); } } else { typeof(datastore) __prev = (ast_channel_datastores
(chan))->first; while (__prev && __prev->entry.
next != __elm) { __prev = __prev->entry.next; } if (__prev
) { __prev->entry.next = __elm->entry.next; __elm->entry
.next = ((void*)0); if ((ast_channel_datastores(chan))->last
== __elm) { (ast_channel_datastores(chan))->last = __prev
; } } else { __elm = ((void*)0); } } } __elm; })
? 0 : -1;
2399}
2400
2401struct ast_datastore *ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
2402{
2403 struct ast_datastore *datastore = NULL((void*)0);
2404
2405 if (info == NULL((void*)0))
2406 return NULL((void*)0);
2407
2408 AST_LIST_TRAVERSE(ast_channel_datastores(chan), datastore, entry)for((datastore) = (ast_channel_datastores(chan))->first; (
datastore); (datastore) = (datastore)->entry.next)
{
2409 if (datastore->info != info) {
2410 continue;
2411 }
2412
2413 if (uid == NULL((void*)0)) {
2414 /* matched by type only */
2415 break;
2416 }
2417
2418 if ((datastore->uid != NULL((void*)0)) && !strcasecmp(uid, datastore->uid)) {
2419 /* Matched by type AND uid */
2420 break;
2421 }
2422 }
2423
2424 return datastore;
2425}
2426
2427/*! Set the file descriptor on the channel */
2428void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
2429{
2430#ifdef HAVE_EPOLL
2431 struct epoll_event ev;
2432 struct ast_epoll_data *aed = NULL((void*)0);
2433
2434 if (ast_channel_fd_isset(chan, which)) {
2435 epoll_ctl(ast_channel_epfd(chan), EPOLL_CTL_DEL, ast_channel_fd(chan, which), &ev);
2436 aed = ast_channel_internal_epfd_data(chan, which);
2437 }
2438
2439 /* If this new fd is valid, add it to the epoll */
2440 if (fd > -1) {
2441 if (!aed && (!(aed = ast_calloc(1, sizeof(*aed))_ast_calloc((1), (sizeof(*aed)), "channel.c", 2441, __PRETTY_FUNCTION__
)
)))
2442 return;
2443
2444 ast_channel_internal_epfd_data_set(chan, which, aed);
2445 aed->chan = chan;
2446 aed->which = which;
2447
2448 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
2449 ev.data.ptr = aed;
2450 epoll_ctl(ast_channel_epfd(chan), EPOLL_CTL_ADD, fd, &ev);
2451 } else if (aed) {
2452 /* We don't have to keep around this epoll data structure now */
2453 ast_freefree(aed);
2454 ast_channel_epfd_data_set(chan, which, NULL((void*)0));
2455 }
2456#endif
2457 ast_channel_internal_fd_set(chan, which, fd);
2458 return;
2459}
2460
2461/*! Add a channel to an optimized waitfor */
2462void ast_poll_channel_add(struct ast_channel *chan0, struct ast_channel *chan1)
2463{
2464#ifdef HAVE_EPOLL
2465 struct epoll_event ev;
2466 int i = 0;
2467
2468 if (ast_channel_epfd(chan0) == -1)
2469 return;
2470
2471 /* Iterate through the file descriptors on chan1, adding them to chan0 */
2472 for (i = 0; i < AST_MAX_FDS11; i++) {
2473 if (!ast_channel_fd_isset(chan1, i)) {
2474 continue;
2475 }
2476 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
2477 ev.data.ptr = ast_channel_internal_epfd_data(chan1, i);
2478 epoll_ctl(ast_channel_epfd(chan0), EPOLL_CTL_ADD, ast_channel_fd(chan1, i), &ev);
2479 }
2480
2481#endif
2482 return;
2483}
2484
2485/*! Delete a channel from an optimized waitfor */
2486void ast_poll_channel_del(struct ast_channel *chan0, struct ast_channel *chan1)
2487{
2488#ifdef HAVE_EPOLL
2489 struct epoll_event ev;
2490 int i = 0;
2491
2492 if (ast_channel_epfd(chan0) == -1)
2493 return;
2494
2495 for (i = 0; i < AST_MAX_FDS11; i++) {
2496 if (!ast_channel_fd_isset(chan1, i)) {
2497 continue;
2498 }
2499 epoll_ctl(ast_channel_epfd(chan0), EPOLL_CTL_DEL, ast_channel_fd(chan1, i), &ev);
2500 }
2501
2502#endif
2503 return;
2504}
2505
2506void ast_channel_clear_softhangup(struct ast_channel *chan, int flag)
2507{
2508 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2508, "chan")
;
2509
2510 ast_channel_softhangup_internal_flag_clear(chan, flag);
2511
2512 if (!ast_channel_softhangup_internal_flag(chan)) {
2513 struct ast_frame *fr;
2514
2515 /* If we have completely cleared the softhangup flag,
2516 * then we need to fully abort the hangup process. This requires
2517 * pulling the END_OF_Q frame out of the channel frame queue if it
2518 * still happens to be there. */
2519
2520 fr = AST_LIST_LAST(ast_channel_readq(chan))((ast_channel_readq(chan))->last);
2521 if (fr && fr->frametype == AST_FRAME_CONTROL &&
2522 fr->subclass.integer == AST_CONTROL_END_OF_Q) {
2523 AST_LIST_REMOVE(ast_channel_readq(chan), fr, frame_list)({ __typeof(fr) __elm = (fr); if (__elm) { if ((ast_channel_readq
(chan))->first == __elm) { (ast_channel_readq(chan))->first
= __elm->frame_list.next; __elm->frame_list.next = ((void
*)0); if ((ast_channel_readq(chan))->last == __elm) { (ast_channel_readq
(chan))->last = ((void*)0); } } else { typeof(fr) __prev =
(ast_channel_readq(chan))->first; while (__prev &&
__prev->frame_list.next != __elm) { __prev = __prev->frame_list
.next; } if (__prev) { __prev->frame_list.next = __elm->
frame_list.next; __elm->frame_list.next = ((void*)0); if (
(ast_channel_readq(chan))->last == __elm) { (ast_channel_readq
(chan))->last = __prev; } } else { __elm = ((void*)0); } }
} __elm; })
;
2524 ast_frfree(fr)ast_frame_free(fr, 1);
2525 }
2526 }
2527
2528 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2528, "chan"
)
;
2529}
2530
2531/*! \brief Softly hangup a channel, don't lock */
2532int ast_softhangup_nolock(struct ast_channel *chan, int cause)
2533{
2534 ast_debug(1, "Soft-Hanging (%#04x) up channel '%s'\n", (unsigned)cause, ast_channel_name(chan))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 2534, __PRETTY_FUNCTION__, "Soft-Hanging (%#04x) up channel '%s'\n"
, (unsigned)cause, ast_channel_name(chan)); } } while (0)
;
2535 /* Inform channel driver that we need to be hung up, if it cares */
2536 ast_channel_softhangup_internal_flag_add(chan, cause);
2537 ast_queue_frame(chan, &ast_null_frame);
2538 /* Interrupt any poll call or such */
2539 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_BLOCKING)); })
)
2540 pthread_kill(ast_channel_blocker(chan), SIGURG23);
2541 return 0;
2542}
2543
2544/*! \brief Softly hangup a channel, lock */
2545int ast_softhangup(struct ast_channel *chan, int cause)
2546{
2547 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref)_raii_cleanup_block_t _raii_cleanup_blob __attribute__((cleanup
(_raii_cleanup_block),unused)) = ((void*)0); __attribute__((__blocks__
(byref))) struct ast_json * blob = ((void*)0); _raii_cleanup_blob
= ^{ {(void)ast_json_unref(blob);} }
;
2548 int res;
2549
2550 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2550, "chan")
;
2551 res = ast_softhangup_nolock(chan, cause);
2552 blob = ast_json_pack("{s: i, s: b}",
2553 "cause", cause,
2554 "soft", 1);
2555 ast_channel_publish_blob(chan, ast_channel_hangup_request_type(), blob);
2556 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2556, "chan"
)
;
2557
2558 return res;
2559}
2560
2561static void free_translation(struct ast_channel *clonechan)
2562{
2563 if (ast_channel_writetrans(clonechan)) {
2564 ast_translator_free_path(ast_channel_writetrans(clonechan));
2565 }
2566 if (ast_channel_readtrans(clonechan)) {
2567 ast_translator_free_path(ast_channel_readtrans(clonechan));
2568 }
2569 ast_channel_writetrans_set(clonechan, NULL((void*)0));
2570 ast_channel_readtrans_set(clonechan, NULL((void*)0));
2571}
2572
2573void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
2574{
2575 RAII_VAR(struct ast_channel *, bridge, ast_channel_bridge_peer(chan), ast_channel_cleanup)_raii_cleanup_block_t _raii_cleanup_bridge __attribute__((cleanup
(_raii_cleanup_block),unused)) = ((void*)0); __attribute__((__blocks__
(byref))) struct ast_channel * bridge = ast_channel_bridge_peer
(chan); _raii_cleanup_bridge = ^{ {(void)({ __ao2_cleanup_debug
((bridge), "", "channel.c", 2575, __PRETTY_FUNCTION__); (struct
ast_channel *) (((void*)0)); });} }
;
2576
2577 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2577, "chan")
;
2578 if (force || ast_strlen_zero(ast_channel_hangupsource(chan))_ast_strlen_zero(ast_channel_hangupsource(chan), "channel.c",
__PRETTY_FUNCTION__, 2578)
) {
2579 ast_channel_hangupsource_set(chan, source);
2580 }
2581 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2581, "chan"
)
;
2582
2583 if (bridge) {
2584 ast_channel_lock(bridge)__ao2_lock(bridge, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2584, "bridge")
;
2585 if (force || ast_strlen_zero(ast_channel_hangupsource(bridge))_ast_strlen_zero(ast_channel_hangupsource(bridge), "channel.c"
, __PRETTY_FUNCTION__, 2585)
) {
2586 ast_channel_hangupsource_set(bridge, source);
2587 }
2588 ast_channel_unlock(bridge)__ao2_unlock(bridge, "channel.c", __PRETTY_FUNCTION__, 2588, "bridge"
)
;
2589 }
2590}
2591
2592int ast_channel_has_audio_frame_or_monitor(struct ast_channel *chan)
2593{
2594 return ast_channel_monitor(chan)
2595 || !ast_audiohook_write_list_empty(ast_channel_audiohooks(chan))
2596 || !ast_framehook_list_contains_no_active(ast_channel_framehooks(chan));
2597}
2598
2599int ast_channel_has_hook_requiring_audio(struct ast_channel *chan)
2600{
2601 return ast_channel_monitor(chan)
2602 || !ast_audiohook_write_list_empty(ast_channel_audiohooks(chan))
2603 || !ast_framehook_list_contains_no_active_of_type(ast_channel_framehooks(chan), AST_FRAME_VOICE);
2604}
2605
2606static void destroy_hooks(struct ast_channel *chan)
2607{
2608 if (ast_channel_audiohooks(chan)) {
2609 ast_audiohook_detach_list(ast_channel_audiohooks(chan));
2610 ast_channel_audiohooks_set(chan, NULL((void*)0));
2611 }
2612
2613 ast_framehook_list_destroy(chan);
2614}
2615
2616/*! \brief Hangup a channel */
2617void ast_hangup(struct ast_channel *chan)
2618{
2619 /* Be NULL safe for RAII_VAR() usage. */
2620 if (!chan) {
2621 return;
2622 }
2623
2624 ast_autoservice_stop(chan);
2625
2626 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2626, "chan")
;
2627
2628 while (ast_channel_masq(chan) || ast_channel_masqr(chan)) {
2629 CHANNEL_DEADLOCK_AVOIDANCE(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2629, "chan"
); usleep(1); __ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c"
, __PRETTY_FUNCTION__, 2629, "chan");
;
2630 }
2631
2632 /* Mark as a zombie so a masquerade cannot be setup on this channel. */
2633 ast_set_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags |= (AST_FLAG_ZOMBIE)); } while(0)
;
2634
2635 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2635, "chan"
)
;
2636
2637 /*
2638 * XXX if running the hangup handlers here causes problems
2639 * because the handlers take too long to execute, we could move
2640 * the meat of this function into another thread. A thread
2641 * where channels go to die.
2642 *
2643 * If this is done, ast_autoservice_chan_hangup_peer() will no
2644 * longer be needed.
2645 */
2646 ast_pbx_hangup_handler_run(chan);
2647 ao2_unlink(channels, chan)__ao2_unlink((channels), (chan), 0, "", "channel.c", 2647, __PRETTY_FUNCTION__
)
;
2648 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2648, "chan")
;
2649
2650 destroy_hooks(chan);
2651
2652 free_translation(chan);
2653 /* Close audio stream */
2654 if (ast_channel_stream(chan)) {
2655 ast_closestream(ast_channel_stream(chan));
2656 ast_channel_stream_set(chan, NULL((void*)0));
2657 }
2658 /* Close video stream */
2659 if (ast_channel_vstream(chan)) {
2660 ast_closestream(ast_channel_vstream(chan));
2661 ast_channel_vstream_set(chan, NULL((void*)0));
2662 }
2663 if (ast_channel_sched(chan)) {
2664 ast_sched_context_destroy(ast_channel_sched(chan));
2665 ast_channel_sched_set(chan, NULL((void*)0));
2666 }
2667
2668 if (ast_channel_generatordata(chan)) { /* Clear any tone stuff remaining */
2669 if (ast_channel_generator(chan) && ast_channel_generator(chan)->release) {
2670 ast_channel_generator(chan)->release(chan, ast_channel_generatordata(chan));
2671 }
2672 }
2673 ast_channel_generatordata_set(chan, NULL((void*)0));
2674 ast_channel_generator_set(chan, NULL((void*)0));
2675
2676 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_BLOCKING)); })
) {
2677 ast_log(LOG_WARNING3, "channel.c", 2677, __PRETTY_FUNCTION__, "Hard hangup called by thread %ld on %s, while fd "
2678 "is blocked by thread %ld in procedure %s! Expect a failure\n",
2679 (long) pthread_self(), ast_channel_name(chan), (long)ast_channel_blocker(chan), ast_channel_blockproc(chan));
2680 ast_assert(ast_test_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING) == 0)_ast_assert(({ typeof ((ast_channel_flags(chan))->flags) __p
= (ast_channel_flags(chan))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(chan))->flags & (AST_FLAG_BLOCKING)); }) == 0, "ast_test_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING) == 0"
, "channel.c", 2680, __PRETTY_FUNCTION__)
;
2681 }
2682
2683 ast_debug(1, "Hanging up channel '%s'\n", ast_channel_name(chan))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 2683, __PRETTY_FUNCTION__, "Hanging up channel '%s'\n"
, ast_channel_name(chan)); } } while (0)
;
2684 if (ast_channel_tech(chan)->hangup) {
2685 ast_channel_tech(chan)->hangup(chan);
2686 }
2687
2688 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2688, "chan"
)
;
2689
2690 ast_cc_offer(chan);
2691
2692 ast_channel_unref(chan)({ __ao2_ref((chan), (-1), "", "channel.c", 2692, __PRETTY_FUNCTION__
); (struct ast_channel *) (((void*)0)); })
;
2693}
2694
2695int ast_raw_answer(struct ast_channel *chan)
2696{
2697 int res = 0;
2698 struct timeval answertime;
2699
2700 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2700, "chan")
;
2701
2702 /* You can't answer an outbound call */
2703 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_OUTGOING)); })
) {
2704 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2704, "chan"
)
;
2705 return 0;
2706 }
2707
2708 /* Stop if we're a zombie or need a soft hangup */
2709 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_ZOMBIE)); })
|| ast_check_hangup(chan)) {
2710 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2710, "chan"
)
;
2711 return -1;
2712 }
2713
2714 answertime = ast_tvnow();
2715 ast_channel_answertime_set(chan, &answertime);
2716
2717 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2717, "chan"
)
;
2718
2719 switch (ast_channel_state(chan)) {
2720 case AST_STATE_RINGING:
2721 case AST_STATE_RING:
2722 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2722, "chan")
;
2723 if (ast_channel_tech(chan)->answer) {
2724 res = ast_channel_tech(chan)->answer(chan);
2725 }
2726 ast_setstate(chan, AST_STATE_UP);
2727 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2727, "chan"
)
;
2728 break;
2729 case AST_STATE_UP:
2730 break;
2731 default:
2732 break;
2733 }
2734
2735 ast_indicate(chan, -1);
2736
2737 return res;
2738}
2739
2740int __ast_answer(struct ast_channel *chan, unsigned int delay)
2741{
2742 int res = 0;
2743 enum ast_channel_state old_state;
2744
2745 old_state = ast_channel_state(chan);
2746 if ((res = ast_raw_answer(chan))) {
2747 return res;
2748 }
2749
2750 switch (old_state) {
2751 case AST_STATE_RINGING:
2752 case AST_STATE_RING:
2753 /* wait for media to start flowing, but don't wait any longer
2754 * than 'delay' or 500 milliseconds, whichever is longer
2755 */
2756 do {
2757 AST_LIST_HEAD_NOLOCK(, ast_frame)struct { struct ast_frame *first; struct ast_frame *last; } frames;
2758 struct ast_frame *cur;
2759 struct ast_frame *new_frame;
2760 int timeout_ms = MAX(delay, 500)({ typeof(delay) __a = (delay); typeof(500) __b = (500); ((__a
< __b) ? __b : __a);})
;
2761 unsigned int done = 0;
2762 struct timeval start;
2763
2764 AST_LIST_HEAD_INIT_NOLOCK(&frames){ (&frames)->first = ((void*)0); (&frames)->last
= ((void*)0); }
;
2765
2766 start = ast_tvnow();
2767 for (;;) {
2768 int ms = ast_remaining_ms(start, timeout_ms);
2769 ms = ast_waitfor(chan, ms);
2770 if (ms < 0) {
2771 ast_log(LOG_WARNING3, "channel.c", 2771, __PRETTY_FUNCTION__, "Error condition occurred when polling channel %s for a voice frame: %s\n", ast_channel_name(chan), strerror(errno(*__errno_location ())));
2772 res = -1;
2773 break;
2774 }
2775 if (ms == 0) {
2776 ast_debug(2, "Didn't receive a media frame from %s within %u ms of answering. Continuing anyway\n", ast_channel_name(chan), MAX(delay, 500))do { if ((option_debug >= (2) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (2)))) { ast_log(0,
"channel.c", 2776, __PRETTY_FUNCTION__, "Didn't receive a media frame from %s within %u ms of answering. Continuing anyway\n"
, ast_channel_name(chan), ({ typeof(delay) __a = (delay); typeof
(500) __b = (500); ((__a < __b) ? __b : __a);})); } } while
(0)
;
2777 break;
2778 }
2779 cur = ast_read(chan);
2780 if (!cur || ((cur->frametype == AST_FRAME_CONTROL) &&
2781 (cur->subclass.integer == AST_CONTROL_HANGUP))) {
2782 if (cur) {
2783 ast_frfree(cur)ast_frame_free(cur, 1);
2784 }
2785 res = -1;
2786 ast_debug(2, "Hangup of channel %s detected in answer routine\n", ast_channel_name(chan))do { if ((option_debug >= (2) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (2)))) { ast_log(0,
"channel.c", 2786, __PRETTY_FUNCTION__, "Hangup of channel %s detected in answer routine\n"
, ast_channel_name(chan)); } } while (0)
;
2787 break;
2788 }
2789
2790 if ((new_frame = ast_frisolate(cur)) != cur) {
2791 ast_frfree(cur)ast_frame_free(cur, 1);
2792 }
2793
2794 AST_LIST_INSERT_HEAD(&frames, new_frame, frame_list)do { (new_frame)->frame_list.next = (&frames)->first
; (&frames)->first = (new_frame); if (!(&frames)->
last) (&frames)->last = (new_frame); } while (0)
;
2795
2796 /* if a specific delay period was requested, continue
2797 * until that delay has passed. don't stop just because
2798 * incoming media has arrived.
2799 */
2800 if (delay) {
2801 continue;
2802 }
2803
2804 switch (new_frame->frametype) {
2805 /* all of these frametypes qualify as 'media' */
2806 case AST_FRAME_VOICE:
2807 case AST_FRAME_VIDEO:
2808 case AST_FRAME_TEXT:
2809 case AST_FRAME_DTMF_BEGIN:
2810 case AST_FRAME_DTMF_END:
2811 case AST_FRAME_IMAGE:
2812 case AST_FRAME_HTML:
2813 case AST_FRAME_MODEM:
2814 done = 1;
2815 break;
2816 case AST_FRAME_CONTROL:
2817 case AST_FRAME_IAX:
2818 case AST_FRAME_BRIDGE_ACTION:
2819 case AST_FRAME_BRIDGE_ACTION_SYNC:
2820 case AST_FRAME_NULL:
2821 case AST_FRAME_CNG:
2822 break;
2823 }
2824
2825 if (done) {
2826 break;
2827 }
2828 }
2829
2830 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2830, "chan")
;
2831 while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list)({ typeof((&frames)->first) __cur = (&frames)->
first; if (__cur) { (&frames)->first = __cur->frame_list
.next; __cur->frame_list.next = ((void*)0); if ((&frames
)->last == __cur) (&frames)->last = ((void*)0); } __cur
; })
)) {
2832 if (res == 0) {
2833 ast_queue_frame_head(chan, cur);
2834 }
2835 ast_frfree(cur)ast_frame_free(cur, 1);
2836 }
2837 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2837, "chan"
)
;
2838 } while (0);
2839 break;
2840 default:
2841 break;
2842 }
2843
2844 return res;
2845}
2846
2847int ast_answer(struct ast_channel *chan)
2848{
2849 return __ast_answer(chan, 0);
2850}
2851
2852inline int ast_auto_answer(struct ast_channel *chan)
2853{
2854 if (ast_channel_state(chan) == AST_STATE_UP) {
2855 /* Already answered */
2856 return 0;
2857 }
2858 return ast_answer(chan);
2859}
2860
2861int ast_channel_get_duration(struct ast_channel *chan)
2862{
2863 ast_assert(NULL != chan)_ast_assert(((void*)0) != chan, "NULL != chan", "channel.c", 2863
, __PRETTY_FUNCTION__)
;
2864
2865 if (ast_tvzero(ast_channel_creationtime(chan))) {
2866 return 0;
2867 }
2868 return (ast_tvdiff_ms(ast_tvnow(), ast_channel_creationtime(chan)) / 1000);
2869}
2870
2871int ast_channel_get_up_time(struct ast_channel *chan)
2872{
2873 ast_assert(NULL != chan)_ast_assert(((void*)0) != chan, "NULL != chan", "channel.c", 2873
, __PRETTY_FUNCTION__)
;
2874
2875 if (ast_tvzero(ast_channel_answertime(chan))) {
2876 return 0;
2877 }
2878 return (ast_tvdiff_ms(ast_tvnow(), ast_channel_answertime(chan)) / 1000);
2879}
2880
2881static void deactivate_generator_nolock(struct ast_channel *chan)
2882{
2883 if (ast_channel_generatordata(chan)) {
2884 struct ast_generator *generator = ast_channel_generator(chan);
2885
2886 if (generator && generator->release) {
2887 generator->release(chan, ast_channel_generatordata(chan));
2888 }
2889 ast_channel_generatordata_set(chan, NULL((void*)0));
2890 ast_channel_generator_set(chan, NULL((void*)0));
2891 ast_channel_set_fd(chan, AST_GENERATOR_FD(11 -4), -1);
2892 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_WRITE_INT)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags &= ~(AST_FLAG_WRITE_INT)); } while(0)
;
2893 ast_settimeout(chan, 0, NULL((void*)0), NULL((void*)0));
2894 }
2895}
2896
2897void ast_deactivate_generator(struct ast_channel *chan)
2898{
2899 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2899, "chan")
;
2900 deactivate_generator_nolock(chan);
2901 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2901, "chan"
)
;
2902}
2903
2904static void generator_write_format_change(struct ast_channel *chan)
2905{
2906 struct ast_generator *generator;
2907
2908 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2908, "chan")
;
2909 generator = ast_channel_generator(chan);
2910 if (generator && generator->write_format_change) {
2911 generator->write_format_change(chan, ast_channel_generatordata(chan));
2912 }
2913 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2913, "chan"
)
;
2914}
2915
2916static int generator_force(const void *data)
2917{
2918 /* Called if generator doesn't have data */
2919 void *tmp;
2920 int res;
2921 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL((void*)0);
2922 struct ast_channel *chan = (struct ast_channel *)data;
2923
2924 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2924, "chan")
;
2925 tmp = ast_channel_generatordata(chan);
2926 ast_channel_generatordata_set(chan, NULL((void*)0));
2927 if (ast_channel_generator(chan))
2928 generate = ast_channel_generator(chan)->generate;
2929 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2929, "chan"
)
;
2930
2931 if (!tmp || !generate) {
2932 return 0;
2933 }
2934
2935 res = generate(chan, tmp, 0, ast_format_get_sample_rate(ast_channel_writeformat(chan)) / 50);
2936
2937 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2937, "chan")
;
2938 if (ast_channel_generator(chan) && generate == ast_channel_generator(chan)->generate) {
2939 ast_channel_generatordata_set(chan, tmp);
2940 }
2941 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2941, "chan"
)
;
2942
2943 if (res) {
2944 ast_debug(1, "Auto-deactivating generator\n")do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 2944, __PRETTY_FUNCTION__, "Auto-deactivating generator\n"
); } } while (0)
;
2945 ast_deactivate_generator(chan);
2946 }
2947
2948 return 0;
2949}
2950
2951int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
2952{
2953 int res = 0;
2954 void *generatordata = NULL((void*)0);
2955
2956 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 2956, "chan")
;
2957 if (ast_channel_generatordata(chan)) {
2958 struct ast_generator *generator_old = ast_channel_generator(chan);
2959
2960 if (generator_old && generator_old->release) {
2961 generator_old->release(chan, ast_channel_generatordata(chan));
2962 }
2963 }
2964 if (gen->alloc && !(generatordata = gen->alloc(chan, params))) {
2965 res = -1;
2966 }
2967 ast_channel_generatordata_set(chan, generatordata);
2968 if (!res) {
2969 ast_settimeout(chan, 50, generator_force, chan);
2970 ast_channel_generator_set(chan, gen);
2971 }
2972 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 2972, "chan"
)
;
2973
2974 ast_prod(chan);
2975
2976 return res;
2977}
2978
2979/*! \brief Wait for x amount of time on a file descriptor to have input. */
2980int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
2981{
2982 int winner = -1;
2983 ast_waitfor_nandfds(NULL((void*)0), 0, fds, n, exception, &winner, ms);
2984 return winner;
2985}
2986
2987/*! \brief Wait for x amount of time on a file descriptor to have input. */
2988#ifdef HAVE_EPOLL
2989static struct ast_channel *ast_waitfor_nandfds_classic(struct ast_channel **c, int n, int *fds, int nfds,
2990 int *exception, int *outfd, int *ms)
2991#else
2992struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
2993 int *exception, int *outfd, int *ms)
2994#endif
2995{
2996 struct timeval start = { 0 , 0 };
2997 struct pollfd *pfds = NULL((void*)0);
2998 int res;
2999 long rms;
3000 int x, y, max;
3001 int sz;
3002 struct timeval now = { 0, 0 };
3003 struct timeval whentohangup = { 0, 0 }, diff;
3004 struct ast_channel *winner = NULL((void*)0);
3005 struct fdmap {
3006 int chan;
3007 int fdno;
3008 } *fdmap = NULL((void*)0);
3009
3010 if (outfd) {
3011 *outfd = -99999;
3012 }
3013 if (exception) {
3014 *exception = 0;
3015 }
3016
3017 if ((sz = n * AST_MAX_FDS11 + nfds)) {
3018 pfds = ast_alloca(sizeof(*pfds) * sz)__builtin_alloca(sizeof(*pfds) * sz);
3019 fdmap = ast_alloca(sizeof(*fdmap) * sz)__builtin_alloca(sizeof(*fdmap) * sz);
3020 } else {
3021 /* nothing to allocate and no FDs to check */
3022 return NULL((void*)0);
3023 }
3024
3025 for (x = 0; x < n; x++) {
3026 ast_channel_lock(c[x])__ao2_lock(c[x], AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 3026, "c[x]")
;
3027 if (!ast_tvzero(*ast_channel_whentohangup(c[x]))) {
3028 if (ast_tvzero(whentohangup))
3029 now = ast_tvnow();
3030 diff = ast_tvsub(*ast_channel_whentohangup(c[x]), now);
3031 if (diff.tv_sec < 0 || ast_tvzero(diff)) {
3032 ast_test_suite_event_notify("HANGUP_TIME", "Channel: %s", ast_channel_name(c[x]));
3033 /* Should already be hungup */
3034 ast_channel_softhangup_internal_flag_add(c[x], AST_SOFTHANGUP_TIMEOUT);
3035 ast_channel_unlock(c[x])__ao2_unlock(c[x], "channel.c", __PRETTY_FUNCTION__, 3035, "c[x]"
)
;
3036 return c[x];
3037 }
3038 if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0)
3039 whentohangup = diff;
3040 }
3041 ast_channel_unlock(c[x])__ao2_unlock(c[x], "channel.c", __PRETTY_FUNCTION__, 3041, "c[x]"
)
;
3042 }
3043 /* Wait full interval */
3044 rms = *ms;
3045 /* INT_MAX, not LONG_MAX, because it matters on 64-bit */
3046 if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX2147483647 / 1000) {
3047 rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000; /* timeout in milliseconds */
3048 if (*ms >= 0 && *ms < rms) { /* original *ms still smaller */
3049 rms = *ms;
3050 }
3051 } else if (!ast_tvzero(whentohangup) && rms < 0) {
3052 /* Tiny corner case... call would need to last >24 days */
3053 rms = INT_MAX2147483647;
3054 }
3055 /*
3056 * Build the pollfd array, putting the channels' fds first,
3057 * followed by individual fds. Order is important because
3058 * individual fd's must have priority over channel fds.
3059 */
3060 max = 0;
3061 for (x = 0; x < n; x++) {
3062 for (y = 0; y < AST_MAX_FDS11; y++) {
3063 fdmap[max].fdno = y; /* fd y is linked to this pfds */
3064 fdmap[max].chan = x; /* channel x is linked to this pfds */
3065 max += ast_add_fd(&pfds[max], ast_channel_fd(c[x], y));
3066 }
3067 CHECK_BLOCKING(c[x])do { if (({ typeof ((ast_channel_flags(c[x]))->flags) __p =
(ast_channel_flags(c[x]))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(c[x]))->flags & (AST_FLAG_BLOCKING)); })) { do { if (
(option_debug >= (1) || (({ typeof ((&ast_options)->
flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 3067, __PRETTY_FUNCTION__, "Thread %p is blocking '%s', already blocked by thread %p in procedure %s\n"
, (void *) pthread_self(), ast_channel_name(c[x]), (void *) ast_channel_blocker
(c[x]), ast_channel_blockproc(c[x])); } } while (0); } else {
ast_channel_blocker_set((c[x]), pthread_self()); ast_channel_blockproc_set
((c[x]), __PRETTY_FUNCTION__); do { typeof ((ast_channel_flags
(c[x]))->flags) __p = (ast_channel_flags(c[x]))->flags;
typeof (__unsigned_int_flags_dummy) __x = 0; (void) (&__p
== &__x); ((ast_channel_flags(c[x]))->flags |= (AST_FLAG_BLOCKING
)); } while(0); } } while (0)
;
3068 }
3069 /* Add the individual fds */
3070 for (x = 0; x < nfds; x++) {
3071 fdmap[max].chan = -1;
3072 max += ast_add_fd(&pfds[max], fds[x]);
3073 }
3074
3075 if (*ms > 0) {
3076 start = ast_tvnow();
3077 }
3078
3079 if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */
3080 do {
3081 int kbrms = rms;
3082 if (kbrms > 600000) {
3083 kbrms = 600000;
3084 }
3085 res = ast_poll(pfds, max, kbrms)poll(pfds, max, kbrms);
3086 if (!res) {
3087 rms -= kbrms;
3088 }
3089 } while (!res && (rms > 0));
3090 } else {
3091 res = ast_poll(pfds, max, rms)poll(pfds, max, rms);
3092 }
3093 for (x = 0; x < n; x++) {
3094 ast_clear_flag(ast_channel_flags(c[x]), AST_FLAG_BLOCKING)do { typeof ((ast_channel_flags(c[x]))->flags) __p = (ast_channel_flags
(c[x]))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(c[x]))->
flags &= ~(AST_FLAG_BLOCKING)); } while(0)
;
3095 }
3096 if (res < 0) { /* Simulate a timeout if we were interrupted */
3097 if (errno(*__errno_location ()) != EINTR4) {
3098 *ms = -1;
3099 }
3100 return NULL((void*)0);
3101 }
3102 if (!ast_tvzero(whentohangup)) { /* if we have a timeout, check who expired */
3103 now = ast_tvnow();
3104 for (x = 0; x < n; x++) {
3105 if (!ast_tvzero(*ast_channel_whentohangup(c[x])) && ast_tvcmp(*ast_channel_whentohangup(c[x]), now) <= 0) {
3106 ast_test_suite_event_notify("HANGUP_TIME", "Channel: %s", ast_channel_name(c[x]));
3107 ast_channel_softhangup_internal_flag_add(c[x], AST_SOFTHANGUP_TIMEOUT);
3108 if (winner == NULL((void*)0)) {
3109 winner = c[x];
3110 }
3111 }
3112 }
3113 }
3114 if (res == 0) { /* no fd ready, reset timeout and done */
3115 *ms = 0; /* XXX use 0 since we may not have an exact timeout. */
3116 return winner;
3117 }
3118 /*
3119 * Then check if any channel or fd has a pending event.
3120 * Remember to check channels first and fds last, as they
3121 * must have priority on setting 'winner'
3122 */
3123 for (x = 0; x < max; x++) {
3124 res = pfds[x].revents;
3125 if (res == 0) {
3126 continue;
3127 }
3128 if (fdmap[x].chan >= 0) { /* this is a channel */
3129 winner = c[fdmap[x].chan]; /* override previous winners */
3130 if (res & POLLPRI0x002) {
3131 ast_set_flag(ast_channel_flags(winner), AST_FLAG_EXCEPTION)do { typeof ((ast_channel_flags(winner))->flags) __p = (ast_channel_flags
(winner))->flags; typeof (__unsigned_int_flags_dummy) __x =
0; (void) (&__p == &__x); ((ast_channel_flags(winner
))->flags |= (AST_FLAG_EXCEPTION)); } while(0)
;
3132 } else {
3133 ast_clear_flag(ast_channel_flags(winner), AST_FLAG_EXCEPTION)do { typeof ((ast_channel_flags(winner))->flags) __p = (ast_channel_flags
(winner))->flags; typeof (__unsigned_int_flags_dummy) __x =
0; (void) (&__p == &__x); ((ast_channel_flags(winner
))->flags &= ~(AST_FLAG_EXCEPTION)); } while(0)
;
3134 }
3135 ast_channel_fdno_set(winner, fdmap[x].fdno);
3136 } else { /* this is an fd */
3137 if (outfd) {
3138 *outfd = pfds[x].fd;
3139 }
3140 if (exception) {
3141 *exception = (res & POLLPRI0x002) ? -1 : 0;
3142 }
3143 winner = NULL((void*)0);
3144 }
3145 }
3146 if (*ms > 0) {
3147 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
3148 if (*ms < 0) {
3149 *ms = 0;
3150 }
3151 }
3152 return winner;
3153}
3154
3155#ifdef HAVE_EPOLL
3156static struct ast_channel *ast_waitfor_nandfds_simple(struct ast_channel *chan, int *ms)
3157{
3158 struct timeval start = { 0 , 0 };
3159 int res = 0;
3160 struct epoll_event ev[1];
3161 long diff, rms = *ms;
3162 struct ast_channel *winner = NULL((void*)0);
3163 struct ast_epoll_data *aed = NULL((void*)0);
3164
3165 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 3165, "chan")
;
3166 /* Figure out their timeout */
3167 if (!ast_tvzero(*ast_channel_whentohangup(chan))) {
3168 if ((diff = ast_tvdiff_ms(*ast_channel_whentohangup(chan), ast_tvnow())) < 0) {
3169 /* They should already be hungup! */
3170 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_TIMEOUT);
3171 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 3171, "chan"
)
;
3172 return NULL((void*)0);
3173 }
3174 /* If this value is smaller then the current one... make it priority */
3175 if (rms > diff) {
3176 rms = diff;
3177 }
3178 }
3179
3180 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 3180, "chan"
)
;
3181
3182 /* Time to make this channel block... */
3183 CHECK_BLOCKING(chan)do { if (({ typeof ((ast_channel_flags(chan))->flags) __p =
(ast_channel_flags(chan))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(chan))->flags & (AST_FLAG_BLOCKING)); })) { do { if (
(option_debug >= (1) || (({ typeof ((&ast_options)->
flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 3183, __PRETTY_FUNCTION__, "Thread %p is blocking '%s', already blocked by thread %p in procedure %s\n"
, (void *) pthread_self(), ast_channel_name(chan), (void *) ast_channel_blocker
(chan), ast_channel_blockproc(chan)); } } while (0); } else {
ast_channel_blocker_set((chan), pthread_self()); ast_channel_blockproc_set
((chan), __PRETTY_FUNCTION__); do { typeof ((ast_channel_flags
(chan))->flags) __p = (ast_channel_flags(chan))->flags;
typeof (__unsigned_int_flags_dummy) __x = 0; (void) (&__p
== &__x); ((ast_channel_flags(chan))->flags |= (AST_FLAG_BLOCKING
)); } while(0); } } while (0)
;
3184
3185 if (*ms > 0) {
3186 start = ast_tvnow();
3187 }
3188
3189 /* We don't have to add any file descriptors... they are already added, we just have to wait! */
3190 res = epoll_wait(ast_channel_epfd(chan), ev, 1, rms);
3191
3192 /* Stop blocking */
3193 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags &= ~(AST_FLAG_BLOCKING)); } while(0)
;
3194
3195 /* Simulate a timeout if we were interrupted */
3196 if (res < 0) {
3197 if (errno(*__errno_location ()) != EINTR4) {
3198 *ms = -1;
3199 }
3200 return NULL((void*)0);
3201 }
3202
3203 /* If this channel has a timeout see if it expired */
3204 if (!ast_tvzero(*ast_channel_whentohangup(chan))) {
3205 if (ast_tvdiff_ms(ast_tvnow(), *ast_channel_whentohangup(chan)) >= 0) {
3206 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_TIMEOUT);
3207 winner = chan;
3208 }
3209 }
3210
3211 /* No fd ready, reset timeout and be done for now */
3212 if (!res) {
3213 *ms = 0;
3214 return winner;
3215 }
3216
3217 /* See what events are pending */
3218 aed = ev[0].data.ptr;
3219 ast_channel_fdno_set(chan, aed->which);
3220 if (ev[0].events & EPOLLPRI) {
3221 ast_set_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags |= (AST_FLAG_EXCEPTION)); } while(0)
;
3222 } else {
3223 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags &= ~(AST_FLAG_EXCEPTION)); } while(0)
;
3224 }
3225
3226 if (*ms > 0) {
3227 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
3228 if (*ms < 0) {
3229 *ms = 0;
3230 }
3231 }
3232
3233 return chan;
3234}
3235
3236static struct ast_channel *ast_waitfor_nandfds_complex(struct ast_channel **c, int n, int *ms)
3237{
3238 struct timeval start = { 0 , 0 };
3239 int res = 0, i;
3240 struct epoll_event ev[25] = { { 0, } };
3241 struct timeval now = { 0, 0 };
3242 long whentohangup = 0, diff = 0, rms = *ms;
3243 struct ast_channel *winner = NULL((void*)0);
3244
3245 for (i = 0; i < n; i++) {
3246 ast_channel_lock(c[i])__ao2_lock(c[i], AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 3246, "c[i]")
;
3247 if (!ast_tvzero(*ast_channel_whentohangup(c[i]))) {
3248 if (whentohangup == 0) {
3249 now = ast_tvnow();
3250 }
3251 if ((diff = ast_tvdiff_ms(*ast_channel_whentohangup(c[i]), now)) < 0) {
3252 ast_channel_softhangup_internal_flag_add(c[i], AST_SOFTHANGUP_TIMEOUT);
3253 ast_channel_unlock(c[i])__ao2_unlock(c[i], "channel.c", __PRETTY_FUNCTION__, 3253, "c[i]"
)
;
3254 return c[i];
3255 }
3256 if (!whentohangup || whentohangup > diff) {
3257 whentohangup = diff;
3258 }
3259 }
3260 ast_channel_unlock(c[i])__ao2_unlock(c[i], "channel.c", __PRETTY_FUNCTION__, 3260, "c[i]"
)
;
3261 CHECK_BLOCKING(c[i])do { if (({ typeof ((ast_channel_flags(c[i]))->flags) __p =
(ast_channel_flags(c[i]))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(c[i]))->flags & (AST_FLAG_BLOCKING)); })) { do { if (
(option_debug >= (1) || (({ typeof ((&ast_options)->
flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 3261, __PRETTY_FUNCTION__, "Thread %p is blocking '%s', already blocked by thread %p in procedure %s\n"
, (void *) pthread_self(), ast_channel_name(c[i]), (void *) ast_channel_blocker
(c[i]), ast_channel_blockproc(c[i])); } } while (0); } else {
ast_channel_blocker_set((c[i]), pthread_self()); ast_channel_blockproc_set
((c[i]), __PRETTY_FUNCTION__); do { typeof ((ast_channel_flags
(c[i]))->flags) __p = (ast_channel_flags(c[i]))->flags;
typeof (__unsigned_int_flags_dummy) __x = 0; (void) (&__p
== &__x); ((ast_channel_flags(c[i]))->flags |= (AST_FLAG_BLOCKING
)); } while(0); } } while (0)
;
3262 }
3263
3264 rms = *ms;
3265 if (whentohangup) {
3266 rms = whentohangup;
3267 if (*ms >= 0 && *ms < rms) {
3268 rms = *ms;
3269 }
3270 }
3271
3272 if (*ms > 0) {
3273 start = ast_tvnow();
3274 }
3275
3276 res = epoll_wait(ast_channel_epfd(c[0]), ev, 25, rms);
3277
3278 for (i = 0; i < n; i++) {
3279 ast_clear_flag(ast_channel_flags(c[i]), AST_FLAG_BLOCKING)do { typeof ((ast_channel_flags(c[i]))->flags) __p = (ast_channel_flags
(c[i]))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(c[i]))->
flags &= ~(AST_FLAG_BLOCKING)); } while(0)
;
3280 }
3281
3282 if (res < 0) {
3283 if (errno(*__errno_location ()) != EINTR4) {
3284 *ms = -1;
3285 }
3286 return NULL((void*)0);
3287 }
3288
3289 if (whentohangup) {
3290 now = ast_tvnow();
3291 for (i = 0; i < n; i++) {
3292 if (!ast_tvzero(*ast_channel_whentohangup(c[i])) && ast_tvdiff_ms(now, *ast_channel_whentohangup(c[i])) >= 0) {
3293 ast_channel_softhangup_internal_flag_add(c[i], AST_SOFTHANGUP_TIMEOUT);
3294 if (!winner) {
3295 winner = c[i];
3296 }
3297 }
3298 }
3299 }
3300
3301 if (!res) {
3302 *ms = 0;
3303 return winner;
3304 }
3305
3306 for (i = 0; i < res; i++) {
3307 struct ast_epoll_data *aed = ev[i].data.ptr;
3308
3309 if (!ev[i].events || !aed) {
3310 continue;
3311 }
3312
3313 winner = aed->chan;
3314 if (ev[i].events & EPOLLPRI) {
3315 ast_set_flag(ast_channel_flags(winner), AST_FLAG_EXCEPTION)do { typeof ((ast_channel_flags(winner))->flags) __p = (ast_channel_flags
(winner))->flags; typeof (__unsigned_int_flags_dummy) __x =
0; (void) (&__p == &__x); ((ast_channel_flags(winner
))->flags |= (AST_FLAG_EXCEPTION)); } while(0)
;
3316 } else {
3317 ast_clear_flag(ast_channel_flags(winner), AST_FLAG_EXCEPTION)do { typeof ((ast_channel_flags(winner))->flags) __p = (ast_channel_flags
(winner))->flags; typeof (__unsigned_int_flags_dummy) __x =
0; (void) (&__p == &__x); ((ast_channel_flags(winner
))->flags &= ~(AST_FLAG_EXCEPTION)); } while(0)
;
3318 }
3319 ast_channel_fdno_set(winner, aed->which);
3320 }
3321
3322 if (*ms > 0) {
3323 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
3324 if (*ms < 0) {
3325 *ms = 0;
3326 }
3327 }
3328
3329 return winner;
3330}
3331
3332struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
3333 int *exception, int *outfd, int *ms)
3334{
3335 /* Clear all provided values in one place. */
3336 if (outfd) {
3337 *outfd = -99999;
3338 }
3339 if (exception) {
3340 *exception = 0;
3341 }
3342
3343 /* If no epoll file descriptor is available resort to classic nandfds */
3344 if (!n || nfds || ast_channel_epfd(c[0]) == -1) {
3345 return ast_waitfor_nandfds_classic(c, n, fds, nfds, exception, outfd, ms);
3346 } else if (!nfds && n == 1) {
3347 return ast_waitfor_nandfds_simple(c[0], ms);
3348 } else {
3349 return ast_waitfor_nandfds_complex(c, n, ms);
3350 }
3351}
3352#endif
3353
3354struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
3355{
3356 return ast_waitfor_nandfds(c, n, NULL((void*)0), 0, NULL((void*)0), NULL((void*)0), ms);
3357}
3358
3359int ast_waitfor(struct ast_channel *c, int ms)
3360{
3361 if (ms < 0) {
3362 do {
3363 ms = 100000;
3364 ast_waitfor_nandfds(&c, 1, NULL((void*)0), 0, NULL((void*)0), NULL((void*)0), &ms);
3365 } while (!ms);
3366 } else {
3367 ast_waitfor_nandfds(&c, 1, NULL((void*)0), 0, NULL((void*)0), NULL((void*)0), &ms);
3368 }
3369 return ms;
3370}
3371
3372int ast_waitfordigit(struct ast_channel *c, int ms)
3373{
3374 return ast_waitfordigit_full(c, ms, -1, -1);
3375}
3376
3377int ast_settimeout(struct ast_channel *c, unsigned int rate, int (*func)(const void *data), void *data)
3378{
3379 return ast_settimeout_full(c, rate, func, data, 0);
3380}
3381
3382int ast_settimeout_full(struct ast_channel *c, unsigned int rate, int (*func)(const void *data), void *data, unsigned int is_ao2_obj)
3383{
3384 int res;
3385 unsigned int real_rate = rate, max_rate;
3386
3387 ast_channel_lock(c)__ao2_lock(c, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 3387, "c")
;
3388
3389 if (ast_channel_timingfd(c) == -1) {
3390 ast_channel_unlock(c)__ao2_unlock(c, "channel.c", __PRETTY_FUNCTION__, 3390, "c");
3391 return -1;
3392 }
3393
3394 if (!func) {
3395 rate = 0;
3396 data = NULL((void*)0);
3397 }
3398
3399 if (rate && rate > (max_rate = ast_timer_get_max_rate(ast_channel_timer(c)))) {
3400 real_rate = max_rate;
3401 }
3402
3403 ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate)do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 3403, __PRETTY_FUNCTION__, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n"
, rate, real_rate); } } while (0)
;
3404
3405 res = ast_timer_set_rate(ast_channel_timer(c), real_rate);
3406
3407 if (ast_channel_timingdata(c) && ast_test_flag(ast_channel_flags(c), AST_FLAG_TIMINGDATA_IS_AO2_OBJ)({ typeof ((ast_channel_flags(c))->flags) __p = (ast_channel_flags
(c))->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (
void) (&__p == &__x); ((ast_channel_flags(c))->flags
& (AST_FLAG_TIMINGDATA_IS_AO2_OBJ)); })
) {
3408 ao2_ref(ast_channel_timingdata(c), -1)__ao2_ref((ast_channel_timingdata(c)), (-1), "", "channel.c",
3408, __PRETTY_FUNCTION__)
;
3409 }
3410
3411 ast_channel_timingfunc_set(c, func);
3412 ast_channel_timingdata_set(c, data);
3413
3414 if (data && is_ao2_obj) {
3415 ao2_ref(data, 1)__ao2_ref((data), (1), "", "channel.c", 3415, __PRETTY_FUNCTION__
)
;
3416 ast_set_flag(ast_channel_flags(c), AST_FLAG_TIMINGDATA_IS_AO2_OBJ)do { typeof ((ast_channel_flags(c))->flags) __p = (ast_channel_flags
(c))->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (
void) (&__p == &__x); ((ast_channel_flags(c))->flags
|= (AST_FLAG_TIMINGDATA_IS_AO2_OBJ)); } while(0)
;
3417 } else {
3418 ast_clear_flag(ast_channel_flags(c), AST_FLAG_TIMINGDATA_IS_AO2_OBJ)do { typeof ((ast_channel_flags(c))->flags) __p = (ast_channel_flags
(c))->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (
void) (&__p == &__x); ((ast_channel_flags(c))->flags
&= ~(AST_FLAG_TIMINGDATA_IS_AO2_OBJ)); } while(0)
;
3419 }
3420
3421 if (func == NULL((void*)0) && rate == 0 && ast_channel_fdno(c) == AST_TIMING_FD(11 -2)) {
3422 /* Clearing the timing func and setting the rate to 0
3423 * means that we don't want to be reading from the timingfd
3424 * any more. Setting c->fdno to -1 means we won't have any
3425 * errant reads from the timingfd, meaning we won't potentially
3426 * miss any important frames.
3427 */
3428 ast_channel_fdno_set(c, -1);
3429 }
3430
3431 ast_channel_unlock(c)__ao2_unlock(c, "channel.c", __PRETTY_FUNCTION__, 3431, "c");
3432
3433 return res;
3434}
3435
3436int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, int cmdfd)
3437{
3438 struct timeval start = ast_tvnow();
3439 int ms;
3440
3441 /* Stop if we're a zombie or need a soft hangup */
3442 if (ast_test_flag(ast_channel_flags(c), AST_FLAG_ZOMBIE)({ typeof ((ast_channel_flags(c))->flags) __p = (ast_channel_flags
(c))->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (
void) (&__p == &__x); ((ast_channel_flags(c))->flags
& (AST_FLAG_ZOMBIE)); })
|| ast_check_hangup(c))
3443 return -1;
3444
3445 /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */
3446 ast_set_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY)do { typeof ((ast_channel_flags(c))->flags) __p = (ast_channel_flags
(c))->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (
void) (&__p == &__x); ((ast_channel_flags(c))->flags
|= (AST_FLAG_END_DTMF_ONLY)); } while(0)
;
3447
3448 /* Wait for a digit, no more than timeout_ms milliseconds total.
3449 * Or, wait indefinitely if timeout_ms is <0.
3450 */
3451 while ((ms = ast_remaining_ms(start, timeout_ms))) {
3452 struct ast_channel *rchan;
3453 int outfd = -1;
3454
3455 errno(*__errno_location ()) = 0;
3456 /* While ast_waitfor_nandfds tries to help by reducing the timeout by how much was waited,
3457 * it is unhelpful if it waited less than a millisecond.
3458 */
3459 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL((void*)0), &outfd, &ms);
3460
3461 if (!rchan && outfd < 0 && ms) {
3462 if (errno(*__errno_location ()) == 0 || errno(*__errno_location ()) == EINTR4)
3463 continue;
3464 ast_log(LOG_WARNING3, "channel.c", 3464, __PRETTY_FUNCTION__, "Wait failed (%s)\n", strerror(errno(*__errno_location ())));
3465 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY)do { typeof ((ast_channel_flags(c))->flags) __p = (ast_channel_flags
(c))->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (
void) (&__p == &__x); ((ast_channel_flags(c))->flags
&= ~(AST_FLAG_END_DTMF_ONLY)); } while(0)
;
3466 return -1;
3467 } else if (outfd > -1) {
3468 /* The FD we were watching has something waiting */
3469 ast_log(LOG_WARNING3, "channel.c", 3469, __PRETTY_FUNCTION__, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n");
3470 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY)do { typeof ((ast_channel_flags(c))->flags) __p = (ast_channel_flags
(c))->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (
void) (&__p == &__x); ((ast_channel_flags(c))->flags
&= ~(AST_FLAG_END_DTMF_ONLY)); } while(0)
;
3471 return 1;
3472 } else if (rchan) {
3473 int res;
3474 struct ast_frame *f = ast_read(c);
3475 if (!f)
3476 return -1;
3477
3478 switch (f->frametype) {
3479 case AST_FRAME_DTMF_BEGIN:
3480 break;
3481 case AST_FRAME_DTMF_END:
3482 res = f->subclass.integer;
3483 ast_frfree(f)ast_frame_free(f, 1);
3484 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY)do { typeof ((ast_channel_flags(c))->flags) __p = (ast_channel_flags
(c))->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (
void) (&__p == &__x); ((ast_channel_flags(c))->flags
&= ~(AST_FLAG_END_DTMF_ONLY)); } while(0)
;
3485 return res;
3486 case AST_FRAME_CONTROL:
3487 switch (f->subclass.integer) {
3488 case AST_CONTROL_HANGUP:
3489 ast_frfree(f)ast_frame_free(f, 1);
3490 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY)do { typeof ((ast_channel_flags(c))->flags) __p = (ast_channel_flags
(c))->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (
void) (&__p == &__x); ((ast_channel_flags(c))->flags
&= ~(AST_FLAG_END_DTMF_ONLY)); } while(0)
;
3491 return -1;
3492 case AST_CONTROL_STREAM_STOP:
3493 case AST_CONTROL_STREAM_SUSPEND:
3494 case AST_CONTROL_STREAM_RESTART:
3495 case AST_CONTROL_STREAM_REVERSE:
3496 case AST_CONTROL_STREAM_FORWARD:
3497 /* Fall-through and treat as if it were a DTMF signal. Items
3498 * that perform stream control will handle this. */
3499 res = f->subclass.integer;
3500 ast_frfree(f)ast_frame_free(f, 1);
3501 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY)do { typeof ((ast_channel_flags(c))->flags) __p = (ast_channel_flags
(c))->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (
void) (&__p == &__x); ((ast_channel_flags(c))->flags
&= ~(AST_FLAG_END_DTMF_ONLY)); } while(0)
;
3502 return res;
3503 case AST_CONTROL_PVT_CAUSE_CODE:
3504 case AST_CONTROL_RINGING:
3505 case AST_CONTROL_ANSWER:
3506 case AST_CONTROL_SRCUPDATE:
3507 case AST_CONTROL_SRCCHANGE:
3508 case AST_CONTROL_CONNECTED_LINE:
3509 case AST_CONTROL_REDIRECTING:
3510 case AST_CONTROL_UPDATE_RTP_PEER:
3511 case AST_CONTROL_HOLD:
3512 case AST_CONTROL_UNHOLD:
3513 case -1:
3514 /* Unimportant */
3515 break;
3516 default:
3517 ast_log(LOG_WARNING3, "channel.c", 3517, __PRETTY_FUNCTION__, "Unexpected control subclass '%d'\n", f->subclass.integer);
3518 break;
3519 }
3520 break;
3521 case AST_FRAME_VOICE:
3522 /* Write audio if appropriate */
3523 if (audiofd > -1) {
3524 if (write(audiofd, f->data.ptr, f->datalen) < 0) {
3525 ast_log(LOG_WARNING3, "channel.c", 3525, __PRETTY_FUNCTION__, "write() failed: %s\n", strerror(errno(*__errno_location ())));
3526 }
3527 }
3528 default:
3529 /* Ignore */
3530 break;
3531 }
3532 ast_frfree(f)ast_frame_free(f, 1);
3533 }
3534 }
3535
3536 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY)do { typeof ((ast_channel_flags(c))->flags) __p = (ast_channel_flags
(c))->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (
void) (&__p == &__x); ((ast_channel_flags(c))->flags
&= ~(AST_FLAG_END_DTMF_ONLY)); } while(0)
;
3537
3538 return 0; /* Time is up */
3539}
3540
3541enum DtmfDirection {
3542 DTMF_RECEIVED,
3543 DTMF_SENT
3544};
3545
3546static const char *dtmf_direction_to_string(enum DtmfDirection direction)
3547{
3548 switch (direction) {
3549 case DTMF_RECEIVED:
3550 return "Received";
3551 case DTMF_SENT:
3552 return "Sent";
3553 }
3554
3555 return "?";
3556}
3557
3558static void send_dtmf_begin_event(struct ast_channel *chan,
3559 enum DtmfDirection direction, const char digit)
3560{
3561 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref)_raii_cleanup_block_t _raii_cleanup_blob __attribute__((cleanup
(_raii_cleanup_block),unused)) = ((void*)0); __attribute__((__blocks__
(byref))) struct ast_json * blob = ((void*)0); _raii_cleanup_blob
= ^{ {(void)ast_json_unref(blob);} }
;
3562 char digit_str[] = { digit, '\0' };
3563
3564 blob = ast_json_pack("{ s: s, s: s }",
3565 "digit", digit_str,
3566 "direction", dtmf_direction_to_string(direction));
3567 if (!blob) {
3568 return;
3569 }
3570
3571 ast_channel_publish_cached_blob(chan, ast_channel_dtmf_begin_type(), blob);
3572}
3573
3574static void send_dtmf_end_event(struct ast_channel *chan,
3575 enum DtmfDirection direction, const char digit, long duration_ms)
3576{
3577 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref)_raii_cleanup_block_t _raii_cleanup_blob __attribute__((cleanup
(_raii_cleanup_block),unused)) = ((void*)0); __attribute__((__blocks__
(byref))) struct ast_json * blob = ((void*)0); _raii_cleanup_blob
= ^{ {(void)ast_json_unref(blob);} }
;
3578 char digit_str[] = { digit, '\0' };
3579
3580 blob = ast_json_pack("{ s: s, s: s, s: i }",
3581 "digit", digit_str,
3582 "direction", dtmf_direction_to_string(direction),
3583 "duration_ms", duration_ms);
3584 if (!blob) {
3585 return;
3586 }
3587
3588 ast_channel_publish_cached_blob(chan, ast_channel_dtmf_end_type(), blob);
3589}
3590
3591static void ast_read_generator_actions(struct ast_channel *chan, struct ast_frame *f)
3592{
3593 struct ast_generator *generator;
3594 void *gendata;
3595 int res;
3596 int samples;
3597
3598 generator = ast_channel_generator(chan);
3599 if (!generator
3600 || !generator->generate
3601 || f->frametype != AST_FRAME_VOICE
3602 || !ast_channel_generatordata(chan)
3603 || ast_channel_timingfunc(chan)) {
3604 return;
3605 }
3606
3607 /*
3608 * We must generate frames in phase locked mode since
3609 * we have no internal timer available.
3610 */
3611 if (ast_format_cmp(f->subclass.format, ast_channel_writeformat(chan)) == AST_FORMAT_CMP_NOT_EQUAL) {
3612 float factor;
3613 factor = ((float) ast_format_get_sample_rate(ast_channel_writeformat(chan))) / ((float) ast_format_get_sample_rate(f->subclass.format));
3614 samples = (int) (((float) f->samples) * factor);
3615 } else {
3616 samples = f->samples;
3617 }
3618
3619 gendata = ast_channel_generatordata(chan);
3620 ast_channel_generatordata_set(chan, NULL((void*)0)); /* reset, to let writes go through */
3621
3622 /*
3623 * This unlock is here based on two assumptions that hold true at
3624 * this point in the code. 1) this function is only called from
3625 * within __ast_read() and 2) all generators call ast_write() in
3626 * their generate callback.
3627 *
3628 * The reason this is added is so that when ast_write is called,
3629 * the lock that occurs there will not recursively lock the
3630 * channel. Doing this will allow deadlock avoidance to work in
3631 * deeper functions.
3632 */
3633 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 3633, "chan"
)
;
3634 res = generator->generate(chan, gendata, f->datalen, samples);
3635 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 3635, "chan")
;
3636 if (generator == ast_channel_generator(chan)) {
3637 ast_channel_generatordata_set(chan, gendata);
3638 if (res) {
3639 ast_debug(1, "Auto-deactivating generator\n")do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 3639, __PRETTY_FUNCTION__, "Auto-deactivating generator\n"
); } } while (0)
;
3640 ast_deactivate_generator(chan);
3641 }
3642 }
3643}
3644
3645static inline void queue_dtmf_readq(struct ast_channel *chan, struct ast_frame *f)
3646{
3647 struct ast_frame *fr = ast_channel_dtmff(chan);
3648
3649 fr->frametype = AST_FRAME_DTMF_END;
3650 fr->subclass.integer = f->subclass.integer;
3651 fr->len = f->len;
3652
3653 /* The only time this function will be called is for a frame that just came
3654 * out of the channel driver. So, we want to stick it on the tail of the
3655 * readq. */
3656
3657 ast_queue_frame(chan, fr);
3658}
3659
3660/*!
3661 * \brief Determine whether or not we should ignore DTMF in the readq
3662 */
3663static inline int should_skip_dtmf(struct ast_channel *chan)
3664{
3665 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)); }
)
) {
3666 /* We're in the middle of emulating a digit, or DTMF has been
3667 * explicitly deferred. Skip this digit, then. */
3668 return 1;
3669 }
3670
3671 if (!ast_tvzero(*ast_channel_dtmf_tv(chan)) &&
3672 ast_tvdiff_ms(ast_tvnow(), *ast_channel_dtmf_tv(chan)) < AST_MIN_DTMF_GAP45) {
3673 /* We're not in the middle of a digit, but it hasn't been long enough
3674 * since the last digit, so we'll have to skip DTMF for now. */
3675 return 1;
3676 }
3677
3678 return 0;
3679}
3680
3681/*!
3682 * \brief calculates the number of samples to jump forward with in a monitor stream.
3683
3684 * \note When using ast_seekstream() with the read and write streams of a monitor,
3685 * the number of samples to seek forward must be of the same sample rate as the stream
3686 * or else the jump will not be calculated correctly.
3687 *
3688 * \retval number of samples to seek forward after rate conversion.
3689 */
3690static inline int calc_monitor_jump(int samples, int sample_rate, int seek_rate)
3691{
3692 int diff = sample_rate - seek_rate;
3693
3694 if (diff > 0) {
3695 samples = samples / (float) (sample_rate / seek_rate);
3696 } else if (diff < 0) {
3697 samples = samples * (float) (seek_rate / sample_rate);
3698 }
3699
3700 return samples;
3701}
3702
3703static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
3704{
3705 struct ast_frame *f = NULL((void*)0); /* the return value */
3706 int prestate;
3707 int cause = 0;
3708
3709 /* this function is very long so make sure there is only one return
3710 * point at the end (there are only two exceptions to this).
3711 */
3712 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 3712, "chan")
;
3713
3714 /* Stop if we're a zombie or need a soft hangup */
3715 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_ZOMBIE)); })
|| ast_check_hangup(chan)) {
3716 if (ast_channel_generator(chan))
3717 ast_deactivate_generator(chan);
3718
3719 /*
3720 * It is possible for chan->_softhangup to be set and there
3721 * still be control frames that need to be read. Instead of
3722 * just going to 'done' in the case of ast_check_hangup(), we
3723 * need to queue the end-of-Q frame so that it can mark the end
3724 * of the read queue. If there are frames to be read,
3725 * ast_queue_control() will be called repeatedly, but will only
3726 * queue the first end-of-Q frame.
3727 */
3728 if (ast_channel_softhangup_internal_flag(chan)) {
3729 ast_queue_control(chan, AST_CONTROL_END_OF_Q);
3730 } else {
3731 goto done;
3732 }
3733 } else {
3734#ifdef AST_DEVMODE1
3735 /*
3736 * The ast_waitfor() code records which of the channel's file
3737 * descriptors reported that data is available. In theory,
3738 * ast_read() should only be called after ast_waitfor() reports
3739 * that a channel has data available for reading. However,
3740 * there still may be some edge cases throughout the code where
3741 * ast_read() is called improperly. This can potentially cause
3742 * problems, so if this is a developer build, make a lot of
3743 * noise if this happens so that it can be addressed.
3744 *
3745 * One of the potential problems is blocking on a dead channel.
3746 */
3747 if (ast_channel_fdno(chan) == -1) {
3748 ast_log(LOG_ERROR4, "channel.c", 3748, __PRETTY_FUNCTION__,
3749 "ast_read() on chan '%s' called with no recorded file descriptor.\n",
3750 ast_channel_name(chan));
3751 }
3752#endif
3753 }
3754
3755 prestate = ast_channel_state(chan);
3756
3757 if (ast_channel_timingfd(chan) > -1 && ast_channel_fdno(chan) == AST_TIMING_FD(11 -2)) {
3758 enum ast_timer_event res;
3759
3760 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags &= ~(AST_FLAG_EXCEPTION)); } while(0)
;
3761
3762 res = ast_timer_get_event(ast_channel_timer(chan));
3763
3764 switch (res) {
3765 case AST_TIMING_EVENT_EXPIRED:
3766 if (ast_timer_ack(ast_channel_timer(chan), 1) < 0) {
3767 ast_log(LOG_ERROR4, "channel.c", 3767, __PRETTY_FUNCTION__, "Failed to acknoweldge timer in ast_read\n");
3768 goto done;
3769 }
3770
3771 if (ast_channel_timingfunc(chan)) {
3772 /* save a copy of func/data before unlocking the channel */
3773 ast_timing_func_t func = ast_channel_timingfunc(chan);
3774 void *data = ast_channel_timingdata(chan);
3775 int got_ref = 0;
3776 if (data && ast_test_flag(ast_channel_flags(chan), AST_FLAG_TIMINGDATA_IS_AO2_OBJ)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_TIMINGDATA_IS_AO2_OBJ)); })
) {
3777 ao2_ref(data, 1)__ao2_ref((data), (1), "", "channel.c", 3777, __PRETTY_FUNCTION__
)
;
3778 got_ref = 1;
3779 }
3780 ast_channel_fdno_set(chan, -1);
3781 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 3781, "chan"
)
;
3782 func(data);
3783 if (got_ref) {
3784 ao2_ref(data, -1)__ao2_ref((data), (-1), "", "channel.c", 3784, __PRETTY_FUNCTION__
)
;
3785 }
3786 } else {
3787 ast_timer_set_rate(ast_channel_timer(chan), 0);
3788 ast_channel_fdno_set(chan, -1);
3789 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 3789, "chan"
)
;
3790 }
3791
3792 /* cannot 'goto done' because the channel is already unlocked */
3793 return &ast_null_frame;
3794
3795 case AST_TIMING_EVENT_CONTINUOUS:
3796 if (AST_LIST_EMPTY(ast_channel_readq(chan))(((ast_channel_readq(chan))->first) == ((void*)0)) ||
3797 !AST_LIST_NEXT(AST_LIST_FIRST(ast_channel_readq(chan)), frame_list)((((ast_channel_readq(chan))->first))->frame_list.next)) {
3798 ast_timer_disable_continuous(ast_channel_timer(chan));
3799 }
3800 break;
3801 }
3802
3803 } else if (ast_channel_fd_isset(chan, AST_GENERATOR_FD(11 -4)) && ast_channel_fdno(chan) == AST_GENERATOR_FD(11 -4)) {
3804 /* if the AST_GENERATOR_FD is set, call the generator with args
3805 * set to -1 so it can do whatever it needs to.
3806 */
3807 void *tmp = ast_channel_generatordata(chan);
3808 ast_channel_generatordata_set(chan, NULL((void*)0)); /* reset to let ast_write get through */
3809 ast_channel_generator(chan)->generate(chan, tmp, -1, -1);
3810 ast_channel_generatordata_set(chan, tmp);
3811 f = &ast_null_frame;
3812 ast_channel_fdno_set(chan, -1);
3813 goto done;
3814 } else if (ast_channel_fd_isset(chan, AST_JITTERBUFFER_FD(11 -5)) && ast_channel_fdno(chan) == AST_JITTERBUFFER_FD(11 -5)) {
3815 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags &= ~(AST_FLAG_EXCEPTION)); } while(0)
;
3816 }
3817
3818 /* Read and ignore anything on the alertpipe, but read only
3819 one sizeof(blah) per frame that we send from it */
3820 if (ast_channel_internal_alert_read(chan) == AST_ALERT_READ_FATAL) {
3821 f = &ast_null_frame;
3822 goto done;
3823 }
3824
3825 /* Check for pending read queue */
3826 if (!AST_LIST_EMPTY(ast_channel_readq(chan))(((ast_channel_readq(chan))->first) == ((void*)0))) {
3827 int skip_dtmf = should_skip_dtmf(chan);
3828
3829 AST_LIST_TRAVERSE_SAFE_BEGIN(ast_channel_readq(chan), f, frame_list){ typeof((ast_channel_readq(chan))) __list_head = ast_channel_readq
(chan); typeof(__list_head->first) __list_next; typeof(__list_head
->first) __list_prev = ((void*)0); typeof(__list_head->
first) __list_current; for ((f) = __list_head->first, __list_current
= (f), __list_next = (f) ? (f)->frame_list.next : ((void*
)0); (f); __list_prev = __list_current, (f) = __list_next, __list_current
= (f), __list_next = (f) ? (f)->frame_list.next : ((void*
)0), (void) __list_prev )
{
3830 /* We have to be picky about which frame we pull off of the readq because
3831 * there are cases where we want to leave DTMF frames on the queue until
3832 * some later time. */
3833
3834 if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) {
3835 continue;
3836 }
3837
3838 AST_LIST_REMOVE_CURRENT(frame_list)do { __list_current->frame_list.next = ((void*)0); __list_current
= __list_prev; if (__list_prev) { __list_prev->frame_list
.next = __list_next; } else { __list_head->first = __list_next
; } if (!__list_next) { __list_head->last = __list_prev; }
} while (0)
;
3839 break;
3840 }
3841 AST_LIST_TRAVERSE_SAFE_END};
3842
3843 if (!f) {
3844 /* There were no acceptable frames on the readq. */
3845 f = &ast_null_frame;
3846 ast_channel_alert_write(chan);
3847 }
3848
3849 /* Interpret hangup and end-of-Q frames to return NULL */
3850 /* XXX why not the same for frames from the channel ? */
3851 if (f->frametype == AST_FRAME_CONTROL) {
3852 switch (f->subclass.integer) {
3853 case AST_CONTROL_HANGUP:
3854 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
3855 cause = f->data.uint32;
3856 /* Fall through */
3857 case AST_CONTROL_END_OF_Q:
3858 ast_frfree(f)ast_frame_free(f, 1);
3859 f = NULL((void*)0);
3860 break;
3861 default:
3862 break;
3863 }
3864 }
3865 } else {
3866 ast_channel_blocker_set(chan, pthread_self());
3867 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_EXCEPTION)); })
) {
3868 if (ast_channel_tech(chan)->exception)
3869 f = ast_channel_tech(chan)->exception(chan);
3870 else {
3871 ast_log(LOG_WARNING3, "channel.c", 3871, __PRETTY_FUNCTION__, "Exception flag set on '%s', but no exception handler\n", ast_channel_name(chan));
3872 f = &ast_null_frame;
3873 }
3874 /* Clear the exception flag */
3875 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags &= ~(AST_FLAG_EXCEPTION)); } while(0)
;
3876 } else if (ast_channel_tech(chan) && ast_channel_tech(chan)->read)
3877 f = ast_channel_tech(chan)->read(chan);
3878 else
3879 ast_log(LOG_WARNING3, "channel.c", 3879, __PRETTY_FUNCTION__, "No read routine on channel %s\n", ast_channel_name(chan));
3880 }
3881
3882 /* Perform the framehook read event here. After the frame enters the framehook list
3883 * there is no telling what will happen, <insert mad scientist laugh here>!!! */
3884 f = ast_framehook_list_read_event(ast_channel_framehooks(chan), f);
3885
3886 /*
3887 * Reset the recorded file descriptor that triggered this read so that we can
3888 * easily detect when ast_read() is called without properly using ast_waitfor().
3889 */
3890 ast_channel_fdno_set(chan, -1);
3891
3892 if (f) {
3893 struct ast_frame *readq_tail = AST_LIST_LAST(ast_channel_readq(chan))((ast_channel_readq(chan))->last);
3894 struct ast_control_read_action_payload *read_action_payload;
3895 struct ast_party_connected_line connected;
3896
3897 /* if the channel driver returned more than one frame, stuff the excess
3898 into the readq for the next ast_read call
3899 */
3900 if (AST_LIST_NEXT(f, frame_list)((f)->frame_list.next)) {
3901 ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list)((f)->frame_list.next));
3902 ast_frfree(AST_LIST_NEXT(f, frame_list))ast_frame_free(((f)->frame_list.next), 1);
3903 AST_LIST_NEXT(f, frame_list)((f)->frame_list.next) = NULL((void*)0);
3904 }
3905
3906 switch (f->frametype) {
3907 case AST_FRAME_CONTROL:
3908 if (f->subclass.integer == AST_CONTROL_ANSWER) {
3909 if (prestate == AST_STATE_UP && ast_channel_is_bridged(chan)) {
3910 ast_debug(1, "Dropping duplicate answer!\n")do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 3910, __PRETTY_FUNCTION__, "Dropping duplicate answer!\n"
); } } while (0)
;
3911 ast_frfree(f)ast_frame_free(f, 1);
3912 f = &ast_null_frame;
3913 } else {
3914 ast_setstate(chan, AST_STATE_UP);
3915 }
3916 } else if (f->subclass.integer == AST_CONTROL_READ_ACTION) {
3917 read_action_payload = f->data.ptr;
3918 switch (read_action_payload->action) {
3919 case AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO:
3920 ast_party_connected_line_init(&connected);
3921 ast_party_connected_line_copy(&connected, ast_channel_connected(chan));
3922 if (ast_connected_line_parse_data(read_action_payload->payload,
3923 read_action_payload->payload_size, &connected)) {
3924 ast_party_connected_line_free(&connected);
3925 break;
3926 }
3927 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 3927, "chan"
)
;
3928 if (ast_channel_connected_line_sub(NULL((void*)0), chan, &connected, 0) &&
3929 ast_channel_connected_line_macro(NULL((void*)0), chan, &connected, 1, 0)) {
3930 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE,
3931 read_action_payload->payload,
3932 read_action_payload->payload_size);
3933 }
3934 ast_party_connected_line_free(&connected);
3935 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 3935, "chan")
;
3936 break;
3937 }
3938 ast_frfree(f)ast_frame_free(f, 1);
3939 f = &ast_null_frame;
3940 }
3941 break;
3942 case AST_FRAME_DTMF_END:
3943 send_dtmf_end_event(chan, DTMF_RECEIVED, f->subclass.integer, f->len);
3944 ast_log(LOG_DTMF6, "channel.c", 3944, __PRETTY_FUNCTION__, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass.integer, ast_channel_name(chan), f->len);
3945 /* Queue it up if DTMF is deferred, or if DTMF emulation is forced. */
3946 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_DEFER_DTMF)); })
|| ast_test_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_EMULATE_DTMF)); })
) {
3947 queue_dtmf_readq(chan, f);
3948 ast_frfree(f)ast_frame_free(f, 1);
3949 f = &ast_null_frame;
3950 } else if (!ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)); })
) {
3951 if (!ast_tvzero(*ast_channel_dtmf_tv(chan)) &&
3952 ast_tvdiff_ms(ast_tvnow(), *ast_channel_dtmf_tv(chan)) < AST_MIN_DTMF_GAP45) {
3953 /* If it hasn't been long enough, defer this digit */
3954 queue_dtmf_readq(chan, f);
3955 ast_frfree(f)ast_frame_free(f, 1);
3956 f = &ast_null_frame;
3957 } else {
3958 /* There was no begin, turn this into a begin and send the end later */
3959 struct timeval tv = ast_tvnow();
3960 f->frametype = AST_FRAME_DTMF_BEGIN;
3961 ast_set_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags |= (AST_FLAG_EMULATE_DTMF)); } while(0)
;
3962 ast_channel_dtmf_digit_to_emulate_set(chan, f->subclass.integer);
3963 ast_channel_dtmf_tv_set(chan, &tv);
3964 if (f->len) {
3965 if (f->len > option_dtmfminduration)
3966 ast_channel_emulate_dtmf_duration_set(chan, f->len);
3967 else
3968 ast_channel_emulate_dtmf_duration_set(chan, option_dtmfminduration);
3969 } else
3970 ast_channel_emulate_dtmf_duration_set(chan, AST_DEFAULT_EMULATE_DTMF_DURATION100);
3971 ast_log(LOG_DTMF6, "channel.c", 3971, __PRETTY_FUNCTION__, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass.integer, ast_channel_emulate_dtmf_duration(chan), ast_channel_name(chan));
3972 }
3973 if (ast_channel_audiohooks(chan)) {
3974 struct ast_frame *old_frame = f;
3975 /*!
3976 * \todo XXX It is possible to write a digit to the audiohook twice
3977 * if the digit was originally read while the channel was in autoservice. */
3978 f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
3979 if (old_frame != f)
3980 ast_frfree(old_frame)ast_frame_free(old_frame, 1);
3981 }
3982 } else {
3983 struct timeval now = ast_tvnow();
3984 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_IN_DTMF)); })
) {
3985 ast_log(LOG_DTMF6, "channel.c", 3985, __PRETTY_FUNCTION__, "DTMF end accepted with begin '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
3986 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags &= ~(AST_FLAG_IN_DTMF)); } while(0)
;
3987 if (!f->len)
3988 f->len = ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan));
3989
3990 /* detect tones that were received on
3991 * the wire with durations shorter than
3992 * option_dtmfminduration and set f->len
3993 * to the actual duration of the DTMF
3994 * frames on the wire. This will cause
3995 * dtmf emulation to be triggered later
3996 * on.
3997 */
3998 if (ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan)) < option_dtmfminduration) {
3999 f->len = ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan));
4000 ast_log(LOG_DTMF6, "channel.c", 4000, __PRETTY_FUNCTION__, "DTMF end '%c' detected to have actual duration %ld on the wire, emulation will be triggered on %s\n", f->subclass.integer, f->len, ast_channel_name(chan));
4001 }
4002 } else if (!f->len) {
4003 ast_log(LOG_DTMF6, "channel.c", 4003, __PRETTY_FUNCTION__, "DTMF end accepted without begin '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
4004 f->len = option_dtmfminduration;
4005 }
4006 if (f->len < option_dtmfminduration && !ast_test_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_END_DTMF_ONLY)); })
) {
4007 ast_log(LOG_DTMF6, "channel.c", 4007, __PRETTY_FUNCTION__, "DTMF end '%c' has duration %ld but want minimum %u, emulating on %s\n", f->subclass.integer, f->len, option_dtmfminduration, ast_channel_name(chan));
4008 ast_set_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags |= (AST_FLAG_EMULATE_DTMF)); } while(0)
;
4009 ast_channel_dtmf_digit_to_emulate_set(chan, f->subclass.integer);
4010 ast_channel_emulate_dtmf_duration_set(chan, option_dtmfminduration - f->len);
4011 ast_frfree(f)ast_frame_free(f, 1);
4012 f = &ast_null_frame;
4013 } else {
4014 ast_log(LOG_DTMF6, "channel.c", 4014, __PRETTY_FUNCTION__, "DTMF end passthrough '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
4015 if (f->len < option_dtmfminduration) {
4016 f->len = option_dtmfminduration;
4017 }
4018 ast_channel_dtmf_tv_set(chan, &now);
4019 }
4020 if (ast_channel_audiohooks(chan)) {
4021 struct ast_frame *old_frame = f;
4022 f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
4023 if (old_frame != f)
4024 ast_frfree(old_frame)ast_frame_free(old_frame, 1);
4025 }
4026 }
4027 break;
4028 case AST_FRAME_DTMF_BEGIN:
4029 send_dtmf_begin_event(chan, DTMF_RECEIVED, f->subclass.integer);
4030 ast_log(LOG_DTMF6, "channel.c", 4030, __PRETTY_FUNCTION__, "DTMF begin '%c' received on %s\n", f->subclass.integer, ast_channel_name(chan));
4031 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF
)); })
||
4032 (!ast_tvzero(*ast_channel_dtmf_tv(chan)) &&
4033 ast_tvdiff_ms(ast_tvnow(), *ast_channel_dtmf_tv(chan)) < AST_MIN_DTMF_GAP45) ) {
4034 ast_log(LOG_DTMF6, "channel.c", 4034, __PRETTY_FUNCTION__, "DTMF begin ignored '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
4035 ast_frfree(f)ast_frame_free(f, 1);
4036 f = &ast_null_frame;
4037 } else {
4038 struct timeval now = ast_tvnow();
4039 ast_set_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags |= (AST_FLAG_IN_DTMF)); } while(0)
;
4040 ast_channel_dtmf_tv_set(chan, &now);
4041 ast_log(LOG_DTMF6, "channel.c", 4041, __PRETTY_FUNCTION__, "DTMF begin passthrough '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
4042 }
4043 break;
4044 case AST_FRAME_NULL:
4045 /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
4046 * is reached , because we want to make sure we pass at least one
4047 * voice frame through before starting the next digit, to ensure a gap
4048 * between DTMF digits. */
4049 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_EMULATE_DTMF)); })
) {
4050 struct timeval now = ast_tvnow();
4051 if (!ast_channel_emulate_dtmf_duration(chan)) {
4052 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags &= ~(AST_FLAG_EMULATE_DTMF)); } while(0)
;
4053 ast_channel_dtmf_digit_to_emulate_set(chan, 0);
4054 } else if (ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan)) >= ast_channel_emulate_dtmf_duration(chan)) {
4055 ast_channel_emulate_dtmf_duration_set(chan, 0);
4056 ast_frfree(f)ast_frame_free(f, 1);
4057 f = ast_channel_dtmff(chan);
4058 f->frametype = AST_FRAME_DTMF_END;
4059 f->subclass.integer = ast_channel_dtmf_digit_to_emulate(chan);
4060 f->len = ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan));
4061 ast_channel_dtmf_tv_set(chan, &now);
4062 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags &= ~(AST_FLAG_EMULATE_DTMF)); } while(0)
;
4063 ast_channel_dtmf_digit_to_emulate_set(chan, 0);
4064 ast_log(LOG_DTMF6, "channel.c", 4064, __PRETTY_FUNCTION__, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, ast_channel_name(chan));
4065 if (ast_channel_audiohooks(chan)) {
4066 struct ast_frame *old_frame = f;
4067 f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
4068 if (old_frame != f) {
4069 ast_frfree(old_frame)ast_frame_free(old_frame, 1);
4070 }
4071 }
4072 }
4073 }
4074 break;
4075 case AST_FRAME_VOICE:
4076 /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
4077 * is reached , because we want to make sure we pass at least one
4078 * voice frame through before starting the next digit, to ensure a gap
4079 * between DTMF digits. */
4080 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_EMULATE_DTMF)); })
&& !ast_channel_emulate_dtmf_duration(chan)) {
4081 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags &= ~(AST_FLAG_EMULATE_DTMF)); } while(0)
;
4082 ast_channel_dtmf_digit_to_emulate_set(chan, 0);
4083 }
4084
4085 if (dropaudio || ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_IN_DTMF)); })
) {
4086 if (dropaudio)
4087 ast_read_generator_actions(chan, f);
4088 ast_frfree(f)ast_frame_free(f, 1);
4089 f = &ast_null_frame;
4090 }
4091
4092 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_EMULATE_DTMF)); })
&& !ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_IN_DTMF)); })
) {
4093 struct timeval now = ast_tvnow();
4094 if (ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan)) >= ast_channel_emulate_dtmf_duration(chan)) {
4095 ast_channel_emulate_dtmf_duration_set(chan, 0);
4096 ast_frfree(f)ast_frame_free(f, 1);
4097 f = ast_channel_dtmff(chan);
4098 f->frametype = AST_FRAME_DTMF_END;
4099 f->subclass.integer = ast_channel_dtmf_digit_to_emulate(chan);
4100 f->len = ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan));
4101 ast_channel_dtmf_tv_set(chan, &now);
4102 if (ast_channel_audiohooks(chan)) {
4103 struct ast_frame *old_frame = f;
4104 f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
4105 if (old_frame != f)
4106 ast_frfree(old_frame)ast_frame_free(old_frame, 1);
4107 }
4108 ast_log(LOG_DTMF6, "channel.c", 4108, __PRETTY_FUNCTION__, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, ast_channel_name(chan));
4109 } else {
4110 /* Drop voice frames while we're still in the middle of the digit */
4111 ast_frfree(f)ast_frame_free(f, 1);
4112 f = &ast_null_frame;
4113 }
4114 break;
4115 }
4116 if (f->frametype != AST_FRAME_VOICE) {
4117 break;
4118 }
4119 if (ast_format_cmp(f->subclass.format, ast_channel_rawreadformat(chan)) != AST_FORMAT_CMP_EQUAL
4120 && ast_format_cmp(f->subclass.format, ast_channel_readformat(chan)) != AST_FORMAT_CMP_EQUAL) {
4121 struct ast_format *core_format;
4122
4123 /*
4124 * Note: This frame may not be one of the current native
4125 * formats. We may have gotten it out of the read queue from
4126 * a previous multi-frame translation, from a framehook
4127 * injected frame, or the device we're talking to isn't
4128 * respecting negotiated formats. Regardless we will accept
4129 * all frames.
4130 *
4131 * Update the read translation path to handle the new format
4132 * that just came in. If the core wants slinear we need to
4133 * setup a new translation path because the core is usually
4134 * doing something with the audio itself and may not handle
4135 * any other format. e.g., Softmix bridge, holding bridge
4136 * announcer channel, recording, AMD... Otherwise, we'll
4137 * setup to pass the frame as is to the core. In this case
4138 * the core doesn't care. The channel is likely in
4139 * autoservice, safesleep, or the channel is in a bridge.
4140 * Let the bridge technology deal with format compatibility
4141 * between the channels in the bridge.
4142 *
4143 * Beware of the transcode_via_slin and genericplc options as
4144 * they force any transcoding to go through slin on a bridge.
4145 * Unfortunately transcode_via_slin is enabled by default and
4146 * genericplc is enabled in the codecs.conf.sample file.
4147 *
4148 * XXX Only updating translation to slinear frames has some
4149 * corner cases if slinear is one of the native formats and
4150 * there are different sample rates involved. We might wind
4151 * up with conflicting translation paths between channels
4152 * where the read translation path on this channel reduces
4153 * the sample rate followed by a write translation path on
4154 * the peer channel that increases the sample rate.
4155 */
4156 core_format = ast_channel_readformat(chan);
4157 if (!ast_format_cache_is_slinear(core_format)) {
4158 core_format = f->subclass.format;
4159 }
4160 if (ast_set_read_format_path(chan, f->subclass.format, core_format)) {
4161 /* Drop frame. We couldn't make it compatible with the core. */
4162 ast_frfree(f)ast_frame_free(f, 1);
4163 f = &ast_null_frame;
4164 break;
4165 }
4166 }
4167 /* Send frame to audiohooks if present */
4168 if (ast_channel_audiohooks(chan)) {
4169 struct ast_frame *old_frame = f;
4170
4171 f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
4172 if (old_frame != f) {
4173 ast_frfree(old_frame)ast_frame_free(old_frame, 1);
4174 }
4175 }
4176 if (ast_channel_monitor(chan) && ast_channel_monitor(chan)->read_stream) {
4177 /* XXX what does this do ? */
4178#ifndef MONITOR_CONSTANT_DELAY
4179 int jump = ast_channel_outsmpl(chan) - ast_channel_insmpl(chan) - 4 * f->samples;
4180 if (jump >= 0) {
4181 jump = calc_monitor_jump((ast_channel_outsmpl(chan) - ast_channel_insmpl(chan)),
4182 ast_format_get_sample_rate(f->subclass.format),
4183 ast_format_get_sample_rate(ast_channel_monitor(chan)->read_stream->fmt->format));
4184 if (ast_seekstream(ast_channel_monitor(chan)->read_stream, jump, SEEK_FORCECUR10) == -1) {
4185 ast_log(LOG_WARNING3, "channel.c", 4185, __PRETTY_FUNCTION__, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
4186 }
4187 ast_channel_insmpl_set(chan, ast_channel_insmpl(chan) + (ast_channel_outsmpl(chan) - ast_channel_insmpl(chan)) + f->samples);
4188 } else {
4189 ast_channel_insmpl_set(chan, ast_channel_insmpl(chan) + f->samples);
4190 }
4191#else
4192 int jump = calc_monitor_jump((ast_channel_outsmpl(chan) - ast_channel_insmpl(chan)),
4193 ast_format_get_sample_rate(f->subclass.codec),
4194 ast_format_get_sample_rate(ast_channel_monitor(chan)->read_stream->fmt->format));
4195 if (jump - MONITOR_DELAY >= 0) {
4196 if (ast_seekstream(ast_channel_monitor(chan)->read_stream, jump - f->samples, SEEK_FORCECUR10) == -1) {
4197 ast_log(LOG_WARNING3, "channel.c", 4197, __PRETTY_FUNCTION__, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
4198 }
4199 ast_channel_insmpl(chan) += ast_channel_outsmpl(chan) - ast_channel_insmpl(chan);
4200 } else {
4201 ast_channel_insmpl(chan) += f->samples;
4202 }
4203#endif
4204 if (ast_channel_monitor(chan)->state == AST_MONITOR_RUNNING) {
4205 if (ast_writestream(ast_channel_monitor(chan)->read_stream, f) < 0)
4206 ast_log(LOG_WARNING3, "channel.c", 4206, __PRETTY_FUNCTION__, "Failed to write data to channel monitor read stream\n");
4207 }
4208 }
4209
4210 if (ast_channel_readtrans(chan)
4211 && ast_format_cmp(f->subclass.format, ast_channel_rawreadformat(chan)) == AST_FORMAT_CMP_EQUAL) {
4212 f = ast_translate(ast_channel_readtrans(chan), f, 1);
4213 if (!f) {
4214 f = &ast_null_frame;
4215 }
4216 }
4217
4218 /*
4219 * It is possible for the translation process on the channel to have
4220 * produced multiple frames from the single input frame we passed it; if
4221 * this happens, queue the additional frames *before* the frames we may
4222 * have queued earlier. if the readq was empty, put them at the head of
4223 * the queue, and if it was not, put them just after the frame that was
4224 * at the end of the queue.
4225 */
4226 if (AST_LIST_NEXT(f, frame_list)((f)->frame_list.next)) {
4227 if (!readq_tail) {
4228 ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list)((f)->frame_list.next));
4229 } else {
4230 __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list)((f)->frame_list.next), 0, readq_tail);
4231 }
4232 ast_frfree(AST_LIST_NEXT(f, frame_list))ast_frame_free(((f)->frame_list.next), 1);
4233 AST_LIST_NEXT(f, frame_list)((f)->frame_list.next) = NULL((void*)0);
4234 }
4235
4236 /*
4237 * Run generator sitting on the line if timing device not available
4238 * and synchronous generation of outgoing frames is necessary
4239 */
4240 ast_read_generator_actions(chan, f);
4241 break;
4242 default:
4243 /* Just pass it on! */
4244 break;
4245 }
4246 } else {
4247 /* Make sure we always return NULL in the future */
4248 if (!ast_channel_softhangup_internal_flag(chan)) {
4249 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
4250 }
4251 if (cause)
4252 ast_channel_hangupcause_set(chan, cause);
4253 if (ast_channel_generator(chan))
4254 ast_deactivate_generator(chan);
4255 /* We no longer End the CDR here */
4256 }
4257
4258 /* High bit prints debugging */
4259 if (ast_channel_fin(chan) & DEBUGCHAN_FLAG0x80000000)
4260 ast_frame_dump(ast_channel_name(chan), f, "<<");
4261 ast_channel_fin_set(chan, FRAMECOUNT_INC(ast_channel_fin(chan))( ((ast_channel_fin(chan)) & 0x80000000) | (((ast_channel_fin
(chan))+1) & ~0x80000000) )
);
4262
4263done:
4264 if (ast_channel_music_state(chan) && ast_channel_generator(chan) && ast_channel_generator(chan)->digit && f && f->frametype == AST_FRAME_DTMF_END)
4265 ast_channel_generator(chan)->digit(chan, f->subclass.integer);
4266
4267 if (ast_channel_audiohooks(chan) && ast_audiohook_write_list_empty(ast_channel_audiohooks(chan))) {
4268 /* The list gets recreated if audiohooks are added again later */
4269 ast_audiohook_detach_list(ast_channel_audiohooks(chan));
4270 ast_channel_audiohooks_set(chan, NULL((void*)0));
4271 }
4272 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 4272, "chan"
)
;
4273 return f;
4274}
4275
4276struct ast_frame *ast_read(struct ast_channel *chan)
4277{
4278 return __ast_read(chan, 0);
4279}
4280
4281struct ast_frame *ast_read_noaudio(struct ast_channel *chan)
4282{
4283 return __ast_read(chan, 1);
4284}
4285
4286int ast_indicate(struct ast_channel *chan, int condition)
4287{
4288 return ast_indicate_data(chan, condition, NULL((void*)0), 0);
4289}
4290
4291static int attribute_const__attribute__((const)) is_visible_indication(enum ast_control_frame_type condition)
4292{
4293 /* Don't include a default case here so that we get compiler warnings
4294 * when a new type is added. */
4295
4296 switch (condition) {
4297 case AST_CONTROL_PROGRESS:
4298 case AST_CONTROL_PROCEEDING:
4299 case AST_CONTROL_VIDUPDATE:
4300 case AST_CONTROL_SRCUPDATE:
4301 case AST_CONTROL_SRCCHANGE:
4302 case AST_CONTROL_RADIO_KEY:
4303 case AST_CONTROL_RADIO_UNKEY:
4304 case AST_CONTROL_OPTION:
4305 case AST_CONTROL_WINK:
4306 case AST_CONTROL_FLASH:
4307 case AST_CONTROL_OFFHOOK:
4308 case AST_CONTROL_TAKEOFFHOOK:
4309 case AST_CONTROL_ANSWER:
4310 case AST_CONTROL_HANGUP:
4311 case AST_CONTROL_CONNECTED_LINE:
4312 case AST_CONTROL_REDIRECTING:
4313 case AST_CONTROL_TRANSFER:
4314 case AST_CONTROL_T38_PARAMETERS:
4315 case _XXX_AST_CONTROL_T38:
4316 case AST_CONTROL_CC:
4317 case AST_CONTROL_READ_ACTION:
4318 case AST_CONTROL_AOC:
4319 case AST_CONTROL_END_OF_Q:
4320 case AST_CONTROL_MCID:
4321 case AST_CONTROL_UPDATE_RTP_PEER:
4322 case AST_CONTROL_PVT_CAUSE_CODE:
4323 case AST_CONTROL_MASQUERADE_NOTIFY:
4324 case AST_CONTROL_STREAM_STOP:
4325 case AST_CONTROL_STREAM_SUSPEND:
4326 case AST_CONTROL_STREAM_REVERSE:
4327 case AST_CONTROL_STREAM_FORWARD:
4328 case AST_CONTROL_STREAM_RESTART:
4329 case AST_CONTROL_RECORD_CANCEL:
4330 case AST_CONTROL_RECORD_STOP:
4331 case AST_CONTROL_RECORD_SUSPEND:
4332 case AST_CONTROL_RECORD_MUTE:
4333 break;
4334
4335 case AST_CONTROL_INCOMPLETE:
4336 case AST_CONTROL_CONGESTION:
4337 case AST_CONTROL_BUSY:
4338 case AST_CONTROL_RINGING:
4339 case AST_CONTROL_RING:
4340 case AST_CONTROL_HOLD:
4341 /* You can hear these */
4342 return 1;
4343
4344 case AST_CONTROL_UNHOLD:
4345 /* This is a special case. You stop hearing this. */
4346 break;
4347 }
4348
4349 return 0;
4350}
4351
4352void ast_channel_hangupcause_hash_set(struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
4353{
4354 char causevar[256];
4355
4356 if (ast_channel_dialed_causes_add(chan, cause_code, datalen)) {
4357 ast_log(LOG_WARNING3, "channel.c", 4357, __PRETTY_FUNCTION__, "Unable to store hangup cause for %s on %s\n", cause_code->chan_name, ast_channel_name(chan));
4358 }
4359
4360 if (cause_code->emulate_sip_cause) {
4361 snprintf(causevar, sizeof(causevar), "HASH(SIP_CAUSE,%s)", cause_code->chan_name);
4362 ast_func_write(chan, causevar, cause_code->code);
4363 }
4364}
4365
4366enum ama_flags ast_channel_string2amaflag(const char *flag)
4367{
4368 if (!strcasecmp(flag, "default"))
4369 return DEFAULT_AMA_FLAGSAST_AMA_DOCUMENTATION;
4370 if (!strcasecmp(flag, "omit"))
4371 return AST_AMA_OMIT;
4372 if (!strcasecmp(flag, "billing"))
4373 return AST_AMA_BILLING;
4374 if (!strcasecmp(flag, "documentation"))
4375 return AST_AMA_DOCUMENTATION;
4376 return AST_AMA_NONE;
4377}
4378
4379const char *ast_channel_amaflags2string(enum ama_flags flag)
4380{
4381 switch (flag) {
4382 case AST_AMA_OMIT:
4383 return "OMIT";
4384 case AST_AMA_BILLING:
4385 return "BILLING";
4386 case AST_AMA_DOCUMENTATION:
4387 return "DOCUMENTATION";
4388 default:
4389 return "Unknown";
4390 }
4391}
4392
4393/*!
4394 * \internal
4395 * \brief Preprocess connected line update.
4396 * \since 12.0.0
4397 *
4398 * \param chan channel to change the indication
4399 * \param data pointer to payload data
4400 * \param datalen size of payload data
4401 *
4402 * \note This function assumes chan is locked.
4403 *
4404 * \retval 0 keep going.
4405 * \retval -1 quit now.
4406 */
4407static int indicate_connected_line(struct ast_channel *chan, const void *data, size_t datalen)
4408{
4409 struct ast_party_connected_line *chan_connected = ast_channel_connected(chan);
4410 struct ast_party_connected_line *chan_indicated = ast_channel_connected_indicated(chan);
4411 struct ast_party_connected_line connected;
4412 unsigned char current[1024];
4413 unsigned char proposed[1024];
4414 int current_size;
4415 int proposed_size;
4416 int res;
4417
4418 ast_party_connected_line_set_init(&connected, chan_connected);
4419 res = ast_connected_line_parse_data(data, datalen, &connected);
4420 if (!res) {
4421 ast_channel_set_connected_line(chan, &connected, NULL((void*)0));
4422 }
4423 ast_party_connected_line_free(&connected);
4424 if (res) {
4425 return -1;
4426 }
4427
4428 current_size = ast_connected_line_build_data(current, sizeof(current),
4429 chan_indicated, NULL((void*)0));
4430 proposed_size = ast_connected_line_build_data(proposed, sizeof(proposed),
4431 chan_connected, NULL((void*)0));
4432 if (current_size == -1 || proposed_size == -1) {
4433 return -1;
4434 }
4435
4436 if (current_size == proposed_size && !memcmp(current, proposed, current_size)) {
4437 ast_debug(1, "%s: Dropping redundant connected line update \"%s\" <%s>.\n",do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 4440, __PRETTY_FUNCTION__, "%s: Dropping redundant connected line update \"%s\" <%s>.\n"
, ast_channel_name(chan), ({typeof(&((chan_connected->
id.name.str)[0])) __x = (chan_connected->id.name.str); (chan_connected
->id.name.valid) && !_ast_strlen_zero(__x, "channel.c"
, __PRETTY_FUNCTION__, 4439) ? (__x) : ("");}), ({typeof(&
((chan_connected->id.number.str)[0])) __x = (chan_connected
->id.number.str); (chan_connected->id.number.valid) &&
!_ast_strlen_zero(__x, "channel.c", __PRETTY_FUNCTION__, 4440
) ? (__x) : ("");})); } } while (0)
4438 ast_channel_name(chan),do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 4440, __PRETTY_FUNCTION__, "%s: Dropping redundant connected line update \"%s\" <%s>.\n"
, ast_channel_name(chan), ({typeof(&((chan_connected->
id.name.str)[0])) __x = (chan_connected->id.name.str); (chan_connected
->id.name.valid) && !_ast_strlen_zero(__x, "channel.c"
, __PRETTY_FUNCTION__, 4439) ? (__x) : ("");}), ({typeof(&
((chan_connected->id.number.str)[0])) __x = (chan_connected
->id.number.str); (chan_connected->id.number.valid) &&
!_ast_strlen_zero(__x, "channel.c", __PRETTY_FUNCTION__, 4440
) ? (__x) : ("");})); } } while (0)
4439 S_COR(chan_connected->id.name.valid, chan_connected->id.name.str, ""),do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 4440, __PRETTY_FUNCTION__, "%s: Dropping redundant connected line update \"%s\" <%s>.\n"
, ast_channel_name(chan), ({typeof(&((chan_connected->
id.name.str)[0])) __x = (chan_connected->id.name.str); (chan_connected
->id.name.valid) && !_ast_strlen_zero(__x, "channel.c"
, __PRETTY_FUNCTION__, 4439) ? (__x) : ("");}), ({typeof(&
((chan_connected->id.number.str)[0])) __x = (chan_connected
->id.number.str); (chan_connected->id.number.valid) &&
!_ast_strlen_zero(__x, "channel.c", __PRETTY_FUNCTION__, 4440
) ? (__x) : ("");})); } } while (0)
4440 S_COR(chan_connected->id.number.valid, chan_connected->id.number.str, ""))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 4440, __PRETTY_FUNCTION__, "%s: Dropping redundant connected line update \"%s\" <%s>.\n"
, ast_channel_name(chan), ({typeof(&((chan_connected->
id.name.str)[0])) __x = (chan_connected->id.name.str); (chan_connected
->id.name.valid) && !_ast_strlen_zero(__x, "channel.c"
, __PRETTY_FUNCTION__, 4439) ? (__x) : ("");}), ({typeof(&
((chan_connected->id.number.str)[0])) __x = (chan_connected
->id.number.str); (chan_connected->id.number.valid) &&
!_ast_strlen_zero(__x, "channel.c", __PRETTY_FUNCTION__, 4440
) ? (__x) : ("");})); } } while (0)
;
4441 return -1;
4442 }
4443
4444 ast_party_connected_line_copy(chan_indicated, chan_connected);
4445 return 0;
4446}
4447
4448/*!
4449 * \internal
4450 * \brief Preprocess redirecting update.
4451 * \since 12.0.0
4452 *
4453 * \param chan channel to change the indication
4454 * \param data pointer to payload data
4455 * \param datalen size of payload data
4456 *
4457 * \note This function assumes chan is locked.
4458 *
4459 * \retval 0 keep going.
4460 * \retval -1 quit now.
4461 */
4462static int indicate_redirecting(struct ast_channel *chan, const void *data, size_t datalen)
4463{
4464 struct ast_party_redirecting redirecting;
4465 int res;
4466
4467 ast_party_redirecting_set_init(&redirecting, ast_channel_redirecting(chan));
4468 res = ast_redirecting_parse_data(data, datalen, &redirecting);
4469 if (!res) {
4470 ast_channel_set_redirecting(chan, &redirecting, NULL((void*)0));
4471 }
4472 ast_party_redirecting_free(&redirecting);
4473 return res ? -1 : 0;
4474}
4475
4476static int indicate_data_internal(struct ast_channel *chan, int _condition, const void *data, size_t datalen)
4477{
4478 /* By using an enum, we'll get compiler warnings for values not handled
4479 * in switch statements. */
4480 enum ast_control_frame_type condition = _condition;
4481 struct ast_tone_zone_sound *ts = NULL((void*)0);
4482 const struct ast_control_t38_parameters *t38_parameters;
4483 int res;
4484
4485 switch (condition) {
4486 case AST_CONTROL_CONNECTED_LINE:
4487 if (indicate_connected_line(chan, data, datalen)) {
4488 res = 0;
4489 return res;
4490 }
4491 break;
4492 case AST_CONTROL_REDIRECTING:
4493 if (indicate_redirecting(chan, data, datalen)) {
4494 res = 0;
4495 return res;
4496 }
4497 break;
4498 case AST_CONTROL_HOLD:
4499 case AST_CONTROL_UNHOLD:
4500 ast_channel_hold_state_set(chan, _condition);
4501 break;
4502 case AST_CONTROL_T38_PARAMETERS:
4503 t38_parameters = data;
4504 switch (t38_parameters->request_response) {
4505 case AST_T38_REQUEST_NEGOTIATE:
4506 case AST_T38_NEGOTIATED:
4507 ast_channel_set_is_t38_active_nolock(chan, 1);
4508 break;
4509 case AST_T38_REQUEST_TERMINATE:
4510 case AST_T38_TERMINATED:
4511 case AST_T38_REFUSED:
4512 ast_channel_set_is_t38_active_nolock(chan, 0);
4513 break;
4514 default:
4515 break;
4516 }
4517 break;
4518 default:
4519 break;
4520 }
4521
4522 if (is_visible_indication(condition)) {
4523 /* A new visible indication is requested. */
4524 ast_channel_visible_indication_set(chan, _condition);
4525 } else if (condition == AST_CONTROL_UNHOLD || _condition < 0) {
4526 /* Visible indication is cleared/stopped. */
4527 ast_channel_visible_indication_set(chan, 0);
4528 }
4529
4530 if (ast_channel_tech(chan)->indicate) {
4531 /* See if the channel driver can handle this condition. */
4532 res = ast_channel_tech(chan)->indicate(chan, _condition, data, datalen);
4533 } else {
4534 res = -1;
4535 }
4536
4537 if (!res) {
4538 /* The channel driver successfully handled this indication */
4539 res = 0;
4540 return res;
4541 }
4542
4543 /* The channel driver does not support this indication, let's fake
4544 * it by doing our own tone generation if applicable. */
4545
4546 /*!\note If we compare the enumeration type, which does not have any
4547 * negative constants, the compiler may optimize this code away.
4548 * Therefore, we must perform an integer comparison here. */
4549 if (_condition < 0) {
4550 /* Stop any tones that are playing */
4551 ast_playtones_stop(chan);
4552 res = 0;
4553 return res;
4554 }
4555
4556 /* Handle conditions that we have tones for. */
4557 switch (condition) {
4558 case _XXX_AST_CONTROL_T38:
4559 /* deprecated T.38 control frame */
4560 res = -1;
4561 return res;
4562 case AST_CONTROL_T38_PARAMETERS:
4563 /* there is no way to provide 'default' behavior for these
4564 * control frames, so we need to return failure, but there
4565 * is also no value in the log message below being emitted
4566 * since failure to handle these frames is not an 'error'
4567 * so just return right now. in addition, we want to return
4568 * whatever value the channel driver returned, in case it
4569 * has some meaning.*/
4570 return res;
4571 case AST_CONTROL_RINGING:
4572 ts = ast_get_indication_tone(ast_channel_zone(chan), "ring");
4573 /* It is common practice for channel drivers to return -1 if trying
4574 * to indicate ringing on a channel which is up. The idea is to let the
4575 * core generate the ringing inband. However, we don't want the
4576 * warning message about not being able to handle the specific indication
4577 * to print nor do we want ast_indicate_data to return an "error" for this
4578 * condition
4579 */
4580 if (ast_channel_state(chan) == AST_STATE_UP) {
4581 res = 0;
4582 }
4583 break;
4584 case AST_CONTROL_BUSY:
4585 ts = ast_get_indication_tone(ast_channel_zone(chan), "busy");
4586 break;
4587 case AST_CONTROL_INCOMPLETE:
4588 case AST_CONTROL_CONGESTION:
4589 ts = ast_get_indication_tone(ast_channel_zone(chan), "congestion");
4590 break;
4591 case AST_CONTROL_PVT_CAUSE_CODE:
4592 ast_channel_hangupcause_hash_set(chan, data, datalen);
4593 res = 0;
4594 break;
4595 case AST_CONTROL_PROGRESS:
4596 case AST_CONTROL_PROCEEDING:
4597 case AST_CONTROL_VIDUPDATE:
4598 case AST_CONTROL_SRCUPDATE:
4599 case AST_CONTROL_SRCCHANGE:
4600 case AST_CONTROL_RADIO_KEY:
4601 case AST_CONTROL_RADIO_UNKEY:
4602 case AST_CONTROL_OPTION:
4603 case AST_CONTROL_WINK:
4604 case AST_CONTROL_FLASH:
4605 case AST_CONTROL_OFFHOOK:
4606 case AST_CONTROL_TAKEOFFHOOK:
4607 case AST_CONTROL_ANSWER:
4608 case AST_CONTROL_HANGUP:
4609 case AST_CONTROL_RING:
4610 case AST_CONTROL_HOLD:
4611 case AST_CONTROL_UNHOLD:
4612 case AST_CONTROL_TRANSFER:
4613 case AST_CONTROL_CONNECTED_LINE:
4614 case AST_CONTROL_REDIRECTING:
4615 case AST_CONTROL_CC:
4616 case AST_CONTROL_READ_ACTION:
4617 case AST_CONTROL_AOC:
4618 case AST_CONTROL_END_OF_Q:
4619 case AST_CONTROL_MCID:
4620 case AST_CONTROL_MASQUERADE_NOTIFY:
4621 case AST_CONTROL_UPDATE_RTP_PEER:
4622 case AST_CONTROL_STREAM_STOP:
4623 case AST_CONTROL_STREAM_SUSPEND:
4624 case AST_CONTROL_STREAM_REVERSE:
4625 case AST_CONTROL_STREAM_FORWARD:
4626 case AST_CONTROL_STREAM_RESTART:
4627 case AST_CONTROL_RECORD_CANCEL:
4628 case AST_CONTROL_RECORD_STOP:
4629 case AST_CONTROL_RECORD_SUSPEND:
4630 case AST_CONTROL_RECORD_MUTE:
4631 /* Nothing left to do for these. */
4632 res = 0;
4633 break;
4634 }
4635
4636 if (ts) {
4637 /* We have a tone to play, yay. */
4638 ast_debug(1, "Driver for channel '%s' does not support indication %u, emulating it\n", ast_channel_name(chan), condition)do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 4638, __PRETTY_FUNCTION__, "Driver for channel '%s' does not support indication %u, emulating it\n"
, ast_channel_name(chan), condition); } } while (0)
;
4639 res = ast_playtones_start(chan, 0, ts->data, 1);
4640 if (!res) {
4641 ast_test_suite_event_notify("RINGING_INBAND",
4642 "Channel: %s\r\n",
4643 ast_channel_name(chan));
4644 }
4645 ts = ast_tone_zone_sound_unref(ts);
4646 }
4647
4648 if (res) {
4649 /* not handled */
4650 ast_log(LOG_WARNING3, "channel.c", 4650, __PRETTY_FUNCTION__, "Unable to handle indication %u for '%s'\n", condition, ast_channel_name(chan));
4651 }
4652
4653 return res;
4654}
4655
4656int ast_indicate_data(struct ast_channel *chan, int _condition, const void *data, size_t datalen)
4657{
4658 int res;
4659 /* this frame is used by framehooks. if it is set, we must free it at the end of this function */
4660 struct ast_frame *awesome_frame = NULL((void*)0);
4661
4662 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 4662, "chan")
;
4663
4664 /* Don't bother if the channel is about to go away, anyway. */
4665 if ((ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_ZOMBIE)); })
4666 || (ast_check_hangup(chan) && !ast_channel_is_leaving_bridge(chan)))
4667 && _condition != AST_CONTROL_MASQUERADE_NOTIFY) {
4668 res = -1;
4669 goto indicate_cleanup;
4670 }
4671
4672 if (!ast_framehook_list_is_empty(ast_channel_framehooks(chan))) {
4673 /* Do framehooks now, do it, go, go now */
4674 struct ast_frame frame = {
4675 .frametype = AST_FRAME_CONTROL,
4676 .subclass.integer = _condition,
4677 .data.ptr = (void *) data, /* this cast from const is only okay because we do the ast_frdup below */
4678 .datalen = datalen
4679 };
4680
4681 /* we have now committed to freeing this frame */
4682 awesome_frame = ast_frdup(&frame);
4683
4684 /* who knows what we will get back! the anticipation is killing me. */
4685 awesome_frame = ast_framehook_list_write_event(ast_channel_framehooks(chan),
4686 awesome_frame);
4687 if (!awesome_frame
4688 || awesome_frame->frametype != AST_FRAME_CONTROL) {
4689 res = 0;
4690 goto indicate_cleanup;
4691 }
4692
4693 _condition = awesome_frame->subclass.integer;
4694 data = awesome_frame->data.ptr;
4695 datalen = awesome_frame->datalen;
4696 }
4697
4698 res = indicate_data_internal(chan, _condition, data, datalen);
4699
4700indicate_cleanup:
4701 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 4701, "chan"
)
;
4702 if (awesome_frame) {
4703 ast_frfree(awesome_frame)ast_frame_free(awesome_frame, 1);
4704 }
4705
4706 return res;
4707}
4708
4709int ast_recvchar(struct ast_channel *chan, int timeout)
4710{
4711 int c;
4712 char *buf = ast_recvtext(chan, timeout);
4713 if (buf == NULL((void*)0))
4714 return -1; /* error or timeout */
4715 c = *(unsigned char *)buf;
4716 ast_freefree(buf);
4717 return c;
4718}
4719
4720char *ast_recvtext(struct ast_channel *chan, int timeout)
4721{
4722 int res;
4723 char *buf = NULL((void*)0);
4724 struct timeval start = ast_tvnow();
4725 int ms;
4726
4727 while ((ms = ast_remaining_ms(start, timeout))) {
4728 struct ast_frame *f;
4729
4730 if (ast_check_hangup(chan)) {
4731 break;
4732 }
4733 res = ast_waitfor(chan, ms);
4734 if (res <= 0) {/* timeout or error */
4735 break;
4736 }
4737 f = ast_read(chan);
4738 if (f == NULL((void*)0)) {
4739 break; /* no frame */
4740 }
4741 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP) {
4742 ast_frfree(f)ast_frame_free(f, 1);
4743 break;
4744 } else if (f->frametype == AST_FRAME_TEXT) { /* what we want */
4745 buf = ast_strndup((char *) f->data.ptr, f->datalen)_ast_strndup(((char *) f->data.ptr), (f->datalen), "channel.c"
, 4745, __PRETTY_FUNCTION__)
; /* dup and break */
4746 ast_frfree(f)ast_frame_free(f, 1);
4747 break;
4748 }
4749 ast_frfree(f)ast_frame_free(f, 1);
4750 }
4751 return buf;
4752}
4753
4754int ast_sendtext(struct ast_channel *chan, const char *text)
4755{
4756 int res = 0;
4757
4758 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 4758, "chan")
;
4759 /* Stop if we're a zombie or need a soft hangup */
4760 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_ZOMBIE)); })
|| ast_check_hangup(chan)) {
4761 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 4761, "chan"
)
;
4762 return -1;
4763 }
4764
4765 if (ast_strlen_zero(text)_ast_strlen_zero(text, "channel.c", __PRETTY_FUNCTION__, 4765
)
) {
4766 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 4766, "chan"
)
;
4767 return 0;
4768 }
4769
4770 CHECK_BLOCKING(chan)do { if (({ typeof ((ast_channel_flags(chan))->flags) __p =
(ast_channel_flags(chan))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(chan))->flags & (AST_FLAG_BLOCKING)); })) { do { if (
(option_debug >= (1) || (({ typeof ((&ast_options)->
flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 4770, __PRETTY_FUNCTION__, "Thread %p is blocking '%s', already blocked by thread %p in procedure %s\n"
, (void *) pthread_self(), ast_channel_name(chan), (void *) ast_channel_blocker
(chan), ast_channel_blockproc(chan)); } } while (0); } else {
ast_channel_blocker_set((chan), pthread_self()); ast_channel_blockproc_set
((chan), __PRETTY_FUNCTION__); do { typeof ((ast_channel_flags
(chan))->flags) __p = (ast_channel_flags(chan))->flags;
typeof (__unsigned_int_flags_dummy) __x = 0; (void) (&__p
== &__x); ((ast_channel_flags(chan))->flags |= (AST_FLAG_BLOCKING
)); } while(0); } } while (0)
;
4771 if (ast_channel_tech(chan)->write_text && (ast_format_cap_has_type(ast_channel_nativeformats(chan), AST_MEDIA_TYPE_TEXT))) {
4772 struct ast_frame f;
4773
4774 f.frametype = AST_FRAME_TEXT;
4775 f.src = "DIALPLAN";
4776 f.mallocd = AST_MALLOCD_DATA(1 << 1);
4777 f.datalen = strlen(text);
4778 f.data.ptr = ast_strdup(text)_ast_strdup((text), "channel.c", 4778, __PRETTY_FUNCTION__);
4779 f.offset = 0;
4780 f.seqno = 0;
4781
4782 f.subclass.format = ast_format_t140;
4783 res = ast_channel_tech(chan)->write_text(chan, &f);
4784 } else if (ast_channel_tech(chan)->send_text) {
4785 res = ast_channel_tech(chan)->send_text(chan, text);
4786 }
4787 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags &= ~(AST_FLAG_BLOCKING)); } while(0)
;
4788 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 4788, "chan"
)
;
4789 return res;
4790}
4791
4792int ast_senddigit_begin(struct ast_channel *chan, char digit)
4793{
4794 /* Device does not support DTMF tones, lets fake
4795 * it by doing our own generation. */
4796 static const char * const dtmf_tones[] = {
4797 "941+1336", /* 0 */
4798 "697+1209", /* 1 */
4799 "697+1336", /* 2 */
4800 "697+1477", /* 3 */
4801 "770+1209", /* 4 */
4802 "770+1336", /* 5 */
4803 "770+1477", /* 6 */
4804 "852+1209", /* 7 */
4805 "852+1336", /* 8 */
4806 "852+1477", /* 9 */
4807 "697+1633", /* A */
4808 "770+1633", /* B */
4809 "852+1633", /* C */
4810 "941+1633", /* D */
4811 "941+1209", /* * */
4812 "941+1477" /* # */
4813 };
4814
4815 if (!ast_channel_tech(chan)->send_digit_begin)
4816 return 0;
4817
4818 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 4818, "chan")
;
4819 ast_channel_sending_dtmf_digit_set(chan, digit);
4820 ast_channel_sending_dtmf_tv_set(chan, ast_tvnow());
4821 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 4821, "chan"
)
;
4822
4823 if (!ast_channel_tech(chan)->send_digit_begin(chan, digit))
4824 return 0;
4825
4826 if (digit >= '0' && digit <='9')
4827 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
4828 else if (digit >= 'A' && digit <= 'D')
4829 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
4830 else if (digit == '*')
4831 ast_playtones_start(chan, 0, dtmf_tones[14], 0);
4832 else if (digit == '#')
4833 ast_playtones_start(chan, 0, dtmf_tones[15], 0);
4834 else {
4835 /* not handled */
4836 ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, ast_channel_name(chan))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 4836, __PRETTY_FUNCTION__, "Unable to generate DTMF tone '%c' for '%s'\n"
, digit, ast_channel_name(chan)); } } while (0)
;
4837 }
4838
4839 return 0;
4840}
4841
4842int ast_senddigit_end(struct ast_channel *chan, char digit, unsigned int duration)
4843{
4844 int res = -1;
4845
4846 if (ast_channel_tech(chan)->send_digit_end)
4847 res = ast_channel_tech(chan)->send_digit_end(chan, digit, duration);
4848
4849 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 4849, "chan")
;
4850 if (ast_channel_sending_dtmf_digit(chan) == digit) {
4851 ast_channel_sending_dtmf_digit_set(chan, 0);
4852 }
4853 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 4853, "chan"
)
;
4854
4855 if (res && ast_channel_generator(chan))
4856 ast_playtones_stop(chan);
4857
4858 return 0;
4859}
4860
4861int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration)
4862{
4863 if (ast_channel_tech(chan)->send_digit_begin) {
4864 ast_senddigit_begin(chan, digit);
4865 ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION100 ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION100));
4866 }
4867
4868 return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION100 ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION100));
4869}
4870
4871int ast_prod(struct ast_channel *chan)
4872{
4873 struct ast_frame a = { AST_FRAME_VOICE };
4874 char nothing[128];
4875
4876 /* Send an empty audio frame to get things moving */
4877 if (ast_channel_state(chan) != AST_STATE_UP) {
4878 ast_debug(1, "Prodding channel '%s'\n", ast_channel_name(chan))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 4878, __PRETTY_FUNCTION__, "Prodding channel '%s'\n"
, ast_channel_name(chan)); } } while (0)
;
4879 a.subclass.format = ast_channel_rawwriteformat(chan);
4880 a.data.ptr = nothing + AST_FRIENDLY_OFFSET64;
4881 a.src = "ast_prod"; /* this better match check in ast_write */
4882 if (ast_write(chan, &a))
4883 ast_log(LOG_WARNING3, "channel.c", 4883, __PRETTY_FUNCTION__, "Prodding channel '%s' failed\n", ast_channel_name(chan));
4884 }
4885 return 0;
4886}
4887
4888int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
4889{
4890 int res;
4891 if (!ast_channel_tech(chan)->write_video)
4892 return 0;
4893 res = ast_write(chan, fr);
4894 if (!res)
4895 res = 1;
4896 return res;
4897}
4898
4899struct plc_ds {
4900 /* A buffer in which to store SLIN PLC
4901 * samples generated by the generic PLC
4902 * functionality in plc.c
4903 */
4904 int16_t *samples_buf;
4905 /* The current number of samples in the
4906 * samples_buf
4907 */
4908 size_t num_samples;
4909 plc_state_t plc_state;
4910};
4911
4912static void plc_ds_destroy(void *data)
4913{
4914 struct plc_ds *plc = data;
4915 ast_freefree(plc->samples_buf);
4916 ast_freefree(plc);
4917}
4918
4919static const struct ast_datastore_info plc_ds_info = {
4920 .type = "plc",
4921 .destroy = plc_ds_destroy,
4922};
4923
4924static void adjust_frame_for_plc(struct ast_channel *chan, struct ast_frame *frame, struct ast_datastore *datastore)
4925{
4926 int num_new_samples = frame->samples;
4927 struct plc_ds *plc = datastore->data;
4928
4929 /* As a general note, let me explain the somewhat odd calculations used when taking
4930 * the frame offset into account here. According to documentation in frame.h, the frame's
4931 * offset field indicates the number of bytes that the audio is offset. The plc->samples_buf
4932 * is not an array of bytes, but rather an array of 16-bit integers since it holds SLIN
4933 * samples. So I had two choices to make here with the offset.
4934 *
4935 * 1. Make the offset AST_FRIENDLY_OFFSET bytes. The main downside for this is that
4936 * I can't just add AST_FRIENDLY_OFFSET to the plc->samples_buf and have the pointer
4937 * arithmetic come out right. I would have to do some odd casting or division for this to
4938 * work as I wanted.
4939 * 2. Make the offset AST_FRIENDLY_OFFSET * 2 bytes. This allows the pointer arithmetic
4940 * to work out better with the plc->samples_buf. The downside here is that the buffer's
4941 * allocation contains an extra 64 bytes of unused space.
4942 *
4943 * I decided to go with option 2. This is why in the calloc statement and the statement that
4944 * sets the frame's offset, AST_FRIENDLY_OFFSET is multiplied by 2.
4945 */
4946
4947 /* If this audio frame has no samples to fill in, ignore it */
4948 if (!num_new_samples) {
4949 return;
4950 }
4951
4952 /* First, we need to be sure that our buffer is large enough to accomodate
4953 * the samples we need to fill in. This will likely only occur on the first
4954 * frame we write.
4955 */
4956 if (plc->num_samples < num_new_samples) {
4957 ast_freefree(plc->samples_buf);
4958 plc->samples_buf = ast_calloc(1, (num_new_samples * sizeof(*plc->samples_buf)) + (AST_FRIENDLY_OFFSET * 2))_ast_calloc((1), ((num_new_samples * sizeof(*plc->samples_buf
)) + (64 * 2)), "channel.c", 4958, __PRETTY_FUNCTION__)
;
4959 if (!plc->samples_buf) {
4960 ast_channel_datastore_remove(chan, datastore);
4961 ast_datastore_free(datastore);
4962 return;
4963 }
4964 plc->num_samples = num_new_samples;
4965 }
4966
4967 if (frame->datalen == 0) {
4968 plc_fillin(&plc->plc_state, plc->samples_buf + AST_FRIENDLY_OFFSET64, frame->samples);
4969 frame->data.ptr = plc->samples_buf + AST_FRIENDLY_OFFSET64;
4970 frame->datalen = num_new_samples * 2;
4971 frame->offset = AST_FRIENDLY_OFFSET64 * 2;
4972 } else {
4973 plc_rx(&plc->plc_state, frame->data.ptr, frame->samples);
4974 }
4975}
4976
4977static void apply_plc(struct ast_channel *chan, struct ast_frame *frame)
4978{
4979 struct ast_datastore *datastore;
4980 struct plc_ds *plc;
4981
4982 datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL((void*)0));
4983 if (datastore) {
4984 plc = datastore->data;
4985 adjust_frame_for_plc(chan, frame, datastore);
4986 return;
4987 }
4988
4989 datastore = ast_datastore_alloc(&plc_ds_info, NULL)__ast_datastore_alloc(&plc_ds_info, ((void*)0), "channel.c"
, 4989, __PRETTY_FUNCTION__)
;
4990 if (!datastore) {
4991 return;
4992 }
4993 plc = ast_calloc(1, sizeof(*plc))_ast_calloc((1), (sizeof(*plc)), "channel.c", 4993, __PRETTY_FUNCTION__
)
;
4994 if (!plc) {
4995 ast_datastore_free(datastore);
4996 return;
4997 }
4998 datastore->data = plc;
4999 ast_channel_datastore_add(chan, datastore);
5000 adjust_frame_for_plc(chan, frame, datastore);
5001}
5002
5003int ast_write(struct ast_channel *chan, struct ast_frame *fr)
5004{
5005 int res = -1;
5006 struct ast_frame *f = NULL((void*)0);
5007 int count = 0;
5008
5009 /*Deadlock avoidance*/
5010 while(ast_channel_trylock(chan)__ao2_trylock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5010, "chan")
) {
5011 /*cannot goto done since the channel is not locked*/
5012 if(count++ > 10) {
5013 ast_debug(1, "Deadlock avoided for write to channel '%s'\n", ast_channel_name(chan))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5013, __PRETTY_FUNCTION__, "Deadlock avoided for write to channel '%s'\n"
, ast_channel_name(chan)); } } while (0)
;
5014 return 0;
5015 }
5016 usleep(1);
5017 }
5018 /* Stop if we're a zombie or need a soft hangup */
5019 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_ZOMBIE)); })
|| ast_check_hangup(chan))
5020 goto done;
5021
5022 /* Perform the framehook write event here. After the frame enters the framehook list
5023 * there is no telling what will happen, how awesome is that!!! */
5024 if (!(fr = ast_framehook_list_write_event(ast_channel_framehooks(chan), fr))) {
5025 res = 0;
5026 goto done;
5027 }
5028
5029 if (ast_channel_generatordata(chan) && (!fr->src || strcasecmp(fr->src, "ast_prod"))) {
5030 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_WRITE_INT)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_WRITE_INT)); })
) {
5031 ast_deactivate_generator(chan);
5032 } else {
5033 if (fr->frametype == AST_FRAME_DTMF_END) {
5034 /* There is a generator running while we're in the middle of a digit.
5035 * It's probably inband DTMF, so go ahead and pass it so it can
5036 * stop the generator */
5037 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags &= ~(AST_FLAG_BLOCKING)); } while(0)
;
5038 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 5038, "chan"
)
;
5039 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);
5040 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5040, "chan")
;
5041 CHECK_BLOCKING(chan)do { if (({ typeof ((ast_channel_flags(chan))->flags) __p =
(ast_channel_flags(chan))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(chan))->flags & (AST_FLAG_BLOCKING)); })) { do { if (
(option_debug >= (1) || (({ typeof ((&ast_options)->
flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5041, __PRETTY_FUNCTION__, "Thread %p is blocking '%s', already blocked by thread %p in procedure %s\n"
, (void *) pthread_self(), ast_channel_name(chan), (void *) ast_channel_blocker
(chan), ast_channel_blockproc(chan)); } } while (0); } else {
ast_channel_blocker_set((chan), pthread_self()); ast_channel_blockproc_set
((chan), __PRETTY_FUNCTION__); do { typeof ((ast_channel_flags
(chan))->flags) __p = (ast_channel_flags(chan))->flags;
typeof (__unsigned_int_flags_dummy) __x = 0; (void) (&__p
== &__x); ((ast_channel_flags(chan))->flags |= (AST_FLAG_BLOCKING
)); } while(0); } } while (0)
;
5042 } else if (fr->frametype == AST_FRAME_CONTROL
5043 && fr->subclass.integer == AST_CONTROL_UNHOLD) {
5044 /*
5045 * This is a side case where Echo is basically being called
5046 * and the person put themselves on hold and took themselves
5047 * off hold.
5048 */
5049 indicate_data_internal(chan, fr->subclass.integer, fr->data.ptr,
5050 fr->datalen);
5051 }
5052 res = 0; /* XXX explain, why 0 ? */
5053 goto done;
5054 }
5055 }
5056 /* High bit prints debugging */
5057 if (ast_channel_fout(chan) & DEBUGCHAN_FLAG0x80000000)
5058 ast_frame_dump(ast_channel_name(chan), fr, ">>");
5059 CHECK_BLOCKING(chan)do { if (({ typeof ((ast_channel_flags(chan))->flags) __p =
(ast_channel_flags(chan))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(chan))->flags & (AST_FLAG_BLOCKING)); })) { do { if (
(option_debug >= (1) || (({ typeof ((&ast_options)->
flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5059, __PRETTY_FUNCTION__, "Thread %p is blocking '%s', already blocked by thread %p in procedure %s\n"
, (void *) pthread_self(), ast_channel_name(chan), (void *) ast_channel_blocker
(chan), ast_channel_blockproc(chan)); } } while (0); } else {
ast_channel_blocker_set((chan), pthread_self()); ast_channel_blockproc_set
((chan), __PRETTY_FUNCTION__); do { typeof ((ast_channel_flags
(chan))->flags) __p = (ast_channel_flags(chan))->flags;
typeof (__unsigned_int_flags_dummy) __x = 0; (void) (&__p
== &__x); ((ast_channel_flags(chan))->flags |= (AST_FLAG_BLOCKING
)); } while(0); } } while (0)
;
5060 switch (fr->frametype) {
5061 case AST_FRAME_CONTROL:
5062 indicate_data_internal(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
5063 res = 0;
5064 break;
5065 case AST_FRAME_DTMF_BEGIN:
5066 if (ast_channel_audiohooks(chan)) {
5067 struct ast_frame *old_frame = fr;
5068 fr = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_WRITE, fr);
5069 if (old_frame != fr)
5070 f = fr;
5071 }
5072 send_dtmf_begin_event(chan, DTMF_SENT, fr->subclass.integer);
5073 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags &= ~(AST_FLAG_BLOCKING)); } while(0)
;
5074 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 5074, "chan"
)
;
5075 res = ast_senddigit_begin(chan, fr->subclass.integer);
5076 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5076, "chan")
;
5077 CHECK_BLOCKING(chan)do { if (({ typeof ((ast_channel_flags(chan))->flags) __p =
(ast_channel_flags(chan))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(chan))->flags & (AST_FLAG_BLOCKING)); })) { do { if (
(option_debug >= (1) || (({ typeof ((&ast_options)->
flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5077, __PRETTY_FUNCTION__, "Thread %p is blocking '%s', already blocked by thread %p in procedure %s\n"
, (void *) pthread_self(), ast_channel_name(chan), (void *) ast_channel_blocker
(chan), ast_channel_blockproc(chan)); } } while (0); } else {
ast_channel_blocker_set((chan), pthread_self()); ast_channel_blockproc_set
((chan), __PRETTY_FUNCTION__); do { typeof ((ast_channel_flags
(chan))->flags) __p = (ast_channel_flags(chan))->flags;
typeof (__unsigned_int_flags_dummy) __x = 0; (void) (&__p
== &__x); ((ast_channel_flags(chan))->flags |= (AST_FLAG_BLOCKING
)); } while(0); } } while (0)
;
5078 break;
5079 case AST_FRAME_DTMF_END:
5080 if (ast_channel_audiohooks(chan)) {
5081 struct ast_frame *new_frame = fr;
5082
5083 new_frame = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_WRITE, fr);
5084 if (new_frame != fr) {
5085 ast_frfree(new_frame)ast_frame_free(new_frame, 1);
5086 }
5087 }
5088 send_dtmf_end_event(chan, DTMF_SENT, fr->subclass.integer, fr->len);
5089 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags &= ~(AST_FLAG_BLOCKING)); } while(0)
;
5090 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 5090, "chan"
)
;
5091 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);
5092 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5092, "chan")
;
5093 CHECK_BLOCKING(chan)do { if (({ typeof ((ast_channel_flags(chan))->flags) __p =
(ast_channel_flags(chan))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(chan))->flags & (AST_FLAG_BLOCKING)); })) { do { if (
(option_debug >= (1) || (({ typeof ((&ast_options)->
flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5093, __PRETTY_FUNCTION__, "Thread %p is blocking '%s', already blocked by thread %p in procedure %s\n"
, (void *) pthread_self(), ast_channel_name(chan), (void *) ast_channel_blocker
(chan), ast_channel_blockproc(chan)); } } while (0); } else {
ast_channel_blocker_set((chan), pthread_self()); ast_channel_blockproc_set
((chan), __PRETTY_FUNCTION__); do { typeof ((ast_channel_flags
(chan))->flags) __p = (ast_channel_flags(chan))->flags;
typeof (__unsigned_int_flags_dummy) __x = 0; (void) (&__p
== &__x); ((ast_channel_flags(chan))->flags |= (AST_FLAG_BLOCKING
)); } while(0); } } while (0)
;
5094 break;
5095 case AST_FRAME_TEXT:
5096 if (ast_format_cmp(fr->subclass.format, ast_format_t140) == AST_FORMAT_CMP_EQUAL) {
5097 res = (ast_channel_tech(chan)->write_text == NULL((void*)0)) ? 0 :
5098 ast_channel_tech(chan)->write_text(chan, fr);
5099 } else {
5100 res = (ast_channel_tech(chan)->send_text == NULL((void*)0)) ? 0 :
5101 ast_channel_tech(chan)->send_text(chan, (char *) fr->data.ptr);
5102 }
5103 break;
5104 case AST_FRAME_HTML:
5105 res = (ast_channel_tech(chan)->send_html == NULL((void*)0)) ? 0 :
5106 ast_channel_tech(chan)->send_html(chan, fr->subclass.integer, (char *) fr->data.ptr, fr->datalen);
5107 break;
5108 case AST_FRAME_VIDEO:
5109 /* XXX Handle translation of video codecs one day XXX */
5110 res = (ast_channel_tech(chan)->write_video == NULL((void*)0)) ? 0 :
5111 ast_channel_tech(chan)->write_video(chan, fr);
5112 break;
5113 case AST_FRAME_MODEM:
5114 res = (ast_channel_tech(chan)->write == NULL((void*)0)) ? 0 :
5115 ast_channel_tech(chan)->write(chan, fr);
5116 break;
5117 case AST_FRAME_VOICE:
5118 if (ast_channel_tech(chan)->write == NULL((void*)0))
5119 break; /*! \todo XXX should return 0 maybe ? */
5120
5121 if (ast_opt_generic_plc({ typeof ((&ast_options)->flags) __p = (&ast_options
)->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (void
) (&__p == &__x); ((&ast_options)->flags &
(AST_OPT_FLAG_GENERIC_PLC)); })
&& ast_format_cmp(fr->subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL) {
5122 apply_plc(chan, fr);
5123 }
5124
5125 /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
5126 if (ast_format_cmp(fr->subclass.format, ast_channel_rawwriteformat(chan)) == AST_FORMAT_CMP_EQUAL) {
5127 f = fr;
5128 } else {
5129 if (ast_format_cmp(ast_channel_writeformat(chan), fr->subclass.format) != AST_FORMAT_CMP_EQUAL) {
5130 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN)({ struct ast_str *__ast_str_buf; __ast_str_buf = __builtin_alloca
(sizeof(*__ast_str_buf) + 384); __ast_str_buf->len = 384; __ast_str_buf
->used = 0; __ast_str_buf->ts = ((struct ast_threadstorage
*)2); __ast_str_buf->str[0] = '\0'; (__ast_str_buf); })
;
5131
5132 /*
5133 * We are not setup to write this frame. Things may have changed
5134 * on the peer side of the world and we try to adjust the format to
5135 * make it compatible again. However, bad things can happen if we
5136 * cannot setup a new translation path. Problems range from no
5137 * audio, one-way audio, to garbled audio. The best we can do is
5138 * request the call to hangup since we could not make it compatible.
5139 *
5140 * Being continuously spammed by this message likely indicates a
5141 * problem with the peer because it cannot make up its mind about
5142 * which format to use.
5143 */
5144 ast_debug(1, "Channel %s changing write format from %s to %s, native formats %s\n",do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5148, __PRETTY_FUNCTION__, "Channel %s changing write format from %s to %s, native formats %s\n"
, ast_channel_name(chan), ast_format_get_name(ast_channel_writeformat
(chan)), ast_format_get_name(fr->subclass.format), ast_format_cap_get_names
(ast_channel_nativeformats(chan), &codec_buf)); } } while
(0)
5145 ast_channel_name(chan),do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5148, __PRETTY_FUNCTION__, "Channel %s changing write format from %s to %s, native formats %s\n"
, ast_channel_name(chan), ast_format_get_name(ast_channel_writeformat
(chan)), ast_format_get_name(fr->subclass.format), ast_format_cap_get_names
(ast_channel_nativeformats(chan), &codec_buf)); } } while
(0)
5146 ast_format_get_name(ast_channel_writeformat(chan)),do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5148, __PRETTY_FUNCTION__, "Channel %s changing write format from %s to %s, native formats %s\n"
, ast_channel_name(chan), ast_format_get_name(ast_channel_writeformat
(chan)), ast_format_get_name(fr->subclass.format), ast_format_cap_get_names
(ast_channel_nativeformats(chan), &codec_buf)); } } while
(0)
5147 ast_format_get_name(fr->subclass.format),do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5148, __PRETTY_FUNCTION__, "Channel %s changing write format from %s to %s, native formats %s\n"
, ast_channel_name(chan), ast_format_get_name(ast_channel_writeformat
(chan)), ast_format_get_name(fr->subclass.format), ast_format_cap_get_names
(ast_channel_nativeformats(chan), &codec_buf)); } } while
(0)
5148 ast_format_cap_get_names(ast_channel_nativeformats(chan), &codec_buf))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5148, __PRETTY_FUNCTION__, "Channel %s changing write format from %s to %s, native formats %s\n"
, ast_channel_name(chan), ast_format_get_name(ast_channel_writeformat
(chan)), ast_format_get_name(fr->subclass.format), ast_format_cap_get_names
(ast_channel_nativeformats(chan), &codec_buf)); } } while
(0)
;
5149 if (ast_set_write_format(chan, fr->subclass.format)) {
5150 /* Could not handle the new write format. Induce a hangup. */
5151 break;
5152 }
5153 }
5154 f = ast_channel_writetrans(chan) ? ast_translate(ast_channel_writetrans(chan), fr, 0) : fr;
5155 }
5156
5157 if (!f) {
5158 res = 0;
5159 break;
5160 }
5161
5162 if (ast_channel_audiohooks(chan)) {
5163 struct ast_frame *prev = NULL((void*)0), *new_frame, *cur, *dup;
5164 int freeoldlist = 0;
5165
5166 if (f != fr) {
5167 freeoldlist = 1;
5168 }
5169
5170 /* Since ast_audiohook_write may return a new frame, and the cur frame is
5171 * an item in a list of frames, create a new list adding each cur frame back to it
5172 * regardless if the cur frame changes or not. */
5173 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)((cur)->frame_list.next)) {
5174 new_frame = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_WRITE, cur);
5175
5176 /* if this frame is different than cur, preserve the end of the list,
5177 * free the old frames, and set cur to be the new frame */
5178 if (new_frame != cur) {
5179
5180 /* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame
5181 * isn't part of local storage, meaning if ast_audiohook_write is called multiple
5182 * times it may override the previous frame we got from it unless we dup it */
5183 if ((dup = ast_frisolate(new_frame))) {
5184 AST_LIST_NEXT(dup, frame_list)((dup)->frame_list.next) = AST_LIST_NEXT(cur, frame_list)((cur)->frame_list.next);
5185 if (freeoldlist) {
5186 AST_LIST_NEXT(cur, frame_list)((cur)->frame_list.next) = NULL((void*)0);
5187 ast_frfree(cur)ast_frame_free(cur, 1);
5188 }
5189 if (new_frame != dup) {
5190 ast_frfree(new_frame)ast_frame_free(new_frame, 1);
5191 }
5192 cur = dup;
5193 }
5194 }
5195
5196 /* now, regardless if cur is new or not, add it to the new list,
5197 * if the new list has not started, cur will become the first item. */
5198 if (prev) {
5199 AST_LIST_NEXT(prev, frame_list)((prev)->frame_list.next) = cur;
5200 } else {
5201 f = cur; /* set f to be the beginning of our new list */
5202 }
5203 prev = cur;
5204 }
5205 }
5206
5207 /* If Monitor is running on this channel, then we have to write frames out there too */
5208 /* the translator on chan->writetrans may have returned multiple frames
5209 from the single frame we passed in; if so, feed each one of them to the
5210 monitor */
5211 if (ast_channel_monitor(chan) && ast_channel_monitor(chan)->write_stream) {
5212 struct ast_frame *cur;
5213
5214 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)((cur)->frame_list.next)) {
5215 /* XXX must explain this code */
5216#ifndef MONITOR_CONSTANT_DELAY
5217 int jump = ast_channel_insmpl(chan) - ast_channel_outsmpl(chan) - 4 * cur->samples;
5218 if (jump >= 0) {
5219 jump = calc_monitor_jump((ast_channel_insmpl(chan) - ast_channel_outsmpl(chan)),
5220 ast_format_get_sample_rate(f->subclass.format),
5221 ast_format_get_sample_rate(ast_channel_monitor(chan)->read_stream->fmt->format));
5222 if (ast_seekstream(ast_channel_monitor(chan)->write_stream, jump, SEEK_FORCECUR10) == -1) {
5223 ast_log(LOG_WARNING3, "channel.c", 5223, __PRETTY_FUNCTION__, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
5224 }
5225 ast_channel_outsmpl_set(chan, ast_channel_outsmpl(chan) + (ast_channel_insmpl(chan) - ast_channel_outsmpl(chan)) + cur->samples);
5226 } else {
5227 ast_channel_outsmpl_set(chan, ast_channel_outsmpl(chan) + cur->samples);
5228 }
5229#else
5230 int jump = calc_monitor_jump((ast_channel_insmpl(chan) - ast_channel_outsmpl(chan)),
5231 ast_format_get_sample_rate(f->subclass.codec),
5232 ast_format_get_sample_rate(ast_channel_monitor(chan)->read_stream->fmt->format));
5233 if (jump - MONITOR_DELAY >= 0) {
5234 if (ast_seekstream(ast_channel_monitor(chan)->write_stream, jump - cur->samples, SEEK_FORCECUR10) == -1) {
5235 ast_log(LOG_WARNING3, "channel.c", 5235, __PRETTY_FUNCTION__, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
5236 }
5237 ast_channel_outsmpl_set(chan, ast_channel_outsmpl(chan) + ast_channel_insmpl(chan) - ast_channel_outsmpl(chan));
5238 } else {
5239 ast_channel_outsmpl_set(chan, ast_channel_outsmpl(chan) + cur->samples);
5240 }
5241#endif
5242 if (ast_channel_monitor(chan)->state == AST_MONITOR_RUNNING) {
5243 if (ast_writestream(ast_channel_monitor(chan)->write_stream, cur) < 0)
5244 ast_log(LOG_WARNING3, "channel.c", 5244, __PRETTY_FUNCTION__, "Failed to write data to channel monitor write stream\n");
5245 }
5246 }
5247 }
5248
5249 /* the translator on chan->writetrans may have returned multiple frames
5250 from the single frame we passed in; if so, feed each one of them to the
5251 channel, freeing each one after it has been written */
5252 if ((f != fr) && AST_LIST_NEXT(f, frame_list)((f)->frame_list.next)) {
5253 struct ast_frame *cur, *next = NULL((void*)0);
5254 unsigned int skip = 0;
5255
5256 cur = f;
5257 while (cur) {
5258 next = AST_LIST_NEXT(cur, frame_list)((cur)->frame_list.next);
5259 AST_LIST_NEXT(cur, frame_list)((cur)->frame_list.next) = NULL((void*)0);
5260 if (!skip) {
5261 if ((res = ast_channel_tech(chan)->write(chan, cur)) < 0) {
5262 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
5263 skip = 1;
5264 } else if (next) {
5265 /* don't do this for the last frame in the list,
5266 as the code outside the loop will do it once
5267 */
5268 ast_channel_fout_set(chan, FRAMECOUNT_INC(ast_channel_fout(chan))( ((ast_channel_fout(chan)) & 0x80000000) | (((ast_channel_fout
(chan))+1) & ~0x80000000) )
);
5269 }
5270 }
5271 ast_frfree(cur)ast_frame_free(cur, 1);
5272 cur = next;
5273 }
5274
5275 /* reset f so the code below doesn't attempt to free it */
5276 f = NULL((void*)0);
5277 } else {
5278 res = ast_channel_tech(chan)->write(chan, f);
5279 }
5280 break;
5281 case AST_FRAME_NULL:
5282 case AST_FRAME_IAX:
5283 /* Ignore these */
5284 res = 0;
5285 break;
5286 default:
5287 /* At this point, fr is the incoming frame and f is NULL. Channels do
5288 * not expect to get NULL as a frame pointer and will segfault. Hence,
5289 * we output the original frame passed in. */
5290 res = ast_channel_tech(chan)->write(chan, fr);
5291 break;
5292 }
5293
5294 if (f && f != fr)
5295 ast_frfree(f)ast_frame_free(f, 1);
5296 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags &= ~(AST_FLAG_BLOCKING)); } while(0)
;
5297
5298 /* Consider a write failure to force a soft hangup */
5299 if (res < 0) {
5300 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
5301 } else {
5302 ast_channel_fout_set(chan, FRAMECOUNT_INC(ast_channel_fout(chan))( ((ast_channel_fout(chan)) & 0x80000000) | (((ast_channel_fout
(chan))+1) & ~0x80000000) )
);
5303 }
5304done:
5305 if (ast_channel_audiohooks(chan) && ast_audiohook_write_list_empty(ast_channel_audiohooks(chan))) {
5306 /* The list gets recreated if audiohooks are added again later */
5307 ast_audiohook_detach_list(ast_channel_audiohooks(chan));
5308 ast_channel_audiohooks_set(chan, NULL((void*)0));
5309 }
5310 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 5310, "chan"
)
;
5311 return res;
5312}
5313
5314int ast_set_read_format_path(struct ast_channel *chan, struct ast_format *raw_format, struct ast_format *core_format)
5315{
5316 struct ast_trans_pvt *trans_old;
5317 struct ast_trans_pvt *trans_new;
5318
5319 if (ast_format_cmp(ast_channel_rawreadformat(chan), raw_format) == AST_FORMAT_CMP_EQUAL
5320 && ast_format_cmp(ast_channel_readformat(chan), core_format) == AST_FORMAT_CMP_EQUAL) {
5321 /* Nothing to setup */
5322 return 0;
5323 }
5324
5325 ast_debug(1, "Channel %s setting read format path: %s -> %s\n",do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5328, __PRETTY_FUNCTION__, "Channel %s setting read format path: %s -> %s\n"
, ast_channel_name(chan), ast_format_get_name(raw_format), ast_format_get_name
(core_format)); } } while (0)
5326 ast_channel_name(chan),do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5328, __PRETTY_FUNCTION__, "Channel %s setting read format path: %s -> %s\n"
, ast_channel_name(chan), ast_format_get_name(raw_format), ast_format_get_name
(core_format)); } } while (0)
5327 ast_format_get_name(raw_format),do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5328, __PRETTY_FUNCTION__, "Channel %s setting read format path: %s -> %s\n"
, ast_channel_name(chan), ast_format_get_name(raw_format), ast_format_get_name
(core_format)); } } while (0)
5328 ast_format_get_name(core_format))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5328, __PRETTY_FUNCTION__, "Channel %s setting read format path: %s -> %s\n"
, ast_channel_name(chan), ast_format_get_name(raw_format), ast_format_get_name
(core_format)); } } while (0)
;
5329
5330 /* Setup new translation path. */
5331 if (ast_format_cmp(raw_format, core_format) != AST_FORMAT_CMP_EQUAL) {
5332 trans_new = ast_translator_build_path(core_format, raw_format);
5333 if (!trans_new) {
5334 return -1;
5335 }
5336 } else {
5337 /* No translation needed. */
5338 trans_new = NULL((void*)0);
5339 }
5340 trans_old = ast_channel_readtrans(chan);
5341 if (trans_old) {
5342 ast_translator_free_path(trans_old);
5343 }
5344 ast_channel_readtrans_set(chan, trans_new);
5345 ast_channel_set_rawreadformat(chan, raw_format);
5346 ast_channel_set_readformat(chan, core_format);
5347 return 0;
5348}
5349
5350struct set_format_access {
5351 const char *direction;
5352 struct ast_trans_pvt *(*get_trans)(const struct ast_channel *chan);
5353 void (*set_trans)(struct ast_channel *chan, struct ast_trans_pvt *value);
5354 struct ast_format *(*get_format)(struct ast_channel *chan);
5355 void (*set_format)(struct ast_channel *chan, struct ast_format *format);
5356 struct ast_format *(*get_rawformat)(struct ast_channel *chan);
5357 void (*set_rawformat)(struct ast_channel *chan, struct ast_format *format);
5358 int setoption;
5359};
5360
5361static const struct set_format_access set_format_access_read = {
5362 .direction = "read",
5363 .get_trans = ast_channel_readtrans,
5364 .set_trans = ast_channel_readtrans_set,
5365 .get_format = ast_channel_readformat,
5366 .set_format = ast_channel_set_readformat,
5367 .get_rawformat = ast_channel_rawreadformat,
5368 .set_rawformat = ast_channel_set_rawreadformat,
5369 .setoption = AST_OPTION_FORMAT_READ11,
5370};
5371
5372static const struct set_format_access set_format_access_write = {
5373 .direction = "write",
5374 .get_trans = ast_channel_writetrans,
5375 .set_trans = ast_channel_writetrans_set,
5376 .get_format = ast_channel_writeformat,
5377 .set_format = ast_channel_set_writeformat,
5378 .get_rawformat = ast_channel_rawwriteformat,
5379 .set_rawformat = ast_channel_set_rawwriteformat,
5380 .setoption = AST_OPTION_FORMAT_WRITE12,
5381};
5382
5383static int set_format(struct ast_channel *chan, struct ast_format_cap *cap_set, const int direction)
5384{
5385 struct ast_trans_pvt *trans_pvt;
5386 struct ast_format_cap *cap_native;
5387 const struct set_format_access *access;
5388 struct ast_format *rawformat;
5389 struct ast_format *format;
5390 RAII_VAR(struct ast_format *, best_set_fmt, NULL, ao2_cleanup)_raii_cleanup_block_t _raii_cleanup_best_set_fmt __attribute__
((cleanup(_raii_cleanup_block),unused)) = ((void*)0); __attribute__
((__blocks__(byref))) struct ast_format * best_set_fmt = ((void
*)0); _raii_cleanup_best_set_fmt = ^{ {(void)__ao2_cleanup_debug
((best_set_fmt), "", "channel.c", 5390, __PRETTY_FUNCTION__);
} }
;
5391 RAII_VAR(struct ast_format *, best_native_fmt, NULL, ao2_cleanup)_raii_cleanup_block_t _raii_cleanup_best_native_fmt __attribute__
((cleanup(_raii_cleanup_block),unused)) = ((void*)0); __attribute__
((__blocks__(byref))) struct ast_format * best_native_fmt = (
(void*)0); _raii_cleanup_best_native_fmt = ^{ {(void)__ao2_cleanup_debug
((best_native_fmt), "", "channel.c", 5391, __PRETTY_FUNCTION__
);} }
;
5392 int res;
5393
5394 if (!direction) {
5395 /* reading */
5396 access = &set_format_access_read;
5397 } else {
5398 /* writing */
5399 access = &set_format_access_write;
5400 }
5401
5402 best_set_fmt = ast_format_cap_get_best_by_type(cap_set, AST_MEDIA_TYPE_AUDIO);
5403 if (!best_set_fmt) {
5404 /*
5405 * Not setting any audio formats?
5406 * Assume a call without any sounds (video, text)
5407 */
5408 return 0;
5409 }
5410
5411 /* See if the underlying channel driver is capable of performing transcoding for us */
5412 res = ast_channel_setoption(chan, access->setoption,
5413 &best_set_fmt, sizeof(best_set_fmt), 0);
5414 if (!res) {
5415 ast_debug(1, "Channel driver natively set channel %s to %s format %s\n",do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5416, __PRETTY_FUNCTION__, "Channel driver natively set channel %s to %s format %s\n"
, ast_channel_name(chan), access->direction, ast_format_get_name
(best_set_fmt)); } } while (0)
5416 ast_channel_name(chan), access->direction, ast_format_get_name(best_set_fmt))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5416, __PRETTY_FUNCTION__, "Channel driver natively set channel %s to %s format %s\n"
, ast_channel_name(chan), access->direction, ast_format_get_name
(best_set_fmt)); } } while (0)
;
5417
5418 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5418, "chan")
;
5419 cap_native = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)__ast_format_cap_alloc((AST_FORMAT_CAP_FLAG_DEFAULT), "ast_format_cap_alloc"
, "channel.c", 5419, __PRETTY_FUNCTION__)
;
5420 if (!cap_native
5421 || ast_format_cap_append(cap_native, best_set_fmt, 0)__ast_format_cap_append((cap_native), (best_set_fmt), (0), "ast_format_cap_append"
, "channel.c", 5421, __PRETTY_FUNCTION__)
) {
5422 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 5422, "chan"
)
;
5423 ao2_cleanup(cap_native)__ao2_cleanup_debug((cap_native), "", "channel.c", 5423, __PRETTY_FUNCTION__
)
;
5424 return -1;
5425 }
5426 ast_channel_nativeformats_set(chan, cap_native);
5427 ao2_cleanup(cap_native)__ao2_cleanup_debug((cap_native), "", "channel.c", 5427, __PRETTY_FUNCTION__
)
;
5428 access->set_format(chan, best_set_fmt);
5429 access->set_rawformat(chan, best_set_fmt);
5430
5431 trans_pvt = access->get_trans(chan);
5432 if (trans_pvt) {
5433 ast_translator_free_path(trans_pvt);
5434 access->set_trans(chan, NULL((void*)0));
5435 }
5436 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 5436, "chan"
)
;
5437
5438 /* If there is a generator on the channel, it needs to know about this
5439 * change if it is the write format. */
5440 if (direction && ast_channel_generatordata(chan)) {
5441 generator_write_format_change(chan);
5442 }
5443
5444 return 0;
5445 }
5446
5447 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5447, "chan")
;
5448
5449 format = access->get_format(chan);
5450 rawformat = access->get_rawformat(chan);
5451 ast_assert(format != NULL)_ast_assert(format != ((void*)0), "format != NULL", "channel.c"
, 5451, __PRETTY_FUNCTION__)
;
5452 ast_assert(rawformat != NULL)_ast_assert(rawformat != ((void*)0), "rawformat != NULL", "channel.c"
, 5452, __PRETTY_FUNCTION__)
;
5453
5454 cap_native = ast_channel_nativeformats(chan);
5455 if (ast_format_cap_empty(cap_native)) {
5456 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 5456, "chan"
)
;
5457 ast_log(LOG_ERROR4, "channel.c", 5457, __PRETTY_FUNCTION__, "Unable to set format because channel %s supports no formats\n",
5458 ast_channel_name(chan));
5459 return -1;
5460 }
5461
5462 /* Find a translation path from the native format to one of the desired formats */
5463 if (!direction) {
5464 /* reading */
5465 res = ast_translator_best_choice(cap_set, cap_native, &best_set_fmt, &best_native_fmt);
5466 } else {
5467 /* writing */
5468 res = ast_translator_best_choice(cap_native, cap_set, &best_native_fmt, &best_set_fmt);
5469 }
5470 if (res < 0) {
5471 struct ast_str *codec_native = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN)({ struct ast_str *__ast_str_buf; __ast_str_buf = __builtin_alloca
(sizeof(*__ast_str_buf) + 384); __ast_str_buf->len = 384; __ast_str_buf
->used = 0; __ast_str_buf->ts = ((struct ast_threadstorage
*)2); __ast_str_buf->str[0] = '\0'; (__ast_str_buf); })
;
5472 struct ast_str *codec_set = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN)({ struct ast_str *__ast_str_buf; __ast_str_buf = __builtin_alloca
(sizeof(*__ast_str_buf) + 384); __ast_str_buf->len = 384; __ast_str_buf
->used = 0; __ast_str_buf->ts = ((struct ast_threadstorage
*)2); __ast_str_buf->str[0] = '\0'; (__ast_str_buf); })
;
5473
5474 ast_format_cap_get_names(cap_native, &codec_native);
5475 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 5475, "chan"
)
;
5476 ast_format_cap_get_names(cap_set, &codec_set);
5477
5478 ast_log(LOG_WARNING3, "channel.c", 5478, __PRETTY_FUNCTION__, "Unable to find a codec translation path: %s -> %s\n",
5479 ast_str_buffer(direction ? codec_set : codec_native),
5480 ast_str_buffer(direction ? codec_native : codec_set));
5481 return -1;
5482 }
5483
5484 /* Now we have a good choice for both. */
5485 if ((ast_format_cmp(rawformat, best_native_fmt) != AST_FORMAT_CMP_NOT_EQUAL) &&
5486 (ast_format_cmp(format, best_set_fmt) != AST_FORMAT_CMP_NOT_EQUAL) &&
5487 ((ast_format_cmp(rawformat, format) != AST_FORMAT_CMP_NOT_EQUAL) || access->get_trans(chan))) {
5488 /* the channel is already in these formats, so nothing to do */
5489 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 5489, "chan"
)
;
5490 return 0;
5491 }
5492
5493 /* Free any translation we have right now */
5494 trans_pvt = access->get_trans(chan);
5495 if (trans_pvt) {
5496 ast_translator_free_path(trans_pvt);
5497 access->set_trans(chan, NULL((void*)0));
5498 }
5499
5500 /* Build a translation path from the raw format to the desired format */
5501 if (ast_format_cmp(best_set_fmt, best_native_fmt) != AST_FORMAT_CMP_NOT_EQUAL) {
5502 /*
5503 * If we were able to swap the native format to the format that
5504 * has been requested, then there is no need to try to build
5505 * a translation path.
5506 */
5507 res = 0;
5508 } else {
5509 if (!direction) {
5510 /* reading */
5511 trans_pvt = ast_translator_build_path(best_set_fmt, best_native_fmt);
5512 } else {
5513 /* writing */
5514 trans_pvt = ast_translator_build_path(best_native_fmt, best_set_fmt);
5515 }
5516 access->set_trans(chan, trans_pvt);
5517 res = trans_pvt ? 0 : -1;
5518 }
5519
5520 if (!res) {
5521 access->set_format(chan, best_set_fmt);
5522 access->set_rawformat(chan, best_native_fmt);
5523
5524 ast_debug(1, "Channel %s setting %s format path: %s -> %s\n",do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5528, __PRETTY_FUNCTION__, "Channel %s setting %s format path: %s -> %s\n"
, ast_channel_name(chan), access->direction, ast_format_get_name
(direction ? best_set_fmt : best_native_fmt), ast_format_get_name
(direction ? best_native_fmt : best_set_fmt)); } } while (0)
5525 ast_channel_name(chan),do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5528, __PRETTY_FUNCTION__, "Channel %s setting %s format path: %s -> %s\n"
, ast_channel_name(chan), access->direction, ast_format_get_name
(direction ? best_set_fmt : best_native_fmt), ast_format_get_name
(direction ? best_native_fmt : best_set_fmt)); } } while (0)
5526 access->direction,do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5528, __PRETTY_FUNCTION__, "Channel %s setting %s format path: %s -> %s\n"
, ast_channel_name(chan), access->direction, ast_format_get_name
(direction ? best_set_fmt : best_native_fmt), ast_format_get_name
(direction ? best_native_fmt : best_set_fmt)); } } while (0)
5527 ast_format_get_name(direction ? best_set_fmt : best_native_fmt),do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5528, __PRETTY_FUNCTION__, "Channel %s setting %s format path: %s -> %s\n"
, ast_channel_name(chan), access->direction, ast_format_get_name
(direction ? best_set_fmt : best_native_fmt), ast_format_get_name
(direction ? best_native_fmt : best_set_fmt)); } } while (0)
5528 ast_format_get_name(direction ? best_native_fmt : best_set_fmt))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 5528, __PRETTY_FUNCTION__, "Channel %s setting %s format path: %s -> %s\n"
, ast_channel_name(chan), access->direction, ast_format_get_name
(direction ? best_set_fmt : best_native_fmt), ast_format_get_name
(direction ? best_native_fmt : best_set_fmt)); } } while (0)
;
5529 }
5530
5531 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 5531, "chan"
)
;
5532
5533 /* If there is a generator on the channel, it needs to know about this
5534 * change if it is the write format. */
5535 if (direction && ast_channel_generatordata(chan)) {
5536 generator_write_format_change(chan);
5537 }
5538
5539 return res;
5540}
5541
5542int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
5543{
5544 struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)__ast_format_cap_alloc((AST_FORMAT_CAP_FLAG_DEFAULT), "ast_format_cap_alloc"
, "channel.c", 5544, __PRETTY_FUNCTION__)
;
5545 int res;
5546
5547 ast_assert(format != NULL)_ast_assert(format != ((void*)0), "format != NULL", "channel.c"
, 5547, __PRETTY_FUNCTION__)
;
5548
5549 if (!cap) {
5550 return -1;
5551 }
5552 ast_format_cap_append(cap, format, 0)__ast_format_cap_append((cap), (format), (0), "ast_format_cap_append"
, "channel.c", 5552, __PRETTY_FUNCTION__)
;
5553
5554 res = set_format(chan, cap, 0);
5555
5556 ao2_cleanup(cap)__ao2_cleanup_debug((cap), "", "channel.c", 5556, __PRETTY_FUNCTION__
)
;
5557 return res;
5558}
5559
5560int ast_set_read_format_from_cap(struct ast_channel *chan, struct ast_format_cap *cap)
5561{
5562 return set_format(chan, cap, 0);
5563}
5564
5565int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
5566{
5567 struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)__ast_format_cap_alloc((AST_FORMAT_CAP_FLAG_DEFAULT), "ast_format_cap_alloc"
, "channel.c", 5567, __PRETTY_FUNCTION__)
;
5568 int res;
5569
5570 ast_assert(format != NULL)_ast_assert(format != ((void*)0), "format != NULL", "channel.c"
, 5570, __PRETTY_FUNCTION__)
;
5571
5572 if (!cap) {
5573 return -1;
5574 }
5575 ast_format_cap_append(cap, format, 0)__ast_format_cap_append((cap), (format), (0), "ast_format_cap_append"
, "channel.c", 5575, __PRETTY_FUNCTION__)
;
5576
5577 res = set_format(chan, cap, 1);
5578
5579 ao2_cleanup(cap)__ao2_cleanup_debug((cap), "", "channel.c", 5579, __PRETTY_FUNCTION__
)
;
5580 return res;
5581}
5582
5583int ast_set_write_format_from_cap(struct ast_channel *chan, struct ast_format_cap *cap)
5584{
5585 return set_format(chan, cap, 1);
5586}
5587
5588const char *ast_channel_reason2str(int reason)
5589{
5590 switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */
5591 {
5592 case 0:
5593 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
5594 case AST_CONTROL_HANGUP:
5595 return "Hangup";
5596 case AST_CONTROL_RING:
5597 return "Local Ring";
5598 case AST_CONTROL_RINGING:
5599 return "Remote end Ringing";
5600 case AST_CONTROL_ANSWER:
5601 return "Remote end has Answered";
5602 case AST_CONTROL_BUSY:
5603 return "Remote end is Busy";
5604 case AST_CONTROL_CONGESTION:
5605 return "Congestion (circuits busy)";
5606 default:
5607 return "Unknown Reason!!";
5608 }
5609}
5610
5611static void handle_cause(int cause, int *outstate)
5612{
5613 if (outstate) {
5614 /* compute error and return */
5615 if (cause == AST_CAUSE_BUSY17)
5616 *outstate = AST_CONTROL_BUSY;
5617 else if (cause == AST_CAUSE_CONGESTION34)
5618 *outstate = AST_CONTROL_CONGESTION;
5619 else
5620 *outstate = 0;
5621 }
5622}
5623
5624/*!
5625 * \internal
5626 * \brief Helper function to inherit info from parent channel.
5627 *
5628 * \param new_chan Channel inheriting information.
5629 * \param parent Channel new_chan inherits information.
5630 * \param orig Channel being replaced by the call forward channel.
5631 *
5632 * \return Nothing
5633 */
5634static void call_forward_inherit(struct ast_channel *new_chan, struct ast_channel *parent, struct ast_channel *orig)
5635{
5636 if (!ast_test_flag(ast_channel_flags(parent), AST_FLAG_ZOMBIE)({ typeof ((ast_channel_flags(parent))->flags) __p = (ast_channel_flags
(parent))->flags; typeof (__unsigned_int_flags_dummy) __x =
0; (void) (&__p == &__x); ((ast_channel_flags(parent
))->flags & (AST_FLAG_ZOMBIE)); })
&& !ast_check_hangup(parent)) {
5637 struct ast_party_redirecting redirecting;
5638
5639 /*
5640 * The parent is not a ZOMBIE or hungup so update it with the
5641 * original channel's redirecting information.
5642 */
5643 ast_party_redirecting_init(&redirecting);
5644 ast_channel_lock(orig)__ao2_lock(orig, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5644, "orig")
;
5645 ast_party_redirecting_copy(&redirecting, ast_channel_redirecting(orig));
5646 ast_channel_unlock(orig)__ao2_unlock(orig, "channel.c", __PRETTY_FUNCTION__, 5646, "orig"
)
;
5647 if (ast_channel_redirecting_sub(orig, parent, &redirecting, 0) &&
5648 ast_channel_redirecting_macro(orig, parent, &redirecting, 1, 0)) {
5649 ast_channel_update_redirecting(parent, &redirecting, NULL((void*)0));
5650 }
5651 ast_party_redirecting_free(&redirecting);
5652 }
5653
5654 /* Safely inherit variables and datastores from the parent channel. */
5655 ast_channel_lock_both(parent, new_chan)do { __ao2_lock(parent, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5655, "parent"); while (__ao2_trylock(new_chan, AO2_LOCK_REQ_MUTEX
, "channel.c", __PRETTY_FUNCTION__, 5655, "new_chan")) { __ao2_unlock
(parent, "channel.c", __PRETTY_FUNCTION__, 5655, "parent"); sched_yield
(); __ao2_lock(parent, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5655, "parent"); } } while (0)
;
5656 ast_channel_inherit_variables(parent, new_chan);
5657 ast_channel_datastore_inherit(parent, new_chan);
5658 ast_max_forwards_decrement(new_chan);
5659 ast_channel_unlock(new_chan)__ao2_unlock(new_chan, "channel.c", __PRETTY_FUNCTION__, 5659
, "new_chan")
;
5660 ast_channel_unlock(parent)__ao2_unlock(parent, "channel.c", __PRETTY_FUNCTION__, 5660, "parent"
)
;
5661}
5662
5663struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_channel *orig, int *timeout, struct ast_format_cap *cap, struct outgoing_helper *oh, int *outstate)
5664{
5665 char tmpchan[256];
5666 char forwarder[AST_CHANNEL_NAME80];
5667 struct ast_channel *new_chan = NULL((void*)0);
5668 char *data, *type;
5669 int cause = 0;
5670 int res;
5671
5672 /* gather data and request the new forward channel */
5673 ast_copy_string(tmpchan, ast_channel_call_forward(orig), sizeof(tmpchan));
5674 ast_copy_string(forwarder, ast_channel_name(orig), sizeof(forwarder));
5675 if ((data = strchr(tmpchan, '/')(__extension__ (__builtin_constant_p ('/') && !__builtin_constant_p
(tmpchan) && ('/') == '\0' ? (char *) __rawmemchr (tmpchan
, '/') : __builtin_strchr (tmpchan, '/')))
)) {
5676 *data++ = '\0';
5677 type = tmpchan;
5678 } else {
5679 const char *forward_context;
5680 ast_channel_lock(orig)__ao2_lock(orig, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5680, "orig")
;
5681 forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT");
5682 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", ast_channel_call_forward(orig), S_OR(forward_context, ast_channel_context(orig))({typeof(&((forward_context)[0])) __x = (forward_context)
; _ast_strlen_zero(__x, "channel.c", __PRETTY_FUNCTION__, 5682
) ? (ast_channel_context(orig)) : __x;})
);
5683 ast_channel_unlock(orig)__ao2_unlock(orig, "channel.c", __PRETTY_FUNCTION__, 5683, "orig"
)
;
5684 data = tmpchan;
5685 type = "Local";
5686 }
5687 if (!(new_chan = ast_request(type, cap, NULL((void*)0), orig, data, &cause))) {
5688 ast_log(LOG_NOTICE2, "channel.c", 5688, __PRETTY_FUNCTION__, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause);
5689 handle_cause(cause, outstate);
5690 ast_hangup(orig);
5691 return NULL((void*)0);
5692 }
5693
5694 /* Copy/inherit important information into new channel */
5695 if (oh) {
5696 if (oh->vars) {
5697 ast_channel_lock(new_chan)__ao2_lock(new_chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5697, "new_chan")
;
5698 ast_set_variables(new_chan, oh->vars);
5699 ast_channel_unlock(new_chan)__ao2_unlock(new_chan, "channel.c", __PRETTY_FUNCTION__, 5699
, "new_chan")
;
5700 }
5701 if (oh->parent_channel) {
5702 call_forward_inherit(new_chan, oh->parent_channel, orig);
5703 }
5704 if (!ast_strlen_zero(oh->account)_ast_strlen_zero(oh->account, "channel.c", __PRETTY_FUNCTION__
, 5704)
) {
5705 ast_channel_lock(new_chan)__ao2_lock(new_chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5705, "new_chan")
;
5706 ast_channel_stage_snapshot(new_chan);
5707 ast_channel_accountcode_set(new_chan, oh->account);
5708 ast_channel_peeraccount_set(new_chan, oh->account);
5709 ast_channel_stage_snapshot_done(new_chan);
5710 ast_channel_unlock(new_chan)__ao2_unlock(new_chan, "channel.c", __PRETTY_FUNCTION__, 5710
, "new_chan")
;
5711 }
5712 } else if (caller) { /* no outgoing helper so use caller if available */
5713 call_forward_inherit(new_chan, caller, orig);
5714 }
5715 ast_set_flag(ast_channel_flags(new_chan), AST_FLAG_ORIGINATED)do { typeof ((ast_channel_flags(new_chan))->flags) __p = (
ast_channel_flags(new_chan))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(new_chan))->flags |= (AST_FLAG_ORIGINATED)); } while(0)
;
5716
5717 ast_channel_lock_both(orig, new_chan)do { __ao2_lock(orig, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5717, "orig"); while (__ao2_trylock(new_chan, AO2_LOCK_REQ_MUTEX
, "channel.c", __PRETTY_FUNCTION__, 5717, "new_chan")) { __ao2_unlock
(orig, "channel.c", __PRETTY_FUNCTION__, 5717, "orig"); sched_yield
(); __ao2_lock(orig, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5717, "orig"); } } while (0)
;
5718 pbx_builtin_setvar_helper(new_chan, "FORWARDERNAME", forwarder);
5719 ast_party_connected_line_copy(ast_channel_connected(new_chan), ast_channel_connected(orig));
5720 ast_party_redirecting_copy(ast_channel_redirecting(new_chan), ast_channel_redirecting(orig));
5721 ast_channel_req_accountcodes(new_chan, orig, AST_CHANNEL_REQUESTOR_REPLACEMENT);
5722 ast_channel_unlock(new_chan)__ao2_unlock(new_chan, "channel.c", __PRETTY_FUNCTION__, 5722
, "new_chan")
;
5723 ast_channel_unlock(orig)__ao2_unlock(orig, "channel.c", __PRETTY_FUNCTION__, 5723, "orig"
)
;
5724
5725 /* call new channel */
5726 res = ast_call(new_chan, data, 0);
5727 if (timeout) {
5728 *timeout = res;
5729 }
5730 if (res) {
5731 ast_log(LOG_NOTICE2, "channel.c", 5731, __PRETTY_FUNCTION__, "Unable to call forward to channel %s/%s\n", type, (char *)data);
5732 ast_hangup(orig);
5733 ast_hangup(new_chan);
5734 return NULL((void*)0);
5735 }
5736 ast_hangup(orig);
5737
5738 return new_chan;
5739}
5740
5741struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
5742{
5743 int dummy_outstate;
5744 int cause = 0;
5745 struct ast_channel *chan;
5746 int res = 0;
5747 int last_subclass = 0;
5748 struct ast_party_connected_line connected;
5749
5750 if (outstate)
5751 *outstate = 0;
5752 else
5753 outstate = &dummy_outstate; /* make outstate always a valid pointer */
5754
5755 chan = ast_request(type, cap, assignedids, requestor, addr, &cause);
5756 if (!chan) {
5757 ast_log(LOG_NOTICE2, "channel.c", 5757, __PRETTY_FUNCTION__, "Unable to request channel %s/%s\n", type, addr);
5758 handle_cause(cause, outstate);
5759 return NULL((void*)0);
5760 }
5761
5762 if (oh) {
5763 if (oh->vars) {
5764 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5764, "chan")
;
5765 ast_set_variables(chan, oh->vars);
5766 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 5766, "chan"
)
;
5767 }
5768 if (!ast_strlen_zero(oh->cid_num)_ast_strlen_zero(oh->cid_num, "channel.c", __PRETTY_FUNCTION__
, 5768)
&& !ast_strlen_zero(oh->cid_name)_ast_strlen_zero(oh->cid_name, "channel.c", __PRETTY_FUNCTION__
, 5768)
) {
5769 /*
5770 * Use the oh values instead of the function parameters for the
5771 * outgoing CallerID.
5772 */
5773 cid_num = oh->cid_num;
5774 cid_name = oh->cid_name;
5775 }
5776 if (oh->parent_channel) {
5777 /* Safely inherit variables and datastores from the parent channel. */
5778 ast_channel_lock_both(oh->parent_channel, chan)do { __ao2_lock(oh->parent_channel, AO2_LOCK_REQ_MUTEX, "channel.c"
, __PRETTY_FUNCTION__, 5778, "oh->parent_channel"); while (
__ao2_trylock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5778, "chan")) { __ao2_unlock(oh->parent_channel, "channel.c"
, __PRETTY_FUNCTION__, 5778, "oh->parent_channel"); sched_yield
(); __ao2_lock(oh->parent_channel, AO2_LOCK_REQ_MUTEX, "channel.c"
, __PRETTY_FUNCTION__, 5778, "oh->parent_channel"); } } while
(0)
;
5779 ast_channel_inherit_variables(oh->parent_channel, chan);
5780 ast_channel_datastore_inherit(oh->parent_channel, chan);
5781 ast_max_forwards_decrement(chan);
5782 ast_channel_unlock(oh->parent_channel)__ao2_unlock(oh->parent_channel, "channel.c", __PRETTY_FUNCTION__
, 5782, "oh->parent_channel")
;
5783 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 5783, "chan"
)
;
5784 }
5785 if (!ast_strlen_zero(oh->account)_ast_strlen_zero(oh->account, "channel.c", __PRETTY_FUNCTION__
, 5785)
) {
5786 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5786, "chan")
;
5787 ast_channel_stage_snapshot(chan);
5788 ast_channel_accountcode_set(chan, oh->account);
5789 ast_channel_peeraccount_set(chan, oh->account);
5790 ast_channel_stage_snapshot_done(chan);
5791 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 5791, "chan"
)
;
5792 }
5793 }
5794
5795 /*
5796 * I seems strange to set the CallerID on an outgoing call leg
5797 * to whom we are calling, but this function's callers are doing
5798 * various Originate methods. This call leg goes to the local
5799 * user. Once the local user answers, the dialplan needs to be
5800 * able to access the CallerID from the CALLERID function as if
5801 * the local user had placed this call.
5802 */
5803 ast_set_callerid(chan, cid_num, cid_name, cid_num);
5804
5805 ast_set_flag(ast_channel_flags(chan), AST_FLAG_ORIGINATED)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags |= (AST_FLAG_ORIGINATED)); } while(0)
;
5806 ast_party_connected_line_set_init(&connected, ast_channel_connected(chan));
5807 if (cid_num) {
5808 connected.id.number.valid = 1;
5809 connected.id.number.str = (char *) cid_num;
5810 connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED(0x00 | 0x00);
5811 }
5812 if (cid_name) {
5813 connected.id.name.valid = 1;
5814 connected.id.name.str = (char *) cid_name;
5815 connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED(0x00 | 0x00);
5816 }
5817 ast_channel_set_connected_line(chan, &connected, NULL((void*)0));
5818 if (requestor) {
5819 ast_channel_lock_both(chan, (struct ast_channel *) requestor)do { __ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5819, "chan"); while (__ao2_trylock((struct ast_channel *) requestor
, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__, 5819,
"(struct ast_channel *) requestor")) { __ao2_unlock(chan, "channel.c"
, __PRETTY_FUNCTION__, 5819, "chan"); sched_yield(); __ao2_lock
(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__, 5819
, "chan"); } } while (0)
;
5820 ast_channel_req_accountcodes(chan, requestor, AST_CHANNEL_REQUESTOR_BRIDGE_PEER);
5821 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 5821, "chan"
)
;
5822 ast_channel_unlock((struct ast_channel *) requestor)__ao2_unlock((struct ast_channel *) requestor, "channel.c", __PRETTY_FUNCTION__
, 5822, "(struct ast_channel *) requestor")
;
5823 }
5824
5825 if (ast_call(chan, addr, 0)) { /* ast_call failed... */
5826 ast_log(LOG_NOTICE2, "channel.c", 5826, __PRETTY_FUNCTION__, "Unable to call channel %s/%s\n", type, addr);
5827 } else {
5828 struct timeval start = ast_tvnow();
5829 res = 1; /* mark success in case chan->_state is already AST_STATE_UP */
5830 while (timeout && ast_channel_state(chan) != AST_STATE_UP) {
5831 struct ast_frame *f;
5832 int ms = ast_remaining_ms(start, timeout);
5833
5834 res = ast_waitfor(chan, ms);
5835 if (res == 0) { /* timeout, treat it like ringing */
5836 *outstate = AST_CONTROL_RINGING;
5837 break;
5838 }
5839 if (res < 0) /* error or done */
5840 break;
5841 if (!ast_strlen_zero(ast_channel_call_forward(chan))_ast_strlen_zero(ast_channel_call_forward(chan), "channel.c",
__PRETTY_FUNCTION__, 5841)
) {
5842 if (!(chan = ast_call_forward(NULL((void*)0), chan, NULL((void*)0), cap, oh, outstate))) {
5843 return NULL((void*)0);
5844 }
5845 continue;
5846 }
5847
5848 f = ast_read(chan);
5849 if (!f) {
5850 *outstate = AST_CONTROL_HANGUP;
5851 res = 0;
5852 break;
5853 }
5854 if (f->frametype == AST_FRAME_CONTROL) {
5855 switch (f->subclass.integer) {
5856 case AST_CONTROL_RINGING: /* record but keep going */
5857 *outstate = f->subclass.integer;
5858 break;
5859
5860 case AST_CONTROL_BUSY:
5861 *outstate = f->subclass.integer;
5862 timeout = 0;
5863 break;
5864
5865 case AST_CONTROL_INCOMPLETE:
5866 *outstate = AST_CONTROL_CONGESTION;
5867 timeout = 0;
5868 break;
5869
5870 case AST_CONTROL_CONGESTION:
5871 *outstate = f->subclass.integer;
5872 timeout = 0;
5873 break;
5874
5875 case AST_CONTROL_ANSWER:
5876 *outstate = f->subclass.integer;
5877 timeout = 0; /* trick to force exit from the while() */
5878 break;
5879
5880 case AST_CONTROL_PVT_CAUSE_CODE:
5881 ast_channel_hangupcause_hash_set(chan, f->data.ptr, f->datalen);
5882 break;
5883
5884 case AST_CONTROL_PROGRESS:
5885 if (oh && oh->connect_on_early_media) {
5886 *outstate = f->subclass.integer;
5887 timeout = 0; /* trick to force exit from the while() */
5888 break;
5889 }
5890 /* Fallthrough */
5891 /* Ignore these */
5892 case AST_CONTROL_PROCEEDING:
5893 case AST_CONTROL_HOLD:
5894 case AST_CONTROL_UNHOLD:
5895 case AST_CONTROL_VIDUPDATE:
5896 case AST_CONTROL_SRCUPDATE:
5897 case AST_CONTROL_SRCCHANGE:
5898 case AST_CONTROL_CONNECTED_LINE:
5899 case AST_CONTROL_REDIRECTING:
5900 case AST_CONTROL_CC:
5901 case -1: /* Ignore -- just stopping indications */
5902 break;
5903
5904 default:
5905 ast_log(LOG_NOTICE2, "channel.c", 5905, __PRETTY_FUNCTION__, "Don't know what to do with control frame %d\n", f->subclass.integer);
5906 }
5907 last_subclass = f->subclass.integer;
5908 }
5909 ast_frfree(f)ast_frame_free(f, 1);
5910 }
5911 }
5912
5913 /* Final fixups */
5914 if (oh) {
5915 if (!ast_strlen_zero(oh->context)_ast_strlen_zero(oh->context, "channel.c", __PRETTY_FUNCTION__
, 5915)
)
5916 ast_channel_context_set(chan, oh->context);
5917 if (!ast_strlen_zero(oh->exten)_ast_strlen_zero(oh->exten, "channel.c", __PRETTY_FUNCTION__
, 5917)
)
5918 ast_channel_exten_set(chan, oh->exten);
5919 if (oh->priority)
5920 ast_channel_priority_set(chan, oh->priority);
5921 }
5922 if (ast_channel_state(chan) == AST_STATE_UP)
5923 *outstate = AST_CONTROL_ANSWER;
5924
5925 if (res <= 0) {
5926 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5926, "chan")
;
5927 if (AST_CONTROL_RINGING == last_subclass) {
5928 ast_channel_hangupcause_set(chan, AST_CAUSE_NO_ANSWER19);
5929 }
5930 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 5930, "chan"
)
;
5931 ast_hangup(chan);
5932 chan = NULL((void*)0);
5933 }
5934 return chan;
5935}
5936
5937struct ast_channel *ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int timeout, int *outstate, const char *cidnum, const char *cidname)
5938{
5939 return __ast_request_and_dial(type, cap, assignedids, requestor, addr, timeout, outstate, cidnum, cidname, NULL((void*)0));
5940}
5941
5942static int set_security_requirements(const struct ast_channel *requestor, struct ast_channel *out)
5943{
5944 int ops[2][2] = {
5945 {AST_OPTION_SECURE_SIGNALING18, 0},
5946 {AST_OPTION_SECURE_MEDIA19, 0},
5947 };
5948 int i;
5949 struct ast_channel *r = (struct ast_channel *) requestor; /* UGLY */
5950 struct ast_datastore *ds;
5951
5952 if (!requestor || !out) {
5953 return 0;
5954 }
5955
5956 ast_channel_lock(r)__ao2_lock(r, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 5956, "r")
;
5957 if ((ds = ast_channel_datastore_find(r, &secure_call_info, NULL((void*)0)))) {
5958 struct ast_secure_call_store *encrypt = ds->data;
5959 ops[0][1] = encrypt->signaling;
5960 ops[1][1] = encrypt->media;
5961 } else {
5962 ast_channel_unlock(r)__ao2_unlock(r, "channel.c", __PRETTY_FUNCTION__, 5962, "r");
5963 return 0;
5964 }
5965 ast_channel_unlock(r)__ao2_unlock(r, "channel.c", __PRETTY_FUNCTION__, 5965, "r");
5966
5967 for (i = 0; i < 2; i++) {
5968 if (ops[i][1]) {
5969 if (ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0)) {
5970 /* We require a security feature, but the channel won't provide it */
5971 return -1;
5972 }
5973 } else {
5974 /* We don't care if we can't clear the option on a channel that doesn't support it */
5975 ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0);
5976 }
5977 }
5978
5979 return 0;
5980}
5981
5982struct ast_channel *ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
5983{
5984 struct chanlist *chan;
5985 struct ast_channel *c;
5986 int res;
5987 int foo;
5988
5989 if (!cause)
5990 cause = &foo;
5991 *cause = AST_CAUSE_NOTDEFINED0;
5992
5993 if (AST_RWLIST_RDLOCK(&backends)__ast_rwlock_rdlock("channel.c", 5993, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
) {
5994 ast_log(LOG_WARNING3, "channel.c", 5994, __PRETTY_FUNCTION__, "Unable to lock technology backend list\n");
5995 return NULL((void*)0);
5996 }
5997
5998 AST_RWLIST_TRAVERSE(&backends, chan, list)for((chan) = (&backends)->first; (chan); (chan) = (chan
)->list.next)
{
5999 struct ast_format_cap *tmp_cap;
6000 RAII_VAR(struct ast_format *, tmp_fmt, NULL, ao2_cleanup)_raii_cleanup_block_t _raii_cleanup_tmp_fmt __attribute__((cleanup
(_raii_cleanup_block),unused)) = ((void*)0); __attribute__((__blocks__
(byref))) struct ast_format * tmp_fmt = ((void*)0); _raii_cleanup_tmp_fmt
= ^{ {(void)__ao2_cleanup_debug((tmp_fmt), "", "channel.c", 6000
, __PRETTY_FUNCTION__);} }
;
6001 RAII_VAR(struct ast_format *, best_audio_fmt, NULL, ao2_cleanup)_raii_cleanup_block_t _raii_cleanup_best_audio_fmt __attribute__
((cleanup(_raii_cleanup_block),unused)) = ((void*)0); __attribute__
((__blocks__(byref))) struct ast_format * best_audio_fmt = ((
void*)0); _raii_cleanup_best_audio_fmt = ^{ {(void)__ao2_cleanup_debug
((best_audio_fmt), "", "channel.c", 6001, __PRETTY_FUNCTION__
);} }
;
6002 struct ast_format_cap *joint_cap;
6003
6004 if (strcasecmp(type, chan->tech->type))
6005 continue;
6006
6007 /* find the best audio format to use */
6008 tmp_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)__ast_format_cap_alloc((AST_FORMAT_CAP_FLAG_DEFAULT), "ast_format_cap_alloc"
, "channel.c", 6008, __PRETTY_FUNCTION__)
;
6009 if (tmp_cap) {
6010 ast_format_cap_append_from_cap(tmp_cap, request_cap, AST_MEDIA_TYPE_AUDIO);
6011 /* We have audio - is it possible to connect the various calls to each other?
6012 (Avoid this check for calls without audio, like text+video calls)
6013 */
6014 res = ast_translator_best_choice(tmp_cap, chan->tech->capabilities, &tmp_fmt, &best_audio_fmt);
6015 ao2_ref(tmp_cap, -1)__ao2_ref((tmp_cap), (-1), "", "channel.c", 6015, __PRETTY_FUNCTION__
)
;
6016 if (res < 0) {
6017 struct ast_str *tech_codecs = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN)({ struct ast_str *__ast_str_buf; __ast_str_buf = __builtin_alloca
(sizeof(*__ast_str_buf) + 384); __ast_str_buf->len = 384; __ast_str_buf
->used = 0; __ast_str_buf->ts = ((struct ast_threadstorage
*)2); __ast_str_buf->str[0] = '\0'; (__ast_str_buf); })
;
6018 struct ast_str *request_codecs = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN)({ struct ast_str *__ast_str_buf; __ast_str_buf = __builtin_alloca
(sizeof(*__ast_str_buf) + 384); __ast_str_buf->len = 384; __ast_str_buf
->used = 0; __ast_str_buf->ts = ((struct ast_threadstorage
*)2); __ast_str_buf->str[0] = '\0'; (__ast_str_buf); })
;
6019
6020 ast_log(LOG_WARNING3, "channel.c", 6020, __PRETTY_FUNCTION__, "No translator path exists for channel type %s (native %s) to %s\n", type,
6021 ast_format_cap_get_names(chan->tech->capabilities, &tech_codecs),
6022 ast_format_cap_get_names(request_cap, &request_codecs));
6023 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL58;
6024 AST_RWLIST_UNLOCK(&backends)__ast_rwlock_unlock("channel.c", 6024, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
6025 return NULL((void*)0);
6026 }
6027 }
6028 AST_RWLIST_UNLOCK(&backends)__ast_rwlock_unlock("channel.c", 6028, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
6029 if (!chan->tech->requester)
6030 return NULL((void*)0);
6031
6032 /* XXX Only the audio format calculated as being the best for translation
6033 * purposes is used for the request. This is because we don't have the ability
6034 * to signal to the initiator which one of their codecs that was offered is
6035 * the one that was selected, particularly in a chain of Local channels.
6036 */
6037 joint_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)__ast_format_cap_alloc((AST_FORMAT_CAP_FLAG_DEFAULT), "ast_format_cap_alloc"
, "channel.c", 6037, __PRETTY_FUNCTION__)
;
6038 if (!joint_cap) {
6039 return NULL((void*)0);
6040 }
6041 ast_format_cap_append_from_cap(joint_cap, request_cap, AST_MEDIA_TYPE_UNKNOWN);
6042 ast_format_cap_remove_by_type(joint_cap, AST_MEDIA_TYPE_AUDIO);
6043 ast_format_cap_append(joint_cap, best_audio_fmt, 0)__ast_format_cap_append((joint_cap), (best_audio_fmt), (0), "ast_format_cap_append"
, "channel.c", 6043, __PRETTY_FUNCTION__)
;
6044
6045 if (!(c = chan->tech->requester(type, joint_cap, assignedids, requestor, addr, cause))) {
6046 ao2_ref(joint_cap, -1)__ao2_ref((joint_cap), (-1), "", "channel.c", 6046, __PRETTY_FUNCTION__
)
;
6047 return NULL((void*)0);
6048 }
6049
6050 if (requestor) {
6051 ast_callid callid;
6052
6053 ast_channel_lock_both(c, (struct ast_channel *) requestor)do { __ao2_lock(c, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 6053, "c"); while (__ao2_trylock((struct ast_channel *) requestor
, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__, 6053,
"(struct ast_channel *) requestor")) { __ao2_unlock(c, "channel.c"
, __PRETTY_FUNCTION__, 6053, "c"); sched_yield(); __ao2_lock(
c, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__, 6053
, "c"); } } while (0)
;
6054
6055 /* Set the newly created channel's callid to the same as the requestor. */
6056 callid = ast_channel_callid(requestor);
6057 if (callid) {
6058 ast_channel_callid_set(c, callid);
6059 }
6060
6061 ast_channel_unlock(c)__ao2_unlock(c, "channel.c", __PRETTY_FUNCTION__, 6061, "c");
6062 ast_channel_unlock((struct ast_channel *) requestor)__ao2_unlock((struct ast_channel *) requestor, "channel.c", __PRETTY_FUNCTION__
, 6062, "(struct ast_channel *) requestor")
;
6063 }
6064
6065 ao2_ref(joint_cap, -1)__ao2_ref((joint_cap), (-1), "", "channel.c", 6065, __PRETTY_FUNCTION__
)
;
6066
6067 if (set_security_requirements(requestor, c)) {
6068 ast_log(LOG_WARNING3, "channel.c", 6068, __PRETTY_FUNCTION__, "Setting security requirements failed\n");
6069 c = ast_channel_release(c);
6070 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL58;
6071 return NULL((void*)0);
6072 }
6073
6074 /* no need to generate a Newchannel event here; it is done in the channel_alloc call */
6075 return c;
6076 }
6077
6078 ast_log(LOG_WARNING3, "channel.c", 6078, __PRETTY_FUNCTION__, "No channel type registered for '%s'\n", type);
6079 *cause = AST_CAUSE_NOSUCHDRIVER66;
6080 AST_RWLIST_UNLOCK(&backends)__ast_rwlock_unlock("channel.c", 6080, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
6081
6082 return NULL((void*)0);
6083}
6084
6085/*!
6086 * \internal
6087 * \brief Setup new channel accountcodes from the requestor channel after ast_request().
6088 * \since 13.0.0
6089 *
6090 * \param chan New channel to get accountcodes setup.
6091 * \param requestor Requesting channel to get accountcodes from.
6092 * \param relationship What the new channel was created for.
6093 * \param precious TRUE if pre-existing accountcodes on chan will not be overwritten.
6094 *
6095 * \pre The chan and requestor channels are already locked.
6096 *
6097 * \return Nothing
6098 */
6099static void channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship, int precious)
6100{
6101 /*
6102 * The primary reason for the existence of this function is
6103 * so local channels can propagate accountcodes to the ;2
6104 * channel before ast_call().
6105 *
6106 * The secondary reason is to propagate the CHANNEL(peeraccount)
6107 * value set before Dial, FollowMe, and Queue while maintaining
6108 * the historic straight across accountcode propagation as a
6109 * fallback.
6110 */
6111 switch (relationship) {
6112 case AST_CHANNEL_REQUESTOR_BRIDGE_PEER:
6113 /* Crossover the requestor's accountcode and peeraccount */
6114 if (!precious || ast_strlen_zero(ast_channel_accountcode(chan))_ast_strlen_zero(ast_channel_accountcode(chan), "channel.c", __PRETTY_FUNCTION__
, 6114)
) {
6115 /*
6116 * The newly created channel does not have an accountcode
6117 * or we don't care.
6118 */
6119 if (!ast_strlen_zero(ast_channel_peeraccount(requestor))_ast_strlen_zero(ast_channel_peeraccount(requestor), "channel.c"
, __PRETTY_FUNCTION__, 6119)
) {
6120 /*
6121 * Set it to the requestor's peeraccount. This allows the
6122 * dialplan to indicate the accountcode to use when dialing
6123 * by setting CHANNEL(peeraccount).
6124 */
6125 ast_channel_accountcode_set(chan, ast_channel_peeraccount(requestor));
6126 } else if (!precious
6127 && !ast_strlen_zero(ast_channel_accountcode(requestor))_ast_strlen_zero(ast_channel_accountcode(requestor), "channel.c"
, __PRETTY_FUNCTION__, 6127)
) {
6128 /*
6129 * Fallback to the historic propagation and set it to the
6130 * requestor's accountcode.
6131 */
6132 ast_channel_accountcode_set(chan, ast_channel_accountcode(requestor));
6133 }
6134 }
6135 if (!ast_strlen_zero(ast_channel_accountcode(requestor))_ast_strlen_zero(ast_channel_accountcode(requestor), "channel.c"
, __PRETTY_FUNCTION__, 6135)
) {
6136 ast_channel_peeraccount_set(chan, ast_channel_accountcode(requestor));
6137 }
6138 break;
6139 case AST_CHANNEL_REQUESTOR_REPLACEMENT:
6140 /* Pass the requestor's accountcode and peeraccount straight. */
6141 if (!precious || ast_strlen_zero(ast_channel_accountcode(chan))_ast_strlen_zero(ast_channel_accountcode(chan), "channel.c", __PRETTY_FUNCTION__
, 6141)
) {
6142 /*
6143 * The newly created channel does not have an accountcode
6144 * or we don't care.
6145 */
6146 if (!ast_strlen_zero(ast_channel_accountcode(requestor))_ast_strlen_zero(ast_channel_accountcode(requestor), "channel.c"
, __PRETTY_FUNCTION__, 6146)
) {
6147 ast_channel_accountcode_set(chan, ast_channel_accountcode(requestor));
6148 }
6149 }
6150 if (!ast_strlen_zero(ast_channel_peeraccount(requestor))_ast_strlen_zero(ast_channel_peeraccount(requestor), "channel.c"
, __PRETTY_FUNCTION__, 6150)
) {
6151 ast_channel_peeraccount_set(chan, ast_channel_peeraccount(requestor));
6152 }
6153 break;
6154 }
6155}
6156
6157void ast_channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
6158{
6159 channel_req_accountcodes(chan, requestor, relationship, 0);
6160}
6161
6162void ast_channel_req_accountcodes_precious(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
6163{
6164 channel_req_accountcodes(chan, requestor, relationship, 1);
6165}
6166
6167int ast_pre_call(struct ast_channel *chan, const char *sub_args)
6168{
6169 int (*pre_call)(struct ast_channel *chan, const char *sub_args);
6170
6171 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 6171, "chan")
;
6172 pre_call = ast_channel_tech(chan)->pre_call;
6173 if (pre_call) {
6174 int res;
6175
6176 res = pre_call(chan, sub_args);
6177 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 6177, "chan"
)
;
6178 return res;
6179 }
6180 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 6180, "chan"
)
;
6181 return ast_app_exec_sub(NULL((void*)0), chan, sub_args, 0);
6182}
6183
6184int ast_call(struct ast_channel *chan, const char *addr, int timeout)
6185{
6186 /* Place an outgoing call, but don't wait any longer than timeout ms before returning.
6187 If the remote end does not answer within the timeout, then do NOT hang up, but
6188 return anyway. */
6189 int res = -1;
6190 /* Stop if we're a zombie or need a soft hangup */
6191 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 6191, "chan")
;
6192 if (!ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_ZOMBIE)); })
&& !ast_check_hangup(chan)) {
6193 if (ast_channel_tech(chan)->call)
6194 res = ast_channel_tech(chan)->call(chan, addr, timeout);
6195 ast_set_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags |= (AST_FLAG_OUTGOING)); } while(0)
;
6196 }
6197 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 6197, "chan"
)
;
6198 return res;
6199}
6200
6201/*!
6202 \brief Transfer a call to dest, if the channel supports transfer
6203
6204 Called by:
6205 \arg app_transfer
6206 \arg the manager interface
6207*/
6208int ast_transfer(struct ast_channel *chan, char *dest)
6209{
6210 int res = -1;
6211
6212 /* Stop if we're a zombie or need a soft hangup */
6213 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 6213, "chan")
;
6214 if (!ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_ZOMBIE)); })
&& !ast_check_hangup(chan)) {
6215 if (ast_channel_tech(chan)->transfer) {
6216 res = ast_channel_tech(chan)->transfer(chan, dest);
6217 if (!res)
6218 res = 1;
6219 } else
6220 res = 0;
6221 }
6222 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 6222, "chan"
)
;
6223
6224 if (res <= 0) {
6225 return res;
6226 }
6227
6228 for (;;) {
6229 struct ast_frame *fr;
6230
6231 res = ast_waitfor(chan, -1);
6232
6233 if (res < 0 || !(fr = ast_read(chan))) {
6234 res = -1;
6235 break;
6236 }
6237
6238 if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) {
6239 enum ast_control_transfer *message = fr->data.ptr;
6240
6241 if (*message == AST_TRANSFER_SUCCESS) {
6242 res = 1;
6243 } else {
6244 res = -1;
6245 }
6246
6247 ast_frfree(fr)ast_frame_free(fr, 1);
6248 break;
6249 }
6250
6251 ast_frfree(fr)ast_frame_free(fr, 1);
6252 }
6253
6254 return res;
6255}
6256
6257int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
6258{
6259 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
6260}
6261
6262int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
6263{
6264 int pos = 0; /* index in the buffer where we accumulate digits */
6265 int to = ftimeout;
6266
6267 struct ast_silence_generator *silgen = NULL((void*)0);
6268
6269 /* Stop if we're a zombie or need a soft hangup */
6270 if (ast_test_flag(ast_channel_flags(c), AST_FLAG_ZOMBIE)({ typeof ((ast_channel_flags(c))->flags) __p = (ast_channel_flags
(c))->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (
void) (&__p == &__x); ((ast_channel_flags(c))->flags
& (AST_FLAG_ZOMBIE)); })
|| ast_check_hangup(c))
6271 return -1;
6272 if (!len)
6273 return -1;
6274 for (;;) {
6275 int d;
6276 if (ast_channel_stream(c)) {
6277 d = ast_waitstream_full(c, AST_DIGIT_ANY"0123456789#*ABCD", audiofd, ctrlfd);
6278 ast_stopstream(c);
6279 if (!silgen && ast_opt_transmit_silence({ typeof ((&ast_options)->flags) __p = (&ast_options
)->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (void
) (&__p == &__x); ((&ast_options)->flags &
(AST_OPT_FLAG_TRANSMIT_SILENCE)); })
)
6280 silgen = ast_channel_start_silence_generator(c);
6281 usleep(1000);
6282 if (!d)
6283 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
6284 } else {
6285 if (!silgen && ast_opt_transmit_silence({ typeof ((&ast_options)->flags) __p = (&ast_options
)->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (void
) (&__p == &__x); ((&ast_options)->flags &
(AST_OPT_FLAG_TRANSMIT_SILENCE)); })
)
6286 silgen = ast_channel_start_silence_generator(c);
6287 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
6288 }
6289 if (d < 0) {
6290 ast_channel_stop_silence_generator(c, silgen);
6291 return AST_GETDATA_FAILED;
6292 }
6293 if (d == 0) {
6294 s[pos] = '\0';
6295 ast_channel_stop_silence_generator(c, silgen);
6296 return AST_GETDATA_TIMEOUT;
6297 }
6298 if (d == 1) {
6299 s[pos] = '\0';
6300 ast_channel_stop_silence_generator(c, silgen);
6301 return AST_GETDATA_INTERRUPTED;
6302 }
6303 if (strchr(enders, d)(__extension__ (__builtin_constant_p (d) && !__builtin_constant_p
(enders) && (d) == '\0' ? (char *) __rawmemchr (enders
, d) : __builtin_strchr (enders, d)))
&& (pos == 0)) {
6304 s[pos] = '\0';
6305 ast_channel_stop_silence_generator(c, silgen);
6306 return AST_GETDATA_EMPTY_END_TERMINATED;
6307 }
6308 if (!strchr(enders, d)(__extension__ (__builtin_constant_p (d) && !__builtin_constant_p
(enders) && (d) == '\0' ? (char *) __rawmemchr (enders
, d) : __builtin_strchr (enders, d)))
) {
6309 s[pos++] = d;
6310 }
6311 if (strchr(enders, d)(__extension__ (__builtin_constant_p (d) && !__builtin_constant_p
(enders) && (d) == '\0' ? (char *) __rawmemchr (enders
, d) : __builtin_strchr (enders, d)))
|| (pos >= len)) {
6312 s[pos] = '\0';
6313 ast_channel_stop_silence_generator(c, silgen);
6314 return AST_GETDATA_COMPLETE;
6315 }
6316 to = timeout;
6317 }
6318 /* Never reached */
6319 return 0;
6320}
6321
6322int ast_channel_supports_html(struct ast_channel *chan)
6323{
6324 return (ast_channel_tech(chan)->send_html) ? 1 : 0;
6325}
6326
6327int ast_channel_sendhtml(struct ast_channel *chan, int subclass, const char *data, int datalen)
6328{
6329 if (ast_channel_tech(chan)->send_html)
6330 return ast_channel_tech(chan)->send_html(chan, subclass, data, datalen);
6331 return -1;
6332}
6333
6334int ast_channel_sendurl(struct ast_channel *chan, const char *url)
6335{
6336 return ast_channel_sendhtml(chan, AST_HTML_URL1, url, strlen(url) + 1);
6337}
6338
6339/*! \brief Set up translation from one channel to another */
6340static int ast_channel_make_compatible_helper(struct ast_channel *from, struct ast_channel *to)
6341{
6342 struct ast_format_cap *src_cap;
6343 struct ast_format_cap *dst_cap;
6344 RAII_VAR(struct ast_format *, best_src_fmt, NULL, ao2_cleanup)_raii_cleanup_block_t _raii_cleanup_best_src_fmt __attribute__
((cleanup(_raii_cleanup_block),unused)) = ((void*)0); __attribute__
((__blocks__(byref))) struct ast_format * best_src_fmt = ((void
*)0); _raii_cleanup_best_src_fmt = ^{ {(void)__ao2_cleanup_debug
((best_src_fmt), "", "channel.c", 6344, __PRETTY_FUNCTION__);
} }
;
6345 RAII_VAR(struct ast_format *, best_dst_fmt, NULL, ao2_cleanup)_raii_cleanup_block_t _raii_cleanup_best_dst_fmt __attribute__
((cleanup(_raii_cleanup_block),unused)) = ((void*)0); __attribute__
((__blocks__(byref))) struct ast_format * best_dst_fmt = ((void
*)0); _raii_cleanup_best_dst_fmt = ^{ {(void)__ao2_cleanup_debug
((best_dst_fmt), "", "channel.c", 6345, __PRETTY_FUNCTION__);
} }
;
6346 int no_path;
6347
6348 /*
6349 * We cannot short circuit this code because it is possible to ask
6350 * to make compatible two channels that are "compatible" because
6351 * they already have translation paths setup but together make for
6352 * a sub-optimal path. e.g., The From channel has g722 -> ulaw
6353 * and the To channel has ulaw -> g722. They are "compatible" but
6354 * together the translations are unnecessary and the audio loses
6355 * fidelity in the process.
6356 */
6357
6358 ast_channel_lock_both(from, to)do { __ao2_lock(from, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 6358, "from"); while (__ao2_trylock(to, AO2_LOCK_REQ_MUTEX,
"channel.c", __PRETTY_FUNCTION__, 6358, "to")) { __ao2_unlock
(from, "channel.c", __PRETTY_FUNCTION__, 6358, "from"); sched_yield
(); __ao2_lock(from, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 6358, "from"); } } while (0)
;
6359
6360 src_cap = ast_channel_nativeformats(from); /* shallow copy, do not destroy */
6361 dst_cap = ast_channel_nativeformats(to); /* shallow copy, do not destroy */
6362
6363 /* If there's no audio in this call, don't bother with trying to find a translation path */
6364 if (!ast_format_cap_has_type(src_cap, AST_MEDIA_TYPE_AUDIO)
6365 || !ast_format_cap_has_type(dst_cap, AST_MEDIA_TYPE_AUDIO)) {
6366 ast_channel_unlock(to)__ao2_unlock(to, "channel.c", __PRETTY_FUNCTION__, 6366, "to"
)
;
6367 ast_channel_unlock(from)__ao2_unlock(from, "channel.c", __PRETTY_FUNCTION__, 6367, "from"
)
;
6368 return 0;
6369 }
6370
6371 no_path = ast_translator_best_choice(dst_cap, src_cap, &best_dst_fmt, &best_src_fmt);
6372
6373 ast_channel_unlock(to)__ao2_unlock(to, "channel.c", __PRETTY_FUNCTION__, 6373, "to"
)
;
6374 ast_channel_unlock(from)__ao2_unlock(from, "channel.c", __PRETTY_FUNCTION__, 6374, "from"
)
;
6375
6376 if (no_path) {
6377 ast_log(LOG_WARNING3, "channel.c", 6377, __PRETTY_FUNCTION__, "No path to translate from %s to %s\n",
6378 ast_channel_name(from), ast_channel_name(to));
6379 return -1;
6380 }
6381
6382 /* if the best path is not 'pass through', then
6383 * transcoding is needed; if desired, force transcode path
6384 * to use SLINEAR between channels, but only if there is
6385 * no direct conversion available. If generic PLC is
6386 * desired, then transcoding via SLINEAR is a requirement
6387 */
6388 if (ast_format_cmp(best_dst_fmt, best_src_fmt) == AST_FORMAT_CMP_NOT_EQUAL
6389 && (ast_opt_generic_plc({ typeof ((&ast_options)->flags) __p = (&ast_options
)->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (void
) (&__p == &__x); ((&ast_options)->flags &
(AST_OPT_FLAG_GENERIC_PLC)); })
|| ast_opt_transcode_via_slin({ typeof ((&ast_options)->flags) __p = (&ast_options
)->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (void
) (&__p == &__x); ((&ast_options)->flags &
(AST_OPT_FLAG_TRANSCODE_VIA_SLIN)); })
)) {
6390 int use_slin = (ast_format_cache_is_slinear(best_src_fmt)
6391 || ast_format_cache_is_slinear(best_dst_fmt)) ? 1 : 0;
6392
6393 if (use_slin || ast_translate_path_steps(best_dst_fmt, best_src_fmt) != 1) {
6394 int best_sample_rate = (ast_format_get_sample_rate(best_src_fmt) > ast_format_get_sample_rate(best_dst_fmt)) ?
6395 ast_format_get_sample_rate(best_src_fmt) : ast_format_get_sample_rate(best_dst_fmt);
6396
6397 /* pick the best signed linear format based upon what preserves the sample rate the best. */
6398 ao2_replace(best_src_fmt, ast_format_cache_get_slin_by_rate(best_sample_rate)){ typeof((best_src_fmt)) *__dst___LINE__ = &(best_src_fmt
); typeof((ast_format_cache_get_slin_by_rate(best_sample_rate
))) __src___LINE__ = (ast_format_cache_get_slin_by_rate(best_sample_rate
)); if (__src___LINE__ != *__dst___LINE__) { if (__src___LINE__
) { __ao2_ref((__src___LINE__), (+1), (("")), "channel.c", 6398
, __PRETTY_FUNCTION__); } if (*__dst___LINE__) { __ao2_ref((*
__dst___LINE__), (-1), (("")), "channel.c", 6398, __PRETTY_FUNCTION__
); } *__dst___LINE__ = __src___LINE__; } }
;
6399 }
6400 }
6401
6402 if (ast_set_read_format(from, best_src_fmt)) {
6403 ast_log(LOG_WARNING3, "channel.c", 6403, __PRETTY_FUNCTION__, "Unable to set read format on channel %s to %s\n",
6404 ast_channel_name(from), ast_format_get_name(best_src_fmt));
6405 return -1;
6406 }
6407 if (ast_set_write_format(to, best_src_fmt)) {
6408 ast_log(LOG_WARNING3, "channel.c", 6408, __PRETTY_FUNCTION__, "Unable to set write format on channel %s to %s\n",
6409 ast_channel_name(to), ast_format_get_name(best_src_fmt));
6410 return -1;
6411 }
6412 return 0;
6413}
6414
6415int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
6416{
6417 /*
6418 * Set up translation from the peer to the chan first in case we
6419 * need to hear any in-band tones and the other direction fails.
6420 */
6421 if (ast_channel_make_compatible_helper(peer, chan)) {
6422 return -1;
6423 }
6424
6425 /* Set up translation from the chan to the peer */
6426 if (ast_channel_make_compatible_helper(chan, peer)) {
6427 return -1;
6428 }
6429
6430 return 0;
6431}
6432
6433/*! \brief this function simply changes the name of the channel and issues a manager_event
6434 * with out unlinking and linking the channel from the ao2_container. This should
6435 * only be used when the channel has already been unlinked from the ao2_container.
6436 */
6437static void __ast_change_name_nolink(struct ast_channel *chan, const char *newname)
6438{
6439 /*** DOCUMENTATION
6440 <managerEventInstance>
6441 <synopsis>Raised when the name of a channel is changed.</synopsis>
6442 </managerEventInstance>
6443 ***/
6444 ast_manager_event(chan, EVENT_FLAG_CALL, "Rename",do { struct ast_channel *_chans[] = { chan, }; __ast_manager_event_multichan
((1 << 1), "Rename", 1, _chans, "channel.c", 6448, __PRETTY_FUNCTION__
, "Channel: %s\r\n" "Newname: %s\r\n" "Uniqueid: %s\r\n" , ast_channel_name
(chan), newname, ast_channel_uniqueid(chan)); } while (0)
6445 "Channel: %s\r\n"do { struct ast_channel *_chans[] = { chan, }; __ast_manager_event_multichan
((1 << 1), "Rename", 1, _chans, "channel.c", 6448, __PRETTY_FUNCTION__
, "Channel: %s\r\n" "Newname: %s\r\n" "Uniqueid: %s\r\n" , ast_channel_name
(chan), newname, ast_channel_uniqueid(chan)); } while (0)
6446 "Newname: %s\r\n"do { struct ast_channel *_chans[] = { chan, }; __ast_manager_event_multichan
((1 << 1), "Rename", 1, _chans, "channel.c", 6448, __PRETTY_FUNCTION__
, "Channel: %s\r\n" "Newname: %s\r\n" "Uniqueid: %s\r\n" , ast_channel_name
(chan), newname, ast_channel_uniqueid(chan)); } while (0)
6447 "Uniqueid: %s\r\n",do { struct ast_channel *_chans[] = { chan, }; __ast_manager_event_multichan
((1 << 1), "Rename", 1, _chans, "channel.c", 6448, __PRETTY_FUNCTION__
, "Channel: %s\r\n" "Newname: %s\r\n" "Uniqueid: %s\r\n" , ast_channel_name
(chan), newname, ast_channel_uniqueid(chan)); } while (0)
6448 ast_channel_name(chan), newname, ast_channel_uniqueid(chan))do { struct ast_channel *_chans[] = { chan, }; __ast_manager_event_multichan
((1 << 1), "Rename", 1, _chans, "channel.c", 6448, __PRETTY_FUNCTION__
, "Channel: %s\r\n" "Newname: %s\r\n" "Uniqueid: %s\r\n" , ast_channel_name
(chan), newname, ast_channel_uniqueid(chan)); } while (0)
;
6449 ast_channel_name_set(chan, newname);
6450}
6451
6452void ast_change_name(struct ast_channel *chan, const char *newname)
6453{
6454 /* We must re-link, as the hash value will change here. */
6455 ao2_lock(channels)__ao2_lock(channels, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 6455, "channels")
;
6456 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 6456, "chan")
;
6457 ao2_unlink(channels, chan)__ao2_unlink((channels), (chan), 0, "", "channel.c", 6457, __PRETTY_FUNCTION__
)
;
6458 __ast_change_name_nolink(chan, newname);
6459 ao2_link(channels, chan)__ao2_link((channels), (chan), 0, "", "channel.c", 6459, __PRETTY_FUNCTION__
)
;
6460 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 6460, "chan"
)
;
6461 ao2_unlock(channels)__ao2_unlock(channels, "channel.c", __PRETTY_FUNCTION__, 6461
, "channels")
;
6462}
6463
6464void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
6465{
6466 struct ast_var_t *current;
6467 struct ast_var_t *newvar;
6468 const char *varname;
6469 int vartype;
6470
6471 AST_LIST_TRAVERSE(ast_channel_varshead((struct ast_channel *) parent), current, entries)for((current) = (ast_channel_varshead((struct ast_channel *) parent
))->first; (current); (current) = (current)->entries.next
)
{
6472 varname = ast_var_full_name(current);
6473 if (!varname) {
6474 continue;
6475 }
6476
6477 vartype = 0;
6478 if (varname[0] == '_') {
6479 vartype = 1;
6480 if (varname[1] == '_') {
6481 vartype = 2;
6482 }
6483 }
6484
6485 switch (vartype) {
6486 case 1:
6487 newvar = ast_var_assign(&varname[1], ast_var_value(current));
6488 break;
6489 case 2:
6490 newvar = ast_var_assign(varname, ast_var_value(current));
6491 break;
6492 default:
6493 continue;
6494 }
6495 if (newvar) {
6496 ast_debug(1, "Inheriting variable %s from %s to %s.\n",do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 6498, __PRETTY_FUNCTION__, "Inheriting variable %s from %s to %s.\n"
, ast_var_full_name(newvar), ast_channel_name(parent), ast_channel_name
(child)); } } while (0)
6497 ast_var_full_name(newvar), ast_channel_name(parent),do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 6498, __PRETTY_FUNCTION__, "Inheriting variable %s from %s to %s.\n"
, ast_var_full_name(newvar), ast_channel_name(parent), ast_channel_name
(child)); } } while (0)
6498 ast_channel_name(child))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 6498, __PRETTY_FUNCTION__, "Inheriting variable %s from %s to %s.\n"
, ast_var_full_name(newvar), ast_channel_name(parent), ast_channel_name
(child)); } } while (0)
;
6499 AST_LIST_INSERT_TAIL(ast_channel_varshead(child), newvar, entries)do { if (!(ast_channel_varshead(child))->first) { (ast_channel_varshead
(child))->first = (newvar); (ast_channel_varshead(child))->
last = (newvar); } else { (ast_channel_varshead(child))->last
->entries.next = (newvar); (ast_channel_varshead(child))->
last = (newvar); } } while (0)
;
6500 ast_channel_publish_varset(child, ast_var_full_name(newvar),
6501 ast_var_value(newvar));
6502 }
6503 }
6504}
6505
6506/*!
6507 \brief Clone channel variables from 'clone' channel into 'original' channel
6508
6509 All variables except those related to app_groupcount are cloned.
6510 Variables are actually _removed_ from 'clone' channel, presumably
6511 because it will subsequently be destroyed.
6512
6513 \note Assumes locks will be in place on both channels when called.
6514*/
6515static void clone_variables(struct ast_channel *original, struct ast_channel *clonechan)
6516{
6517 struct ast_var_t *current, *newvar;
6518 /* Append variables from clone channel into original channel */
6519 /* XXX Is this always correct? We have to in order to keep MACROS working XXX */
6520 AST_LIST_APPEND_LIST(ast_channel_varshead(original), ast_channel_varshead(clonechan), entries)do { if (!(ast_channel_varshead(clonechan))->first) { break
; } if (!(ast_channel_varshead(original))->first) { (ast_channel_varshead
(original))->first = (ast_channel_varshead(clonechan))->
first; (ast_channel_varshead(original))->last = (ast_channel_varshead
(clonechan))->last; } else { (ast_channel_varshead(original
))->last->entries.next = (ast_channel_varshead(clonechan
))->first; (ast_channel_varshead(original))->last = (ast_channel_varshead
(clonechan))->last; } (ast_channel_varshead(clonechan))->
first = ((void*)0); (ast_channel_varshead(clonechan))->last
= ((void*)0); } while (0)
;
6521
6522 /* then, dup the varshead list into the clone */
6523
6524 AST_LIST_TRAVERSE(ast_channel_varshead(original), current, entries)for((current) = (ast_channel_varshead(original))->first; (
current); (current) = (current)->entries.next)
{
6525 newvar = ast_var_assign(current->name, current->value);
6526 if (newvar)
6527 AST_LIST_INSERT_TAIL(ast_channel_varshead(clonechan), newvar, entries)do { if (!(ast_channel_varshead(clonechan))->first) { (ast_channel_varshead
(clonechan))->first = (newvar); (ast_channel_varshead(clonechan
))->last = (newvar); } else { (ast_channel_varshead(clonechan
))->last->entries.next = (newvar); (ast_channel_varshead
(clonechan))->last = (newvar); } } while (0)
;
6528 }
6529}
6530
6531
6532void ast_channel_name_to_dial_string(char *channel_name)
6533{
6534 char *dash;
6535
6536 /* Truncate after the dash */
6537 dash = strrchr(channel_name, '-');
6538 if (dash) {
6539 *dash = '\0';
6540 }
6541}
6542
6543/*!
6544 * \brief Masquerade a channel
6545 *
6546 * \note Assumes _NO_ channels and _NO_ channel pvt's are locked. If a channel is locked while calling
6547 * this function, it invalidates our channel container locking order. All channels
6548 * must be unlocked before it is permissible to lock the channels' ao2 container.
6549 */
6550static void channel_do_masquerade(struct ast_channel *original, struct ast_channel *clonechan)
6551{
6552 int x;
6553 int origstate;
6554 unsigned int orig_disablestatecache;
6555 unsigned int clone_disablestatecache;
6556 int visible_indication;
6557 int clone_hold_state;
6558 int moh_is_playing;
6559 struct ast_frame *current;
6560 const struct ast_channel_tech *t;
6561 void *t_pvt;
6562 union {
6563 struct ast_hangup_handler_list handlers;
6564 struct ast_party_dialed dialed;
6565 struct ast_party_caller caller;
6566 struct ast_party_connected_line connected;
6567 struct ast_party_redirecting redirecting;
6568 } exchange;
6569 struct ast_channel *bridged;
6570 struct ast_format *rformat;
6571 struct ast_format *wformat;
6572 struct ast_format *tmp_format;
6573 struct ast_format_cap *tmp_cap;
6574 char tmp_name[AST_CHANNEL_NAME80];
6575 char clone_sending_dtmf_digit;
6576 struct timeval clone_sending_dtmf_tv;
6577
6578 /* XXX This operation is a bit odd. We're essentially putting the guts of
6579 * the clone channel into the original channel. Start by killing off the
6580 * original channel's backend. While the features are nice, which is the
6581 * reason we're keeping it, it's still awesomely weird. XXX */
6582
6583 /* Indicate to each channel that a masquerade is about to begin. */
6584 x = 1;
6585 ast_indicate_data(original, AST_CONTROL_MASQUERADE_NOTIFY, &x, sizeof(x));
6586 ast_indicate_data(clonechan, AST_CONTROL_MASQUERADE_NOTIFY, &x, sizeof(x));
6587
6588 /*
6589 * The container lock is necessary for proper locking order
6590 * because the channels must be unlinked to change their
6591 * names.
6592 *
6593 * The original and clonechan locks must be held while the
6594 * channel contents are shuffled around for the masquerade.
6595 *
6596 * The masq and masqr pointers need to be left alone until the masquerade
6597 * has restabilized the channels to hold off ast_hangup() and until
6598 * AST_FLAG_ZOMBIE can be set on the clonechan.
6599 */
6600 ao2_lock(channels)__ao2_lock(channels, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 6600, "channels")
;
6601
6602 /* Bump the refs to ensure that they won't dissapear on us. */
6603 ast_channel_ref(original)({ __ao2_ref((original), (+1), "", "channel.c", 6603, __PRETTY_FUNCTION__
); (original); })
;
6604 ast_channel_ref(clonechan)({ __ao2_ref((clonechan), (+1), "", "channel.c", 6604, __PRETTY_FUNCTION__
); (clonechan); })
;
6605
6606 /* unlink from channels container as name (which is the hash value) will change */
6607 ao2_unlink(channels, original)__ao2_unlink((channels), (original), 0, "", "channel.c", 6607
, __PRETTY_FUNCTION__)
;
6608 ao2_unlink(channels, clonechan)__ao2_unlink((channels), (clonechan), 0, "", "channel.c", 6608
, __PRETTY_FUNCTION__)
;
6609
6610 moh_is_playing = ast_test_flag(ast_channel_flags(original), AST_FLAG_MOH)({ typeof ((ast_channel_flags(original))->flags) __p = (ast_channel_flags
(original))->flags; typeof (__unsigned_int_flags_dummy) __x
= 0; (void) (&__p == &__x); ((ast_channel_flags(original
))->flags & (AST_FLAG_MOH)); })
;
6611 if (moh_is_playing) {
6612 /* Stop MOH on the old original channel. */
6613 ast_moh_stop(original);
6614 }
6615
6616 /*
6617 * Stop any visible indication on the original channel so we can
6618 * transfer it to the clonechan taking the original's place.
6619 */
6620 ast_channel_lock(original)__ao2_lock(original, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 6620, "original")
;
6621 visible_indication = ast_channel_visible_indication(original);
6622 ast_channel_unlock(original)__ao2_unlock(original, "channel.c", __PRETTY_FUNCTION__, 6622
, "original")
;
6623 ast_indicate(original, -1);
6624
6625 /* Start the masquerade channel contents rearangement. */
6626 ast_channel_lock_both(original, clonechan)do { __ao2_lock(original, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 6626, "original"); while (__ao2_trylock(clonechan, AO2_LOCK_REQ_MUTEX
, "channel.c", __PRETTY_FUNCTION__, 6626, "clonechan")) { __ao2_unlock
(original, "channel.c", __PRETTY_FUNCTION__, 6626, "original"
); sched_yield(); __ao2_lock(original, AO2_LOCK_REQ_MUTEX, "channel.c"
, __PRETTY_FUNCTION__, 6626, "original"); } } while (0)
;
6627
6628 ast_debug(1, "Actually Masquerading %s(%u) into the structure of %s(%u)\n",do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 6630, __PRETTY_FUNCTION__, "Actually Masquerading %s(%u) into the structure of %s(%u)\n"
, ast_channel_name(clonechan), ast_channel_state(clonechan), ast_channel_name
(original), ast_channel_state(original)); } } while (0)
6629 ast_channel_name(clonechan), ast_channel_state(clonechan),do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 6630, __PRETTY_FUNCTION__, "Actually Masquerading %s(%u) into the structure of %s(%u)\n"
, ast_channel_name(clonechan), ast_channel_state(clonechan), ast_channel_name
(original), ast_channel_state(original)); } } while (0)
6630 ast_channel_name(original), ast_channel_state(original))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 6630, __PRETTY_FUNCTION__, "Actually Masquerading %s(%u) into the structure of %s(%u)\n"
, ast_channel_name(clonechan), ast_channel_state(clonechan), ast_channel_name
(original), ast_channel_state(original)); } } while (0)
;
6631
6632 /*
6633 * Remember the original read/write formats. We turn off any
6634 * translation on either one
6635 */
6636 rformat = ao2_bump(ast_channel_readformat(original))({ typeof((ast_channel_readformat(original))) __obj___LINE__ =
((ast_channel_readformat(original))); if (__obj___LINE__) { __ao2_ref
((__obj___LINE__), (+1), (("")), "channel.c", 6636, __PRETTY_FUNCTION__
); } __obj___LINE__; })
;
6637 wformat = ao2_bump(ast_channel_writeformat(original))({ typeof((ast_channel_writeformat(original))) __obj___LINE__
= ((ast_channel_writeformat(original))); if (__obj___LINE__)
{ __ao2_ref((__obj___LINE__), (+1), (("")), "channel.c", 6637
, __PRETTY_FUNCTION__); } __obj___LINE__; })
;
6638 free_translation(clonechan);
6639 free_translation(original);
6640
6641 clone_hold_state = ast_channel_hold_state(clonechan);
6642
6643 /* Save the current DTMF digit being sent if any. */
6644 clone_sending_dtmf_digit = ast_channel_sending_dtmf_digit(clonechan);
6645 clone_sending_dtmf_tv = ast_channel_sending_dtmf_tv(clonechan);
6646
6647 /* Swap uniqueid's of the channels. This needs to happen before channel renames,
6648 * so rename events get the proper id's.
6649 */
6650 ast_channel_internal_swap_uniqueid_and_linkedid(clonechan, original);
6651
6652 /* Make sure the Stasis topic on the channel is updated appropriately */
6653 ast_channel_internal_swap_topics(clonechan, original);
6654
6655 /* Swap channel names. This uses ast_channel_name_set directly, so we
6656 * don't get any spurious rename events.
6657 */
6658 ast_copy_string(tmp_name, ast_channel_name(clonechan), sizeof(tmp_name));
6659 ast_channel_name_set(clonechan, ast_channel_name(original));
6660 ast_channel_name_set(original, tmp_name);
6661
6662 /* Swap the technologies */
6663 t = ast_channel_tech(original);
6664 ast_channel_tech_set(original, ast_channel_tech(clonechan));
6665 ast_channel_tech_set(clonechan, t);
6666
6667 t_pvt = ast_channel_tech_pvt(original);
6668 ast_channel_tech_pvt_set(original, ast_channel_tech_pvt(clonechan));
6669 ast_channel_tech_pvt_set(clonechan, t_pvt);
6670
6671 /* Swap the alertpipes */
6672 ast_channel_internal_alertpipe_swap(original, clonechan);
6673
6674 /*
6675 * Swap the readq's. The end result should be this:
6676 *
6677 * 1) All frames should be on the new (original) channel.
6678 * 2) Any frames that were already on the new channel before this
6679 * masquerade need to be at the end of the readq, after all of the
6680 * frames on the old (clone) channel.
6681 * 3) The alertpipe needs to get poked for every frame that was already
6682 * on the new channel, since we are now using the alert pipe from the
6683 * old (clone) channel.
6684 */
6685 {
6686 AST_LIST_HEAD_NOLOCK(, ast_frame)struct { struct ast_frame *first; struct ast_frame *last; } tmp_readq;
6687
6688 AST_LIST_HEAD_INIT_NOLOCK(&tmp_readq){ (&tmp_readq)->first = ((void*)0); (&tmp_readq)->
last = ((void*)0); }
;
6689 AST_LIST_APPEND_LIST(&tmp_readq, ast_channel_readq(original), frame_list)do { if (!(ast_channel_readq(original))->first) { break; }
if (!(&tmp_readq)->first) { (&tmp_readq)->first
= (ast_channel_readq(original))->first; (&tmp_readq)->
last = (ast_channel_readq(original))->last; } else { (&
tmp_readq)->last->frame_list.next = (ast_channel_readq(
original))->first; (&tmp_readq)->last = (ast_channel_readq
(original))->last; } (ast_channel_readq(original))->first
= ((void*)0); (ast_channel_readq(original))->last = ((void
*)0); } while (0)
;
6690 AST_LIST_APPEND_LIST(ast_channel_readq(original), ast_channel_readq(clonechan), frame_list)do { if (!(ast_channel_readq(clonechan))->first) { break; }
if (!(ast_channel_readq(original))->first) { (ast_channel_readq
(original))->first = (ast_channel_readq(clonechan))->first
; (ast_channel_readq(original))->last = (ast_channel_readq
(clonechan))->last; } else { (ast_channel_readq(original))
->last->frame_list.next = (ast_channel_readq(clonechan)
)->first; (ast_channel_readq(original))->last = (ast_channel_readq
(clonechan))->last; } (ast_channel_readq(clonechan))->first
= ((void*)0); (ast_channel_readq(clonechan))->last = ((void
*)0); } while (0)
;
6691
6692 while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list)({ typeof((&tmp_readq)->first) __cur = (&tmp_readq
)->first; if (__cur) { (&tmp_readq)->first = __cur->
frame_list.next; __cur->frame_list.next = ((void*)0); if (
(&tmp_readq)->last == __cur) (&tmp_readq)->last
= ((void*)0); } __cur; })
)) {
6693 AST_LIST_INSERT_TAIL(ast_channel_readq(original), current, frame_list)do { if (!(ast_channel_readq(original))->first) { (ast_channel_readq
(original))->first = (current); (ast_channel_readq(original
))->last = (current); } else { (ast_channel_readq(original
))->last->frame_list.next = (current); (ast_channel_readq
(original))->last = (current); } } while (0)
;
6694 if (ast_channel_alert_write(original)) {
6695 ast_log(LOG_WARNING3, "channel.c", 6695, __PRETTY_FUNCTION__, "write() failed: %s\n", strerror(errno(*__errno_location ())));
6696 }
6697 }
6698 }
6699
6700 /* Swap the raw formats */
6701 tmp_format = ao2_bump(ast_channel_rawreadformat(original))({ typeof((ast_channel_rawreadformat(original))) __obj___LINE__
= ((ast_channel_rawreadformat(original))); if (__obj___LINE__
) { __ao2_ref((__obj___LINE__), (+1), (("")), "channel.c", 6701
, __PRETTY_FUNCTION__); } __obj___LINE__; })
;
6702 ast_channel_set_rawreadformat(original, ast_channel_rawreadformat(clonechan));
6703 ast_channel_set_rawreadformat(clonechan, tmp_format);
6704 ao2_cleanup(tmp_format)__ao2_cleanup_debug((tmp_format), "", "channel.c", 6704, __PRETTY_FUNCTION__
)
;
6705
6706 tmp_format = ao2_bump(ast_channel_rawwriteformat(original))({ typeof((ast_channel_rawwriteformat(original))) __obj___LINE__
= ((ast_channel_rawwriteformat(original))); if (__obj___LINE__
) { __ao2_ref((__obj___LINE__), (+1), (("")), "channel.c", 6706
, __PRETTY_FUNCTION__); } __obj___LINE__; })
;
6707 ast_channel_set_rawwriteformat(original, ast_channel_rawwriteformat(clonechan));
6708 ast_channel_set_rawwriteformat(clonechan, tmp_format);
6709 ao2_cleanup(tmp_format)__ao2_cleanup_debug((tmp_format), "", "channel.c", 6709, __PRETTY_FUNCTION__
)
;
6710
6711 ast_channel_softhangup_internal_flag_set(clonechan, AST_SOFTHANGUP_DEV);
6712
6713 /* And of course, so does our current state. Note we need not
6714 call ast_setstate since the event manager doesn't really consider
6715 these separate. We do this early so that the clone has the proper
6716 state of the original channel. */
6717 origstate = ast_channel_state(original);
6718 ast_channel_state_set(original, ast_channel_state(clonechan));
6719 ast_channel_state_set(clonechan, origstate);
6720
6721 /* And the swap the cachable state too. Otherwise we'd start caching
6722 * Local channels and ignoring real ones. */
6723 orig_disablestatecache = ast_test_flag(ast_channel_flags(original), AST_FLAG_DISABLE_DEVSTATE_CACHE)({ typeof ((ast_channel_flags(original))->flags) __p = (ast_channel_flags
(original))->flags; typeof (__unsigned_int_flags_dummy) __x
= 0; (void) (&__p == &__x); ((ast_channel_flags(original
))->flags & (AST_FLAG_DISABLE_DEVSTATE_CACHE)); })
;
6724 clone_disablestatecache = ast_test_flag(ast_channel_flags(clonechan), AST_FLAG_DISABLE_DEVSTATE_CACHE)({ typeof ((ast_channel_flags(clonechan))->flags) __p = (ast_channel_flags
(clonechan))->flags; typeof (__unsigned_int_flags_dummy) __x
= 0; (void) (&__p == &__x); ((ast_channel_flags(clonechan
))->flags & (AST_FLAG_DISABLE_DEVSTATE_CACHE)); })
;
6725 if (orig_disablestatecache != clone_disablestatecache) {
6726 if (orig_disablestatecache) {
6727 ast_clear_flag(ast_channel_flags(original), AST_FLAG_DISABLE_DEVSTATE_CACHE)do { typeof ((ast_channel_flags(original))->flags) __p = (
ast_channel_flags(original))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(original))->flags &= ~(AST_FLAG_DISABLE_DEVSTATE_CACHE
)); } while(0)
;
6728 ast_set_flag(ast_channel_flags(clonechan), AST_FLAG_DISABLE_DEVSTATE_CACHE)do { typeof ((ast_channel_flags(clonechan))->flags) __p = (
ast_channel_flags(clonechan))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(clonechan))->flags |= (AST_FLAG_DISABLE_DEVSTATE_CACHE));
} while(0)
;
6729 } else {
6730 ast_set_flag(ast_channel_flags(original), AST_FLAG_DISABLE_DEVSTATE_CACHE)do { typeof ((ast_channel_flags(original))->flags) __p = (
ast_channel_flags(original))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(original))->flags |= (AST_FLAG_DISABLE_DEVSTATE_CACHE)); }
while(0)
;
6731 ast_clear_flag(ast_channel_flags(clonechan), AST_FLAG_DISABLE_DEVSTATE_CACHE)do { typeof ((ast_channel_flags(clonechan))->flags) __p = (
ast_channel_flags(clonechan))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(clonechan))->flags &= ~(AST_FLAG_DISABLE_DEVSTATE_CACHE
)); } while(0)
;
6732 }
6733 }
6734
6735 /* Update the type. */
6736 t_pvt = ast_channel_monitor(original);
6737 ast_channel_monitor_set(original, ast_channel_monitor(clonechan));
6738 ast_channel_monitor_set(clonechan, t_pvt);
6739
6740 /* Keep the same language. */
6741 ast_channel_language_set(original, ast_channel_language(clonechan));
6742
6743 /* Keep the same parkinglot. */
6744 ast_channel_parkinglot_set(original, ast_channel_parkinglot(clonechan));
6745
6746 /* Copy the FD's other than the generator fd */
6747 for (x = 0; x < AST_MAX_FDS11; x++) {
6748 if (x != AST_GENERATOR_FD(11 -4))
6749 ast_channel_set_fd(original, x, ast_channel_fd(clonechan, x));
6750 }
6751
6752 ast_app_group_update(clonechan, original);
6753
6754 /* Swap hangup handlers. */
6755 exchange.handlers = *ast_channel_hangup_handlers(original);
6756 *ast_channel_hangup_handlers(original) = *ast_channel_hangup_handlers(clonechan);
6757 *ast_channel_hangup_handlers(clonechan) = exchange.handlers;
6758
6759 /* Call fixup handlers for the clone chan */
6760 if (AST_LIST_FIRST(ast_channel_datastores(clonechan))((ast_channel_datastores(clonechan))->first)) {
6761 struct ast_datastore *ds;
6762 /* We use a safe traversal here because some fixup routines actually
6763 * remove the datastore from the list and free them.
6764 */
6765 AST_LIST_TRAVERSE_SAFE_BEGIN(ast_channel_datastores(clonechan), ds, entry){ typeof((ast_channel_datastores(clonechan))) __list_head = ast_channel_datastores
(clonechan); typeof(__list_head->first) __list_next; typeof
(__list_head->first) __list_prev = ((void*)0); typeof(__list_head
->first) __list_current; for ((ds) = __list_head->first
, __list_current = (ds), __list_next = (ds) ? (ds)->entry.
next : ((void*)0); (ds); __list_prev = __list_current, (ds) =
__list_next, __list_current = (ds), __list_next = (ds) ? (ds
)->entry.next : ((void*)0), (void) __list_prev )
{
6766 if (ds->info->chan_fixup) {
6767 ds->info->chan_fixup(ds->data, clonechan, original);
6768 }
6769 }
6770 AST_LIST_TRAVERSE_SAFE_END};
6771 }
6772
6773 /* Call breakdown handlers for the original chan */
6774 if (AST_LIST_FIRST(ast_channel_datastores(original))((ast_channel_datastores(original))->first)) {
6775 struct ast_datastore *ds;
6776 /* We use a safe traversal here because some breakdown routines may
6777 * remove the datastore from the list and free them.
6778 */
6779 AST_LIST_TRAVERSE_SAFE_BEGIN(ast_channel_datastores(original), ds, entry){ typeof((ast_channel_datastores(original))) __list_head = ast_channel_datastores
(original); typeof(__list_head->first) __list_next; typeof
(__list_head->first) __list_prev = ((void*)0); typeof(__list_head
->first) __list_current; for ((ds) = __list_head->first
, __list_current = (ds), __list_next = (ds) ? (ds)->entry.
next : ((void*)0); (ds); __list_prev = __list_current, (ds) =
__list_next, __list_current = (ds), __list_next = (ds) ? (ds
)->entry.next : ((void*)0), (void) __list_prev )
{
6780 if (ds->info->chan_breakdown) {
6781 ds->info->chan_breakdown(ds->data, clonechan, original);
6782 }
6783 }
6784 AST_LIST_TRAVERSE_SAFE_END};
6785 }
6786
6787 /* Move data stores over */
6788 if (AST_LIST_FIRST(ast_channel_datastores(clonechan))((ast_channel_datastores(clonechan))->first)) {
6789 AST_LIST_APPEND_LIST(ast_channel_datastores(original), ast_channel_datastores(clonechan), entry)do { if (!(ast_channel_datastores(clonechan))->first) { break
; } if (!(ast_channel_datastores(original))->first) { (ast_channel_datastores
(original))->first = (ast_channel_datastores(clonechan))->
first; (ast_channel_datastores(original))->last = (ast_channel_datastores
(clonechan))->last; } else { (ast_channel_datastores(original
))->last->entry.next = (ast_channel_datastores(clonechan
))->first; (ast_channel_datastores(original))->last = (
ast_channel_datastores(clonechan))->last; } (ast_channel_datastores
(clonechan))->first = ((void*)0); (ast_channel_datastores(
clonechan))->last = ((void*)0); } while (0)
;
6790 }
6791
6792 /* Move framehooks over */
6793 ast_framehook_list_fixup(clonechan, original);
6794
6795 /* Move audiohooks over */
6796 ast_audiohook_move_all(clonechan, original);
6797
6798 ast_autochan_new_channel(clonechan, original);
6799
6800 clone_variables(original, clonechan);
6801 /* Presense of ADSI capable CPE follows clone */
6802 ast_channel_adsicpe_set(original, ast_channel_adsicpe(clonechan));
6803 /* Bridge remains the same */
6804 /* CDR fields remain the same */
6805 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
6806 /* Application and data remain the same */
6807 /* Clone exception becomes real one, as with fdno */
6808 ast_set_flag(ast_channel_flags(original), ast_test_flag(ast_channel_flags(clonechan), AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING))do { typeof ((ast_channel_flags(original))->flags) __p = (
ast_channel_flags(original))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(original))->flags |= (({ typeof ((ast_channel_flags(clonechan
))->flags) __p = (ast_channel_flags(clonechan))->flags;
typeof (__unsigned_int_flags_dummy) __x = 0; (void) (&__p
== &__x); ((ast_channel_flags(clonechan))->flags &
(AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING)); }))); } while(0)
;
6809 ast_channel_fdno_set(original, ast_channel_fdno(clonechan));
6810 /* Schedule context remains the same */
6811 /* Stream stuff stays the same */
6812 /* Keep the original state. The fixup code will need to work with it most likely */
6813
6814 /*
6815 * Just swap the whole structures, nevermind the allocations,
6816 * they'll work themselves out.
6817 */
6818 exchange.dialed = *ast_channel_dialed(original);
6819 ast_channel_dialed_set(original, ast_channel_dialed(clonechan));
6820 ast_channel_dialed_set(clonechan, &exchange.dialed);
6821
6822 /* Reset any earlier private caller id representations */
6823 ast_party_id_reset(&ast_channel_caller(original)->priv);
6824 ast_party_id_reset(&ast_channel_caller(clonechan)->priv);
6825
6826 exchange.caller = *ast_channel_caller(original);
6827 ast_channel_caller_set(original, ast_channel_caller(clonechan));
6828 ast_channel_caller_set(clonechan, &exchange.caller);
6829
6830 /* Reset any earlier private connected id representations */
6831 ast_party_id_reset(&ast_channel_connected(original)->priv);
6832 ast_party_id_reset(&ast_channel_connected(clonechan)->priv);
6833
6834 exchange.connected = *ast_channel_connected(original);
6835 ast_channel_connected_set(original, ast_channel_connected(clonechan));
6836 ast_channel_connected_set(clonechan, &exchange.connected);
6837
6838 /* Reset any earlier private redirecting orig, from or to representations */
6839 ast_party_id_reset(&ast_channel_redirecting(original)->priv_orig);
6840 ast_party_id_reset(&ast_channel_redirecting(clonechan)->priv_orig);
6841 ast_party_id_reset(&ast_channel_redirecting(original)->priv_from);
6842 ast_party_id_reset(&ast_channel_redirecting(clonechan)->priv_from);
6843 ast_party_id_reset(&ast_channel_redirecting(original)->priv_to);
6844 ast_party_id_reset(&ast_channel_redirecting(clonechan)->priv_to);
6845
6846 exchange.redirecting = *ast_channel_redirecting(original);
6847 ast_channel_redirecting_set(original, ast_channel_redirecting(clonechan));
6848 ast_channel_redirecting_set(clonechan, &exchange.redirecting);
6849
6850 ast_channel_publish_snapshot(original);
6851
6852 /* Restore original timing file descriptor */
6853 ast_channel_set_fd(original, AST_TIMING_FD(11 -2), ast_channel_timingfd(original));
6854
6855 /* Our native formats are different now */
6856 tmp_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)__ast_format_cap_alloc((AST_FORMAT_CAP_FLAG_DEFAULT), "ast_format_cap_alloc"
, "channel.c", 6856, __PRETTY_FUNCTION__)
;
6857 if (tmp_cap) {
6858 ast_format_cap_append_from_cap(tmp_cap, ast_channel_nativeformats(clonechan), AST_MEDIA_TYPE_UNKNOWN);
6859 ast_channel_nativeformats_set(original, tmp_cap);
6860 ao2_ref(tmp_cap, -1)__ao2_ref((tmp_cap), (-1), "", "channel.c", 6860, __PRETTY_FUNCTION__
)
;
6861 }
6862
6863 /* Context, extension, priority, app data, jump table, remain the same */
6864 /* pvt switches. pbx stays the same, as does next */
6865
6866 /* Set the write format */
6867 ast_set_write_format(original, wformat);
6868
6869 /* Set the read format */
6870 ast_set_read_format(original, rformat);
6871
6872 /* Copy the music class */
6873 ast_channel_musicclass_set(original, ast_channel_musicclass(clonechan));
6874
6875 /* copy over accuntcode and set peeraccount across the bridge */
6876 ast_channel_accountcode_set(original, S_OR(ast_channel_accountcode(clonechan), "")({typeof(&((ast_channel_accountcode(clonechan))[0])) __x =
(ast_channel_accountcode(clonechan)); _ast_strlen_zero(__x, "channel.c"
, __PRETTY_FUNCTION__, 6876) ? ("") : __x;})
);
6877
6878 ast_debug(1, "Putting channel %s in %s/%s formats\n", ast_channel_name(original),do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 6879, __PRETTY_FUNCTION__, "Putting channel %s in %s/%s formats\n"
, ast_channel_name(original), ast_format_get_name(wformat), ast_format_get_name
(rformat)); } } while (0)
6879 ast_format_get_name(wformat), ast_format_get_name(rformat))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 6879, __PRETTY_FUNCTION__, "Putting channel %s in %s/%s formats\n"
, ast_channel_name(original), ast_format_get_name(wformat), ast_format_get_name
(rformat)); } } while (0)
;
6880
6881 /* Fixup the original clonechan's physical side */
6882 if (ast_channel_tech(original)->fixup && ast_channel_tech(original)->fixup(clonechan, original)) {
6883 ast_log(LOG_WARNING3, "channel.c", 6883, __PRETTY_FUNCTION__, "Channel type '%s' could not fixup channel %s, strange things may happen. (clonechan)\n",
6884 ast_channel_tech(original)->type, ast_channel_name(original));
6885 }
6886
6887 /* Fixup the original original's physical side */
6888 if (ast_channel_tech(clonechan)->fixup && ast_channel_tech(clonechan)->fixup(original, clonechan)) {
6889 ast_log(LOG_WARNING3, "channel.c", 6889, __PRETTY_FUNCTION__, "Channel type '%s' could not fixup channel %s, strange things may happen. (original)\n",
6890 ast_channel_tech(clonechan)->type, ast_channel_name(clonechan));
6891 }
6892
6893 /*
6894 * Now, at this point, the "clone" channel is totally F'd up.
6895 * We mark it as a zombie so nothing tries to touch it.
6896 *
6897 * This must be done before we unlock clonechan to prevent
6898 * setting up another masquerade on the clonechan.
6899 */
6900 ast_set_flag(ast_channel_flags(clonechan), AST_FLAG_ZOMBIE)do { typeof ((ast_channel_flags(clonechan))->flags) __p = (
ast_channel_flags(clonechan))->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((ast_channel_flags
(clonechan))->flags |= (AST_FLAG_ZOMBIE)); } while(0)
;
6901 ast_queue_frame(clonechan, &ast_null_frame);
6902
6903 ast_channel_unlock(original)__ao2_unlock(original, "channel.c", __PRETTY_FUNCTION__, 6903
, "original")
;
6904 ast_channel_unlock(clonechan)__ao2_unlock(clonechan, "channel.c", __PRETTY_FUNCTION__, 6904
, "clonechan")
;
6905
6906 /*
6907 * Indicate to each channel that a masquerade is complete.
6908 *
6909 * We can still do this to clonechan even though it is a
6910 * zombie because ast_indicate_data() will explicitly pass
6911 * this control and ast_hangup() is held off until the
6912 * ast_channel_masq() and ast_channel_masqr() pointers are
6913 * cleared.
6914 */
6915 x = 0;
6916 ast_indicate_data(original, AST_CONTROL_MASQUERADE_NOTIFY, &x, sizeof(x));
6917 ast_indicate_data(clonechan, AST_CONTROL_MASQUERADE_NOTIFY, &x, sizeof(x));
6918
6919 ast_bridge_notify_masquerade(original);
6920
6921 if (clone_hold_state == AST_CONTROL_HOLD) {
6922 ast_debug(1, "Channel %s simulating UNHOLD for masquerade.\n",do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 6923, __PRETTY_FUNCTION__, "Channel %s simulating UNHOLD for masquerade.\n"
, ast_channel_name(original)); } } while (0)
6923 ast_channel_name(original))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 6923, __PRETTY_FUNCTION__, "Channel %s simulating UNHOLD for masquerade.\n"
, ast_channel_name(original)); } } while (0)
;
6924 ast_indicate(original, AST_CONTROL_UNHOLD);
6925 }
6926 if (clone_sending_dtmf_digit) {
6927 /*
6928 * The clonechan was sending a DTMF digit that was not completed
6929 * before the masquerade.
6930 */
6931 ast_channel_end_dtmf(original, clone_sending_dtmf_digit, clone_sending_dtmf_tv,
6932 "masquerade");
6933 }
6934
6935 /*
6936 * If an indication is currently playing, maintain it on the
6937 * channel that is taking the place of original.
6938 *
6939 * This is needed because the masquerade is swapping out the
6940 * internals of the channel, and the new channel private data
6941 * needs to be made aware of the current visible indication
6942 * (RINGING, CONGESTION, etc.)
6943 */
6944 if (visible_indication) {
6945 if (visible_indication == AST_CONTROL_HOLD) {
6946 const char *latest_musicclass;
6947 int len;
6948
6949 ast_channel_lock(original)__ao2_lock(original, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 6949, "original")
;
6950 latest_musicclass = ast_strdupa(ast_channel_latest_musicclass(original))(__extension__ ({ const char *__old = (ast_channel_latest_musicclass
(original)); size_t __len = strlen(__old) + 1; char *__new = __builtin_alloca
(__len); memcpy (__new, __old, __len); __new; }))
;
6951 ast_channel_unlock(original)__ao2_unlock(original, "channel.c", __PRETTY_FUNCTION__, 6951
, "original")
;
6952 if (ast_strlen_zero(latest_musicclass)_ast_strlen_zero(latest_musicclass, "channel.c", __PRETTY_FUNCTION__
, 6952)
) {
6953 latest_musicclass = NULL((void*)0);
6954 len = 0;
6955 } else {
6956 len = strlen(latest_musicclass) + 1;
6957 }
6958 ast_indicate_data(original, visible_indication, latest_musicclass, len);
6959 } else {
6960 ast_indicate(original, visible_indication);
6961 }
6962 }
6963
6964 /*
6965 * If MOH was playing on the original channel then it needs to be
6966 * maintained on the channel that is replacing it.
6967 */
6968 if (moh_is_playing) {
6969 /* Start MOH on the new original channel. */
6970 ast_moh_start(original, NULL((void*)0), NULL((void*)0));
6971 }
6972
6973 ast_channel_lock(original)__ao2_lock(original, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 6973, "original")
;
6974
6975 /* Signal any blocker */
6976 if (ast_test_flag(ast_channel_flags(original), AST_FLAG_BLOCKING)({ typeof ((ast_channel_flags(original))->flags) __p = (ast_channel_flags
(original))->flags; typeof (__unsigned_int_flags_dummy) __x
= 0; (void) (&__p == &__x); ((ast_channel_flags(original
))->flags & (AST_FLAG_BLOCKING)); })
) {
6977 pthread_kill(ast_channel_blocker(original), SIGURG23);
6978 }
6979
6980 ast_debug(1, "Done Masquerading %s (%u)\n", ast_channel_name(original), ast_channel_state(original))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 6980, __PRETTY_FUNCTION__, "Done Masquerading %s (%u)\n"
, ast_channel_name(original), ast_channel_state(original)); }
} while (0)
;
6981 ast_channel_unlock(original)__ao2_unlock(original, "channel.c", __PRETTY_FUNCTION__, 6981
, "original")
;
6982
6983 if ((bridged = ast_channel_bridge_peer(original))) {
6984 ast_indicate(bridged, AST_CONTROL_SRCCHANGE);
6985 ast_channel_unref(bridged)({ __ao2_ref((bridged), (-1), "", "channel.c", 6985, __PRETTY_FUNCTION__
); (struct ast_channel *) (((void*)0)); })
;
6986 }
6987 ast_indicate(original, AST_CONTROL_SRCCHANGE);
6988
6989 /* Now that the operation is complete, we can clear the masq
6990 * and masqr fields of both channels.
6991 */
6992 ast_channel_lock_both(original, clonechan)do { __ao2_lock(original, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 6992, "original"); while (__ao2_trylock(clonechan, AO2_LOCK_REQ_MUTEX
, "channel.c", __PRETTY_FUNCTION__, 6992, "clonechan")) { __ao2_unlock
(original, "channel.c", __PRETTY_FUNCTION__, 6992, "original"
); sched_yield(); __ao2_lock(original, AO2_LOCK_REQ_MUTEX, "channel.c"
, __PRETTY_FUNCTION__, 6992, "original"); } } while (0)
;
6993 ast_channel_masq_set(original, NULL((void*)0));
6994 ast_channel_masqr_set(clonechan, NULL((void*)0));
6995 ast_channel_unlock(original)__ao2_unlock(original, "channel.c", __PRETTY_FUNCTION__, 6995
, "original")
;
6996 ast_channel_unlock(clonechan)__ao2_unlock(clonechan, "channel.c", __PRETTY_FUNCTION__, 6996
, "clonechan")
;
6997
6998 ao2_link(channels, clonechan)__ao2_link((channels), (clonechan), 0, "", "channel.c", 6998,
__PRETTY_FUNCTION__)
;
6999 ao2_link(channels, original)__ao2_link((channels), (original), 0, "", "channel.c", 6999, __PRETTY_FUNCTION__
)
;
7000 ao2_unlock(channels)__ao2_unlock(channels, "channel.c", __PRETTY_FUNCTION__, 7000
, "channels")
;
7001
7002 /* Release our held safety references. */
7003 ast_channel_unref(original)({ __ao2_ref((original), (-1), "", "channel.c", 7003, __PRETTY_FUNCTION__
); (struct ast_channel *) (((void*)0)); })
;
7004 ast_channel_unref(clonechan)({ __ao2_ref((clonechan), (-1), "", "channel.c", 7004, __PRETTY_FUNCTION__
); (struct ast_channel *) (((void*)0)); })
;
7005
7006 ao2_cleanup(rformat)__ao2_cleanup_debug((rformat), "", "channel.c", 7006, __PRETTY_FUNCTION__
)
;
7007 ao2_cleanup(wformat)__ao2_cleanup_debug((wformat), "", "channel.c", 7007, __PRETTY_FUNCTION__
)
;
7008}
7009
7010void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
7011{
7012 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 7012, "chan")
;
7013
7014 if (cid_num) {
7015 ast_channel_caller(chan)->id.number.valid = 1;
7016 ast_freefree(ast_channel_caller(chan)->id.number.str);
7017 ast_channel_caller(chan)->id.number.str = ast_strdup(cid_num)_ast_strdup((cid_num), "channel.c", 7017, __PRETTY_FUNCTION__
)
;
7018 }
7019 if (cid_name) {
7020 ast_channel_caller(chan)->id.name.valid = 1;
7021 ast_freefree(ast_channel_caller(chan)->id.name.str);
7022 ast_channel_caller(chan)->id.name.str = ast_strdup(cid_name)_ast_strdup((cid_name), "channel.c", 7022, __PRETTY_FUNCTION__
)
;
7023 }
7024 if (cid_ani) {
7025 ast_channel_caller(chan)->ani.number.valid = 1;
7026 ast_freefree(ast_channel_caller(chan)->ani.number.str);
7027 ast_channel_caller(chan)->ani.number.str = ast_strdup(cid_ani)_ast_strdup((cid_ani), "channel.c", 7027, __PRETTY_FUNCTION__
)
;
7028 }
7029
7030 ast_channel_publish_snapshot(chan);
7031
7032 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 7032, "chan"
)
;
7033}
7034
7035void ast_channel_set_caller(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
7036{
7037 if (ast_channel_caller(chan) == caller) {
7038 /* Don't set to self */
7039 return;
7040 }
7041
7042 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 7042, "chan")
;
7043 ast_party_caller_set(ast_channel_caller(chan), caller, update);
7044 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 7044, "chan"
)
;
7045}
7046
7047void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
7048{
7049 if (ast_channel_caller(chan) == caller) {
7050 /* Don't set to self */
7051 return;
7052 }
7053
7054 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 7054, "chan")
;
7055 ast_party_caller_set(ast_channel_caller(chan), caller, update);
7056 ast_channel_publish_snapshot(chan);
7057 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 7057, "chan"
)
;
7058}
7059
7060int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
7061{
7062 int oldstate = ast_channel_state(chan);
7063 char name[AST_CHANNEL_NAME80], *dashptr;
7064
7065 if (oldstate == state)
7066 return 0;
7067
7068 ast_copy_string(name, ast_channel_name(chan), sizeof(name));
7069 if ((dashptr = strrchr(name, '-'))) {
7070 *dashptr = '\0';
7071 }
7072
7073 ast_channel_state_set(chan, state);
7074
7075 ast_publish_channel_state(chan);
7076
7077 /* We have to pass AST_DEVICE_UNKNOWN here because it is entirely possible that the channel driver
7078 * for this channel is using the callback method for device state. If we pass in an actual state here
7079 * we override what they are saying the state is and things go amuck. */
7080 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_DISABLE_DEVSTATE_CACHE)); })
? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), name);
7081
7082 return 0;
7083}
7084
7085/*! \brief Bridge two channels together (early) */
7086int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
7087{
7088 /* Make sure we can early bridge, if not error out */
7089 if (!ast_channel_tech(c0)->early_bridge || (c1 && (!ast_channel_tech(c1)->early_bridge || ast_channel_tech(c0)->early_bridge != ast_channel_tech(c1)->early_bridge)))
7090 return -1;
7091
7092 return ast_channel_tech(c0)->early_bridge(c0, c1);
7093}
7094
7095/*! \brief Sets an option on a channel */
7096int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
7097{
7098 int res;
7099
7100 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 7100, "chan")
;
7101 if (!ast_channel_tech(chan)->setoption) {
7102 errno(*__errno_location ()) = ENOSYS38;
7103 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 7103, "chan"
)
;
7104 return -1;
7105 }
7106
7107 if (block)
7108 ast_log(LOG_ERROR4, "channel.c", 7108, __PRETTY_FUNCTION__, "XXX Blocking not implemented yet XXX\n");
7109
7110 res = ast_channel_tech(chan)->setoption(chan, option, data, datalen);
7111 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 7111, "chan"
)
;
7112
7113 return res;
7114}
7115
7116int ast_channel_queryoption(struct ast_channel *chan, int option, void *data, int *datalen, int block)
7117{
7118 int res;
7119
7120 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 7120, "chan")
;
7121 if (!ast_channel_tech(chan)->queryoption) {
7122 errno(*__errno_location ()) = ENOSYS38;
7123 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 7123, "chan"
)
;
7124 return -1;
7125 }
7126
7127 if (block)
7128 ast_log(LOG_ERROR4, "channel.c", 7128, __PRETTY_FUNCTION__, "XXX Blocking not implemented yet XXX\n");
7129
7130 res = ast_channel_tech(chan)->queryoption(chan, option, data, datalen);
7131 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 7131, "chan"
)
;
7132
7133 return res;
7134}
7135
7136struct tonepair_def {
7137 int freq1;
7138 int freq2;
7139 int duration;
7140 int vol;
7141};
7142
7143struct tonepair_state {
7144 int fac1;
7145 int fac2;
7146 int v1_1;
7147 int v2_1;
7148 int v3_1;
7149 int v1_2;
7150 int v2_2;
7151 int v3_2;
7152 struct ast_format *origwfmt;
7153 int pos;
7154 int duration;
7155 int modulate;
7156 struct ast_frame f;
7157 unsigned char offset[AST_FRIENDLY_OFFSET64];
7158 short data[4000];
7159};
7160
7161static void tonepair_release(struct ast_channel *chan, void *params)
7162{
7163 struct tonepair_state *ts = params;
7164
7165 if (chan) {
7166 ast_set_write_format(chan, ts->origwfmt);
7167 }
7168 ao2_cleanup(ts->origwfmt)__ao2_cleanup_debug((ts->origwfmt), "", "channel.c", 7168,
__PRETTY_FUNCTION__)
;
7169 ast_freefree(ts);
7170}
7171
7172static void *tonepair_alloc(struct ast_channel *chan, void *params)
7173{
7174 struct tonepair_state *ts;
7175 struct tonepair_def *td = params;
7176
7177 if (!(ts = ast_calloc(1, sizeof(*ts))_ast_calloc((1), (sizeof(*ts)), "channel.c", 7177, __PRETTY_FUNCTION__
)
)) {
7178 return NULL((void*)0);
7179 }
7180
7181 ts->origwfmt = ao2_bump(ast_channel_writeformat(chan))({ typeof((ast_channel_writeformat(chan))) __obj___LINE__ = (
(ast_channel_writeformat(chan))); if (__obj___LINE__) { __ao2_ref
((__obj___LINE__), (+1), (("")), "channel.c", 7181, __PRETTY_FUNCTION__
); } __obj___LINE__; })
;
7182 if (ast_set_write_format(chan, ast_format_slin)) {
7183 ast_log(LOG_WARNING3, "channel.c", 7183, __PRETTY_FUNCTION__, "Unable to set '%s' to signed linear format (write)\n", ast_channel_name(chan));
7184 tonepair_release(NULL((void*)0), ts);
7185 ts = NULL((void*)0);
7186 } else {
7187 ts->fac1 = 2.0 * cos(2.0 * M_PI3.14159265358979323846 * (td->freq1 / 8000.0)) * 32768.0;
7188 ts->v1_1 = 0;
7189 ts->v2_1 = sin(-4.0 * M_PI3.14159265358979323846 * (td->freq1 / 8000.0)) * td->vol;
7190 ts->v3_1 = sin(-2.0 * M_PI3.14159265358979323846 * (td->freq1 / 8000.0)) * td->vol;
7191 ts->v2_1 = 0;
7192 ts->fac2 = 2.0 * cos(2.0 * M_PI3.14159265358979323846 * (td->freq2 / 8000.0)) * 32768.0;
7193 ts->v2_2 = sin(-4.0 * M_PI3.14159265358979323846 * (td->freq2 / 8000.0)) * td->vol;
7194 ts->v3_2 = sin(-2.0 * M_PI3.14159265358979323846 * (td->freq2 / 8000.0)) * td->vol;
7195 ts->duration = td->duration;
7196 ts->modulate = 0;
7197 }
7198 /* Let interrupts interrupt :) */
7199 ast_set_flag(ast_channel_flags(chan), AST_FLAG_WRITE_INT)do { typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags |= (AST_FLAG_WRITE_INT)); } while(0)
;
7200 return ts;
7201}
7202
7203static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples)
7204{
7205 struct tonepair_state *ts = data;
7206 int x;
7207
7208 /* we need to prepare a frame with 16 * timelen samples as we're
7209 * generating SLIN audio
7210 */
7211 len = samples * 2;
7212
7213 if (len > sizeof(ts->data) / 2 - 1) {
7214 ast_log(LOG_WARNING3, "channel.c", 7214, __PRETTY_FUNCTION__, "Can't generate that much data!\n");
7215 return -1;
7216 }
7217 memset(&ts->f, 0, sizeof(ts->f));
7218 for (x=0;x<len/2;x++) {
7219 ts->v1_1 = ts->v2_1;
7220 ts->v2_1 = ts->v3_1;
7221 ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
7222
7223 ts->v1_2 = ts->v2_2;
7224 ts->v2_2 = ts->v3_2;
7225 ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
7226 if (ts->modulate) {
7227 int p;
7228 p = ts->v3_2 - 32768;
7229 if (p < 0) p = -p;
7230 p = ((p * 9) / 10) + 1;
7231 ts->data[x] = (ts->v3_1 * p) >> 15;
7232 } else
7233 ts->data[x] = ts->v3_1 + ts->v3_2;
7234 }
7235 ts->f.frametype = AST_FRAME_VOICE;
7236 ts->f.subclass.format = ast_format_slin;
7237 ts->f.datalen = len;
7238 ts->f.samples = samples;
7239 ts->f.offset = AST_FRIENDLY_OFFSET64;
7240 ts->f.data.ptr = ts->data;
7241 ast_write(chan, &ts->f);
7242 ts->pos += x;
7243 if (ts->duration > 0) {
7244 if (ts->pos >= ts->duration * 8)
7245 return -1;
7246 }
7247 return 0;
7248}
7249
7250static struct ast_generator tonepair = {
7251 .alloc = tonepair_alloc,
7252 .release = tonepair_release,
7253 .generate = tonepair_generator,
7254};
7255
7256int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
7257{
7258 struct tonepair_def d = { 0, };
7259
7260 d.freq1 = freq1;
7261 d.freq2 = freq2;
7262 d.duration = duration;
7263 d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */
7264 if (ast_activate_generator(chan, &tonepair, &d))
7265 return -1;
7266 return 0;
7267}
7268
7269void ast_tonepair_stop(struct ast_channel *chan)
7270{
7271 ast_deactivate_generator(chan);
7272}
7273
7274int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
7275{
7276 int res;
7277
7278 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
7279 return res;
7280
7281 /* Give us some wiggle room */
7282 while (ast_channel_generatordata(chan) && ast_waitfor(chan, 100) >= 0) {
7283 struct ast_frame *f = ast_read(chan);
7284 if (f)
7285 ast_frfree(f)ast_frame_free(f, 1);
7286 else
7287 return -1;
7288 }
7289 return 0;
7290}
7291
7292ast_group_t ast_get_group(const char *s)
7293{
7294 char *piece;
7295 char *c;
7296 int start=0, finish=0, x;
7297 ast_group_t group = 0;
7298
7299 if (ast_strlen_zero(s)_ast_strlen_zero(s, "channel.c", __PRETTY_FUNCTION__, 7299))
7300 return 0;
7301
7302 c = ast_strdupa(s)(__extension__ ({ const char *__old = (s); size_t __len = strlen
(__old) + 1; char *__new = __builtin_alloca(__len); memcpy (__new
, __old, __len); __new; }))
;
7303
7304 while ((piece = strsep(&c, ","))) {
7305 if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) {
7306 /* Range */
7307 } else if (sscanf(piece, "%30d", &start)) {
7308 /* Just one */
7309 finish = start;
7310 } else {
7311 ast_log(LOG_ERROR4, "channel.c", 7311, __PRETTY_FUNCTION__, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
7312 continue;
7313 }
7314 for (x = start; x <= finish; x++) {
7315 if ((x > 63) || (x < 0)) {
7316 ast_log(LOG_WARNING3, "channel.c", 7316, __PRETTY_FUNCTION__, "Ignoring invalid group %d (maximum group is 63)\n", x);
7317 } else
7318 group |= ((ast_group_t) 1 << x);
7319 }
7320 }
7321 return group;
7322}
7323
7324/*! \brief Named group member structure */
7325struct namedgroup_member {
7326 /*! Pre-built hash of group member name. */
7327 unsigned int hash;
7328 /*! Group member name. (End allocation of name string.) */
7329 char name[1];
7330};
7331
7332/*! \brief Comparison function used for named group container */
7333static int namedgroup_cmp_cb(void *obj, void *arg, int flags)
7334{
7335 const struct namedgroup_member *an = obj;
7336 const struct namedgroup_member *bn = arg;
7337
7338 return strcmp(an->name, bn->name) ? 0 : CMP_MATCH | CMP_STOP;
7339}
7340
7341/*! \brief Hashing function used for named group container */
7342static int namedgroup_hash_cb(const void *obj, const int flags)
7343{
7344 const struct namedgroup_member *member = obj;
7345
7346 return member->hash;
7347}
7348
7349struct ast_namedgroups *ast_get_namedgroups(const char *s)
7350{
7351 struct ao2_container *namedgroups;
7352 char *piece;
7353 char *c;
7354
7355 if (!s) {
1
Assuming 's' is non-null
2
Taking false branch
7356 return NULL((void*)0);
7357 }
7358
7359 /*! \brief Remove leading and trailing whitespace */
7360 c = ast_trim_blanks(ast_strdupa(ast_skip_blanks(s))(__extension__ ({ const char *__old = (ast_skip_blanks(s)); size_t
__len = strlen(__old) + 1; char *__new = __builtin_alloca(__len
); memcpy (__new, __old, __len); __new; }))
);
7361 if (ast_strlen_zero(c)_ast_strlen_zero(c, "channel.c", __PRETTY_FUNCTION__, 7361)) {
3
Taking false branch
7362 return NULL((void*)0);
7363 }
7364
7365 namedgroups = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, 19,__ao2_container_alloc_hash(((AO2_ALLOC_OPT_LOCK_NOLOCK)), (0)
, ((19)), ((namedgroup_hash_cb)), (((void*)0)), ((namedgroup_cmp_cb
)), "", "channel.c", 7366, __PRETTY_FUNCTION__)
7366 namedgroup_hash_cb, namedgroup_cmp_cb)__ao2_container_alloc_hash(((AO2_ALLOC_OPT_LOCK_NOLOCK)), (0)
, ((19)), ((namedgroup_hash_cb)), (((void*)0)), ((namedgroup_cmp_cb
)), "", "channel.c", 7366, __PRETTY_FUNCTION__)
;
7367 if (!namedgroups) {
4
Assuming 'namedgroups' is non-null
5
Taking false branch
7368 return NULL((void*)0);
7369 }
7370
7371 while ((piece = strsep(&c, ","))) {
6
Loop condition is true. Entering loop body
7372 struct namedgroup_member *member;
7373 size_t len;
7374
7375 /* remove leading/trailing whitespace */
7376 piece = ast_strip(piece);
7377
7378 len = strlen(piece);
7379 if (!len) {
7
Assuming 'len' is not equal to 0
8
Taking false branch
7380 continue;
7381 }
7382
7383 member = ao2_alloc_options(sizeof(*member) + len, NULL, AO2_ALLOC_OPT_LOCK_NOLOCK)__ao2_alloc((sizeof(*member) + len), (((void*)0)), (AO2_ALLOC_OPT_LOCK_NOLOCK
), "", "channel.c", 7383, __PRETTY_FUNCTION__)
;
7384 if (!member) {
9
Assuming 'member' is non-null
10
Taking false branch
7385 ao2_ref(namedgroups, -1)__ao2_ref((namedgroups), (-1), "", "channel.c", 7385, __PRETTY_FUNCTION__
)
;
7386 return NULL((void*)0);
7387 }
7388 strcpy(member->name, piece);/* Safe */
11
String copy function overflows destination buffer
7389 member->hash = ast_str_hash(member->name);
7390
7391 /* every group name may exist only once, delete duplicates */
7392 ao2_find(namedgroups, member, OBJ_POINTER | OBJ_UNLINK | OBJ_NODATA)__ao2_find((namedgroups), (member), (OBJ_SEARCH_OBJECT | OBJ_UNLINK
| OBJ_NODATA), "", "channel.c", 7392, __PRETTY_FUNCTION__)
;
7393 ao2_link(namedgroups, member)__ao2_link((namedgroups), (member), 0, "", "channel.c", 7393,
__PRETTY_FUNCTION__)
;
7394 ao2_ref(member, -1)__ao2_ref((member), (-1), "", "channel.c", 7394, __PRETTY_FUNCTION__
)
;
7395 }
7396
7397 if (!ao2_container_count(namedgroups)) {
7398 /* There were no group names specified. */
7399 ao2_ref(namedgroups, -1)__ao2_ref((namedgroups), (-1), "", "channel.c", 7399, __PRETTY_FUNCTION__
)
;
7400 namedgroups = NULL((void*)0);
7401 }
7402
7403 return (struct ast_namedgroups *) namedgroups;
7404}
7405
7406struct ast_namedgroups *ast_unref_namedgroups(struct ast_namedgroups *groups)
7407{
7408 ao2_cleanup(groups)__ao2_cleanup_debug((groups), "", "channel.c", 7408, __PRETTY_FUNCTION__
)
;
7409 return NULL((void*)0);
7410}
7411
7412struct ast_namedgroups *ast_ref_namedgroups(struct ast_namedgroups *groups)
7413{
7414 if (groups) {
7415 ao2_ref(groups, 1)__ao2_ref((groups), (1), "", "channel.c", 7415, __PRETTY_FUNCTION__
)
;
7416 }
7417 return groups;
7418}
7419
7420static int (*ast_moh_start_ptr)(struct ast_channel *, const char *, const char *) = NULL((void*)0);
7421static void (*ast_moh_stop_ptr)(struct ast_channel *) = NULL((void*)0);
7422static void (*ast_moh_cleanup_ptr)(struct ast_channel *) = NULL((void*)0);
7423
7424void ast_install_music_functions(int (*start_ptr)(struct ast_channel *, const char *, const char *),
7425 void (*stop_ptr)(struct ast_channel *),
7426 void (*cleanup_ptr)(struct ast_channel *))
7427{
7428 ast_moh_start_ptr = start_ptr;
7429 ast_moh_stop_ptr = stop_ptr;
7430 ast_moh_cleanup_ptr = cleanup_ptr;
7431}
7432
7433void ast_uninstall_music_functions(void)
7434{
7435 ast_moh_start_ptr = NULL((void*)0);
7436 ast_moh_stop_ptr = NULL((void*)0);
7437 ast_moh_cleanup_ptr = NULL((void*)0);
7438}
7439
7440int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
7441{
7442 if (ast_moh_start_ptr)
7443 return ast_moh_start_ptr(chan, mclass, interpclass);
7444
7445 ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default"))do { if (((3) <= ast_verb_sys_level) ) { __ast_verbose("channel.c"
, 7445, __PRETTY_FUNCTION__, 3, "Music class %s requested but no musiconhold loaded.\n"
, mclass ? mclass : (interpclass ? interpclass : "default"));
} } while (0)
;
7446
7447 return -1;
7448}
7449
7450void ast_moh_stop(struct ast_channel *chan)
7451{
7452 if (ast_moh_stop_ptr)
7453 ast_moh_stop_ptr(chan);
7454}
7455
7456void ast_moh_cleanup(struct ast_channel *chan)
7457{
7458 if (ast_moh_cleanup_ptr)
7459 ast_moh_cleanup_ptr(chan);
7460}
7461
7462static int ast_channel_hash_cb(const void *obj, const int flags)
7463{
7464 const char *name = (flags & OBJ_KEYOBJ_SEARCH_KEY) ? obj : ast_channel_name((struct ast_channel *) obj);
7465
7466 /* If the name isn't set, return 0 so that the ao2_find() search will
7467 * start in the first bucket. */
7468 if (ast_strlen_zero(name)_ast_strlen_zero(name, "channel.c", __PRETTY_FUNCTION__, 7468
)
) {
7469 return 0;
7470 }
7471
7472 return ast_str_case_hash(name);
7473}
7474
7475int ast_plc_reload(void)
7476{
7477 struct ast_variable *var;
7478 struct ast_flags config_flags = { 0 };
7479 struct ast_config *cfg = ast_config_load("codecs.conf", config_flags)ast_config_load2("codecs.conf", "core", config_flags);
7480 if (cfg == CONFIG_STATUS_FILEMISSING(void *)0 || cfg == CONFIG_STATUS_FILEUNCHANGED(void *)-1 || cfg == CONFIG_STATUS_FILEINVALID(void *)-2)
7481 return 0;
7482 for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
7483 if (!strcasecmp(var->name, "genericplc")) {
7484 ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC)do { typeof ((&ast_options)->flags) __p = (&ast_options
)->flags; typeof (__unsigned_int_flags_dummy) __x = 0; (void
) (&__p == &__x); if (ast_true(var->value)) (&
ast_options)->flags |= (AST_OPT_FLAG_GENERIC_PLC); else (&
ast_options)->flags &= ~(AST_OPT_FLAG_GENERIC_PLC); } while
(0)
;
7485 }
7486 }
7487 ast_config_destroy(cfg);
7488 return 0;
7489}
7490
7491/*!
7492 * \internal
7493 * \brief Implements the channels provider.
7494 */
7495static int data_channels_provider_handler(const struct ast_data_search *search,
7496 struct ast_data *root)
7497{
7498 struct ast_channel *c;
7499 struct ast_channel_iterator *iter = NULL((void*)0);
7500 struct ast_data *data_channel;
7501
7502 for (iter = ast_channel_iterator_all_new();
7503 iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)({ __ao2_ref((c), (-1), "", "channel.c", 7503, __PRETTY_FUNCTION__
); (struct ast_channel *) (((void*)0)); })
) {
7504 ast_channel_lock(c)__ao2_lock(c, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 7504, "c")
;
7505
7506 data_channel = ast_data_add_node(root, "channel");
7507 if (!data_channel) {
7508 ast_channel_unlock(c)__ao2_unlock(c, "channel.c", __PRETTY_FUNCTION__, 7508, "c");
7509 continue;
7510 }
7511
7512 if (ast_channel_data_add_structure(data_channel, c, 1) < 0) {
7513 ast_log(LOG_ERROR4, "channel.c", 7513, __PRETTY_FUNCTION__, "Unable to add channel structure for channel: %s\n", ast_channel_name(c));
7514 }
7515
7516 ast_channel_unlock(c)__ao2_unlock(c, "channel.c", __PRETTY_FUNCTION__, 7516, "c");
7517
7518 if (!ast_data_search_match(search, data_channel)) {
7519 ast_data_remove_node(root, data_channel);
7520 }
7521 }
7522 if (iter) {
7523 ast_channel_iterator_destroy(iter);
7524 }
7525
7526 return 0;
7527}
7528
7529/*!
7530 * \internal
7531 * \brief Implements the channeltypes provider.
7532 */
7533static int data_channeltypes_provider_handler(const struct ast_data_search *search,
7534 struct ast_data *data_root)
7535{
7536 struct chanlist *cl;
7537 struct ast_data *data_type;
7538
7539 AST_RWLIST_RDLOCK(&backends)__ast_rwlock_rdlock("channel.c", 7539, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
7540 AST_RWLIST_TRAVERSE(&backends, cl, list)for((cl) = (&backends)->first; (cl); (cl) = (cl)->list
.next)
{
7541 data_type = ast_data_add_node(data_root, "type");
7542 if (!data_type) {
7543 continue;
7544 }
7545 ast_data_add_str(data_type, "name", cl->tech->type);
7546 ast_data_add_str(data_type, "description", cl->tech->description);
7547 ast_data_add_bool(data_type, "devicestate", cl->tech->devicestate ? 1 : 0);
7548 ast_data_add_bool(data_type, "presencestate", cl->tech->presencestate ? 1 : 0);
7549 ast_data_add_bool(data_type, "indications", cl->tech->indicate ? 1 : 0);
7550 ast_data_add_bool(data_type, "transfer", cl->tech->transfer ? 1 : 0);
7551 ast_data_add_bool(data_type, "send_digit_begin", cl->tech->send_digit_begin ? 1 : 0);
7552 ast_data_add_bool(data_type, "send_digit_end", cl->tech->send_digit_end ? 1 : 0);
7553 ast_data_add_bool(data_type, "call", cl->tech->call ? 1 : 0);
7554 ast_data_add_bool(data_type, "hangup", cl->tech->hangup ? 1 : 0);
7555 ast_data_add_bool(data_type, "answer", cl->tech->answer ? 1 : 0);
7556 ast_data_add_bool(data_type, "read", cl->tech->read ? 1 : 0);
7557 ast_data_add_bool(data_type, "write", cl->tech->write ? 1 : 0);
7558 ast_data_add_bool(data_type, "send_text", cl->tech->send_text ? 1 : 0);
7559 ast_data_add_bool(data_type, "send_image", cl->tech->send_image ? 1 : 0);
7560 ast_data_add_bool(data_type, "send_html", cl->tech->send_html ? 1 : 0);
7561 ast_data_add_bool(data_type, "exception", cl->tech->exception ? 1 : 0);
7562 ast_data_add_bool(data_type, "early_bridge", cl->tech->early_bridge ? 1 : 0);
7563 ast_data_add_bool(data_type, "fixup", cl->tech->fixup ? 1 : 0);
7564 ast_data_add_bool(data_type, "setoption", cl->tech->setoption ? 1 : 0);
7565 ast_data_add_bool(data_type, "queryoption", cl->tech->queryoption ? 1 : 0);
7566 ast_data_add_bool(data_type, "write_video", cl->tech->write_video ? 1 : 0);
7567 ast_data_add_bool(data_type, "write_text", cl->tech->write_text ? 1 : 0);
7568 ast_data_add_bool(data_type, "func_channel_read", cl->tech->func_channel_read ? 1 : 0);
7569 ast_data_add_bool(data_type, "func_channel_write", cl->tech->func_channel_write ? 1 : 0);
7570 ast_data_add_bool(data_type, "get_pvt_uniqueid", cl->tech->get_pvt_uniqueid ? 1 : 0);
7571 ast_data_add_bool(data_type, "cc_callback", cl->tech->cc_callback ? 1 : 0);
7572
7573 ast_data_add_codecs(data_type, "capabilities", cl->tech->capabilities);
7574
7575 if (!ast_data_search_match(search, data_type)) {
7576 ast_data_remove_node(data_root, data_type);
7577 }
7578 }
7579 AST_RWLIST_UNLOCK(&backends)__ast_rwlock_unlock("channel.c", 7579, __PRETTY_FUNCTION__, &
(&backends)->lock, "&(&backends)->lock")
;
7580
7581 return 0;
7582}
7583
7584/*!
7585 * \internal
7586 * \brief /asterisk/core/channels provider.
7587 */
7588static const struct ast_data_handler channels_provider = {
7589 .version = AST_DATA_HANDLER_VERSION1,
7590 .get = data_channels_provider_handler
7591};
7592
7593/*!
7594 * \internal
7595 * \brief /asterisk/core/channeltypes provider.
7596 */
7597static const struct ast_data_handler channeltypes_provider = {
7598 .version = AST_DATA_HANDLER_VERSION1,
7599 .get = data_channeltypes_provider_handler
7600};
7601
7602static const struct ast_data_entry channel_providers[] = {
7603 AST_DATA_ENTRY("/asterisk/core/channels", &channels_provider){ .path = "/asterisk/core/channels", .handler = &channels_provider
}
,
7604 AST_DATA_ENTRY("/asterisk/core/channeltypes", &channeltypes_provider){ .path = "/asterisk/core/channeltypes", .handler = &channeltypes_provider
}
,
7605};
7606
7607/*!
7608 * \internal
7609 * \brief Print channel object key (name).
7610 * \since 12.0.0
7611 *
7612 * \param v_obj A pointer to the object we want the key printed.
7613 * \param where User data needed by prnt to determine where to put output.
7614 * \param prnt Print output callback function to use.
7615 *
7616 * \return Nothing
7617 */
7618static void prnt_channel_key(void *v_obj, void *where, ao2_prnt_fn *prnt)
7619{
7620 struct ast_channel *chan = v_obj;
7621
7622 if (!chan) {
7623 return;
7624 }
7625 prnt(where, "%s", ast_channel_name(chan));
7626}
7627
7628/*!
7629 * \brief List of channel variables to append to all channel-related events.
7630 */
7631struct manager_channel_variable {
7632 AST_LIST_ENTRY(manager_channel_variable)struct { struct manager_channel_variable *next; } entry;
7633 unsigned int isfunc:1;
7634 char name[];
7635};
7636
7637static AST_RWLIST_HEAD_STATIC(channelvars, manager_channel_variable)struct channelvars { struct manager_channel_variable *first; struct
manager_channel_variable *last; ast_rwlock_t lock; } channelvars
= { .first = ((void*)0), .last = ((void*)0), .lock = { { { 0
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, ((void*)0), 1 }, }
;
7638
7639static void free_channelvars(void)
7640{
7641 struct manager_channel_variable *var;
7642 AST_RWLIST_WRLOCK(&channelvars)__ast_rwlock_wrlock("channel.c", 7642, __PRETTY_FUNCTION__, &
(&channelvars)->lock, "&(&channelvars)->lock"
)
;
7643 while ((var = AST_RWLIST_REMOVE_HEAD(&channelvars, entry)({ typeof((&channelvars)->first) __cur = (&channelvars
)->first; if (__cur) { (&channelvars)->first = __cur
->entry.next; __cur->entry.next = ((void*)0); if ((&
channelvars)->last == __cur) (&channelvars)->last =
((void*)0); } __cur; })
)) {
7644 ast_freefree(var);
7645 }
7646 AST_RWLIST_UNLOCK(&channelvars)__ast_rwlock_unlock("channel.c", 7646, __PRETTY_FUNCTION__, &
(&channelvars)->lock, "&(&channelvars)->lock"
)
;
7647}
7648
7649int ast_channel_has_manager_vars(void)
7650{
7651 int vars_present;
7652
7653 AST_RWLIST_RDLOCK(&channelvars)__ast_rwlock_rdlock("channel.c", 7653, __PRETTY_FUNCTION__, &
(&channelvars)->lock, "&(&channelvars)->lock"
)
;
7654 vars_present = !AST_LIST_EMPTY(&channelvars)(((&channelvars)->first) == ((void*)0));
7655 AST_RWLIST_UNLOCK(&channelvars)__ast_rwlock_unlock("channel.c", 7655, __PRETTY_FUNCTION__, &
(&channelvars)->lock, "&(&channelvars)->lock"
)
;
7656
7657 return vars_present;
7658}
7659
7660void ast_channel_set_manager_vars(size_t varc, char **vars)
7661{
7662 size_t i;
7663
7664 free_channelvars();
7665 AST_RWLIST_WRLOCK(&channelvars)__ast_rwlock_wrlock("channel.c", 7665, __PRETTY_FUNCTION__, &
(&channelvars)->lock, "&(&channelvars)->lock"
)
;
7666 for (i = 0; i < varc; ++i) {
7667 const char *var = vars[i];
7668 struct manager_channel_variable *mcv;
7669 if (!(mcv = ast_calloc(1, sizeof(*mcv) + strlen(var) + 1)_ast_calloc((1), (sizeof(*mcv) + strlen(var) + 1), "channel.c"
, 7669, __PRETTY_FUNCTION__)
)) {
7670 break;
7671 }
7672 strcpy(mcv->name, var); /* SAFE */
7673 if (strchr(var, '(')(__extension__ (__builtin_constant_p ('(') && !__builtin_constant_p
(var) && ('(') == '\0' ? (char *) __rawmemchr (var, '('
) : __builtin_strchr (var, '(')))
) {
7674 mcv->isfunc = 1;
7675 }
7676 AST_RWLIST_INSERT_TAIL(&channelvars, mcv, entry)do { if (!(&channelvars)->first) { (&channelvars)->
first = (mcv); (&channelvars)->last = (mcv); } else { (
&channelvars)->last->entry.next = (mcv); (&channelvars
)->last = (mcv); } } while (0)
;
7677 }
7678 AST_RWLIST_UNLOCK(&channelvars)__ast_rwlock_unlock("channel.c", 7678, __PRETTY_FUNCTION__, &
(&channelvars)->lock, "&(&channelvars)->lock"
)
;
7679}
7680
7681/*!
7682 * \brief Destructor for lists of variables.
7683 * \param obj AO2 object.
7684 */
7685static void varshead_dtor(void *obj)
7686{
7687 struct varshead *head = obj;
7688 struct ast_var_t *var;
7689
7690 while ((var = AST_RWLIST_REMOVE_HEAD(head, entries)({ typeof((head)->first) __cur = (head)->first; if (__cur
) { (head)->first = __cur->entries.next; __cur->entries
.next = ((void*)0); if ((head)->last == __cur) (head)->
last = ((void*)0); } __cur; })
)) {
7691 ast_var_delete(var);
7692 }
7693}
7694
7695struct varshead *ast_channel_get_vars(struct ast_channel *chan)
7696{
7697 RAII_VAR(struct varshead *, ret, NULL, ao2_cleanup)_raii_cleanup_block_t _raii_cleanup_ret __attribute__((cleanup
(_raii_cleanup_block),unused)) = ((void*)0); __attribute__((__blocks__
(byref))) struct varshead * ret = ((void*)0); _raii_cleanup_ret
= ^{ {(void)__ao2_cleanup_debug((ret), "", "channel.c", 7697
, __PRETTY_FUNCTION__);} }
;
7698 struct ast_var_t *cv;
7699
7700 ret = ao2_alloc(sizeof(*ret), varshead_dtor)__ao2_alloc((sizeof(*ret)), (varshead_dtor), AO2_ALLOC_OPT_LOCK_MUTEX
, "", "channel.c", 7700, __PRETTY_FUNCTION__)
;
7701
7702 if (!ret) {
7703 return NULL((void*)0);
7704 }
7705
7706 AST_LIST_TRAVERSE(ast_channel_varshead(chan), cv, entries)for((cv) = (ast_channel_varshead(chan))->first; (cv); (cv)
= (cv)->entries.next)
{
7707 struct ast_var_t *var = ast_var_assign(ast_var_name(cv), ast_var_value(cv));
7708
7709 if (!var) {
7710 return NULL((void*)0);
7711 }
7712
7713 AST_LIST_INSERT_TAIL(ret, var, entries)do { if (!(ret)->first) { (ret)->first = (var); (ret)->
last = (var); } else { (ret)->last->entries.next = (var
); (ret)->last = (var); } } while (0)
;
7714 }
7715
7716 ao2_ref(ret, +1)__ao2_ref((ret), (+1), "", "channel.c", 7716, __PRETTY_FUNCTION__
)
;
7717 return ret;
7718}
7719
7720struct varshead *ast_channel_get_manager_vars(struct ast_channel *chan)
7721{
7722 RAII_VAR(struct varshead *, ret, NULL, ao2_cleanup)_raii_cleanup_block_t _raii_cleanup_ret __attribute__((cleanup
(_raii_cleanup_block),unused)) = ((void*)0); __attribute__((__blocks__
(byref))) struct varshead * ret = ((void*)0); _raii_cleanup_ret
= ^{ {(void)__ao2_cleanup_debug((ret), "", "channel.c", 7722
, __PRETTY_FUNCTION__);} }
;
7723 RAII_VAR(struct ast_str *, tmp, NULL, ast_free)_raii_cleanup_block_t _raii_cleanup_tmp __attribute__((cleanup
(_raii_cleanup_block),unused)) = ((void*)0); __attribute__((__blocks__
(byref))) struct ast_str * tmp = ((void*)0); _raii_cleanup_tmp
= ^{ {(void)free(tmp);} }
;
7724 struct manager_channel_variable *mcv;
7725 SCOPED_LOCK(lock, &channelvars, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK)_raii_cleanup_block_t _raii_cleanup_lock __attribute__((cleanup
(_raii_cleanup_block),unused)) = ((void*)0); __attribute__((__blocks__
(byref))) typeof((&channelvars)) lock = ({__ast_rwlock_rdlock
("channel.c", 7725, __PRETTY_FUNCTION__, &((&channelvars
))->lock, "&((&channelvars))->lock"); (&channelvars
); }); _raii_cleanup_lock = ^{ {(void)__ast_rwlock_unlock("channel.c"
, 7725, __PRETTY_FUNCTION__, &(lock)->lock, "&(lock)->lock"
);} }
;
7726
7727 if (AST_LIST_EMPTY(&channelvars)(((&channelvars)->first) == ((void*)0))) {
7728 return NULL((void*)0);
7729 }
7730
7731 ret = ao2_alloc(sizeof(*ret), varshead_dtor)__ao2_alloc((sizeof(*ret)), (varshead_dtor), AO2_ALLOC_OPT_LOCK_MUTEX
, "", "channel.c", 7731, __PRETTY_FUNCTION__)
;
7732 tmp = ast_str_create(16);
7733
7734 if (!ret || !tmp) {
7735 return NULL((void*)0);
7736 }
7737
7738 AST_LIST_TRAVERSE(&channelvars, mcv, entry)for((mcv) = (&channelvars)->first; (mcv); (mcv) = (mcv
)->entry.next)
{
7739 const char *val = NULL((void*)0);
7740 struct ast_var_t *var;
7741
7742 if (mcv->isfunc) {
7743 if (ast_func_read2(chan, mcv->name, &tmp, 0) == 0) {
7744 val = ast_str_buffer(tmp);
7745 } else {
7746 ast_log(LOG_ERROR4, "channel.c", 7746, __PRETTY_FUNCTION__,
7747 "Error invoking function %s\n", mcv->name);
7748 }
7749 } else {
7750 val = pbx_builtin_getvar_helper(chan, mcv->name);
7751 }
7752
7753 var = ast_var_assign(mcv->name, val ? val : "");
7754 if (!var) {
7755 return NULL((void*)0);
7756 }
7757
7758 AST_RWLIST_INSERT_TAIL(ret, var, entries)do { if (!(ret)->first) { (ret)->first = (var); (ret)->
last = (var); } else { (ret)->last->entries.next = (var
); (ret)->last = (var); } } while (0)
;
7759 }
7760
7761 ao2_ref(ret, +1)__ao2_ref((ret), (+1), "", "channel.c", 7761, __PRETTY_FUNCTION__
)
;
7762 return ret;
7763}
7764
7765static void channels_shutdown(void)
7766{
7767 free_channelvars();
7768
7769 ast_data_unregister(NULL)__ast_data_unregister(((void*)0), "channel.c");
7770 ast_cli_unregister_multiple(cli_channel, ARRAY_LEN(cli_channel)(size_t) (sizeof(cli_channel) / sizeof(0[cli_channel])));
7771 if (channels) {
7772 ao2_container_unregister("channels");
7773 ao2_ref(channels, -1)__ao2_ref((channels), (-1), "", "channel.c", 7773, __PRETTY_FUNCTION__
)
;
7774 channels = NULL((void*)0);
7775 }
7776 ast_channel_unregister(&surrogate_tech);
7777}
7778
7779void ast_channels_init(void)
7780{
7781 channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS,__ao2_container_alloc_hash(((AO2_ALLOC_OPT_LOCK_MUTEX)), (0),
(((1567))), (((ast_channel_hash_cb))), (((void*)0)), (((ast_channel_cmp_cb
))), "", "channel.c", 7782, __PRETTY_FUNCTION__)
7782 ast_channel_hash_cb, ast_channel_cmp_cb)__ao2_container_alloc_hash(((AO2_ALLOC_OPT_LOCK_MUTEX)), (0),
(((1567))), (((ast_channel_hash_cb))), (((void*)0)), (((ast_channel_cmp_cb
))), "", "channel.c", 7782, __PRETTY_FUNCTION__)
;
7783 if (channels) {
7784 ao2_container_register("channels", channels, prnt_channel_key);
7785 }
7786
7787 ast_channel_register(&surrogate_tech);
7788
7789 ast_stasis_channels_init();
7790
7791 ast_cli_register_multiple(cli_channel, ARRAY_LEN(cli_channel))__ast_cli_register_multiple(cli_channel, (size_t) (sizeof(cli_channel
) / sizeof(0[cli_channel])), ((void*)0))
;
7792
7793 ast_data_register_multiple_core(channel_providers, ARRAY_LEN(channel_providers))__ast_data_register_multiple(channel_providers, (size_t) (sizeof
(channel_providers) / sizeof(0[channel_providers])), "channel.c"
, ((void*)0))
;
7794
7795 ast_plc_reload();
7796
7797 ast_register_cleanup(channels_shutdown);
7798
7799}
7800
7801/*! \brief Print call group and pickup group ---*/
7802char *ast_print_group(char *buf, int buflen, ast_group_t group)
7803{
7804 unsigned int i;
7805 int first = 1;
7806 char num[3];
7807
7808 buf[0] = '\0';
7809
7810 if (!group) /* Return empty string if no group */
7811 return buf;
7812
7813 for (i = 0; i <= 63; i++) { /* Max group is 63 */
7814 if (group & ((ast_group_t) 1 << i)) {
7815 if (!first) {
7816 strncat(buf, ", ", buflen - strlen(buf) - 1)__builtin_strncat (buf, ", ", buflen - strlen(buf) - 1);
7817 } else {
7818 first = 0;
7819 }
7820 snprintf(num, sizeof(num), "%u", i);
7821 strncat(buf, num, buflen - strlen(buf) - 1)__builtin_strncat (buf, num, buflen - strlen(buf) - 1);
7822 }
7823 }
7824 return buf;
7825}
7826
7827char *ast_print_namedgroups(struct ast_str **buf, struct ast_namedgroups *group)
7828{
7829 struct ao2_container *grp = (struct ao2_container *) group;
7830 struct namedgroup_member *ng;
7831 int first = 1;
7832 struct ao2_iterator it;
7833
7834 if (!grp) {
7835 return ast_str_buffer(*buf);
7836 }
7837
7838 for (it = ao2_iterator_init(grp, 0); (ng = ao2_iterator_next(&it)__ao2_iterator_next((&it), "", "channel.c", 7838, __PRETTY_FUNCTION__
)
); ao2_ref(ng, -1)__ao2_ref((ng), (-1), "", "channel.c", 7838, __PRETTY_FUNCTION__
)
) {
7839 if (!first) {
7840 ast_str_append(buf, 0, ", ");
7841 } else {
7842 first = 0;
7843 }
7844 ast_str_append(buf, 0, "%s", ng->name);
7845 }
7846 ao2_iterator_destroy(&it);
7847
7848 return ast_str_buffer(*buf);
7849}
7850
7851static int namedgroup_match(void *obj, void *arg, int flags)
7852{
7853 void *match;
7854
7855 match = ao2_find(arg, obj, OBJ_POINTER)__ao2_find((arg), (obj), (OBJ_SEARCH_OBJECT), "", "channel.c"
, 7855, __PRETTY_FUNCTION__)
;
7856 ao2_cleanup(match)__ao2_cleanup_debug((match), "", "channel.c", 7856, __PRETTY_FUNCTION__
)
;
7857
7858 return match ? CMP_MATCH | CMP_STOP : 0;
7859}
7860
7861int ast_namedgroups_intersect(struct ast_namedgroups *a, struct ast_namedgroups *b)
7862{
7863 void *match;
7864 struct ao2_container *group_a = (struct ao2_container *) a;
7865 struct ao2_container *group_b = (struct ao2_container *) b;
7866
7867 if (!a || !b) {
7868 return 0;
7869 }
7870
7871 /*
7872 * Do groups a and b intersect? Since a and b are hash tables,
7873 * the average time complexity is:
7874 * O(a.count <= b.count ? a.count : b.count)
7875 */
7876 if (ao2_container_count(group_b) < ao2_container_count(group_a)) {
7877 /* Traverse over the smaller group. */
7878 SWAP(group_a, group_b)do { typeof(group_a) __tmp = (group_a); (group_a) = (group_b)
; (group_b) = __tmp; } while (0)
;
7879 }
7880 match = ao2_callback(group_a, 0, namedgroup_match, group_b)__ao2_callback((group_a), (0), (namedgroup_match), (group_b),
"", "channel.c", 7880, __PRETTY_FUNCTION__)
;
7881 ao2_cleanup(match)__ao2_cleanup_debug((match), "", "channel.c", 7881, __PRETTY_FUNCTION__
)
;
7882
7883 return match != NULL((void*)0);
7884}
7885
7886void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
7887{
7888 struct ast_variable *cur;
7889
7890 for (cur = vars; cur; cur = cur->next) {
7891 pbx_builtin_setvar_helper(chan, cur->name, cur->value);
7892 }
7893}
7894
7895static void *silence_generator_alloc(struct ast_channel *chan, void *data)
7896{
7897 /* just store the data pointer in the channel structure */
7898 return data;
7899}
7900
7901static void silence_generator_release(struct ast_channel *chan, void *data)
7902{
7903 /* nothing to do */
7904}
7905
7906static int silence_generator_generate(struct ast_channel *chan, void *data, int len, int samples)
7907{
7908 short buf[samples];
7909 struct ast_frame frame = {
7910 .frametype = AST_FRAME_VOICE,
7911 .data.ptr = buf,
7912 .samples = samples,
7913 .datalen = sizeof(buf),
7914 };
7915 frame.subclass.format = ast_format_slin;
7916
7917 memset(buf, 0, sizeof(buf));
7918
7919 if (ast_write(chan, &frame))
7920 return -1;
7921
7922 return 0;
7923}
7924
7925static struct ast_generator silence_generator = {
7926 .alloc = silence_generator_alloc,
7927 .release = silence_generator_release,
7928 .generate = silence_generator_generate,
7929};
7930
7931struct ast_silence_generator {
7932 struct ast_format *old_write_format;
7933};
7934
7935struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan)
7936{
7937 struct ast_silence_generator *state;
7938
7939 if (!(state = ast_calloc(1, sizeof(*state))_ast_calloc((1), (sizeof(*state)), "channel.c", 7939, __PRETTY_FUNCTION__
)
)) {
7940 return NULL((void*)0);
7941 }
7942
7943 state->old_write_format = ao2_bump(ast_channel_writeformat(chan))({ typeof((ast_channel_writeformat(chan))) __obj___LINE__ = (
(ast_channel_writeformat(chan))); if (__obj___LINE__) { __ao2_ref
((__obj___LINE__), (+1), (("")), "channel.c", 7943, __PRETTY_FUNCTION__
); } __obj___LINE__; })
;
7944
7945 if (ast_set_write_format(chan, ast_format_slin) < 0) {
7946 ast_log(LOG_ERROR4, "channel.c", 7946, __PRETTY_FUNCTION__, "Could not set write format to SLINEAR\n");
7947 ast_freefree(state);
7948 return NULL((void*)0);
7949 }
7950
7951 ast_activate_generator(chan, &silence_generator, state);
7952
7953 ast_debug(1, "Started silence generator on '%s'\n", ast_channel_name(chan))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 7953, __PRETTY_FUNCTION__, "Started silence generator on '%s'\n"
, ast_channel_name(chan)); } } while (0)
;
7954
7955 return state;
7956}
7957
7958static int deactivate_silence_generator(struct ast_channel *chan)
7959{
7960 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 7960, "chan")
;
7961
7962 if (!ast_channel_generatordata(chan)) {
7963 ast_debug(1, "Trying to stop silence generator when there is no generator on '%s'\n",do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 7964, __PRETTY_FUNCTION__, "Trying to stop silence generator when there is no generator on '%s'\n"
, ast_channel_name(chan)); } } while (0)
7964 ast_channel_name(chan))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 7964, __PRETTY_FUNCTION__, "Trying to stop silence generator when there is no generator on '%s'\n"
, ast_channel_name(chan)); } } while (0)
;
7965 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 7965, "chan"
)
;
7966 return 0;
7967 }
7968 if (ast_channel_generator(chan) != &silence_generator) {
7969 ast_debug(1, "Trying to stop silence generator when it is not the current generator on '%s'\n",do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 7970, __PRETTY_FUNCTION__, "Trying to stop silence generator when it is not the current generator on '%s'\n"
, ast_channel_name(chan)); } } while (0)
7970 ast_channel_name(chan))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 7970, __PRETTY_FUNCTION__, "Trying to stop silence generator when it is not the current generator on '%s'\n"
, ast_channel_name(chan)); } } while (0)
;
7971 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 7971, "chan"
)
;
7972 return 0;
7973 }
7974 deactivate_generator_nolock(chan);
7975
7976 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 7976, "chan"
)
;
7977
7978 return 1;
7979}
7980
7981void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
7982{
7983 if (!state) {
7984 return;
7985 }
7986
7987 if (deactivate_silence_generator(chan)) {
7988 ast_debug(1, "Stopped silence generator on '%s'\n", ast_channel_name(chan))do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 7988, __PRETTY_FUNCTION__, "Stopped silence generator on '%s'\n"
, ast_channel_name(chan)); } } while (0)
;
7989 if (ast_set_write_format(chan, state->old_write_format) < 0) {
7990 ast_log(LOG_ERROR4, "channel.c", 7990, __PRETTY_FUNCTION__, "Could not return write format to its original state\n");
7991 }
7992 }
7993 ao2_cleanup(state->old_write_format)__ao2_cleanup_debug((state->old_write_format), "", "channel.c"
, 7993, __PRETTY_FUNCTION__)
;
7994 ast_freefree(state);
7995}
7996
7997
7998/*! \ brief Convert channel reloadreason (ENUM) to text string for manager event */
7999const char *channelreloadreason2txt(enum channelreloadreason reason)
8000{
8001 switch (reason) {
8002 case CHANNEL_MODULE_LOAD:
8003 return "LOAD (Channel module load)";
8004
8005 case CHANNEL_MODULE_RELOAD:
8006 return "RELOAD (Channel module reload)";
8007
8008 case CHANNEL_CLI_RELOAD:
8009 return "CLIRELOAD (Channel module reload by CLI command)";
8010
8011 default:
8012 return "MANAGERRELOAD (Channel module reload by manager)";
8013 }
8014};
8015
8016/*
8017 * Wrappers for various ast_say_*() functions that call the full version
8018 * of the same functions.
8019 * The proper place would be say.c, but that file is optional and one
8020 * must be able to build asterisk even without it (using a loadable 'say'
8021 * implementation that only supplies the 'full' version of the functions.
8022 */
8023
8024int ast_say_number(struct ast_channel *chan, int num,
8025 const char *ints, const char *language, const char *options)
8026{
8027 return ast_say_number_full(chan, num, ints, language, options, -1, -1);
8028}
8029
8030int ast_say_enumeration(struct ast_channel *chan, int num,
8031 const char *ints, const char *language, const char *options)
8032{
8033 return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
8034}
8035
8036int ast_say_digits(struct ast_channel *chan, int num,
8037 const char *ints, const char *lang)
8038{
8039 return ast_say_digits_full(chan, num, ints, lang, -1, -1);
8040}
8041
8042int ast_say_digit_str(struct ast_channel *chan, const char *str,
8043 const char *ints, const char *lang)
8044{
8045 return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
8046}
8047
8048int ast_say_character_str(struct ast_channel *chan, const char *str,
8049 const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity)
8050{
8051 return ast_say_character_str_full(chan, str, ints, lang, sensitivity, -1, -1);
8052}
8053
8054int ast_say_phonetic_str(struct ast_channel *chan, const char *str,
8055 const char *ints, const char *lang)
8056{
8057 return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
8058}
8059
8060int ast_say_digits_full(struct ast_channel *chan, int num,
8061 const char *ints, const char *lang, int audiofd, int ctrlfd)
8062{
8063 char buf[256];
8064
8065 snprintf(buf, sizeof(buf), "%d", num);
8066
8067 return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
8068}
8069
8070void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
8071{
8072 ast_party_id_copy(&dest->id, &src->id);
8073 ast_party_id_copy(&dest->ani, &src->ani);
8074 dest->ani2 = src->ani2;
8075}
8076
8077void ast_connected_line_copy_to_caller(struct ast_party_caller *dest, const struct ast_party_connected_line *src)
8078{
8079 ast_party_id_copy(&dest->id, &src->id);
8080 ast_party_id_copy(&dest->ani, &src->ani);
8081
8082 dest->ani2 = src->ani2;
8083}
8084
8085void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
8086{
8087 if (ast_channel_connected(chan) == connected) {
8088 /* Don't set to self */
8089 return;
8090 }
8091
8092 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 8092, "chan")
;
8093 ast_party_connected_line_set(ast_channel_connected(chan), connected, update);
8094 ast_channel_publish_snapshot(chan);
8095 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 8095, "chan"
)
;
8096}
8097
8098/*! \note Should follow struct ast_party_name */
8099struct ast_party_name_ies {
8100 /*! \brief Subscriber name ie */
8101 int str;
8102 /*! \brief Character set ie. */
8103 int char_set;
8104 /*! \brief presentation-indicator ie */
8105 int presentation;
8106 /*! \brief valid/present ie */
8107 int valid;
8108};
8109
8110/*!
8111 * \internal
8112 * \since 1.8
8113 * \brief Build a party name information data frame component.
8114 *
8115 * \param data Buffer to fill with the frame data
8116 * \param datalen Size of the buffer to fill
8117 * \param name Party name information
8118 * \param label Name of particular party name
8119 * \param ies Data frame ie values for the party name components
8120 *
8121 * \retval -1 if error
8122 * \retval Amount of data buffer used
8123 */
8124static 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)
8125{
8126 size_t length;
8127 size_t pos = 0;
8128
8129 /*
8130 * The size of integer values must be fixed in case the frame is
8131 * shipped to another machine.
8132 */
8133 if (name->str) {
8134 length = strlen(name->str);
8135 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
8136 ast_log(LOG_WARNING3, "channel.c", 8136, __PRETTY_FUNCTION__, "No space left for %s name\n", label);
8137 return -1;
8138 }
8139 data[pos++] = ies->str;
8140 data[pos++] = length;
8141 memcpy(data + pos, name->str, length);
8142 pos += length;
8143 }
8144
8145 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
8146 ast_log(LOG_WARNING3, "channel.c", 8146, __PRETTY_FUNCTION__, "No space left for %s name char set\n", label);
8147 return -1;
8148 }
8149 data[pos++] = ies->char_set;
8150 data[pos++] = 1;
8151 data[pos++] = name->char_set;
8152
8153 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
8154 ast_log(LOG_WARNING3, "channel.c", 8154, __PRETTY_FUNCTION__, "No space left for %s name presentation\n", label);
8155 return -1;
8156 }
8157 data[pos++] = ies->presentation;
8158 data[pos++] = 1;
8159 data[pos++] = name->presentation;
8160
8161 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
8162 ast_log(LOG_WARNING3, "channel.c", 8162, __PRETTY_FUNCTION__, "No space left for %s name valid\n", label);
8163 return -1;
8164 }
8165 data[pos++] = ies->valid;
8166 data[pos++] = 1;
8167 data[pos++] = name->valid;
8168
8169 return pos;
8170}
8171
8172/*! \note Should follow struct ast_party_number */
8173struct ast_party_number_ies {
8174 /*! \brief Subscriber phone number ie */
8175 int str;
8176 /*! \brief Type-Of-Number and Numbering-Plan ie */
8177 int plan;
8178 /*! \brief presentation-indicator ie */
8179 int presentation;
8180 /*! \brief valid/present ie */
8181 int valid;
8182};
8183
8184/*!
8185 * \internal
8186 * \since 1.8
8187 * \brief Build a party number information data frame component.
8188 *
8189 * \param data Buffer to fill with the frame data
8190 * \param datalen Size of the buffer to fill
8191 * \param number Party number information
8192 * \param label Name of particular party number
8193 * \param ies Data frame ie values for the party number components
8194 *
8195 * \retval -1 if error
8196 * \retval Amount of data buffer used
8197 */
8198static 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)
8199{
8200 size_t length;
8201 size_t pos = 0;
8202
8203 /*
8204 * The size of integer values must be fixed in case the frame is
8205 * shipped to another machine.
8206 */
8207 if (number->str) {
8208 length = strlen(number->str);
8209 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
8210 ast_log(LOG_WARNING3, "channel.c", 8210, __PRETTY_FUNCTION__, "No space left for %s number\n", label);
8211 return -1;
8212 }
8213 data[pos++] = ies->str;
8214 data[pos++] = length;
8215 memcpy(data + pos, number->str, length);
8216 pos += length;
8217 }
8218
8219 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
8220 ast_log(LOG_WARNING3, "channel.c", 8220, __PRETTY_FUNCTION__, "No space left for %s numbering plan\n", label);
8221 return -1;
8222 }
8223 data[pos++] = ies->plan;
8224 data[pos++] = 1;
8225 data[pos++] = number->plan;
8226
8227 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
8228 ast_log(LOG_WARNING3, "channel.c", 8228, __PRETTY_FUNCTION__, "No space left for %s number presentation\n", label);
8229 return -1;
8230 }
8231 data[pos++] = ies->presentation;
8232 data[pos++] = 1;
8233 data[pos++] = number->presentation;
8234
8235 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
8236 ast_log(LOG_WARNING3, "channel.c", 8236, __PRETTY_FUNCTION__, "No space left for %s number valid\n", label);
8237 return -1;
8238 }
8239 data[pos++] = ies->valid;
8240 data[pos++] = 1;
8241 data[pos++] = number->valid;
8242
8243 return pos;
8244}
8245
8246/*! \note Should follow struct ast_party_subaddress */
8247struct ast_party_subaddress_ies {
8248 /*! \brief subaddress ie. */
8249 int str;
8250 /*! \brief subaddress type ie */
8251 int type;
8252 /*! \brief odd/even indicator ie */
8253 int odd_even_indicator;
8254 /*! \brief valid/present ie */
8255 int valid;
8256};
8257
8258/*!
8259 * \internal
8260 * \since 1.8
8261 * \brief Build a party subaddress information data frame component.
8262 *
8263 * \param data Buffer to fill with the frame data
8264 * \param datalen Size of the buffer to fill
8265 * \param subaddress Party subaddress information
8266 * \param label Name of particular party subaddress
8267 * \param ies Data frame ie values for the party subaddress components
8268 *
8269 * \retval -1 if error
8270 * \retval Amount of data buffer used
8271 */
8272static 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)
8273{
8274 size_t length;
8275 size_t pos = 0;
8276
8277 /*
8278 * The size of integer values must be fixed in case the frame is
8279 * shipped to another machine.
8280 */
8281 if (subaddress->str) {
8282 length = strlen(subaddress->str);
8283 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
8284 ast_log(LOG_WARNING3, "channel.c", 8284, __PRETTY_FUNCTION__, "No space left for %s subaddress\n", label);
8285 return -1;
8286 }
8287 data[pos++] = ies->str;
8288 data[pos++] = length;
8289 memcpy(data + pos, subaddress->str, length);
8290 pos += length;
8291 }
8292
8293 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
8294 ast_log(LOG_WARNING3, "channel.c", 8294, __PRETTY_FUNCTION__, "No space left for %s type of subaddress\n", label);
8295 return -1;
8296 }
8297 data[pos++] = ies->type;
8298 data[pos++] = 1;
8299 data[pos++] = subaddress->type;
8300
8301 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
8302 ast_log(LOG_WARNING3, "channel.c", 8302, __PRETTY_FUNCTION__,
8303 "No space left for %s subaddress odd-even indicator\n", label);
8304 return -1;
8305 }
8306 data[pos++] = ies->odd_even_indicator;
8307 data[pos++] = 1;
8308 data[pos++] = subaddress->odd_even_indicator;
8309
8310 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
8311 ast_log(LOG_WARNING3, "channel.c", 8311, __PRETTY_FUNCTION__, "No space left for %s subaddress valid\n", label);
8312 return -1;
8313 }
8314 data[pos++] = ies->valid;
8315 data[pos++] = 1;
8316 data[pos++] = subaddress->valid;
8317
8318 return pos;
8319}
8320
8321/*! \note Should follow struct ast_party_id */
8322struct ast_party_id_ies {
8323 /*! \brief Subscriber name ies */
8324 struct ast_party_name_ies name;
8325 /*! \brief Subscriber phone number ies */
8326 struct ast_party_number_ies number;
8327 /*! \brief Subscriber subaddress ies. */
8328 struct ast_party_subaddress_ies subaddress;
8329 /*! \brief User party id tag ie. */
8330 int tag;
8331 /*!
8332 * \brief Combined name and number presentation ie.
8333 * \note Not sent if value is zero.
8334 */
8335 int combined_presentation;
8336};
8337
8338/*!
8339 * \internal
8340 * \since 1.8
8341 * \brief Build a party id information data frame component.
8342 *
8343 * \param data Buffer to fill with the frame data
8344 * \param datalen Size of the buffer to fill
8345 * \param id Party id information
8346 * \param label Name of particular party id
8347 * \param ies Data frame ie values for the party id components
8348 * \param update What id information to build. NULL if all.
8349 *
8350 * \retval -1 if error
8351 * \retval Amount of data buffer used
8352 */
8353static int party_id_build_data(unsigned char *data, size_t datalen,
8354 const struct ast_party_id *id, const char *label, const struct ast_party_id_ies *ies,
8355 const struct ast_set_party_id *update)
8356{
8357 size_t length;
8358 size_t pos = 0;
8359 int res;
8360
8361 /*
8362 * The size of integer values must be fixed in case the frame is
8363 * shipped to another machine.
8364 */
8365
8366 if (!update || update->name) {
8367 res = party_name_build_data(data + pos, datalen - pos, &id->name, label,
8368 &ies->name);
8369 if (res < 0) {
8370 return -1;
8371 }
8372 pos += res;
8373 }
8374
8375 if (!update || update->number) {
8376 res = party_number_build_data(data + pos, datalen - pos, &id->number, label,
8377 &ies->number);
8378 if (res < 0) {
8379 return -1;
8380 }
8381 pos += res;
8382 }
8383
8384 if (!update || update->subaddress) {
8385 res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress,
8386 label, &ies->subaddress);
8387 if (res < 0) {
8388 return -1;
8389 }
8390 pos += res;
8391 }
8392
8393 /* *************** Party id user tag **************************** */
8394 if (id->tag) {
8395 length = strlen(id->tag);
8396 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
8397 ast_log(LOG_WARNING3, "channel.c", 8397, __PRETTY_FUNCTION__, "No space left for %s tag\n", label);
8398 return -1;
8399 }
8400 data[pos++] = ies->tag;
8401 data[pos++] = length;
8402 memcpy(data + pos, id->tag, length);
8403 pos += length;
8404 }
8405
8406 /* *************** Party id combined presentation *************** */
8407 if (ies->combined_presentation && (!update || update->number)) {
8408 int presentation;
8409
8410 if (!update || update->name) {
8411 presentation = ast_party_id_presentation(id);
8412 } else {
8413 /*
8414 * We must compromise because not all the information is available
8415 * to determine a combined presentation value.
8416 * We will only send the number presentation instead.
8417 */
8418 presentation = id->number.presentation;
8419 }
8420
8421 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
8422 ast_log(LOG_WARNING3, "channel.c", 8422, __PRETTY_FUNCTION__, "No space left for %s combined presentation\n", label);
8423 return -1;
8424 }
8425 data[pos++] = ies->combined_presentation;
8426 data[pos++] = 1;
8427 data[pos++] = presentation;
8428 }
8429
8430 return pos;
8431}
8432
8433/*!
8434 * \brief Element identifiers for connected line indication frame data
8435 * \note Only add to the end of this enum.
8436 */
8437enum {
8438 AST_CONNECTED_LINE_NUMBER,
8439 AST_CONNECTED_LINE_NAME,
8440 AST_CONNECTED_LINE_NUMBER_PLAN,
8441 AST_CONNECTED_LINE_ID_PRESENTATION,/* Combined number and name presentation. */
8442 AST_CONNECTED_LINE_SOURCE,
8443 AST_CONNECTED_LINE_SUBADDRESS,
8444 AST_CONNECTED_LINE_SUBADDRESS_TYPE,
8445 AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
8446 AST_CONNECTED_LINE_SUBADDRESS_VALID,
8447 AST_CONNECTED_LINE_TAG,
8448 AST_CONNECTED_LINE_VERSION,
8449 /*
8450 * No more party id combined number and name presentation values
8451 * need to be created.
8452 */
8453 AST_CONNECTED_LINE_NAME_VALID,
8454 AST_CONNECTED_LINE_NAME_CHAR_SET,
8455 AST_CONNECTED_LINE_NAME_PRESENTATION,
8456 AST_CONNECTED_LINE_NUMBER_VALID,
8457 AST_CONNECTED_LINE_NUMBER_PRESENTATION,
8458 AST_CONNECTED_LINE_PRIV_NUMBER,
8459 AST_CONNECTED_LINE_PRIV_NUMBER_PLAN,
8460 AST_CONNECTED_LINE_PRIV_NUMBER_VALID,
8461 AST_CONNECTED_LINE_PRIV_NUMBER_PRESENTATION,
8462 AST_CONNECTED_LINE_PRIV_NAME,
8463 AST_CONNECTED_LINE_PRIV_NAME_VALID,
8464 AST_CONNECTED_LINE_PRIV_NAME_CHAR_SET,
8465 AST_CONNECTED_LINE_PRIV_NAME_PRESENTATION,
8466 AST_CONNECTED_LINE_PRIV_SUBADDRESS,
8467 AST_CONNECTED_LINE_PRIV_SUBADDRESS_TYPE,
8468 AST_CONNECTED_LINE_PRIV_SUBADDRESS_ODD_EVEN,
8469 AST_CONNECTED_LINE_PRIV_SUBADDRESS_VALID,
8470 AST_CONNECTED_LINE_PRIV_TAG,
8471};
8472
8473int 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)
8474{
8475 int32_t value;
8476 size_t pos = 0;
8477 int res;
8478
8479 static const struct ast_party_id_ies ies = {
8480 .name.str = AST_CONNECTED_LINE_NAME,
8481 .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET,
8482 .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION,
8483 .name.valid = AST_CONNECTED_LINE_NAME_VALID,
8484
8485 .number.str = AST_CONNECTED_LINE_NUMBER,
8486 .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN,
8487 .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION,
8488 .number.valid = AST_CONNECTED_LINE_NUMBER_VALID,
8489
8490 .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS,
8491 .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE,
8492 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
8493 .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID,
8494
8495 .tag = AST_CONNECTED_LINE_TAG,
8496 .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION,
8497 };
8498
8499 static const struct ast_party_id_ies priv_ies = {
8500 .name.str = AST_CONNECTED_LINE_PRIV_NAME,
8501 .name.char_set = AST_CONNECTED_LINE_PRIV_NAME_CHAR_SET,
8502 .name.presentation = AST_CONNECTED_LINE_PRIV_NAME_PRESENTATION,
8503 .name.valid = AST_CONNECTED_LINE_PRIV_NAME_VALID,
8504
8505 .number.str = AST_CONNECTED_LINE_PRIV_NUMBER,
8506 .number.plan = AST_CONNECTED_LINE_PRIV_NUMBER_PLAN,
8507 .number.presentation = AST_CONNECTED_LINE_PRIV_NUMBER_PRESENTATION,
8508 .number.valid = AST_CONNECTED_LINE_PRIV_NUMBER_VALID,
8509
8510 .subaddress.str = AST_CONNECTED_LINE_PRIV_SUBADDRESS,
8511 .subaddress.type = AST_CONNECTED_LINE_PRIV_SUBADDRESS_TYPE,
8512 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_PRIV_SUBADDRESS_ODD_EVEN,
8513 .subaddress.valid = AST_CONNECTED_LINE_PRIV_SUBADDRESS_VALID,
8514
8515 .tag = AST_CONNECTED_LINE_PRIV_TAG,
8516 .combined_presentation = 0,/* Not sent. */
8517 };
8518
8519 /*
8520 * The size of integer values must be fixed in case the frame is
8521 * shipped to another machine.
8522 */
8523
8524 /* Connected line frame version */
8525 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
8526 ast_log(LOG_WARNING3, "channel.c", 8526, __PRETTY_FUNCTION__, "No space left for connected line frame version\n");
8527 return -1;
8528 }
8529 data[pos++] = AST_CONNECTED_LINE_VERSION;
8530 data[pos++] = 1;
8531 data[pos++] = 2;/* Version 1 did not have a version ie */
8532
8533 res = party_id_build_data(data + pos, datalen - pos, &connected->id,
8534 "connected line", &ies, update ? &update->id : NULL((void*)0));
8535 if (res < 0) {
8536 return -1;
8537 }
8538 pos += res;
8539
8540 res = party_id_build_data(data + pos, datalen - pos, &connected->priv,
8541 "connected line priv", &priv_ies, update ? &update->priv : NULL((void*)0));
8542 if (res < 0) {
8543 return -1;
8544 }
8545 pos += res;
8546
8547 /* Connected line source */
8548 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
8549 ast_log(LOG_WARNING3, "channel.c", 8549, __PRETTY_FUNCTION__, "No space left for connected line source\n");
8550 return -1;
8551 }
8552 data[pos++] = AST_CONNECTED_LINE_SOURCE;
8553 data[pos++] = sizeof(value);
8554 value = htonl(connected->source)(__extension__ ({ unsigned int __v, __x = (connected->source
); if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; }))
;
8555 memcpy(data + pos, &value, sizeof(value));
8556 pos += sizeof(value);
8557
8558 return pos;
8559}
8560
8561int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, struct ast_party_connected_line *connected)
8562{
8563 size_t pos;
8564 unsigned char ie_len;
8565 unsigned char ie_id;
8566 int32_t value;
8567 int frame_version = 1;
8568 int combined_presentation = 0;
8569 int got_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
8570
8571 for (pos = 0; pos < datalen; pos += ie_len) {
8572 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
8573 ast_log(LOG_WARNING3, "channel.c", 8573, __PRETTY_FUNCTION__, "Invalid connected line update\n");
8574 return -1;
8575 }
8576 ie_id = data[pos++];
8577 ie_len = data[pos++];
8578 if (datalen < pos + ie_len) {
8579 ast_log(LOG_WARNING3, "channel.c", 8579, __PRETTY_FUNCTION__, "Invalid connected line update\n");
8580 return -1;
8581 }
8582
8583 switch (ie_id) {
8584/* Connected line party frame version */
8585 case AST_CONNECTED_LINE_VERSION:
8586 if (ie_len != 1) {
8587 ast_log(LOG_WARNING3, "channel.c", 8587, __PRETTY_FUNCTION__, "Invalid connected line frame version (%u)\n",
8588 (unsigned) ie_len);
8589 break;
8590 }
8591 frame_version = data[pos];
8592 break;
8593/* Connected line party id name */
8594 case AST_CONNECTED_LINE_NAME:
8595 ast_freefree(connected->id.name.str);
8596 connected->id.name.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 8596, __PRETTY_FUNCTION__
)
;
8597 if (connected->id.name.str) {
8598 memcpy(connected->id.name.str, data + pos, ie_len);
8599 connected->id.name.str[ie_len] = 0;
8600 }
8601 break;
8602 case AST_CONNECTED_LINE_NAME_CHAR_SET:
8603 if (ie_len != 1) {
8604 ast_log(LOG_WARNING3, "channel.c", 8604, __PRETTY_FUNCTION__, "Invalid connected line name char set (%u)\n",
8605 (unsigned) ie_len);
8606 break;
8607 }
8608 connected->id.name.char_set = data[pos];
8609 break;
8610 case AST_CONNECTED_LINE_NAME_PRESENTATION:
8611 if (ie_len != 1) {
8612 ast_log(LOG_WARNING3, "channel.c", 8612, __PRETTY_FUNCTION__, "Invalid connected line name presentation (%u)\n",
8613 (unsigned) ie_len);
8614 break;
8615 }
8616 connected->id.name.presentation = data[pos];
8617 break;
8618 case AST_CONNECTED_LINE_NAME_VALID:
8619 if (ie_len != 1) {
8620 ast_log(LOG_WARNING3, "channel.c", 8620, __PRETTY_FUNCTION__, "Invalid connected line name valid (%u)\n",
8621 (unsigned) ie_len);
8622 break;
8623 }
8624 connected->id.name.valid = data[pos];
8625 break;
8626/* Connected line party id number */
8627 case AST_CONNECTED_LINE_NUMBER:
8628 ast_freefree(connected->id.number.str);
8629 connected->id.number.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 8629, __PRETTY_FUNCTION__
)
;
8630 if (connected->id.number.str) {
8631 memcpy(connected->id.number.str, data + pos, ie_len);
8632 connected->id.number.str[ie_len] = 0;
8633 }
8634 break;
8635 case AST_CONNECTED_LINE_NUMBER_PLAN:
8636 if (ie_len != 1) {
8637 ast_log(LOG_WARNING3, "channel.c", 8637, __PRETTY_FUNCTION__, "Invalid connected line numbering plan (%u)\n",
8638 (unsigned) ie_len);
8639 break;
8640 }
8641 connected->id.number.plan = data[pos];
8642 break;
8643 case AST_CONNECTED_LINE_NUMBER_PRESENTATION:
8644 if (ie_len != 1) {
8645 ast_log(LOG_WARNING3, "channel.c", 8645, __PRETTY_FUNCTION__, "Invalid connected line number presentation (%u)\n",
8646 (unsigned) ie_len);
8647 break;
8648 }
8649 connected->id.number.presentation = data[pos];
8650 break;
8651 case AST_CONNECTED_LINE_NUMBER_VALID:
8652 if (ie_len != 1) {
8653 ast_log(LOG_WARNING3, "channel.c", 8653, __PRETTY_FUNCTION__, "Invalid connected line number valid (%u)\n",
8654 (unsigned) ie_len);
8655 break;
8656 }
8657 connected->id.number.valid = data[pos];
8658 break;
8659/* Connected line party id subaddress */
8660 case AST_CONNECTED_LINE_SUBADDRESS:
8661 ast_freefree(connected->id.subaddress.str);
8662 connected->id.subaddress.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 8662, __PRETTY_FUNCTION__
)
;
8663 if (connected->id.subaddress.str) {
8664 memcpy(connected->id.subaddress.str, data + pos, ie_len);
8665 connected->id.subaddress.str[ie_len] = 0;
8666 }
8667 break;
8668 case AST_CONNECTED_LINE_SUBADDRESS_TYPE:
8669 if (ie_len != 1) {
8670 ast_log(LOG_WARNING3, "channel.c", 8670, __PRETTY_FUNCTION__, "Invalid connected line type of subaddress (%u)\n",
8671 (unsigned) ie_len);
8672 break;
8673 }
8674 connected->id.subaddress.type = data[pos];
8675 break;
8676 case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN:
8677 if (ie_len != 1) {
8678 ast_log(LOG_WARNING3, "channel.c", 8678, __PRETTY_FUNCTION__,
8679 "Invalid connected line subaddress odd-even indicator (%u)\n",
8680 (unsigned) ie_len);
8681 break;
8682 }
8683 connected->id.subaddress.odd_even_indicator = data[pos];
8684 break;
8685 case AST_CONNECTED_LINE_SUBADDRESS_VALID:
8686 if (ie_len != 1) {
8687 ast_log(LOG_WARNING3, "channel.c", 8687, __PRETTY_FUNCTION__, "Invalid connected line subaddress valid (%u)\n",
8688 (unsigned) ie_len);
8689 break;
8690 }
8691 connected->id.subaddress.valid = data[pos];
8692 break;
8693/* Connected line party tag */
8694 case AST_CONNECTED_LINE_TAG:
8695 ast_freefree(connected->id.tag);
8696 connected->id.tag = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 8696, __PRETTY_FUNCTION__
)
;
8697 if (connected->id.tag) {
8698 memcpy(connected->id.tag, data + pos, ie_len);
8699 connected->id.tag[ie_len] = 0;
8700 }
8701 break;
8702/* Connected line party id combined presentation */
8703 case AST_CONNECTED_LINE_ID_PRESENTATION:
8704 if (ie_len != 1) {
8705 ast_log(LOG_WARNING3, "channel.c", 8705, __PRETTY_FUNCTION__, "Invalid connected line combined presentation (%u)\n",
8706 (unsigned) ie_len);
8707 break;
8708 }
8709 combined_presentation = data[pos];
8710 got_combined_presentation = 1;
8711 break;
8712/* Private connected line party id name */
8713 case AST_CONNECTED_LINE_PRIV_NAME:
8714 ast_freefree(connected->priv.name.str);
8715 connected->priv.name.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 8715, __PRETTY_FUNCTION__
)
;
8716 if (connected->priv.name.str) {
8717 memcpy(connected->priv.name.str, data + pos, ie_len);
8718 connected->priv.name.str[ie_len] = 0;
8719 }
8720 break;
8721 case AST_CONNECTED_LINE_PRIV_NAME_CHAR_SET:
8722 if (ie_len != 1) {
8723 ast_log(LOG_WARNING3, "channel.c", 8723, __PRETTY_FUNCTION__, "Invalid connected line private name char set (%u)\n",
8724 (unsigned) ie_len);
8725 break;
8726 }
8727 connected->priv.name.char_set = data[pos];
8728 break;
8729 case AST_CONNECTED_LINE_PRIV_NAME_PRESENTATION:
8730 if (ie_len != 1) {
8731 ast_log(LOG_WARNING3, "channel.c", 8731, __PRETTY_FUNCTION__, "Invalid connected line private name presentation (%u)\n",
8732 (unsigned) ie_len);
8733 break;
8734 }
8735 connected->priv.name.presentation = data[pos];
8736 break;
8737 case AST_CONNECTED_LINE_PRIV_NAME_VALID:
8738 if (ie_len != 1) {
8739 ast_log(LOG_WARNING3, "channel.c", 8739, __PRETTY_FUNCTION__, "Invalid connected line private name valid (%u)\n",
8740 (unsigned) ie_len);
8741 break;
8742 }
8743 connected->priv.name.valid = data[pos];
8744 break;
8745/* Private connected line party id number */
8746 case AST_CONNECTED_LINE_PRIV_NUMBER:
8747 ast_freefree(connected->priv.number.str);
8748 connected->priv.number.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 8748, __PRETTY_FUNCTION__
)
;
8749 if (connected->priv.number.str) {
8750 memcpy(connected->priv.number.str, data + pos, ie_len);
8751 connected->priv.number.str[ie_len] = 0;
8752 }
8753 break;
8754 case AST_CONNECTED_LINE_PRIV_NUMBER_PLAN:
8755 if (ie_len != 1) {
8756 ast_log(LOG_WARNING3, "channel.c", 8756, __PRETTY_FUNCTION__, "Invalid connected line private numbering plan (%u)\n",
8757 (unsigned) ie_len);
8758 break;
8759 }
8760 connected->priv.number.plan = data[pos];
8761 break;
8762 case AST_CONNECTED_LINE_PRIV_NUMBER_PRESENTATION:
8763 if (ie_len != 1) {
8764 ast_log(LOG_WARNING3, "channel.c", 8764, __PRETTY_FUNCTION__, "Invalid connected line private number presentation (%u)\n",
8765 (unsigned) ie_len);
8766 break;
8767 }
8768 connected->priv.number.presentation = data[pos];
8769 break;
8770 case AST_CONNECTED_LINE_PRIV_NUMBER_VALID:
8771 if (ie_len != 1) {
8772 ast_log(LOG_WARNING3, "channel.c", 8772, __PRETTY_FUNCTION__, "Invalid connected line private number valid (%u)\n",
8773 (unsigned) ie_len);
8774 break;
8775 }
8776 connected->priv.number.valid = data[pos];
8777 break;
8778/* Private connected line party id subaddress */
8779 case AST_CONNECTED_LINE_PRIV_SUBADDRESS:
8780 ast_freefree(connected->priv.subaddress.str);
8781 connected->priv.subaddress.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 8781, __PRETTY_FUNCTION__
)
;
8782 if (connected->priv.subaddress.str) {
8783 memcpy(connected->priv.subaddress.str, data + pos, ie_len);
8784 connected->priv.subaddress.str[ie_len] = 0;
8785 }
8786 break;
8787 case AST_CONNECTED_LINE_PRIV_SUBADDRESS_TYPE:
8788 if (ie_len != 1) {
8789 ast_log(LOG_WARNING3, "channel.c", 8789, __PRETTY_FUNCTION__, "Invalid connected line private type of subaddress (%u)\n",
8790 (unsigned) ie_len);
8791 break;
8792 }
8793 connected->priv.subaddress.type = data[pos];
8794 break;
8795 case AST_CONNECTED_LINE_PRIV_SUBADDRESS_ODD_EVEN:
8796 if (ie_len != 1) {
8797 ast_log(LOG_WARNING3, "channel.c", 8797, __PRETTY_FUNCTION__,
8798 "Invalid connected line private subaddress odd-even indicator (%u)\n",
8799 (unsigned) ie_len);
8800 break;
8801 }
8802 connected->priv.subaddress.odd_even_indicator = data[pos];
8803 break;
8804 case AST_CONNECTED_LINE_PRIV_SUBADDRESS_VALID:
8805 if (ie_len != 1) {
8806 ast_log(LOG_WARNING3, "channel.c", 8806, __PRETTY_FUNCTION__, "Invalid connected line private subaddress valid (%u)\n",
8807 (unsigned) ie_len);
8808 break;
8809 }
8810 connected->priv.subaddress.valid = data[pos];
8811 break;
8812/* Private connected line party tag */
8813 case AST_CONNECTED_LINE_PRIV_TAG:
8814 ast_freefree(connected->priv.tag);
8815 connected->priv.tag = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 8815, __PRETTY_FUNCTION__
)
;
8816 if (connected->priv.tag) {
8817 memcpy(connected->priv.tag, data + pos, ie_len);
8818 connected->priv.tag[ie_len] = 0;
8819 }
8820 break;
8821/* Connected line party source */
8822 case AST_CONNECTED_LINE_SOURCE:
8823 if (ie_len != sizeof(value)) {
8824 ast_log(LOG_WARNING3, "channel.c", 8824, __PRETTY_FUNCTION__, "Invalid connected line source (%u)\n",
8825 (unsigned) ie_len);
8826 break;
8827 }
8828 memcpy(&value, data + pos, sizeof(value));
8829 connected->source = ntohl(value)(__extension__ ({ unsigned int __v, __x = (value); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
8830 break;
8831/* Connected line party unknown element */
8832 default:
8833 ast_debug(1, "Unknown connected line element: %u (%u)\n",do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 8834, __PRETTY_FUNCTION__, "Unknown connected line element: %u (%u)\n"
, (unsigned) ie_id, (unsigned) ie_len); } } while (0)
8834 (unsigned) ie_id, (unsigned) ie_len)do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 8834, __PRETTY_FUNCTION__, "Unknown connected line element: %u (%u)\n"
, (unsigned) ie_id, (unsigned) ie_len); } } while (0)
;
8835 break;
8836 }
8837 }
8838
8839 switch (frame_version) {
8840 case 1:
8841 /*
8842 * The other end is an earlier version that we need to adjust
8843 * for compatibility.
8844 */
8845 connected->id.name.valid = 1;
8846 connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
8847 connected->id.number.valid = 1;
8848 if (got_combined_presentation) {
8849 connected->id.name.presentation = combined_presentation;
8850 connected->id.number.presentation = combined_presentation;
8851 }
8852 break;
8853 case 2:
8854 /* The other end is at the same level as we are. */
8855 break;
8856 default:
8857 /*
8858 * The other end is newer than we are.
8859 * We need to assume that they are compatible with us.
8860 */
8861 ast_debug(1, "Connected line frame has newer version: %u\n",do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 8862, __PRETTY_FUNCTION__, "Connected line frame has newer version: %u\n"
, (unsigned) frame_version); } } while (0)
8862 (unsigned) frame_version)do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 8862, __PRETTY_FUNCTION__, "Connected line frame has newer version: %u\n"
, (unsigned) frame_version); } } while (0)
;
8863 break;
8864 }
8865
8866 return 0;
8867}
8868
8869void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
8870{
8871 unsigned char data[1024]; /* This should be large enough */
8872 size_t datalen;
8873
8874 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
8875 if (datalen == (size_t) -1) {
8876 return;
8877 }
8878
8879 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
8880}
8881
8882void 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)
8883{
8884 unsigned char data[1024]; /* This should be large enough */
8885 size_t datalen;
8886
8887 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
8888 if (datalen == (size_t) -1) {
8889 return;
8890 }
8891
8892 ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
8893}
8894
8895void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
8896{
8897 if (ast_channel_redirecting(chan) == redirecting) {
8898 /* Don't set to self */
8899 return;
8900 }
8901
8902 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 8902, "chan")
;
8903 ast_party_redirecting_set(ast_channel_redirecting(chan), redirecting, update);
8904 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 8904, "chan"
)
;
8905}
8906
8907/*!
8908 * \brief Element identifiers for redirecting indication frame data
8909 * \note Only add to the end of this enum.
8910 */
8911enum {
8912 AST_REDIRECTING_FROM_NUMBER,
8913 AST_REDIRECTING_FROM_NAME,
8914 AST_REDIRECTING_FROM_NUMBER_PLAN,
8915 AST_REDIRECTING_FROM_ID_PRESENTATION,/* Combined number and name presentation. */
8916 AST_REDIRECTING_TO_NUMBER,
8917 AST_REDIRECTING_TO_NAME,
8918 AST_REDIRECTING_TO_NUMBER_PLAN,
8919 AST_REDIRECTING_TO_ID_PRESENTATION,/* Combined number and name presentation. */
8920 AST_REDIRECTING_REASON_CODE,
8921 AST_REDIRECTING_COUNT,
8922 AST_REDIRECTING_FROM_SUBADDRESS,
8923 AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
8924 AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
8925 AST_REDIRECTING_FROM_SUBADDRESS_VALID,
8926 AST_REDIRECTING_TO_SUBADDRESS,
8927 AST_REDIRECTING_TO_SUBADDRESS_TYPE,
8928 AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
8929 AST_REDIRECTING_TO_SUBADDRESS_VALID,
8930 AST_REDIRECTING_FROM_TAG,
8931 AST_REDIRECTING_TO_TAG,
8932 AST_REDIRECTING_VERSION,
8933 /*
8934 * No more party id combined number and name presentation values
8935 * need to be created.
8936 */
8937 AST_REDIRECTING_FROM_NAME_VALID,
8938 AST_REDIRECTING_FROM_NAME_CHAR_SET,
8939 AST_REDIRECTING_FROM_NAME_PRESENTATION,
8940 AST_REDIRECTING_FROM_NUMBER_VALID,
8941 AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
8942 AST_REDIRECTING_TO_NAME_VALID,
8943 AST_REDIRECTING_TO_NAME_CHAR_SET,
8944 AST_REDIRECTING_TO_NAME_PRESENTATION,
8945 AST_REDIRECTING_TO_NUMBER_VALID,
8946 AST_REDIRECTING_TO_NUMBER_PRESENTATION,
8947 AST_REDIRECTING_ORIG_NUMBER,
8948 AST_REDIRECTING_ORIG_NUMBER_VALID,
8949 AST_REDIRECTING_ORIG_NUMBER_PLAN,
8950 AST_REDIRECTING_ORIG_NUMBER_PRESENTATION,
8951 AST_REDIRECTING_ORIG_NAME,
8952 AST_REDIRECTING_ORIG_NAME_VALID,
8953 AST_REDIRECTING_ORIG_NAME_CHAR_SET,
8954 AST_REDIRECTING_ORIG_NAME_PRESENTATION,
8955 AST_REDIRECTING_ORIG_SUBADDRESS,
8956 AST_REDIRECTING_ORIG_SUBADDRESS_TYPE,
8957 AST_REDIRECTING_ORIG_SUBADDRESS_ODD_EVEN,
8958 AST_REDIRECTING_ORIG_SUBADDRESS_VALID,
8959 AST_REDIRECTING_ORIG_TAG,
8960 AST_REDIRECTING_ORIG_REASON_CODE,
8961 AST_REDIRECTING_PRIV_TO_NUMBER,
8962 AST_REDIRECTING_PRIV_TO_NUMBER_PLAN,
8963 AST_REDIRECTING_PRIV_TO_NUMBER_VALID,
8964 AST_REDIRECTING_PRIV_TO_NUMBER_PRESENTATION,
8965 AST_REDIRECTING_PRIV_TO_NAME,
8966 AST_REDIRECTING_PRIV_TO_NAME_VALID,
8967 AST_REDIRECTING_PRIV_TO_NAME_CHAR_SET,
8968 AST_REDIRECTING_PRIV_TO_NAME_PRESENTATION,
8969 AST_REDIRECTING_PRIV_TO_SUBADDRESS,
8970 AST_REDIRECTING_PRIV_TO_SUBADDRESS_TYPE,
8971 AST_REDIRECTING_PRIV_TO_SUBADDRESS_ODD_EVEN,
8972 AST_REDIRECTING_PRIV_TO_SUBADDRESS_VALID,
8973 AST_REDIRECTING_PRIV_TO_TAG,
8974 AST_REDIRECTING_PRIV_FROM_NUMBER,
8975 AST_REDIRECTING_PRIV_FROM_NUMBER_PLAN,
8976 AST_REDIRECTING_PRIV_FROM_NUMBER_VALID,
8977 AST_REDIRECTING_PRIV_FROM_NUMBER_PRESENTATION,
8978 AST_REDIRECTING_PRIV_FROM_NAME,
8979 AST_REDIRECTING_PRIV_FROM_NAME_VALID,
8980 AST_REDIRECTING_PRIV_FROM_NAME_CHAR_SET,
8981 AST_REDIRECTING_PRIV_FROM_NAME_PRESENTATION,
8982 AST_REDIRECTING_PRIV_FROM_SUBADDRESS,
8983 AST_REDIRECTING_PRIV_FROM_SUBADDRESS_TYPE,
8984 AST_REDIRECTING_PRIV_FROM_SUBADDRESS_ODD_EVEN,
8985 AST_REDIRECTING_PRIV_FROM_SUBADDRESS_VALID,
8986 AST_REDIRECTING_PRIV_FROM_TAG,
8987 AST_REDIRECTING_PRIV_ORIG_NUMBER,
8988 AST_REDIRECTING_PRIV_ORIG_NUMBER_VALID,
8989 AST_REDIRECTING_PRIV_ORIG_NUMBER_PLAN,
8990 AST_REDIRECTING_PRIV_ORIG_NUMBER_PRESENTATION,
8991 AST_REDIRECTING_PRIV_ORIG_NAME,
8992 AST_REDIRECTING_PRIV_ORIG_NAME_VALID,
8993 AST_REDIRECTING_PRIV_ORIG_NAME_CHAR_SET,
8994 AST_REDIRECTING_PRIV_ORIG_NAME_PRESENTATION,
8995 AST_REDIRECTING_PRIV_ORIG_SUBADDRESS,
8996 AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_TYPE,
8997 AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_ODD_EVEN,
8998 AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_VALID,
8999 AST_REDIRECTING_PRIV_ORIG_TAG,
9000 AST_REDIRECTING_REASON_STR,
9001 AST_REDIRECTING_ORIG_REASON_STR,
9002};
9003
9004struct ast_party_redirecting_reason_ies {
9005 int code;
9006 int str;
9007};
9008
9009static int redirecting_reason_build_data(unsigned char *data, size_t datalen,
9010 const struct ast_party_redirecting_reason *reason, const char *label,
9011 const struct ast_party_redirecting_reason_ies *ies)
9012{
9013 size_t length;
9014 size_t pos = 0;
9015 int32_t value;
9016
9017 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
9018 ast_log(LOG_WARNING3, "channel.c", 9018, __PRETTY_FUNCTION__, "No space left for %s code\n", label);
9019 return -1;
9020 }
9021 data[pos++] = ies->code;
9022 data[pos++] = sizeof(value);
9023 value = htonl(reason->code)(__extension__ ({ unsigned int __v, __x = (reason->code); if
(__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; }))
;
9024 memcpy(data + pos, &value, sizeof(value));
9025 pos += sizeof(value);
9026
9027 if (reason->str) {
9028 length = strlen(reason->str);
9029 if (datalen < pos + sizeof(data[0] * 2) + length) {
9030 ast_log(LOG_WARNING3, "channel.c", 9030, __PRETTY_FUNCTION__, "No space left for %s string\n", label);
9031 return -1;
9032 }
9033 data[pos++] = ies->str;
9034 data[pos++] = length;
9035 memcpy(data + pos, reason->str, length);
9036 pos += length;
9037 }
9038
9039 return pos;
9040}
9041
9042int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
9043{
9044 int32_t value;
9045 size_t pos = 0;
9046 int res;
9047
9048 static const struct ast_party_id_ies orig_ies = {
9049 .name.str = AST_REDIRECTING_ORIG_NAME,
9050 .name.char_set = AST_REDIRECTING_ORIG_NAME_CHAR_SET,
9051 .name.presentation = AST_REDIRECTING_ORIG_NAME_PRESENTATION,
9052 .name.valid = AST_REDIRECTING_ORIG_NAME_VALID,
9053
9054 .number.str = AST_REDIRECTING_ORIG_NUMBER,
9055 .number.plan = AST_REDIRECTING_ORIG_NUMBER_PLAN,
9056 .number.presentation = AST_REDIRECTING_ORIG_NUMBER_PRESENTATION,
9057 .number.valid = AST_REDIRECTING_ORIG_NUMBER_VALID,
9058
9059 .subaddress.str = AST_REDIRECTING_ORIG_SUBADDRESS,
9060 .subaddress.type = AST_REDIRECTING_ORIG_SUBADDRESS_TYPE,
9061 .subaddress.odd_even_indicator = AST_REDIRECTING_ORIG_SUBADDRESS_ODD_EVEN,
9062 .subaddress.valid = AST_REDIRECTING_ORIG_SUBADDRESS_VALID,
9063
9064 .tag = AST_REDIRECTING_ORIG_TAG,
9065 .combined_presentation = 0,/* Not sent. */
9066 };
9067 static const struct ast_party_id_ies from_ies = {
9068 .name.str = AST_REDIRECTING_FROM_NAME,
9069 .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET,
9070 .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION,
9071 .name.valid = AST_REDIRECTING_FROM_NAME_VALID,
9072
9073 .number.str = AST_REDIRECTING_FROM_NUMBER,
9074 .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN,
9075 .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
9076 .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID,
9077
9078 .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS,
9079 .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
9080 .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
9081 .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID,
9082
9083 .tag = AST_REDIRECTING_FROM_TAG,
9084 .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION,
9085 };
9086 static const struct ast_party_id_ies to_ies = {
9087 .name.str = AST_REDIRECTING_TO_NAME,
9088 .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET,
9089 .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION,
9090 .name.valid = AST_REDIRECTING_TO_NAME_VALID,
9091
9092 .number.str = AST_REDIRECTING_TO_NUMBER,
9093 .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN,
9094 .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION,
9095 .number.valid = AST_REDIRECTING_TO_NUMBER_VALID,
9096
9097 .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS,
9098 .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE,
9099 .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
9100 .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID,
9101
9102 .tag = AST_REDIRECTING_TO_TAG,
9103 .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION,
9104 };
9105 static const struct ast_party_id_ies priv_orig_ies = {
9106 .name.str = AST_REDIRECTING_PRIV_ORIG_NAME,
9107 .name.char_set = AST_REDIRECTING_PRIV_ORIG_NAME_CHAR_SET,
9108 .name.presentation = AST_REDIRECTING_PRIV_ORIG_NAME_PRESENTATION,
9109 .name.valid = AST_REDIRECTING_PRIV_ORIG_NAME_VALID,
9110
9111 .number.str = AST_REDIRECTING_PRIV_ORIG_NUMBER,
9112 .number.plan = AST_REDIRECTING_PRIV_ORIG_NUMBER_PLAN,
9113 .number.presentation = AST_REDIRECTING_PRIV_ORIG_NUMBER_PRESENTATION,
9114 .number.valid = AST_REDIRECTING_PRIV_ORIG_NUMBER_VALID,
9115
9116 .subaddress.str = AST_REDIRECTING_PRIV_ORIG_SUBADDRESS,
9117 .subaddress.type = AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_TYPE,
9118 .subaddress.odd_even_indicator = AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_ODD_EVEN,
9119 .subaddress.valid = AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_VALID,
9120
9121 .tag = AST_REDIRECTING_PRIV_ORIG_TAG,
9122 .combined_presentation = 0,/* Not sent. */
9123 };
9124 static const struct ast_party_id_ies priv_from_ies = {
9125 .name.str = AST_REDIRECTING_PRIV_FROM_NAME,
9126 .name.char_set = AST_REDIRECTING_PRIV_FROM_NAME_CHAR_SET,
9127 .name.presentation = AST_REDIRECTING_PRIV_FROM_NAME_PRESENTATION,
9128 .name.valid = AST_REDIRECTING_PRIV_FROM_NAME_VALID,
9129
9130 .number.str = AST_REDIRECTING_PRIV_FROM_NUMBER,
9131 .number.plan = AST_REDIRECTING_PRIV_FROM_NUMBER_PLAN,
9132 .number.presentation = AST_REDIRECTING_PRIV_FROM_NUMBER_PRESENTATION,
9133 .number.valid = AST_REDIRECTING_PRIV_FROM_NUMBER_VALID,
9134
9135 .subaddress.str = AST_REDIRECTING_PRIV_FROM_SUBADDRESS,
9136 .subaddress.type = AST_REDIRECTING_PRIV_FROM_SUBADDRESS_TYPE,
9137 .subaddress.odd_even_indicator = AST_REDIRECTING_PRIV_FROM_SUBADDRESS_ODD_EVEN,
9138 .subaddress.valid = AST_REDIRECTING_PRIV_FROM_SUBADDRESS_VALID,
9139
9140 .tag = AST_REDIRECTING_PRIV_FROM_TAG,
9141 .combined_presentation = 0,/* Not sent. */
9142 };
9143 static const struct ast_party_id_ies priv_to_ies = {
9144 .name.str = AST_REDIRECTING_PRIV_TO_NAME,
9145 .name.char_set = AST_REDIRECTING_PRIV_TO_NAME_CHAR_SET,
9146 .name.presentation = AST_REDIRECTING_PRIV_TO_NAME_PRESENTATION,
9147 .name.valid = AST_REDIRECTING_PRIV_TO_NAME_VALID,
9148
9149 .number.str = AST_REDIRECTING_PRIV_TO_NUMBER,
9150 .number.plan = AST_REDIRECTING_PRIV_TO_NUMBER_PLAN,
9151 .number.presentation = AST_REDIRECTING_PRIV_TO_NUMBER_PRESENTATION,
9152 .number.valid = AST_REDIRECTING_PRIV_TO_NUMBER_VALID,
9153
9154 .subaddress.str = AST_REDIRECTING_PRIV_TO_SUBADDRESS,
9155 .subaddress.type = AST_REDIRECTING_PRIV_TO_SUBADDRESS_TYPE,
9156 .subaddress.odd_even_indicator = AST_REDIRECTING_PRIV_TO_SUBADDRESS_ODD_EVEN,
9157 .subaddress.valid = AST_REDIRECTING_PRIV_TO_SUBADDRESS_VALID,
9158
9159 .tag = AST_REDIRECTING_PRIV_TO_TAG,
9160 .combined_presentation = 0,/* Not sent. */
9161 };
9162 static const struct ast_party_redirecting_reason_ies reason_ies = {
9163 .code = AST_REDIRECTING_REASON_CODE,
9164 .str = AST_REDIRECTING_REASON_STR,
9165 };
9166
9167 static const struct ast_party_redirecting_reason_ies orig_reason_ies = {
9168 .code = AST_REDIRECTING_ORIG_REASON_CODE,
9169 .str = AST_REDIRECTING_ORIG_REASON_STR,
9170 };
9171
9172 /* Redirecting frame version */
9173 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
9174 ast_log(LOG_WARNING3, "channel.c", 9174, __PRETTY_FUNCTION__, "No space left for redirecting frame version\n");
9175 return -1;
9176 }
9177 data[pos++] = AST_REDIRECTING_VERSION;
9178 data[pos++] = 1;
9179 data[pos++] = 2;/* Version 1 did not have a version ie */
9180
9181 res = party_id_build_data(data + pos, datalen - pos, &redirecting->orig,
9182 "redirecting-orig", &orig_ies, update ? &update->orig : NULL((void*)0));
9183 if (res < 0) {
9184 return -1;
9185 }
9186 pos += res;
9187
9188 res = party_id_build_data(data + pos, datalen - pos, &redirecting->from,
9189 "redirecting-from", &from_ies, update ? &update->from : NULL((void*)0));
9190 if (res < 0) {
9191 return -1;
9192 }
9193 pos += res;
9194
9195 res = party_id_build_data(data + pos, datalen - pos, &redirecting->to,
9196 "redirecting-to", &to_ies, update ? &update->to : NULL((void*)0));
9197 if (res < 0) {
9198 return -1;
9199 }
9200 pos += res;
9201
9202 res = party_id_build_data(data + pos, datalen - pos, &redirecting->priv_orig,
9203 "redirecting-priv-orig", &priv_orig_ies, update ? &update->priv_orig : NULL((void*)0));
9204 if (res < 0) {
9205 return -1;
9206 }
9207 pos += res;
9208
9209 res = party_id_build_data(data + pos, datalen - pos, &redirecting->priv_from,
9210 "redirecting-priv-from", &priv_from_ies, update ? &update->priv_from : NULL((void*)0));
9211 if (res < 0) {
9212 return -1;
9213 }
9214 pos += res;
9215
9216 res = party_id_build_data(data + pos, datalen - pos, &redirecting->priv_to,
9217 "redirecting-priv-to", &priv_to_ies, update ? &update->priv_to : NULL((void*)0));
9218 if (res < 0) {
9219 return -1;
9220 }
9221 pos += res;
9222
9223 /* Redirecting reason */
9224 res = redirecting_reason_build_data(data + pos, datalen - pos, &redirecting->reason,
9225 "redirecting-reason", &reason_ies);
9226 if (res < 0) {
9227 return -1;
9228 }
9229 pos += res;
9230
9231 /* Redirecting original reason */
9232 res = redirecting_reason_build_data(data + pos, datalen - pos, &redirecting->orig_reason,
9233 "redirecting-orig-reason", &orig_reason_ies);
9234 if (res < 0) {
9235 return -1;
9236 }
9237 pos += res;
9238
9239 /* Redirecting count */
9240 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
9241 ast_log(LOG_WARNING3, "channel.c", 9241, __PRETTY_FUNCTION__, "No space left for redirecting count\n");
9242 return -1;
9243 }
9244 data[pos++] = AST_REDIRECTING_COUNT;
9245 data[pos++] = sizeof(value);
9246 value = htonl(redirecting->count)(__extension__ ({ unsigned int __v, __x = (redirecting->count
); if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; }))
;
9247 memcpy(data + pos, &value, sizeof(value));
9248 pos += sizeof(value);
9249
9250 return pos;
9251}
9252
9253int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct ast_party_redirecting *redirecting)
9254{
9255 size_t pos;
9256 unsigned char ie_len;
9257 unsigned char ie_id;
9258 int32_t value;
9259 int frame_version = 1;
9260 int from_combined_presentation = 0;
9261 int got_from_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
9262 int to_combined_presentation = 0;
9263 int got_to_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
9264
9265 for (pos = 0; pos < datalen; pos += ie_len) {
9266 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
9267 ast_log(LOG_WARNING3, "channel.c", 9267, __PRETTY_FUNCTION__, "Invalid redirecting update\n");
9268 return -1;
9269 }
9270 ie_id = data[pos++];
9271 ie_len = data[pos++];
9272 if (datalen < pos + ie_len) {
9273 ast_log(LOG_WARNING3, "channel.c", 9273, __PRETTY_FUNCTION__, "Invalid redirecting update\n");
9274 return -1;
9275 }
9276
9277 switch (ie_id) {
9278/* Redirecting frame version */
9279 case AST_REDIRECTING_VERSION:
9280 if (ie_len != 1) {
9281 ast_log(LOG_WARNING3, "channel.c", 9281, __PRETTY_FUNCTION__, "Invalid redirecting frame version (%u)\n",
9282 (unsigned) ie_len);
9283 break;
9284 }
9285 frame_version = data[pos];
9286 break;
9287/* Redirecting-orig party id name */
9288 case AST_REDIRECTING_ORIG_NAME:
9289 ast_freefree(redirecting->orig.name.str);
9290 redirecting->orig.name.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9290, __PRETTY_FUNCTION__
)
;
9291 if (redirecting->orig.name.str) {
9292 memcpy(redirecting->orig.name.str, data + pos, ie_len);
9293 redirecting->orig.name.str[ie_len] = 0;
9294 }
9295 break;
9296 case AST_REDIRECTING_ORIG_NAME_CHAR_SET:
9297 if (ie_len != 1) {
9298 ast_log(LOG_WARNING3, "channel.c", 9298, __PRETTY_FUNCTION__, "Invalid redirecting-orig name char set (%u)\n",
9299 (unsigned) ie_len);
9300 break;
9301 }
9302 redirecting->orig.name.char_set = data[pos];
9303 break;
9304 case AST_REDIRECTING_ORIG_NAME_PRESENTATION:
9305 if (ie_len != 1) {
9306 ast_log(LOG_WARNING3, "channel.c", 9306, __PRETTY_FUNCTION__, "Invalid redirecting-orig name presentation (%u)\n",
9307 (unsigned) ie_len);
9308 break;
9309 }
9310 redirecting->orig.name.presentation = data[pos];
9311 break;
9312 case AST_REDIRECTING_ORIG_NAME_VALID:
9313 if (ie_len != 1) {
9314 ast_log(LOG_WARNING3, "channel.c", 9314, __PRETTY_FUNCTION__, "Invalid redirecting-orig name valid (%u)\n",
9315 (unsigned) ie_len);
9316 break;
9317 }
9318 redirecting->orig.name.valid = data[pos];
9319 break;
9320/* Redirecting-orig party id number */
9321 case AST_REDIRECTING_ORIG_NUMBER:
9322 ast_freefree(redirecting->orig.number.str);
9323 redirecting->orig.number.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9323, __PRETTY_FUNCTION__
)
;
9324 if (redirecting->orig.number.str) {
9325 memcpy(redirecting->orig.number.str, data + pos, ie_len);
9326 redirecting->orig.number.str[ie_len] = 0;
9327 }
9328 break;
9329 case AST_REDIRECTING_ORIG_NUMBER_PLAN:
9330 if (ie_len != 1) {
9331 ast_log(LOG_WARNING3, "channel.c", 9331, __PRETTY_FUNCTION__, "Invalid redirecting-orig numbering plan (%u)\n",
9332 (unsigned) ie_len);
9333 break;
9334 }
9335 redirecting->orig.number.plan = data[pos];
9336 break;
9337 case AST_REDIRECTING_ORIG_NUMBER_PRESENTATION:
9338 if (ie_len != 1) {
9339 ast_log(LOG_WARNING3, "channel.c", 9339, __PRETTY_FUNCTION__, "Invalid redirecting-orig number presentation (%u)\n",
9340 (unsigned) ie_len);
9341 break;
9342 }
9343 redirecting->orig.number.presentation = data[pos];
9344 break;
9345 case AST_REDIRECTING_ORIG_NUMBER_VALID:
9346 if (ie_len != 1) {
9347 ast_log(LOG_WARNING3, "channel.c", 9347, __PRETTY_FUNCTION__, "Invalid redirecting-orig number valid (%u)\n",
9348 (unsigned) ie_len);
9349 break;
9350 }
9351 redirecting->orig.number.valid = data[pos];
9352 break;
9353/* Redirecting-orig party id subaddress */
9354 case AST_REDIRECTING_ORIG_SUBADDRESS:
9355 ast_freefree(redirecting->orig.subaddress.str);
9356 redirecting->orig.subaddress.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9356, __PRETTY_FUNCTION__
)
;
9357 if (redirecting->orig.subaddress.str) {
9358 memcpy(redirecting->orig.subaddress.str, data + pos, ie_len);
9359 redirecting->orig.subaddress.str[ie_len] = 0;
9360 }
9361 break;
9362 case AST_REDIRECTING_ORIG_SUBADDRESS_TYPE:
9363 if (ie_len != 1) {
9364 ast_log(LOG_WARNING3, "channel.c", 9364, __PRETTY_FUNCTION__, "Invalid redirecting-orig type of subaddress (%u)\n",
9365 (unsigned) ie_len);
9366 break;
9367 }
9368 redirecting->orig.subaddress.type = data[pos];
9369 break;
9370 case AST_REDIRECTING_ORIG_SUBADDRESS_ODD_EVEN:
9371 if (ie_len != 1) {
9372 ast_log(LOG_WARNING3, "channel.c", 9372, __PRETTY_FUNCTION__,
9373 "Invalid redirecting-orig subaddress odd-even indicator (%u)\n",
9374 (unsigned) ie_len);
9375 break;
9376 }
9377 redirecting->orig.subaddress.odd_even_indicator = data[pos];
9378 break;
9379 case AST_REDIRECTING_ORIG_SUBADDRESS_VALID:
9380 if (ie_len != 1) {
9381 ast_log(LOG_WARNING3, "channel.c", 9381, __PRETTY_FUNCTION__, "Invalid redirecting-orig subaddress valid (%u)\n",
9382 (unsigned) ie_len);
9383 break;
9384 }
9385 redirecting->orig.subaddress.valid = data[pos];
9386 break;
9387/* Redirecting-orig party id tag */
9388 case AST_REDIRECTING_ORIG_TAG:
9389 ast_freefree(redirecting->orig.tag);
9390 redirecting->orig.tag = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9390, __PRETTY_FUNCTION__
)
;
9391 if (redirecting->orig.tag) {
9392 memcpy(redirecting->orig.tag, data + pos, ie_len);
9393 redirecting->orig.tag[ie_len] = 0;
9394 }
9395 break;
9396/* Redirecting-from party id name */
9397 case AST_REDIRECTING_FROM_NAME:
9398 ast_freefree(redirecting->from.name.str);
9399 redirecting->from.name.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9399, __PRETTY_FUNCTION__
)
;
9400 if (redirecting->from.name.str) {
9401 memcpy(redirecting->from.name.str, data + pos, ie_len);
9402 redirecting->from.name.str[ie_len] = 0;
9403 }
9404 break;
9405 case AST_REDIRECTING_FROM_NAME_CHAR_SET:
9406 if (ie_len != 1) {
9407 ast_log(LOG_WARNING3, "channel.c", 9407, __PRETTY_FUNCTION__, "Invalid redirecting-from name char set (%u)\n",
9408 (unsigned) ie_len);
9409 break;
9410 }
9411 redirecting->from.name.char_set = data[pos];
9412 break;
9413 case AST_REDIRECTING_FROM_NAME_PRESENTATION:
9414 if (ie_len != 1) {
9415 ast_log(LOG_WARNING3, "channel.c", 9415, __PRETTY_FUNCTION__, "Invalid redirecting-from name presentation (%u)\n",
9416 (unsigned) ie_len);
9417 break;
9418 }
9419 redirecting->from.name.presentation = data[pos];
9420 break;
9421 case AST_REDIRECTING_FROM_NAME_VALID:
9422 if (ie_len != 1) {
9423 ast_log(LOG_WARNING3, "channel.c", 9423, __PRETTY_FUNCTION__, "Invalid redirecting-from name valid (%u)\n",
9424 (unsigned) ie_len);
9425 break;
9426 }
9427 redirecting->from.name.valid = data[pos];
9428 break;
9429/* Redirecting-from party id number */
9430 case AST_REDIRECTING_FROM_NUMBER:
9431 ast_freefree(redirecting->from.number.str);
9432 redirecting->from.number.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9432, __PRETTY_FUNCTION__
)
;
9433 if (redirecting->from.number.str) {
9434 memcpy(redirecting->from.number.str, data + pos, ie_len);
9435 redirecting->from.number.str[ie_len] = 0;
9436 }
9437 break;
9438 case AST_REDIRECTING_FROM_NUMBER_PLAN:
9439 if (ie_len != 1) {
9440 ast_log(LOG_WARNING3, "channel.c", 9440, __PRETTY_FUNCTION__, "Invalid redirecting-from numbering plan (%u)\n",
9441 (unsigned) ie_len);
9442 break;
9443 }
9444 redirecting->from.number.plan = data[pos];
9445 break;
9446 case AST_REDIRECTING_FROM_NUMBER_PRESENTATION:
9447 if (ie_len != 1) {
9448 ast_log(LOG_WARNING3, "channel.c", 9448, __PRETTY_FUNCTION__, "Invalid redirecting-from number presentation (%u)\n",
9449 (unsigned) ie_len);
9450 break;
9451 }
9452 redirecting->from.number.presentation = data[pos];
9453 break;
9454 case AST_REDIRECTING_FROM_NUMBER_VALID:
9455 if (ie_len != 1) {
9456 ast_log(LOG_WARNING3, "channel.c", 9456, __PRETTY_FUNCTION__, "Invalid redirecting-from number valid (%u)\n",
9457 (unsigned) ie_len);
9458 break;
9459 }
9460 redirecting->from.number.valid = data[pos];
9461 break;
9462/* Redirecting-from party id combined presentation */
9463 case AST_REDIRECTING_FROM_ID_PRESENTATION:
9464 if (ie_len != 1) {
9465 ast_log(LOG_WARNING3, "channel.c", 9465, __PRETTY_FUNCTION__, "Invalid redirecting-from combined presentation (%u)\n",
9466 (unsigned) ie_len);
9467 break;
9468 }
9469 from_combined_presentation = data[pos];
9470 got_from_combined_presentation = 1;
9471 break;
9472/* Redirecting-from party id subaddress */
9473 case AST_REDIRECTING_FROM_SUBADDRESS:
9474 ast_freefree(redirecting->from.subaddress.str);
9475 redirecting->from.subaddress.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9475, __PRETTY_FUNCTION__
)
;
9476 if (redirecting->from.subaddress.str) {
9477 memcpy(redirecting->from.subaddress.str, data + pos, ie_len);
9478 redirecting->from.subaddress.str[ie_len] = 0;
9479 }
9480 break;
9481 case AST_REDIRECTING_FROM_SUBADDRESS_TYPE:
9482 if (ie_len != 1) {
9483 ast_log(LOG_WARNING3, "channel.c", 9483, __PRETTY_FUNCTION__, "Invalid redirecting-from type of subaddress (%u)\n",
9484 (unsigned) ie_len);
9485 break;
9486 }
9487 redirecting->from.subaddress.type = data[pos];
9488 break;
9489 case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN:
9490 if (ie_len != 1) {
9491 ast_log(LOG_WARNING3, "channel.c", 9491, __PRETTY_FUNCTION__,
9492 "Invalid redirecting-from subaddress odd-even indicator (%u)\n",
9493 (unsigned) ie_len);
9494 break;
9495 }
9496 redirecting->from.subaddress.odd_even_indicator = data[pos];
9497 break;
9498 case AST_REDIRECTING_FROM_SUBADDRESS_VALID:
9499 if (ie_len != 1) {
9500 ast_log(LOG_WARNING3, "channel.c", 9500, __PRETTY_FUNCTION__, "Invalid redirecting-from subaddress valid (%u)\n",
9501 (unsigned) ie_len);
9502 break;
9503 }
9504 redirecting->from.subaddress.valid = data[pos];
9505 break;
9506/* Redirecting-from party id tag */
9507 case AST_REDIRECTING_FROM_TAG:
9508 ast_freefree(redirecting->from.tag);
9509 redirecting->from.tag = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9509, __PRETTY_FUNCTION__
)
;
9510 if (redirecting->from.tag) {
9511 memcpy(redirecting->from.tag, data + pos, ie_len);
9512 redirecting->from.tag[ie_len] = 0;
9513 }
9514 break;
9515/* Redirecting-to party id name */
9516 case AST_REDIRECTING_TO_NAME:
9517 ast_freefree(redirecting->to.name.str);
9518 redirecting->to.name.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9518, __PRETTY_FUNCTION__
)
;
9519 if (redirecting->to.name.str) {
9520 memcpy(redirecting->to.name.str, data + pos, ie_len);
9521 redirecting->to.name.str[ie_len] = 0;
9522 }
9523 break;
9524 case AST_REDIRECTING_TO_NAME_CHAR_SET:
9525 if (ie_len != 1) {
9526 ast_log(LOG_WARNING3, "channel.c", 9526, __PRETTY_FUNCTION__, "Invalid redirecting-to name char set (%u)\n",
9527 (unsigned) ie_len);
9528 break;
9529 }
9530 redirecting->to.name.char_set = data[pos];
9531 break;
9532 case AST_REDIRECTING_TO_NAME_PRESENTATION:
9533 if (ie_len != 1) {
9534 ast_log(LOG_WARNING3, "channel.c", 9534, __PRETTY_FUNCTION__, "Invalid redirecting-to name presentation (%u)\n",
9535 (unsigned) ie_len);
9536 break;
9537 }
9538 redirecting->to.name.presentation = data[pos];
9539 break;
9540 case AST_REDIRECTING_TO_NAME_VALID:
9541 if (ie_len != 1) {
9542 ast_log(LOG_WARNING3, "channel.c", 9542, __PRETTY_FUNCTION__, "Invalid redirecting-to name valid (%u)\n",
9543 (unsigned) ie_len);
9544 break;
9545 }
9546 redirecting->to.name.valid = data[pos];
9547 break;
9548/* Redirecting-to party id number */
9549 case AST_REDIRECTING_TO_NUMBER:
9550 ast_freefree(redirecting->to.number.str);
9551 redirecting->to.number.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9551, __PRETTY_FUNCTION__
)
;
9552 if (redirecting->to.number.str) {
9553 memcpy(redirecting->to.number.str, data + pos, ie_len);
9554 redirecting->to.number.str[ie_len] = 0;
9555 }
9556 break;
9557 case AST_REDIRECTING_TO_NUMBER_PLAN:
9558 if (ie_len != 1) {
9559 ast_log(LOG_WARNING3, "channel.c", 9559, __PRETTY_FUNCTION__, "Invalid redirecting-to numbering plan (%u)\n",
9560 (unsigned) ie_len);
9561 break;
9562 }
9563 redirecting->to.number.plan = data[pos];
9564 break;
9565 case AST_REDIRECTING_TO_NUMBER_PRESENTATION:
9566 if (ie_len != 1) {
9567 ast_log(LOG_WARNING3, "channel.c", 9567, __PRETTY_FUNCTION__, "Invalid redirecting-to number presentation (%u)\n",
9568 (unsigned) ie_len);
9569 break;
9570 }
9571 redirecting->to.number.presentation = data[pos];
9572 break;
9573 case AST_REDIRECTING_TO_NUMBER_VALID:
9574 if (ie_len != 1) {
9575 ast_log(LOG_WARNING3, "channel.c", 9575, __PRETTY_FUNCTION__, "Invalid redirecting-to number valid (%u)\n",
9576 (unsigned) ie_len);
9577 break;
9578 }
9579 redirecting->to.number.valid = data[pos];
9580 break;
9581/* Redirecting-to party id combined presentation */
9582 case AST_REDIRECTING_TO_ID_PRESENTATION:
9583 if (ie_len != 1) {
9584 ast_log(LOG_WARNING3, "channel.c", 9584, __PRETTY_FUNCTION__, "Invalid redirecting-to combined presentation (%u)\n",
9585 (unsigned) ie_len);
9586 break;
9587 }
9588 to_combined_presentation = data[pos];
9589 got_to_combined_presentation = 1;
9590 break;
9591/* Redirecting-to party id subaddress */
9592 case AST_REDIRECTING_TO_SUBADDRESS:
9593 ast_freefree(redirecting->to.subaddress.str);
9594 redirecting->to.subaddress.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9594, __PRETTY_FUNCTION__
)
;
9595 if (redirecting->to.subaddress.str) {
9596 memcpy(redirecting->to.subaddress.str, data + pos, ie_len);
9597 redirecting->to.subaddress.str[ie_len] = 0;
9598 }
9599 break;
9600 case AST_REDIRECTING_TO_SUBADDRESS_TYPE:
9601 if (ie_len != 1) {
9602 ast_log(LOG_WARNING3, "channel.c", 9602, __PRETTY_FUNCTION__, "Invalid redirecting-to type of subaddress (%u)\n",
9603 (unsigned) ie_len);
9604 break;
9605 }
9606 redirecting->to.subaddress.type = data[pos];
9607 break;
9608 case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN:
9609 if (ie_len != 1) {
9610 ast_log(LOG_WARNING3, "channel.c", 9610, __PRETTY_FUNCTION__,
9611 "Invalid redirecting-to subaddress odd-even indicator (%u)\n",
9612 (unsigned) ie_len);
9613 break;
9614 }
9615 redirecting->to.subaddress.odd_even_indicator = data[pos];
9616 break;
9617 case AST_REDIRECTING_TO_SUBADDRESS_VALID:
9618 if (ie_len != 1) {
9619 ast_log(LOG_WARNING3, "channel.c", 9619, __PRETTY_FUNCTION__, "Invalid redirecting-to subaddress valid (%u)\n",
9620 (unsigned) ie_len);
9621 break;
9622 }
9623 redirecting->to.subaddress.valid = data[pos];
9624 break;
9625/* Redirecting-to party id tag */
9626 case AST_REDIRECTING_TO_TAG:
9627 ast_freefree(redirecting->to.tag);
9628 redirecting->to.tag = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9628, __PRETTY_FUNCTION__
)
;
9629 if (redirecting->to.tag) {
9630 memcpy(redirecting->to.tag, data + pos, ie_len);
9631 redirecting->to.tag[ie_len] = 0;
9632 }
9633 break;
9634/* Private redirecting-orig party id name */
9635 case AST_REDIRECTING_PRIV_ORIG_NAME:
9636 ast_freefree(redirecting->priv_orig.name.str);
9637 redirecting->priv_orig.name.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9637, __PRETTY_FUNCTION__
)
;
9638 if (redirecting->priv_orig.name.str) {
9639 memcpy(redirecting->priv_orig.name.str, data + pos, ie_len);
9640 redirecting->priv_orig.name.str[ie_len] = 0;
9641 }
9642 break;
9643 case AST_REDIRECTING_PRIV_ORIG_NAME_CHAR_SET:
9644 if (ie_len != 1) {
9645 ast_log(LOG_WARNING3, "channel.c", 9645, __PRETTY_FUNCTION__, "Invalid private redirecting-orig name char set (%u)\n",
9646 (unsigned) ie_len);
9647 break;
9648 }
9649 redirecting->priv_orig.name.char_set = data[pos];
9650 break;
9651 case AST_REDIRECTING_PRIV_ORIG_NAME_PRESENTATION:
9652 if (ie_len != 1) {
9653 ast_log(LOG_WARNING3, "channel.c", 9653, __PRETTY_FUNCTION__, "Invalid private redirecting-orig name presentation (%u)\n",
9654 (unsigned) ie_len);
9655 break;
9656 }
9657 redirecting->priv_orig.name.presentation = data[pos];
9658 break;
9659 case AST_REDIRECTING_PRIV_ORIG_NAME_VALID:
9660 if (ie_len != 1) {
9661 ast_log(LOG_WARNING3, "channel.c", 9661, __PRETTY_FUNCTION__, "Invalid private redirecting-orig name valid (%u)\n",
9662 (unsigned) ie_len);
9663 break;
9664 }
9665 redirecting->priv_orig.name.valid = data[pos];
9666 break;
9667/* Private redirecting-orig party id number */
9668 case AST_REDIRECTING_PRIV_ORIG_NUMBER:
9669 ast_freefree(redirecting->priv_orig.number.str);
9670 redirecting->priv_orig.number.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9670, __PRETTY_FUNCTION__
)
;
9671 if (redirecting->priv_orig.number.str) {
9672 memcpy(redirecting->priv_orig.number.str, data + pos, ie_len);
9673 redirecting->priv_orig.number.str[ie_len] = 0;
9674 }
9675 break;
9676 case AST_REDIRECTING_PRIV_ORIG_NUMBER_PLAN:
9677 if (ie_len != 1) {
9678 ast_log(LOG_WARNING3, "channel.c", 9678, __PRETTY_FUNCTION__, "Invalid private redirecting-orig numbering plan (%u)\n",
9679 (unsigned) ie_len);
9680 break;
9681 }
9682 redirecting->priv_orig.number.plan = data[pos];
9683 break;
9684 case AST_REDIRECTING_PRIV_ORIG_NUMBER_PRESENTATION:
9685 if (ie_len != 1) {
9686 ast_log(LOG_WARNING3, "channel.c", 9686, __PRETTY_FUNCTION__, "Invalid private redirecting-orig number presentation (%u)\n",
9687 (unsigned) ie_len);
9688 break;
9689 }
9690 redirecting->priv_orig.number.presentation = data[pos];
9691 break;
9692 case AST_REDIRECTING_PRIV_ORIG_NUMBER_VALID:
9693 if (ie_len != 1) {
9694 ast_log(LOG_WARNING3, "channel.c", 9694, __PRETTY_FUNCTION__, "Invalid private redirecting-orig number valid (%u)\n",
9695 (unsigned) ie_len);
9696 break;
9697 }
9698 redirecting->priv_orig.number.valid = data[pos];
9699 break;
9700/* Private redirecting-orig party id subaddress */
9701 case AST_REDIRECTING_PRIV_ORIG_SUBADDRESS:
9702 ast_freefree(redirecting->priv_orig.subaddress.str);
9703 redirecting->priv_orig.subaddress.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9703, __PRETTY_FUNCTION__
)
;
9704 if (redirecting->priv_orig.subaddress.str) {
9705 memcpy(redirecting->priv_orig.subaddress.str, data + pos, ie_len);
9706 redirecting->priv_orig.subaddress.str[ie_len] = 0;
9707 }
9708 break;
9709 case AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_TYPE:
9710 if (ie_len != 1) {
9711 ast_log(LOG_WARNING3, "channel.c", 9711, __PRETTY_FUNCTION__, "Invalid private redirecting-orig type of subaddress (%u)\n",
9712 (unsigned) ie_len);
9713 break;
9714 }
9715 redirecting->priv_orig.subaddress.type = data[pos];
9716 break;
9717 case AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_ODD_EVEN:
9718 if (ie_len != 1) {
9719 ast_log(LOG_WARNING3, "channel.c", 9719, __PRETTY_FUNCTION__,
9720 "Invalid private redirecting-orig subaddress odd-even indicator (%u)\n",
9721 (unsigned) ie_len);
9722 break;
9723 }
9724 redirecting->priv_orig.subaddress.odd_even_indicator = data[pos];
9725 break;
9726 case AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_VALID:
9727 if (ie_len != 1) {
9728 ast_log(LOG_WARNING3, "channel.c", 9728, __PRETTY_FUNCTION__, "Invalid private redirecting-orig subaddress valid (%u)\n",
9729 (unsigned) ie_len);
9730 break;
9731 }
9732 redirecting->priv_orig.subaddress.valid = data[pos];
9733 break;
9734/* Private redirecting-orig party id tag */
9735 case AST_REDIRECTING_PRIV_ORIG_TAG:
9736 ast_freefree(redirecting->priv_orig.tag);
9737 redirecting->priv_orig.tag = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9737, __PRETTY_FUNCTION__
)
;
9738 if (redirecting->priv_orig.tag) {
9739 memcpy(redirecting->priv_orig.tag, data + pos, ie_len);
9740 redirecting->priv_orig.tag[ie_len] = 0;
9741 }
9742 break;
9743/* Private redirecting-from party id name */
9744 case AST_REDIRECTING_PRIV_FROM_NAME:
9745 ast_freefree(redirecting->priv_from.name.str);
9746 redirecting->priv_from.name.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9746, __PRETTY_FUNCTION__
)
;
9747 if (redirecting->priv_from.name.str) {
9748 memcpy(redirecting->priv_from.name.str, data + pos, ie_len);
9749 redirecting->priv_from.name.str[ie_len] = 0;
9750 }
9751 break;
9752 case AST_REDIRECTING_PRIV_FROM_NAME_CHAR_SET:
9753 if (ie_len != 1) {
9754 ast_log(LOG_WARNING3, "channel.c", 9754, __PRETTY_FUNCTION__, "Invalid private redirecting-from name char set (%u)\n",
9755 (unsigned) ie_len);
9756 break;
9757 }
9758 redirecting->priv_from.name.char_set = data[pos];
9759 break;
9760 case AST_REDIRECTING_PRIV_FROM_NAME_PRESENTATION:
9761 if (ie_len != 1) {
9762 ast_log(LOG_WARNING3, "channel.c", 9762, __PRETTY_FUNCTION__, "Invalid private redirecting-from name presentation (%u)\n",
9763 (unsigned) ie_len);
9764 break;
9765 }
9766 redirecting->priv_from.name.presentation = data[pos];
9767 break;
9768 case AST_REDIRECTING_PRIV_FROM_NAME_VALID:
9769 if (ie_len != 1) {
9770 ast_log(LOG_WARNING3, "channel.c", 9770, __PRETTY_FUNCTION__, "Invalid private redirecting-from name valid (%u)\n",
9771 (unsigned) ie_len);
9772 break;
9773 }
9774 redirecting->priv_from.name.valid = data[pos];
9775 break;
9776/* Private redirecting-from party id number */
9777 case AST_REDIRECTING_PRIV_FROM_NUMBER:
9778 ast_freefree(redirecting->priv_from.number.str);
9779 redirecting->priv_from.number.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9779, __PRETTY_FUNCTION__
)
;
9780 if (redirecting->priv_from.number.str) {
9781 memcpy(redirecting->priv_from.number.str, data + pos, ie_len);
9782 redirecting->priv_from.number.str[ie_len] = 0;
9783 }
9784 break;
9785 case AST_REDIRECTING_PRIV_FROM_NUMBER_PLAN:
9786 if (ie_len != 1) {
9787 ast_log(LOG_WARNING3, "channel.c", 9787, __PRETTY_FUNCTION__, "Invalid private redirecting-from numbering plan (%u)\n",
9788 (unsigned) ie_len);
9789 break;
9790 }
9791 redirecting->priv_from.number.plan = data[pos];
9792 break;
9793 case AST_REDIRECTING_PRIV_FROM_NUMBER_PRESENTATION:
9794 if (ie_len != 1) {
9795 ast_log(LOG_WARNING3, "channel.c", 9795, __PRETTY_FUNCTION__, "Invalid private redirecting-from number presentation (%u)\n",
9796 (unsigned) ie_len);
9797 break;
9798 }
9799 redirecting->priv_from.number.presentation = data[pos];
9800 break;
9801 case AST_REDIRECTING_PRIV_FROM_NUMBER_VALID:
9802 if (ie_len != 1) {
9803 ast_log(LOG_WARNING3, "channel.c", 9803, __PRETTY_FUNCTION__, "Invalid private redirecting-from number valid (%u)\n",
9804 (unsigned) ie_len);
9805 break;
9806 }
9807 redirecting->priv_from.number.valid = data[pos];
9808 break;
9809/* Private redirecting-from party id subaddress */
9810 case AST_REDIRECTING_PRIV_FROM_SUBADDRESS:
9811 ast_freefree(redirecting->priv_from.subaddress.str);
9812 redirecting->priv_from.subaddress.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9812, __PRETTY_FUNCTION__
)
;
9813 if (redirecting->priv_from.subaddress.str) {
9814 memcpy(redirecting->priv_from.subaddress.str, data + pos, ie_len);
9815 redirecting->priv_from.subaddress.str[ie_len] = 0;
9816 }
9817 break;
9818 case AST_REDIRECTING_PRIV_FROM_SUBADDRESS_TYPE:
9819 if (ie_len != 1) {
9820 ast_log(LOG_WARNING3, "channel.c", 9820, __PRETTY_FUNCTION__, "Invalid private redirecting-from type of subaddress (%u)\n",
9821 (unsigned) ie_len);
9822 break;
9823 }
9824 redirecting->priv_from.subaddress.type = data[pos];
9825 break;
9826 case AST_REDIRECTING_PRIV_FROM_SUBADDRESS_ODD_EVEN:
9827 if (ie_len != 1) {
9828 ast_log(LOG_WARNING3, "channel.c", 9828, __PRETTY_FUNCTION__,
9829 "Invalid private redirecting-from subaddress odd-even indicator (%u)\n",
9830 (unsigned) ie_len);
9831 break;
9832 }
9833 redirecting->priv_from.subaddress.odd_even_indicator = data[pos];
9834 break;
9835 case AST_REDIRECTING_PRIV_FROM_SUBADDRESS_VALID:
9836 if (ie_len != 1) {
9837 ast_log(LOG_WARNING3, "channel.c", 9837, __PRETTY_FUNCTION__, "Invalid private redirecting-from subaddress valid (%u)\n",
9838 (unsigned) ie_len);
9839 break;
9840 }
9841 redirecting->priv_from.subaddress.valid = data[pos];
9842 break;
9843/* Private redirecting-from party id tag */
9844 case AST_REDIRECTING_PRIV_FROM_TAG:
9845 ast_freefree(redirecting->priv_from.tag);
9846 redirecting->priv_from.tag = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9846, __PRETTY_FUNCTION__
)
;
9847 if (redirecting->priv_from.tag) {
9848 memcpy(redirecting->priv_from.tag, data + pos, ie_len);
9849 redirecting->priv_from.tag[ie_len] = 0;
9850 }
9851 break;
9852/* Private redirecting-to party id name */
9853 case AST_REDIRECTING_PRIV_TO_NAME:
9854 ast_freefree(redirecting->priv_to.name.str);
9855 redirecting->priv_to.name.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9855, __PRETTY_FUNCTION__
)
;
9856 if (redirecting->priv_to.name.str) {
9857 memcpy(redirecting->priv_to.name.str, data + pos, ie_len);
9858 redirecting->priv_to.name.str[ie_len] = 0;
9859 }
9860 break;
9861 case AST_REDIRECTING_PRIV_TO_NAME_CHAR_SET:
9862 if (ie_len != 1) {
9863 ast_log(LOG_WARNING3, "channel.c", 9863, __PRETTY_FUNCTION__, "Invalid private redirecting-to name char set (%u)\n",
9864 (unsigned) ie_len);
9865 break;
9866 }
9867 redirecting->priv_to.name.char_set = data[pos];
9868 break;
9869 case AST_REDIRECTING_PRIV_TO_NAME_PRESENTATION:
9870 if (ie_len != 1) {
9871 ast_log(LOG_WARNING3, "channel.c", 9871, __PRETTY_FUNCTION__, "Invalid private redirecting-to name presentation (%u)\n",
9872 (unsigned) ie_len);
9873 break;
9874 }
9875 redirecting->priv_to.name.presentation = data[pos];
9876 break;
9877 case AST_REDIRECTING_PRIV_TO_NAME_VALID:
9878 if (ie_len != 1) {
9879 ast_log(LOG_WARNING3, "channel.c", 9879, __PRETTY_FUNCTION__, "Invalid private redirecting-to name valid (%u)\n",
9880 (unsigned) ie_len);
9881 break;
9882 }
9883 redirecting->priv_to.name.valid = data[pos];
9884 break;
9885/* Private redirecting-to party id number */
9886 case AST_REDIRECTING_PRIV_TO_NUMBER:
9887 ast_freefree(redirecting->priv_to.number.str);
9888 redirecting->priv_to.number.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9888, __PRETTY_FUNCTION__
)
;
9889 if (redirecting->priv_to.number.str) {
9890 memcpy(redirecting->priv_to.number.str, data + pos, ie_len);
9891 redirecting->priv_to.number.str[ie_len] = 0;
9892 }
9893 break;
9894 case AST_REDIRECTING_PRIV_TO_NUMBER_PLAN:
9895 if (ie_len != 1) {
9896 ast_log(LOG_WARNING3, "channel.c", 9896, __PRETTY_FUNCTION__, "Invalid private redirecting-to numbering plan (%u)\n",
9897 (unsigned) ie_len);
9898 break;
9899 }
9900 redirecting->priv_to.number.plan = data[pos];
9901 break;
9902 case AST_REDIRECTING_PRIV_TO_NUMBER_PRESENTATION:
9903 if (ie_len != 1) {
9904 ast_log(LOG_WARNING3, "channel.c", 9904, __PRETTY_FUNCTION__, "Invalid private redirecting-to number presentation (%u)\n",
9905 (unsigned) ie_len);
9906 break;
9907 }
9908 redirecting->priv_to.number.presentation = data[pos];
9909 break;
9910 case AST_REDIRECTING_PRIV_TO_NUMBER_VALID:
9911 if (ie_len != 1) {
9912 ast_log(LOG_WARNING3, "channel.c", 9912, __PRETTY_FUNCTION__, "Invalid private redirecting-to number valid (%u)\n",
9913 (unsigned) ie_len);
9914 break;
9915 }
9916 redirecting->priv_to.number.valid = data[pos];
9917 break;
9918/* Private redirecting-to party id subaddress */
9919 case AST_REDIRECTING_PRIV_TO_SUBADDRESS:
9920 ast_freefree(redirecting->priv_to.subaddress.str);
9921 redirecting->priv_to.subaddress.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9921, __PRETTY_FUNCTION__
)
;
9922 if (redirecting->priv_to.subaddress.str) {
9923 memcpy(redirecting->priv_to.subaddress.str, data + pos, ie_len);
9924 redirecting->priv_to.subaddress.str[ie_len] = 0;
9925 }
9926 break;
9927 case AST_REDIRECTING_PRIV_TO_SUBADDRESS_TYPE:
9928 if (ie_len != 1) {
9929 ast_log(LOG_WARNING3, "channel.c", 9929, __PRETTY_FUNCTION__, "Invalid private redirecting-to type of subaddress (%u)\n",
9930 (unsigned) ie_len);
9931 break;
9932 }
9933 redirecting->priv_to.subaddress.type = data[pos];
9934 break;
9935 case AST_REDIRECTING_PRIV_TO_SUBADDRESS_ODD_EVEN:
9936 if (ie_len != 1) {
9937 ast_log(LOG_WARNING3, "channel.c", 9937, __PRETTY_FUNCTION__,
9938 "Invalid private redirecting-to subaddress odd-even indicator (%u)\n",
9939 (unsigned) ie_len);
9940 break;
9941 }
9942 redirecting->priv_to.subaddress.odd_even_indicator = data[pos];
9943 break;
9944 case AST_REDIRECTING_PRIV_TO_SUBADDRESS_VALID:
9945 if (ie_len != 1) {
9946 ast_log(LOG_WARNING3, "channel.c", 9946, __PRETTY_FUNCTION__, "Invalid private redirecting-to subaddress valid (%u)\n",
9947 (unsigned) ie_len);
9948 break;
9949 }
9950 redirecting->priv_to.subaddress.valid = data[pos];
9951 break;
9952/* Private redirecting-to party id tag */
9953 case AST_REDIRECTING_PRIV_TO_TAG:
9954 ast_freefree(redirecting->priv_to.tag);
9955 redirecting->priv_to.tag = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9955, __PRETTY_FUNCTION__
)
;
9956 if (redirecting->priv_to.tag) {
9957 memcpy(redirecting->priv_to.tag, data + pos, ie_len);
9958 redirecting->priv_to.tag[ie_len] = 0;
9959 }
9960 break;
9961/* Redirecting reason code */
9962 case AST_REDIRECTING_REASON_CODE:
9963 if (ie_len != sizeof(value)) {
9964 ast_log(LOG_WARNING3, "channel.c", 9964, __PRETTY_FUNCTION__, "Invalid redirecting reason (%u)\n",
9965 (unsigned) ie_len);
9966 break;
9967 }
9968 memcpy(&value, data + pos, sizeof(value));
9969 redirecting->reason.code = ntohl(value)(__extension__ ({ unsigned int __v, __x = (value); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
9970 break;
9971/* Redirecting reason string */
9972 case AST_REDIRECTING_REASON_STR:
9973 ast_freefree(redirecting->reason.str);
9974 redirecting->reason.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9974, __PRETTY_FUNCTION__
)
;
9975 if (redirecting->reason.str) {
9976 memcpy(redirecting->reason.str, data + pos, ie_len);
9977 redirecting->reason.str[ie_len] = 0;
9978 }
9979 break;
9980/* Redirecting orig-reason code */
9981 case AST_REDIRECTING_ORIG_REASON_CODE:
9982 if (ie_len != sizeof(value)) {
9983 ast_log(LOG_WARNING3, "channel.c", 9983, __PRETTY_FUNCTION__, "Invalid redirecting original reason (%u)\n",
9984 (unsigned) ie_len);
9985 break;
9986 }
9987 memcpy(&value, data + pos, sizeof(value));
9988 redirecting->orig_reason.code = ntohl(value)(__extension__ ({ unsigned int __v, __x = (value); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
9989 break;
9990/* Redirecting orig-reason string */
9991 case AST_REDIRECTING_ORIG_REASON_STR:
9992 ast_freefree(redirecting->orig_reason.str);
9993 redirecting->orig_reason.str = ast_malloc(ie_len + 1)_ast_malloc((ie_len + 1), "channel.c", 9993, __PRETTY_FUNCTION__
)
;
9994 if (redirecting->orig_reason.str) {
9995 memcpy(redirecting->orig_reason.str, data + pos, ie_len);
9996 redirecting->orig_reason.str[ie_len] = 0;
9997 }
9998 break;
9999/* Redirecting count */
10000 case AST_REDIRECTING_COUNT:
10001 if (ie_len != sizeof(value)) {
10002 ast_log(LOG_WARNING3, "channel.c", 10002, __PRETTY_FUNCTION__, "Invalid redirecting count (%u)\n",
10003 (unsigned) ie_len);
10004 break;
10005 }
10006 memcpy(&value, data + pos, sizeof(value));
10007 redirecting->count = ntohl(value)(__extension__ ({ unsigned int __v, __x = (value); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
10008 break;
10009/* Redirecting unknown element */
10010 default:
10011 ast_debug(1, "Unknown redirecting element: %u (%u)\n",do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 10012, __PRETTY_FUNCTION__, "Unknown redirecting element: %u (%u)\n"
, (unsigned) ie_id, (unsigned) ie_len); } } while (0)
10012 (unsigned) ie_id, (unsigned) ie_len)do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 10012, __PRETTY_FUNCTION__, "Unknown redirecting element: %u (%u)\n"
, (unsigned) ie_id, (unsigned) ie_len); } } while (0)
;
10013 break;
10014 }
10015 }
10016
10017 switch (frame_version) {
10018 case 1:
10019 /*
10020 * The other end is an earlier version that we need to adjust
10021 * for compatibility.
10022 *
10023 * The earlier version did not have the orig party id or
10024 * orig_reason value.
10025 */
10026 redirecting->from.name.valid = 1;
10027 redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
10028 redirecting->from.number.valid = 1;
10029 if (got_from_combined_presentation) {
10030 redirecting->from.name.presentation = from_combined_presentation;
10031 redirecting->from.number.presentation = from_combined_presentation;
10032 }
10033
10034 redirecting->to.name.valid = 1;
10035 redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
10036 redirecting->to.number.valid = 1;
10037 if (got_to_combined_presentation) {
10038 redirecting->to.name.presentation = to_combined_presentation;
10039 redirecting->to.number.presentation = to_combined_presentation;
10040 }
10041 break;
10042 case 2:
10043 /* The other end is at the same level as we are. */
10044 break;
10045 default:
10046 /*
10047 * The other end is newer than we are.
10048 * We need to assume that they are compatible with us.
10049 */
10050 ast_debug(1, "Redirecting frame has newer version: %u\n",do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 10051, __PRETTY_FUNCTION__, "Redirecting frame has newer version: %u\n"
, (unsigned) frame_version); } } while (0)
10051 (unsigned) frame_version)do { if ((option_debug >= (1) || (({ typeof ((&ast_options
)->flags) __p = (&ast_options)->flags; typeof (__unsigned_int_flags_dummy
) __x = 0; (void) (&__p == &__x); ((&ast_options)
->flags & (AST_OPT_FLAG_DEBUG_MODULE)); }) && (
int)ast_debug_get_by_module("core") >= (1)))) { ast_log(0,
"channel.c", 10051, __PRETTY_FUNCTION__, "Redirecting frame has newer version: %u\n"
, (unsigned) frame_version); } } while (0)
;
10052 break;
10053 }
10054
10055 return 0;
10056}
10057
10058void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
10059{
10060 unsigned char data[1024]; /* This should be large enough */
10061 size_t datalen;
10062
10063 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
10064 if (datalen == (size_t) -1) {
10065 return;
10066 }
10067
10068 ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
10069}
10070
10071void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
10072{
10073 unsigned char data[1024]; /* This should be large enough */
10074 size_t datalen;
10075
10076 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
10077 if (datalen == (size_t) -1) {
10078 return;
10079 }
10080
10081 ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
10082}
10083
10084int 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)
10085{
10086 static int deprecation_warning = 0;
10087 const char *macro;
10088 const char *macro_args;
10089 int retval;
10090
10091 ast_channel_lock(macro_chan)__ao2_lock(macro_chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 10091, "macro_chan")
;
10092 macro = pbx_builtin_getvar_helper(macro_chan, is_caller
10093 ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO");
10094 macro = ast_strdupa(S_OR(macro, ""))(__extension__ ({ const char *__old = (({typeof(&((macro)
[0])) __x = (macro); _ast_strlen_zero(__x, "channel.c", __PRETTY_FUNCTION__
, 10094) ? ("") : __x;})); size_t __len = strlen(__old) + 1; char
*__new = __builtin_alloca(__len); memcpy (__new, __old, __len
); __new; }))
;
10095 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
10096 ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS");
10097 macro_args = ast_strdupa(S_OR(macro_args, ""))(__extension__ ({ const char *__old = (({typeof(&((macro_args
)[0])) __x = (macro_args); _ast_strlen_zero(__x, "channel.c",
__PRETTY_FUNCTION__, 10097) ? ("") : __x;})); size_t __len =
strlen(__old) + 1; char *__new = __builtin_alloca(__len); memcpy
(__new, __old, __len); __new; }))
;
10098
10099 if (ast_strlen_zero(macro)_ast_strlen_zero(macro, "channel.c", __PRETTY_FUNCTION__, 10099
)
) {
10100 ast_channel_unlock(macro_chan)__ao2_unlock(macro_chan, "channel.c", __PRETTY_FUNCTION__, 10100
, "macro_chan")
;
10101 return -1;
10102 }
10103
10104 if (!deprecation_warning) {
10105 deprecation_warning = 1;
10106 ast_log(LOG_WARNING3, "channel.c", 10106, __PRETTY_FUNCTION__, "Usage of CONNECTED_LINE_CALLE[ER]_SEND_MACRO is deprecated. Please use CONNECTED_LINE_SEND_SUB instead.\n");
10107 }
10108 if (is_frame) {
10109 const struct ast_frame *frame = connected_info;
10110
10111 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ast_channel_connected(macro_chan));
10112 } else {
10113 const struct ast_party_connected_line *connected = connected_info;
10114
10115 ast_party_connected_line_copy(ast_channel_connected(macro_chan), connected);
10116 }
10117 ast_channel_unlock(macro_chan)__ao2_unlock(macro_chan, "channel.c", __PRETTY_FUNCTION__, 10117
, "macro_chan")
;
10118
10119 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
10120 if (!retval) {
10121 struct ast_party_connected_line saved_connected;
10122
10123 ast_party_connected_line_init(&saved_connected);
10124 ast_channel_lock(macro_chan)__ao2_lock(macro_chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 10124, "macro_chan")
;
10125 ast_party_connected_line_copy(&saved_connected, ast_channel_connected(macro_chan));
10126 ast_channel_unlock(macro_chan)__ao2_unlock(macro_chan, "channel.c", __PRETTY_FUNCTION__, 10126
, "macro_chan")
;
10127 ast_channel_update_connected_line(macro_chan, &saved_connected, NULL((void*)0));
10128 ast_party_connected_line_free(&saved_connected);
10129 }
10130
10131 return retval;
10132}
10133
10134int ast_channel_redirecting_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *redirecting_info, int is_caller, int is_frame)
10135{
10136 static int deprecation_warning = 0;
10137 const char *macro;
10138 const char *macro_args;
10139 int retval;
10140
10141 ast_channel_lock(macro_chan)__ao2_lock(macro_chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 10141, "macro_chan")
;
10142 macro = pbx_builtin_getvar_helper(macro_chan, is_caller
10143 ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO");
10144 macro = ast_strdupa(S_OR(macro, ""))(__extension__ ({ const char *__old = (({typeof(&((macro)
[0])) __x = (macro); _ast_strlen_zero(__x, "channel.c", __PRETTY_FUNCTION__
, 10144) ? ("") : __x;})); size_t __len = strlen(__old) + 1; char
*__new = __builtin_alloca(__len); memcpy (__new, __old, __len
); __new; }))
;
10145 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
10146 ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS");
10147 macro_args = ast_strdupa(S_OR(macro_args, ""))(__extension__ ({ const char *__old = (({typeof(&((macro_args
)[0])) __x = (macro_args); _ast_strlen_zero(__x, "channel.c",
__PRETTY_FUNCTION__, 10147) ? ("") : __x;})); size_t __len =
strlen(__old) + 1; char *__new = __builtin_alloca(__len); memcpy
(__new, __old, __len); __new; }))
;
10148
10149 if (ast_strlen_zero(macro)_ast_strlen_zero(macro, "channel.c", __PRETTY_FUNCTION__, 10149
)
) {
10150 ast_channel_unlock(macro_chan)__ao2_unlock(macro_chan, "channel.c", __PRETTY_FUNCTION__, 10150
, "macro_chan")
;
10151 return -1;
10152 }
10153
10154 if (!deprecation_warning) {
10155 deprecation_warning = 1;
10156 ast_log(LOG_WARNING3, "channel.c", 10156, __PRETTY_FUNCTION__, "Usage of REDIRECTING_CALLE[ER]_SEND_MACRO is deprecated. Please use REDIRECTING_SEND_SUB instead.\n");
10157 }
10158 if (is_frame) {
10159 const struct ast_frame *frame = redirecting_info;
10160
10161 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ast_channel_redirecting(macro_chan));
10162 } else {
10163 const struct ast_party_redirecting *redirecting = redirecting_info;
10164
10165 ast_party_redirecting_copy(ast_channel_redirecting(macro_chan), redirecting);
10166 }
10167 ast_channel_unlock(macro_chan)__ao2_unlock(macro_chan, "channel.c", __PRETTY_FUNCTION__, 10167
, "macro_chan")
;
10168
10169 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
10170 if (!retval) {
10171 struct ast_party_redirecting saved_redirecting;
10172
10173 ast_party_redirecting_init(&saved_redirecting);
10174 ast_channel_lock(macro_chan)__ao2_lock(macro_chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 10174, "macro_chan")
;
10175 ast_party_redirecting_copy(&saved_redirecting, ast_channel_redirecting(macro_chan));
10176 ast_channel_unlock(macro_chan)__ao2_unlock(macro_chan, "channel.c", __PRETTY_FUNCTION__, 10176
, "macro_chan")
;
10177 ast_channel_update_redirecting(macro_chan, &saved_redirecting, NULL((void*)0));
10178 ast_party_redirecting_free(&saved_redirecting);
10179 }
10180
10181 return retval;
10182}
10183
10184int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int is_frame)
10185{
10186 const char *sub;
10187 const char *sub_args;
10188 int retval;
10189
10190 ast_channel_lock(sub_chan)__ao2_lock(sub_chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 10190, "sub_chan")
;
10191 sub = pbx_builtin_getvar_helper(sub_chan, "CONNECTED_LINE_SEND_SUB");
10192 sub = ast_strdupa(S_OR(sub, ""))(__extension__ ({ const char *__old = (({typeof(&((sub)[0
])) __x = (sub); _ast_strlen_zero(__x, "channel.c", __PRETTY_FUNCTION__
, 10192) ? ("") : __x;})); size_t __len = strlen(__old) + 1; char
*__new = __builtin_alloca(__len); memcpy (__new, __old, __len
); __new; }))
;
10193 sub_args = pbx_builtin_getvar_helper(sub_chan, "CONNECTED_LINE_SEND_SUB_ARGS");
10194 sub_args = ast_strdupa(S_OR(sub_args, ""))(__extension__ ({ const char *__old = (({typeof(&((sub_args
)[0])) __x = (sub_args); _ast_strlen_zero(__x, "channel.c", __PRETTY_FUNCTION__
, 10194) ? ("") : __x;})); size_t __len = strlen(__old) + 1; char
*__new = __builtin_alloca(__len); memcpy (__new, __old, __len
); __new; }))
;
10195
10196 if (ast_strlen_zero(sub)_ast_strlen_zero(sub, "channel.c", __PRETTY_FUNCTION__, 10196
)
) {
10197 ast_channel_unlock(sub_chan)__ao2_unlock(sub_chan, "channel.c", __PRETTY_FUNCTION__, 10197
, "sub_chan")
;
10198 return -1;
10199 }
10200
10201 if (is_frame) {
10202 const struct ast_frame *frame = connected_info;
10203
10204 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ast_channel_connected(sub_chan));
10205 } else {
10206 const struct ast_party_connected_line *connected = connected_info;
10207
10208 ast_party_connected_line_copy(ast_channel_connected(sub_chan), connected);
10209 }
10210 ast_channel_unlock(sub_chan)__ao2_unlock(sub_chan, "channel.c", __PRETTY_FUNCTION__, 10210
, "sub_chan")
;
10211
10212 retval = ast_app_run_sub(autoservice_chan, sub_chan, sub, sub_args, 0);
10213 if (!retval) {
10214 struct ast_party_connected_line saved_connected;
10215
10216 ast_party_connected_line_init(&saved_connected);
10217 ast_channel_lock(sub_chan)__ao2_lock(sub_chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 10217, "sub_chan")
;
10218 ast_party_connected_line_copy(&saved_connected, ast_channel_connected(sub_chan));
10219 ast_channel_unlock(sub_chan)__ao2_unlock(sub_chan, "channel.c", __PRETTY_FUNCTION__, 10219
, "sub_chan")
;
10220 ast_channel_update_connected_line(sub_chan, &saved_connected, NULL((void*)0));
10221 ast_party_connected_line_free(&saved_connected);
10222 }
10223
10224 return retval;
10225}
10226
10227int ast_channel_redirecting_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *redirecting_info, int is_frame)
10228{
10229 const char *sub;
10230 const char *sub_args;
10231 int retval;
10232
10233 ast_channel_lock(sub_chan)__ao2_lock(sub_chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 10233, "sub_chan")
;
10234 sub = pbx_builtin_getvar_helper(sub_chan, "REDIRECTING_SEND_SUB");
10235 sub = ast_strdupa(S_OR(sub, ""))(__extension__ ({ const char *__old = (({typeof(&((sub)[0
])) __x = (sub); _ast_strlen_zero(__x, "channel.c", __PRETTY_FUNCTION__
, 10235) ? ("") : __x;})); size_t __len = strlen(__old) + 1; char
*__new = __builtin_alloca(__len); memcpy (__new, __old, __len
); __new; }))
;
10236 sub_args = pbx_builtin_getvar_helper(sub_chan, "REDIRECTING_SEND_SUB_ARGS");
10237 sub_args = ast_strdupa(S_OR(sub_args, ""))(__extension__ ({ const char *__old = (({typeof(&((sub_args
)[0])) __x = (sub_args); _ast_strlen_zero(__x, "channel.c", __PRETTY_FUNCTION__
, 10237) ? ("") : __x;})); size_t __len = strlen(__old) + 1; char
*__new = __builtin_alloca(__len); memcpy (__new, __old, __len
); __new; }))
;
10238
10239 if (ast_strlen_zero(sub)_ast_strlen_zero(sub, "channel.c", __PRETTY_FUNCTION__, 10239
)
) {
10240 ast_channel_unlock(sub_chan)__ao2_unlock(sub_chan, "channel.c", __PRETTY_FUNCTION__, 10240
, "sub_chan")
;
10241 return -1;
10242 }
10243
10244 if (is_frame) {
10245 const struct ast_frame *frame = redirecting_info;
10246
10247 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ast_channel_redirecting(sub_chan));
10248 } else {
10249 const struct ast_party_redirecting *redirecting = redirecting_info;
10250
10251 ast_party_redirecting_copy(ast_channel_redirecting(sub_chan), redirecting);
10252 }
10253 ast_channel_unlock(sub_chan)__ao2_unlock(sub_chan, "channel.c", __PRETTY_FUNCTION__, 10253
, "sub_chan")
;
10254
10255 retval = ast_app_run_sub(autoservice_chan, sub_chan, sub, sub_args, 0);
10256 if (!retval) {
10257 struct ast_party_redirecting saved_redirecting;
10258
10259 ast_party_redirecting_init(&saved_redirecting);
10260 ast_channel_lock(sub_chan)__ao2_lock(sub_chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 10260, "sub_chan")
;
10261 ast_party_redirecting_copy(&saved_redirecting, ast_channel_redirecting(sub_chan));
10262 ast_channel_unlock(sub_chan)__ao2_unlock(sub_chan, "channel.c", __PRETTY_FUNCTION__, 10262
, "sub_chan")
;
10263 ast_channel_update_redirecting(sub_chan, &saved_redirecting, NULL((void*)0));
10264 ast_party_redirecting_free(&saved_redirecting);
10265 }
10266
10267 return retval;
10268}
10269
10270static void *channel_cc_params_copy(void *data)
10271{
10272 const struct ast_cc_config_params *src = data;
10273 struct ast_cc_config_params *dest = ast_cc_config_params_init()__ast_cc_config_params_init("channel.c", 10273, __PRETTY_FUNCTION__
)
;
10274 if (!dest) {
10275 return NULL((void*)0);
10276 }
10277 ast_cc_copy_config_params(dest, src);
10278 return dest;
10279}
10280
10281static void channel_cc_params_destroy(void *data)
10282{
10283 struct ast_cc_config_params *cc_params = data;
10284 ast_cc_config_params_destroy(cc_params);
10285}
10286
10287static const struct ast_datastore_info cc_channel_datastore_info = {
10288 .type = "Call Completion",
10289 .duplicate = channel_cc_params_copy,
10290 .destroy = channel_cc_params_destroy,
10291};
10292
10293int ast_channel_cc_params_init(struct ast_channel *chan,
10294 const struct ast_cc_config_params *base_params)
10295{
10296 struct ast_cc_config_params *cc_params;
10297 struct ast_datastore *cc_datastore;
10298
10299 if (!(cc_params = ast_cc_config_params_init()__ast_cc_config_params_init("channel.c", 10299, __PRETTY_FUNCTION__
)
)) {
10300 return -1;
10301 }
10302
10303 if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL)__ast_datastore_alloc(&cc_channel_datastore_info, ((void*
)0), "channel.c", 10303, __PRETTY_FUNCTION__)
)) {
10304 ast_cc_config_params_destroy(cc_params);
10305 return -1;
10306 }
10307
10308 if (base_params) {
10309 ast_cc_copy_config_params(cc_params, base_params);
10310 }
10311 cc_datastore->data = cc_params;
10312 ast_channel_datastore_add(chan, cc_datastore);
10313 return 0;
10314}
10315
10316struct ast_cc_config_params *ast_channel_get_cc_config_params(struct ast_channel *chan)
10317{
10318 struct ast_datastore *cc_datastore;
10319
10320 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL((void*)0)))) {
10321 /* If we can't find the datastore, it almost definitely means that the channel type being
10322 * used has not had its driver modified to parse CC config parameters. The best action
10323 * to take here is to create the parameters on the spot with the defaults set.
10324 */
10325 if (ast_channel_cc_params_init(chan, NULL((void*)0))) {
10326 return NULL((void*)0);
10327 }
10328 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL((void*)0)))) {
10329 /* Should be impossible */
10330 return NULL((void*)0);
10331 }
10332 }
10333
10334 ast_assert(cc_datastore->data != NULL)_ast_assert(cc_datastore->data != ((void*)0), "cc_datastore->data != NULL"
, "channel.c", 10334, __PRETTY_FUNCTION__)
;
10335 return cc_datastore->data;
10336}
10337
10338int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
10339{
10340 int len = name_buffer_length;
10341 char *dash;
10342 if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME16, device_name, &len, 0)) {
10343 return 0;
10344 }
10345
10346 /* Dang. Do it the old-fashioned way */
10347 ast_copy_string(device_name, ast_channel_name(chan), name_buffer_length);
10348 if ((dash = strrchr(device_name, '-'))) {
10349 *dash = '\0';
10350 }
10351
10352 return 0;
10353}
10354
10355int ast_channel_get_cc_agent_type(struct ast_channel *chan, char *agent_type, size_t size)
10356{
10357 int len = size;
10358 char *slash;
10359
10360 if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE17, agent_type, &len, 0)) {
10361 return 0;
10362 }
10363
10364 ast_copy_string(agent_type, ast_channel_name(chan), size);
10365 if ((slash = strchr(agent_type, '/')(__extension__ (__builtin_constant_p ('/') && !__builtin_constant_p
(agent_type) && ('/') == '\0' ? (char *) __rawmemchr
(agent_type, '/') : __builtin_strchr (agent_type, '/')))
)) {
10366 *slash = '\0';
10367 }
10368 return 0;
10369}
10370
10371void ast_channel_unlink(struct ast_channel *chan)
10372{
10373 ao2_unlink(channels, chan)__ao2_unlink((channels), (chan), 0, "", "channel.c", 10373, __PRETTY_FUNCTION__
)
;
10374}
10375
10376struct ast_bridge *ast_channel_get_bridge(const struct ast_channel *chan)
10377{
10378 struct ast_bridge *bridge;
10379
10380 bridge = ast_channel_internal_bridge(chan);
10381 if (bridge) {
10382 ao2_ref(bridge, +1)__ao2_ref((bridge), (+1), "", "channel.c", 10382, __PRETTY_FUNCTION__
)
;
10383 }
10384 return bridge;
10385}
10386
10387int ast_channel_is_bridged(const struct ast_channel *chan)
10388{
10389 return ast_channel_internal_bridge(chan) != NULL((void*)0);
10390}
10391
10392int ast_channel_is_leaving_bridge(struct ast_channel *chan)
10393{
10394 int hangup_flags = ast_channel_softhangup_internal_flag(chan);
10395 int hangup_test = hangup_flags & AST_SOFTHANGUP_ASYNCGOTO;
10396 int unbridge = ast_channel_unbridged(chan);
10397
10398 /* This function should only return true if either the unbridged flag or
10399 * the ASYNCGOTO soft hangup flag is set and when no other soft hangup
10400 * flags are set. Any other soft hangup flags being set should make it
10401 * return false.
10402 */
10403 return ((hangup_test || unbridge) && (hangup_test == hangup_flags));
10404}
10405
10406struct ast_channel *ast_channel_bridge_peer(struct ast_channel *chan)
10407{
10408 struct ast_channel *peer;
10409 struct ast_bridge *bridge;
10410
10411 /* Get the bridge the channel is in. */
10412 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 10412, "chan")
;
10413 bridge = ast_channel_get_bridge(chan);
10414 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 10414, "chan"
)
;
10415 if (!bridge) {
10416 return NULL((void*)0);
10417 }
10418
10419 peer = ast_bridge_peer(bridge, chan);
10420 ao2_ref(bridge, -1)__ao2_ref((bridge), (-1), "", "channel.c", 10420, __PRETTY_FUNCTION__
)
;
10421 return peer;
10422}
10423
10424struct ast_bridge_channel *ast_channel_get_bridge_channel(struct ast_channel *chan)
10425{
10426 struct ast_bridge_channel *bridge_channel;
10427
10428 bridge_channel = ast_channel_internal_bridge_channel(chan);
10429 if (bridge_channel) {
10430 ao2_ref(bridge_channel, +1)__ao2_ref((bridge_channel), (+1), "", "channel.c", 10430, __PRETTY_FUNCTION__
)
;
10431 }
10432 return bridge_channel;
10433}
10434
10435struct ast_channel *ast_channel_yank(struct ast_channel *yankee)
10436{
10437 struct ast_channel *yanked_chan;
10438 struct {
10439 char *accountcode;
10440 char *exten;
10441 char *context;
10442 char *name;
10443 int amaflags;
10444 struct ast_format *readformat;
10445 struct ast_format *writeformat;
10446 } my_vars = { 0, };
10447
10448 ast_channel_lock(yankee)__ao2_lock(yankee, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 10448, "yankee")
;
10449 my_vars.accountcode = ast_strdupa(ast_channel_accountcode(yankee))(__extension__ ({ const char *__old = (ast_channel_accountcode
(yankee)); size_t __len = strlen(__old) + 1; char *__new = __builtin_alloca
(__len); memcpy (__new, __old, __len); __new; }))
;
10450 my_vars.exten = ast_strdupa(ast_channel_exten(yankee))(__extension__ ({ const char *__old = (ast_channel_exten(yankee
)); size_t __len = strlen(__old) + 1; char *__new = __builtin_alloca
(__len); memcpy (__new, __old, __len); __new; }))
;
10451 my_vars.context = ast_strdupa(ast_channel_context(yankee))(__extension__ ({ const char *__old = (ast_channel_context(yankee
)); size_t __len = strlen(__old) + 1; char *__new = __builtin_alloca
(__len); memcpy (__new, __old, __len); __new; }))
;
10452 my_vars.name = ast_strdupa(ast_channel_name(yankee))(__extension__ ({ const char *__old = (ast_channel_name(yankee
)); size_t __len = strlen(__old) + 1; char *__new = __builtin_alloca
(__len); memcpy (__new, __old, __len); __new; }))
;
10453 my_vars.amaflags = ast_channel_amaflags(yankee);
10454 my_vars.writeformat = ao2_bump(ast_channel_writeformat(yankee))({ typeof((ast_channel_writeformat(yankee))) __obj___LINE__ =
((ast_channel_writeformat(yankee))); if (__obj___LINE__) { __ao2_ref
((__obj___LINE__), (+1), (("")), "channel.c", 10454, __PRETTY_FUNCTION__
); } __obj___LINE__; })
;
10455 my_vars.readformat = ao2_bump(ast_channel_readformat(yankee))({ typeof((ast_channel_readformat(yankee))) __obj___LINE__ = (
(ast_channel_readformat(yankee))); if (__obj___LINE__) { __ao2_ref
((__obj___LINE__), (+1), (("")), "channel.c", 10455, __PRETTY_FUNCTION__
); } __obj___LINE__; })
;
10456 ast_channel_unlock(yankee)__ao2_unlock(yankee, "channel.c", __PRETTY_FUNCTION__, 10456,
"yankee")
;
10457
10458 /* Do not hold any channel locks while calling channel_alloc() since the function
10459 * locks the channel container when linking the new channel in. */
10460 if (!(yanked_chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, my_vars.accountcode,__ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, my_vars.accountcode
, my_vars.exten, my_vars.context, ((void*)0), yankee, my_vars
.amaflags, ((void*)0), "channel.c", 10462, __FUNCTION__, "Surrogate/%s"
, my_vars.name)
10461 my_vars.exten, my_vars.context, NULL, yankee, my_vars.amaflags,__ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, my_vars.accountcode
, my_vars.exten, my_vars.context, ((void*)0), yankee, my_vars
.amaflags, ((void*)0), "channel.c", 10462, __FUNCTION__, "Surrogate/%s"
, my_vars.name)
10462 "Surrogate/%s", my_vars.name)__ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, my_vars.accountcode
, my_vars.exten, my_vars.context, ((void*)0), yankee, my_vars
.amaflags, ((void*)0), "channel.c", 10462, __FUNCTION__, "Surrogate/%s"
, my_vars.name)
)) {
10463 ao2_cleanup(my_vars.writeformat)__ao2_cleanup_debug((my_vars.writeformat), "", "channel.c", 10463
, __PRETTY_FUNCTION__)
;
10464 ao2_cleanup(my_vars.readformat)__ao2_cleanup_debug((my_vars.readformat), "", "channel.c", 10464
, __PRETTY_FUNCTION__)
;
10465 return NULL((void*)0);
10466 }
10467
10468 /* Make formats okay */
10469 ast_channel_set_readformat(yanked_chan, my_vars.readformat);
10470 ast_channel_set_writeformat(yanked_chan, my_vars.writeformat);
10471 ao2_cleanup(my_vars.readformat)__ao2_cleanup_debug((my_vars.readformat), "", "channel.c", 10471
, __PRETTY_FUNCTION__)
;
10472 ao2_cleanup(my_vars.writeformat)__ao2_cleanup_debug((my_vars.writeformat), "", "channel.c", 10472
, __PRETTY_FUNCTION__)
;
10473
10474 ast_channel_unlock(yanked_chan)__ao2_unlock(yanked_chan, "channel.c", __PRETTY_FUNCTION__, 10474
, "yanked_chan")
;
10475
10476 if (ast_channel_move(yanked_chan, yankee)) {
10477 ast_hangup(yanked_chan);
10478 return NULL((void*)0);
10479 }
10480
10481 return yanked_chan;
10482}
10483
10484/*!
10485 * Mutex that prevents multiple ast_channel_move() operations
10486 * from occurring simultaneously. This is necessary since the
10487 * involved channels have to be locked and unlocked throughout
10488 * the move operation.
10489 *
10490 * The most important data being protected are the masq and masqr
10491 * data on channels. We don't want them getting criss-crossed due
10492 * to multiple moves mucking with them.
10493 */
10494AST_MUTEX_DEFINE_STATIC(channel_move_lock)static ast_mutex_t channel_move_lock = { { { 0, 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP
, 0, 0, { 0, 0 } } }, ((void*)0), 1 }
;
10495
10496int ast_channel_move(struct ast_channel *dest, struct ast_channel *source)
10497{
10498 SCOPED_MUTEX(lock, &channel_move_lock)_raii_cleanup_block_t _raii_cleanup_lock __attribute__((cleanup
(_raii_cleanup_block),unused)) = ((void*)0); __attribute__((__blocks__
(byref))) typeof(((&channel_move_lock))) lock = ({__ast_pthread_mutex_lock
("channel.c", 10498, __PRETTY_FUNCTION__, "((&channel_move_lock))"
, ((&channel_move_lock))); ((&channel_move_lock)); })
; _raii_cleanup_lock = ^{ {(void)__ast_pthread_mutex_unlock("channel.c"
, 10498, __PRETTY_FUNCTION__, "lock", lock);} }
;
10499
10500 if (dest == source) {
10501 ast_log(LOG_WARNING3, "channel.c", 10501, __PRETTY_FUNCTION__, "Can't move channel '%s' into itself!\n",
10502 ast_channel_name(dest));
10503 return -1;
10504 }
10505
10506 ast_channel_lock_both(dest, source)do { __ao2_lock(dest, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 10506, "dest"); while (__ao2_trylock(source, AO2_LOCK_REQ_MUTEX
, "channel.c", __PRETTY_FUNCTION__, 10506, "source")) { __ao2_unlock
(dest, "channel.c", __PRETTY_FUNCTION__, 10506, "dest"); sched_yield
(); __ao2_lock(dest, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 10506, "dest"); } } while (0)
;
10507
10508 if (ast_test_flag(ast_channel_flags(dest), AST_FLAG_ZOMBIE)({ typeof ((ast_channel_flags(dest))->flags) __p = (ast_channel_flags
(dest))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(dest))->
flags & (AST_FLAG_ZOMBIE)); })
10509 || ast_test_flag(ast_channel_flags(source), AST_FLAG_ZOMBIE)({ typeof ((ast_channel_flags(source))->flags) __p = (ast_channel_flags
(source))->flags; typeof (__unsigned_int_flags_dummy) __x =
0; (void) (&__p == &__x); ((ast_channel_flags(source
))->flags & (AST_FLAG_ZOMBIE)); })
) {
10510 /* Zombies! Run! */
10511 ast_log(LOG_WARNING3, "channel.c", 10511, __PRETTY_FUNCTION__,
10512 "Can't move channel. One or both is dead (%s <-- %s)\n",
10513 ast_channel_name(dest), ast_channel_name(source));
10514 ast_channel_unlock(source)__ao2_unlock(source, "channel.c", __PRETTY_FUNCTION__, 10514,
"source")
;
10515 ast_channel_unlock(dest)__ao2_unlock(dest, "channel.c", __PRETTY_FUNCTION__, 10515, "dest"
)
;
10516 return -1;
10517 }
10518
10519 ast_channel_masq_set(dest, source);
10520 ast_channel_masqr_set(source, dest);
10521
10522 ast_channel_unlock(dest)__ao2_unlock(dest, "channel.c", __PRETTY_FUNCTION__, 10522, "dest"
)
;
10523 ast_channel_unlock(source)__ao2_unlock(source, "channel.c", __PRETTY_FUNCTION__, 10523,
"source")
;
10524
10525 channel_do_masquerade(dest, source);
10526 return 0;
10527}
10528
10529static void suppress_datastore_destroy_cb(void *data)
10530{
10531 ao2_cleanup(data)__ao2_cleanup_debug((data), "", "channel.c", 10531, __PRETTY_FUNCTION__
)
;
10532}
10533
10534static const struct ast_datastore_info suppress_datastore_voice = {
10535 .type = "suppressvoice",
10536 .destroy = suppress_datastore_destroy_cb
10537};
10538
10539static void suppress_framehook_destroy_cb(void *data)
10540{
10541 ao2_cleanup(data)__ao2_cleanup_debug((data), "", "channel.c", 10541, __PRETTY_FUNCTION__
)
;
10542}
10543
10544struct suppress_data {
10545 enum ast_frame_type frametype;
10546 unsigned int direction;
10547 int framehook_id;
10548};
10549
10550static void suppress_framehook_fixup_cb(void *data, int framehook_id, struct ast_channel *old_chan, struct ast_channel *new_chan)
10551{
10552 struct suppress_data *suppress = data;
10553
10554 suppress->framehook_id = framehook_id;
10555}
10556
10557static struct ast_frame *suppress_framehook_event_cb(struct ast_channel *chan, struct ast_frame *frame, enum ast_framehook_event event, void *data)
10558{
10559 struct suppress_data *suppress = data;
10560 int suppress_frame = 0;
10561
10562 if (!frame) {
10563 return NULL((void*)0);
10564 }
10565
10566 if (frame->frametype != suppress->frametype) {
10567 return frame;
10568 }
10569
10570 if (event == AST_FRAMEHOOK_EVENT_READ && (suppress->direction & AST_MUTE_DIRECTION_READ(1 << 0))) {
10571 suppress_frame = 1;
10572 } else if (event == AST_FRAMEHOOK_EVENT_WRITE && (suppress->direction & AST_MUTE_DIRECTION_WRITE(1 << 1))) {
10573 suppress_frame = 1;
10574 }
10575
10576 if (suppress_frame) {
10577 switch (frame->frametype) {
10578 case AST_FRAME_VOICE:
10579 frame = &ast_null_frame;
10580 break;
10581 default:
10582 break;
10583 }
10584 }
10585
10586 return frame;
10587}
10588
10589static const struct ast_datastore_info *suppress_get_datastore_information(enum ast_frame_type frametype)
10590{
10591 switch (frametype) {
10592 case AST_FRAME_VOICE:
10593 return &suppress_datastore_voice;
10594 default:
10595 return NULL((void*)0);
10596 }
10597}
10598
10599int ast_channel_suppress(struct ast_channel *chan, unsigned int direction, enum ast_frame_type frametype)
10600{
10601 RAII_VAR(struct suppress_data *, suppress, NULL, ao2_cleanup)_raii_cleanup_block_t _raii_cleanup_suppress __attribute__((cleanup
(_raii_cleanup_block),unused)) = ((void*)0); __attribute__((__blocks__
(byref))) struct suppress_data * suppress = ((void*)0); _raii_cleanup_suppress
= ^{ {(void)__ao2_cleanup_debug((suppress), "", "channel.c",
10601, __PRETTY_FUNCTION__);} }
;
10602 const struct ast_datastore_info *datastore_info = NULL((void*)0);
10603 struct ast_datastore *datastore = NULL((void*)0);
10604 struct ast_framehook_interface interface = {
10605 .version = AST_FRAMEHOOK_INTERFACE_VERSION4,
10606 .event_cb = suppress_framehook_event_cb,
10607 .destroy_cb = suppress_framehook_destroy_cb,
10608 .chan_fixup_cb = suppress_framehook_fixup_cb,
10609 };
10610 int framehook_id;
10611
10612 if (!(datastore_info = suppress_get_datastore_information(frametype))) {
10613 ast_log(LOG_WARNING3, "channel.c", 10613, __PRETTY_FUNCTION__, "Attempted to suppress an unsupported frame type (%u).\n", frametype);
10614 return -1;
10615 }
10616
10617 if ((datastore = ast_channel_datastore_find(chan, datastore_info, NULL((void*)0)))) {
10618 suppress = datastore->data;
10619 suppress->direction |= direction;
10620 return 0;
10621 }
10622
10623 if (!(suppress = ao2_alloc(sizeof(*suppress), NULL)__ao2_alloc((sizeof(*suppress)), (((void*)0)), AO2_ALLOC_OPT_LOCK_MUTEX
, "", "channel.c", 10623, __PRETTY_FUNCTION__)
)) {
10624 ast_log(LOG_WARNING3, "channel.c", 10624, __PRETTY_FUNCTION__, "Failed to allocate data while attempting to suppress a stream.\n");
10625 return -1;
10626 }
10627
10628 suppress->frametype = frametype;
10629 suppress->direction |= direction;
10630
10631 interface.data = suppress;
10632
10633 framehook_id = ast_framehook_attach(chan, &interface);
10634 if (framehook_id < 0) {
10635 /* Hook attach failed. Get rid of the evidence. */
10636 ast_log(LOG_WARNING3, "channel.c", 10636, __PRETTY_FUNCTION__, "Failed to attach framehook while attempting to suppress a stream.\n");
10637 return -1;
10638 }
10639
10640 /* One ref for the framehook */
10641 ao2_ref(suppress, +1)__ao2_ref((suppress), (+1), "", "channel.c", 10641, __PRETTY_FUNCTION__
)
;
10642
10643 suppress->framehook_id = framehook_id;
10644
10645 if (!(datastore = ast_datastore_alloc(datastore_info, NULL)__ast_datastore_alloc(datastore_info, ((void*)0), "channel.c"
, 10645, __PRETTY_FUNCTION__)
)) {
10646 ast_log(LOG_WARNING3, "channel.c", 10646, __PRETTY_FUNCTION__, "Failed to allocate datastore while attempting to suppress a stream.\n");
10647 ast_framehook_detach(chan, framehook_id);
10648 return -1;
10649 }
10650
10651 /* and another ref for the datastore */
10652 ao2_ref(suppress, +1)__ao2_ref((suppress), (+1), "", "channel.c", 10652, __PRETTY_FUNCTION__
)
;
10653 datastore->data = suppress;
10654
10655 ast_channel_datastore_add(chan, datastore);
10656
10657 return 0;
10658}
10659
10660int ast_channel_unsuppress(struct ast_channel *chan, unsigned int direction, enum ast_frame_type frametype)
10661{
10662 const struct ast_datastore_info *datastore_info = NULL((void*)0);
10663 struct ast_datastore *datastore = NULL((void*)0);
10664 struct suppress_data *suppress;
10665
10666 if (!(datastore_info = suppress_get_datastore_information(frametype))) {
10667 ast_log(LOG_WARNING3, "channel.c", 10667, __PRETTY_FUNCTION__, "Attempted to unsuppress an unsupported frame type (%u).\n", frametype);
10668 return -1;
10669 }
10670
10671 if (!(datastore = ast_channel_datastore_find(chan, datastore_info, NULL((void*)0)))) {
10672 /* Nothing to do! */
10673 return 0;
10674 }
10675
10676 suppress = datastore->data;
10677
10678 suppress->direction &= ~(direction);
10679
10680 if (suppress->direction == 0) {
10681 /* Nothing left to suppress. Bye! */
10682 ast_framehook_detach(chan, suppress->framehook_id);
10683 ast_channel_datastore_remove(chan, datastore);
10684 ast_datastore_free(datastore);
10685 }
10686
10687 return 0;
10688}
10689
10690void ast_channel_end_dtmf(struct ast_channel *chan, char digit, struct timeval start, const char *why)
10691{
10692 int dead;
10693 long duration;
10694
10695 ast_channel_lock(chan)__ao2_lock(chan, AO2_LOCK_REQ_MUTEX, "channel.c", __PRETTY_FUNCTION__
, 10695, "chan")
;
10696 dead = ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)({ typeof ((ast_channel_flags(chan))->flags) __p = (ast_channel_flags
(chan))->flags; typeof (__unsigned_int_flags_dummy) __x = 0
; (void) (&__p == &__x); ((ast_channel_flags(chan))->
flags & (AST_FLAG_ZOMBIE)); })
10697 || (ast_channel_softhangup_internal_flag(chan)
10698 & ~AST_SOFTHANGUP_ASYNCGOTO);
10699 ast_channel_unlock(chan)__ao2_unlock(chan, "channel.c", __PRETTY_FUNCTION__, 10699, "chan"
)
;
10700 if (dead) {
10701 /* Channel is a zombie or a real hangup. */
10702 return;
10703 }
10704
10705 duration = ast_tvdiff_ms(ast_tvnow(), start);
10706 if (duration < option_dtmfminduration) {
10707 duration = option_dtmfminduration;
10708 }
10709 ast_senddigit_end(chan, digit, duration);
10710 ast_log(LOG_DTMF6, "channel.c", 10710, __PRETTY_FUNCTION__, "DTMF end '%c' simulated on %s due to %s, duration %ld ms\n",
10711 digit, ast_channel_name(chan), why, duration);
10712}
10713
10714static void features_destroy(void *obj)
10715{
10716 ast_bridge_features_destroy(obj);
10717}
10718
10719static const struct ast_datastore_info bridge_features_info = {
10720 .type = "bridge-features",
10721 .destroy = features_destroy,
10722};
10723
10724struct ast_bridge_features *ast_channel_feature_hooks_get(struct ast_channel *chan)
10725{
10726 struct ast_datastore *datastore;
10727
10728 datastore = ast_channel_datastore_find(chan, &bridge_features_info, NULL((void*)0));
10729 if (!datastore) {
10730 return NULL((void*)0);
10731 }
10732 return datastore->data;
10733}
10734
10735static int channel_feature_hooks_set_full(struct ast_channel *chan, struct ast_bridge_features *features, int replace)
10736{
10737 struct ast_datastore *datastore;
10738 struct ast_bridge_features *ds_features;
10739
10740 datastore = ast_channel_datastore_find(chan, &bridge_features_info, NULL((void*)0));
10741 if (datastore) {
10742 ds_features = datastore->data;
10743 if (replace) {
10744 ast_bridge_features_cleanup(ds_features);
10745 ast_bridge_features_init(ds_features);
10746 }
10747 if (features) {
10748 ast_bridge_features_merge(ds_features, features);
10749 }
10750 return 0;
10751 }
10752
10753 datastore = ast_datastore_alloc(&bridge_features_info, NULL)__ast_datastore_alloc(&bridge_features_info, ((void*)0), "channel.c"
, 10753, __PRETTY_FUNCTION__)
;
10754 if (!datastore) {
10755 return -1;
10756 }
10757
10758 ds_features = ast_bridge_features_new();
10759 if (!ds_features) {
10760 ast_datastore_free(datastore);
10761 return -1;
10762 }
10763
10764 if (features) {
10765 ast_bridge_features_merge(ds_features, features);
10766 }
10767 datastore->data = ds_features;
10768 ast_channel_datastore_add(chan, datastore);
10769 return 0;
10770}
10771
10772int ast_channel_feature_hooks_append(struct ast_channel *chan, struct ast_bridge_features *features)
10773{
10774 return channel_feature_hooks_set_full(chan, features, 0);
10775}
10776
10777int ast_channel_feature_hooks_replace(struct ast_channel *chan, struct ast_bridge_features *features)
10778{
10779 return channel_feature_hooks_set_full(chan, features, 1);
10780}