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