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