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