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