006c0cb99a03f49f1392fa8bc06ffe5066477def
[asterisk/asterisk.git] / funcs / func_channel.c
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  *
24  * \ingroup functions
25  */
26
27 /*** MODULEINFO
28         <support_level>core</support_level>
29  ***/
30
31 #include "asterisk.h"
32
33 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
34
35 #include <regex.h>
36 #include <ctype.h>
37
38 #include "asterisk/module.h"
39 #include "asterisk/channel.h"
40 #include "asterisk/bridging.h"
41 #include "asterisk/pbx.h"
42 #include "asterisk/utils.h"
43 #include "asterisk/app.h"
44 #include "asterisk/indications.h"
45 #include "asterisk/stringfields.h"
46 #include "asterisk/global_datastores.h"
47
48 /*** DOCUMENTATION
49         <function name="CHANNELS" language="en_US">
50                 <synopsis>
51                         Gets the list of channels, optionally filtering by a regular expression.
52                 </synopsis>
53                 <syntax>
54                         <parameter name="regular_expression" />
55                 </syntax>
56                 <description>
57                         <para>Gets the list of channels, optionally filtering by a <replaceable>regular_expression</replaceable>. If
58                         no argument is provided, all known channels are returned. The
59                         <replaceable>regular_expression</replaceable> must correspond to
60                         the POSIX.2 specification, as shown in <emphasis>regex(7)</emphasis>. The list returned
61                         will be space-delimited.</para>
62                 </description>
63         </function>
64         <function name="MASTER_CHANNEL" language="en_US">
65                 <synopsis>
66                         Gets or sets variables on the master channel
67                 </synopsis>
68                 <description>
69                         <para>Allows access to the channel which created the current channel, if any.  If the channel is already
70                         a master channel, then accesses local channel variables.</para>
71                 </description>
72         </function>
73         <function name="CHANNEL" language="en_US">
74                 <synopsis>
75                         Gets/sets various pieces of information about the channel.
76                 </synopsis>
77                 <syntax>
78                         <parameter name="item" required="true">
79                                 <para>Standard items (provided by all channel technologies) are:</para>
80                                 <enumlist>
81                                         <enum name="amaflags">
82                                                 <para>R/W the Automatic Message Accounting (AMA) flags on the channel.
83                                                 When read from a channel, the integer value will always be returned.
84                                                 When written to a channel, both the string format or integer value
85                                                 is accepted.</para>
86                                                 <enumlist>
87                                                         <enum name="1"><para><literal>OMIT</literal></para></enum>
88                                                         <enum name="2"><para><literal>BILLING</literal></para></enum>
89                                                         <enum name="3"><para><literal>DOCUMENTATION</literal></para></enum>
90                                                 </enumlist>
91                                         </enum>
92                                         <enum name="accountcode">
93                                                 <para>R/W the channel's account code.</para>
94                                         </enum>
95                                         <enum name="audioreadformat">
96                                                 <para>R/O format currently being read.</para>
97                                         </enum>
98                                         <enum name="audionativeformat">
99                                                 <para>R/O format used natively for audio.</para>
100                                         </enum>
101                                         <enum name="audiowriteformat">
102                                                 <para>R/O format currently being written.</para>
103                                         </enum>
104                                         <enum name="callgroup">
105                                                 <para>R/W numeric call pickup groups that this channel is a member.</para>
106                                         </enum>
107                                         <enum name="pickupgroup">
108                                                 <para>R/W numeric call pickup groups this channel can pickup.</para>
109                                         </enum>
110                                         <enum name="namedcallgroup">
111                                                 <para>R/W named call pickup groups that this channel is a member.</para>
112                                         </enum>
113                                         <enum name="namedpickupgroup">
114                                                 <para>R/W named call pickup groups this channel can pickup.</para>
115                                         </enum>
116                                         <enum name="channeltype">
117                                                 <para>R/O technology used for channel.</para>
118                                         </enum>
119                                         <enum name="checkhangup">
120                                                 <para>R/O Whether the channel is hanging up (1/0)</para>
121                                         </enum>
122                                         <enum name="after_bridge_goto">
123                                                 <para>R/W the parseable goto string indicating where the channel is
124                                                 expected to return to in the PBX after exiting the next bridge it joins
125                                                 on the condition that it doesn't hang up. The parseable goto string uses
126                                                 the same syntax as the <literal>Goto</literal> application.</para>
127                                         </enum>
128                                         <enum name="hangup_handler_pop">
129                                                 <para>W/O Replace the most recently added hangup handler
130                                                 with a new hangup handler on the channel if supplied.  The
131                                                 assigned string is passed to the Gosub application when
132                                                 the channel is hung up.  Any optionally omitted context
133                                                 and exten are supplied by the channel pushing the handler
134                                                 before it is pushed.</para>
135                                         </enum>
136                                         <enum name="hangup_handler_push">
137                                                 <para>W/O Push a hangup handler onto the channel hangup
138                                                 handler stack.  The assigned string is passed to the
139                                                 Gosub application when the channel is hung up.  Any
140                                                 optionally omitted context and exten are supplied by the
141                                                 channel pushing the handler before it is pushed.</para>
142                                         </enum>
143                                         <enum name="hangup_handler_wipe">
144                                                 <para>W/O Wipe the entire hangup handler stack and replace
145                                                 with a new hangup handler on the channel if supplied.  The
146                                                 assigned string is passed to the Gosub application when
147                                                 the channel is hung up.  Any optionally omitted context
148                                                 and exten are supplied by the channel pushing the handler
149                                                 before it is pushed.</para>
150                                         </enum>
151                                         <enum name="language">
152                                                 <para>R/W language for sounds played.</para>
153                                         </enum>
154                                         <enum name="musicclass">
155                                                 <para>R/W class (from musiconhold.conf) for hold music.</para>
156                                         </enum>
157                                         <enum name="name">
158                                                 <para>The name of the channel</para>
159                                         </enum>
160                                         <enum name="parkinglot">
161                                                 <para>R/W parkinglot for parking.</para>
162                                         </enum>
163                                         <enum name="rxgain">
164                                                 <para>R/W set rxgain level on channel drivers that support it.</para>
165                                         </enum>
166                                         <enum name="secure_bridge_signaling">
167                                                 <para>Whether or not channels bridged to this channel require secure signaling</para>
168                                         </enum>
169                                         <enum name="secure_bridge_media">
170                                                 <para>Whether or not channels bridged to this channel require secure media</para>
171                                         </enum>
172                                         <enum name="state">
173                                                 <para>R/O state for channel</para>
174                                         </enum>
175                                         <enum name="tonezone">
176                                                 <para>R/W zone for indications played</para>
177                                         </enum>
178                                         <enum name="transfercapability">
179                                                 <para>R/W ISDN Transfer Capability, one of:</para>
180                                                 <enumlist>
181                                                         <enum name="SPEECH" />
182                                                         <enum name="DIGITAL" />
183                                                         <enum name="RESTRICTED_DIGITAL" />
184                                                         <enum name="3K1AUDIO" />
185                                                         <enum name="DIGITAL_W_TONES" />
186                                                         <enum name="VIDEO" />
187                                                 </enumlist>
188                                         </enum>
189                                         <enum name="txgain">
190                                                 <para>R/W set txgain level on channel drivers that support it.</para>
191                                         </enum>
192                                         <enum name="videonativeformat">
193                                                 <para>R/O format used natively for video</para>
194                                         </enum>
195                                         <enum name="trace">
196                                                 <para>R/W whether or not context tracing is enabled, only available
197                                                 <emphasis>if CHANNEL_TRACE is defined</emphasis>.</para>
198                                         </enum>
199                                 </enumlist>
200                                 <para><emphasis>chan_sip</emphasis> provides the following additional options:</para>
201                                 <enumlist>
202                                         <enum name="peerip">
203                                                 <para>R/O Get the IP address of the peer.</para>
204                                         </enum>
205                                         <enum name="recvip">
206                                                 <para>R/O Get the source IP address of the peer.</para>
207                                         </enum>
208                                         <enum name="from">
209                                                 <para>R/O Get the URI from the From: header.</para>
210                                         </enum>
211                                         <enum name="uri">
212                                                 <para>R/O Get the URI from the Contact: header.</para>
213                                         </enum>
214                                         <enum name="useragent">
215                                                 <para>R/O Get the useragent.</para>
216                                         </enum>
217                                         <enum name="peername">
218                                                 <para>R/O Get the name of the peer.</para>
219                                         </enum>
220                                         <enum name="t38passthrough">
221                                                 <para>R/O <literal>1</literal> if T38 is offered or enabled in this channel,
222                                                 otherwise <literal>0</literal></para>
223                                         </enum>
224                                         <enum name="rtpqos">
225                                                 <para>R/O Get QOS information about the RTP stream</para>
226                                                 <para>    This option takes two additional arguments:</para>
227                                                 <para>    Argument 1:</para>
228                                                 <para>     <literal>audio</literal>             Get data about the audio stream</para>
229                                                 <para>     <literal>video</literal>             Get data about the video stream</para>
230                                                 <para>     <literal>text</literal>              Get data about the text stream</para>
231                                                 <para>    Argument 2:</para>
232                                                 <para>     <literal>local_ssrc</literal>        Local SSRC (stream ID)</para>
233                                                 <para>     <literal>local_lostpackets</literal> Local lost packets</para>
234                                                 <para>     <literal>local_jitter</literal>      Local calculated jitter</para>
235                                                 <para>     <literal>local_maxjitter</literal>   Local calculated jitter (maximum)</para>
236                                                 <para>     <literal>local_minjitter</literal>   Local calculated jitter (minimum)</para>
237                                                 <para>     <literal>local_normdevjitter</literal>Local calculated jitter (normal deviation)</para>
238                                                 <para>     <literal>local_stdevjitter</literal> Local calculated jitter (standard deviation)</para>
239                                                 <para>     <literal>local_count</literal>       Number of received packets</para>
240                                                 <para>     <literal>remote_ssrc</literal>       Remote SSRC (stream ID)</para>
241                                                 <para>     <literal>remote_lostpackets</literal>Remote lost packets</para>
242                                                 <para>     <literal>remote_jitter</literal>     Remote reported jitter</para>
243                                                 <para>     <literal>remote_maxjitter</literal>  Remote calculated jitter (maximum)</para>
244                                                 <para>     <literal>remote_minjitter</literal>  Remote calculated jitter (minimum)</para>
245                                                 <para>     <literal>remote_normdevjitter</literal>Remote calculated jitter (normal deviation)</para>
246                                                 <para>     <literal>remote_stdevjitter</literal>Remote calculated jitter (standard deviation)</para>
247                                                 <para>     <literal>remote_count</literal>      Number of transmitted packets</para>
248                                                 <para>     <literal>rtt</literal>               Round trip time</para>
249                                                 <para>     <literal>maxrtt</literal>            Round trip time (maximum)</para>
250                                                 <para>     <literal>minrtt</literal>            Round trip time (minimum)</para>
251                                                 <para>     <literal>normdevrtt</literal>        Round trip time (normal deviation)</para>
252                                                 <para>     <literal>stdevrtt</literal>          Round trip time (standard deviation)</para>
253                                                 <para>     <literal>all</literal>               All statistics (in a form suited to logging,
254                                                 but not for parsing)</para>
255                                         </enum>
256                                         <enum name="rtpdest">
257                                                 <para>R/O Get remote RTP destination information.</para>
258                                                 <para>   This option takes one additional argument:</para>
259                                                 <para>    Argument 1:</para>
260                                                 <para>     <literal>audio</literal>             Get audio destination</para>
261                                                 <para>     <literal>video</literal>             Get video destination</para>
262                                                 <para>     <literal>text</literal>              Get text destination</para>
263                                                 <para>   Defaults to <literal>audio</literal> if unspecified.</para>
264                                         </enum>
265                                         <enum name="rtpsource">
266                                                 <para>R/O Get source RTP destination information.</para>
267                                                 <para>   This option takes one additional argument:</para>
268                                                 <para>    Argument 1:</para>
269                                                 <para>     <literal>audio</literal>             Get audio destination</para>
270                                                 <para>     <literal>video</literal>             Get video destination</para>
271                                                 <para>     <literal>text</literal>              Get text destination</para>
272                                                 <para>   Defaults to <literal>audio</literal> if unspecified.</para>
273                                         </enum>
274                                 </enumlist>
275                                 <para><emphasis>chan_iax2</emphasis> provides the following additional options:</para>
276                                 <enumlist>
277                                         <enum name="osptoken">
278                                                 <para>R/O Get the peer's osptoken.</para>
279                                         </enum>
280                                         <enum name="peerip">
281                                                 <para>R/O Get the peer's ip address.</para>
282                                         </enum>
283                                         <enum name="peername">
284                                                 <para>R/O Get the peer's username.</para>
285                                         </enum>
286                                         <enum name="secure_signaling">
287                                                 <para>R/O Get the if the IAX channel is secured.</para>
288                                         </enum>
289                                         <enum name="secure_media">
290                                                 <para>R/O Get the if the IAX channel is secured.</para>
291                                         </enum>
292                                 </enumlist>
293                                 <para><emphasis>chan_dahdi</emphasis> provides the following additional options:</para>
294                                 <enumlist>
295                                         <enum name="dahdi_channel">
296                                                 <para>R/O DAHDI channel related to this channel.</para>
297                                         </enum>
298                                         <enum name="dahdi_span">
299                                                 <para>R/O DAHDI span related to this channel.</para>
300                                         </enum>
301                                         <enum name="dahdi_type">
302                                                 <para>R/O DAHDI channel type, one of:</para>
303                                                 <enumlist>
304                                                         <enum name="analog" />
305                                                         <enum name="mfc/r2" />
306                                                         <enum name="pri" />
307                                                         <enum name="pseudo" />
308                                                         <enum name="ss7" />
309                                                 </enumlist>
310                                         </enum>
311                                         <enum name="keypad_digits">
312                                                 <para>R/O PRI Keypad digits that came in with the SETUP message.</para>
313                                         </enum>
314                                         <enum name="reversecharge">
315                                                 <para>R/O PRI Reverse Charging Indication, one of:</para>
316                                                 <enumlist>
317                                                         <enum name="-1"> <para>None</para></enum>
318                                                         <enum name=" 1"> <para>Reverse Charging Requested</para></enum>
319                                                 </enumlist>
320                                         </enum>
321                                         <enum name="no_media_path">
322                                                 <para>R/O PRI Nonzero if the channel has no B channel.
323                                                 The channel is either on hold or a call waiting call.</para>
324                                         </enum>
325                                         <enum name="buffers">
326                                                 <para>W/O Change the channel's buffer policy (for the current call only)</para>
327                                                 <para>This option takes two arguments:</para>
328                                                 <para>  Number of buffers,</para>
329                                                 <para>  Buffer policy being one of:</para>
330                                                 <para>      <literal>full</literal></para>
331                                                 <para>      <literal>immediate</literal></para>
332                                                 <para>      <literal>half</literal></para>
333                                         </enum>
334                                         <enum name="echocan_mode">
335                                                 <para>W/O Change the configuration of the active echo
336                                                 canceller on the channel (if any), for the current call
337                                                 only.</para>
338                                                 <para>Possible values are:</para>
339                                                 <para>  <literal>on</literal>   Normal mode (the echo canceller is actually reinitalized)</para>
340                                                 <para>  <literal>off</literal>  Disabled</para>
341                                                 <para>  <literal>fax</literal>  FAX/data mode (NLP disabled if possible, otherwise
342                                                         completely disabled)</para>
343                                                 <para>  <literal>voice</literal>        Voice mode (returns from FAX mode, reverting the changes that were made)</para>
344                                         </enum>
345                                 </enumlist>
346                                 <para><emphasis>chan_ooh323</emphasis> provides the following additional options:</para>
347                                 <enumlist>
348                                         <enum name="faxdetect">
349                                                 <para>R/W Fax Detect</para>
350                                                 <para>Returns 0 or 1</para>
351                                                 <para>Write yes or no</para>
352                                         </enum>
353                                         <enum name="t38support">
354                                                 <para>R/W t38support</para>
355                                                 <para>Returns 0 or 1</para>
356                                                 <para>Write yes or no</para>
357                                         </enum>
358                                         <enum name="h323id_url">
359                                                 <para>R/0 Returns caller URL</para>
360                                         </enum>
361                                         <enum name="caller_h323id">
362                                                 <para>R/0 Returns caller h323id</para>
363                                         </enum>
364                                         <enum name="caller_dialeddigits">
365                                                 <para>R/0 Returns caller dialed digits</para>
366                                         </enum>
367                                         <enum name="caller_email">
368                                                 <para>R/0 Returns caller email</para>
369                                         </enum>
370                                         <enum name="callee_email">
371                                                 <para>R/0 Returns callee email</para>
372                                         </enum>
373                                         <enum name="callee_dialeddigits">
374                                                 <para>R/0 Returns callee dialed digits</para>
375                                         </enum>
376                                         <enum name="caller_url">
377                                                 <para>R/0 Returns caller URL</para>
378                                         </enum>
379                                 </enumlist>
380                         </parameter>
381                 </syntax>
382                 <description>
383                         <para>Gets/sets various pieces of information about the channel, additional <replaceable>item</replaceable> may
384                         be available from the channel driver; see its documentation for details. Any <replaceable>item</replaceable>
385                         requested that is not available on the current channel will return an empty string.</para>
386                 </description>
387         </function>
388  ***/
389
390 #define locked_copy_string(chan, dest, source, len) \
391         do { \
392                 ast_channel_lock(chan); \
393                 ast_copy_string(dest, source, len); \
394                 ast_channel_unlock(chan); \
395         } while (0)
396 #define locked_string_field_set(chan, field, source) \
397         do { \
398                 ast_channel_lock(chan); \
399                 ast_channel_##field##_set(chan, source); \
400                 ast_channel_unlock(chan); \
401         } while (0)
402
403 static const char * const transfercapability_table[0x20] = {
404         "SPEECH", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
405         "DIGITAL", "RESTRICTED_DIGITAL", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
406         "3K1AUDIO", "DIGITAL_W_TONES", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
407         "VIDEO", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", };
408
409 static int func_channel_read(struct ast_channel *chan, const char *function,
410                              char *data, char *buf, size_t len)
411 {
412         int ret = 0;
413         struct ast_format_cap *tmpcap;
414
415         if (!strcasecmp(data, "audionativeformat")) {
416                 char tmp[512];
417
418                 if ((tmpcap = ast_format_cap_get_type(ast_channel_nativeformats(chan), AST_FORMAT_TYPE_AUDIO))) {
419                         ast_copy_string(buf, ast_getformatname_multiple(tmp, sizeof(tmp), tmpcap), len);
420                         tmpcap = ast_format_cap_destroy(tmpcap);
421                 }
422         } else if (!strcasecmp(data, "videonativeformat")) {
423                 char tmp[512];
424
425                 if ((tmpcap = ast_format_cap_get_type(ast_channel_nativeformats(chan), AST_FORMAT_TYPE_VIDEO))) {
426                         ast_copy_string(buf, ast_getformatname_multiple(tmp, sizeof(tmp), tmpcap), len);
427                         tmpcap = ast_format_cap_destroy(tmpcap);
428                 }
429         } else if (!strcasecmp(data, "audioreadformat")) {
430                 ast_copy_string(buf, ast_getformatname(ast_channel_readformat(chan)), len);
431         } else if (!strcasecmp(data, "audiowriteformat")) {
432                 ast_copy_string(buf, ast_getformatname(ast_channel_writeformat(chan)), len);
433 #ifdef CHANNEL_TRACE
434         } else if (!strcasecmp(data, "trace")) {
435                 ast_channel_lock(chan);
436                 ast_copy_string(buf, ast_channel_trace_is_enabled(chan) ? "1" : "0", len);
437                 ast_channel_unlock(chan);
438 #endif
439         } else if (!strcasecmp(data, "tonezone") && ast_channel_zone(chan))
440                 locked_copy_string(chan, buf, ast_channel_zone(chan)->country, len);
441         else if (!strcasecmp(data, "language"))
442                 locked_copy_string(chan, buf, ast_channel_language(chan), len);
443         else if (!strcasecmp(data, "musicclass"))
444                 locked_copy_string(chan, buf, ast_channel_musicclass(chan), len);
445         else if (!strcasecmp(data, "name")) {
446                 locked_copy_string(chan, buf, ast_channel_name(chan), len);
447         } else if (!strcasecmp(data, "parkinglot"))
448                 locked_copy_string(chan, buf, ast_channel_parkinglot(chan), len);
449         else if (!strcasecmp(data, "state"))
450                 locked_copy_string(chan, buf, ast_state2str(ast_channel_state(chan)), len);
451         else if (!strcasecmp(data, "channeltype"))
452                 locked_copy_string(chan, buf, ast_channel_tech(chan)->type, len);
453         else if (!strcasecmp(data, "accountcode"))
454                 locked_copy_string(chan, buf, ast_channel_accountcode(chan), len);
455         else if (!strcasecmp(data, "checkhangup")) {
456                 ast_channel_lock(chan);
457                 ast_copy_string(buf, ast_check_hangup(chan) ? "1" : "0", len);
458                 ast_channel_unlock(chan);
459         } else if (!strcasecmp(data, "peeraccount"))
460                 locked_copy_string(chan, buf, ast_channel_peeraccount(chan), len);
461         else if (!strcasecmp(data, "hangupsource"))
462                 locked_copy_string(chan, buf, ast_channel_hangupsource(chan), len);
463         else if (!strcasecmp(data, "appname") && ast_channel_appl(chan))
464                 locked_copy_string(chan, buf, ast_channel_appl(chan), len);
465         else if (!strcasecmp(data, "appdata") && ast_channel_data(chan))
466                 locked_copy_string(chan, buf, ast_channel_data(chan), len);
467         else if (!strcasecmp(data, "exten") && ast_channel_data(chan))
468                 locked_copy_string(chan, buf, ast_channel_exten(chan), len);
469         else if (!strcasecmp(data, "context") && ast_channel_data(chan))
470                 locked_copy_string(chan, buf, ast_channel_context(chan), len);
471         else if (!strcasecmp(data, "userfield") && ast_channel_data(chan))
472                 locked_copy_string(chan, buf, ast_channel_userfield(chan), len);
473         else if (!strcasecmp(data, "channame") && ast_channel_data(chan))
474                 locked_copy_string(chan, buf, ast_channel_name(chan), len);
475         else if (!strcasecmp(data, "linkedid")) {
476                 ast_channel_lock(chan);
477                 if (ast_strlen_zero(ast_channel_linkedid(chan))) {
478                         /* fall back on the channel's uniqueid if linkedid is unset */
479                         ast_copy_string(buf, ast_channel_uniqueid(chan), len);
480                 }
481                 else {
482                         ast_copy_string(buf, ast_channel_linkedid(chan), len);
483                 }
484                 ast_channel_unlock(chan);
485         } else if (!strcasecmp(data, "peer")) {
486                 struct ast_channel *p;
487
488                 ast_channel_lock(chan);
489                 p = ast_bridged_channel(chan);
490                 if (p || ast_channel_tech(chan)) /* dummy channel? if so, we hid the peer name in the language */
491                         ast_copy_string(buf, (p ? ast_channel_name(p) : ""), len);
492                 else {
493                         /* a dummy channel can still pass along bridged peer info via
494                            the BRIDGEPEER variable */
495                         const char *pname = pbx_builtin_getvar_helper(chan, "BRIDGEPEER");
496                         if (!ast_strlen_zero(pname))
497                                 ast_copy_string(buf, pname, len); /* a horrible kludge, but... how else? */
498                         else
499                                 buf[0] = 0;
500                 }
501                 ast_channel_unlock(chan);
502         } else if (!strcasecmp(data, "uniqueid")) {
503                 locked_copy_string(chan, buf, ast_channel_uniqueid(chan), len);
504         } else if (!strcasecmp(data, "transfercapability")) {
505                 locked_copy_string(chan, buf, transfercapability_table[ast_channel_transfercapability(chan) & 0x1f], len);
506         } else if (!strcasecmp(data, "callgroup")) {
507                 char groupbuf[256];
508
509                 locked_copy_string(chan, buf,  ast_print_group(groupbuf, sizeof(groupbuf), ast_channel_callgroup(chan)), len);
510         } else if (!strcasecmp(data, "pickupgroup")) {
511                 char groupbuf[256];
512
513                 locked_copy_string(chan, buf,  ast_print_group(groupbuf, sizeof(groupbuf), ast_channel_pickupgroup(chan)), len);
514         } else if (!strcasecmp(data, "namedcallgroup")) {
515                 struct ast_str *tmp_str = ast_str_alloca(1024);
516
517                 locked_copy_string(chan, buf,  ast_print_namedgroups(&tmp_str, ast_channel_named_callgroups(chan)), len);
518         } else if (!strcasecmp(data, "namedpickupgroup")) {
519                 struct ast_str *tmp_str = ast_str_alloca(1024);
520
521                 locked_copy_string(chan, buf,  ast_print_namedgroups(&tmp_str, ast_channel_named_pickupgroups(chan)), len);
522         } else if (!strcasecmp(data, "after_bridge_goto")) {
523                 ast_after_bridge_goto_read(chan, buf, len);
524         } else if (!strcasecmp(data, "amaflags")) {
525                 ast_channel_lock(chan);
526                 snprintf(buf, len, "%d", ast_channel_amaflags(chan));
527                 ast_channel_unlock(chan);
528         } else if (!strncasecmp(data, "secure_bridge_", 14)) {
529                 struct ast_datastore *ds;
530
531                 ast_channel_lock(chan);
532                 if ((ds = ast_channel_datastore_find(chan, &secure_call_info, NULL))) {
533                         struct ast_secure_call_store *encrypt = ds->data;
534                         if (!strcasecmp(data, "secure_bridge_signaling")) {
535                                 snprintf(buf, len, "%s", encrypt->signaling ? "1" : "");
536                         } else if (!strcasecmp(data, "secure_bridge_media")) {
537                                 snprintf(buf, len, "%s", encrypt->media ? "1" : "");
538                         }
539                 }
540                 ast_channel_unlock(chan);
541         } 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)) {
542                 ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n", data);
543                 ret = -1;
544         }
545
546         return ret;
547 }
548
549 static int func_channel_write_real(struct ast_channel *chan, const char *function,
550                               char *data, const char *value)
551 {
552         int ret = 0;
553         signed char gainset;
554
555         if (!strcasecmp(data, "language"))
556                 locked_string_field_set(chan, language, value);
557         else if (!strcasecmp(data, "parkinglot"))
558                 locked_string_field_set(chan, parkinglot, value);
559         else if (!strcasecmp(data, "musicclass"))
560                 locked_string_field_set(chan, musicclass, value);
561         else if (!strcasecmp(data, "accountcode"))
562                 locked_string_field_set(chan, accountcode, value);
563         else if (!strcasecmp(data, "userfield"))
564                 locked_string_field_set(chan, userfield, value);
565         else if (!strcasecmp(data, "after_bridge_goto")) {
566                 if (ast_strlen_zero(value)) {
567                         ast_after_bridge_goto_discard(chan);
568                 } else {
569                         ast_after_bridge_set_go_on(chan, ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan), value);
570                 }
571         } else if (!strcasecmp(data, "amaflags")) {
572                 ast_channel_lock(chan);
573                 if (isdigit(*value)) {
574                         int amaflags;
575                         sscanf(value, "%30d", &amaflags);
576                         ast_channel_amaflags_set(chan, amaflags);
577                 } else if (!strcasecmp(value,"OMIT")){
578                         ast_channel_amaflags_set(chan, 1);
579                 } else if (!strcasecmp(value,"BILLING")){
580                         ast_channel_amaflags_set(chan, 2);
581                 } else if (!strcasecmp(value,"DOCUMENTATION")){
582                         ast_channel_amaflags_set(chan, 3);
583                 }
584                 ast_channel_unlock(chan);
585         } else if (!strcasecmp(data, "peeraccount"))
586                 locked_string_field_set(chan, peeraccount, value);
587         else if (!strcasecmp(data, "hangupsource"))
588                 /* XXX - should we be forcing this here? */
589                 ast_set_hangupsource(chan, value, 0);
590 #ifdef CHANNEL_TRACE
591         else if (!strcasecmp(data, "trace")) {
592                 ast_channel_lock(chan);
593                 if (ast_true(value))
594                         ret = ast_channel_trace_enable(chan);
595                 else if (ast_false(value))
596                         ret = ast_channel_trace_disable(chan);
597                 else {
598                         ret = -1;
599                         ast_log(LOG_WARNING, "Invalid value for CHANNEL(trace).\n");
600                 }
601                 ast_channel_unlock(chan);
602         }
603 #endif
604         else if (!strcasecmp(data, "tonezone")) {
605                 struct ast_tone_zone *new_zone;
606                 if (!(new_zone = ast_get_indication_zone(value))) {
607                         ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", value);
608                         ret = -1;
609                 } else {
610                         ast_channel_lock(chan);
611                         if (ast_channel_zone(chan)) {
612                                 ast_channel_zone_set(chan, ast_tone_zone_unref(ast_channel_zone(chan)));
613                         }
614                         ast_channel_zone_set(chan, ast_tone_zone_ref(new_zone));
615                         ast_channel_unlock(chan);
616                         new_zone = ast_tone_zone_unref(new_zone);
617                 }
618         } else if (!strcasecmp(data, "callgroup")) {
619                 ast_channel_lock(chan);
620                 ast_channel_callgroup_set(chan, ast_get_group(value));
621                 ast_channel_unlock(chan);
622         } else if (!strcasecmp(data, "pickupgroup")) {
623                 ast_channel_lock(chan);
624                 ast_channel_pickupgroup_set(chan, ast_get_group(value));
625                 ast_channel_unlock(chan);
626         } else if (!strcasecmp(data, "namedcallgroup")) {
627                 struct ast_namedgroups *groups = ast_get_namedgroups(value);
628
629                 ast_channel_lock(chan);
630                 ast_channel_named_callgroups_set(chan, groups);
631                 ast_channel_unlock(chan);
632                 ast_unref_namedgroups(groups);
633         } else if (!strcasecmp(data, "namedpickupgroup")) {
634                 struct ast_namedgroups *groups = ast_get_namedgroups(value);
635
636                 ast_channel_lock(chan);
637                 ast_channel_named_pickupgroups_set(chan, groups);
638                 ast_channel_unlock(chan);
639                 ast_unref_namedgroups(groups);
640         } else if (!strcasecmp(data, "txgain")) {
641                 sscanf(value, "%4hhd", &gainset);
642                 ast_channel_setoption(chan, AST_OPTION_TXGAIN, &gainset, sizeof(gainset), 0);
643         } else if (!strcasecmp(data, "rxgain")) {
644                 sscanf(value, "%4hhd", &gainset);
645                 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &gainset, sizeof(gainset), 0);
646         } else if (!strcasecmp(data, "transfercapability")) {
647                 unsigned short i;
648
649                 ast_channel_lock(chan);
650                 for (i = 0; i < 0x20; i++) {
651                         if (!strcasecmp(transfercapability_table[i], value) && strcmp(value, "UNK")) {
652                                 ast_channel_transfercapability_set(chan, i);
653                                 break;
654                         }
655                 }
656                 ast_channel_unlock(chan);
657         } else if (!strcasecmp(data, "hangup_handler_pop")) {
658                 /* Pop one hangup handler before pushing the new handler. */
659                 ast_pbx_hangup_handler_pop(chan);
660                 ast_pbx_hangup_handler_push(chan, value);
661         } else if (!strcasecmp(data, "hangup_handler_push")) {
662                 ast_pbx_hangup_handler_push(chan, value);
663         } else if (!strcasecmp(data, "hangup_handler_wipe")) {
664                 /* Pop all hangup handlers before pushing the new handler. */
665                 while (ast_pbx_hangup_handler_pop(chan)) {
666                 }
667                 ast_pbx_hangup_handler_push(chan, value);
668         } else if (!strncasecmp(data, "secure_bridge_", 14)) {
669                 struct ast_datastore *ds;
670                 struct ast_secure_call_store *store;
671
672                 if (!chan || !value) {
673                         return -1;
674                 }
675
676                 ast_channel_lock(chan);
677                 if (!(ds = ast_channel_datastore_find(chan, &secure_call_info, NULL))) {
678                         if (!(ds = ast_datastore_alloc(&secure_call_info, NULL))) {
679                                 ast_channel_unlock(chan);
680                                 return -1;
681                         }
682                         if (!(store = ast_calloc(1, sizeof(*store)))) {
683                                 ast_channel_unlock(chan);
684                                 ast_free(ds);
685                                 return -1;
686                         }
687                         ds->data = store;
688                         ast_channel_datastore_add(chan, ds);
689                 } else {
690                         store = ds->data;
691                 }
692
693                 if (!strcasecmp(data, "secure_bridge_signaling")) {
694                         store->signaling = ast_true(value) ? 1 : 0;
695                 } else if (!strcasecmp(data, "secure_bridge_media")) {
696                         store->media = ast_true(value) ? 1 : 0;
697                 }
698                 ast_channel_unlock(chan);
699         } else if (!ast_channel_tech(chan)->func_channel_write
700                  || ast_channel_tech(chan)->func_channel_write(chan, function, data, value)) {
701                 ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n",
702                                 data);
703                 ret = -1;
704         }
705
706         return ret;
707 }
708
709 static int func_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value)
710 {
711         int res;
712         ast_chan_write_info_t write_info = {
713                 .version = AST_CHAN_WRITE_INFO_T_VERSION,
714                 .write_fn = func_channel_write_real,
715                 .chan = chan,
716                 .function = function,
717                 .data = data,
718                 .value = value,
719         };
720
721         res = func_channel_write_real(chan, function, data, value);
722         ast_channel_setoption(chan, AST_OPTION_CHANNEL_WRITE, &write_info, sizeof(write_info), 0);
723
724         return res;
725 }
726
727 static struct ast_custom_function channel_function = {
728         .name = "CHANNEL",
729         .read = func_channel_read,
730         .write = func_channel_write,
731 };
732
733 static int func_channels_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
734 {
735         struct ast_channel *c = NULL;
736         regex_t re;
737         int res;
738         size_t buflen = 0;
739         struct ast_channel_iterator *iter;
740
741         buf[0] = '\0';
742
743         if (!ast_strlen_zero(data)) {
744                 if ((res = regcomp(&re, data, REG_EXTENDED | REG_ICASE | REG_NOSUB))) {
745                         regerror(res, &re, buf, maxlen);
746                         ast_log(LOG_WARNING, "Error compiling regular expression for %s(%s): %s\n", function, data, buf);
747                         return -1;
748                 }
749         }
750
751         if (!(iter = ast_channel_iterator_all_new())) {
752                 if (!ast_strlen_zero(data)) {
753                         regfree(&re);
754                 }
755                 return -1;
756         }
757
758         while ((c = ast_channel_iterator_next(iter))) {
759                 ast_channel_lock(c);
760                 if (ast_strlen_zero(data) || regexec(&re, ast_channel_name(c), 0, NULL, 0) == 0) {
761                         size_t namelen = strlen(ast_channel_name(c));
762                         if (buflen + namelen + (ast_strlen_zero(buf) ? 0 : 1) + 1 < maxlen) {
763                                 if (!ast_strlen_zero(buf)) {
764                                         strcat(buf, " ");
765                                         buflen++;
766                                 }
767                                 strcat(buf, ast_channel_name(c));
768                                 buflen += namelen;
769                         } else {
770                                 ast_log(LOG_WARNING, "Number of channels exceeds the available buffer space.  Output will be truncated!\n");
771                         }
772                 }
773                 ast_channel_unlock(c);
774                 c = ast_channel_unref(c);
775         }
776
777         ast_channel_iterator_destroy(iter);
778
779         if (!ast_strlen_zero(data)) {
780                 regfree(&re);
781         }
782
783         return 0;
784 }
785
786 static struct ast_custom_function channels_function = {
787         .name = "CHANNELS",
788         .read = func_channels_read,
789 };
790
791 static int func_mchan_read(struct ast_channel *chan, const char *function,
792                              char *data, struct ast_str **buf, ssize_t len)
793 {
794         struct ast_channel *mchan = ast_channel_get_by_name(ast_channel_linkedid(chan));
795         char *template = ast_alloca(4 + strlen(data));
796         sprintf(template, "${%s}", data); /* SAFE */
797         ast_str_substitute_variables(buf, len, mchan ? mchan : chan, template);
798         if (mchan) {
799                 ast_channel_unref(mchan);
800         }
801         return 0;
802 }
803
804 static int func_mchan_write(struct ast_channel *chan, const char *function,
805                               char *data, const char *value)
806 {
807         struct ast_channel *mchan = ast_channel_get_by_name(ast_channel_linkedid(chan));
808         pbx_builtin_setvar_helper(mchan ? mchan : chan, data, value);
809         if (mchan) {
810                 ast_channel_unref(mchan);
811         }
812         return 0;
813 }
814
815 static struct ast_custom_function mchan_function = {
816         .name = "MASTER_CHANNEL",
817         .read2 = func_mchan_read,
818         .write = func_mchan_write,
819 };
820
821 static int unload_module(void)
822 {
823         int res = 0;
824
825         res |= ast_custom_function_unregister(&channel_function);
826         res |= ast_custom_function_unregister(&channels_function);
827         res |= ast_custom_function_unregister(&mchan_function);
828
829         return res;
830 }
831
832 static int load_module(void)
833 {
834         int res = 0;
835
836         res |= ast_custom_function_register(&channel_function);
837         res |= ast_custom_function_register(&channels_function);
838         res |= ast_custom_function_register(&mchan_function);
839
840         return res;
841 }
842
843 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Channel information dialplan functions");