git migration: Refactor the ASTERISK_FILE_VERSION macro
[asterisk/asterisk.git] / main / features_config.c
1 /*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2013, Digium, Inc.
5 *
6 * Mark Michelson <mmichelson@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19 #include "asterisk.h"
20
21 #include "asterisk/features_config.h"
22 #include "asterisk/config_options.h"
23 #include "asterisk/datastore.h"
24 #include "asterisk/channel.h"
25 #include "asterisk/pbx.h"
26 #include "asterisk/app.h"
27 #include "asterisk/cli.h"
28
29 /*** DOCUMENTATION
30         <configInfo name="features" language="en_US">
31                 <synopsis>Features Configuration</synopsis>
32                 <configFile name="features.conf">
33                         <configObject name="globals">
34                                 <synopsis>
35                                 </synopsis>
36                                 <configOption name="featuredigittimeout" default="1000">
37                                         <synopsis>Milliseconds allowed between digit presses when entering a feature code.</synopsis>
38                                 </configOption>
39                                 <configOption name="courtesytone">
40                                         <synopsis>Sound to play when automon or automixmon is activated</synopsis>
41                                 </configOption>
42                                 <configOption name="recordingfailsound">
43                                         <synopsis>Sound to play when automon or automixmon is attempted but fails to start</synopsis>
44                                 </configOption>
45                                 <configOption name="transferdigittimeout" default="3">
46                                         <synopsis>Seconds allowed between digit presses when dialing a transfer destination</synopsis>
47                                 </configOption>
48                                 <configOption name="atxfernoanswertimeout" default="15">
49                                         <synopsis>Seconds to wait for attended transfer destination to answer</synopsis>
50                                 </configOption>
51                                 <configOption name="atxferdropcall" default="no">
52                                         <synopsis>Hang up the call entirely if the attended transfer fails</synopsis>
53                                         <description>
54                                                 <para>When this option is set to <literal>no</literal>, then Asterisk will attempt to
55                                                 re-call the transferrer if the call to the transfer target fails. If the call to the
56                                                 transferrer fails, then Asterisk will wait <replaceable>atxferloopdelay</replaceable>
57                                                 milliseconds and then attempt to dial the transfer target again. This process will
58                                                 repeat until <replaceable>atxfercallbackretries</replaceable> attempts to re-call
59                                                 the transferrer have occurred.</para>
60                                                 <para>When this option is set to <literal>yes</literal>, then Asterisk will not attempt
61                                                 to re-call the transferrer if the call to the transfer target fails. Asterisk will instead
62                                                 hang up all channels involved in the transfer.</para>
63                                         </description>
64                                 </configOption>
65                                 <configOption name="atxferloopdelay" default="10">
66                                         <synopsis>Seconds to wait between attempts to re-dial transfer destination</synopsis>
67                                         <see-also><ref type="configOption">atxferdropcall</ref></see-also>
68                                 </configOption>
69                                 <configOption name="atxfercallbackretries" default="2">
70                                         <synopsis>Number of times to re-attempt dialing a transfer destination</synopsis>
71                                         <see-also><ref type="configOption">atxferdropcall</ref></see-also>
72                                 </configOption>
73                                 <configOption name="xfersound" default="beep">
74                                         <synopsis>Sound to play to during transfer and transfer-like operations.</synopsis>
75                                         <description>
76                                                 <para>This sound will play to the transferrer and transfer target channels when
77                                                 an attended transfer completes. This sound is also played to channels when performing
78                                                 an AMI <literal>Bridge</literal> action.</para>
79                                         </description>
80                                 </configOption>
81                                 <configOption name="xferfailsound" default="beeperr">
82                                         <synopsis>Sound to play to a transferee when a transfer fails</synopsis>
83                                 </configOption>
84                                 <configOption name="atxferabort" default="*1">
85                                         <synopsis>Digits to dial to abort an attended transfer attempt</synopsis>
86                                         <description>
87                                                 <para>This option is only available to the transferrer during an attended
88                                                 transfer operation. Aborting a transfer results in the transfer being cancelled and
89                                                 the original parties in the call being re-bridged.</para>
90                                         </description>
91                                 </configOption>
92                                 <configOption name="atxfercomplete" default="*2">
93                                         <synopsis>Digits to dial to complete an attended transfer</synopsis>
94                                         <description>
95                                                 <para>This option is only available to the transferrer during an attended
96                                                 transfer operation. Completing the transfer with a DTMF sequence is functionally
97                                                 equivalent to hanging up the transferrer channel during an attended transfer. The
98                                                 result is that the transfer target and transferees are bridged.</para>
99                                         </description>
100                                 </configOption>
101                                 <configOption name="atxferthreeway" default="*3">
102                                         <synopsis>Digits to dial to change an attended transfer into a three-way call</synopsis>
103                                         <description>
104                                                 <para>This option is only available to the transferrer during an attended
105                                                 transfer operation. Pressing this DTMF sequence will result in the transferrer,
106                                                 the transferees, and the transfer target all being in a single bridge together.</para>
107                                         </description>
108                                 </configOption>
109                                 <configOption name="atxferswap" default="*4">
110                                         <synopsis>Digits to dial to toggle who the transferrer is currently bridged to during an attended transfer</synopsis>
111                                         <description>
112                                                 <para>This option is only available to the transferrer during an attended
113                                                 transfer operation. Pressing this DTMF sequence will result in the transferrer swapping
114                                                 which party he is bridged with. For instance, if the transferrer is currently bridged with
115                                                 the transfer target, then pressing this DTMF sequence will cause the transferrer to be
116                                                 bridged with the transferees.</para>
117                                         </description>
118                                 </configOption>
119                                 <configOption name="pickupexten" default="*8">
120                                         <synopsis>Digits used for picking up ringing calls</synopsis>
121                                         <description>
122                                                 <para>In order for the pickup attempt to be successful, the party attempting to
123                                                 pick up the call must either have a <replaceable>namedpickupgroup</replaceable> in
124                                                 common with a ringing party's <replaceable>namedcallgroup</replaceable> or must
125                                                 have a <replaceable>pickupgroup</replaceable> in common with a ringing party's
126                                                 <replaceable>callgroup</replaceable>.</para>
127                                         </description>
128                                 </configOption>
129                                 <configOption name="pickupsound">
130                                         <synopsis>Sound to play to picker when a call is picked up</synopsis>
131                                 </configOption>
132                                 <configOption name="pickupfailsound">
133                                         <synopsis>Sound to play to picker when a call cannot be picked up</synopsis>
134                                 </configOption>
135                                 <configOption name="transferdialattempts" default="3">
136                                         <synopsis>Number of dial attempts allowed when attempting a transfer</synopsis>
137                                 </configOption>
138                                 <configOption name="transferretrysound" default="pbx-invalid">
139                                         <synopsis>Sound that is played when an incorrect extension is dialed and the transferer should try again.</synopsis>
140                                 </configOption>
141                                 <configOption name="transferinvalidsound" default="privacy-incorrect">
142                                         <synopsis>Sound that is played when an incorrect extension is dialed and the transferer has no attempts remaining.</synopsis>
143                                 </configOption>
144                         </configObject>
145                         <configObject name="featuremap">
146                                 <synopsis>DTMF options that can be triggered during bridged calls</synopsis>
147                                 <configOption name="atxfer">
148                                         <synopsis>DTMF sequence to initiate an attended transfer</synopsis>
149                                         <description>
150                                                 <para>The transferee parties will be placed on hold and the
151                                                 transferrer may dial an extension to reach a transfer target. During an
152                                                 attended transfer, the transferrer may consult with the transfer target
153                                                 before completing the transfer. Once the transferrer has hung up or pressed
154                                                 the <replaceable>atxfercomplete</replaceable> DTMF sequence, then the transferees
155                                                 and transfer target will be bridged.</para>
156                                         </description>
157                                 </configOption>
158                                 <configOption name="blindxfer" default="#">
159                                         <synopsis>DTMF sequence to initiate a blind transfer</synopsis>
160                                         <description>
161                                                 <para>The transferee parties will be placed on hold and the
162                                                 transferrer may dial an extension to reach a transfer target. During a
163                                                 blind transfer, as soon as the transfer target is dialed, the transferrer
164                                                 is hung up.</para>
165                                         </description>
166                                 </configOption>
167                                 <configOption name="disconnect" default="*">
168                                         <synopsis>DTMF sequence to disconnect the current call</synopsis>
169                                         <description>
170                                                 <para>Entering this DTMF sequence will cause the bridge to end, no
171                                                 matter the number of parties present</para>
172                                         </description>
173                                 </configOption>
174                                 <configOption name="parkcall">
175                                         <synopsis>DTMF sequence to park a call</synopsis>
176                                         <description>
177                                                 <para>The parking lot used to park the call is determined by using either the
178                                                 <replaceable>PARKINGLOT</replaceable> channel variable or a configured value on
179                                                 the channel (provided by the channel driver) if the variable is not present. If
180                                                 no configured value on the channel is present, then <literal>"default"</literal>
181                                                 is used. The call is parked in the next available space in the parking lot.</para>
182                                         </description>
183                                 </configOption>
184                                 <configOption name="automon">
185                                         <synopsis>DTMF sequence to start or stop monitoring a call</synopsis>
186                                         <description>
187                                                 <para>This will cause the channel that pressed the DTMF sequence
188                                                 to be monitored by the <literal>Monitor</literal> application. The
189                                                 format for the recording is determined by the <replaceable>TOUCH_MONITOR_FORMAT</replaceable>
190                                                 channel variable. If this variable is not specified, then <literal>wav</literal> is the
191                                                 default. The filename is constructed in the following manner:</para>
192
193                                                 <para>    prefix-timestamp-filename</para>
194
195                                                 <para>where prefix is either the value of the <replaceable>TOUCH_MONITOR_PREFIX</replaceable>
196                                                 channel variable or <literal>auto</literal> if the variable is not set. The timestamp
197                                                 is a UNIX timestamp. The filename is either the value of the <replaceable>TOUCH_MONITOR</replaceable>
198                                                 channel variable or the callerID of the channels if the variable is not set.</para>
199                                         </description>
200                                 </configOption>
201                                 <configOption name="automixmon">
202                                         <synopsis>DTMF sequence to start or stop mixmonitoring a call </synopsis>
203                                         <description>
204                                                 <para>Operation of the automixmon is similar to the <literal> automon </literal>
205                                                 feature, with the following exceptions:
206                                                         <replaceable>TOUCH_MIXMONITOR</replaceable> is used in place of <replaceable>TOUCH_MONITOR</replaceable>
207                                                         <replaceable>TOUCH_MIXMONITOR_FORMAT</replaceable> is used in place of <replaceable>TOUCH_MIXMONITOR</replaceable>
208                                                         There is no equivalent for <replaceable>TOUCH_MONITOR_PREFIX</replaceable>. <literal>"auto"</literal> is always how the filename begins.</para>
209                                         </description>
210                                         <see-also><ref type="configOption">automon</ref></see-also>
211                                 </configOption>
212                         </configObject>
213                         <configObject name="applicationmap">
214                                 <synopsis>Section for defining custom feature invocations during a call</synopsis>
215                                 <description>
216                                         <para>The applicationmap is an area where new custom features can be created. Items
217                                         defined in the applicationmap are not automatically accessible to bridged parties. Access
218                                         to the individual items is controled using the <replaceable>DYNAMIC_FEATURES</replaceable> channel variable.
219                                         The <replaceable>DYNAMIC_FEATURES</replaceable> is a <literal>#</literal> separated list of
220                                         either applicationmap item names or featuregroup names.</para>
221                                 </description>
222                                 <configOption name="^.*$" regex="true">
223                                         <synopsis>A custom feature to invoke during a bridged call</synopsis>
224                                         <description>
225                                                 <para>Each item listed here is a comma-separated list of parameters that determine
226                                                 how a feature may be invoked during a call</para>
227                                                 <para>    Example:</para>
228                                                 <para>    eggs = *5,self,Playback(hello-world),default</para>
229                                                 <para>This would create a feature called <literal>eggs</literal> that could be invoked
230                                                 during a call by pressing the <literal>*5</literal>. The party that presses the DTMF
231                                                 sequence would then trigger the <literal>Playback</literal> application to play the
232                                                 <literal>hello-world</literal> file. The application invocation would happen on the
233                                                 party that pressed the DTMF sequence since <literal>self</literal> is specified. The
234                                                 other parties in the bridge would hear the <literal>default</literal> music on hold
235                                                 class during the playback.</para>
236                                                 <para>In addition to the syntax outlined in this documentation, a backwards-compatible alternative
237                                                 is also allowed. The following applicationmap lines are functionally identical:</para>
238                                                 <para>    eggs = *5,self,Playback(hello-world),default</para>
239                                                 <para>    eggs = *5,self,Playback,hello-world,default</para>
240                                                 <para>    eggs = *5,self,Playback,"hello-world",default</para>
241                                         </description>
242                                         <syntax argsep=",">
243                                                 <parameter name="dtmf" required="true">
244                                                         <para>The DTMF sequence used to trigger the option</para>
245                                                 </parameter>
246                                                 <parameter name="activate_on" required="true">
247                                                         <para>The party that the feature will be invoked on</para>
248                                                         <optionlist>
249                                                                 <option name="self"><para>Feature is invoked on party that presses the DTMF sequence</para></option>
250                                                                 <option name="peer"><para>Feature is invoked on other parties in the bridge</para></option>
251                                                         </optionlist>
252                                                 </parameter>
253                                                 <parameter name="app" required="true">
254                                                         <para>The dialplan application to run when the DTMF sequence is pressed</para>
255                                                         <argument name="app_args" required="false">
256                                                                 <para>The arguments to the dialplan application to run</para>
257                                                         </argument>
258                                                 </parameter>
259                                                 <parameter name="moh_class" required="false">
260                                                         <para>Music on hold class to play to bridge participants that are not the target of the application invocation</para>
261                                                 </parameter>
262                                         </syntax>
263                                 </configOption>
264                         </configObject>
265                         <configObject name="featuregroup">
266                                 <synopsis>Groupings of items from the applicationmap</synopsis>
267                                 <description>
268                                         <para>Feature groups allow for multiple applicationmap items to be
269                                         grouped together. Like with individual applicationmap items, feature groups
270                                         can be part of the <replaceable>DYNAMIC_FEATURES</replaceable> channel variable.
271                                         In addition to creating groupings, the feature group section allows for the
272                                         DTMF sequence used to invoke an applicationmap item to be overridden with
273                                         a different sequence.</para>
274                                 </description>
275                                 <configOption name="^.*$" regex="true">
276                                         <synopsis>Applicationmap item to place in the feature group</synopsis>
277                                         <description>
278                                                 <para>Each item here must be a name of an item in the applicationmap. The
279                                                 argument may either be a new DTMF sequence to use for the item or it
280                                                 may be left blank in order to use the DTMF sequence specified in the
281                                                 applicationmap. For example:</para>
282                                                 <para>  eggs => *1</para>
283                                                 <para>  bacon =></para>
284                                                 <para>would result in the applicationmap items <literal>eggs</literal> and
285                                                 <literal>bacon</literal> being in the featuregroup. The former would have its
286                                                 default DTMF trigger overridden with <literal>*1</literal> and the latter would
287                                                 have the DTMF value specified in the applicationmap.</para>
288                                         </description>
289                                 </configOption>
290                         </configObject>
291                 </configFile>
292         </configInfo>
293         <function name="FEATURE" language="en_US">
294                 <synopsis>
295                         Get or set a feature option on a channel.
296                 </synopsis>
297                 <syntax>
298                         <parameter name="option_name" required="true">
299                                 <para>The allowed values are:</para>
300                                 <enumlist>
301                                         <enum name="inherit"><para>Inherit feature settings made in FEATURE or FEATUREMAP to child channels.</para></enum>
302                                         <enum name="featuredigittimeout"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='featuredigittimeout']/synopsis/text())" /></para></enum>
303                                         <enum name="transferdigittimeout"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='transferdigittimeout']/synopsis/text())" /></para></enum>
304                                         <enum name="atxfernoanswertimeout"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='atxfernoanswertimeout']/synopsis/text())" /></para></enum>
305                                         <enum name="atxferdropcall"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='atxferdropcall']/synopsis/text())" /></para></enum>
306                                         <enum name="atxferloopdelay"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='atxferloopdelay']/synopsis/text())" /></para></enum>
307                                         <enum name="atxfercallbackretries"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='atxfercallbackretries']/synopsis/text())" /></para></enum>
308                                         <enum name="xfersound"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='xfersound']/synopsis/text())" /></para></enum>
309                                         <enum name="xferfailsound"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='xferfailsound']/synopsis/text())" /></para></enum>
310                                         <enum name="atxferabort"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='atxferabort']/synopsis/text())" /></para></enum>
311                                         <enum name="atxfercomplete"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='atxfercomplete']/synopsis/text())" /></para></enum>
312                                         <enum name="atxferthreeway"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='atxferthreeway']/synopsis/text())" /></para></enum>
313                                         <enum name="pickupexten"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='pickupexten']/synopsis/text())" /></para></enum>
314                                         <enum name="pickupsound"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='pickupsound']/synopsis/text())" /></para></enum>
315                                         <enum name="pickupfailsound"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='pickupfailsound']/synopsis/text())" /></para></enum>
316                                         <enum name="courtesytone"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='courtesytone']/synopsis/text())" /></para></enum>
317                                         <enum name="recordingfailsound"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='recordingfailsound']/synopsis/text())" /></para></enum>
318                                         <enum name="transferdialattempts"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='transferdialattempts']/synopsis/text())" /></para></enum>
319                                         <enum name="transferretrysound"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='transferretrysound']/synopsis/text())" /></para></enum>
320                                         <enum name="transferinvalidsound"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='transferinvalidsound']/synopsis/text())" /></para></enum>
321                                 </enumlist>
322                         </parameter>
323                 </syntax>
324                 <description>
325                         <para>When this function is used as a read, it will get the current
326                         value of the specified feature option for this channel.  It will be
327                         the value of this option configured in features.conf if a channel specific
328                         value has not been set.  This function can also be used to set a channel
329                         specific value for the supported feature options.</para>
330                 </description>
331                 <see-also>
332                         <ref type="function">FEATUREMAP</ref>
333                 </see-also>
334         </function>
335         <function name="FEATUREMAP" language="en_US">
336                 <synopsis>
337                         Get or set a feature map to a given value on a specific channel.
338                 </synopsis>
339                 <syntax>
340                         <parameter name="feature_name" required="true">
341                                 <para>The allowed values are:</para>
342                                 <enumlist>
343                                         <enum name="atxfer"><para>Attended Transfer</para></enum>
344                                         <enum name="blindxfer"><para>Blind Transfer</para></enum>
345                                         <enum name="automon"><para>Auto Monitor</para></enum>
346                                         <enum name="disconnect"><para>Call Disconnect</para></enum>
347                                         <enum name="parkcall"><para>Park Call</para></enum>
348                                         <enum name="automixmon"><para>Auto MixMonitor</para></enum>
349                                 </enumlist>
350                         </parameter>
351                 </syntax>
352                 <description>
353                         <para>When this function is used as a read, it will get the current
354                         digit sequence mapped to the specified feature for this channel.  This
355                         value will be the one configured in features.conf if a channel specific
356                         value has not been set.  This function can also be used to set a channel
357                         specific value for a feature mapping.</para>
358                 </description>
359                 <see-also>
360                         <ref type="function">FEATURE</ref>
361                 </see-also>
362         </function>
363  ***/
364 /*! Default general options */
365 #define DEFAULT_FEATURE_DIGIT_TIMEOUT               1000
366 #define DEFAULT_COURTESY_TONE                       ""
367 #define DEFAULT_RECORDING_FAIL_SOUND                ""
368
369 /*! Default xfer options */
370 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT              3
371 #define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER  15
372 #define DEFAULT_ATXFER_DROP_CALL                    0
373 #define DEFAULT_ATXFER_LOOP_DELAY                   10
374 #define DEFAULT_ATXFER_CALLBACK_RETRIES             2
375 #define DEFAULT_XFERSOUND                           "beep"
376 #define DEFAULT_XFERFAILSOUND                       "beeperr"
377 #define DEFAULT_ATXFER_ABORT                        "*1"
378 #define DEFAULT_ATXFER_COMPLETE                     "*2"
379 #define DEFAULT_ATXFER_THREEWAY                     "*3"
380 #define DEFAULT_ATXFER_SWAP                         "*4"
381 #define DEFAULT_TRANSFER_DIAL_ATTEMPTS              3
382 #define DEFAULT_TRANSFER_RETRY_SOUND                "pbx-invalid"
383 #define DEFAULT_TRANSFER_INVALID_SOUND              "privacy-incorrect"
384
385 /*! Default pickup options */
386 #define DEFAULT_PICKUPEXTEN                         "*8"
387 #define DEFAULT_PICKUPSOUND                         ""
388 #define DEFAULT_PICKUPFAILSOUND                     ""
389
390 /*! Default featuremap options */
391 #define DEFAULT_FEATUREMAP_BLINDXFER                "#"
392 #define DEFAULT_FEATUREMAP_DISCONNECT               "*"
393 #define DEFAULT_FEATUREMAP_AUTOMON                  ""
394 #define DEFAULT_FEATUREMAP_ATXFER                   ""
395 #define DEFAULT_FEATUREMAP_PARKCALL                 ""
396 #define DEFAULT_FEATUREMAP_AUTOMIXMON               ""
397
398 /*!
399  * \brief Configuration from the "general" section of features.conf
400  */
401 struct features_global_config {
402         struct ast_features_general_config *general;
403         struct ast_features_xfer_config *xfer;
404         struct ast_features_pickup_config *pickup;
405 };
406
407 static void ast_applicationmap_item_destructor(void *obj)
408 {
409         struct ast_applicationmap_item *item = obj;
410
411         ast_string_field_free_memory(item);
412 }
413
414 static int applicationmap_sort(const void *obj, const void *arg, int flags)
415 {
416         const struct ast_applicationmap_item *item1 = obj;
417         const struct ast_applicationmap_item *item2;
418         const char *key2;
419
420         switch(flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
421         case OBJ_KEY:
422                 key2 = arg;
423                 return strcasecmp(item1->name, key2);
424         case OBJ_PARTIAL_KEY:
425                 key2 = arg;
426                 return strncasecmp(item1->name, key2, strlen(key2));
427         default:
428         case OBJ_POINTER:
429                 item2 = arg;
430                 return strcasecmp(item1->name, item2->name);
431         }
432 }
433
434 /*!
435  * \brief Entry in the container of featuregroups
436  */
437 struct featuregroup_item {
438         AST_DECLARE_STRING_FIELDS(
439                 /*! The name of the applicationmap item that we are referring to */
440                 AST_STRING_FIELD(appmap_item_name);
441                 /*! Custom DTMF override to use instead of the default for the applicationmap item */
442                 AST_STRING_FIELD(dtmf_override);
443         );
444         /*! The applicationmap item that is being referred to */
445         struct ast_applicationmap_item *appmap_item;
446 };
447
448 static void featuregroup_item_destructor(void *obj)
449 {
450         struct featuregroup_item *item = obj;
451
452         ast_string_field_free_memory(item);
453         ao2_cleanup(item->appmap_item);
454 }
455
456 static int group_item_sort(const void *obj, const void *arg, int flags)
457 {
458         const struct featuregroup_item *item1 = obj;
459         const struct featuregroup_item *item2;
460         const char *key2;
461
462         switch(flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
463         case OBJ_KEY:
464                 key2 = arg;
465                 return strcasecmp(item1->appmap_item_name, key2);
466         case OBJ_PARTIAL_KEY:
467                 key2 = arg;
468                 return strncasecmp(item1->appmap_item_name, key2, strlen(key2));
469         case OBJ_POINTER:
470                 item2 = arg;
471                 return strcasecmp(item1->appmap_item_name, item2->appmap_item_name);
472         default:
473                 return CMP_STOP;
474         }
475 }
476
477 /*!
478  * \brief Featuregroup representation
479  */
480 struct featuregroup {
481         /*! The name of the featuregroup */
482         const char *name;
483         /*! A container of featuregroup_items */
484         struct ao2_container *items;
485 };
486
487 static int featuregroup_hash(const void *obj, int flags)
488 {
489         const struct featuregroup *group;
490         const char *key;
491
492         switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
493         case OBJ_KEY:
494                 key = obj;
495                 return ast_str_case_hash(key);
496         case OBJ_PARTIAL_KEY:
497                 ast_assert(0);
498                 return 0;
499         case OBJ_POINTER:
500         default:
501                 group = obj;
502                 return ast_str_case_hash(group->name);
503         }
504 }
505
506 static int featuregroup_cmp(void *obj, void *arg, int flags)
507 {
508         struct featuregroup *group1 = obj;
509         struct featuregroup *group2;
510         const char *key2;
511
512         switch(flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
513         case OBJ_KEY:
514                 key2 = arg;
515                 return strcasecmp(group1->name, key2) ? 0 : CMP_MATCH;
516         case OBJ_PARTIAL_KEY:
517                 key2 = arg;
518                 return strncasecmp(group1->name, key2, strlen(key2)) ? 0 : CMP_MATCH;
519         case OBJ_POINTER:
520                 group2 = arg;
521                 return strcasecmp(group1->name, group2->name) ? 0 : CMP_MATCH;
522         default:
523                 return CMP_STOP;
524         }
525 }
526
527 static void *featuregroup_find(struct ao2_container *group_container, const char *category)
528 {
529         return ao2_find(group_container, category, OBJ_KEY);
530 }
531
532 static void featuregroup_destructor(void *obj)
533 {
534         struct featuregroup *group = obj;
535
536         ast_free((char *) group->name);
537         ao2_cleanup(group->items);
538 }
539
540 static void *featuregroup_alloc(const char *cat)
541 {
542         struct featuregroup *group;
543
544         group = ao2_alloc(sizeof(*group), featuregroup_destructor);
545         if (!group) {
546                 return NULL;
547         }
548
549         group->name = ast_strdup(cat);
550         if (!group->name) {
551                 ao2_cleanup(group);
552                 return NULL;
553         }
554
555         group->items = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK,
556                 AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, group_item_sort, NULL);
557         if (!group->items) {
558                 ao2_cleanup(group);
559                 return NULL;
560         }
561
562         return group;
563 }
564
565 /* Used for deprecated parking configuration */
566 struct dummy_config {
567         char dummy;
568 };
569
570 struct features_config {
571         struct features_global_config *global;
572         struct ast_featuremap_config *featuremap;
573         struct dummy_config *parkinglots;
574         struct ao2_container *applicationmap;
575         struct ao2_container *featuregroups;
576 };
577
578 static struct aco_type global_option = {
579         .type = ACO_GLOBAL,
580         .name = "globals",
581         .category_match = ACO_WHITELIST,
582         .category = "^general$",
583         .item_offset = offsetof(struct features_config, global),
584 };
585
586 static struct aco_type featuremap_option = {
587         .type = ACO_GLOBAL,
588         .name = "featuremap",
589         .category_match = ACO_WHITELIST,
590         .category = "^featuremap$",
591         .item_offset = offsetof(struct features_config, featuremap),
592 };
593
594 static struct aco_type applicationmap_option = {
595         .type = ACO_GLOBAL,
596         .name = "applicationmap",
597         .category_match = ACO_WHITELIST,
598         .category = "^applicationmap$",
599         .item_offset = offsetof(struct features_config, applicationmap),
600 };
601
602 static struct aco_type featuregroup_option = {
603         .type = ACO_ITEM,
604         .name = "featuregroup",
605         .category_match = ACO_BLACKLIST,
606         .category = "^(general|featuremap|applicationmap|parkinglot_.*)$",
607         .item_offset = offsetof(struct features_config, featuregroups),
608         .item_alloc = featuregroup_alloc,
609         .item_find = featuregroup_find,
610 };
611
612 static struct aco_type parkinglot_option = {
613         .type = ACO_GLOBAL,
614         .name = "parkinglot",
615         .category_match = ACO_WHITELIST,
616         .category = "^parkinglot_.*$",
617         .item_offset = offsetof(struct features_config, parkinglots),
618         .hidden = 1,
619 };
620
621 static struct aco_type *global_options[] = ACO_TYPES(&global_option);
622 static struct aco_type *featuremap_options[] = ACO_TYPES(&featuremap_option);
623 static struct aco_type *applicationmap_options[] = ACO_TYPES(&applicationmap_option);
624 static struct aco_type *featuregroup_options[] = ACO_TYPES(&featuregroup_option);
625 static struct aco_type *parkinglot_options[] = ACO_TYPES(&parkinglot_option);
626
627 static struct aco_file features_conf = {
628         .filename = "features.conf",
629         .types = ACO_TYPES(&global_option, &featuremap_option, &applicationmap_option, &featuregroup_option, &parkinglot_option),
630 };
631
632 AO2_GLOBAL_OBJ_STATIC(globals);
633
634 static void features_config_destructor(void *obj)
635 {
636         struct features_config *cfg = obj;
637
638         ao2_cleanup(cfg->global);
639         ao2_cleanup(cfg->featuremap);
640         ao2_cleanup(cfg->parkinglots);
641         ao2_cleanup(cfg->applicationmap);
642         ao2_cleanup(cfg->featuregroups);
643 }
644
645 static void featuremap_config_destructor(void *obj)
646 {
647         struct ast_featuremap_config *cfg = obj;
648
649         ast_string_field_free_memory(cfg);
650 }
651
652 static void global_config_destructor(void *obj)
653 {
654         struct features_global_config *cfg = obj;
655
656         ao2_cleanup(cfg->general);
657         ao2_cleanup(cfg->xfer);
658         ao2_cleanup(cfg->pickup);
659 }
660
661 static void general_destructor(void *obj)
662 {
663         struct ast_features_general_config *cfg = obj;
664
665         ast_string_field_free_memory(cfg);
666 }
667
668 static void xfer_destructor(void *obj)
669 {
670         struct ast_features_xfer_config *cfg = obj;
671
672         ast_string_field_free_memory(cfg);
673 }
674
675 static void pickup_destructor(void *obj)
676 {
677         struct ast_features_pickup_config *cfg = obj;
678
679         ast_string_field_free_memory(cfg);
680 }
681
682 static struct features_global_config *global_config_alloc(void)
683 {
684         RAII_VAR(struct features_global_config *, cfg, NULL, ao2_cleanup);
685
686         cfg = ao2_alloc(sizeof(*cfg), global_config_destructor);
687         if (!cfg) {
688                 return NULL;
689         }
690
691         cfg->general = ao2_alloc(sizeof(*cfg->general), general_destructor);
692         if (!cfg->general || ast_string_field_init(cfg->general, 32)) {
693                 return NULL;
694         }
695
696         cfg->xfer = ao2_alloc(sizeof(*cfg->xfer), xfer_destructor);
697         if (!cfg->xfer || ast_string_field_init(cfg->xfer, 32)) {
698                 return NULL;
699         }
700
701         cfg->pickup = ao2_alloc(sizeof(*cfg->pickup), pickup_destructor);
702         if (!cfg->pickup || ast_string_field_init(cfg->pickup, 32)) {
703                 return NULL;
704         }
705
706         ao2_ref(cfg, +1);
707         return cfg;
708 }
709
710 static struct ao2_container *applicationmap_alloc(int replace_duplicates)
711 {
712         return ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK,
713                 replace_duplicates ? AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE : AO2_CONTAINER_ALLOC_OPT_DUPS_ALLOW,
714                 applicationmap_sort, NULL);
715 }
716
717 /*!
718  * \internal
719  * \brief Allocate the major configuration structure
720  *
721  * The parameter is used to determine if the applicationmap and featuregroup
722  * structures should be allocated. We only want to allocate these structures for
723  * the global features_config structure. For the datastores on channels, we don't
724  * need to allocate these structures because they are not used.
725  *
726  * \param allocate_applicationmap See previous explanation
727  * \retval NULL Failed to alloate configuration
728  * \retval non-NULL Allocated configuration
729  */
730 static struct features_config *__features_config_alloc(int allocate_applicationmap)
731 {
732         RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
733
734         cfg = ao2_alloc(sizeof(*cfg), features_config_destructor);
735         if (!cfg) {
736                 return NULL;
737         }
738
739         cfg->global = global_config_alloc();
740         if (!cfg->global) {
741                 return NULL;
742         }
743
744         cfg->featuremap = ao2_alloc(sizeof(*cfg->featuremap), featuremap_config_destructor);
745         if (!cfg->featuremap || ast_string_field_init(cfg->featuremap, 32)) {
746                 return NULL;
747         }
748
749         cfg->parkinglots = ao2_alloc(sizeof(*cfg->parkinglots), NULL);
750         if (!cfg->parkinglots) {
751                 return NULL;
752         }
753
754         if (allocate_applicationmap) {
755                 cfg->applicationmap = applicationmap_alloc(1);
756                 if (!cfg->applicationmap) {
757                         return NULL;
758                 }
759
760                 cfg->featuregroups = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, 11, featuregroup_hash,
761                         featuregroup_cmp);
762                 if (!cfg->featuregroups) {
763                         return NULL;
764                 }
765         }
766
767         ao2_ref(cfg, +1);
768         return cfg;
769
770 }
771
772 static void *features_config_alloc(void)
773 {
774         return __features_config_alloc(1);
775 }
776
777 static void general_copy(struct ast_features_general_config *dest, const struct ast_features_general_config *src)
778 {
779         ast_string_fields_copy(dest, src);
780         dest->featuredigittimeout = src->featuredigittimeout;
781 }
782
783 static void xfer_copy(struct ast_features_xfer_config *dest, const struct ast_features_xfer_config *src)
784 {
785         ast_string_fields_copy(dest, src);
786         dest->transferdigittimeout = src->transferdigittimeout;
787         dest->atxfernoanswertimeout = src->atxfernoanswertimeout;
788         dest->atxferloopdelay = src->atxferloopdelay;
789         dest->atxfercallbackretries = src->atxfercallbackretries;
790         dest->atxferdropcall = src->atxferdropcall;
791         dest->transferdialattempts = src->transferdialattempts;
792 }
793
794 static void pickup_copy(struct ast_features_pickup_config *dest, const struct ast_features_pickup_config *src)
795 {
796         ast_string_fields_copy(dest, src);
797 }
798
799 static void global_copy(struct features_global_config *dest, const struct features_global_config *src)
800 {
801         general_copy(dest->general, src->general);
802         xfer_copy(dest->xfer, src->xfer);
803         pickup_copy(dest->pickup, src->pickup);
804 }
805
806 static void featuremap_copy(struct ast_featuremap_config *dest, const struct ast_featuremap_config *src)
807 {
808         ast_string_fields_copy(dest, src);
809 }
810
811 static void features_copy(struct features_config *dest, const struct features_config *src)
812 {
813         global_copy(dest->global, src->global);
814         featuremap_copy(dest->featuremap, src->featuremap);
815
816         /* applicationmap and featuregroups are purposely not copied. A channel's applicationmap
817          * is produced on the fly when ast_get_chan_applicationmap() is called
818          * NOTE: This does not apply to the global cfg->applicationmap and cfg->featuresgroups
819          */
820 }
821
822 static struct features_config *features_config_dup(const struct features_config *orig)
823 {
824         struct features_config *dup;
825
826         dup = __features_config_alloc(0);
827         if (!dup) {
828                 return NULL;
829         }
830
831         features_copy(dup, orig);
832
833         return dup;
834 }
835
836 static int general_set(struct ast_features_general_config *general, const char *name,
837                 const char *value)
838 {
839         int res = 0;
840
841         if (!strcasecmp(name, "featuredigittimeout")) {
842                 res = ast_parse_arg(value, PARSE_INT32, &general->featuredigittimeout);
843         } else if (!strcasecmp(name, "courtesytone")) {
844                 ast_string_field_set(general, courtesytone, value);
845         } else if (!strcasecmp(name, "recordingfailsound")) {
846                 ast_string_field_set(general, recordingfailsound, value);
847         } else {
848                 /* Unrecognized option */
849                 res = -1;
850         }
851
852         return res;
853 }
854
855 static int general_get(struct ast_features_general_config *general, const char *field,
856                 char *buf, size_t len)
857 {
858         int res = 0;
859
860         if (!strcasecmp(field, "featuredigittimeout")) {
861                 snprintf(buf, len, "%u", general->featuredigittimeout);
862         } else if (!strcasecmp(field, "courtesytone")) {
863                 ast_copy_string(buf, general->courtesytone, len);
864         } else if (!strcasecmp(field, "recordingfailsound")) {
865                 ast_copy_string(buf, general->recordingfailsound, len);
866         } else {
867                 /* Unrecognized option */
868                 res = -1;
869         }
870
871         return res;
872 }
873
874 static int xfer_set(struct ast_features_xfer_config *xfer, const char *name,
875                 const char *value)
876 {
877         int res = 0;
878
879         if (!strcasecmp(name, "transferdigittimeout")) {
880                 res = ast_parse_arg(value, PARSE_INT32, &xfer->transferdigittimeout);
881         } else if (!strcasecmp(name, "atxfernoanswertimeout")) {
882                 res = ast_parse_arg(value, PARSE_INT32, &xfer->atxfernoanswertimeout);
883         } else if (!strcasecmp(name, "atxferloopdelay")) {
884                 res = ast_parse_arg(value, PARSE_INT32, &xfer->atxferloopdelay);
885         } else if (!strcasecmp(name, "atxfercallbackretries")) {
886                 res = ast_parse_arg(value, PARSE_INT32, &xfer->atxfercallbackretries);
887         } else if (!strcasecmp(name, "atxferdropcall")) {
888                 xfer->atxferdropcall = ast_true(value);
889         } else if (!strcasecmp(name, "xfersound")) {
890                 ast_string_field_set(xfer, xfersound, value);
891         } else if (!strcasecmp(name, "xferfailsound")) {
892                 ast_string_field_set(xfer, xferfailsound, value);
893         } else if (!strcasecmp(name, "atxferabort")) {
894                 ast_string_field_set(xfer, atxferabort, value);
895         } else if (!strcasecmp(name, "atxfercomplete")) {
896                 ast_string_field_set(xfer, atxfercomplete, value);
897         } else if (!strcasecmp(name, "atxferthreeway")) {
898                 ast_string_field_set(xfer, atxferthreeway, value);
899         } else if (!strcasecmp(name, "atxferswap")) {
900                 ast_string_field_set(xfer, atxferswap, value);
901         } else if (!strcasecmp(name, "transferdialattempts")) {
902                 res = ast_parse_arg(value, PARSE_INT32, &xfer->transferdialattempts);
903         } else if (!strcasecmp(name, "transferretrysound")) {
904                 ast_string_field_set(xfer, transferretrysound, value);
905         } else if (!strcasecmp(name, "transferinvalidsound")) {
906                 ast_string_field_set(xfer, transferinvalidsound, value);
907         } else {
908                 /* Unrecognized option */
909                 res = -1;
910         }
911
912         return res;
913 }
914
915 static int xfer_get(struct ast_features_xfer_config *xfer, const char *field,
916                 char *buf, size_t len)
917 {
918         int res = 0;
919
920         if (!strcasecmp(field, "transferdigittimeout")) {
921                 snprintf(buf, len, "%u", xfer->transferdigittimeout);
922         } else if (!strcasecmp(field, "atxfernoanswertimeout")) {
923                 snprintf(buf, len, "%u", xfer->atxfernoanswertimeout);
924         } else if (!strcasecmp(field, "atxferloopdelay")) {
925                 snprintf(buf, len, "%u", xfer->atxferloopdelay);
926         } else if (!strcasecmp(field, "atxfercallbackretries")) {
927                 snprintf(buf, len, "%u", xfer->atxfercallbackretries);
928         } else if (!strcasecmp(field, "atxferdropcall")) {
929                 snprintf(buf, len, "%u", xfer->atxferdropcall);
930         } else if (!strcasecmp(field, "xfersound")) {
931                 ast_copy_string(buf, xfer->xfersound, len);
932         } else if (!strcasecmp(field, "xferfailsound")) {
933                 ast_copy_string(buf, xfer->xferfailsound, len);
934         } else if (!strcasecmp(field, "atxferabort")) {
935                 ast_copy_string(buf, xfer->atxferabort, len);
936         } else if (!strcasecmp(field, "atxfercomplete")) {
937                 ast_copy_string(buf, xfer->atxfercomplete, len);
938         } else if (!strcasecmp(field, "atxferthreeway")) {
939                 ast_copy_string(buf, xfer->atxferthreeway, len);
940         } else if (!strcasecmp(field, "atxferswap")) {
941                 ast_copy_string(buf, xfer->atxferswap, len);
942         } else if (!strcasecmp(field, "transferdialattempts")) {
943                 snprintf(buf, len, "%u", xfer->transferdialattempts);
944         } else if (!strcasecmp(field, "transferretrysound")) {
945                 ast_copy_string(buf, xfer->transferretrysound, len);
946         } else if (!strcasecmp(field, "transferinvalidsound")) {
947                 ast_copy_string(buf, xfer->transferinvalidsound, len);
948         } else {
949                 /* Unrecognized option */
950                 res = -1;
951         }
952
953         return res;
954 }
955
956 static int pickup_set(struct ast_features_pickup_config *pickup, const char *name,
957                 const char *value)
958 {
959         int res = 0;
960
961         if (!strcasecmp(name, "pickupsound")) {
962                 ast_string_field_set(pickup, pickupsound, value);
963         } else if (!strcasecmp(name, "pickupfailsound")) {
964                 ast_string_field_set(pickup, pickupfailsound, value);
965         } else if (!strcasecmp(name, "pickupexten")) {
966                 ast_string_field_set(pickup, pickupexten, value);
967         } else {
968                 /* Unrecognized option */
969                 res = -1;
970         }
971
972         return res;
973 }
974
975 static int pickup_get(struct ast_features_pickup_config *pickup, const char *field,
976                 char *buf, size_t len)
977 {
978         int res = 0;
979
980         if (!strcasecmp(field, "pickupsound")) {
981                 ast_copy_string(buf, pickup->pickupsound, len);
982         } else if (!strcasecmp(field, "pickupfailsound")) {
983                 ast_copy_string(buf, pickup->pickupfailsound, len);
984         } else if (!strcasecmp(field, "pickupexten")) {
985                 ast_copy_string(buf, pickup->pickupexten, len);
986         } else {
987                 /* Unrecognized option */
988                 res = -1;
989         }
990
991         return res;
992 }
993
994 static int featuremap_set(struct ast_featuremap_config *featuremap, const char *name,
995                 const char *value)
996 {
997         int res = 0;
998
999         if (!strcasecmp(name, "blindxfer")) {
1000                 ast_string_field_set(featuremap, blindxfer, value);
1001         } else if (!strcasecmp(name, "disconnect")) {
1002                 ast_string_field_set(featuremap, disconnect, value);
1003         } else if (!strcasecmp(name, "automon")) {
1004                 ast_string_field_set(featuremap, automon, value);
1005         } else if (!strcasecmp(name, "atxfer")) {
1006                 ast_string_field_set(featuremap, atxfer, value);
1007         } else if (!strcasecmp(name, "automixmon")) {
1008                 ast_string_field_set(featuremap, automixmon, value);
1009         } else if (!strcasecmp(name, "parkcall")) {
1010                 ast_string_field_set(featuremap, parkcall, value);
1011         } else {
1012                 /* Unrecognized option */
1013                 res = -1;
1014         }
1015
1016         return res;
1017 }
1018
1019 static int featuremap_get(struct ast_featuremap_config *featuremap, const char *field,
1020                 char *buf, size_t len)
1021 {
1022         int res = 0;
1023
1024         if (!strcasecmp(field, "blindxfer")) {
1025                 ast_copy_string(buf, featuremap->blindxfer, len);
1026         } else if (!strcasecmp(field, "disconnect")) {
1027                 ast_copy_string(buf, featuremap->disconnect, len);
1028         } else if (!strcasecmp(field, "automon")) {
1029                 ast_copy_string(buf, featuremap->automon, len);
1030         } else if (!strcasecmp(field, "atxfer")) {
1031                 ast_copy_string(buf, featuremap->atxfer, len);
1032         } else if (!strcasecmp(field, "automixmon")) {
1033                 ast_copy_string(buf, featuremap->automixmon, len);
1034         } else if (!strcasecmp(field, "parkcall")) {
1035                 ast_copy_string(buf, featuremap->parkcall, len);
1036         } else {
1037                 /* Unrecognized option */
1038                 res = -1;
1039         }
1040
1041         return res;
1042 }
1043
1044 static void feature_ds_destroy(void *data)
1045 {
1046         struct features_config *cfg = data;
1047         ao2_cleanup(cfg);
1048 }
1049
1050 static void *feature_ds_duplicate(void *data)
1051 {
1052         struct features_config *old_cfg = data;
1053
1054         return features_config_dup(old_cfg);
1055 }
1056
1057 static const struct ast_datastore_info feature_ds_info = {
1058         .type = "FEATURE",
1059         .destroy = feature_ds_destroy,
1060         .duplicate = feature_ds_duplicate,
1061 };
1062
1063 /*!
1064  * \internal
1065  * \brief Find or create feature datastore on a channel
1066  *
1067  * \pre chan is locked
1068  *
1069  * \return the data on the FEATURE datastore, or NULL on error
1070  */
1071 static struct features_config *get_feature_ds(struct ast_channel *chan)
1072 {
1073         RAII_VAR(struct features_config *, orig, NULL, ao2_cleanup);
1074         struct features_config *cfg;
1075         struct ast_datastore *ds;
1076
1077         if ((ds = ast_channel_datastore_find(chan, &feature_ds_info, NULL))) {
1078                 cfg = ds->data;
1079                 ao2_ref(cfg, +1);
1080                 return cfg;
1081         }
1082
1083         orig = ao2_global_obj_ref(globals);
1084         if (!orig) {
1085                 return NULL;
1086         }
1087
1088         cfg = features_config_dup(orig);
1089         if (!cfg) {
1090                 return NULL;
1091         }
1092
1093         if (!(ds = ast_datastore_alloc(&feature_ds_info, NULL))) {
1094                 ao2_cleanup(cfg);
1095                 return NULL;
1096         }
1097
1098         /* Give the datastore a reference to the config */
1099         ao2_ref(cfg, +1);
1100         ds->data = cfg;
1101
1102         ast_channel_datastore_add(chan, ds);
1103
1104         return cfg;
1105 }
1106
1107 static struct ast_datastore *get_feature_chan_ds(struct ast_channel *chan)
1108 {
1109         struct ast_datastore *ds;
1110
1111         if (!(ds = ast_channel_datastore_find(chan, &feature_ds_info, NULL))) {
1112                 /* Hasn't been created yet.  Trigger creation. */
1113                 ao2_cleanup(get_feature_ds(chan));
1114
1115                 ds = ast_channel_datastore_find(chan, &feature_ds_info, NULL);
1116         }
1117
1118         return ds;
1119 }
1120
1121 struct ast_features_general_config *ast_get_chan_features_general_config(struct ast_channel *chan)
1122 {
1123         RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
1124
1125         if (chan) {
1126                 cfg = get_feature_ds(chan);
1127         } else {
1128                 cfg = ao2_global_obj_ref(globals);
1129         }
1130
1131         if (!cfg) {
1132                 return NULL;
1133         }
1134
1135         ast_assert(cfg->global && cfg->global->general);
1136
1137         ao2_ref(cfg->global->general, +1);
1138         return cfg->global->general;
1139 }
1140
1141 struct ast_features_xfer_config *ast_get_chan_features_xfer_config(struct ast_channel *chan)
1142 {
1143         RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
1144
1145         if (chan) {
1146                 cfg = get_feature_ds(chan);
1147         } else {
1148                 cfg = ao2_global_obj_ref(globals);
1149         }
1150
1151         if (!cfg) {
1152                 return NULL;
1153         }
1154
1155         ast_assert(cfg->global && cfg->global->xfer);
1156
1157         ao2_ref(cfg->global->xfer, +1);
1158         return cfg->global->xfer;
1159 }
1160
1161 struct ast_features_pickup_config *ast_get_chan_features_pickup_config(struct ast_channel *chan)
1162 {
1163         RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
1164
1165         if (chan) {
1166                 cfg = get_feature_ds(chan);
1167         } else {
1168                 cfg = ao2_global_obj_ref(globals);
1169         }
1170
1171         if (!cfg) {
1172                 return NULL;
1173         }
1174
1175         ast_assert(cfg->global && cfg->global->pickup);
1176
1177         ao2_ref(cfg->global->pickup, +1);
1178         return cfg->global->pickup;
1179 }
1180
1181 struct ast_featuremap_config *ast_get_chan_featuremap_config(struct ast_channel *chan)
1182 {
1183         RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
1184
1185         if (chan) {
1186                 cfg = get_feature_ds(chan);
1187         } else {
1188                 cfg = ao2_global_obj_ref(globals);
1189         }
1190
1191         if (!cfg) {
1192                 return NULL;
1193         }
1194
1195         ast_assert(cfg->featuremap != NULL);
1196
1197         ao2_ref(cfg->featuremap, +1);
1198         return cfg->featuremap;
1199 }
1200
1201 int ast_get_builtin_feature(struct ast_channel *chan, const char *feature, char *buf, size_t len)
1202 {
1203         RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
1204
1205         if (chan) {
1206                 cfg = get_feature_ds(chan);
1207         } else {
1208                 cfg = ao2_global_obj_ref(globals);
1209         }
1210
1211         if (!cfg) {
1212                 return -1;
1213         }
1214
1215         return featuremap_get(cfg->featuremap, feature, buf, len);
1216 }
1217
1218 int ast_get_feature(struct ast_channel *chan, const char *feature, char *buf, size_t len)
1219 {
1220         RAII_VAR(struct ao2_container *, applicationmap, NULL, ao2_cleanup);
1221         RAII_VAR(struct ast_applicationmap_item *, item, NULL, ao2_cleanup);
1222
1223         if (!ast_get_builtin_feature(chan, feature, buf, len)) {
1224                 return 0;
1225         }
1226
1227         /* Dang, must be in the application map */
1228         applicationmap = ast_get_chan_applicationmap(chan);
1229         if (!applicationmap) {
1230                 return -1;
1231         }
1232
1233         item = ao2_find(applicationmap, feature, OBJ_KEY);
1234         if (!item) {
1235                 return -1;
1236         }
1237
1238         ast_copy_string(buf, item->dtmf, len);
1239         return 0;
1240 }
1241
1242 static struct ast_applicationmap_item *applicationmap_item_alloc(const char *name,
1243                 const char *app, const char *app_data, const char *moh_class, const char *dtmf,
1244                 unsigned int activate_on_self)
1245 {
1246         struct ast_applicationmap_item *item;
1247
1248         item = ao2_alloc(sizeof(*item), ast_applicationmap_item_destructor);
1249
1250         if (!item || ast_string_field_init(item, 64)) {
1251                 return NULL;
1252         }
1253
1254         ast_string_field_set(item, name, name);
1255         ast_string_field_set(item, app, app);
1256         ast_string_field_set(item, app_data, app_data);
1257         ast_string_field_set(item, moh_class, moh_class);
1258         ast_copy_string(item->dtmf, dtmf, sizeof(item->dtmf));
1259         item->activate_on_self = activate_on_self;
1260
1261         return item;
1262 }
1263
1264 static int add_item(void *obj, void *arg, int flags)
1265 {
1266         struct featuregroup_item *fg_item = obj;
1267         struct ao2_container *applicationmap = arg;
1268         RAII_VAR(struct ast_applicationmap_item *, appmap_item, NULL, ao2_cleanup);
1269
1270         /* If there's no DTMF override, then we can just link
1271          * the applicationmap item directly. Otherwise, we need
1272          * to create a copy with the DTMF override in place and
1273          * link that instead
1274          */
1275         if (ast_strlen_zero(fg_item->dtmf_override)) {
1276                 ao2_ref(fg_item->appmap_item, +1);
1277                 appmap_item = fg_item->appmap_item;
1278         } else {
1279                 appmap_item = applicationmap_item_alloc(fg_item->appmap_item_name,
1280                                 fg_item->appmap_item->app, fg_item->appmap_item->app_data,
1281                                 fg_item->appmap_item->moh_class, fg_item->dtmf_override,
1282                                 fg_item->appmap_item->activate_on_self);
1283         }
1284
1285         if (!appmap_item) {
1286                 return 0;
1287         }
1288
1289         ao2_link(applicationmap, appmap_item);
1290         return 0;
1291 }
1292
1293 struct ao2_container *ast_get_chan_applicationmap(struct ast_channel *chan)
1294 {
1295         RAII_VAR(struct features_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
1296         struct ao2_container *applicationmap;
1297         char *group_names;
1298         char *name;
1299
1300         if (!cfg) {
1301                 return NULL;
1302         }
1303
1304         if (!chan) {
1305                 if (!cfg->applicationmap || ao2_container_count(cfg->applicationmap) == 0) {
1306                         return NULL;
1307                 }
1308                 ao2_ref(cfg->applicationmap, +1);
1309                 return cfg->applicationmap;
1310         }
1311
1312         group_names = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES"), ""));
1313         if (ast_strlen_zero(group_names)) {
1314                 return NULL;
1315         }
1316
1317         applicationmap = applicationmap_alloc(0);
1318         if (!applicationmap) {
1319                 return NULL;
1320         }
1321
1322         /* global config must be initialized */
1323         ast_assert(cfg->featuregroups != NULL);
1324         ast_assert(cfg->applicationmap != NULL);
1325         while ((name = strsep(&group_names, "#"))) {
1326                 RAII_VAR(struct featuregroup *, group, ao2_find(cfg->featuregroups, name, OBJ_KEY), ao2_cleanup);
1327
1328                 if (!group) {
1329                         RAII_VAR(struct ast_applicationmap_item *, item, ao2_find(cfg->applicationmap, name, OBJ_KEY), ao2_cleanup);
1330
1331                         if (item) {
1332                                 ao2_link(applicationmap, item);
1333                         } else {
1334                                 ast_log(LOG_WARNING, "Unknown DYNAMIC_FEATURES item '%s' on channel %s.\n",
1335                                         name, ast_channel_name(chan));
1336                         }
1337                 } else {
1338                         ao2_callback(group->items, 0, add_item, applicationmap);
1339                 }
1340         }
1341
1342         if (ao2_container_count(applicationmap) == 0) {
1343                 ao2_cleanup(applicationmap);
1344                 return NULL;
1345         }
1346
1347         return applicationmap;
1348 }
1349
1350 static int applicationmap_handler(const struct aco_option *opt,
1351                 struct ast_variable *var, void *obj)
1352 {
1353         RAII_VAR(struct ast_applicationmap_item *, item, NULL, ao2_cleanup);
1354         struct ao2_container *applicationmap = obj;
1355         AST_DECLARE_APP_ARGS(args,
1356                 AST_APP_ARG(dtmf);
1357                 AST_APP_ARG(activate_on);
1358                 AST_APP_ARG(app);
1359                 AST_APP_ARG(app_data);
1360                 AST_APP_ARG(moh_class);
1361         );
1362         char *parse = ast_strdupa(var->value);
1363         char *slash;
1364         char *paren;
1365         unsigned int activate_on_self;
1366
1367         AST_STANDARD_APP_ARGS(args, parse);
1368
1369         if (ast_strlen_zero(args.dtmf) ||
1370                         ast_strlen_zero(args.activate_on) ||
1371                         ast_strlen_zero(args.app)) {
1372                 ast_log(LOG_WARNING, "Invalid applicationmap syntax for '%s'. Missing required argument\n", var->name);
1373                 return -1;
1374         }
1375
1376         /* features.conf used to have an "activated_by" portion
1377          * in addition to activate_on. Get rid of whatever may be
1378          * there
1379          */
1380         slash = strchr(args.activate_on, '/');
1381         if (slash) {
1382                 *slash = '\0';
1383         }
1384
1385         /* Some applications do not require arguments. */
1386         if (!args.app_data) {
1387                 args.app_data = "";
1388         }
1389
1390         /* Two syntaxes allowed for applicationmap:
1391          * Old: foo = *1,self,NoOp,Boo!,default
1392          * New: foo = *1,self,NoOp(Boo!),default
1393          *
1394          * We need to handle both
1395          */
1396         paren = strchr(args.app, '(');
1397         if (paren) {
1398                 /* New syntax */
1399                 char *close_paren;
1400
1401                 args.moh_class = args.app_data;
1402                 *paren++ = '\0';
1403                 close_paren = strrchr(paren, ')');
1404                 if (close_paren) {
1405                         *close_paren = '\0';
1406                 }
1407                 args.app_data = paren;
1408
1409                 /* Re-check that the application is not empty */
1410                 if (ast_strlen_zero(args.app)) {
1411                         ast_log(LOG_WARNING, "Applicationmap item '%s' does not contain an application name.\n", var->name);
1412                         return -1;
1413                 }
1414         } else if (strchr(args.app_data, '"')) {
1415                 args.app_data = ast_strip_quoted(args.app_data, "\"", "\"");
1416         }
1417
1418         /* Allow caller and callee to be specified for backwards compatibility */
1419         if (!strcasecmp(args.activate_on, "self") || !strcasecmp(args.activate_on, "caller")) {
1420                 activate_on_self = 1;
1421         } else if (!strcasecmp(args.activate_on, "peer") || !strcasecmp(args.activate_on, "callee")) {
1422                 activate_on_self = 0;
1423         } else {
1424                 ast_log(LOG_WARNING, "Invalid 'activate_on' value %s for applicationmap item %s\n",
1425                         args.activate_on, var->name);
1426                 return -1;
1427         }
1428
1429         ast_debug(1, "Allocating applicationmap item: dtmf = %s, app = %s, app_data = %s, moh_class = %s\n",
1430                         args.dtmf, args.app, args.app_data, args.moh_class);
1431
1432         item = applicationmap_item_alloc(var->name, args.app, args.app_data,
1433                         args.moh_class, args.dtmf, activate_on_self);
1434
1435         if (!item) {
1436                 return -1;
1437         }
1438
1439         if (!ao2_link(applicationmap, item)) {
1440                 return -1;
1441         }
1442
1443         return 0;
1444 }
1445
1446 static int featuregroup_handler(const struct aco_option *opt,
1447                 struct ast_variable *var, void *obj)
1448 {
1449         RAII_VAR(struct featuregroup_item *, item, NULL, ao2_cleanup);
1450         struct featuregroup *group = obj;
1451
1452         item = ao2_alloc(sizeof(*item), featuregroup_item_destructor);
1453         if (!item || ast_string_field_init(item, 32)) {
1454                 return -1;
1455         }
1456
1457         ast_string_field_set(item, appmap_item_name, var->name);
1458         ast_string_field_set(item, dtmf_override, var->value);
1459
1460         if (!ao2_link(group->items, item)) {
1461                 return -1;
1462         }
1463
1464         /* We wait to look up the application map item in the preapply callback */
1465
1466         return 0;
1467 }
1468
1469 static int general_handler(const struct aco_option *opt,
1470                 struct ast_variable *var, void *obj)
1471 {
1472         struct features_global_config *global = obj;
1473         struct ast_features_general_config *general = global->general;
1474
1475         return general_set(general, var->name, var->value);
1476 }
1477
1478 static int xfer_handler(const struct aco_option *opt,
1479                 struct ast_variable *var, void *obj)
1480 {
1481         struct features_global_config *global = obj;
1482         struct ast_features_xfer_config *xfer = global->xfer;
1483
1484         return xfer_set(xfer, var->name, var->value);
1485 }
1486
1487 static int pickup_handler(const struct aco_option *opt,
1488                 struct ast_variable *var, void *obj)
1489 {
1490         struct features_global_config *global = obj;
1491         struct ast_features_pickup_config *pickup = global->pickup;
1492
1493         return pickup_set(pickup, var->name, var->value);
1494 }
1495
1496 static int parking_warning = 0;
1497 static int unsupported_handler(const struct aco_option *opt,
1498                 struct ast_variable *var, void *obj)
1499 {
1500         if (!parking_warning) {
1501                 ast_log(LOG_WARNING, "Parkinglots are no longer configurable in features.conf; "
1502                         "parking is now handled by res_parking.conf\n");
1503                 parking_warning = 1;
1504         }
1505         ast_log(LOG_WARNING, "The option '%s' is no longer configurable in features.conf.\n", var->name);
1506         return 0;
1507 }
1508
1509 static int featuremap_handler(const struct aco_option *opt,
1510                 struct ast_variable *var, void *obj)
1511 {
1512         struct ast_featuremap_config *featuremap = obj;
1513
1514         return featuremap_set(featuremap, var->name, var->value);
1515 }
1516
1517 static int check_featuregroup_item(void *obj, void *arg, void *data, int flags)
1518 {
1519         struct ast_applicationmap_item *appmap_item;
1520         struct featuregroup_item *fg_item = obj;
1521         int *err = arg;
1522         struct ao2_container *applicationmap = data;
1523
1524         appmap_item = ao2_find(applicationmap, fg_item->appmap_item_name, OBJ_KEY);
1525         if (!appmap_item) {
1526                 *err = 1;
1527                 return CMP_STOP;
1528         }
1529
1530         fg_item->appmap_item = appmap_item;
1531
1532         return 0;
1533 }
1534
1535 static int check_featuregroup(void *obj, void *arg, void *data, int flags)
1536 {
1537         struct featuregroup *group = obj;
1538         int *err = arg;
1539
1540         ao2_callback_data(group->items, 0, check_featuregroup_item, arg, data);
1541
1542         if (*err) {
1543                 ast_log(LOG_WARNING, "Featuregroup %s refers to non-existent applicationmap item\n",
1544                                 group->name);
1545         }
1546
1547         return *err ? CMP_STOP : 0;
1548 }
1549
1550 static int features_pre_apply_config(void);
1551
1552 CONFIG_INFO_CORE("features", cfg_info, globals, features_config_alloc,
1553         .files = ACO_FILES(&features_conf),
1554         .pre_apply_config = features_pre_apply_config,
1555 );
1556
1557 static int features_pre_apply_config(void)
1558 {
1559         struct features_config *cfg = aco_pending_config(&cfg_info);
1560         int err = 0;
1561
1562         /* Now that the entire config has been processed, we can check that the featuregroup
1563          * items refer to actual applicationmap items.
1564          */
1565
1566         /* global config must be initialized */
1567         ast_assert(cfg->featuregroups != NULL);
1568         ast_assert(cfg->applicationmap != NULL);
1569         ao2_callback_data(cfg->featuregroups, 0, check_featuregroup, &err, cfg->applicationmap);
1570
1571         return err;
1572 }
1573
1574 static int internal_feature_read(struct ast_channel *chan, const char *cmd, char *data,
1575                char *buf, size_t len)
1576 {
1577         int res;
1578         RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
1579         SCOPED_CHANNELLOCK(lock, chan);
1580
1581         if (!strcasecmp(data, "inherit")) {
1582                 struct ast_datastore *ds = get_feature_chan_ds(chan);
1583                 unsigned int inherit = ds ? ds->inheritance : 0;
1584
1585                 snprintf(buf, len, "%s", inherit ? "yes" : "no");
1586                 return 0;
1587         }
1588
1589         cfg = get_feature_ds(chan);
1590         if (!cfg) {
1591                 return -1;
1592         }
1593
1594         res = general_get(cfg->global->general, data, buf, len) &&
1595                 xfer_get(cfg->global->xfer, data, buf, len) &&
1596                 pickup_get(cfg->global->pickup, data, buf, len);
1597
1598         if (res) {
1599                 ast_log(LOG_WARNING, "Invalid argument '%s' to FEATURE()\n", data);
1600         }
1601
1602         return res;
1603 }
1604
1605 static int internal_feature_write(struct ast_channel *chan, const char *cmd, char *data,
1606                 const char *value)
1607 {
1608         int res;
1609         RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
1610         SCOPED_CHANNELLOCK(lock, chan);
1611
1612         if (!strcasecmp(data, "inherit")) {
1613                 struct ast_datastore *ds = get_feature_chan_ds(chan);
1614                 if (ds) {
1615                         ds->inheritance = ast_true(value) ? DATASTORE_INHERIT_FOREVER : 0;
1616                 }
1617                 return 0;
1618         }
1619
1620         if (!(cfg = get_feature_ds(chan))) {
1621                 return -1;
1622         }
1623
1624         res = general_set(cfg->global->general, data, value) &&
1625                 xfer_set(cfg->global->xfer, data, value) &&
1626                 pickup_set(cfg->global->pickup, data, value);
1627
1628         if (res) {
1629                 ast_log(LOG_WARNING, "Invalid argument '%s' to FEATURE()\n", data);
1630         }
1631
1632         return res;
1633 }
1634
1635 static int internal_featuremap_read(struct ast_channel *chan, const char *cmd, char *data,
1636                char *buf, size_t len)
1637 {
1638         int res;
1639         SCOPED_CHANNELLOCK(lock, chan);
1640
1641         res = ast_get_builtin_feature(chan, data, buf, len);
1642
1643         if (res) {
1644                 ast_log(LOG_WARNING, "Invalid argument '%s' to FEATUREMAP()\n", data);
1645         }
1646
1647         return res;
1648 }
1649
1650 static int internal_featuremap_write(struct ast_channel *chan, const char *cmd, char *data,
1651                 const char *value)
1652 {
1653         int res;
1654         RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
1655         SCOPED_CHANNELLOCK(lock, chan);
1656
1657         if (!(cfg = get_feature_ds(chan))) {
1658                 return -1;
1659         }
1660
1661         res = featuremap_set(cfg->featuremap, data, value);
1662         if (res) {
1663                 ast_log(LOG_WARNING, "Invalid argument '%s' to FEATUREMAP()\n", data);
1664                 return -1;
1665         }
1666
1667         return 0;
1668 }
1669
1670 static int feature_read(struct ast_channel *chan, const char *cmd, char *data,
1671                 char *buf, size_t len)
1672 {
1673         if (!chan) {
1674                 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1675                 return -1;
1676         }
1677
1678         return internal_feature_read(chan, cmd, data, buf, len);
1679 }
1680
1681 static int feature_write(struct ast_channel *chan, const char *cmd, char *data,
1682                 const char *value)
1683 {
1684         if (!chan) {
1685                 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1686                 return -1;
1687         }
1688
1689         return internal_feature_write(chan, cmd, data, value);
1690 }
1691
1692 static int featuremap_read(struct ast_channel *chan, const char *cmd, char *data,
1693                 char *buf, size_t len)
1694 {
1695         if (!chan) {
1696                 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1697                 return -1;
1698         }
1699
1700         return internal_featuremap_read(chan, cmd, data, buf, len);
1701 }
1702
1703 static int featuremap_write(struct ast_channel *chan, const char *cmd, char *data,
1704                 const char *value)
1705 {
1706         if (!chan) {
1707                 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1708                 return -1;
1709         }
1710
1711         return internal_featuremap_write(chan, cmd, data, value);
1712 }
1713
1714 static struct ast_custom_function feature_function = {
1715         .name = "FEATURE",
1716         .read = feature_read,
1717         .write = feature_write
1718 };
1719
1720 static struct ast_custom_function featuremap_function = {
1721         .name = "FEATUREMAP",
1722         .read = featuremap_read,
1723         .write = featuremap_write
1724 };
1725
1726 static int load_config(void)
1727 {
1728         if (aco_info_init(&cfg_info)) {
1729                 ast_log(LOG_ERROR, "Unable to initialize configuration info for features\n");
1730                 return -1;
1731         }
1732
1733         aco_option_register_custom(&cfg_info, "featuredigittimeout", ACO_EXACT, global_options,
1734                         __stringify(DEFAULT_FEATURE_DIGIT_TIMEOUT), general_handler, 0);
1735         aco_option_register_custom(&cfg_info, "recordingfailsound", ACO_EXACT, global_options,
1736                         DEFAULT_RECORDING_FAIL_SOUND, general_handler, 0);
1737         aco_option_register_custom(&cfg_info, "courtesytone", ACO_EXACT, global_options,
1738                         DEFAULT_COURTESY_TONE, general_handler, 0);
1739
1740         aco_option_register_custom(&cfg_info, "transferdigittimeout", ACO_EXACT, global_options,
1741                         __stringify(DEFAULT_TRANSFER_DIGIT_TIMEOUT), xfer_handler, 0)
1742         aco_option_register_custom(&cfg_info, "atxfernoanswertimeout", ACO_EXACT, global_options,
1743                         __stringify(DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER), xfer_handler, 0);
1744         aco_option_register_custom(&cfg_info, "atxferdropcall", ACO_EXACT, global_options,
1745                         __stringify(DEFAULT_ATXFER_DROP_CALL), xfer_handler, 0);
1746         aco_option_register_custom(&cfg_info, "atxferloopdelay", ACO_EXACT, global_options,
1747                         __stringify(DEFAULT_ATXFER_LOOP_DELAY), xfer_handler, 0);
1748         aco_option_register_custom(&cfg_info, "atxfercallbackretries", ACO_EXACT, global_options,
1749                         __stringify(DEFAULT_ATXFER_CALLBACK_RETRIES), xfer_handler, 0);
1750         aco_option_register_custom(&cfg_info, "xfersound", ACO_EXACT, global_options,
1751                         DEFAULT_XFERSOUND, xfer_handler, 0);
1752         aco_option_register_custom(&cfg_info, "xferfailsound", ACO_EXACT, global_options,
1753                         DEFAULT_XFERFAILSOUND, xfer_handler, 0);
1754         aco_option_register_custom(&cfg_info, "atxferabort", ACO_EXACT, global_options,
1755                         DEFAULT_ATXFER_ABORT, xfer_handler, 0);
1756         aco_option_register_custom(&cfg_info, "atxfercomplete", ACO_EXACT, global_options,
1757                         DEFAULT_ATXFER_COMPLETE, xfer_handler, 0);
1758         aco_option_register_custom(&cfg_info, "atxferthreeway", ACO_EXACT, global_options,
1759                         DEFAULT_ATXFER_THREEWAY, xfer_handler, 0);
1760         aco_option_register_custom(&cfg_info, "atxferswap", ACO_EXACT, global_options,
1761                         DEFAULT_ATXFER_SWAP, xfer_handler, 0);
1762         aco_option_register_custom(&cfg_info, "transferdialattempts", ACO_EXACT, global_options,
1763                         __stringify(DEFAULT_TRANSFER_DIAL_ATTEMPTS), xfer_handler, 0);
1764         aco_option_register_custom(&cfg_info, "transferretrysound", ACO_EXACT, global_options,
1765                         DEFAULT_TRANSFER_RETRY_SOUND, xfer_handler, 0);
1766         aco_option_register_custom(&cfg_info, "transferinvalidsound", ACO_EXACT, global_options,
1767                         DEFAULT_TRANSFER_INVALID_SOUND, xfer_handler, 0);
1768
1769         aco_option_register_custom(&cfg_info, "pickupexten", ACO_EXACT, global_options,
1770                         DEFAULT_PICKUPEXTEN, pickup_handler, 0);
1771         aco_option_register_custom(&cfg_info, "pickupsound", ACO_EXACT, global_options,
1772                         DEFAULT_PICKUPSOUND, pickup_handler, 0);
1773         aco_option_register_custom(&cfg_info, "pickupfailsound", ACO_EXACT, global_options,
1774                         DEFAULT_PICKUPFAILSOUND, pickup_handler, 0);
1775
1776         aco_option_register_custom_nodoc(&cfg_info, "context", ACO_EXACT, global_options,
1777                         "", unsupported_handler, 0);
1778         aco_option_register_custom_nodoc(&cfg_info, "parkext", ACO_EXACT, global_options,
1779                         "", unsupported_handler, 0);
1780         aco_option_register_custom_nodoc(&cfg_info, "parkext_exclusive", ACO_EXACT, global_options,
1781                         "", unsupported_handler, 0);
1782         aco_option_register_custom_nodoc(&cfg_info, "parkinghints", ACO_EXACT, global_options,
1783                         "", unsupported_handler, 0);
1784         aco_option_register_custom_nodoc(&cfg_info, "parkedmusicclass", ACO_EXACT, global_options,
1785                         "", unsupported_handler, 0);
1786         aco_option_register_custom_nodoc(&cfg_info, "parkingtime", ACO_EXACT, global_options,
1787                         "", unsupported_handler, 0);
1788         aco_option_register_custom_nodoc(&cfg_info, "parkpos", ACO_EXACT, global_options,
1789                         "", unsupported_handler, 0);
1790         aco_option_register_custom_nodoc(&cfg_info, "findslot", ACO_EXACT, global_options,
1791                         "", unsupported_handler, 0);
1792         aco_option_register_custom_nodoc(&cfg_info, "parkedcalltransfers", ACO_EXACT, global_options,
1793                         "", unsupported_handler, 0);
1794         aco_option_register_custom_nodoc(&cfg_info, "parkedcallreparking", ACO_EXACT, global_options,
1795                         "", unsupported_handler, 0);
1796         aco_option_register_custom_nodoc(&cfg_info, "parkedcallhangup", ACO_EXACT, global_options,
1797                         "", unsupported_handler, 0);
1798         aco_option_register_custom_nodoc(&cfg_info, "parkedcallrecording", ACO_EXACT, global_options,
1799                         "", unsupported_handler, 0);
1800         aco_option_register_custom_nodoc(&cfg_info, "comebackcontext", ACO_EXACT, global_options,
1801                         "", unsupported_handler, 0);
1802         aco_option_register_custom_nodoc(&cfg_info, "comebacktoorigin", ACO_EXACT, global_options,
1803                         "", unsupported_handler, 0);
1804         aco_option_register_custom_nodoc(&cfg_info, "comebackdialtime", ACO_EXACT, global_options,
1805                         "", unsupported_handler, 0);
1806         aco_option_register_custom_nodoc(&cfg_info, "parkeddynamic", ACO_EXACT, global_options,
1807                         "", unsupported_handler, 0);
1808         aco_option_register_custom_nodoc(&cfg_info, "adsipark", ACO_EXACT, global_options,
1809                         "", unsupported_handler, 0);
1810
1811         aco_option_register_custom(&cfg_info, "blindxfer", ACO_EXACT, featuremap_options,
1812                         DEFAULT_FEATUREMAP_BLINDXFER, featuremap_handler, 0);
1813         aco_option_register_custom(&cfg_info, "disconnect", ACO_EXACT, featuremap_options,
1814                         DEFAULT_FEATUREMAP_DISCONNECT, featuremap_handler, 0);
1815         aco_option_register_custom(&cfg_info, "automon", ACO_EXACT, featuremap_options,
1816                         DEFAULT_FEATUREMAP_AUTOMON, featuremap_handler, 0);
1817         aco_option_register_custom(&cfg_info, "atxfer", ACO_EXACT, featuremap_options,
1818                         DEFAULT_FEATUREMAP_ATXFER, featuremap_handler, 0);
1819         aco_option_register_custom(&cfg_info, "parkcall", ACO_EXACT, featuremap_options,
1820                         DEFAULT_FEATUREMAP_PARKCALL, featuremap_handler, 0);
1821         aco_option_register_custom(&cfg_info, "automixmon", ACO_EXACT, featuremap_options,
1822                         DEFAULT_FEATUREMAP_AUTOMIXMON, featuremap_handler, 0);
1823
1824         aco_option_register_custom(&cfg_info, "^.*$", ACO_REGEX, applicationmap_options,
1825                         "", applicationmap_handler, 0);
1826
1827         aco_option_register_custom(&cfg_info, "^.*$", ACO_REGEX, featuregroup_options,
1828                         "", featuregroup_handler, 0);
1829
1830         aco_option_register_custom_nodoc(&cfg_info, "^.*$", ACO_REGEX, parkinglot_options,
1831                         "", unsupported_handler, 0);
1832
1833         if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
1834                 RAII_VAR(struct features_config *, features_cfg, features_config_alloc(), ao2_cleanup);
1835
1836                 if (aco_set_defaults(&global_option, "general", features_cfg->global) ||
1837                         aco_set_defaults(&featuremap_option, "featuremap", features_cfg->featuremap)) {
1838                         ast_log(LOG_ERROR, "Failed to load features.conf and failed to initialize defaults.\n");
1839                         return -1;
1840                 }
1841
1842                 ast_log(LOG_NOTICE, "Could not load features config; using defaults\n");
1843                 ao2_global_obj_replace_unref(globals, features_cfg);
1844         }
1845
1846         return 0;
1847 }
1848
1849 static int print_featuregroup(void *obj, void *arg, int flags)
1850 {
1851         struct featuregroup_item *item = obj;
1852         struct ast_cli_args *a = arg;
1853
1854         ast_cli(a->fd, "===> --> %s (%s)\n", item->appmap_item_name,
1855                         S_OR(item->dtmf_override, item->appmap_item->dtmf));
1856
1857         return 0;
1858 }
1859
1860 static int print_featuregroups(void *obj, void *arg, int flags)
1861 {
1862         struct featuregroup *group = obj;
1863         struct ast_cli_args *a = arg;
1864
1865         ast_cli(a->fd, "===> Group: %s\n", group->name);
1866
1867         ao2_callback(group->items, 0, print_featuregroup, a);
1868         return 0;
1869 }
1870
1871 #define HFS_FORMAT "%-25s %-7s %-7s\n"
1872
1873 static int print_applicationmap(void *obj, void *arg, int flags)
1874 {
1875         struct ast_applicationmap_item *item = obj;
1876         struct ast_cli_args *a = arg;
1877
1878         ast_cli(a->fd, HFS_FORMAT, item->name, "no def", item->dtmf);
1879         return 0;
1880 }
1881
1882 /*!
1883  * \brief CLI command to list configured features
1884  * \param e
1885  * \param cmd
1886  * \param a
1887  *
1888  * \retval CLI_SUCCESS on success.
1889  * \retval NULL when tab completion is used.
1890  */
1891 static char *handle_feature_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1892 {
1893         RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
1894
1895         switch (cmd) {
1896
1897         case CLI_INIT:
1898                 e->command = "features show";
1899                 e->usage =
1900                         "Usage: features show\n"
1901                         "       Lists configured features\n";
1902                 return NULL;
1903         case CLI_GENERATE:
1904                 return NULL;
1905         }
1906
1907         cfg = ao2_global_obj_ref(globals);
1908
1909         ast_cli(a->fd, HFS_FORMAT, "Builtin Feature", "Default", "Current");
1910         ast_cli(a->fd, HFS_FORMAT, "---------------", "-------", "-------");
1911
1912         ast_cli(a->fd, HFS_FORMAT, "Pickup", DEFAULT_PICKUPEXTEN, cfg->global->pickup->pickupexten);
1913         ast_cli(a->fd, HFS_FORMAT, "Blind Transfer", DEFAULT_FEATUREMAP_BLINDXFER, cfg->featuremap->blindxfer);
1914         ast_cli(a->fd, HFS_FORMAT, "Attended Transfer", DEFAULT_FEATUREMAP_ATXFER, cfg->featuremap->atxfer);
1915         ast_cli(a->fd, HFS_FORMAT, "One Touch Monitor", DEFAULT_FEATUREMAP_AUTOMON, cfg->featuremap->automon);
1916         ast_cli(a->fd, HFS_FORMAT, "Disconnect Call", DEFAULT_FEATUREMAP_DISCONNECT, cfg->featuremap->disconnect);
1917         ast_cli(a->fd, HFS_FORMAT, "Park Call", DEFAULT_FEATUREMAP_PARKCALL, cfg->featuremap->parkcall);
1918         ast_cli(a->fd, HFS_FORMAT, "One Touch MixMonitor", DEFAULT_FEATUREMAP_AUTOMIXMON, cfg->featuremap->automixmon);
1919
1920         ast_cli(a->fd, "\n");
1921         ast_cli(a->fd, HFS_FORMAT, "Dynamic Feature", "Default", "Current");
1922         ast_cli(a->fd, HFS_FORMAT, "---------------", "-------", "-------");
1923         if (!cfg->applicationmap || ao2_container_count(cfg->applicationmap) == 0) {
1924                 ast_cli(a->fd, "(none)\n");
1925         } else {
1926                 ao2_callback(cfg->applicationmap, 0, print_applicationmap, a);
1927         }
1928
1929         ast_cli(a->fd, "\nFeature Groups:\n");
1930         ast_cli(a->fd, "---------------\n");
1931         if (!cfg->featuregroups || ao2_container_count(cfg->featuregroups) == 0) {
1932                 ast_cli(a->fd, "(none)\n");
1933         } else {
1934                 ao2_callback(cfg->featuregroups, 0, print_featuregroups, a);
1935         }
1936
1937         ast_cli(a->fd, "\n");
1938
1939         return CLI_SUCCESS;
1940 }
1941
1942 static struct ast_cli_entry cli_features_config[] = {
1943         AST_CLI_DEFINE(handle_feature_show, "Lists configured features"),
1944 };
1945
1946 void ast_features_config_shutdown(void)
1947 {
1948         ast_custom_function_unregister(&featuremap_function);
1949         ast_custom_function_unregister(&feature_function);
1950         ast_cli_unregister_multiple(cli_features_config, ARRAY_LEN(cli_features_config));
1951         aco_info_destroy(&cfg_info);
1952         ao2_global_obj_release(globals);
1953 }
1954
1955 int ast_features_config_reload(void)
1956 {
1957         /* Rearm the parking config options have moved warning. */
1958         parking_warning = 0;
1959
1960         if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
1961                 return -1;
1962         }
1963         return 0;
1964 }
1965
1966 int ast_features_config_init(void)
1967 {
1968         int res;
1969
1970         res = load_config();
1971         res |= __ast_custom_function_register(&feature_function, NULL);
1972         res |= __ast_custom_function_register(&featuremap_function, NULL);
1973         res |= ast_cli_register_multiple(cli_features_config, ARRAY_LEN(cli_features_config));
1974
1975         if (res) {
1976                 ast_features_config_shutdown();
1977         }
1978
1979         return res;
1980 }