Asterisk - The Open Source Telephony Project GIT-master-2de1a68
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="max_forwards">
277 <para>R/W The maximum number of forwards allowed.</para>
278 </enum>
279 <enum name="callid">
280 <para>R/O Call identifier log tag associated with the channel
281 e.g., <literal>[C-00000000]</literal>.</para>
282 </enum>
283 </enumlist>
284 <xi:include xpointer="xpointer(/docs/info[@name='CHANNEL'])" />
285 </parameter>
286 </syntax>
287 <description>
288 <para>Gets/sets various pieces of information about the channel, additional <replaceable>item</replaceable> may
289 be available from the channel driver; see its documentation for details. Any <replaceable>item</replaceable>
290 requested that is not available on the current channel will return an empty string.</para>
291 <example title="Standard CHANNEL item examples">
292 ; Push a hangup handler subroutine existing at dialplan
293 ; location default,s,1 onto the current channel
294 same => n,Set(CHANNEL(hangup_handler_push)=default,s,1)
295
296 ; Set the current tonezone to Germany (de)
297 same => n,Set(CHANNEL(tonezone)=de)
298
299 ; Set the allowed maximum number of forwarding attempts
300 same => n,Set(CHANNEL(max_forwards)=10)
301
302 ; If this channel is ejected from its next bridge, and if
303 ; the channel is not hung up, begin executing dialplan at
304 ; location default,after-bridge,1
305 same => n,Set(CHANNEL(after_bridge_goto)=default,after-bridge,1)
306
307 ; Log the current state of the channel
308 same => n,Log(NOTICE, This channel is: ${CHANNEL(state)})
309 </example>
310 <xi:include xpointer="xpointer(/docs/info[@name='CHANNEL_EXAMPLES'])" />
311 <para>The following channel variables are available as special built-in
312 dialplan channel variables. These variables cannot be set or modified
313 and are read-only.</para>
314 <variablelist>
315 <variable name="CALLINGPRES">
316 <para>Caller ID presentation for incoming calls (PRI channels)</para>
317 </variable>
318 <variable name="CALLINGANI2">
319 <para>Caller ANI2 (PRI channels)</para>
320 </variable>
321 <variable name="CALLINGTON">
322 <para>Caller Type of Number (PRI channels)</para>
323 </variable>
324 <variable name="CALLINGTNS">
325 <para>Transit Network Selector (PRI channels)</para>
326 </variable>
327 <variable name="EXTEN">
328 <para>Current extension</para>
329 </variable>
330 <variable name="CONTEXT">
331 <para>Current context</para>
332 </variable>
333 <variable name="PRIORITY">
334 <para>Current priority</para>
335 </variable>
336 <variable name="CHANNEL">
337 <para>Current channel name</para>
338 </variable>
339 <variable name="UNIQUEID">
340 <para>Current call unique identifier</para>
341 </variable>
342 <variable name="HANGUPCAUSE">
343 <para>Asterisk cause of hangup (inbound/outbound)</para>
344 </variable>
345 </variablelist>
346 </description>
347 </function>
348 ***/
349
350#define locked_copy_string(chan, dest, source, len) \
351 do { \
352 ast_channel_lock(chan); \
353 ast_copy_string(dest, source, len); \
354 ast_channel_unlock(chan); \
355 } while (0)
356#define locked_string_field_set(chan, field, source) \
357 do { \
358 ast_channel_lock(chan); \
359 ast_channel_##field##_set(chan, source); \
360 ast_channel_unlock(chan); \
361 } while (0)
362
363static const char * const transfercapability_table[0x20] = {
364 "SPEECH", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
365 "DIGITAL", "RESTRICTED_DIGITAL", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
366 "3K1AUDIO", "DIGITAL_W_TONES", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
367 "VIDEO", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", };
368
369static int func_channel_read(struct ast_channel *chan, const char *function,
370 char *data, char *buf, size_t len)
371{
372 int ret = 0;
373 struct ast_format_cap *tmpcap;
374
375 if (!chan) {
376 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
377 return -1;
378 }
379
380 if (!strcasecmp(data, "audionativeformat")) {
382 if (tmpcap) {
384
385 ast_channel_lock(chan);
387 ast_channel_unlock(chan);
388 ast_copy_string(buf, ast_format_cap_get_names(tmpcap, &codec_buf), len);
389 ao2_ref(tmpcap, -1);
390 }
391 } else if (!strcasecmp(data, "videonativeformat")) {
393 if (tmpcap) {
395
396 ast_channel_lock(chan);
398 ast_channel_unlock(chan);
399 ast_copy_string(buf, ast_format_cap_get_names(tmpcap, &codec_buf), len);
400 ao2_ref(tmpcap, -1);
401 }
402 } else if (!strcasecmp(data, "audioreadformat")) {
404 } else if (!strcasecmp(data, "audiowriteformat")) {
406 } else if (!strcasecmp(data, "tonezone") && ast_channel_zone(chan)) {
408 } else if (!strcasecmp(data, "dtmf_features")) {
410 buf[0] = '\0';
411 }
412 } else if (!strcasecmp(data, "language"))
414 else if (!strcasecmp(data, "musicclass"))
416 else if (!strcasecmp(data, "name")) {
418 } else if (!strcasecmp(data, "parkinglot"))
420 else if (!strcasecmp(data, "state"))
422 else if (!strcasecmp(data, "onhold")) {
424 ast_channel_hold_state(chan) == AST_CONTROL_HOLD ? "1" : "0", len);
425 } else if (!strcasecmp(data, "channeltype"))
427 else if (!strcasecmp(data, "accountcode"))
429 else if (!strcasecmp(data, "checkhangup")) {
430 locked_copy_string(chan, buf, ast_check_hangup(chan) ? "1" : "0", len);
431 } else if (!strcasecmp(data, "peeraccount"))
433 else if (!strcasecmp(data, "hangupsource"))
435 else if (!strcasecmp(data, "appname") && ast_channel_appl(chan))
437 else if (!strcasecmp(data, "appdata") && ast_channel_data(chan))
439 else if (!strcasecmp(data, "exten"))
441 else if (!strcasecmp(data, "context"))
443 else if (!strcasecmp(data, "lastexten"))
445 else if (!strcasecmp(data, "lastcontext"))
447 else if (!strcasecmp(data, "userfield"))
449 else if (!strcasecmp(data, "channame"))
451 else if (!strcasecmp(data, "linkedid")) {
452 ast_channel_lock(chan);
454 /* fall back on the channel's uniqueid if linkedid is unset */
456 }
457 else {
459 }
460 ast_channel_unlock(chan);
461 } else if (!strcasecmp(data, "peer")) {
462 struct ast_channel *peer;
463
464 peer = ast_channel_bridge_peer(chan);
465 if (peer) {
466 /* Only real channels could have a bridge peer this way. */
467 ast_channel_lock(peer);
469 ast_channel_unlock(peer);
470 ast_channel_unref(peer);
471 } else {
472 buf[0] = '\0';
473 ast_channel_lock(chan);
474 if (!ast_channel_tech(chan)) {
475 const char *pname;
476
477 /*
478 * A dummy channel can still pass along bridged peer info
479 * via the BRIDGEPEER variable.
480 *
481 * A horrible kludge, but... how else?
482 */
483 pname = pbx_builtin_getvar_helper(chan, "BRIDGEPEER");
484 if (!ast_strlen_zero(pname)) {
485 ast_copy_string(buf, pname, len);
486 }
487 }
488 ast_channel_unlock(chan);
489 }
490 } else if (!strcasecmp(data, "uniqueid")) {
492 } else if (!strcasecmp(data, "transfercapability")) {
494 } else if (!strcasecmp(data, "callgroup")) {
495 char groupbuf[256];
496
497 locked_copy_string(chan, buf, ast_print_group(groupbuf, sizeof(groupbuf), ast_channel_callgroup(chan)), len);
498 } else if (!strcasecmp(data, "pickupgroup")) {
499 char groupbuf[256];
500
501 locked_copy_string(chan, buf, ast_print_group(groupbuf, sizeof(groupbuf), ast_channel_pickupgroup(chan)), len);
502 } else if (!strcasecmp(data, "namedcallgroup")) {
503 struct ast_str *tmp_str = ast_str_alloca(1024);
504
506 } else if (!strcasecmp(data, "namedpickupgroup")) {
507 struct ast_str *tmp_str = ast_str_alloca(1024);
508
510 } else if (!strcasecmp(data, "after_bridge_goto")) {
512 } else if (!strcasecmp(data, "amaflags")) {
513 ast_channel_lock(chan);
514 snprintf(buf, len, "%u", ast_channel_amaflags(chan));
515 ast_channel_unlock(chan);
516 } else if (!strncasecmp(data, "secure_bridge_", 14)) {
517 struct ast_datastore *ds;
518
519 buf[0] = '\0';
520 ast_channel_lock(chan);
522 struct ast_secure_call_store *encrypt = ds->data;
523
524 if (!strcasecmp(data, "secure_bridge_signaling")) {
525 snprintf(buf, len, "%s", encrypt->signaling ? "1" : "");
526 } else if (!strcasecmp(data, "secure_bridge_media")) {
527 snprintf(buf, len, "%s", encrypt->media ? "1" : "");
528 }
529 }
530 ast_channel_unlock(chan);
531 } else if (!strcasecmp(data, "max_forwards")) {
532 ast_channel_lock(chan);
533 snprintf(buf, len, "%d", ast_max_forwards_get(chan));
534 ast_channel_unlock(chan);
535 } else if (!strcasecmp(data, "callid")) {
536 ast_callid callid;
537
538 buf[0] = '\0';
539 ast_channel_lock(chan);
540 callid = ast_channel_callid(chan);
541 if (callid) {
542 ast_callid_strnprint(buf, len, callid);
543 }
544 ast_channel_unlock(chan);
545 } else if (!strcasecmp(data, "tdd")) {
546 char status;
547 int status_size = (int) sizeof(status);
548 ret = ast_channel_queryoption(chan, AST_OPTION_TDD, &status, &status_size, 0);
549 if (!ret) {
550 ast_copy_string(buf, status == 2 ? "mate" : status ? "1" : "0", len);
551 }
552 } else if (!strcasecmp(data, "digitdetect")) {
553 char status;
554 int status_size = (int) sizeof(status);
555 ret = ast_channel_queryoption(chan, AST_OPTION_DIGIT_DETECT, &status, &status_size, 0);
556 if (!ret) {
557 ast_copy_string(buf, status ? "1" : "0", len);
558 }
559 } else if (!strcasecmp(data, "faxdetect")) {
560 char status;
561 int status_size = (int) sizeof(status);
562 ret = ast_channel_queryoption(chan, AST_OPTION_FAX_DETECT, &status, &status_size, 0);
563 if (!ret) {
564 ast_copy_string(buf, status ? "1" : "0", len);
565 }
566 } else if (!strcasecmp(data, "device_name")) {
567 ret = ast_channel_get_device_name(chan, buf, len);
568 } 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)) {
569 ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n", data);
570 ret = -1;
571 }
572
573 return ret;
574}
575
576static int func_channel_write_real(struct ast_channel *chan, const char *function,
577 char *data, const char *value)
578{
579 int ret = 0;
580 signed char gainset;
581
582 if (!strcasecmp(data, "language"))
584 else if (!strcasecmp(data, "parkinglot"))
585 locked_string_field_set(chan, parkinglot, value);
586 else if (!strcasecmp(data, "musicclass"))
587 locked_string_field_set(chan, musicclass, value);
588 else if (!strcasecmp(data, "accountcode"))
590 else if (!strcasecmp(data, "userfield"))
591 locked_string_field_set(chan, userfield, value);
592 else if (!strcasecmp(data, "after_bridge_goto")) {
593 if (ast_strlen_zero(value)) {
595 } else {
597 }
598 } else if (!strcasecmp(data, "amaflags")) {
599 int amaflags;
600
601 if (isdigit(*value)) {
602 if (sscanf(value, "%30d", &amaflags) != 1) {
604 }
605 } else {
607 }
608 ast_channel_lock(chan);
610 ast_channel_unlock(chan);
611 } else if (!strcasecmp(data, "peeraccount"))
612 locked_string_field_set(chan, peeraccount, value);
613 else if (!strcasecmp(data, "hangupsource"))
614 /* XXX - should we be forcing this here? */
615 ast_set_hangupsource(chan, value, 0);
616 else if (!strcasecmp(data, "tonezone")) {
617 struct ast_tone_zone *new_zone;
618 if (!(new_zone = ast_get_indication_zone(value))) {
619 ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", value);
620 ret = -1;
621 } else {
622 ast_channel_lock(chan);
623 if (ast_channel_zone(chan)) {
625 }
627 ast_channel_unlock(chan);
628 new_zone = ast_tone_zone_unref(new_zone);
629 }
630 } else if (!strcasecmp(data, "dtmf_features")) {
632 } else if (!strcasecmp(data, "callgroup")) {
633 ast_channel_lock(chan);
635 ast_channel_unlock(chan);
636 } else if (!strcasecmp(data, "pickupgroup")) {
637 ast_channel_lock(chan);
639 ast_channel_unlock(chan);
640 } else if (!strcasecmp(data, "namedcallgroup")) {
641 struct ast_namedgroups *groups = ast_get_namedgroups(value);
642
643 ast_channel_lock(chan);
645 ast_channel_unlock(chan);
647 } else if (!strcasecmp(data, "namedpickupgroup")) {
648 struct ast_namedgroups *groups = ast_get_namedgroups(value);
649
650 ast_channel_lock(chan);
652 ast_channel_unlock(chan);
654 } else if (!strcasecmp(data, "tdd")) {
655 char enabled;
656 if (!strcasecmp(value, "mate")) {
657 enabled = 2;
658 } else {
659 enabled = ast_true(value) ? 1 : 0;
660 }
662 } else if (!strcasecmp(data, "relaxdtmf")) {
663 char enabled = ast_true(value) ? 1 : 0;
665 } else if (!strcasecmp(data, "txgain")) {
666 sscanf(value, "%4hhd", &gainset);
667 ast_channel_setoption(chan, AST_OPTION_TXGAIN, &gainset, sizeof(gainset), 0);
668 } else if (!strcasecmp(data, "rxgain")) {
669 sscanf(value, "%4hhd", &gainset);
670 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &gainset, sizeof(gainset), 0);
671 } else if (!strcasecmp(data, "digitdetect")) {
672 char enabled = ast_true(value) ? 1 : 0;
674 } else if (!strcasecmp(data, "faxdetect")) {
675 char enabled = ast_true(value) ? 1 : 0;
677 } else if (!strcasecmp(data, "transfercapability")) {
678 unsigned short i;
679
680 ast_channel_lock(chan);
681 for (i = 0; i < 0x20; i++) {
682 if (!strcasecmp(transfercapability_table[i], value) && strcmp(value, "UNK")) {
684 break;
685 }
686 }
687 ast_channel_unlock(chan);
688 } else if (!strcasecmp(data, "hangup_handler_pop")) {
689 /* Pop one hangup handler before pushing the new handler. */
692 } else if (!strcasecmp(data, "hangup_handler_push")) {
694 } else if (!strcasecmp(data, "hangup_handler_wipe")) {
695 /* Pop all hangup handlers before pushing the new handler. */
696 while (ast_pbx_hangup_handler_pop(chan)) {
697 }
699 } else if (!strncasecmp(data, "secure_bridge_", 14)) {
700 struct ast_datastore *ds;
701 struct ast_secure_call_store *store;
702
703 if (!chan || !value) {
704 return -1;
705 }
706
707 ast_channel_lock(chan);
708 if (!(ds = ast_channel_datastore_find(chan, &secure_call_info, NULL))) {
710 ast_channel_unlock(chan);
711 return -1;
712 }
713 if (!(store = ast_calloc(1, sizeof(*store)))) {
714 ast_channel_unlock(chan);
715 ast_free(ds);
716 return -1;
717 }
718 ds->data = store;
720 } else {
721 store = ds->data;
722 }
723
724 if (!strcasecmp(data, "secure_bridge_signaling")) {
725 store->signaling = ast_true(value) ? 1 : 0;
726 } else if (!strcasecmp(data, "secure_bridge_media")) {
727 store->media = ast_true(value) ? 1 : 0;
728 }
729 ast_channel_unlock(chan);
730 } else if (!strcasecmp(data, "max_forwards")) {
731 int max_forwards;
732 if (sscanf(value, "%d", &max_forwards) != 1) {
733 ast_log(LOG_WARNING, "Unable to set max forwards to '%s'\n", value);
734 ret = -1;
735 } else {
736 ast_channel_lock(chan);
738 ast_channel_unlock(chan);
739 }
740 } else if (!ast_channel_tech(chan)->func_channel_write
741 || ast_channel_tech(chan)->func_channel_write(chan, function, data, value)) {
742 ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n",
743 data);
744 ret = -1;
745 }
746
747 return ret;
748}
749
750static int func_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value)
751{
752 int res;
753 ast_chan_write_info_t write_info = {
755 .write_fn = func_channel_write_real,
756 .chan = chan,
757 .function = function,
758 .data = data,
759 .value = value,
760 };
761
762 if (!chan) {
763 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
764 return -1;
765 }
766
767 res = func_channel_write_real(chan, function, data, value);
768 ast_channel_setoption(chan, AST_OPTION_CHANNEL_WRITE, &write_info, sizeof(write_info), 0);
769
770 return res;
771}
772
774 .name = "CHANNEL",
775 .read = func_channel_read,
776 .write = func_channel_write,
777};
778
779static int func_channels_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
780{
781 struct ast_channel *c = NULL;
782 regex_t re;
783 int res;
784 size_t buflen = 0;
785 struct ast_channel_iterator *iter;
786
787 buf[0] = '\0';
788
789 if (!ast_strlen_zero(data)) {
790 if ((res = regcomp(&re, data, REG_EXTENDED | REG_ICASE | REG_NOSUB))) {
791 regerror(res, &re, buf, maxlen);
792 ast_log(LOG_WARNING, "Error compiling regular expression for %s(%s): %s\n", function, data, buf);
793 return -1;
794 }
795 }
796
797 if (!(iter = ast_channel_iterator_all_new())) {
798 if (!ast_strlen_zero(data)) {
799 regfree(&re);
800 }
801 return -1;
802 }
803
804 while ((c = ast_channel_iterator_next(iter))) {
806 if (ast_strlen_zero(data) || regexec(&re, ast_channel_name(c), 0, NULL, 0) == 0) {
807 size_t namelen = strlen(ast_channel_name(c));
808 if (buflen + namelen + (ast_strlen_zero(buf) ? 0 : 1) + 1 < maxlen) {
809 if (!ast_strlen_zero(buf)) {
810 strcat(buf, " ");
811 buflen++;
812 }
813 strcat(buf, ast_channel_name(c));
814 buflen += namelen;
815 } else {
816 ast_log(LOG_WARNING, "Number of channels exceeds the available buffer space. Output will be truncated!\n");
817 }
818 }
821 }
822
824
825 if (!ast_strlen_zero(data)) {
826 regfree(&re);
827 }
828
829 return 0;
830}
831
833 .name = "CHANNELS",
834 .read = func_channels_read,
835};
836
837static int func_chan_exists_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
838{
839 struct ast_channel *chan_found = NULL;
840
841 if (ast_strlen_zero(data)) {
842 ast_log(LOG_WARNING, "%s: Channel name or unique ID required\n", function);
843 return -1;
844 }
845
846 chan_found = ast_channel_get_by_name(data);
847 snprintf(buf, maxlen, "%d", (chan_found ? 1 : 0));
848 if (chan_found) {
849 ast_channel_unref(chan_found);
850 }
851 return 0;
852}
853
855 .name = "CHANNEL_EXISTS",
856 .read = func_chan_exists_read,
857};
858
859static int func_mchan_read(struct ast_channel *chan, const char *function,
860 char *data, struct ast_str **buf, ssize_t len)
861{
862 struct ast_channel *mchan;
863 char *template = ast_alloca(4 + strlen(data));
864
865 if (!chan) {
866 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
867 return -1;
868 }
869
871 sprintf(template, "${%s}", data); /* SAFE */
872 ast_str_substitute_variables(buf, len, mchan ? mchan : chan, template);
873 if (mchan) {
874 ast_channel_unref(mchan);
875 }
876 return 0;
877}
878
879static int func_mchan_write(struct ast_channel *chan, const char *function,
880 char *data, const char *value)
881{
882 struct ast_channel *mchan;
883
884 if (!chan) {
885 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
886 return -1;
887 }
888
890 pbx_builtin_setvar_helper(mchan ? mchan : chan, data, value);
891 if (mchan) {
892 ast_channel_unref(mchan);
893 }
894 return 0;
895}
896
898 .name = "MASTER_CHANNEL",
899 .read2 = func_mchan_read,
900 .write = func_mchan_write,
901};
902
903static int unload_module(void)
904{
905 int res = 0;
906
911
912 return res;
913}
914
915static int load_module(void)
916{
917 int res = 0;
918
923
924 return res;
925}
926
927AST_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:479
static char language[MAX_LANGUAGE]
Definition: chan_iax2.c:327
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:476
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:8055
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:10495
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:2385
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Definition: channel.c:1360
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:10563
const char * ast_channel_musicclass(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2922
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:1422
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:7441
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:8030
@ AST_AMA_NONE
Definition: channel.h:1178
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:7674
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:2499
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:2958
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:4359
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:591
struct ast_namedgroups * ast_unref_namedgroups(struct ast_namedgroups *groups)
Definition: channel.c:7731
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:7421
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:1454
ast_group_t ast_get_group(const char *s)
Definition: channel.c:7617
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1408
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2923
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:2399
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:356
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:859
static int func_channel_write_real(struct ast_channel *chan, const char *function, char *data, const char *value)
Definition: func_channel.c:576
static struct ast_custom_function channels_function
Definition: func_channel.c:832
static struct ast_custom_function channel_function
Definition: func_channel.c:773
static int func_channels_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
Definition: func_channel.c:779
#define locked_copy_string(chan, dest, source, len)
Definition: func_channel.c:350
static struct ast_custom_function mchan_function
Definition: func_channel.c:897
static int func_chan_exists_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
Definition: func_channel.c:837
static int load_module(void)
Definition: func_channel.c:915
static int func_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value)
Definition: func_channel.c:750
static int func_mchan_write(struct ast_channel *chan, const char *function, char *data, const char *value)
Definition: func_channel.c:879
static int unload_module(void)
Definition: func_channel.c:903
static struct ast_custom_function chan_exists_function
Definition: func_channel.c:854
static const char *const transfercapability_table[0x20]
Definition: func_channel.c:363
static int func_channel_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
Definition: func_channel.c:369
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:2276
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:567
#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:589
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.