Asterisk - The Open Source Telephony Project GIT-master-8924258
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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 <since>
53 <version>1.6.1.0</version>
54 </since>
55 <synopsis>
56 Gets the list of channels, optionally filtering by a regular expression.
57 </synopsis>
58 <syntax>
59 <parameter name="regular_expression" />
60 </syntax>
61 <description>
62 <para>Gets the list of channels, optionally filtering by a <replaceable>regular_expression</replaceable>. If
63 no argument is provided, all known channels are returned. The
64 <replaceable>regular_expression</replaceable> must correspond to
65 the POSIX.2 specification, as shown in <emphasis>regex(7)</emphasis>. The list returned
66 will be space-delimited.</para>
67 </description>
68 </function>
69 <function name="CHANNEL_EXISTS" language="en_US">
70 <since>
71 <version>16.22.0</version>
72 <version>18.8.0</version>
73 </since>
74 <synopsis>
75 Checks if the specified channel exists.
76 </synopsis>
77 <syntax>
78 <parameter name="name_or_uid" required="true">
79 <para>The name or unique ID of the channel to check.</para>
80 </parameter>
81 </syntax>
82 <description>
83 <para>Returns 1 if the channel <replaceable>name_or_uid</replaceable> exists, 0 if not.</para>
84 </description>
85 </function>
86 <function name="MASTER_CHANNEL" language="en_US">
87 <since>
88 <version>1.8.0</version>
89 </since>
90 <synopsis>
91 Gets or sets variables on the master channel
92 </synopsis>
93 <description>
94 <para>Allows access to the oldest channel associated with the current
95 channel if it still exists. If the channel is the master channel or
96 the master channel no longer exists then access local channel variables
97 instead. In other words, the master channel is the channel identified by
98 the channel's linkedid.</para>
99 </description>
100 </function>
101 <function name="CHANNEL" language="en_US">
102 <since>
103 <version>1.2.0</version>
104 </since>
105 <synopsis>
106 Gets/sets various pieces of information about the channel.
107 </synopsis>
108 <syntax>
109 <parameter name="item" required="true">
110 <para>Standard items (provided by all channel technologies) are:</para>
111 <enumlist>
112 <enum name="amaflags">
113 <para>R/W the Automatic Message Accounting (AMA) flags on the channel.
114 When read from a channel, the integer value will always be returned.
115 When written to a channel, both the string format or integer value
116 is accepted.</para>
117 <enumlist>
118 <enum name="1"><para><literal>OMIT</literal></para></enum>
119 <enum name="2"><para><literal>BILLING</literal></para></enum>
120 <enum name="3"><para><literal>DOCUMENTATION</literal></para></enum>
121 </enumlist>
122 </enum>
123 <enum name="accountcode">
124 <para>R/W the channel's account code.</para>
125 </enum>
126 <enum name="audioreadformat">
127 <para>R/O format currently being read.</para>
128 </enum>
129 <enum name="audionativeformat">
130 <para>R/O format used natively for audio.</para>
131 </enum>
132 <enum name="audiowriteformat">
133 <para>R/O format currently being written.</para>
134 </enum>
135 <enum name="dtmf_features">
136 <para>R/W The channel's DTMF bridge features.
137 May include one or more of 'T' 'K' 'H' 'W' and 'X' in a similar manner to options
138 in the <literal>Dial</literal> application. When setting it, the features string
139 must be all upper case.</para>
140 </enum>
141 <enum name="callgroup">
142 <para>R/W numeric call pickup groups that this channel is a member.</para>
143 </enum>
144 <enum name="pickupgroup">
145 <para>R/W numeric call pickup groups this channel can pickup.</para>
146 </enum>
147 <enum name="namedcallgroup">
148 <para>R/W named call pickup groups that this channel is a member.</para>
149 </enum>
150 <enum name="namedpickupgroup">
151 <para>R/W named call pickup groups this channel can pickup.</para>
152 </enum>
153 <enum name="channeltype">
154 <para>R/O technology used for channel.</para>
155 </enum>
156 <enum name="checkhangup">
157 <para>R/O Whether the channel is hanging up (1/0)</para>
158 </enum>
159 <enum name="digitdetect">
160 <para>R/W Enable or disable DTMF detection on channel drivers that support it.</para>
161 <para>If set on a DAHDI channel, this will only disable DTMF detection, not pulse dialing detection.
162 To disable pulse dialing, use the <literal>dialmode</literal> option.</para>
163 <para>On DAHDI channels, this will disable DSP if it is not needed for anything else.
164 This will prevent DTMF detection regardless of the <literal>dialmode</literal> setting.</para>
165 </enum>
166 <enum name="faxdetect">
167 <para>R/W Enable or disable fax detection on channel drivers that support it.</para>
168 </enum>
169 <enum name="after_bridge_goto">
170 <para>R/W the parseable goto string indicating where the channel is
171 expected to return to in the PBX after exiting the next bridge it joins
172 on the condition that it doesn't hang up. The parseable goto string uses
173 the same syntax as the <literal>Goto</literal> application.</para>
174 </enum>
175 <enum name="hangup_handler_pop">
176 <para>W/O Replace the most recently added hangup handler
177 with a new hangup handler on the channel if supplied. The
178 assigned string is passed to the Gosub application when
179 the channel is hung up. Any optionally omitted context
180 and exten are supplied by the channel pushing the handler
181 before it is pushed.</para>
182 </enum>
183 <enum name="hangup_handler_push">
184 <para>W/O Push a hangup handler onto the channel hangup
185 handler stack. The assigned string is passed to the
186 Gosub application when the channel is hung up. Any
187 optionally omitted context and exten are supplied by the
188 channel pushing the handler before it is pushed.</para>
189 </enum>
190 <enum name="hangup_handler_wipe">
191 <para>W/O Wipe the entire hangup handler stack and replace
192 with a new hangup handler on the channel if supplied. The
193 assigned string is passed to the Gosub application when
194 the channel is hung up. Any optionally omitted context
195 and exten are supplied by the channel pushing the handler
196 before it is pushed.</para>
197 </enum>
198 <enum name="onhold">
199 <para>R/O Whether or not the channel is onhold. (1/0)</para>
200 </enum>
201 <enum name="language">
202 <para>R/W language for sounds played.</para>
203 </enum>
204 <enum name="musicclass">
205 <para>R/W class (from musiconhold.conf) for hold music.</para>
206 </enum>
207 <enum name="name">
208 <para>The name of the channel</para>
209 </enum>
210 <enum name="parkinglot">
211 <para>R/W parkinglot for parking.</para>
212 </enum>
213 <enum name="relaxdtmf">
214 <para>W/O Enable or disable relaxed DTMF detection for channel drivers that support it,
215 overriding any setting previously defaulted by the channel driver.</para>
216 </enum>
217 <enum name="rxgain">
218 <para>R/W set rxgain level on channel drivers that support it.</para>
219 </enum>
220 <enum name="secure_bridge_signaling">
221 <para>Whether or not channels bridged to this channel require secure signaling (1/0)</para>
222 </enum>
223 <enum name="secure_bridge_media">
224 <para>Whether or not channels bridged to this channel require secure media (1/0)</para>
225 </enum>
226 <enum name="state">
227 <para>R/O state of the channel</para>
228 </enum>
229 <enum name="tdd">
230 <para>R/W Enable or disable TDD mode on channel drivers that support it.</para>
231 <para>When reading this option, 1 indicates TDD mode enabled, 0 indicates TDD mode disabled,
232 and <literal>mate</literal> indicates TDD mate mode.</para>
233 </enum>
234 <enum name="tonezone">
235 <para>R/W zone for indications played</para>
236 </enum>
237 <enum name="transfercapability">
238 <para>R/W ISDN Transfer Capability, one of:</para>
239 <enumlist>
240 <enum name="SPEECH" />
241 <enum name="DIGITAL" />
242 <enum name="RESTRICTED_DIGITAL" />
243 <enum name="3K1AUDIO" />
244 <enum name="DIGITAL_W_TONES" />
245 <enum name="VIDEO" />
246 </enumlist>
247 </enum>
248 <enum name="txgain">
249 <para>R/W set txgain level on channel drivers that support it.</para>
250 </enum>
251 <enum name="videonativeformat">
252 <para>R/O format used natively for video</para>
253 </enum>
254 <enum name="hangupsource">
255 <para>R/W returns the channel responsible for hangup.</para>
256 </enum>
257 <enum name="appname">
258 <para>R/O returns the internal application name.</para>
259 </enum>
260 <enum name="appdata">
261 <para>R/O returns the application data if available.</para>
262 </enum>
263 <enum name="exten">
264 <para>R/O returns the extension for an outbound channel.</para>
265 </enum>
266 <enum name="context">
267 <para>R/O returns the context for an outbound channel.</para>
268 </enum>
269 <enum name="lastexten">
270 <para>R/O returns the last unique extension for an outbound channel.</para>
271 </enum>
272 <enum name="lastcontext">
273 <para>R/O returns the last unique context for an outbound channel.</para>
274 </enum>
275 <enum name="channame">
276 <para>R/O returns the channel name for an outbound channel.</para>
277 </enum>
278 <enum name="uniqueid">
279 <para>R/O returns the channel uniqueid.</para>
280 </enum>
281 <enum name="linkedid">
282 <para>R/O returns the linkedid if available, otherwise returns the uniqueid.</para>
283 </enum>
284 <enum name="tenantid">
285 <para>R/W The channel tenantid.</para>
286 </enum>
287 <enum name="max_forwards">
288 <para>R/W The maximum number of forwards allowed.</para>
289 </enum>
290 <enum name="callid">
291 <para>R/O Call identifier log tag associated with the channel
292 e.g., <literal>[C-00000000]</literal>.</para>
293 </enum>
294 </enumlist>
295 <xi:include xpointer="xpointer(/docs/info[@name='CHANNEL'])" />
296 </parameter>
297 </syntax>
298 <description>
299 <para>Gets/sets various pieces of information about the channel, additional <replaceable>item</replaceable> may
300 be available from the channel driver; see its documentation for details. Any <replaceable>item</replaceable>
301 requested that is not available on the current channel will return an empty string.</para>
302 <example title="Standard CHANNEL item examples">
303 ; Push a hangup handler subroutine existing at dialplan
304 ; location default,s,1 onto the current channel
305 same => n,Set(CHANNEL(hangup_handler_push)=default,s,1)
306
307 ; Set the current tonezone to Germany (de)
308 same => n,Set(CHANNEL(tonezone)=de)
309
310 ; Set the allowed maximum number of forwarding attempts
311 same => n,Set(CHANNEL(max_forwards)=10)
312
313 ; If this channel is ejected from its next bridge, and if
314 ; the channel is not hung up, begin executing dialplan at
315 ; location default,after-bridge,1
316 same => n,Set(CHANNEL(after_bridge_goto)=default,after-bridge,1)
317
318 ; Log the current state of the channel
319 same => n,Log(NOTICE, This channel is: ${CHANNEL(state)})
320 </example>
321 <xi:include xpointer="xpointer(/docs/info[@name='CHANNEL_EXAMPLES'])" />
322 <para>The following channel variables are available as special built-in
323 dialplan channel variables. These variables cannot be set or modified
324 and are read-only.</para>
325 <variablelist>
326 <variable name="CALLINGPRES">
327 <para>Caller ID presentation for incoming calls (PRI channels)</para>
328 </variable>
329 <variable name="CALLINGANI2">
330 <para>Caller ANI2 (PRI channels)</para>
331 </variable>
332 <variable name="CALLINGTON">
333 <para>Caller Type of Number (PRI channels)</para>
334 </variable>
335 <variable name="CALLINGTNS">
336 <para>Transit Network Selector (PRI channels)</para>
337 </variable>
338 <variable name="EXTEN">
339 <para>Current extension</para>
340 </variable>
341 <variable name="CONTEXT">
342 <para>Current context</para>
343 </variable>
344 <variable name="PRIORITY">
345 <para>Current priority</para>
346 </variable>
347 <variable name="CHANNEL">
348 <para>Current channel name</para>
349 </variable>
350 <variable name="UNIQUEID">
351 <para>Current call unique identifier</para>
352 </variable>
353 <variable name="HANGUPCAUSE">
354 <para>Asterisk cause of hangup (inbound/outbound)</para>
355 </variable>
356 </variablelist>
357 </description>
358 </function>
359 ***/
360
361#define locked_copy_string(chan, dest, source, len) \
362 do { \
363 ast_channel_lock(chan); \
364 ast_copy_string(dest, source, len); \
365 ast_channel_unlock(chan); \
366 } while (0)
367#define locked_string_field_set(chan, field, source) \
368 do { \
369 ast_channel_lock(chan); \
370 ast_channel_##field##_set(chan, source); \
371 ast_channel_unlock(chan); \
372 } while (0)
373
374static const char * const transfercapability_table[0x20] = {
375 "SPEECH", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
376 "DIGITAL", "RESTRICTED_DIGITAL", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
377 "3K1AUDIO", "DIGITAL_W_TONES", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
378 "VIDEO", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", };
379
380static int func_channel_read(struct ast_channel *chan, const char *function,
381 char *data, char *buf, size_t len)
382{
383 int ret = 0;
384 struct ast_format_cap *tmpcap;
385
386 if (!chan) {
387 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
388 return -1;
389 }
390
391 if (!strcasecmp(data, "audionativeformat")) {
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, "videonativeformat")) {
404 if (tmpcap) {
406
407 ast_channel_lock(chan);
409 ast_channel_unlock(chan);
410 ast_copy_string(buf, ast_format_cap_get_names(tmpcap, &codec_buf), len);
411 ao2_ref(tmpcap, -1);
412 }
413 } else if (!strcasecmp(data, "audioreadformat")) {
415 } else if (!strcasecmp(data, "audiowriteformat")) {
417 } else if (!strcasecmp(data, "tonezone") && ast_channel_zone(chan)) {
419 } else if (!strcasecmp(data, "dtmf_features")) {
421 buf[0] = '\0';
422 }
423 } else if (!strcasecmp(data, "language"))
425 else if (!strcasecmp(data, "musicclass"))
427 else if (!strcasecmp(data, "name")) {
429 } else if (!strcasecmp(data, "parkinglot"))
431 else if (!strcasecmp(data, "state"))
433 else if (!strcasecmp(data, "onhold")) {
435 ast_channel_hold_state(chan) == AST_CONTROL_HOLD ? "1" : "0", len);
436 } else if (!strcasecmp(data, "channeltype"))
438 else if (!strcasecmp(data, "accountcode"))
440 else if (!strcasecmp(data, "checkhangup")) {
441 locked_copy_string(chan, buf, ast_check_hangup(chan) ? "1" : "0", len);
442 } else if (!strcasecmp(data, "peeraccount"))
444 else if (!strcasecmp(data, "hangupsource"))
446 else if (!strcasecmp(data, "appname") && ast_channel_appl(chan))
448 else if (!strcasecmp(data, "appdata") && ast_channel_data(chan))
450 else if (!strcasecmp(data, "exten"))
452 else if (!strcasecmp(data, "context"))
454 else if (!strcasecmp(data, "lastexten"))
456 else if (!strcasecmp(data, "lastcontext"))
458 else if (!strcasecmp(data, "userfield"))
460 else if (!strcasecmp(data, "channame"))
462 else if (!strcasecmp(data, "linkedid")) {
463 ast_channel_lock(chan);
465 /* fall back on the channel's uniqueid if linkedid is unset */
467 }
468 else {
470 }
471 ast_channel_unlock(chan);
472 } else if (!strcasecmp(data, "peer")) {
473 struct ast_channel *peer;
474
475 peer = ast_channel_bridge_peer(chan);
476 if (peer) {
477 /* Only real channels could have a bridge peer this way. */
478 ast_channel_lock(peer);
480 ast_channel_unlock(peer);
481 ast_channel_unref(peer);
482 } else {
483 buf[0] = '\0';
484 ast_channel_lock(chan);
485 if (!ast_channel_tech(chan)) {
486 const char *pname;
487
488 /*
489 * A dummy channel can still pass along bridged peer info
490 * via the BRIDGEPEER variable.
491 *
492 * A horrible kludge, but... how else?
493 */
494 pname = pbx_builtin_getvar_helper(chan, "BRIDGEPEER");
495 if (!ast_strlen_zero(pname)) {
496 ast_copy_string(buf, pname, len);
497 }
498 }
499 ast_channel_unlock(chan);
500 }
501 } else if (!strcasecmp(data, "uniqueid")) {
503 } else if (!strcasecmp(data, "transfercapability")) {
505 } else if (!strcasecmp(data, "callgroup")) {
506 char groupbuf[256];
507
508 locked_copy_string(chan, buf, ast_print_group(groupbuf, sizeof(groupbuf), ast_channel_callgroup(chan)), len);
509 } else if (!strcasecmp(data, "pickupgroup")) {
510 char groupbuf[256];
511
512 locked_copy_string(chan, buf, ast_print_group(groupbuf, sizeof(groupbuf), ast_channel_pickupgroup(chan)), len);
513 } else if (!strcasecmp(data, "namedcallgroup")) {
514 struct ast_str *tmp_str = ast_str_alloca(1024);
515
517 } else if (!strcasecmp(data, "namedpickupgroup")) {
518 struct ast_str *tmp_str = ast_str_alloca(1024);
519
521 } else if (!strcasecmp(data, "after_bridge_goto")) {
523 } else if (!strcasecmp(data, "amaflags")) {
524 ast_channel_lock(chan);
525 snprintf(buf, len, "%u", ast_channel_amaflags(chan));
526 ast_channel_unlock(chan);
527 } else if (!strncasecmp(data, "secure_bridge_", 14)) {
528 struct ast_datastore *ds;
529
530 buf[0] = '\0';
531 ast_channel_lock(chan);
533 struct ast_secure_call_store *encrypt = ds->data;
534
535 if (!strcasecmp(data, "secure_bridge_signaling")) {
536 snprintf(buf, len, "%s", encrypt->signaling ? "1" : "");
537 } else if (!strcasecmp(data, "secure_bridge_media")) {
538 snprintf(buf, len, "%s", encrypt->media ? "1" : "");
539 }
540 }
541 ast_channel_unlock(chan);
542 } else if (!strcasecmp(data, "max_forwards")) {
543 ast_channel_lock(chan);
544 snprintf(buf, len, "%d", ast_max_forwards_get(chan));
545 ast_channel_unlock(chan);
546 } else if (!strcasecmp(data, "callid")) {
547 ast_callid callid;
548
549 buf[0] = '\0';
550 ast_channel_lock(chan);
551 callid = ast_channel_callid(chan);
552 if (callid) {
553 ast_callid_strnprint(buf, len, callid);
554 }
555 ast_channel_unlock(chan);
556 } else if (!strcasecmp(data, "tdd")) {
557 char status;
558 int status_size = (int) sizeof(status);
559 ret = ast_channel_queryoption(chan, AST_OPTION_TDD, &status, &status_size, 0);
560 if (!ret) {
561 ast_copy_string(buf, status == 2 ? "mate" : status ? "1" : "0", len);
562 }
563 } else if (!strcasecmp(data, "digitdetect")) {
564 char status;
565 int status_size = (int) sizeof(status);
566 ret = ast_channel_queryoption(chan, AST_OPTION_DIGIT_DETECT, &status, &status_size, 0);
567 if (!ret) {
568 ast_copy_string(buf, status ? "1" : "0", len);
569 }
570 } else if (!strcasecmp(data, "faxdetect")) {
571 char status;
572 int status_size = (int) sizeof(status);
573 ret = ast_channel_queryoption(chan, AST_OPTION_FAX_DETECT, &status, &status_size, 0);
574 if (!ret) {
575 ast_copy_string(buf, status ? "1" : "0", len);
576 }
577 } else if (!strcasecmp(data, "device_name")) {
578 ret = ast_channel_get_device_name(chan, buf, len);
579 } else if (!strcasecmp(data, "tenantid")) {
581 } 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)) {
582 ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n", data);
583 ret = -1;
584 }
585
586 return ret;
587}
588
589static int func_channel_write_real(struct ast_channel *chan, const char *function,
590 char *data, const char *value)
591{
592 int ret = 0;
593 signed char gainset;
594
595 if (!strcasecmp(data, "language"))
597 else if (!strcasecmp(data, "parkinglot"))
598 locked_string_field_set(chan, parkinglot, value);
599 else if (!strcasecmp(data, "musicclass"))
600 locked_string_field_set(chan, musicclass, value);
601 else if (!strcasecmp(data, "accountcode"))
603 else if (!strcasecmp(data, "userfield"))
604 locked_string_field_set(chan, userfield, value);
605 else if (!strcasecmp(data, "after_bridge_goto")) {
606 if (ast_strlen_zero(value)) {
608 } else {
610 }
611 } else if (!strcasecmp(data, "amaflags")) {
612 int amaflags;
613
614 if (isdigit(*value)) {
615 if (sscanf(value, "%30d", &amaflags) != 1) {
617 }
618 } else {
620 }
621 ast_channel_lock(chan);
623 ast_channel_unlock(chan);
624 } else if (!strcasecmp(data, "peeraccount"))
625 locked_string_field_set(chan, peeraccount, value);
626 else if (!strcasecmp(data, "hangupsource"))
627 /* XXX - should we be forcing this here? */
628 ast_set_hangupsource(chan, value, 0);
629 else if (!strcasecmp(data, "tonezone")) {
630 struct ast_tone_zone *new_zone;
631 if (!(new_zone = ast_get_indication_zone(value))) {
632 ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", value);
633 ret = -1;
634 } else {
635 ast_channel_lock(chan);
636 if (ast_channel_zone(chan)) {
638 }
640 ast_channel_unlock(chan);
641 new_zone = ast_tone_zone_unref(new_zone);
642 }
643 } else if (!strcasecmp(data, "dtmf_features")) {
645 } else if (!strcasecmp(data, "callgroup")) {
646 ast_channel_lock(chan);
648 ast_channel_unlock(chan);
649 } else if (!strcasecmp(data, "pickupgroup")) {
650 ast_channel_lock(chan);
652 ast_channel_unlock(chan);
653 } else if (!strcasecmp(data, "namedcallgroup")) {
654 struct ast_namedgroups *groups = ast_get_namedgroups(value);
655
656 ast_channel_lock(chan);
658 ast_channel_unlock(chan);
660 } else if (!strcasecmp(data, "namedpickupgroup")) {
661 struct ast_namedgroups *groups = ast_get_namedgroups(value);
662
663 ast_channel_lock(chan);
665 ast_channel_unlock(chan);
667 } else if (!strcasecmp(data, "tdd")) {
668 char enabled;
669 if (!strcasecmp(value, "mate")) {
670 enabled = 2;
671 } else {
672 enabled = ast_true(value) ? 1 : 0;
673 }
675 } else if (!strcasecmp(data, "relaxdtmf")) {
676 char enabled = ast_true(value) ? 1 : 0;
678 } else if (!strcasecmp(data, "txgain")) {
679 sscanf(value, "%4hhd", &gainset);
680 ast_channel_setoption(chan, AST_OPTION_TXGAIN, &gainset, sizeof(gainset), 0);
681 } else if (!strcasecmp(data, "rxgain")) {
682 sscanf(value, "%4hhd", &gainset);
683 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &gainset, sizeof(gainset), 0);
684 } else if (!strcasecmp(data, "digitdetect")) {
685 char enabled = ast_true(value) ? 1 : 0;
687 } else if (!strcasecmp(data, "faxdetect")) {
688 char enabled = ast_true(value) ? 1 : 0;
690 } else if (!strcasecmp(data, "transfercapability")) {
691 unsigned short i;
692
693 ast_channel_lock(chan);
694 for (i = 0; i < 0x20; i++) {
695 if (!strcasecmp(transfercapability_table[i], value) && strcmp(value, "UNK")) {
697 break;
698 }
699 }
700 ast_channel_unlock(chan);
701 } else if (!strcasecmp(data, "hangup_handler_pop")) {
702 /* Pop one hangup handler before pushing the new handler. */
705 } else if (!strcasecmp(data, "hangup_handler_push")) {
707 } else if (!strcasecmp(data, "hangup_handler_wipe")) {
708 /* Pop all hangup handlers before pushing the new handler. */
709 while (ast_pbx_hangup_handler_pop(chan)) {
710 }
712 } else if (!strncasecmp(data, "secure_bridge_", 14)) {
713 struct ast_datastore *ds;
714 struct ast_secure_call_store *store;
715
716 if (!chan || !value) {
717 return -1;
718 }
719
720 ast_channel_lock(chan);
721 if (!(ds = ast_channel_datastore_find(chan, &secure_call_info, NULL))) {
723 ast_channel_unlock(chan);
724 return -1;
725 }
726 if (!(store = ast_calloc(1, sizeof(*store)))) {
727 ast_channel_unlock(chan);
728 ast_free(ds);
729 return -1;
730 }
731 ds->data = store;
733 } else {
734 store = ds->data;
735 }
736
737 if (!strcasecmp(data, "secure_bridge_signaling")) {
738 store->signaling = ast_true(value) ? 1 : 0;
739 } else if (!strcasecmp(data, "secure_bridge_media")) {
740 store->media = ast_true(value) ? 1 : 0;
741 }
742 ast_channel_unlock(chan);
743 } else if (!strcasecmp(data, "max_forwards")) {
744 int max_forwards;
745 if (sscanf(value, "%d", &max_forwards) != 1) {
746 ast_log(LOG_WARNING, "Unable to set max forwards to '%s'\n", value);
747 ret = -1;
748 } else {
749 ast_channel_lock(chan);
751 ast_channel_unlock(chan);
752 }
753 } else if (!strcasecmp(data, "tenantid")) {
755 } else if (!ast_channel_tech(chan)->func_channel_write
756 || ast_channel_tech(chan)->func_channel_write(chan, function, data, value)) {
757 ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n",
758 data);
759 ret = -1;
760 }
761
762 return ret;
763}
764
765static int func_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value)
766{
767 int res;
768 ast_chan_write_info_t write_info = {
770 .write_fn = func_channel_write_real,
771 .chan = chan,
772 .function = function,
773 .data = data,
774 .value = value,
775 };
776
777 if (!chan) {
778 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
779 return -1;
780 }
781
782 res = func_channel_write_real(chan, function, data, value);
783 ast_channel_setoption(chan, AST_OPTION_CHANNEL_WRITE, &write_info, sizeof(write_info), 0);
784
785 return res;
786}
787
789 .name = "CHANNEL",
790 .read = func_channel_read,
791 .write = func_channel_write,
792};
793
794static int func_channels_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
795{
796 struct ast_channel *c = NULL;
797 regex_t re;
798 int res;
799 size_t buflen = 0;
800 struct ast_channel_iterator *iter;
801
802 buf[0] = '\0';
803
804 if (!ast_strlen_zero(data)) {
805 if ((res = regcomp(&re, data, REG_EXTENDED | REG_ICASE | REG_NOSUB))) {
806 regerror(res, &re, buf, maxlen);
807 ast_log(LOG_WARNING, "Error compiling regular expression for %s(%s): %s\n", function, data, buf);
808 return -1;
809 }
810 }
811
812 if (!(iter = ast_channel_iterator_all_new())) {
813 if (!ast_strlen_zero(data)) {
814 regfree(&re);
815 }
816 return -1;
817 }
818
819 while ((c = ast_channel_iterator_next(iter))) {
821 if (ast_strlen_zero(data) || regexec(&re, ast_channel_name(c), 0, NULL, 0) == 0) {
822 size_t namelen = strlen(ast_channel_name(c));
823 if (buflen + namelen + (ast_strlen_zero(buf) ? 0 : 1) + 1 < maxlen) {
824 if (!ast_strlen_zero(buf)) {
825 strcat(buf, " ");
826 buflen++;
827 }
828 strcat(buf, ast_channel_name(c));
829 buflen += namelen;
830 } else {
831 ast_log(LOG_WARNING, "Number of channels exceeds the available buffer space. Output will be truncated!\n");
832 }
833 }
836 }
837
839
840 if (!ast_strlen_zero(data)) {
841 regfree(&re);
842 }
843
844 return 0;
845}
846
848 .name = "CHANNELS",
849 .read = func_channels_read,
850};
851
852static int func_chan_exists_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
853{
854 struct ast_channel *chan_found = NULL;
855
856 if (ast_strlen_zero(data)) {
857 ast_log(LOG_WARNING, "%s: Channel name or unique ID required\n", function);
858 return -1;
859 }
860
861 chan_found = ast_channel_get_by_name(data);
862 snprintf(buf, maxlen, "%d", (chan_found ? 1 : 0));
863 if (chan_found) {
864 ast_channel_unref(chan_found);
865 }
866 return 0;
867}
868
870 .name = "CHANNEL_EXISTS",
871 .read = func_chan_exists_read,
872};
873
874static int func_mchan_read(struct ast_channel *chan, const char *function,
875 char *data, struct ast_str **buf, ssize_t len)
876{
877 struct ast_channel *mchan;
878 char *template = ast_alloca(4 + strlen(data));
879
880 if (!chan) {
881 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
882 return -1;
883 }
884
886 sprintf(template, "${%s}", data); /* SAFE */
887 ast_str_substitute_variables(buf, len, mchan ? mchan : chan, template);
888 if (mchan) {
889 ast_channel_unref(mchan);
890 }
891 return 0;
892}
893
894static int func_mchan_write(struct ast_channel *chan, const char *function,
895 char *data, const char *value)
896{
897 struct ast_channel *mchan;
898
899 if (!chan) {
900 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
901 return -1;
902 }
903
905 pbx_builtin_setvar_helper(mchan ? mchan : chan, data, value);
906 if (mchan) {
907 ast_channel_unref(mchan);
908 }
909 return 0;
910}
911
913 .name = "MASTER_CHANNEL",
914 .read2 = func_mchan_read,
915 .write = func_mchan_write,
916};
917
918static int unload_module(void)
919{
920 int res = 0;
921
926
927 return res;
928}
929
930static int load_module(void)
931{
932 int res = 0;
933
938
939 return res;
940}
941
942AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Channel information dialplan functions");
jack_status_t status
Definition: app_jack.c:149
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:500
static char language[MAX_LANGUAGE]
Definition: chan_iax2.c:348
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:497
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:8082
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:10522
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:2414
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:1387
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:10590
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:2970
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:1449
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:7463
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:8057
@ 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:7696
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:2528
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:3006
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:4377
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:7753
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:7443
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:1481
ast_group_t ast_get_group(const char *s)
Definition: channel.c:7639
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1435
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2971
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:2428
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:367
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:874
static int func_channel_write_real(struct ast_channel *chan, const char *function, char *data, const char *value)
Definition: func_channel.c:589
static struct ast_custom_function channels_function
Definition: func_channel.c:847
static struct ast_custom_function channel_function
Definition: func_channel.c:788
static int func_channels_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
Definition: func_channel.c:794
#define locked_copy_string(chan, dest, source, len)
Definition: func_channel.c:361
static struct ast_custom_function mchan_function
Definition: func_channel.c:912
static int func_chan_exists_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
Definition: func_channel.c:852
static int load_module(void)
Definition: func_channel.c:930
static int func_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value)
Definition: func_channel.c:765
static int func_mchan_write(struct ast_channel *chan, const char *function, char *data, const char *value)
Definition: func_channel.c:894
static int unload_module(void)
Definition: func_channel.c:918
static struct ast_custom_function chan_exists_function
Definition: func_channel.c:869
static const char *const transfercapability_table[0x20]
Definition: func_channel.c:374
static int func_channel_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
Definition: func_channel.c:380
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:2263
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:1559
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:214
#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.