Asterisk - The Open Source Telephony Project GIT-master-d5a0626
func_channel.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2006, Digium, Inc.
5 *
6 * See http://www.asterisk.org for more information about
7 * the Asterisk project. Please do not directly contact
8 * any of the maintainers of this project for assistance;
9 * the project provides a web site, mailing lists and IRC
10 * channels for your use.
11 *
12 * This program is free software, distributed under the terms of
13 * the GNU General Public License Version 2. See the LICENSE file
14 * at the top of the source tree.
15 */
16
17/*! \file
18 *
19 * \brief Channel info dialplan functions
20 *
21 * \author Kevin P. Fleming <kpfleming@digium.com>
22 * \author Ben Winslow
23 * \author Naveen Albert <asterisk@phreaknet.org>
24 *
25 * \ingroup functions
26 */
27
28/*** MODULEINFO
29 <support_level>core</support_level>
30 ***/
31
32#include "asterisk.h"
33
34#include <regex.h>
35#include <ctype.h>
36
37#include "asterisk/module.h"
38#include "asterisk/channel.h"
39#include "asterisk/bridge.h"
40#include "asterisk/pbx.h"
41#include "asterisk/utils.h"
42#include "asterisk/app.h"
49
50/*** DOCUMENTATION
51 <function name="CHANNELS" language="en_US">
52 <synopsis>
53 Gets the list of channels, optionally filtering by a regular expression.
54 </synopsis>
55 <syntax>
56 <parameter name="regular_expression" />
57 </syntax>
58 <description>
59 <para>Gets the list of channels, optionally filtering by a <replaceable>regular_expression</replaceable>. If
60 no argument is provided, all known channels are returned. The
61 <replaceable>regular_expression</replaceable> must correspond to
62 the POSIX.2 specification, as shown in <emphasis>regex(7)</emphasis>. The list returned
63 will be space-delimited.</para>
64 </description>
65 </function>
66 <function name="CHANNEL_EXISTS" language="en_US">
67 <since>
68 <version>16.22.0</version>
69 <version>18.8.0</version>
70 <version>19.0.0</version>
71 </since>
72 <synopsis>
73 Checks if the specified channel exists.
74 </synopsis>
75 <syntax>
76 <parameter name="name_or_uid" required="true">
77 <para>The name or unique ID of the channel to check.</para>
78 </parameter>
79 </syntax>
80 <description>
81 <para>Returns 1 if the channel <replaceable>name_or_uid</replaceable> exists, 0 if not.</para>
82 </description>
83 </function>
84 <function name="MASTER_CHANNEL" language="en_US">
85 <synopsis>
86 Gets or sets variables on the master channel
87 </synopsis>
88 <description>
89 <para>Allows access to the oldest channel associated with the current
90 channel if it still exists. If the channel is the master channel or
91 the master channel no longer exists then access local channel variables
92 instead. In other words, the master channel is the channel identified by
93 the channel's linkedid.</para>
94 </description>
95 </function>
96 <function name="CHANNEL" language="en_US">
97 <synopsis>
98 Gets/sets various pieces of information about the channel.
99 </synopsis>
100 <syntax>
101 <parameter name="item" required="true">
102 <para>Standard items (provided by all channel technologies) are:</para>
103 <enumlist>
104 <enum name="amaflags">
105 <para>R/W the Automatic Message Accounting (AMA) flags on the channel.
106 When read from a channel, the integer value will always be returned.
107 When written to a channel, both the string format or integer value
108 is accepted.</para>
109 <enumlist>
110 <enum name="1"><para><literal>OMIT</literal></para></enum>
111 <enum name="2"><para><literal>BILLING</literal></para></enum>
112 <enum name="3"><para><literal>DOCUMENTATION</literal></para></enum>
113 </enumlist>
114 </enum>
115 <enum name="accountcode">
116 <para>R/W the channel's account code.</para>
117 </enum>
118 <enum name="audioreadformat">
119 <para>R/O format currently being read.</para>
120 </enum>
121 <enum name="audionativeformat">
122 <para>R/O format used natively for audio.</para>
123 </enum>
124 <enum name="audiowriteformat">
125 <para>R/O format currently being written.</para>
126 </enum>
127 <enum name="dtmf_features">
128 <para>R/W The channel's DTMF bridge features.
129 May include one or more of 'T' 'K' 'H' 'W' and 'X' in a similar manner to options
130 in the <literal>Dial</literal> application. When setting it, the features string
131 must be all upper case.</para>
132 </enum>
133 <enum name="callgroup">
134 <para>R/W numeric call pickup groups that this channel is a member.</para>
135 </enum>
136 <enum name="pickupgroup">
137 <para>R/W numeric call pickup groups this channel can pickup.</para>
138 </enum>
139 <enum name="namedcallgroup">
140 <para>R/W named call pickup groups that this channel is a member.</para>
141 </enum>
142 <enum name="namedpickupgroup">
143 <para>R/W named call pickup groups this channel can pickup.</para>
144 </enum>
145 <enum name="channeltype">
146 <para>R/O technology used for channel.</para>
147 </enum>
148 <enum name="checkhangup">
149 <para>R/O Whether the channel is hanging up (1/0)</para>
150 </enum>
151 <enum name="digitdetect">
152 <para>R/W Enable or disable DTMF detection on channel drivers that support it.</para>
153 <para>If set on a DAHDI channel, this will only disable DTMF detection, not pulse dialing detection.
154 To disable pulse dialing, use the <literal>dialmode</literal> option.</para>
155 <para>On DAHDI channels, this will disable DSP if it is not needed for anything else.
156 This will prevent DTMF detection regardless of the <literal>dialmode</literal> setting.</para>
157 </enum>
158 <enum name="faxdetect">
159 <para>R/W Enable or disable fax detection on channel drivers that support it.</para>
160 </enum>
161 <enum name="after_bridge_goto">
162 <para>R/W the parseable goto string indicating where the channel is
163 expected to return to in the PBX after exiting the next bridge it joins
164 on the condition that it doesn't hang up. The parseable goto string uses
165 the same syntax as the <literal>Goto</literal> application.</para>
166 </enum>
167 <enum name="hangup_handler_pop">
168 <para>W/O Replace the most recently added hangup handler
169 with a new hangup handler on the channel if supplied. The
170 assigned string is passed to the Gosub application when
171 the channel is hung up. Any optionally omitted context
172 and exten are supplied by the channel pushing the handler
173 before it is pushed.</para>
174 </enum>
175 <enum name="hangup_handler_push">
176 <para>W/O Push a hangup handler onto the channel hangup
177 handler stack. The assigned string is passed to the
178 Gosub application when the channel is hung up. Any
179 optionally omitted context and exten are supplied by the
180 channel pushing the handler before it is pushed.</para>
181 </enum>
182 <enum name="hangup_handler_wipe">
183 <para>W/O Wipe the entire hangup handler stack and replace
184 with a new hangup handler on the channel if supplied. The
185 assigned string is passed to the Gosub application when
186 the channel is hung up. Any optionally omitted context
187 and exten are supplied by the channel pushing the handler
188 before it is pushed.</para>
189 </enum>
190 <enum name="onhold">
191 <para>R/O Whether or not the channel is onhold. (1/0)</para>
192 </enum>
193 <enum name="language">
194 <para>R/W language for sounds played.</para>
195 </enum>
196 <enum name="musicclass">
197 <para>R/W class (from musiconhold.conf) for hold music.</para>
198 </enum>
199 <enum name="name">
200 <para>The name of the channel</para>
201 </enum>
202 <enum name="parkinglot">
203 <para>R/W parkinglot for parking.</para>
204 </enum>
205 <enum name="relaxdtmf">
206 <para>W/O Enable or disable relaxed DTMF detection for channel drivers that support it,
207 overriding any setting previously defaulted by the channel driver.</para>
208 </enum>
209 <enum name="rxgain">
210 <para>R/W set rxgain level on channel drivers that support it.</para>
211 </enum>
212 <enum name="secure_bridge_signaling">
213 <para>Whether or not channels bridged to this channel require secure signaling (1/0)</para>
214 </enum>
215 <enum name="secure_bridge_media">
216 <para>Whether or not channels bridged to this channel require secure media (1/0)</para>
217 </enum>
218 <enum name="state">
219 <para>R/O state of the channel</para>
220 </enum>
221 <enum name="tdd">
222 <para>R/W Enable or disable TDD mode on channel drivers that support it.</para>
223 <para>When reading this option, 1 indicates TDD mode enabled, 0 indicates TDD mode disabled,
224 and <literal>mate</literal> indicates TDD mate mode.</para>
225 </enum>
226 <enum name="tonezone">
227 <para>R/W zone for indications played</para>
228 </enum>
229 <enum name="transfercapability">
230 <para>R/W ISDN Transfer Capability, one of:</para>
231 <enumlist>
232 <enum name="SPEECH" />
233 <enum name="DIGITAL" />
234 <enum name="RESTRICTED_DIGITAL" />
235 <enum name="3K1AUDIO" />
236 <enum name="DIGITAL_W_TONES" />
237 <enum name="VIDEO" />
238 </enumlist>
239 </enum>
240 <enum name="txgain">
241 <para>R/W set txgain level on channel drivers that support it.</para>
242 </enum>
243 <enum name="videonativeformat">
244 <para>R/O format used natively for video</para>
245 </enum>
246 <enum name="hangupsource">
247 <para>R/W returns the channel responsible for hangup.</para>
248 </enum>
249 <enum name="appname">
250 <para>R/O returns the internal application name.</para>
251 </enum>
252 <enum name="appdata">
253 <para>R/O returns the application data if available.</para>
254 </enum>
255 <enum name="exten">
256 <para>R/O returns the extension for an outbound channel.</para>
257 </enum>
258 <enum name="context">
259 <para>R/O returns the context for an outbound channel.</para>
260 </enum>
261 <enum name="lastexten">
262 <para>R/O returns the last unique extension for an outbound channel.</para>
263 </enum>
264 <enum name="lastcontext">
265 <para>R/O returns the last unique context for an outbound channel.</para>
266 </enum>
267 <enum name="channame">
268 <para>R/O returns the channel name for an outbound channel.</para>
269 </enum>
270 <enum name="uniqueid">
271 <para>R/O returns the channel uniqueid.</para>
272 </enum>
273 <enum name="linkedid">
274 <para>R/O returns the linkedid if available, otherwise returns the uniqueid.</para>
275 </enum>
276 <enum name="tenantid">
277 <para>R/W The channel tenantid.</para>
278 </enum>
279 <enum name="max_forwards">
280 <para>R/W The maximum number of forwards allowed.</para>
281 </enum>
282 <enum name="callid">
283 <para>R/O Call identifier log tag associated with the channel
284 e.g., <literal>[C-00000000]</literal>.</para>
285 </enum>
286 </enumlist>
287 <xi:include xpointer="xpointer(/docs/info[@name='CHANNEL'])" />
288 </parameter>
289 </syntax>
290 <description>
291 <para>Gets/sets various pieces of information about the channel, additional <replaceable>item</replaceable> may
292 be available from the channel driver; see its documentation for details. Any <replaceable>item</replaceable>
293 requested that is not available on the current channel will return an empty string.</para>
294 <example title="Standard CHANNEL item examples">
295 ; Push a hangup handler subroutine existing at dialplan
296 ; location default,s,1 onto the current channel
297 same => n,Set(CHANNEL(hangup_handler_push)=default,s,1)
298
299 ; Set the current tonezone to Germany (de)
300 same => n,Set(CHANNEL(tonezone)=de)
301
302 ; Set the allowed maximum number of forwarding attempts
303 same => n,Set(CHANNEL(max_forwards)=10)
304
305 ; If this channel is ejected from its next bridge, and if
306 ; the channel is not hung up, begin executing dialplan at
307 ; location default,after-bridge,1
308 same => n,Set(CHANNEL(after_bridge_goto)=default,after-bridge,1)
309
310 ; Log the current state of the channel
311 same => n,Log(NOTICE, This channel is: ${CHANNEL(state)})
312 </example>
313 <xi:include xpointer="xpointer(/docs/info[@name='CHANNEL_EXAMPLES'])" />
314 <para>The following channel variables are available as special built-in
315 dialplan channel variables. These variables cannot be set or modified
316 and are read-only.</para>
317 <variablelist>
318 <variable name="CALLINGPRES">
319 <para>Caller ID presentation for incoming calls (PRI channels)</para>
320 </variable>
321 <variable name="CALLINGANI2">
322 <para>Caller ANI2 (PRI channels)</para>
323 </variable>
324 <variable name="CALLINGTON">
325 <para>Caller Type of Number (PRI channels)</para>
326 </variable>
327 <variable name="CALLINGTNS">
328 <para>Transit Network Selector (PRI channels)</para>
329 </variable>
330 <variable name="EXTEN">
331 <para>Current extension</para>
332 </variable>
333 <variable name="CONTEXT">
334 <para>Current context</para>
335 </variable>
336 <variable name="PRIORITY">
337 <para>Current priority</para>
338 </variable>
339 <variable name="CHANNEL">
340 <para>Current channel name</para>
341 </variable>
342 <variable name="UNIQUEID">
343 <para>Current call unique identifier</para>
344 </variable>
345 <variable name="HANGUPCAUSE">
346 <para>Asterisk cause of hangup (inbound/outbound)</para>
347 </variable>
348 </variablelist>
349 </description>
350 </function>
351 ***/
352
353#define locked_copy_string(chan, dest, source, len) \
354 do { \
355 ast_channel_lock(chan); \
356 ast_copy_string(dest, source, len); \
357 ast_channel_unlock(chan); \
358 } while (0)
359#define locked_string_field_set(chan, field, source) \
360 do { \
361 ast_channel_lock(chan); \
362 ast_channel_##field##_set(chan, source); \
363 ast_channel_unlock(chan); \
364 } while (0)
365
366static const char * const transfercapability_table[0x20] = {
367 "SPEECH", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
368 "DIGITAL", "RESTRICTED_DIGITAL", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
369 "3K1AUDIO", "DIGITAL_W_TONES", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
370 "VIDEO", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", };
371
372static int func_channel_read(struct ast_channel *chan, const char *function,
373 char *data, char *buf, size_t len)
374{
375 int ret = 0;
376 struct ast_format_cap *tmpcap;
377
378 if (!chan) {
379 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
380 return -1;
381 }
382
383 if (!strcasecmp(data, "audionativeformat")) {
385 if (tmpcap) {
387
388 ast_channel_lock(chan);
390 ast_channel_unlock(chan);
391 ast_copy_string(buf, ast_format_cap_get_names(tmpcap, &codec_buf), len);
392 ao2_ref(tmpcap, -1);
393 }
394 } else if (!strcasecmp(data, "videonativeformat")) {
396 if (tmpcap) {
398
399 ast_channel_lock(chan);
401 ast_channel_unlock(chan);
402 ast_copy_string(buf, ast_format_cap_get_names(tmpcap, &codec_buf), len);
403 ao2_ref(tmpcap, -1);
404 }
405 } else if (!strcasecmp(data, "audioreadformat")) {
407 } else if (!strcasecmp(data, "audiowriteformat")) {
409 } else if (!strcasecmp(data, "tonezone") && ast_channel_zone(chan)) {
411 } else if (!strcasecmp(data, "dtmf_features")) {
413 buf[0] = '\0';
414 }
415 } else if (!strcasecmp(data, "language"))
417 else if (!strcasecmp(data, "musicclass"))
419 else if (!strcasecmp(data, "name")) {
421 } else if (!strcasecmp(data, "parkinglot"))
423 else if (!strcasecmp(data, "state"))
425 else if (!strcasecmp(data, "onhold")) {
427 ast_channel_hold_state(chan) == AST_CONTROL_HOLD ? "1" : "0", len);
428 } else if (!strcasecmp(data, "channeltype"))
430 else if (!strcasecmp(data, "accountcode"))
432 else if (!strcasecmp(data, "checkhangup")) {
433 locked_copy_string(chan, buf, ast_check_hangup(chan) ? "1" : "0", len);
434 } else if (!strcasecmp(data, "peeraccount"))
436 else if (!strcasecmp(data, "hangupsource"))
438 else if (!strcasecmp(data, "appname") && ast_channel_appl(chan))
440 else if (!strcasecmp(data, "appdata") && ast_channel_data(chan))
442 else if (!strcasecmp(data, "exten"))
444 else if (!strcasecmp(data, "context"))
446 else if (!strcasecmp(data, "lastexten"))
448 else if (!strcasecmp(data, "lastcontext"))
450 else if (!strcasecmp(data, "userfield"))
452 else if (!strcasecmp(data, "channame"))
454 else if (!strcasecmp(data, "linkedid")) {
455 ast_channel_lock(chan);
457 /* fall back on the channel's uniqueid if linkedid is unset */
459 }
460 else {
462 }
463 ast_channel_unlock(chan);
464 } else if (!strcasecmp(data, "peer")) {
465 struct ast_channel *peer;
466
467 peer = ast_channel_bridge_peer(chan);
468 if (peer) {
469 /* Only real channels could have a bridge peer this way. */
470 ast_channel_lock(peer);
472 ast_channel_unlock(peer);
473 ast_channel_unref(peer);
474 } else {
475 buf[0] = '\0';
476 ast_channel_lock(chan);
477 if (!ast_channel_tech(chan)) {
478 const char *pname;
479
480 /*
481 * A dummy channel can still pass along bridged peer info
482 * via the BRIDGEPEER variable.
483 *
484 * A horrible kludge, but... how else?
485 */
486 pname = pbx_builtin_getvar_helper(chan, "BRIDGEPEER");
487 if (!ast_strlen_zero(pname)) {
488 ast_copy_string(buf, pname, len);
489 }
490 }
491 ast_channel_unlock(chan);
492 }
493 } else if (!strcasecmp(data, "uniqueid")) {
495 } else if (!strcasecmp(data, "transfercapability")) {
497 } else if (!strcasecmp(data, "callgroup")) {
498 char groupbuf[256];
499
500 locked_copy_string(chan, buf, ast_print_group(groupbuf, sizeof(groupbuf), ast_channel_callgroup(chan)), len);
501 } else if (!strcasecmp(data, "pickupgroup")) {
502 char groupbuf[256];
503
504 locked_copy_string(chan, buf, ast_print_group(groupbuf, sizeof(groupbuf), ast_channel_pickupgroup(chan)), len);
505 } else if (!strcasecmp(data, "namedcallgroup")) {
506 struct ast_str *tmp_str = ast_str_alloca(1024);
507
509 } else if (!strcasecmp(data, "namedpickupgroup")) {
510 struct ast_str *tmp_str = ast_str_alloca(1024);
511
513 } else if (!strcasecmp(data, "after_bridge_goto")) {
515 } else if (!strcasecmp(data, "amaflags")) {
516 ast_channel_lock(chan);
517 snprintf(buf, len, "%u", ast_channel_amaflags(chan));
518 ast_channel_unlock(chan);
519 } else if (!strncasecmp(data, "secure_bridge_", 14)) {
520 struct ast_datastore *ds;
521
522 buf[0] = '\0';
523 ast_channel_lock(chan);
525 struct ast_secure_call_store *encrypt = ds->data;
526
527 if (!strcasecmp(data, "secure_bridge_signaling")) {
528 snprintf(buf, len, "%s", encrypt->signaling ? "1" : "");
529 } else if (!strcasecmp(data, "secure_bridge_media")) {
530 snprintf(buf, len, "%s", encrypt->media ? "1" : "");
531 }
532 }
533 ast_channel_unlock(chan);
534 } else if (!strcasecmp(data, "max_forwards")) {
535 ast_channel_lock(chan);
536 snprintf(buf, len, "%d", ast_max_forwards_get(chan));
537 ast_channel_unlock(chan);
538 } else if (!strcasecmp(data, "callid")) {
539 ast_callid callid;
540
541 buf[0] = '\0';
542 ast_channel_lock(chan);
543 callid = ast_channel_callid(chan);
544 if (callid) {
545 ast_callid_strnprint(buf, len, callid);
546 }
547 ast_channel_unlock(chan);
548 } else if (!strcasecmp(data, "tdd")) {
549 char status;
550 int status_size = (int) sizeof(status);
551 ret = ast_channel_queryoption(chan, AST_OPTION_TDD, &status, &status_size, 0);
552 if (!ret) {
553 ast_copy_string(buf, status == 2 ? "mate" : status ? "1" : "0", len);
554 }
555 } else if (!strcasecmp(data, "digitdetect")) {
556 char status;
557 int status_size = (int) sizeof(status);
558 ret = ast_channel_queryoption(chan, AST_OPTION_DIGIT_DETECT, &status, &status_size, 0);
559 if (!ret) {
560 ast_copy_string(buf, status ? "1" : "0", len);
561 }
562 } else if (!strcasecmp(data, "faxdetect")) {
563 char status;
564 int status_size = (int) sizeof(status);
565 ret = ast_channel_queryoption(chan, AST_OPTION_FAX_DETECT, &status, &status_size, 0);
566 if (!ret) {
567 ast_copy_string(buf, status ? "1" : "0", len);
568 }
569 } else if (!strcasecmp(data, "device_name")) {
570 ret = ast_channel_get_device_name(chan, buf, len);
571 } else if (!strcasecmp(data, "tenantid")) {
573 } else if (!ast_channel_tech(chan) || !ast_channel_tech(chan)->func_channel_read || ast_channel_tech(chan)->func_channel_read(chan, function, data, buf, len)) {
574 ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n", data);
575 ret = -1;
576 }
577
578 return ret;
579}
580
581static int func_channel_write_real(struct ast_channel *chan, const char *function,
582 char *data, const char *value)
583{
584 int ret = 0;
585 signed char gainset;
586
587 if (!strcasecmp(data, "language"))
589 else if (!strcasecmp(data, "parkinglot"))
590 locked_string_field_set(chan, parkinglot, value);
591 else if (!strcasecmp(data, "musicclass"))
592 locked_string_field_set(chan, musicclass, value);
593 else if (!strcasecmp(data, "accountcode"))
595 else if (!strcasecmp(data, "userfield"))
596 locked_string_field_set(chan, userfield, value);
597 else if (!strcasecmp(data, "after_bridge_goto")) {
598 if (ast_strlen_zero(value)) {
600 } else {
602 }
603 } else if (!strcasecmp(data, "amaflags")) {
604 int amaflags;
605
606 if (isdigit(*value)) {
607 if (sscanf(value, "%30d", &amaflags) != 1) {
609 }
610 } else {
612 }
613 ast_channel_lock(chan);
615 ast_channel_unlock(chan);
616 } else if (!strcasecmp(data, "peeraccount"))
617 locked_string_field_set(chan, peeraccount, value);
618 else if (!strcasecmp(data, "hangupsource"))
619 /* XXX - should we be forcing this here? */
620 ast_set_hangupsource(chan, value, 0);
621 else if (!strcasecmp(data, "tonezone")) {
622 struct ast_tone_zone *new_zone;
623 if (!(new_zone = ast_get_indication_zone(value))) {
624 ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", value);
625 ret = -1;
626 } else {
627 ast_channel_lock(chan);
628 if (ast_channel_zone(chan)) {
630 }
632 ast_channel_unlock(chan);
633 new_zone = ast_tone_zone_unref(new_zone);
634 }
635 } else if (!strcasecmp(data, "dtmf_features")) {
637 } else if (!strcasecmp(data, "callgroup")) {
638 ast_channel_lock(chan);
640 ast_channel_unlock(chan);
641 } else if (!strcasecmp(data, "pickupgroup")) {
642 ast_channel_lock(chan);
644 ast_channel_unlock(chan);
645 } else if (!strcasecmp(data, "namedcallgroup")) {
646 struct ast_namedgroups *groups = ast_get_namedgroups(value);
647
648 ast_channel_lock(chan);
650 ast_channel_unlock(chan);
652 } else if (!strcasecmp(data, "namedpickupgroup")) {
653 struct ast_namedgroups *groups = ast_get_namedgroups(value);
654
655 ast_channel_lock(chan);
657 ast_channel_unlock(chan);
659 } else if (!strcasecmp(data, "tdd")) {
660 char enabled;
661 if (!strcasecmp(value, "mate")) {
662 enabled = 2;
663 } else {
664 enabled = ast_true(value) ? 1 : 0;
665 }
667 } else if (!strcasecmp(data, "relaxdtmf")) {
668 char enabled = ast_true(value) ? 1 : 0;
670 } else if (!strcasecmp(data, "txgain")) {
671 sscanf(value, "%4hhd", &gainset);
672 ast_channel_setoption(chan, AST_OPTION_TXGAIN, &gainset, sizeof(gainset), 0);
673 } else if (!strcasecmp(data, "rxgain")) {
674 sscanf(value, "%4hhd", &gainset);
675 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &gainset, sizeof(gainset), 0);
676 } else if (!strcasecmp(data, "digitdetect")) {
677 char enabled = ast_true(value) ? 1 : 0;
679 } else if (!strcasecmp(data, "faxdetect")) {
680 char enabled = ast_true(value) ? 1 : 0;
682 } else if (!strcasecmp(data, "transfercapability")) {
683 unsigned short i;
684
685 ast_channel_lock(chan);
686 for (i = 0; i < 0x20; i++) {
687 if (!strcasecmp(transfercapability_table[i], value) && strcmp(value, "UNK")) {
689 break;
690 }
691 }
692 ast_channel_unlock(chan);
693 } else if (!strcasecmp(data, "hangup_handler_pop")) {
694 /* Pop one hangup handler before pushing the new handler. */
697 } else if (!strcasecmp(data, "hangup_handler_push")) {
699 } else if (!strcasecmp(data, "hangup_handler_wipe")) {
700 /* Pop all hangup handlers before pushing the new handler. */
701 while (ast_pbx_hangup_handler_pop(chan)) {
702 }
704 } else if (!strncasecmp(data, "secure_bridge_", 14)) {
705 struct ast_datastore *ds;
706 struct ast_secure_call_store *store;
707
708 if (!chan || !value) {
709 return -1;
710 }
711
712 ast_channel_lock(chan);
713 if (!(ds = ast_channel_datastore_find(chan, &secure_call_info, NULL))) {
715 ast_channel_unlock(chan);
716 return -1;
717 }
718 if (!(store = ast_calloc(1, sizeof(*store)))) {
719 ast_channel_unlock(chan);
720 ast_free(ds);
721 return -1;
722 }
723 ds->data = store;
725 } else {
726 store = ds->data;
727 }
728
729 if (!strcasecmp(data, "secure_bridge_signaling")) {
730 store->signaling = ast_true(value) ? 1 : 0;
731 } else if (!strcasecmp(data, "secure_bridge_media")) {
732 store->media = ast_true(value) ? 1 : 0;
733 }
734 ast_channel_unlock(chan);
735 } else if (!strcasecmp(data, "max_forwards")) {
736 int max_forwards;
737 if (sscanf(value, "%d", &max_forwards) != 1) {
738 ast_log(LOG_WARNING, "Unable to set max forwards to '%s'\n", value);
739 ret = -1;
740 } else {
741 ast_channel_lock(chan);
743 ast_channel_unlock(chan);
744 }
745 } else if (!strcasecmp(data, "tenantid")) {
747 } else if (!ast_channel_tech(chan)->func_channel_write
748 || ast_channel_tech(chan)->func_channel_write(chan, function, data, value)) {
749 ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n",
750 data);
751 ret = -1;
752 }
753
754 return ret;
755}
756
757static int func_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value)
758{
759 int res;
760 ast_chan_write_info_t write_info = {
762 .write_fn = func_channel_write_real,
763 .chan = chan,
764 .function = function,
765 .data = data,
766 .value = value,
767 };
768
769 if (!chan) {
770 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
771 return -1;
772 }
773
774 res = func_channel_write_real(chan, function, data, value);
775 ast_channel_setoption(chan, AST_OPTION_CHANNEL_WRITE, &write_info, sizeof(write_info), 0);
776
777 return res;
778}
779
781 .name = "CHANNEL",
782 .read = func_channel_read,
783 .write = func_channel_write,
784};
785
786static int func_channels_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
787{
788 struct ast_channel *c = NULL;
789 regex_t re;
790 int res;
791 size_t buflen = 0;
792 struct ast_channel_iterator *iter;
793
794 buf[0] = '\0';
795
796 if (!ast_strlen_zero(data)) {
797 if ((res = regcomp(&re, data, REG_EXTENDED | REG_ICASE | REG_NOSUB))) {
798 regerror(res, &re, buf, maxlen);
799 ast_log(LOG_WARNING, "Error compiling regular expression for %s(%s): %s\n", function, data, buf);
800 return -1;
801 }
802 }
803
804 if (!(iter = ast_channel_iterator_all_new())) {
805 if (!ast_strlen_zero(data)) {
806 regfree(&re);
807 }
808 return -1;
809 }
810
811 while ((c = ast_channel_iterator_next(iter))) {
813 if (ast_strlen_zero(data) || regexec(&re, ast_channel_name(c), 0, NULL, 0) == 0) {
814 size_t namelen = strlen(ast_channel_name(c));
815 if (buflen + namelen + (ast_strlen_zero(buf) ? 0 : 1) + 1 < maxlen) {
816 if (!ast_strlen_zero(buf)) {
817 strcat(buf, " ");
818 buflen++;
819 }
820 strcat(buf, ast_channel_name(c));
821 buflen += namelen;
822 } else {
823 ast_log(LOG_WARNING, "Number of channels exceeds the available buffer space. Output will be truncated!\n");
824 }
825 }
828 }
829
831
832 if (!ast_strlen_zero(data)) {
833 regfree(&re);
834 }
835
836 return 0;
837}
838
840 .name = "CHANNELS",
841 .read = func_channels_read,
842};
843
844static int func_chan_exists_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
845{
846 struct ast_channel *chan_found = NULL;
847
848 if (ast_strlen_zero(data)) {
849 ast_log(LOG_WARNING, "%s: Channel name or unique ID required\n", function);
850 return -1;
851 }
852
853 chan_found = ast_channel_get_by_name(data);
854 snprintf(buf, maxlen, "%d", (chan_found ? 1 : 0));
855 if (chan_found) {
856 ast_channel_unref(chan_found);
857 }
858 return 0;
859}
860
862 .name = "CHANNEL_EXISTS",
863 .read = func_chan_exists_read,
864};
865
866static int func_mchan_read(struct ast_channel *chan, const char *function,
867 char *data, struct ast_str **buf, ssize_t len)
868{
869 struct ast_channel *mchan;
870 char *template = ast_alloca(4 + strlen(data));
871
872 if (!chan) {
873 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
874 return -1;
875 }
876
878 sprintf(template, "${%s}", data); /* SAFE */
879 ast_str_substitute_variables(buf, len, mchan ? mchan : chan, template);
880 if (mchan) {
881 ast_channel_unref(mchan);
882 }
883 return 0;
884}
885
886static int func_mchan_write(struct ast_channel *chan, const char *function,
887 char *data, const char *value)
888{
889 struct ast_channel *mchan;
890
891 if (!chan) {
892 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
893 return -1;
894 }
895
897 pbx_builtin_setvar_helper(mchan ? mchan : chan, data, value);
898 if (mchan) {
899 ast_channel_unref(mchan);
900 }
901 return 0;
902}
903
905 .name = "MASTER_CHANNEL",
906 .read2 = func_mchan_read,
907 .write = func_mchan_write,
908};
909
910static int unload_module(void)
911{
912 int res = 0;
913
918
919 return res;
920}
921
922static int load_module(void)
923{
924 int res = 0;
925
930
931 return res;
932}
933
934AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Channel information dialplan functions");
jack_status_t status
Definition: app_jack.c:146
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
#define ast_free(a)
Definition: astmm.h:180
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
Bridging API.
After Bridge Execution API.
void ast_bridge_discard_after_goto(struct ast_channel *chan)
Discard channel after bridge goto location.
Definition: bridge_after.c:384
void ast_bridge_read_after_goto(struct ast_channel *chan, char *buffer, size_t buf_size)
Read after bridge goto if it exists.
Definition: bridge_after.c:394
void ast_bridge_set_after_go_on(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *parseable_goto)
Set channel to go on in the dialplan after the bridge.
Definition: bridge_after.c:622
Basic bridge subclass API.
int ast_bridge_features_ds_get_string(struct ast_channel *chan, char *buffer, size_t buf_size)
writes a channel's DTMF features to a buffer string
Definition: bridge_basic.c:208
int ast_bridge_features_ds_set_string(struct ast_channel *chan, const char *features)
Sets the features a channel will use upon being bridged.
Definition: bridge_basic.c:189
static int amaflags
Definition: chan_iax2.c:476
static char language[MAX_LANGUAGE]
Definition: chan_iax2.c:324
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:473
static const char type[]
Definition: chan_ooh323.c:109
General Asterisk PBX channel definitions.
const char * ast_channel_linkedid(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)
char * ast_print_namedgroups(struct ast_str **buf, struct ast_namedgroups *groups)
Print named call groups and named pickup groups.
Definition: channel.c:8078
void ast_channel_named_pickupgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
Get a device name given its channel structure.
Definition: channel.c:10518
struct ast_namedgroups * ast_channel_named_pickupgroups(const struct ast_channel *chan)
const char * ast_channel_data(const struct ast_channel *chan)
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2404
void ast_channel_tenantid_set(struct ast_channel *chan, const char *value)
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Definition: channel.c:1379
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
Definition: channel.c:10586
const char * ast_channel_tenantid(const struct ast_channel *chan)
const char * ast_channel_musicclass(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2968
const char * ast_channel_lastexten(const struct ast_channel *chan)
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
struct ast_namedgroups * ast_channel_named_callgroups(const struct ast_channel *chan)
ast_group_t ast_channel_pickupgroup(const struct ast_channel *chan)
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
Definition: channel.c:1441
int ast_channel_queryoption(struct ast_channel *channel, int option, void *data, int *datalen, int block)
Checks the value of an option.
Definition: channel.c:7464
int ast_channel_priority(const struct ast_channel *chan)
ast_callid ast_channel_callid(const struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
const char * ast_channel_accountcode(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
const char * ast_channel_userfield(const struct ast_channel *chan)
char * ast_print_group(char *buf, int buflen, ast_group_t group)
Print call and pickup groups into buffer.
Definition: channel.c:8053
@ AST_AMA_NONE
Definition: channel.h:1198
const char * ast_channel_parkinglot(const struct ast_channel *chan)
const char * ast_channel_appl(const struct ast_channel *chan)
const char * ast_channel_peeraccount(const struct ast_channel *chan)
enum ama_flags ast_channel_amaflags(const struct ast_channel *chan)
struct ast_namedgroups * ast_get_namedgroups(const char *s)
Create an ast_namedgroups set with group names from comma separated string.
Definition: channel.c:7697
void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
const char * ast_channel_hangupsource(const struct ast_channel *chan)
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
struct ast_tone_zone * ast_channel_zone(const struct ast_channel *chan)
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it's bridge.
Definition: channel.c:2518
void ast_channel_named_callgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
const char * ast_channel_lastcontext(const struct ast_channel *chan)
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3004
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
ast_group_t ast_channel_callgroup(const struct ast_channel *chan)
int ast_channel_hold_state(const struct ast_channel *chan)
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
const char * ast_channel_language(const struct ast_channel *chan)
const char * ast_state2str(enum ast_channel_state state)
Gives the string form of a given channel state.
Definition: channel.c:636
enum ama_flags ast_channel_string2amaflag(const char *flag)
Convert a string to a detail record AMA flag.
Definition: channel.c:4379
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
void ast_channel_zone_set(struct ast_channel *chan, struct ast_tone_zone *value)
#define AST_CHAN_WRITE_INFO_T_VERSION
ast_chan_write_info_t version. Must be incremented if structure is changed
Definition: channel.h:593
struct ast_namedgroups * ast_unref_namedgroups(struct ast_namedgroups *groups)
Definition: channel.c:7754
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
Definition: channel.c:7444
void ast_channel_transfercapability_set(struct ast_channel *chan, unsigned short value)
void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1473
ast_group_t ast_get_group(const char *s)
Definition: channel.c:7640
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1427
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2969
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2418
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
@ AST_MEDIA_TYPE_VIDEO
Definition: codec.h:33
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
static int enabled
Definition: dnsmgr.c:91
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:324
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:734
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
#define locked_string_field_set(chan, field, source)
Definition: func_channel.c:359
static int func_mchan_read(struct ast_channel *chan, const char *function, char *data, struct ast_str **buf, ssize_t len)
Definition: func_channel.c:866
static int func_channel_write_real(struct ast_channel *chan, const char *function, char *data, const char *value)
Definition: func_channel.c:581
static struct ast_custom_function channels_function
Definition: func_channel.c:839
static struct ast_custom_function channel_function
Definition: func_channel.c:780
static int func_channels_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
Definition: func_channel.c:786
#define locked_copy_string(chan, dest, source, len)
Definition: func_channel.c:353
static struct ast_custom_function mchan_function
Definition: func_channel.c:904
static int func_chan_exists_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
Definition: func_channel.c:844
static int load_module(void)
Definition: func_channel.c:922
static int func_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value)
Definition: func_channel.c:757
static int func_mchan_write(struct ast_channel *chan, const char *function, char *data, const char *value)
Definition: func_channel.c:886
static int unload_module(void)
Definition: func_channel.c:910
static struct ast_custom_function chan_exists_function
Definition: func_channel.c:861
static const char *const transfercapability_table[0x20]
Definition: func_channel.c:366
static int func_channel_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
Definition: func_channel.c:372
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
globally accessible channel datastores
const struct ast_datastore_info secure_call_info
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define AST_OPTION_RELAXDTMF
#define AST_OPTION_RXGAIN
#define AST_OPTION_DIGIT_DETECT
#define AST_OPTION_CHANNEL_WRITE
Handle channel write data If a channel needs to process the data from a func_channel write operation ...
#define AST_OPTION_TDD
#define AST_OPTION_FAX_DETECT
#define AST_OPTION_TXGAIN
@ AST_CONTROL_HOLD
void ast_callid_strnprint(char *buffer, size_t buffer_size, ast_callid callid)
copy a string representation of the callid into a target string
Definition: logger.c:2288
unsigned int ast_callid
#define LOG_ERROR
#define LOG_WARNING
Tone Indication Support.
static struct ast_tone_zone * ast_tone_zone_unref(struct ast_tone_zone *tz)
Release a reference to an ast_tone_zone.
Definition: indications.h:205
struct ast_tone_zone * ast_get_indication_zone(const char *country)
locate ast_tone_zone
Definition: indications.c:439
static struct ast_tone_zone * ast_tone_zone_ref(struct ast_tone_zone *tz)
Increase the reference count on an ast_tone_zone.
Definition: indications.h:216
int ast_max_forwards_get(struct ast_channel *chan)
Get the current max forwards for a particular channel.
Definition: max_forwards.c:121
int ast_max_forwards_set(struct ast_channel *chan, int starting_count)
Set the starting max forwards for a particular channel.
Definition: max_forwards.c:105
Asterisk module definitions.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:581
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Core PBX routines and definitions.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1558
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
void ast_pbx_hangup_handler_push(struct ast_channel *chan, const char *handler)
Push the given hangup handler onto the channel hangup handler stack.
int ast_pbx_hangup_handler_pop(struct ast_channel *chan)
Pop the top of the channel hangup handler stack.
static char country[80]
Definition: pbx_dundi.c:205
#define NULL
Definition: resample.c:96
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ast_str_alloca(init_len)
Definition: strings.h:848
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Structure to handle passing func_channel_write info to channels via setoption.
Definition: channel.h:591
Main Channel structure associated with a channel.
const char * data
Data structure associated with a custom dialplan function.
Definition: pbx.h:118
const char * name
Definition: pbx.h:119
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
Support for dynamic strings.
Definition: strings.h:623
A set of tones for a given locale.
Definition: indications.h:74
Channel datastore data for max forwards.
Definition: max_forwards.c:29
int value
Definition: syslog.c:37
static struct test_val c
Utility functions.