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