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