Asterisk - The Open Source Telephony Project GIT-master-545c459
Loading...
Searching...
No Matches
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="adsicpe">
127 <para>R/W The channel's support for ADSI (Analog Display Services Interface) CPE.</para>
128 <enumlist>
129 <enum name="available" />
130 <enum name="offhookonly" />
131 <enum name="unavailable" />
132 <enum name="unknown" />
133 </enumlist>
134 </enum>
135 <enum name="audioreadformat">
136 <para>R/O format currently being read.</para>
137 </enum>
138 <enum name="audionativeformat">
139 <para>R/O format used natively for audio.</para>
140 </enum>
141 <enum name="audiowriteformat">
142 <para>R/O format currently being written.</para>
143 </enum>
144 <enum name="dtmf_features">
145 <para>R/W The channel's DTMF bridge features.
146 May include one or more of 'T' 'K' 'H' 'W' and 'X' in a similar manner to options
147 in the <literal>Dial</literal> application. When setting it, the features string
148 must be all upper case.</para>
149 </enum>
150 <enum name="callgroup">
151 <para>R/W numeric call pickup groups that this channel is a member.</para>
152 </enum>
153 <enum name="pickupgroup">
154 <para>R/W numeric call pickup groups this channel can pickup.</para>
155 </enum>
156 <enum name="namedcallgroup">
157 <para>R/W named call pickup groups that this channel is a member.</para>
158 </enum>
159 <enum name="namedpickupgroup">
160 <para>R/W named call pickup groups this channel can pickup.</para>
161 </enum>
162 <enum name="channeltype">
163 <para>R/O technology used for channel.</para>
164 </enum>
165 <enum name="checkhangup">
166 <para>R/O Whether the channel is hanging up (1/0)</para>
167 </enum>
168 <enum name="digitdetect">
169 <para>R/W Enable or disable DTMF detection on channel drivers that support it.</para>
170 <para>If set on a DAHDI channel, this will only disable DTMF detection, not pulse dialing detection.
171 To disable pulse dialing, use the <literal>dialmode</literal> option.</para>
172 <para>On DAHDI channels, this will disable DSP if it is not needed for anything else.
173 This will prevent DTMF detection regardless of the <literal>dialmode</literal> setting.</para>
174 </enum>
175 <enum name="faxdetect">
176 <para>R/W Enable or disable fax detection on channel drivers that support it.</para>
177 </enum>
178 <enum name="after_bridge_goto">
179 <para>R/W the parseable goto string indicating where the channel is
180 expected to return to in the PBX after exiting the next bridge it joins
181 on the condition that it doesn't hang up. The parseable goto string uses
182 the same syntax as the <literal>Goto</literal> application.</para>
183 </enum>
184 <enum name="hangup_handler_pop">
185 <para>W/O Replace the most recently added hangup handler
186 with a new hangup handler on the channel if supplied. The
187 assigned string is passed to the Gosub application when
188 the channel is hung up. Any optionally omitted context
189 and exten are supplied by the channel pushing the handler
190 before it is pushed.</para>
191 </enum>
192 <enum name="hangup_handler_push">
193 <para>W/O Push a hangup handler onto the channel hangup
194 handler stack. The assigned string is passed to the
195 Gosub application when the channel is hung up. Any
196 optionally omitted context and exten are supplied by the
197 channel pushing the handler before it is pushed.</para>
198 </enum>
199 <enum name="hangup_handler_wipe">
200 <para>W/O Wipe the entire hangup handler stack and replace
201 with a new hangup handler on the channel if supplied. The
202 assigned string is passed to the Gosub application when
203 the channel is hung up. Any optionally omitted context
204 and exten are supplied by the channel pushing the handler
205 before it is pushed.</para>
206 </enum>
207 <enum name="onhold">
208 <para>R/O Whether or not the channel is onhold. (1/0)</para>
209 </enum>
210 <enum name="language">
211 <para>R/W language for sounds played.</para>
212 </enum>
213 <enum name="musicclass">
214 <para>R/W class (from musiconhold.conf) for hold music.</para>
215 </enum>
216 <enum name="name">
217 <para>The name of the channel</para>
218 </enum>
219 <enum name="parkinglot">
220 <para>R/W parkinglot for parking.</para>
221 </enum>
222 <enum name="relaxdtmf">
223 <para>W/O Enable or disable relaxed DTMF detection for channel drivers that support it,
224 overriding any setting previously defaulted by the channel driver.</para>
225 </enum>
226 <enum name="rxgain">
227 <para>R/W set rxgain level on channel drivers that support it.</para>
228 </enum>
229 <enum name="secure_bridge_signaling">
230 <para>Whether or not channels bridged to this channel require secure signaling (1/0)</para>
231 </enum>
232 <enum name="secure_bridge_media">
233 <para>Whether or not channels bridged to this channel require secure media (1/0)</para>
234 </enum>
235 <enum name="state">
236 <para>R/O state of the channel</para>
237 </enum>
238 <enum name="tdd">
239 <para>R/W Enable or disable TDD mode on channel drivers that support it.</para>
240 <para>When reading this option, 1 indicates TDD mode enabled, 0 indicates TDD mode disabled,
241 and <literal>mate</literal> indicates TDD mate mode.</para>
242 </enum>
243 <enum name="tonezone">
244 <para>R/W zone for indications played</para>
245 </enum>
246 <enum name="transfercapability">
247 <para>R/W ISDN Transfer Capability, one of:</para>
248 <enumlist>
249 <enum name="SPEECH" />
250 <enum name="DIGITAL" />
251 <enum name="RESTRICTED_DIGITAL" />
252 <enum name="3K1AUDIO" />
253 <enum name="DIGITAL_W_TONES" />
254 <enum name="VIDEO" />
255 </enumlist>
256 </enum>
257 <enum name="txgain">
258 <para>R/W set txgain level on channel drivers that support it.</para>
259 </enum>
260 <enum name="videonativeformat">
261 <para>R/O format used natively for video</para>
262 </enum>
263 <enum name="hangupsource">
264 <para>R/W returns the channel responsible for hangup.</para>
265 </enum>
266 <enum name="appname">
267 <para>R/O returns the internal application name.</para>
268 </enum>
269 <enum name="appdata">
270 <para>R/O returns the application data if available.</para>
271 </enum>
272 <enum name="exten">
273 <para>R/O returns the extension for an outbound channel.</para>
274 </enum>
275 <enum name="context">
276 <para>R/O returns the context for an outbound channel.</para>
277 </enum>
278 <enum name="lastexten">
279 <para>R/O returns the last unique extension for an outbound channel.</para>
280 </enum>
281 <enum name="lastcontext">
282 <para>R/O returns the last unique context for an outbound channel.</para>
283 </enum>
284 <enum name="channame">
285 <para>R/O returns the channel name for an outbound channel.</para>
286 </enum>
287 <enum name="uniqueid">
288 <para>R/O returns the channel uniqueid.</para>
289 </enum>
290 <enum name="linkedid">
291 <para>R/O returns the linkedid if available, otherwise returns the uniqueid.</para>
292 </enum>
293 <enum name="tenantid">
294 <para>R/W The channel tenantid.</para>
295 </enum>
296 <enum name="max_forwards">
297 <para>R/W The maximum number of forwards allowed.</para>
298 </enum>
299 <enum name="callid">
300 <para>R/O Call identifier log tag associated with the channel
301 e.g., <literal>[C-00000000]</literal>.</para>
302 </enum>
303 </enumlist>
304 <xi:include xpointer="xpointer(/docs/info[@name='CHANNEL'])" />
305 </parameter>
306 </syntax>
307 <description>
308 <para>Gets/sets various pieces of information about the channel, additional <replaceable>item</replaceable> may
309 be available from the channel driver; see its documentation for details. Any <replaceable>item</replaceable>
310 requested that is not available on the current channel will return an empty string.</para>
311 <example title="Standard CHANNEL item examples">
312 ; Push a hangup handler subroutine existing at dialplan
313 ; location default,s,1 onto the current channel
314 same => n,Set(CHANNEL(hangup_handler_push)=default,s,1)
315
316 ; Set the current tonezone to Germany (de)
317 same => n,Set(CHANNEL(tonezone)=de)
318
319 ; Set the allowed maximum number of forwarding attempts
320 same => n,Set(CHANNEL(max_forwards)=10)
321
322 ; If this channel is ejected from its next bridge, and if
323 ; the channel is not hung up, begin executing dialplan at
324 ; location default,after-bridge,1
325 same => n,Set(CHANNEL(after_bridge_goto)=default,after-bridge,1)
326
327 ; Log the current state of the channel
328 same => n,Log(NOTICE, This channel is: ${CHANNEL(state)})
329 </example>
330 <xi:include xpointer="xpointer(/docs/info[@name='CHANNEL_EXAMPLES'])" />
331 <para>The following channel variables are available as special built-in
332 dialplan channel variables. These variables cannot be set or modified
333 and are read-only.</para>
334 <variablelist>
335 <variable name="CALLINGPRES">
336 <para>Caller ID presentation for incoming calls (PRI channels)</para>
337 </variable>
338 <variable name="CALLINGANI2">
339 <para>Caller ANI2 (PRI channels)</para>
340 </variable>
341 <variable name="CALLINGTON">
342 <para>Caller Type of Number (PRI channels)</para>
343 </variable>
344 <variable name="CALLINGTNS">
345 <para>Transit Network Selector (PRI channels)</para>
346 </variable>
347 <variable name="EXTEN">
348 <para>Current extension</para>
349 </variable>
350 <variable name="CONTEXT">
351 <para>Current context</para>
352 </variable>
353 <variable name="PRIORITY">
354 <para>Current priority</para>
355 </variable>
356 <variable name="CHANNEL">
357 <para>Current channel name</para>
358 </variable>
359 <variable name="UNIQUEID">
360 <para>Current call unique identifier</para>
361 </variable>
362 <variable name="HANGUPCAUSE">
363 <para>Asterisk cause of hangup (inbound/outbound)</para>
364 </variable>
365 </variablelist>
366 </description>
367 </function>
368 ***/
369
370#define locked_copy_string(chan, dest, source, len) \
371 do { \
372 ast_channel_lock(chan); \
373 ast_copy_string(dest, source, len); \
374 ast_channel_unlock(chan); \
375 } while (0)
376#define locked_string_field_set(chan, field, source) \
377 do { \
378 ast_channel_lock(chan); \
379 ast_channel_##field##_set(chan, source); \
380 ast_channel_unlock(chan); \
381 } while (0)
382
383static const char * const transfercapability_table[0x20] = {
384 "SPEECH", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
385 "DIGITAL", "RESTRICTED_DIGITAL", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
386 "3K1AUDIO", "DIGITAL_W_TONES", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
387 "VIDEO", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", };
388
389static int func_channel_read(struct ast_channel *chan, const char *function,
390 char *data, char *buf, size_t len)
391{
392 int ret = 0;
393 struct ast_format_cap *tmpcap;
394
395 if (!chan) {
396 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
397 return -1;
398 }
399
400 if (!strcasecmp(data, "audionativeformat")) {
402 if (tmpcap) {
404
405 ast_channel_lock(chan);
407 ast_channel_unlock(chan);
408 ast_copy_string(buf, ast_format_cap_get_names(tmpcap, &codec_buf), len);
409 ao2_ref(tmpcap, -1);
410 }
411 } else if (!strcasecmp(data, "videonativeformat")) {
413 if (tmpcap) {
415
416 ast_channel_lock(chan);
418 ast_channel_unlock(chan);
419 ast_copy_string(buf, ast_format_cap_get_names(tmpcap, &codec_buf), len);
420 ao2_ref(tmpcap, -1);
421 }
422 } else if (!strcasecmp(data, "audioreadformat")) {
424 } else if (!strcasecmp(data, "audiowriteformat")) {
426 } else if (!strcasecmp(data, "tonezone") && ast_channel_zone(chan)) {
428 } else if (!strcasecmp(data, "adsicpe")) {
429 int adsi;
430 ast_channel_lock(chan);
432 ast_channel_unlock(chan);
433 switch (adsi) {
435 ast_copy_string(buf, "available", len);
436 break;
438 ast_copy_string(buf, "unavailable", len);
439 break;
441 ast_copy_string(buf, "offhookonly", len);
442 break;
443 default:
444 ast_copy_string(buf, "unknown", len);
445 break;
446 }
447 } else if (!strcasecmp(data, "dtmf_features")) {
449 buf[0] = '\0';
450 }
451 } else if (!strcasecmp(data, "language"))
453 else if (!strcasecmp(data, "musicclass"))
455 else if (!strcasecmp(data, "name")) {
457 } else if (!strcasecmp(data, "parkinglot"))
459 else if (!strcasecmp(data, "state"))
461 else if (!strcasecmp(data, "onhold")) {
463 ast_channel_hold_state(chan) == AST_CONTROL_HOLD ? "1" : "0", len);
464 } else if (!strcasecmp(data, "channeltype"))
466 ast_channel_tech(chan) ? ast_channel_tech(chan)->type : "", len);
467 else if (!strcasecmp(data, "accountcode"))
469 else if (!strcasecmp(data, "checkhangup")) {
470 locked_copy_string(chan, buf, ast_check_hangup(chan) ? "1" : "0", len);
471 } else if (!strcasecmp(data, "peeraccount"))
473 else if (!strcasecmp(data, "hangupsource"))
475 else if (!strcasecmp(data, "appname") && ast_channel_appl(chan))
477 else if (!strcasecmp(data, "appdata") && ast_channel_data(chan))
479 else if (!strcasecmp(data, "exten"))
481 else if (!strcasecmp(data, "context"))
483 else if (!strcasecmp(data, "lastexten"))
485 else if (!strcasecmp(data, "lastcontext"))
487 else if (!strcasecmp(data, "userfield"))
489 else if (!strcasecmp(data, "channame"))
491 else if (!strcasecmp(data, "linkedid")) {
492 ast_channel_lock(chan);
494 /* fall back on the channel's uniqueid if linkedid is unset */
496 }
497 else {
499 }
500 ast_channel_unlock(chan);
501 } else if (!strcasecmp(data, "peer")) {
502 struct ast_channel *peer;
503
504 peer = ast_channel_bridge_peer(chan);
505 if (peer) {
506 /* Only real channels could have a bridge peer this way. */
507 ast_channel_lock(peer);
509 ast_channel_unlock(peer);
510 ast_channel_unref(peer);
511 } else {
512 buf[0] = '\0';
513 ast_channel_lock(chan);
514 if (!ast_channel_tech(chan)) {
515 const char *pname;
516
517 /*
518 * A dummy channel can still pass along bridged peer info
519 * via the BRIDGEPEER variable.
520 *
521 * A horrible kludge, but... how else?
522 */
523 pname = pbx_builtin_getvar_helper(chan, "BRIDGEPEER");
524 if (!ast_strlen_zero(pname)) {
525 ast_copy_string(buf, pname, len);
526 }
527 }
528 ast_channel_unlock(chan);
529 }
530 } else if (!strcasecmp(data, "uniqueid")) {
532 } else if (!strcasecmp(data, "transfercapability")) {
534 } else if (!strcasecmp(data, "callgroup")) {
535 char groupbuf[256];
536
537 locked_copy_string(chan, buf, ast_print_group(groupbuf, sizeof(groupbuf), ast_channel_callgroup(chan)), len);
538 } else if (!strcasecmp(data, "pickupgroup")) {
539 char groupbuf[256];
540
541 locked_copy_string(chan, buf, ast_print_group(groupbuf, sizeof(groupbuf), ast_channel_pickupgroup(chan)), len);
542 } else if (!strcasecmp(data, "namedcallgroup")) {
543 struct ast_str *tmp_str = ast_str_alloca(1024);
544
546 } else if (!strcasecmp(data, "namedpickupgroup")) {
547 struct ast_str *tmp_str = ast_str_alloca(1024);
548
550 } else if (!strcasecmp(data, "after_bridge_goto")) {
552 } else if (!strcasecmp(data, "amaflags")) {
553 ast_channel_lock(chan);
554 snprintf(buf, len, "%u", ast_channel_amaflags(chan));
555 ast_channel_unlock(chan);
556 } else if (!strncasecmp(data, "secure_bridge_", 14)) {
557 struct ast_datastore *ds;
558
559 buf[0] = '\0';
560 ast_channel_lock(chan);
562 struct ast_secure_call_store *encrypt = ds->data;
563
564 if (!strcasecmp(data, "secure_bridge_signaling")) {
565 snprintf(buf, len, "%s", encrypt->signaling ? "1" : "");
566 } else if (!strcasecmp(data, "secure_bridge_media")) {
567 snprintf(buf, len, "%s", encrypt->media ? "1" : "");
568 }
569 }
570 ast_channel_unlock(chan);
571 } else if (!strcasecmp(data, "max_forwards")) {
572 ast_channel_lock(chan);
573 snprintf(buf, len, "%d", ast_max_forwards_get(chan));
574 ast_channel_unlock(chan);
575 } else if (!strcasecmp(data, "callid")) {
576 ast_callid callid;
577
578 buf[0] = '\0';
579 ast_channel_lock(chan);
580 callid = ast_channel_callid(chan);
581 if (callid) {
582 ast_callid_strnprint(buf, len, callid);
583 }
584 ast_channel_unlock(chan);
585 } else if (!strcasecmp(data, "tdd")) {
586 char status;
587 int status_size = (int) sizeof(status);
588 ret = ast_channel_queryoption(chan, AST_OPTION_TDD, &status, &status_size, 0);
589 if (!ret) {
590 ast_copy_string(buf, status == 2 ? "mate" : status ? "1" : "0", len);
591 }
592 } else if (!strcasecmp(data, "digitdetect")) {
593 char status;
594 int status_size = (int) sizeof(status);
595 ret = ast_channel_queryoption(chan, AST_OPTION_DIGIT_DETECT, &status, &status_size, 0);
596 if (!ret) {
597 ast_copy_string(buf, status ? "1" : "0", len);
598 }
599 } else if (!strcasecmp(data, "faxdetect")) {
600 char status;
601 int status_size = (int) sizeof(status);
602 ret = ast_channel_queryoption(chan, AST_OPTION_FAX_DETECT, &status, &status_size, 0);
603 if (!ret) {
604 ast_copy_string(buf, status ? "1" : "0", len);
605 }
606 } else if (!strcasecmp(data, "device_name")) {
607 ret = ast_channel_get_device_name(chan, buf, len);
608 } else if (!strcasecmp(data, "tenantid")) {
610 } 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)) {
611 ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n", data);
612 ret = -1;
613 }
614
615 return ret;
616}
617
618static int func_channel_write_real(struct ast_channel *chan, const char *function,
619 char *data, const char *value)
620{
621 int ret = 0;
622 signed char gainset;
623
624 if (!strcasecmp(data, "language"))
626 else if (!strcasecmp(data, "parkinglot"))
627 locked_string_field_set(chan, parkinglot, value);
628 else if (!strcasecmp(data, "musicclass"))
629 locked_string_field_set(chan, musicclass, value);
630 else if (!strcasecmp(data, "accountcode"))
632 else if (!strcasecmp(data, "userfield"))
633 locked_string_field_set(chan, userfield, value);
634 else if (!strcasecmp(data, "after_bridge_goto")) {
635 if (ast_strlen_zero(value)) {
637 } else {
639 }
640 } else if (!strcasecmp(data, "amaflags")) {
641 int amaflags;
642
643 if (isdigit(*value)) {
644 if (sscanf(value, "%30d", &amaflags) != 1) {
646 }
647 } else {
649 }
650 ast_channel_lock(chan);
652 ast_channel_unlock(chan);
653 } else if (!strcasecmp(data, "peeraccount"))
654 locked_string_field_set(chan, peeraccount, value);
655 else if (!strcasecmp(data, "hangupsource"))
656 /* XXX - should we be forcing this here? */
657 ast_set_hangupsource(chan, value, 0);
658 else if (!strcasecmp(data, "tonezone")) {
659 struct ast_tone_zone *new_zone;
660 if (!(new_zone = ast_get_indication_zone(value))) {
661 ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", value);
662 ret = -1;
663 } else {
664 ast_channel_lock(chan);
665 if (ast_channel_zone(chan)) {
667 }
669 ast_channel_unlock(chan);
670 new_zone = ast_tone_zone_unref(new_zone);
671 }
672 } else if (!strcasecmp(data, "adsicpe")) {
673 int adsi;
674 if (!strcasecmp(value, "unknown")) {
676 } else if (!strcasecmp(value, "available")) {
678 } else if (!strcasecmp(value, "unavailable")) {
680 } else if (!strcasecmp(value, "offhookonly")) {
682 } else {
683 ast_log(LOG_ERROR, "Unknown ADSI availability '%s'\n", value);
684 return -1;
685 }
686 ast_channel_lock(chan);
688 ast_channel_unlock(chan);
689 } else if (!strcasecmp(data, "dtmf_features")) {
691 } else if (!strcasecmp(data, "callgroup")) {
692 ast_channel_lock(chan);
694 ast_channel_unlock(chan);
695 } else if (!strcasecmp(data, "pickupgroup")) {
696 ast_channel_lock(chan);
698 ast_channel_unlock(chan);
699 } else if (!strcasecmp(data, "namedcallgroup")) {
700 struct ast_namedgroups *groups = ast_get_namedgroups(value);
701
702 ast_channel_lock(chan);
704 ast_channel_unlock(chan);
706 } else if (!strcasecmp(data, "namedpickupgroup")) {
707 struct ast_namedgroups *groups = ast_get_namedgroups(value);
708
709 ast_channel_lock(chan);
711 ast_channel_unlock(chan);
713 } else if (!strcasecmp(data, "tdd")) {
714 char enabled;
715 if (!strcasecmp(value, "mate")) {
716 enabled = 2;
717 } else {
718 enabled = ast_true(value) ? 1 : 0;
719 }
721 } else if (!strcasecmp(data, "relaxdtmf")) {
722 char enabled = ast_true(value) ? 1 : 0;
724 } else if (!strcasecmp(data, "txgain")) {
725 sscanf(value, "%4hhd", &gainset);
726 ast_channel_setoption(chan, AST_OPTION_TXGAIN, &gainset, sizeof(gainset), 0);
727 } else if (!strcasecmp(data, "rxgain")) {
728 sscanf(value, "%4hhd", &gainset);
729 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &gainset, sizeof(gainset), 0);
730 } else if (!strcasecmp(data, "digitdetect")) {
731 char enabled = ast_true(value) ? 1 : 0;
733 } else if (!strcasecmp(data, "faxdetect")) {
734 char enabled = ast_true(value) ? 1 : 0;
736 } else if (!strcasecmp(data, "transfercapability")) {
737 unsigned short i;
738
739 ast_channel_lock(chan);
740 for (i = 0; i < 0x20; i++) {
741 if (!strcasecmp(transfercapability_table[i], value) && strcmp(value, "UNK")) {
743 break;
744 }
745 }
746 ast_channel_unlock(chan);
747 } else if (!strcasecmp(data, "hangup_handler_pop")) {
748 /* Pop one hangup handler before pushing the new handler. */
751 } else if (!strcasecmp(data, "hangup_handler_push")) {
753 } else if (!strcasecmp(data, "hangup_handler_wipe")) {
754 /* Pop all hangup handlers before pushing the new handler. */
755 while (ast_pbx_hangup_handler_pop(chan)) {
756 }
758 } else if (!strncasecmp(data, "secure_bridge_", 14)) {
759 struct ast_datastore *ds;
760 struct ast_secure_call_store *store;
761
762 if (!chan || !value) {
763 return -1;
764 }
765
766 ast_channel_lock(chan);
767 if (!(ds = ast_channel_datastore_find(chan, &secure_call_info, NULL))) {
769 ast_channel_unlock(chan);
770 return -1;
771 }
772 if (!(store = ast_calloc(1, sizeof(*store)))) {
773 ast_channel_unlock(chan);
774 ast_free(ds);
775 return -1;
776 }
777 ds->data = store;
779 } else {
780 store = ds->data;
781 }
782
783 if (!strcasecmp(data, "secure_bridge_signaling")) {
784 store->signaling = ast_true(value) ? 1 : 0;
785 } else if (!strcasecmp(data, "secure_bridge_media")) {
786 store->media = ast_true(value) ? 1 : 0;
787 }
788 ast_channel_unlock(chan);
789 } else if (!strcasecmp(data, "max_forwards")) {
790 int max_forwards;
791 if (sscanf(value, "%d", &max_forwards) != 1) {
792 ast_log(LOG_WARNING, "Unable to set max forwards to '%s'\n", value);
793 ret = -1;
794 } else {
795 ast_channel_lock(chan);
797 ast_channel_unlock(chan);
798 }
799 } else if (!strcasecmp(data, "tenantid")) {
801 } else if (!ast_channel_tech(chan)
803 || ast_channel_tech(chan)->func_channel_write(chan, function, data, value)) {
804 ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n",
805 data);
806 ret = -1;
807 }
808
809 return ret;
810}
811
812static int func_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value)
813{
814 int res;
815 ast_chan_write_info_t write_info = {
817 .write_fn = func_channel_write_real,
818 .chan = chan,
819 .function = function,
820 .data = data,
821 .value = value,
822 };
823
824 if (!chan) {
825 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
826 return -1;
827 }
828
829 res = func_channel_write_real(chan, function, data, value);
830 ast_channel_setoption(chan, AST_OPTION_CHANNEL_WRITE, &write_info, sizeof(write_info), 0);
831
832 return res;
833}
834
836 .name = "CHANNEL",
837 .read = func_channel_read,
838 .write = func_channel_write,
839};
840
841static int func_channels_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
842{
843 struct ast_channel *c = NULL;
844 regex_t re;
845 int res;
846 size_t buflen = 0;
847 struct ast_channel_iterator *iter;
848
849 buf[0] = '\0';
850
851 if (!ast_strlen_zero(data)) {
852 if ((res = regcomp(&re, data, REG_EXTENDED | REG_ICASE | REG_NOSUB))) {
853 regerror(res, &re, buf, maxlen);
854 ast_log(LOG_WARNING, "Error compiling regular expression for %s(%s): %s\n", function, data, buf);
855 return -1;
856 }
857 }
858
859 if (!(iter = ast_channel_iterator_all_new())) {
860 if (!ast_strlen_zero(data)) {
861 regfree(&re);
862 }
863 return -1;
864 }
865
866 while ((c = ast_channel_iterator_next(iter))) {
868 if (ast_strlen_zero(data) || regexec(&re, ast_channel_name(c), 0, NULL, 0) == 0) {
869 size_t namelen = strlen(ast_channel_name(c));
870 if (buflen + namelen + (ast_strlen_zero(buf) ? 0 : 1) + 1 < maxlen) {
871 if (!ast_strlen_zero(buf)) {
872 strcat(buf, " ");
873 buflen++;
874 }
875 strcat(buf, ast_channel_name(c));
876 buflen += namelen;
877 } else {
878 ast_log(LOG_WARNING, "Number of channels exceeds the available buffer space. Output will be truncated!\n");
879 }
880 }
883 }
884
886
887 if (!ast_strlen_zero(data)) {
888 regfree(&re);
889 }
890
891 return 0;
892}
893
895 .name = "CHANNELS",
896 .read = func_channels_read,
897};
898
899static int func_chan_exists_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
900{
901 struct ast_channel *chan_found = NULL;
902
903 if (ast_strlen_zero(data)) {
904 ast_log(LOG_WARNING, "%s: Channel name or unique ID required\n", function);
905 return -1;
906 }
907
908 chan_found = ast_channel_get_by_name(data);
909 snprintf(buf, maxlen, "%d", (chan_found ? 1 : 0));
910 if (chan_found) {
911 ast_channel_unref(chan_found);
912 }
913 return 0;
914}
915
917 .name = "CHANNEL_EXISTS",
918 .read = func_chan_exists_read,
919};
920
921static int func_mchan_read(struct ast_channel *chan, const char *function,
922 char *data, struct ast_str **buf, ssize_t len)
923{
924 struct ast_channel *mchan;
925 char *template = ast_alloca(4 + strlen(data));
926
927 if (!chan) {
928 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
929 return -1;
930 }
931
933 sprintf(template, "${%s}", data); /* SAFE */
934 ast_str_substitute_variables(buf, len, mchan ? mchan : chan, template);
935 if (mchan) {
936 ast_channel_unref(mchan);
937 }
938 return 0;
939}
940
941static int func_mchan_write(struct ast_channel *chan, const char *function,
942 char *data, const char *value)
943{
944 struct ast_channel *mchan;
945
946 if (!chan) {
947 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
948 return -1;
949 }
950
952 pbx_builtin_setvar_helper(mchan ? mchan : chan, data, value);
953 if (mchan) {
954 ast_channel_unref(mchan);
955 }
956 return 0;
957}
958
960 .name = "MASTER_CHANNEL",
961 .read2 = func_mchan_read,
962 .write = func_mchan_write,
963};
964
976
977static int load_module(void)
978{
979 int res = 0;
980
985
986 return res;
987}
988
989AST_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.
void ast_bridge_read_after_goto(struct ast_channel *chan, char *buffer, size_t buf_size)
Read after bridge goto if it exists.
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.
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
int ast_bridge_features_ds_set_string(struct ast_channel *chan, const char *features)
Sets the features a channel will use upon being bridged.
static int adsi
Definition chan_iax2.c:514
static int amaflags
Definition chan_iax2.c:513
static char language[MAX_LANGUAGE]
Definition chan_iax2.c:361
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition chan_iax2.c:510
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:8232
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:10676
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:2376
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:1349
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:10744
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:2983
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:1388
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:7478
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:8207
@ AST_AMA_NONE
Definition channel.h:1198
const char * ast_channel_parkinglot(const struct ast_channel *chan)
ast_channel_adsicpe
Definition channel.h:888
@ AST_ADSI_UNKNOWN
Definition channel.h:889
@ AST_ADSI_UNAVAILABLE
Definition channel.h:891
@ AST_ADSI_AVAILABLE
Definition channel.h:890
@ AST_ADSI_OFFHOOKONLY
Definition channel.h:892
const char * ast_channel_appl(const struct ast_channel *chan)
const char * ast_channel_peeraccount(const struct ast_channel *chan)
struct ast_channel * ast_channel_get_by_name(const char *search)
Find a channel by name or uniqueid.
Definition channel.c:1417
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:7711
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:446
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:2498
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:3019
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:637
enum ama_flags ast_channel_string2amaflag(const char *flag)
Convert a string to a detail record AMA flag.
Definition channel.c:4382
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:7768
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:7458
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)
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
ast_group_t ast_get_group(const char *s)
Definition channel.c:7654
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition channel.c:1380
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition channel.h:2984
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:2390
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
ast_channel_state
ast_channel states
@ 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:742
#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)
static int func_mchan_read(struct ast_channel *chan, const char *function, char *data, struct ast_str **buf, ssize_t len)
static int func_channel_write_real(struct ast_channel *chan, const char *function, char *data, const char *value)
static struct ast_custom_function channels_function
static struct ast_custom_function channel_function
static int func_channels_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
#define locked_copy_string(chan, dest, source, len)
static struct ast_custom_function mchan_function
static int func_chan_exists_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
static int load_module(void)
static int func_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value)
static int func_mchan_write(struct ast_channel *chan, const char *function, char *data, const char *value)
static int unload_module(void)
static struct ast_custom_function chan_exists_function
static const char *const transfercapability_table[0x20]
static int func_channel_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
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
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:2277
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.
struct ast_tone_zone * ast_get_indication_zone(const char *country)
locate ast_tone_zone
static struct ast_tone_zone * ast_tone_zone_ref(struct ast_tone_zone *tz)
Increase the reference count on an ast_tone_zone.
int ast_max_forwards_get(struct ast_channel *chan)
Get the current max forwards for a particular channel.
int ast_max_forwards_set(struct ast_channel *chan, int starting_count)
Set the starting max forwards for a particular channel.
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:1563
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:2233
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
Structure to describe a channel "technology", ie a channel driver See for examples:
Definition channel.h:648
const char *const type
Definition channel.h:649
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.
int value
Definition syslog.c:37
static struct test_val c
Utility functions.