2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2008, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
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.
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.
21 * \brief Core PBX routines.
23 * \author Mark Spencer <markster@digium.com>
27 <support_level>core</support_level>
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
34 #include "asterisk/_private.h"
35 #include "asterisk/paths.h" /* use ast_config_AST_SYSTEM_NAME */
39 #if defined(HAVE_SYSINFO)
40 #include <sys/sysinfo.h>
43 #include <sys/loadavg.h>
46 #include "asterisk/lock.h"
47 #include "asterisk/cli.h"
48 #include "asterisk/pbx.h"
49 #include "asterisk/channel.h"
50 #include "asterisk/file.h"
51 #include "asterisk/callerid.h"
52 #include "asterisk/cdr.h"
53 #include "asterisk/config.h"
54 #include "asterisk/term.h"
55 #include "asterisk/time.h"
56 #include "asterisk/manager.h"
57 #include "asterisk/ast_expr.h"
58 #include "asterisk/linkedlists.h"
59 #define SAY_STUBS /* generate declarations and stubs for say methods */
60 #include "asterisk/say.h"
61 #include "asterisk/utils.h"
62 #include "asterisk/causes.h"
63 #include "asterisk/musiconhold.h"
64 #include "asterisk/app.h"
65 #include "asterisk/devicestate.h"
66 #include "asterisk/presencestate.h"
67 #include "asterisk/hashtab.h"
68 #include "asterisk/module.h"
69 #include "asterisk/indications.h"
70 #include "asterisk/taskprocessor.h"
71 #include "asterisk/xmldoc.h"
72 #include "asterisk/astobj2.h"
73 #include "asterisk/stasis_channels.h"
74 #include "asterisk/dial.h"
77 * \note I M P O R T A N T :
79 * The speed of extension handling will likely be among the most important
80 * aspects of this PBX. The switching scheme as it exists right now isn't
81 * terribly bad (it's O(N+M), where N is the # of extensions and M is the avg #
82 * of priorities, but a constant search time here would be great ;-)
84 * A new algorithm to do searching based on a 'compiled' pattern tree is introduced
85 * here, and shows a fairly flat (constant) search time, even for over
88 * Also, using a hash table for context/priority name lookup can help prevent
89 * the find_extension routines from absorbing exponential cpu cycles as the number
90 * of contexts/priorities grow. I've previously tested find_extension with red-black trees,
91 * which have O(log2(n)) speed. Right now, I'm using hash tables, which do
92 * searches (ideally) in O(1) time. While these techniques do not yield much
93 * speed in small dialplans, they are worth the trouble in large dialplans.
98 <application name="Answer" language="en_US">
100 Answer a channel if ringing.
103 <parameter name="delay">
104 <para>Asterisk will wait this number of milliseconds before returning to
105 the dialplan after answering the call.</para>
107 <parameter name="nocdr">
108 <para>Asterisk will send an answer signal to the calling phone, but will not
109 set the disposition or answer time in the CDR for this call.</para>
113 <para>If the call has not been answered, this application will
114 answer it. Otherwise, it has no effect on the call.</para>
117 <ref type="application">Hangup</ref>
120 <application name="BackGround" language="en_US">
122 Play an audio file while waiting for digits of an extension to go to.
125 <parameter name="filenames" required="true" argsep="&">
126 <argument name="filename1" required="true" />
127 <argument name="filename2" multiple="true" />
129 <parameter name="options">
132 <para>Causes the playback of the message to be skipped
133 if the channel is not in the <literal>up</literal> state (i.e. it
134 hasn't been answered yet). If this happens, the
135 application will return immediately.</para>
138 <para>Don't answer the channel before playing the files.</para>
141 <para>Only break if a digit hit matches a one digit
142 extension in the destination context.</para>
146 <parameter name="langoverride">
147 <para>Explicitly specifies which language to attempt to use for the requested sound files.</para>
149 <parameter name="context">
150 <para>This is the dialplan context that this application will use when exiting
151 to a dialed extension.</para>
155 <para>This application will play the given list of files <emphasis>(do not put extension)</emphasis>
156 while waiting for an extension to be dialed by the calling channel. To continue waiting
157 for digits after this application has finished playing files, the <literal>WaitExten</literal>
158 application should be used.</para>
159 <para>If one of the requested sound files does not exist, call processing will be terminated.</para>
160 <para>This application sets the following channel variable upon completion:</para>
162 <variable name="BACKGROUNDSTATUS">
163 <para>The status of the background attempt as a text string.</para>
164 <value name="SUCCESS" />
165 <value name="FAILED" />
170 <ref type="application">ControlPlayback</ref>
171 <ref type="application">WaitExten</ref>
172 <ref type="application">BackgroundDetect</ref>
173 <ref type="function">TIMEOUT</ref>
176 <application name="Busy" language="en_US">
178 Indicate the Busy condition.
181 <parameter name="timeout">
182 <para>If specified, the calling channel will be hung up after the specified number of seconds.
183 Otherwise, this application will wait until the calling channel hangs up.</para>
187 <para>This application will indicate the busy condition to the calling channel.</para>
190 <ref type="application">Congestion</ref>
191 <ref type="application">Progress</ref>
192 <ref type="application">Playtones</ref>
193 <ref type="application">Hangup</ref>
196 <application name="Congestion" language="en_US">
198 Indicate the Congestion condition.
201 <parameter name="timeout">
202 <para>If specified, the calling channel will be hung up after the specified number of seconds.
203 Otherwise, this application will wait until the calling channel hangs up.</para>
207 <para>This application will indicate the congestion condition to the calling channel.</para>
210 <ref type="application">Busy</ref>
211 <ref type="application">Progress</ref>
212 <ref type="application">Playtones</ref>
213 <ref type="application">Hangup</ref>
216 <application name="ExecIfTime" language="en_US">
218 Conditional application execution based on the current time.
221 <parameter name="day_condition" required="true">
222 <argument name="times" required="true" />
223 <argument name="weekdays" required="true" />
224 <argument name="mdays" required="true" />
225 <argument name="months" required="true" />
226 <argument name="timezone" required="false" />
228 <parameter name="appname" required="true" hasparams="optional">
229 <argument name="appargs" required="true" />
233 <para>This application will execute the specified dialplan application, with optional
234 arguments, if the current time matches the given time specification.</para>
237 <ref type="application">Exec</ref>
238 <ref type="application">ExecIf</ref>
239 <ref type="application">TryExec</ref>
240 <ref type="application">GotoIfTime</ref>
243 <application name="Goto" language="en_US">
245 Jump to a particular priority, extension, or context.
248 <parameter name="context" />
249 <parameter name="extensions" />
250 <parameter name="priority" required="true" />
253 <para>This application will set the current context, extension, and priority in the channel structure.
254 After it completes, the pbx engine will continue dialplan execution at the specified location.
255 If no specific <replaceable>extension</replaceable>, or <replaceable>extension</replaceable> and
256 <replaceable>context</replaceable>, are specified, then this application will
257 just set the specified <replaceable>priority</replaceable> of the current extension.</para>
258 <para>At least a <replaceable>priority</replaceable> is required as an argument, or the goto will
259 return a <literal>-1</literal>, and the channel and call will be terminated.</para>
260 <para>If the location that is put into the channel information is bogus, and asterisk cannot
261 find that location in the dialplan, then the execution engine will try to find and execute the code in
262 the <literal>i</literal> (invalid) extension in the current context. If that does not exist, it will try to execute the
263 <literal>h</literal> extension. If neither the <literal>h</literal> nor <literal>i</literal> extensions
264 have been defined, the channel is hung up, and the execution of instructions on the channel is terminated.
265 What this means is that, for example, you specify a context that does not exist, then
266 it will not be possible to find the <literal>h</literal> or <literal>i</literal> extensions,
267 and the call will terminate!</para>
270 <ref type="application">GotoIf</ref>
271 <ref type="application">GotoIfTime</ref>
272 <ref type="application">Gosub</ref>
273 <ref type="application">Macro</ref>
276 <application name="GotoIf" language="en_US">
281 <parameter name="condition" required="true" />
282 <parameter name="destination" required="true" argsep=":">
283 <argument name="labeliftrue">
284 <para>Continue at <replaceable>labeliftrue</replaceable> if the condition is true.
285 Takes the form similar to Goto() of [[context,]extension,]priority.</para>
287 <argument name="labeliffalse">
288 <para>Continue at <replaceable>labeliffalse</replaceable> if the condition is false.
289 Takes the form similar to Goto() of [[context,]extension,]priority.</para>
294 <para>This application will set the current context, extension, and priority in the channel structure
295 based on the evaluation of the given condition. After this application completes, the
296 pbx engine will continue dialplan execution at the specified location in the dialplan.
297 The labels are specified with the same syntax as used within the Goto application.
298 If the label chosen by the condition is omitted, no jump is performed, and the execution passes to the
299 next instruction. If the target location is bogus, and does not exist, the execution engine will try
300 to find and execute the code in the <literal>i</literal> (invalid) extension in the current context.
301 If that does not exist, it will try to execute the <literal>h</literal> extension.
302 If neither the <literal>h</literal> nor <literal>i</literal> extensions have been defined,
303 the channel is hung up, and the execution of instructions on the channel is terminated.
304 Remember that this command can set the current context, and if the context specified
305 does not exist, then it will not be able to find any 'h' or 'i' extensions there, and
306 the channel and call will both be terminated!.</para>
309 <ref type="application">Goto</ref>
310 <ref type="application">GotoIfTime</ref>
311 <ref type="application">GosubIf</ref>
312 <ref type="application">MacroIf</ref>
315 <application name="GotoIfTime" language="en_US">
317 Conditional Goto based on the current time.
320 <parameter name="condition" required="true">
321 <argument name="times" required="true" />
322 <argument name="weekdays" required="true" />
323 <argument name="mdays" required="true" />
324 <argument name="months" required="true" />
325 <argument name="timezone" required="false" />
327 <parameter name="destination" required="true" argsep=":">
328 <argument name="labeliftrue">
329 <para>Continue at <replaceable>labeliftrue</replaceable> if the condition is true.
330 Takes the form similar to Goto() of [[context,]extension,]priority.</para>
332 <argument name="labeliffalse">
333 <para>Continue at <replaceable>labeliffalse</replaceable> if the condition is false.
334 Takes the form similar to Goto() of [[context,]extension,]priority.</para>
339 <para>This application will set the context, extension, and priority in the channel structure
340 based on the evaluation of the given time specification. After this application completes,
341 the pbx engine will continue dialplan execution at the specified location in the dialplan.
342 If the current time is within the given time specification, the channel will continue at
343 <replaceable>labeliftrue</replaceable>. Otherwise the channel will continue at <replaceable>labeliffalse</replaceable>.
344 If the label chosen by the condition is omitted, no jump is performed, and execution passes to the next
345 instruction. If the target jump location is bogus, the same actions would be taken as for <literal>Goto</literal>.
346 Further information on the time specification can be found in examples
347 illustrating how to do time-based context includes in the dialplan.</para>
350 <ref type="application">GotoIf</ref>
351 <ref type="application">Goto</ref>
352 <ref type="function">IFTIME</ref>
353 <ref type="function">TESTTIME</ref>
356 <application name="ImportVar" language="en_US">
358 Import a variable from a channel into a new variable.
361 <parameter name="newvar" required="true" />
362 <parameter name="vardata" required="true">
363 <argument name="channelname" required="true" />
364 <argument name="variable" required="true" />
368 <para>This application imports a <replaceable>variable</replaceable> from the specified
369 <replaceable>channel</replaceable> (as opposed to the current one) and stores it as a variable
370 (<replaceable>newvar</replaceable>) in the current channel (the channel that is calling this
371 application). Variables created by this application have the same inheritance properties as those
372 created with the <literal>Set</literal> application.</para>
375 <ref type="application">Set</ref>
378 <application name="Hangup" language="en_US">
380 Hang up the calling channel.
383 <parameter name="causecode">
384 <para>If a <replaceable>causecode</replaceable> is given the channel's
385 hangup cause will be set to the given value.</para>
389 <para>This application will hang up the calling channel.</para>
392 <ref type="application">Answer</ref>
393 <ref type="application">Busy</ref>
394 <ref type="application">Congestion</ref>
397 <application name="Incomplete" language="en_US">
399 Returns AST_PBX_INCOMPLETE value.
403 <para>If specified, then Incomplete will not attempt to answer the channel first.</para>
404 <note><para>Most channel types need to be in Answer state in order to receive DTMF.</para></note>
408 <para>Signals the PBX routines that the previous matched extension is incomplete
409 and that further input should be allowed before matching can be considered
410 to be complete. Can be used within a pattern match when certain criteria warrants
411 a longer match.</para>
414 <application name="NoOp" language="en_US">
416 Do Nothing (No Operation).
419 <parameter name="text">
420 <para>Any text provided can be viewed at the Asterisk CLI.</para>
424 <para>This application does nothing. However, it is useful for debugging purposes.</para>
425 <para>This method can be used to see the evaluations of variables or functions without having any effect.</para>
428 <ref type="application">Verbose</ref>
429 <ref type="application">Log</ref>
432 <application name="Proceeding" language="en_US">
438 <para>This application will request that a proceeding message be provided to the calling channel.</para>
441 <application name="Progress" language="en_US">
447 <para>This application will request that in-band progress information be provided to the calling channel.</para>
450 <ref type="application">Busy</ref>
451 <ref type="application">Congestion</ref>
452 <ref type="application">Ringing</ref>
453 <ref type="application">Playtones</ref>
456 <application name="RaiseException" language="en_US">
458 Handle an exceptional condition.
461 <parameter name="reason" required="true" />
464 <para>This application will jump to the <literal>e</literal> extension in the current context, setting the
465 dialplan function EXCEPTION(). If the <literal>e</literal> extension does not exist, the call will hangup.</para>
468 <ref type="function">Exception</ref>
471 <application name="Ringing" language="en_US">
473 Indicate ringing tone.
477 <para>This application will request that the channel indicate a ringing tone to the user.</para>
480 <ref type="application">Busy</ref>
481 <ref type="application">Congestion</ref>
482 <ref type="application">Progress</ref>
483 <ref type="application">Playtones</ref>
486 <application name="SayAlpha" language="en_US">
491 <parameter name="string" required="true" />
494 <para>This application will play the sounds that correspond to the letters
495 of the given <replaceable>string</replaceable>. If the channel variable
496 <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive),
497 then this application will react to DTMF in the same way as
498 <literal>Background</literal>.</para>
501 <ref type="application">SayDigits</ref>
502 <ref type="application">SayNumber</ref>
503 <ref type="application">SayPhonetic</ref>
504 <ref type="function">CHANNEL</ref>
507 <application name="SayAlphaCase" language="en_US">
512 <parameter name="casetype" required="true" >
515 <para>Case sensitive (all) pronunciation.
516 (Ex: SayAlphaCase(a,aBc); - lowercase a uppercase b lowercase c).</para>
519 <para>Case sensitive (lower) pronunciation.
520 (Ex: SayAlphaCase(l,aBc); - lowercase a b lowercase c).</para>
523 <para>Case insensitive pronunciation. Equivalent to SayAlpha.
524 (Ex: SayAlphaCase(n,aBc) - a b c).</para>
527 <para>Case sensitive (upper) pronunciation.
528 (Ex: SayAlphaCase(u,aBc); - a uppercase b c).</para>
532 <parameter name="string" required="true" />
535 <para>This application will play the sounds that correspond to the letters of the
536 given <replaceable>string</replaceable>. Optionally, a <replaceable>casetype</replaceable> may be
537 specified. This will be used for case-insensitive or case-sensitive pronunciations. If the channel
538 variable <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
539 application will react to DTMF in the same way as <literal>Background</literal>.</para>
542 <ref type="application">SayDigits</ref>
543 <ref type="application">SayNumber</ref>
544 <ref type="application">SayPhonetic</ref>
545 <ref type="application">SayAlpha</ref>
546 <ref type="function">CHANNEL</ref>
549 <application name="SayDigits" language="en_US">
554 <parameter name="digits" required="true" />
557 <para>This application will play the sounds that correspond to the digits of
558 the given number. This will use the language that is currently set for the channel.
559 If the channel variable <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true'
560 (case insensitive), then this application will react to DTMF in the same way as
561 <literal>Background</literal>.</para>
564 <ref type="application">SayAlpha</ref>
565 <ref type="application">SayNumber</ref>
566 <ref type="application">SayPhonetic</ref>
567 <ref type="function">CHANNEL</ref>
570 <application name="SayNumber" language="en_US">
575 <parameter name="digits" required="true" />
576 <parameter name="gender" />
579 <para>This application will play the sounds that correspond to the given
580 <replaceable>digits</replaceable>. Optionally, a <replaceable>gender</replaceable> may be
581 specified. This will use the language that is currently set for the channel. See the CHANNEL()
582 function for more information on setting the language for the channel. If the channel variable
583 <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
584 application will react to DTMF in the same way as <literal>Background</literal>.</para>
587 <ref type="application">SayAlpha</ref>
588 <ref type="application">SayDigits</ref>
589 <ref type="application">SayPhonetic</ref>
590 <ref type="function">CHANNEL</ref>
593 <application name="SayPhonetic" language="en_US">
598 <parameter name="string" required="true" />
601 <para>This application will play the sounds from the phonetic alphabet that correspond to the
602 letters in the given <replaceable>string</replaceable>. If the channel variable
603 <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
604 application will react to DTMF in the same way as <literal>Background</literal>.</para>
607 <ref type="application">SayAlpha</ref>
608 <ref type="application">SayDigits</ref>
609 <ref type="application">SayNumber</ref>
612 <application name="Set" language="en_US">
614 Set channel variable or function value.
617 <parameter name="name" required="true" />
618 <parameter name="value" required="true" />
621 <para>This function can be used to set the value of channel variables or dialplan functions.
622 When setting variables, if the variable name is prefixed with <literal>_</literal>,
623 the variable will be inherited into channels created from the current channel.
624 If the variable name is prefixed with <literal>__</literal>, the variable will be
625 inherited into channels created from the current channel and all children channels.</para>
626 <note><para>If (and only if), in <filename>/etc/asterisk/asterisk.conf</filename>, you have
627 a <literal>[compat]</literal> category, and you have <literal>app_set = 1.4</literal> under that, then
628 the behavior of this app changes, and strips surrounding quotes from the right hand side as
629 it did previously in 1.4.
630 The advantages of not stripping out quoting, and not caring about the separator characters (comma and vertical bar)
631 were sufficient to make these changes in 1.6. Confusion about how many backslashes would be needed to properly
632 protect separators and quotes in various database access strings has been greatly
633 reduced by these changes.</para></note>
636 <ref type="application">MSet</ref>
637 <ref type="function">GLOBAL</ref>
638 <ref type="function">SET</ref>
639 <ref type="function">ENV</ref>
642 <application name="MSet" language="en_US">
644 Set channel variable(s) or function value(s).
647 <parameter name="set1" required="true" argsep="=">
648 <argument name="name1" required="true" />
649 <argument name="value1" required="true" />
651 <parameter name="set2" multiple="true" argsep="=">
652 <argument name="name2" required="true" />
653 <argument name="value2" required="true" />
657 <para>This function can be used to set the value of channel variables or dialplan functions.
658 When setting variables, if the variable name is prefixed with <literal>_</literal>,
659 the variable will be inherited into channels created from the current channel
660 If the variable name is prefixed with <literal>__</literal>, the variable will be
661 inherited into channels created from the current channel and all children channels.
662 MSet behaves in a similar fashion to the way Set worked in 1.2/1.4 and is thus
663 prone to doing things that you may not expect. For example, it strips surrounding
664 double-quotes from the right-hand side (value). If you need to put a separator
665 character (comma or vert-bar), you will need to escape them by inserting a backslash
666 before them. Avoid its use if possible.</para>
669 <ref type="application">Set</ref>
672 <application name="SetAMAFlags" language="en_US">
677 <parameter name="flag" />
680 <para>This application will set the channel's AMA Flags for billing purposes.</para>
681 <warning><para>This application is deprecated. Please use the CHANNEL function instead.</para></warning>
684 <ref type="function">CDR</ref>
685 <ref type="function">CHANNEL</ref>
688 <application name="Wait" language="en_US">
693 <parameter name="seconds" required="true">
694 <para>Can be passed with fractions of a second. For example, <literal>1.5</literal> will ask the
695 application to wait for 1.5 seconds.</para>
699 <para>This application waits for a specified number of <replaceable>seconds</replaceable>.</para>
702 <application name="WaitExten" language="en_US">
704 Waits for an extension to be entered.
707 <parameter name="seconds">
708 <para>Can be passed with fractions of a second. For example, <literal>1.5</literal> will ask the
709 application to wait for 1.5 seconds.</para>
711 <parameter name="options">
714 <para>Provide music on hold to the caller while waiting for an extension.</para>
716 <para>Specify the class for music on hold. <emphasis>CHANNEL(musicclass) will
717 be used instead if set</emphasis></para>
724 <para>This application waits for the user to enter a new extension for a specified number
725 of <replaceable>seconds</replaceable>.</para>
726 <xi:include xpointer="xpointer(/docs/application[@name='Macro']/description/warning[2])" />
729 <ref type="application">Background</ref>
730 <ref type="function">TIMEOUT</ref>
733 <function name="EXCEPTION" language="en_US">
735 Retrieve the details of the current dialplan exception.
738 <parameter name="field" required="true">
739 <para>The following fields are available for retrieval:</para>
742 <para>INVALID, ERROR, RESPONSETIMEOUT, ABSOLUTETIMEOUT, or custom
743 value set by the RaiseException() application</para>
745 <enum name="context">
746 <para>The context executing when the exception occurred.</para>
749 <para>The extension executing when the exception occurred.</para>
751 <enum name="priority">
752 <para>The numeric priority executing when the exception occurred.</para>
758 <para>Retrieve the details (specified <replaceable>field</replaceable>) of the current dialplan exception.</para>
761 <ref type="application">RaiseException</ref>
764 <function name="TESTTIME" language="en_US">
766 Sets a time to be used with the channel to test logical conditions.
769 <parameter name="date" required="true" argsep=" ">
770 <para>Date in ISO 8601 format</para>
772 <parameter name="time" required="true" argsep=" ">
773 <para>Time in HH:MM:SS format (24-hour time)</para>
775 <parameter name="zone" required="false">
776 <para>Timezone name</para>
780 <para>To test dialplan timing conditions at times other than the current time, use
781 this function to set an alternate date and time. For example, you may wish to evaluate
782 whether a location will correctly identify to callers that the area is closed on Christmas
783 Day, when Christmas would otherwise fall on a day when the office is normally open.</para>
786 <ref type="application">GotoIfTime</ref>
789 <manager name="ShowDialPlan" language="en_US">
791 Show dialplan contexts and extensions
794 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
795 <parameter name="Extension">
796 <para>Show a specific extension.</para>
798 <parameter name="Context">
799 <para>Show a specific context.</para>
803 <para>Show dialplan contexts and extensions. Be aware that showing the full dialplan
804 may take a lot of capacity.</para>
810 #define EXT_DATA_SIZE 256
812 #define EXT_DATA_SIZE 8192
815 #define SWITCH_DATA_LENGTH 256
817 #define VAR_BUF_SIZE 4096
820 #define VAR_SOFTTRAN 2
821 #define VAR_HARDTRAN 3
823 #define BACKGROUND_SKIP (1 << 0)
824 #define BACKGROUND_NOANSWER (1 << 1)
825 #define BACKGROUND_MATCHEXTEN (1 << 2)
826 #define BACKGROUND_PLAYBACK (1 << 3)
828 AST_APP_OPTIONS(background_opts, {
829 AST_APP_OPTION('s', BACKGROUND_SKIP),
830 AST_APP_OPTION('n', BACKGROUND_NOANSWER),
831 AST_APP_OPTION('m', BACKGROUND_MATCHEXTEN),
832 AST_APP_OPTION('p', BACKGROUND_PLAYBACK),
835 #define WAITEXTEN_MOH (1 << 0)
836 #define WAITEXTEN_DIALTONE (1 << 1)
838 AST_APP_OPTIONS(waitexten_opts, {
839 AST_APP_OPTION_ARG('m', WAITEXTEN_MOH, 0),
840 AST_APP_OPTION_ARG('d', WAITEXTEN_DIALTONE, 0),
846 AST_THREADSTORAGE(switch_data);
847 AST_THREADSTORAGE(extensionstate_buf);
849 * \brief A thread local indicating whether the current thread can run
850 * 'dangerous' dialplan functions.
852 AST_THREADSTORAGE(thread_inhibit_escalations_tl);
855 * \brief Set to true (non-zero) to globally allow all dangerous dialplan
858 static int live_dangerously;
861 \brief ast_exten: An extension
862 The dialplan is saved as a linked list with each context
863 having it's own linked list of extensions - one item per
867 char *exten; /*!< Extension name */
868 int matchcid; /*!< Match caller id ? */
869 const char *cidmatch; /*!< Caller id to match for this extension */
870 int priority; /*!< Priority */
871 const char *label; /*!< Label */
872 struct ast_context *parent; /*!< The context this extension belongs to */
873 const char *app; /*!< Application to execute */
874 struct ast_app *cached_app; /*!< Cached location of application */
875 void *data; /*!< Data to use (arguments) */
876 void (*datad)(void *); /*!< Data destructor */
877 struct ast_exten *peer; /*!< Next higher priority with our extension */
878 struct ast_hashtab *peer_table; /*!< Priorities list in hashtab form -- only on the head of the peer list */
879 struct ast_hashtab *peer_label_table; /*!< labeled priorities in the peers -- only on the head of the peer list */
880 const char *registrar; /*!< Registrar */
881 struct ast_exten *next; /*!< Extension with a greater ID */
885 /*! \brief ast_include: include= support in extensions.conf */
888 const char *rname; /*!< Context to include */
889 const char *registrar; /*!< Registrar */
890 int hastime; /*!< If time construct exists */
891 struct ast_timing timing; /*!< time construct */
892 struct ast_include *next; /*!< Link them together */
896 /*! \brief ast_sw: Switch statement in extensions.conf */
899 const char *registrar; /*!< Registrar */
900 char *data; /*!< Data load */
902 AST_LIST_ENTRY(ast_sw) list;
906 /*! \brief ast_ignorepat: Ignore patterns in dial plan */
907 struct ast_ignorepat {
908 const char *registrar;
909 struct ast_ignorepat *next;
910 const char pattern[0];
913 /*! \brief match_char: forms a syntax tree for quick matching of extension patterns */
916 int is_pattern; /* the pattern started with '_' */
917 int deleted; /* if this is set, then... don't return it */
918 int specificity; /* simply the strlen of x, or 10 for X, 9 for Z, and 8 for N; and '.' and '!' will add 11 ? */
919 struct match_char *alt_char;
920 struct match_char *next_char;
921 struct ast_exten *exten; /* attached to last char of a pattern for exten */
922 char x[1]; /* the pattern itself-- matches a single char */
925 struct scoreboard /* make sure all fields are 0 before calling new_find_extension */
927 int total_specificity;
929 char last_char; /* set to ! or . if they are the end of the pattern */
930 int canmatch; /* if the string to match was just too short */
931 struct match_char *node;
932 struct ast_exten *canmatch_exten;
933 struct ast_exten *exten;
936 /*! \brief ast_context: An extension context */
938 ast_rwlock_t lock; /*!< A lock to prevent multiple threads from clobbering the context */
939 struct ast_exten *root; /*!< The root of the list of extensions */
940 struct ast_hashtab *root_table; /*!< For exact matches on the extensions in the pattern tree, and for traversals of the pattern_tree */
941 struct match_char *pattern_tree; /*!< A tree to speed up extension pattern matching */
942 struct ast_context *next; /*!< Link them together */
943 struct ast_include *includes; /*!< Include other contexts */
944 struct ast_ignorepat *ignorepats; /*!< Patterns for which to continue playing dialtone */
945 char *registrar; /*!< Registrar -- make sure you malloc this, as the registrar may have to survive module unloads */
946 int refcount; /*!< each module that would have created this context should inc/dec this as appropriate */
947 AST_LIST_HEAD_NOLOCK(, ast_sw) alts; /*!< Alternative switches */
948 ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
949 char name[0]; /*!< Name of the context */
952 /*! \brief ast_app: A registered application */
954 int (*execute)(struct ast_channel *chan, const char *data);
955 AST_DECLARE_STRING_FIELDS(
956 AST_STRING_FIELD(synopsis); /*!< Synopsis text for 'show applications' */
957 AST_STRING_FIELD(description); /*!< Description (help text) for 'show application <name>' */
958 AST_STRING_FIELD(syntax); /*!< Syntax text for 'core show applications' */
959 AST_STRING_FIELD(arguments); /*!< Arguments description */
960 AST_STRING_FIELD(seealso); /*!< See also */
963 enum ast_doc_src docsrc; /*!< Where the documentation come from. */
965 AST_RWLIST_ENTRY(ast_app) list; /*!< Next app in list */
966 struct ast_module *module; /*!< Module this app belongs to */
967 char name[0]; /*!< Name of the application */
970 /*! \brief ast_state_cb: An extension state notify register item */
971 struct ast_state_cb {
972 /*! Watcher ID returned when registered. */
974 /*! Arbitrary data passed for callbacks. */
976 /*! Flag if this callback is an extended callback containing detailed device status */
978 /*! Callback when state changes. */
979 ast_state_cb_type change_cb;
980 /*! Callback when destroyed so any resources given by the registerer can be freed. */
981 ast_state_cb_destroy_type destroy_cb;
982 /*! \note Only used by ast_merge_contexts_and_delete */
983 AST_LIST_ENTRY(ast_state_cb) entry;
987 * \brief Structure for dial plan hints
989 * \note Hints are pointers from an extension in the dialplan to
990 * one or more devices (tech/name)
992 * See \ref AstExtState
996 * \brief Hint extension
999 * Will never be NULL while the hint is in the hints container.
1001 struct ast_exten *exten;
1002 struct ao2_container *callbacks; /*!< Device state callback container for this extension */
1004 /*! Dev state variables */
1005 int laststate; /*!< Last known device state */
1007 /*! Presence state variables */
1008 int last_presence_state; /*!< Last known presence state */
1009 char *last_presence_subtype; /*!< Last known presence subtype string */
1010 char *last_presence_message; /*!< Last known presence message string */
1012 char context_name[AST_MAX_CONTEXT];/*!< Context of destroyed hint extension. */
1013 char exten_name[AST_MAX_EXTENSION];/*!< Extension of destroyed hint extension. */
1017 #define HINTDEVICE_DATA_LENGTH 16
1018 AST_THREADSTORAGE(hintdevice_data);
1020 /* --- Hash tables of various objects --------*/
1022 #define HASH_EXTENHINT_SIZE 17
1024 #define HASH_EXTENHINT_SIZE 563
1028 /*! \brief Container for hint devices */
1029 static struct ao2_container *hintdevices;
1032 * \brief Structure for dial plan hint devices
1033 * \note hintdevice is one device pointing to a hint.
1035 struct ast_hintdevice {
1037 * \brief Hint this hintdevice belongs to.
1038 * \note Holds a reference to the hint object.
1040 struct ast_hint *hint;
1041 /*! Name of the hint device. */
1047 * \note Using the device for hash
1049 static int hintdevice_hash_cb(const void *obj, const int flags)
1051 const struct ast_hintdevice *ext = obj;
1053 return ast_str_case_hash(ext->hintdevice);
1056 * \note Devices on hints are not unique so no CMP_STOP is returned
1057 * Dont use ao2_find against hintdevices container cause there always
1058 * could be more than one result.
1060 static int hintdevice_cmp_multiple(void *obj, void *arg, int flags)
1062 struct ast_hintdevice *ext = obj, *ext2 = arg;
1064 return !strcasecmp(ext->hintdevice, ext2->hintdevice) ? CMP_MATCH : 0;
1068 * \details This is used with ao2_callback to remove old devices
1069 * when they are linked to the hint
1071 static int hintdevice_remove_cb(void *deviceobj, void *arg, int flags)
1073 struct ast_hintdevice *device = deviceobj;
1074 struct ast_hint *hint = arg;
1076 return (device->hint == hint) ? CMP_MATCH : 0;
1079 static int remove_hintdevice(struct ast_hint *hint)
1081 /* iterate through all devices and remove the devices which are linked to this hint */
1082 ao2_t_callback(hintdevices, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK,
1083 hintdevice_remove_cb, hint,
1084 "callback to remove all devices which are linked to a hint");
1088 static char *parse_hint_device(struct ast_str *hint_args);
1091 * \brief Destroy the given hintdevice object.
1093 * \param obj Hint device to destroy.
1097 static void hintdevice_destroy(void *obj)
1099 struct ast_hintdevice *doomed = obj;
1102 ao2_ref(doomed->hint, -1);
1103 doomed->hint = NULL;
1107 /*! \brief add hintdevice structure and link it into the container.
1109 static int add_hintdevice(struct ast_hint *hint, const char *devicelist)
1111 struct ast_str *str;
1114 struct ast_hintdevice *device;
1117 if (!hint || !devicelist) {
1118 /* Trying to add garbage? Don't bother. */
1121 if (!(str = ast_str_thread_get(&hintdevice_data, 16))) {
1124 ast_str_set(&str, 0, "%s", devicelist);
1125 parse = parse_hint_device(str);
1127 while ((cur = strsep(&parse, "&"))) {
1128 devicelength = strlen(cur);
1129 device = ao2_t_alloc(sizeof(*device) + devicelength, hintdevice_destroy,
1130 "allocating a hintdevice structure");
1134 strcpy(device->hintdevice, cur);
1136 device->hint = hint;
1137 ao2_t_link(hintdevices, device, "Linking device into hintdevice container.");
1138 ao2_t_ref(device, -1, "hintdevice is linked so we can unref");
1145 static const struct cfextension_states {
1146 int extension_state;
1147 const char * const text;
1148 } extension_states[] = {
1149 { AST_EXTENSION_NOT_INUSE, "Idle" },
1150 { AST_EXTENSION_INUSE, "InUse" },
1151 { AST_EXTENSION_BUSY, "Busy" },
1152 { AST_EXTENSION_UNAVAILABLE, "Unavailable" },
1153 { AST_EXTENSION_RINGING, "Ringing" },
1154 { AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" },
1155 { AST_EXTENSION_ONHOLD, "Hold" },
1156 { AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD, "InUse&Hold" }
1159 struct pbx_exception {
1160 AST_DECLARE_STRING_FIELDS(
1161 AST_STRING_FIELD(context); /*!< Context associated with this exception */
1162 AST_STRING_FIELD(exten); /*!< Exten associated with this exception */
1163 AST_STRING_FIELD(reason); /*!< The exception reason */
1166 int priority; /*!< Priority associated with this exception */
1169 static int pbx_builtin_answer(struct ast_channel *, const char *);
1170 static int pbx_builtin_goto(struct ast_channel *, const char *);
1171 static int pbx_builtin_hangup(struct ast_channel *, const char *);
1172 static int pbx_builtin_background(struct ast_channel *, const char *);
1173 static int pbx_builtin_wait(struct ast_channel *, const char *);
1174 static int pbx_builtin_waitexten(struct ast_channel *, const char *);
1175 static int pbx_builtin_incomplete(struct ast_channel *, const char *);
1176 static int pbx_builtin_setamaflags(struct ast_channel *, const char *);
1177 static int pbx_builtin_ringing(struct ast_channel *, const char *);
1178 static int pbx_builtin_proceeding(struct ast_channel *, const char *);
1179 static int pbx_builtin_progress(struct ast_channel *, const char *);
1180 static int pbx_builtin_congestion(struct ast_channel *, const char *);
1181 static int pbx_builtin_busy(struct ast_channel *, const char *);
1182 static int pbx_builtin_noop(struct ast_channel *, const char *);
1183 static int pbx_builtin_gotoif(struct ast_channel *, const char *);
1184 static int pbx_builtin_gotoiftime(struct ast_channel *, const char *);
1185 static int pbx_builtin_execiftime(struct ast_channel *, const char *);
1186 static int pbx_builtin_saynumber(struct ast_channel *, const char *);
1187 static int pbx_builtin_saydigits(struct ast_channel *, const char *);
1188 static int pbx_builtin_saycharacters(struct ast_channel *, const char *);
1189 static int pbx_builtin_saycharacters_case(struct ast_channel *, const char *);
1190 static int pbx_builtin_sayphonetic(struct ast_channel *, const char *);
1191 static int matchcid(const char *cidpattern, const char *callerid);
1193 static void log_match_char_tree(struct match_char *node, char *prefix); /* for use anywhere */
1195 static int pbx_builtin_importvar(struct ast_channel *, const char *);
1196 static void set_ext_pri(struct ast_channel *c, const char *exten, int pri);
1197 static void new_find_extension(const char *str, struct scoreboard *score,
1198 struct match_char *tree, int length, int spec, const char *callerid,
1199 const char *label, enum ext_match_t action);
1200 static struct match_char *already_in_tree(struct match_char *current, char *pat, int is_pattern);
1201 static struct match_char *add_exten_to_pattern_tree(struct ast_context *con,
1202 struct ast_exten *e1, int findonly);
1203 static void create_match_char_tree(struct ast_context *con);
1204 static struct ast_exten *get_canmatch_exten(struct match_char *node);
1205 static void destroy_pattern_tree(struct match_char *pattern_tree);
1206 static int hashtab_compare_extens(const void *ha_a, const void *ah_b);
1207 static int hashtab_compare_exten_numbers(const void *ah_a, const void *ah_b);
1208 static int hashtab_compare_exten_labels(const void *ah_a, const void *ah_b);
1209 static unsigned int hashtab_hash_extens(const void *obj);
1210 static unsigned int hashtab_hash_priority(const void *obj);
1211 static unsigned int hashtab_hash_labels(const void *obj);
1212 static void __ast_internal_context_destroy( struct ast_context *con);
1213 static int ast_add_extension_nolock(const char *context, int replace, const char *extension,
1214 int priority, const char *label, const char *callerid,
1215 const char *application, void *data, void (*datad)(void *), const char *registrar);
1216 static int ast_add_extension2_lockopt(struct ast_context *con,
1217 int replace, const char *extension, int priority, const char *label, const char *callerid,
1218 const char *application, void *data, void (*datad)(void *),
1219 const char *registrar, int lock_context);
1220 static struct ast_context *find_context_locked(const char *context);
1221 static struct ast_context *find_context(const char *context);
1222 static void get_device_state_causing_channels(struct ao2_container *c);
1226 * \brief Character array comparison function for qsort.
1228 * \param a Left side object.
1229 * \param b Right side object.
1231 * \retval <0 if a < b
1232 * \retval =0 if a = b
1233 * \retval >0 if a > b
1235 static int compare_char(const void *a, const void *b)
1237 const unsigned char *ac = a;
1238 const unsigned char *bc = b;
1243 /* labels, contexts are case sensitive priority numbers are ints */
1244 int ast_hashtab_compare_contexts(const void *ah_a, const void *ah_b)
1246 const struct ast_context *ac = ah_a;
1247 const struct ast_context *bc = ah_b;
1248 if (!ac || !bc) /* safety valve, but it might prevent a crash you'd rather have happen */
1250 /* assume context names are registered in a string table! */
1251 return strcmp(ac->name, bc->name);
1254 static int hashtab_compare_extens(const void *ah_a, const void *ah_b)
1256 const struct ast_exten *ac = ah_a;
1257 const struct ast_exten *bc = ah_b;
1258 int x = strcmp(ac->exten, bc->exten);
1259 if (x) { /* if exten names are diff, then return */
1263 /* but if they are the same, do the cidmatch values match? */
1264 /* not sure which side may be using ast_ext_matchcid_types, so check both */
1265 if (ac->matchcid == AST_EXT_MATCHCID_ANY || bc->matchcid == AST_EXT_MATCHCID_ANY) {
1268 if (ac->matchcid == AST_EXT_MATCHCID_OFF && bc->matchcid == AST_EXT_MATCHCID_OFF) {
1271 if (ac->matchcid != bc->matchcid) {
1274 /* all other cases already disposed of, match now required on callerid string (cidmatch) */
1275 /* although ast_add_extension2_lockopt() enforces non-zero ptr, caller may not have */
1276 if (ast_strlen_zero(ac->cidmatch) && ast_strlen_zero(bc->cidmatch)) {
1279 return strcmp(ac->cidmatch, bc->cidmatch);
1282 static int hashtab_compare_exten_numbers(const void *ah_a, const void *ah_b)
1284 const struct ast_exten *ac = ah_a;
1285 const struct ast_exten *bc = ah_b;
1286 return ac->priority != bc->priority;
1289 static int hashtab_compare_exten_labels(const void *ah_a, const void *ah_b)
1291 const struct ast_exten *ac = ah_a;
1292 const struct ast_exten *bc = ah_b;
1293 return strcmp(S_OR(ac->label, ""), S_OR(bc->label, ""));
1296 unsigned int ast_hashtab_hash_contexts(const void *obj)
1298 const struct ast_context *ac = obj;
1299 return ast_hashtab_hash_string(ac->name);
1302 static unsigned int hashtab_hash_extens(const void *obj)
1304 const struct ast_exten *ac = obj;
1305 unsigned int x = ast_hashtab_hash_string(ac->exten);
1307 if (ac->matchcid == AST_EXT_MATCHCID_ON)
1308 y = ast_hashtab_hash_string(ac->cidmatch);
1312 static unsigned int hashtab_hash_priority(const void *obj)
1314 const struct ast_exten *ac = obj;
1315 return ast_hashtab_hash_int(ac->priority);
1318 static unsigned int hashtab_hash_labels(const void *obj)
1320 const struct ast_exten *ac = obj;
1321 return ast_hashtab_hash_string(S_OR(ac->label, ""));
1325 AST_RWLOCK_DEFINE_STATIC(globalslock);
1326 static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
1328 static int autofallthrough = 1;
1329 static int extenpatternmatchnew = 0;
1330 static char *overrideswitch = NULL;
1332 /*! \brief Subscription for device state change events */
1333 static struct stasis_subscription *device_state_sub;
1334 /*! \brief Subscription for presence state change events */
1335 static struct stasis_subscription *presence_state_sub;
1337 AST_MUTEX_DEFINE_STATIC(maxcalllock);
1338 static int countcalls;
1339 static int totalcalls;
1342 * \brief Registered functions container.
1344 * It is sorted by function name.
1346 static AST_RWLIST_HEAD_STATIC(acf_root, ast_custom_function);
1348 /*! \brief Declaration of builtin applications */
1349 static struct pbx_builtin {
1350 char name[AST_MAX_APP];
1351 int (*execute)(struct ast_channel *chan, const char *data);
1354 /* These applications are built into the PBX core and do not
1355 need separate modules */
1357 { "Answer", pbx_builtin_answer },
1358 { "BackGround", pbx_builtin_background },
1359 { "Busy", pbx_builtin_busy },
1360 { "Congestion", pbx_builtin_congestion },
1361 { "ExecIfTime", pbx_builtin_execiftime },
1362 { "Goto", pbx_builtin_goto },
1363 { "GotoIf", pbx_builtin_gotoif },
1364 { "GotoIfTime", pbx_builtin_gotoiftime },
1365 { "ImportVar", pbx_builtin_importvar },
1366 { "Hangup", pbx_builtin_hangup },
1367 { "Incomplete", pbx_builtin_incomplete },
1368 { "NoOp", pbx_builtin_noop },
1369 { "Proceeding", pbx_builtin_proceeding },
1370 { "Progress", pbx_builtin_progress },
1371 { "RaiseException", pbx_builtin_raise_exception },
1372 { "Ringing", pbx_builtin_ringing },
1373 { "SayAlpha", pbx_builtin_saycharacters },
1374 { "SayAlphaCase", pbx_builtin_saycharacters_case },
1375 { "SayDigits", pbx_builtin_saydigits },
1376 { "SayNumber", pbx_builtin_saynumber },
1377 { "SayPhonetic", pbx_builtin_sayphonetic },
1378 { "Set", pbx_builtin_setvar },
1379 { "MSet", pbx_builtin_setvar_multiple },
1380 { "SetAMAFlags", pbx_builtin_setamaflags },
1381 { "Wait", pbx_builtin_wait },
1382 { "WaitExten", pbx_builtin_waitexten }
1385 static struct ast_context *contexts;
1386 static struct ast_hashtab *contexts_table = NULL;
1389 * \brief Lock for the ast_context list
1391 * This lock MUST be recursive, or a deadlock on reload may result. See
1392 * https://issues.asterisk.org/view.php?id=17643
1394 AST_MUTEX_DEFINE_STATIC(conlock);
1397 * \brief Lock to hold off restructuring of hints by ast_merge_contexts_and_delete.
1399 AST_MUTEX_DEFINE_STATIC(context_merge_lock);
1402 * \brief Registered applications container.
1404 * It is sorted by application name.
1406 static AST_RWLIST_HEAD_STATIC(apps, ast_app);
1408 static AST_RWLIST_HEAD_STATIC(switches, ast_switch);
1410 static int stateid = 1;
1412 * \note When holding this container's lock, do _not_ do
1413 * anything that will cause conlock to be taken, unless you
1414 * _already_ hold it. The ast_merge_contexts_and_delete function
1415 * will take the locks in conlock/hints order, so any other
1416 * paths that require both locks must also take them in that
1419 static struct ao2_container *hints;
1421 static struct ao2_container *statecbs;
1423 #ifdef CONTEXT_DEBUG
1425 /* these routines are provided for doing run-time checks
1426 on the extension structures, in case you are having
1427 problems, this routine might help you localize where
1428 the problem is occurring. It's kinda like a debug memory
1429 allocator's arena checker... It'll eat up your cpu cycles!
1430 but you'll see, if you call it in the right places,
1431 right where your problems began...
1434 /* you can break on the check_contexts_trouble()
1435 routine in your debugger to stop at the moment
1436 there's a problem */
1437 void check_contexts_trouble(void);
1439 void check_contexts_trouble(void)
1445 int check_contexts(char *, int);
1447 int check_contexts(char *file, int line )
1449 struct ast_hashtab_iter *t1;
1450 struct ast_context *c1, *c2;
1452 struct ast_exten *e1, *e2, *e3;
1453 struct ast_exten ex;
1455 /* try to find inconsistencies */
1456 /* is every context in the context table in the context list and vice-versa ? */
1458 if (!contexts_table) {
1459 ast_log(LOG_NOTICE,"Called from: %s:%d: No contexts_table!\n", file, line);
1463 t1 = ast_hashtab_start_traversal(contexts_table);
1464 while( (c1 = ast_hashtab_next(t1))) {
1465 for(c2=contexts;c2;c2=c2->next) {
1466 if (!strcmp(c1->name, c2->name)) {
1472 ast_log(LOG_NOTICE,"Called from: %s:%d: Could not find the %s context in the linked list\n", file, line, c1->name);
1473 check_contexts_trouble();
1476 ast_hashtab_end_traversal(t1);
1477 for(c2=contexts;c2;c2=c2->next) {
1478 c1 = find_context_locked(c2->name);
1480 ast_log(LOG_NOTICE,"Called from: %s:%d: Could not find the %s context in the hashtab\n", file, line, c2->name);
1481 check_contexts_trouble();
1483 ast_unlock_contexts();
1486 /* loop thru all contexts, and verify the exten structure compares to the
1487 hashtab structure */
1488 for(c2=contexts;c2;c2=c2->next) {
1489 c1 = find_context_locked(c2->name);
1491 ast_unlock_contexts();
1493 /* is every entry in the root list also in the root_table? */
1494 for(e1 = c1->root; e1; e1=e1->next)
1496 char dummy_name[1024];
1497 ex.exten = dummy_name;
1498 ex.matchcid = e1->matchcid;
1499 ex.cidmatch = e1->cidmatch;
1500 ast_copy_string(dummy_name, e1->exten, sizeof(dummy_name));
1501 e2 = ast_hashtab_lookup(c1->root_table, &ex);
1503 if (e1->matchcid == AST_EXT_MATCHCID_ON) {
1504 ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context records the exten %s (CID match: %s) but it is not in its root_table\n", file, line, c2->name, dummy_name, e1->cidmatch );
1506 ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context records the exten %s but it is not in its root_table\n", file, line, c2->name, dummy_name );
1508 check_contexts_trouble();
1512 /* is every entry in the root_table also in the root list? */
1513 if (!c2->root_table) {
1515 ast_log(LOG_NOTICE,"Called from: %s:%d: No c2->root_table for context %s!\n", file, line, c2->name);
1519 t1 = ast_hashtab_start_traversal(c2->root_table);
1520 while( (e2 = ast_hashtab_next(t1)) ) {
1521 for(e1=c2->root;e1;e1=e1->next) {
1522 if (!strcmp(e1->exten, e2->exten)) {
1528 ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context records the exten %s but it is not in its root_table\n", file, line, c2->name, e2->exten);
1529 check_contexts_trouble();
1533 ast_hashtab_end_traversal(t1);
1536 /* is every priority reflected in the peer_table at the head of the list? */
1538 /* is every entry in the root list also in the root_table? */
1539 /* are the per-extension peer_tables in the right place? */
1541 for(e1 = c2->root; e1; e1 = e1->next) {
1543 for(e2=e1;e2;e2=e2->peer) {
1544 ex.priority = e2->priority;
1545 if (e2 != e1 && e2->peer_table) {
1546 ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority has a peer_table entry, and shouldn't!\n", file, line, c2->name, e1->exten, e2->priority );
1547 check_contexts_trouble();
1550 if (e2 != e1 && e2->peer_label_table) {
1551 ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority has a peer_label_table entry, and shouldn't!\n", file, line, c2->name, e1->exten, e2->priority );
1552 check_contexts_trouble();
1555 if (e2 == e1 && !e2->peer_table){
1556 ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority doesn't have a peer_table!\n", file, line, c2->name, e1->exten, e2->priority );
1557 check_contexts_trouble();
1560 if (e2 == e1 && !e2->peer_label_table) {
1561 ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority doesn't have a peer_label_table!\n", file, line, c2->name, e1->exten, e2->priority );
1562 check_contexts_trouble();
1566 e3 = ast_hashtab_lookup(e1->peer_table, &ex);
1568 ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority is not reflected in the peer_table\n", file, line, c2->name, e1->exten, e2->priority );
1569 check_contexts_trouble();
1573 if (!e1->peer_table){
1574 ast_log(LOG_NOTICE,"Called from: %s:%d: No e1->peer_table!\n", file, line);
1578 /* is every entry in the peer_table also in the peer list? */
1579 t1 = ast_hashtab_start_traversal(e1->peer_table);
1580 while( (e2 = ast_hashtab_next(t1)) ) {
1581 for(e3=e1;e3;e3=e3->peer) {
1582 if (e3->priority == e2->priority) {
1588 ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority is not reflected in the peer list\n", file, line, c2->name, e1->exten, e2->priority );
1589 check_contexts_trouble();
1592 ast_hashtab_end_traversal(t1);
1600 \note This function is special. It saves the stack so that no matter
1601 how many times it is called, it returns to the same place */
1602 int pbx_exec(struct ast_channel *c, /*!< Channel */
1603 struct ast_app *app, /*!< Application */
1604 const char *data) /*!< Data for execution */
1607 struct ast_module_user *u = NULL;
1608 const char *saved_c_appl;
1609 const char *saved_c_data;
1611 /* save channel values */
1612 saved_c_appl= ast_channel_appl(c);
1613 saved_c_data= ast_channel_data(c);
1615 ast_channel_appl_set(c, app->name);
1616 ast_channel_data_set(c, data);
1617 ast_channel_publish_snapshot(c);
1620 u = __ast_module_user_add(app->module, c);
1621 res = app->execute(c, S_OR(data, ""));
1622 if (app->module && u)
1623 __ast_module_user_remove(app->module, u);
1624 /* restore channel values */
1625 ast_channel_appl_set(c, saved_c_appl);
1626 ast_channel_data_set(c, saved_c_data);
1631 /*! Go no deeper than this through includes (not counting loops) */
1632 #define AST_PBX_MAX_STACK 128
1634 static struct ast_app *pbx_findapp_nolock(const char *name)
1636 struct ast_app *cur;
1639 AST_RWLIST_TRAVERSE(&apps, cur, list) {
1640 cmp = strcasecmp(name, cur->name);
1648 /* Not in container. */
1656 struct ast_app *pbx_findapp(const char *app)
1658 struct ast_app *ret;
1660 AST_RWLIST_RDLOCK(&apps);
1661 ret = pbx_findapp_nolock(app);
1662 AST_RWLIST_UNLOCK(&apps);
1667 static struct ast_switch *pbx_findswitch(const char *sw)
1669 struct ast_switch *asw;
1671 AST_RWLIST_RDLOCK(&switches);
1672 AST_RWLIST_TRAVERSE(&switches, asw, list) {
1673 if (!strcasecmp(asw->name, sw))
1676 AST_RWLIST_UNLOCK(&switches);
1681 static inline int include_valid(struct ast_include *i)
1686 return ast_check_timing(&(i->timing));
1689 static void pbx_destroy(struct ast_pbx *p)
1694 /* form a tree that fully describes all the patterns in a context's extensions
1695 * in this tree, a "node" represents an individual character or character set
1696 * meant to match the corresponding character in a dial string. The tree
1697 * consists of a series of match_char structs linked in a chain
1698 * via the alt_char pointers. More than one pattern can share the same parts of the
1699 * tree as other extensions with the same pattern to that point.
1700 * My first attempt to duplicate the finding of the 'best' pattern was flawed in that
1701 * I misunderstood the general algorithm. I thought that the 'best' pattern
1702 * was the one with lowest total score. This was not true. Thus, if you have
1703 * patterns "1XXXXX" and "X11111", you would be tempted to say that "X11111" is
1704 * the "best" match because it has fewer X's, and is therefore more specific,
1705 * but this is not how the old algorithm works. It sorts matching patterns
1706 * in a similar collating sequence as sorting alphabetic strings, from left to
1707 * right. Thus, "1XXXXX" comes before "X11111", and would be the "better" match,
1708 * because "1" is more specific than "X".
1709 * So, to accomodate this philosophy, I sort the tree branches along the alt_char
1710 * line so they are lowest to highest in specificity numbers. This way, as soon
1711 * as we encounter our first complete match, we automatically have the "best"
1712 * match and can stop the traversal immediately. Same for CANMATCH/MATCHMORE.
1713 * If anyone would like to resurrect the "wrong" pattern trie searching algorithm,
1714 * they are welcome to revert pbx to before 1 Apr 2008.
1715 * As an example, consider these 4 extensions:
1721 * In the above, between (a) and (d), (a) is a more specific pattern than (d), and would win over
1722 * most numbers. For all numbers beginning with 307754, (b) should always win.
1724 * These pattern should form a (sorted) tree that looks like this:
1725 * { "3" } --next--> { "0" } --next--> { "7" } --next--> { "7" } --next--> { "5" } ... blah ... --> { "X" exten_match: (b) }
1729 * { "f" } --next--> { "a" } --next--> { "x" exten_match: (c) }
1730 * { "N" } --next--> { "X" } --next--> { "X" } --next--> { "N" } --next--> { "X" } ... blah ... --> { "X" exten_match: (a) }
1734 * | { "X" } --next--> { "X" } ... blah ... --> { "X" exten_match: (d) }
1738 * In the above, I could easily turn "N" into "23456789", but I think that a quick "if( *z >= '2' && *z <= '9' )" might take
1739 * fewer CPU cycles than a call to strchr("23456789",*z), where *z is the char to match...
1741 * traversal is pretty simple: one routine merely traverses the alt list, and for each matching char in the pattern, it calls itself
1742 * on the corresponding next pointer, incrementing also the pointer of the string to be matched, and passing the total specificity and length.
1743 * We pass a pointer to a scoreboard down through, also.
1744 * The scoreboard isn't as necessary to the revised algorithm, but I kept it as a handy way to return the matched extension.
1745 * The first complete match ends the traversal, which should make this version of the pattern matcher faster
1746 * the previous. The same goes for "CANMATCH" or "MATCHMORE"; the first such match ends the traversal. In both
1747 * these cases, the reason we can stop immediately, is because the first pattern match found will be the "best"
1748 * according to the sort criteria.
1749 * Hope the limit on stack depth won't be a problem... this routine should
1750 * be pretty lean as far a stack usage goes. Any non-match terminates the recursion down a branch.
1752 * In the above example, with the number "3077549999" as the pattern, the traversor could match extensions a, b and d. All are
1753 * of length 10; they have total specificities of 24580, 10246, and 25090, respectively, not that this matters
1754 * at all. (b) wins purely because the first character "3" is much more specific (lower specificity) than "N". I have
1755 * left the specificity totals in the code as an artifact; at some point, I will strip it out.
1757 * Just how much time this algorithm might save over a plain linear traversal over all possible patterns is unknown,
1758 * because it's a function of how many extensions are stored in a context. With thousands of extensions, the speedup
1759 * can be very noticeable. The new matching algorithm can run several hundreds of times faster, if not a thousand or
1760 * more times faster in extreme cases.
1762 * MatchCID patterns are also supported, and stored in the tree just as the extension pattern is. Thus, you
1763 * can have patterns in your CID field as well.
1768 static void update_scoreboard(struct scoreboard *board, int length, int spec, struct ast_exten *exten, char last, const char *callerid, int deleted, struct match_char *node)
1770 /* if this extension is marked as deleted, then skip this -- if it never shows
1771 on the scoreboard, it will never be found, nor will halt the traversal. */
1774 board->total_specificity = spec;
1775 board->total_length = length;
1776 board->exten = exten;
1777 board->last_char = last;
1779 #ifdef NEED_DEBUG_HERE
1780 ast_log(LOG_NOTICE,"Scoreboarding (LONGER) %s, len=%d, score=%d\n", exten->exten, length, spec);
1785 static void log_match_char_tree(struct match_char *node, char *prefix)
1788 struct ast_str *my_prefix = ast_str_alloca(1024);
1792 if (node && node->exten)
1793 snprintf(extenstr, sizeof(extenstr), "(%p)", node->exten);
1795 if (strlen(node->x) > 1) {
1796 ast_debug(1, "%s[%s]:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y':'N',
1797 node->deleted? 'D':'-', node->specificity, node->exten? "EXTEN:":"",
1798 node->exten ? node->exten->exten : "", extenstr);
1800 ast_debug(1, "%s%s:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y':'N',
1801 node->deleted? 'D':'-', node->specificity, node->exten? "EXTEN:":"",
1802 node->exten ? node->exten->exten : "", extenstr);
1805 ast_str_set(&my_prefix, 0, "%s+ ", prefix);
1807 if (node->next_char)
1808 log_match_char_tree(node->next_char, ast_str_buffer(my_prefix));
1811 log_match_char_tree(node->alt_char, prefix);
1815 static void cli_match_char_tree(struct match_char *node, char *prefix, int fd)
1818 struct ast_str *my_prefix = ast_str_alloca(1024);
1823 snprintf(extenstr, sizeof(extenstr), "(%p)", node->exten);
1826 if (strlen(node->x) > 1) {
1827 ast_cli(fd, "%s[%s]:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y' : 'N',
1828 node->deleted ? 'D' : '-', node->specificity, node->exten? "EXTEN:" : "",
1829 node->exten ? node->exten->exten : "", extenstr);
1831 ast_cli(fd, "%s%s:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y' : 'N',
1832 node->deleted ? 'D' : '-', node->specificity, node->exten? "EXTEN:" : "",
1833 node->exten ? node->exten->exten : "", extenstr);
1836 ast_str_set(&my_prefix, 0, "%s+ ", prefix);
1838 if (node->next_char)
1839 cli_match_char_tree(node->next_char, ast_str_buffer(my_prefix), fd);
1842 cli_match_char_tree(node->alt_char, prefix, fd);
1845 static struct ast_exten *get_canmatch_exten(struct match_char *node)
1847 /* find the exten at the end of the rope */
1848 struct match_char *node2 = node;
1850 for (node2 = node; node2; node2 = node2->next_char) {
1852 #ifdef NEED_DEBUG_HERE
1853 ast_log(LOG_NOTICE,"CanMatch_exten returns exten %s(%p)\n", node2->exten->exten, node2->exten);
1855 return node2->exten;
1858 #ifdef NEED_DEBUG_HERE
1859 ast_log(LOG_NOTICE,"CanMatch_exten returns NULL, match_char=%s\n", node->x);
1864 static struct ast_exten *trie_find_next_match(struct match_char *node)
1866 struct match_char *m3;
1867 struct match_char *m4;
1868 struct ast_exten *e3;
1870 if (node && node->x[0] == '.' && !node->x[1]) { /* dot and ! will ALWAYS be next match in a matchmore */
1874 if (node && node->x[0] == '!' && !node->x[1]) {
1878 if (!node || !node->next_char) {
1882 m3 = node->next_char;
1887 for (m4 = m3->alt_char; m4; m4 = m4->alt_char) {
1892 for (m4 = m3; m4; m4 = m4->alt_char) {
1893 e3 = trie_find_next_match(m3);
1903 static char *action2str(enum ext_match_t action)
1923 static void new_find_extension(const char *str, struct scoreboard *score, struct match_char *tree, int length, int spec, const char *callerid, const char *label, enum ext_match_t action)
1925 struct match_char *p; /* note minimal stack storage requirements */
1926 struct ast_exten pattern = { .label = label };
1929 ast_log(LOG_NOTICE,"new_find_extension called with %s on (sub)tree %s action=%s\n", str, tree->x, action2str(action));
1931 ast_log(LOG_NOTICE,"new_find_extension called with %s on (sub)tree NULL action=%s\n", str, action2str(action));
1933 for (p = tree; p; p = p->alt_char) {
1934 if (p->is_pattern) {
1935 if (p->x[0] == 'N') {
1936 if (p->x[1] == 0 && *str >= '2' && *str <= '9' ) {
1937 #define NEW_MATCHER_CHK_MATCH \
1938 if (p->exten && !(*(str + 1))) { /* if a shorter pattern matches along the way, might as well report it */ \
1939 if (action == E_MATCH || action == E_SPAWN || action == E_FINDLABEL) { /* if in CANMATCH/MATCHMORE, don't let matches get in the way */ \
1940 update_scoreboard(score, length + 1, spec + p->specificity, p->exten, 0, callerid, p->deleted, p); \
1941 if (!p->deleted) { \
1942 if (action == E_FINDLABEL) { \
1943 if (ast_hashtab_lookup(score->exten->peer_label_table, &pattern)) { \
1944 ast_debug(4, "Found label in preferred extension\n"); \
1948 ast_debug(4, "returning an exact match-- first found-- %s\n", p->exten->exten); \
1949 return; /* the first match, by definition, will be the best, because of the sorted tree */ \
1955 #define NEW_MATCHER_RECURSE \
1956 if (p->next_char && (*(str + 1) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0) \
1957 || p->next_char->x[0] == '!')) { \
1958 if (*(str + 1) || p->next_char->x[0] == '!') { \
1959 new_find_extension(str + 1, score, p->next_char, length + 1, spec + p->specificity, callerid, label, action); \
1960 if (score->exten) { \
1961 ast_debug(4 ,"returning an exact match-- %s\n", score->exten->exten); \
1962 return; /* the first match is all we need */ \
1965 new_find_extension("/", score, p->next_char, length + 1, spec + p->specificity, callerid, label, action); \
1966 if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) { \
1967 ast_debug(4,"returning a (can/more) match--- %s\n", score->exten ? score->exten->exten : \
1969 return; /* the first match is all we need */ \
1972 } else if ((p->next_char || action == E_CANMATCH) && !*(str + 1)) { \
1973 score->canmatch = 1; \
1974 score->canmatch_exten = get_canmatch_exten(p); \
1975 if (action == E_CANMATCH || action == E_MATCHMORE) { \
1976 ast_debug(4, "returning a canmatch/matchmore--- str=%s\n", str); \
1981 NEW_MATCHER_CHK_MATCH;
1982 NEW_MATCHER_RECURSE;
1984 } else if (p->x[0] == 'Z') {
1985 if (p->x[1] == 0 && *str >= '1' && *str <= '9' ) {
1986 NEW_MATCHER_CHK_MATCH;
1987 NEW_MATCHER_RECURSE;
1989 } else if (p->x[0] == 'X') {
1990 if (p->x[1] == 0 && *str >= '0' && *str <= '9' ) {
1991 NEW_MATCHER_CHK_MATCH;
1992 NEW_MATCHER_RECURSE;
1994 } else if (p->x[0] == '.' && p->x[1] == 0) {
1995 /* how many chars will the . match against? */
1997 const char *str2 = str;
1998 while (*str2 && *str2 != '/') {
2002 if (p->exten && *str2 != '/') {
2003 update_scoreboard(score, length + i, spec + (i * p->specificity), p->exten, '.', callerid, p->deleted, p);
2005 ast_debug(4,"return because scoreboard has a match with '/'--- %s\n", score->exten->exten);
2006 return; /* the first match is all we need */
2009 if (p->next_char && p->next_char->x[0] == '/' && p->next_char->x[1] == 0) {
2010 new_find_extension("/", score, p->next_char, length + i, spec+(p->specificity*i), callerid, label, action);
2011 if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) {
2012 ast_debug(4, "return because scoreboard has exact match OR CANMATCH/MATCHMORE & canmatch set--- %s\n", score->exten ? score->exten->exten : "NULL");
2013 return; /* the first match is all we need */
2016 } else if (p->x[0] == '!' && p->x[1] == 0) {
2017 /* how many chars will the . match against? */
2019 const char *str2 = str;
2020 while (*str2 && *str2 != '/') {
2024 if (p->exten && *str2 != '/') {
2025 update_scoreboard(score, length + 1, spec + (p->specificity * i), p->exten, '!', callerid, p->deleted, p);
2027 ast_debug(4, "return because scoreboard has a '!' match--- %s\n", score->exten->exten);
2028 return; /* the first match is all we need */
2031 if (p->next_char && p->next_char->x[0] == '/' && p->next_char->x[1] == 0) {
2032 new_find_extension("/", score, p->next_char, length + i, spec + (p->specificity * i), callerid, label, action);
2033 if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) {
2034 ast_debug(4, "return because scoreboard has exact match OR CANMATCH/MATCHMORE & canmatch set with '/' and '!'--- %s\n", score->exten ? score->exten->exten : "NULL");
2035 return; /* the first match is all we need */
2038 } else if (p->x[0] == '/' && p->x[1] == 0) {
2039 /* the pattern in the tree includes the cid match! */
2040 if (p->next_char && callerid && *callerid) {
2041 new_find_extension(callerid, score, p->next_char, length + 1, spec, callerid, label, action);
2042 if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) {
2043 ast_debug(4, "return because scoreboard has exact match OR CANMATCH/MATCHMORE & canmatch set with '/'--- %s\n", score->exten ? score->exten->exten : "NULL");
2044 return; /* the first match is all we need */
2047 } else if (strchr(p->x, *str)) {
2048 ast_debug(4, "Nothing strange about this match\n");
2049 NEW_MATCHER_CHK_MATCH;
2050 NEW_MATCHER_RECURSE;
2052 } else if (strchr(p->x, *str)) {
2053 ast_debug(4, "Nothing strange about this match\n");
2054 NEW_MATCHER_CHK_MATCH;
2055 NEW_MATCHER_RECURSE;
2058 ast_debug(4, "return at end of func\n");
2061 /* the algorithm for forming the extension pattern tree is also a bit simple; you
2062 * traverse all the extensions in a context, and for each char of the extension,
2063 * you see if it exists in the tree; if it doesn't, you add it at the appropriate
2064 * spot. What more can I say? At the end of each exten, you cap it off by adding the
2065 * address of the extension involved. Duplicate patterns will be complained about.
2067 * Ideally, this would be done for each context after it is created and fully
2068 * filled. It could be done as a finishing step after extensions.conf or .ael is
2069 * loaded, or it could be done when the first search is encountered. It should only
2070 * have to be done once, until the next unload or reload.
2072 * I guess forming this pattern tree would be analogous to compiling a regex. Except
2073 * that a regex only handles 1 pattern, really. This trie holds any number
2074 * of patterns. Well, really, it **could** be considered a single pattern,
2075 * where the "|" (or) operator is allowed, I guess, in a way, sort of...
2078 static struct match_char *already_in_tree(struct match_char *current, char *pat, int is_pattern)
2080 struct match_char *t;
2086 for (t = current; t; t = t->alt_char) {
2087 if (is_pattern == t->is_pattern && !strcmp(pat, t->x)) {/* uh, we may want to sort exploded [] contents to make matching easy */
2095 /* The first arg is the location of the tree ptr, or the
2096 address of the next_char ptr in the node, so we can mess
2097 with it, if we need to insert at the beginning of the list */
2099 static void insert_in_next_chars_alt_char_list(struct match_char **parent_ptr, struct match_char *node)
2101 struct match_char *curr, *lcurr;
2103 /* insert node into the tree at "current", so the alt_char list from current is
2104 sorted in increasing value as you go to the leaves */
2105 if (!(*parent_ptr)) {
2110 if ((*parent_ptr)->specificity > node->specificity) {
2111 /* insert at head */
2112 node->alt_char = (*parent_ptr);
2117 lcurr = *parent_ptr;
2118 for (curr = (*parent_ptr)->alt_char; curr; curr = curr->alt_char) {
2119 if (curr->specificity > node->specificity) {
2120 node->alt_char = curr;
2121 lcurr->alt_char = node;
2128 lcurr->alt_char = node;
2133 struct pattern_node {
2134 /*! Pattern node specificity */
2136 /*! Pattern node match characters. */
2140 static struct match_char *add_pattern_node(struct ast_context *con, struct match_char *current, const struct pattern_node *pattern, int is_pattern, int already, struct match_char **nextcharptr)
2142 struct match_char *m;
2144 if (!(m = ast_calloc(1, sizeof(*m) + strlen(pattern->buf)))) {
2148 /* strcpy is safe here since we know its size and have allocated
2149 * just enough space for when we allocated m
2151 strcpy(m->x, pattern->buf);
2153 /* the specificity scores are the same as used in the old
2155 m->is_pattern = is_pattern;
2156 if (pattern->specif == 1 && is_pattern && pattern->buf[0] == 'N') {
2157 m->specificity = 0x0832;
2158 } else if (pattern->specif == 1 && is_pattern && pattern->buf[0] == 'Z') {
2159 m->specificity = 0x0931;
2160 } else if (pattern->specif == 1 && is_pattern && pattern->buf[0] == 'X') {
2161 m->specificity = 0x0a30;
2162 } else if (pattern->specif == 1 && is_pattern && pattern->buf[0] == '.') {
2163 m->specificity = 0x18000;
2164 } else if (pattern->specif == 1 && is_pattern && pattern->buf[0] == '!') {
2165 m->specificity = 0x28000;
2167 m->specificity = pattern->specif;
2170 if (!con->pattern_tree) {
2171 insert_in_next_chars_alt_char_list(&con->pattern_tree, m);
2173 if (already) { /* switch to the new regime (traversing vs appending)*/
2174 insert_in_next_chars_alt_char_list(nextcharptr, m);
2176 insert_in_next_chars_alt_char_list(¤t->next_char, m);
2185 * \brief Extract the next exten pattern node.
2187 * \param node Pattern node to fill.
2188 * \param src Next source character to read.
2189 * \param pattern TRUE if the exten is a pattern.
2190 * \param extenbuf Original exten buffer to use in diagnostic messages.
2192 * \retval Ptr to next extenbuf pos to read.
2194 static const char *get_pattern_node(struct pattern_node *node, const char *src, int pattern, const char *extenbuf)
2196 #define INC_DST_OVERFLOW_CHECK \
2198 if (dst - node->buf < sizeof(node->buf) - 1) { \
2206 node->buf[0] = '\0';
2208 if (*src == '[' && pattern) {
2209 char *dst = node->buf;
2210 const char *src_next;
2214 /* get past the '[' */
2218 /* Escaped character. */
2220 if (*src == '[' || *src == '\\' || *src == '-' || *src == ']') {
2222 INC_DST_OVERFLOW_CHECK;
2224 } else if (*src == '-') {
2225 unsigned char first;
2229 first = *(src_next - 1);
2233 /* Escaped character. */
2237 /* Possible char range. */
2238 if (node->buf[0] && last) {
2239 /* Expand the char range. */
2240 while (++first <= last) {
2242 INC_DST_OVERFLOW_CHECK;
2247 * There was no left or right char for the range.
2251 INC_DST_OVERFLOW_CHECK;
2253 } else if (*src == '\0') {
2254 ast_log(LOG_WARNING,
2255 "A matching ']' was not found for '[' in exten pattern '%s'\n",
2258 } else if (*src == ']') {
2263 INC_DST_OVERFLOW_CHECK;
2266 /* null terminate the exploded range */
2271 "Expanded character set too large to deal with in exten pattern '%s'. Ignoring character set.\n",
2273 node->buf[0] = '\0';
2277 /* Sort the characters in character set. */
2278 length = strlen(node->buf);
2280 ast_log(LOG_WARNING, "Empty character set in exten pattern '%s'. Ignoring.\n",
2282 node->buf[0] = '\0';
2285 qsort(node->buf, length, 1, compare_char);
2287 /* Remove duplicate characters from character set. */
2289 src_next = node->buf;
2290 while (*src_next++) {
2291 if (*dst != *src_next) {
2296 length = strlen(node->buf);
2298 node->specif = length | (unsigned char) node->buf[0];
2300 } else if (*src == '-') {
2301 /* Skip dashes in all extensions. */
2306 * XXX The escape character here does not remove any special
2307 * meaning to characters except the '[', '\\', and '-'
2308 * characters since they are special only in this function.
2310 node->buf[0] = *++src;
2311 if (!node->buf[0]) {
2315 node->buf[0] = *src;
2317 /* make sure n,x,z patterns are canonicalized to N,X,Z */
2318 if (node->buf[0] == 'n') {
2320 } else if (node->buf[0] == 'x') {
2322 } else if (node->buf[0] == 'z') {
2327 node->buf[1] = '\0';
2335 #undef INC_DST_OVERFLOW_CHECK
2338 static struct match_char *add_exten_to_pattern_tree(struct ast_context *con, struct ast_exten *e1, int findonly)
2340 struct match_char *m1 = NULL;
2341 struct match_char *m2 = NULL;
2342 struct match_char **m0;
2349 struct pattern_node pat_node[2];
2352 if (sizeof(extenbuf) < strlen(e1->exten) + strlen(e1->cidmatch) + 2) {
2354 "The pattern %s/%s is too big to deal with: it will be ignored! Disaster!\n",
2355 e1->exten, e1->cidmatch);
2358 sprintf(extenbuf, "%s/%s", e1->exten, e1->cidmatch);/* Safe. We just checked. */
2360 ast_copy_string(extenbuf, e1->exten, sizeof(extenbuf));
2364 ast_debug(1, "Adding exten %s to tree\n", extenbuf);
2366 m1 = con->pattern_tree; /* each pattern starts over at the root of the pattern tree */
2367 m0 = &con->pattern_tree;
2376 pos = get_pattern_node(&pat_node[idx_cur], pos, pattern, extenbuf);
2377 for (; pat_node[idx_cur].buf[0]; idx_cur = idx_next) {
2378 idx_next = (idx_cur + 1) % ARRAY_LEN(pat_node);
2379 pos = get_pattern_node(&pat_node[idx_next], pos, pattern, extenbuf);
2381 /* See about adding node to tree. */
2383 if (already && (m2 = already_in_tree(m1, pat_node[idx_cur].buf, pattern))
2385 if (!pat_node[idx_next].buf[0]) {
2387 * This is the end of the pattern, but not the end of the tree.
2388 * Mark this node with the exten... a shorter pattern might win
2389 * if the longer one doesn't match.
2395 ast_log(LOG_WARNING, "Found duplicate exten. Had %s found %s\n",
2396 m2->deleted ? "(deleted/invalid)" : m2->exten->exten, e1->exten);
2401 m1 = m2->next_char; /* m1 points to the node to compare against */
2402 m0 = &m2->next_char; /* m0 points to the ptr that points to m1 */
2403 } else { /* not already OR not m2 OR nor m2->next_char */
2408 m1 = m2; /* while m0 stays the same */
2413 m1 = add_pattern_node(con, m1, &pat_node[idx_cur], pattern, already, m0);
2414 if (!m1) { /* m1 is the node just added */
2417 m0 = &m1->next_char;
2419 if (!pat_node[idx_next].buf[0]) {
2420 if (m2 && m2->exten) {
2421 ast_log(LOG_WARNING, "Found duplicate exten. Had %s found %s\n",
2422 m2->deleted ? "(deleted/invalid)" : m2->exten->exten, e1->exten);
2428 /* The 'already' variable is a mini-optimization designed to make it so that we
2429 * don't have to call already_in_tree when we know it will return false.
2437 static void create_match_char_tree(struct ast_context *con)
2439 struct ast_hashtab_iter *t1;
2440 struct ast_exten *e1;
2442 int biggest_bucket, resizes, numobjs, numbucks;
2444 ast_debug(1, "Creating Extension Trie for context %s(%p)\n", con->name, con);
2445 ast_hashtab_get_stats(con->root_table, &biggest_bucket, &resizes, &numobjs, &numbucks);
2446 ast_debug(1, "This tree has %d objects in %d bucket lists, longest list=%d objects, and has resized %d times\n",
2447 numobjs, numbucks, biggest_bucket, resizes);
2449 t1 = ast_hashtab_start_traversal(con->root_table);
2450 while ((e1 = ast_hashtab_next(t1))) {
2452 add_exten_to_pattern_tree(con, e1, 0);
2454 ast_log(LOG_ERROR, "Attempt to create extension with no extension name.\n");
2457 ast_hashtab_end_traversal(t1);
2460 static void destroy_pattern_tree(struct match_char *pattern_tree) /* pattern tree is a simple binary tree, sort of, so the proper way to destroy it is... recursively! */
2462 /* destroy all the alternates */
2463 if (pattern_tree->alt_char) {
2464 destroy_pattern_tree(pattern_tree->alt_char);
2465 pattern_tree->alt_char = 0;
2467 /* destroy all the nexts */
2468 if (pattern_tree->next_char) {
2469 destroy_pattern_tree(pattern_tree->next_char);
2470 pattern_tree->next_char = 0;
2472 pattern_tree->exten = 0; /* never hurts to make sure there's no pointers laying around */
2473 ast_free(pattern_tree);
2478 * \brief Get the length of the exten string.
2480 * \param str Exten to get length.
2482 * \retval strlen of exten.
2484 static int ext_cmp_exten_strlen(const char *str)
2490 /* Ignore '-' chars as eye candy fluff. */
2491 while (*str == '-') {
2505 * \brief Partial comparison of non-pattern extens.
2507 * \param left Exten to compare.
2508 * \param right Exten to compare. Also matches if this string ends first.
2510 * \retval <0 if left < right
2511 * \retval =0 if left == right
2512 * \retval >0 if left > right
2514 static int ext_cmp_exten_partial(const char *left, const char *right)
2519 /* Ignore '-' chars as eye candy fluff. */
2520 while (*left == '-') {
2523 while (*right == '-') {
2529 * Right ended first for partial match or both ended at the same
2536 cmp = *left - *right;
2548 * \brief Comparison of non-pattern extens.
2550 * \param left Exten to compare.
2551 * \param right Exten to compare.
2553 * \retval <0 if left < right
2554 * \retval =0 if left == right
2555 * \retval >0 if left > right
2557 static int ext_cmp_exten(const char *left, const char *right)
2562 /* Ignore '-' chars as eye candy fluff. */
2563 while (*left == '-') {
2566 while (*right == '-') {
2570 cmp = *left - *right;
2576 * Get here only if both strings ended at the same time. cmp
2577 * would be non-zero if only one string ended.
2588 * Special characters used in patterns:
2589 * '_' underscore is the leading character of a pattern.
2590 * In other position it is treated as a regular char.
2591 * '-' The '-' is a separator and ignored. Why? So patterns like NXX-XXX-XXXX work.
2592 * . one or more of any character. Only allowed at the end of
2594 * ! zero or more of anything. Also impacts the result of CANMATCH
2595 * and MATCHMORE. Only allowed at the end of a pattern.
2596 * In the core routine, ! causes a match with a return code of 2.
2597 * In turn, depending on the search mode: (XXX check if it is implemented)
2598 * - E_MATCH retuns 1 (does match)
2599 * - E_MATCHMORE returns 0 (no match)
2600 * - E_CANMATCH returns 1 (does match)
2602 * / should not appear as it is considered the separator of the CID info.
2603 * XXX at the moment we may stop on this char.
2605 * X Z N match ranges 0-9, 1-9, 2-9 respectively.
2606 * [ denotes the start of a set of character. Everything inside
2607 * is considered literally. We can have ranges a-d and individual
2608 * characters. A '[' and '-' can be considered literally if they
2609 * are just before ']'.
2610 * XXX currently there is no way to specify ']' in a range, nor \ is
2611 * considered specially.
2613 * When we compare a pattern with a specific extension, all characters in the extension
2614 * itself are considered literally.
2615 * XXX do we want to consider space as a separator as well ?
2616 * XXX do we want to consider the separators in non-patterns as well ?
2620 * \brief helper functions to sort extension patterns in the desired way,
2621 * so that more specific patterns appear first.
2624 * The function compares individual characters (or sets of), returning
2625 * an int where bits 0-7 are the ASCII code of the first char in the set,
2626 * bits 8-15 are the number of characters in the set, and bits 16-20 are
2627 * for special cases.
2628 * This way more specific patterns (smaller character sets) appear first.
2629 * Wildcards have a special value, so that we can directly compare them to
2630 * sets by subtracting the two values. In particular:
2631 * 0x001xx one character, character set starting with xx
2632 * 0x0yyxx yy characters, character set starting with xx
2633 * 0x18000 '.' (one or more of anything)
2634 * 0x28000 '!' (zero or more of anything)
2635 * 0x30000 NUL (end of string)
2636 * 0x40000 error in set.
2637 * The pointer to the string is advanced according to needs.
2639 * 1. the empty set is ignored.
2640 * 2. given that a full set has always 0 as the first element,
2641 * we could encode the special cases as 0xffXX where XX
2642 * is 1, 2, 3, 4 as used above.
2644 static int ext_cmp_pattern_pos(const char **p, unsigned char *bitwise)
2646 #define BITS_PER 8 /* Number of bits per unit (byte). */
2653 /* Get character and advance. (Ignore '-' chars as eye candy fluff.) */
2658 /* always return unless we have a set of chars */
2661 /* ordinary character */
2662 bitwise[c / BITS_PER] = 1 << ((BITS_PER - 1) - (c % BITS_PER));
2670 return 0x0800 | '2';
2677 return 0x0A00 | '0';
2684 return 0x0900 | '1';
2692 return 0x28000; /* less specific than '.' */
2703 /* locate end of set */
2704 end = strchr(*p, ']');
2707 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
2708 return 0x40000; /* XXX make this entry go last... */
2713 for (; *p < end; ++*p) {
2714 unsigned char c1; /* first char in range */
2715 unsigned char c2; /* last char in range */
2718 if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */
2720 *p += 2; /* skip a total of 3 chars */
2721 } else { /* individual character */
2727 for (; c1 <= c2; ++c1) {
2728 unsigned char mask = 1 << ((BITS_PER - 1) - (c1 % BITS_PER));
2731 * Note: If two character sets score the same, the one with the
2732 * lowest ASCII values will compare as coming first. Must fill
2733 * in most significant bits for lower ASCII values to accomplish
2734 * the desired sort order.
2736 if (!(bitwise[c1 / BITS_PER] & mask)) {
2737 /* Add the character to the set. */
2738 bitwise[c1 / BITS_PER] |= mask;
2744 } while (!count);/* While the char set was empty. */
2745 return count | cmin;
2750 * \brief Comparison of exten patterns.
2752 * \param left Pattern to compare.
2753 * \param right Pattern to compare.
2755 * \retval <0 if left < right
2756 * \retval =0 if left == right
2757 * \retval >0 if left > right
2759 static int ext_cmp_pattern(const char *left, const char *right)
2766 unsigned char left_bitwise[32] = { 0, };
2767 unsigned char right_bitwise[32] = { 0, };
2769 left_pos = ext_cmp_pattern_pos(&left, left_bitwise);
2770 right_pos = ext_cmp_pattern_pos(&right, right_bitwise);
2771 cmp = left_pos - right_pos;
2774 * Are the character sets different, even though they score the same?
2776 * Note: Must swap left and right to get the sense of the
2777 * comparison correct. Otherwise, we would need to multiply by
2780 cmp = memcmp(right_bitwise, left_bitwise, ARRAY_LEN(left_bitwise));
2787 * Get here only if both patterns ended at the same time. cmp
2788 * would be non-zero if only one pattern ended.
2798 * \brief Comparison of dialplan extens for sorting purposes.
2800 * \param left Exten/pattern to compare.
2801 * \param right Exten/pattern to compare.
2803 * \retval <0 if left < right
2804 * \retval =0 if left == right
2805 * \retval >0 if left > right
2807 static int ext_cmp(const char *left, const char *right)
2809 /* Make sure non-pattern extens come first. */
2810 if (left[0] != '_') {
2811 if (right[0] == '_') {
2814 /* Compare two non-pattern extens. */
2815 return ext_cmp_exten(left, right);
2817 if (right[0] != '_') {
2822 * OK, we need full pattern sorting routine.
2824 * Skip past the underscores
2826 return ext_cmp_pattern(left + 1, right + 1);
2829 int ast_extension_cmp(const char *a, const char *b)
2833 cmp = ext_cmp(a, b);
2845 * \brief used ast_extension_{match|close}
2846 * mode is as follows:
2847 * E_MATCH success only on exact match
2848 * E_MATCHMORE success only on partial match (i.e. leftover digits in pattern)
2849 * E_CANMATCH either of the above.
2850 * \retval 0 on no-match
2851 * \retval 1 on match
2852 * \retval 2 on early match.
2855 static int _extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
2857 mode &= E_MATCH_MASK; /* only consider the relevant bits */
2859 #ifdef NEED_DEBUG_HERE
2860 ast_log(LOG_NOTICE,"match core: pat: '%s', dat: '%s', mode=%d\n", pattern, data, (int)mode);
2863 if (pattern[0] != '_') { /* not a pattern, try exact or partial match */
2864 int lp = ext_cmp_exten_strlen(pattern);
2865 int ld = ext_cmp_exten_strlen(data);
2867 if (lp < ld) { /* pattern too short, cannot match */
2868 #ifdef NEED_DEBUG_HERE
2869 ast_log(LOG_NOTICE,"return (0) - pattern too short, cannot match\n");
2873 /* depending on the mode, accept full or partial match or both */
2874 if (mode == E_MATCH) {
2875 #ifdef NEED_DEBUG_HERE
2876 ast_log(LOG_NOTICE,"return (!ext_cmp_exten(%s,%s) when mode== E_MATCH)\n", pattern, data);
2878 return !ext_cmp_exten(pattern, data); /* 1 on match, 0 on fail */
2880 if (ld == 0 || !ext_cmp_exten_partial(pattern, data)) { /* partial or full match */
2881 #ifdef NEED_DEBUG_HERE
2882 ast_log(LOG_NOTICE,"return (mode(%d) == E_MATCHMORE ? lp(%d) > ld(%d) : 1)\n", mode, lp, ld);
2884 return (mode == E_MATCHMORE) ? lp > ld : 1; /* XXX should consider '!' and '/' ? */
2886 #ifdef NEED_DEBUG_HERE
2887 ast_log(LOG_NOTICE,"return (0) when ld(%d) > 0 && pattern(%s) != data(%s)\n", ld, pattern, data);
2892 if (mode == E_MATCH && data[0] == '_') {
2894 * XXX It is bad design that we don't know if we should be
2895 * comparing data and pattern as patterns or comparing data if
2896 * it conforms to pattern when the function is called. First,
2897 * assume they are both patterns. If they don't match then try
2898 * to see if data conforms to the given pattern.
2900 * note: if this test is left out, then _x. will not match _x. !!!
2902 #ifdef NEED_DEBUG_HERE
2903 ast_log(LOG_NOTICE, "Comparing as patterns first. pattern:%s data:%s\n", pattern, data);
2905 if (!ext_cmp_pattern(pattern + 1, data + 1)) {
2906 #ifdef NEED_DEBUG_HERE
2907 ast_log(LOG_NOTICE,"return (1) - pattern matches pattern\n");
2913 ++pattern; /* skip leading _ */
2915 * XXX below we stop at '/' which is a separator for the CID info. However we should
2916 * not store '/' in the pattern at all. When we insure it, we can remove the checks.
2921 /* Ignore '-' chars as eye candy fluff. */
2922 while (*data == '-') {
2925 while (*pattern == '-') {
2928 if (!*data || !*pattern || *pattern == '/') {
2933 case '[': /* a range */
2935 end = strchr(pattern, ']'); /* XXX should deal with escapes ? */
2937 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
2938 return 0; /* unconditional failure */
2940 if (pattern == end) {
2941 /* Ignore empty character sets. */
2945 for (; pattern < end; ++pattern) {
2946 if (pattern+2 < end && pattern[1] == '-') { /* this is a range */
2947 if (*data >= pattern[0] && *data <= pattern[2])
2948 break; /* match found */
2950 pattern += 2; /* skip a total of 3 chars */
2953 } else if (*data == pattern[0])
2954 break; /* match found */
2956 if (pattern >= end) {
2957 #ifdef NEED_DEBUG_HERE
2958 ast_log(LOG_NOTICE,"return (0) when pattern>=end\n");
2962 pattern = end; /* skip and continue */
2966 if (*data < '2' || *data > '9') {
2967 #ifdef NEED_DEBUG_HERE
2968 ast_log(LOG_NOTICE,"return (0) N is not matched\n");
2975 if (*data < '0' || *data > '9') {
2976 #ifdef NEED_DEBUG_HERE
2977 ast_log(LOG_NOTICE,"return (0) X is not matched\n");
2984 if (*data < '1' || *data > '9') {
2985 #ifdef NEED_DEBUG_HERE
2986 ast_log(LOG_NOTICE,"return (0) Z is not matched\n");
2991 case '.': /* Must match, even with more digits */
2992 #ifdef NEED_DEBUG_HERE
2993 ast_log(LOG_NOTICE, "return (1) when '.' is matched\n");
2996 case '!': /* Early match */
2997 #ifdef NEED_DEBUG_HERE
2998 ast_log(LOG_NOTICE, "return (2) when '!' is matched\n");
3002 if (*data != *pattern) {
3003 #ifdef NEED_DEBUG_HERE
3004 ast_log(LOG_NOTICE, "return (0) when *data(%c) != *pattern(%c)\n", *data, *pattern);
3013 if (*data) /* data longer than pattern, no match */ {
3014 #ifdef NEED_DEBUG_HERE
3015 ast_log(LOG_NOTICE, "return (0) when data longer than pattern\n");
3021 * match so far, but ran off the end of data.
3022 * Depending on what is next, determine match or not.
3024 if (*pattern == '\0' || *pattern == '/') { /* exact match */
3025 #ifdef NEED_DEBUG_HERE
3026 ast_log(LOG_NOTICE, "at end, return (%d) in 'exact match'\n", (mode==E_MATCHMORE) ? 0 : 1);
3028 return (mode == E_MATCHMORE) ? 0 : 1; /* this is a failure for E_MATCHMORE */
3029 } else if (*pattern == '!') { /* early match */
3030 #ifdef NEED_DEBUG_HERE
3031 ast_log(LOG_NOTICE, "at end, return (2) when '!' is matched\n");
3034 } else { /* partial match */
3035 #ifdef NEED_DEBUG_HERE
3036 ast_log(LOG_NOTICE, "at end, return (%d) which deps on E_MATCH\n", (mode == E_MATCH) ? 0 : 1);
3038 return (mode == E_MATCH) ? 0 : 1; /* this is a failure for E_MATCH */
3043 * Wrapper around _extension_match_core() to do performance measurement
3044 * using the profiling code.
3046 static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
3049 static int prof_id = -2; /* marker for 'unallocated' id */
3050 if (prof_id == -2) {
3051 prof_id = ast_add_profile("ext_match", 0);
3053 ast_mark(prof_id, 1);
3054 i = _extension_match_core(ast_strlen_zero(pattern) ? "" : pattern, ast_strlen_zero(data) ? "" : data, mode);
3055 ast_mark(prof_id, 0);
3059 int ast_extension_match(const char *pattern, const char *data)
3061 return extension_match_core(pattern, data, E_MATCH);
3064 int ast_extension_close(const char *pattern, const char *data, int needmore)
3066 if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
3067 ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
3068 return extension_match_core(pattern, data, needmore);
3071 struct fake_context /* this struct is purely for matching in the hashtab */
3074 struct ast_exten *root;
3075 struct ast_hashtab *root_table;
3076 struct match_char *pattern_tree;
3077 struct ast_context *next;
3078 struct ast_include *includes;
3079 struct ast_ignorepat *ignorepats;
3080 const char *registrar;
3082 AST_LIST_HEAD_NOLOCK(, ast_sw) alts;
3083 ast_mutex_t macrolock;
3087 struct ast_context *ast_context_find(const char *name)
3089 struct ast_context *tmp;
3090 struct fake_context item;
3095 ast_rdlock_contexts();
3096 if (contexts_table) {
3097 ast_copy_string(item.name, name, sizeof(item.name));
3098 tmp = ast_hashtab_lookup(contexts_table, &item);
3101 while ((tmp = ast_walk_contexts(tmp))) {
3102 if (!strcasecmp(name, tmp->name)) {
3107 ast_unlock_contexts();
3111 #define STATUS_NO_CONTEXT 1
3112 #define STATUS_NO_EXTENSION 2
3113 #define STATUS_NO_PRIORITY 3
3114 #define STATUS_NO_LABEL 4
3115 #define STATUS_SUCCESS 5
3117 static int matchcid(const char *cidpattern, const char *callerid)
3119 /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so
3120 failing to get a number should count as a match, otherwise not */
3122 if (ast_strlen_zero(callerid)) {
3123 return ast_strlen_zero(cidpattern) ? 1 : 0;
3126 return ast_extension_match(cidpattern, callerid);
3129 struct ast_exten *pbx_find_extension(struct ast_channel *chan,
3130 struct ast_context *bypass, struct pbx_find_info *q,
3131 const char *context, const char *exten, int priority,
3132 const char *label, const char *callerid, enum ext_match_t action)
3135 struct ast_context *tmp = NULL;
3136 struct ast_exten *e = NULL, *eroot = NULL;
3137 struct ast_include *i = NULL;
3138 struct ast_sw *sw = NULL;
3139 struct ast_exten pattern = {NULL, };
3140 struct scoreboard score = {0, };
3141 struct ast_str *tmpdata = NULL;
3143 pattern.label = label;
3144 pattern.priority = priority;
3145 #ifdef NEED_DEBUG_HERE
3146 ast_log(LOG_NOTICE, "Looking for cont/ext/prio/label/action = %s/%s/%d/%s/%d\n", context, exten, priority, label, (int) action);
3149 /* Initialize status if appropriate */
3150 if (q->stacklen == 0) {
3151 q->status = STATUS_NO_CONTEXT;
3154 q->foundcontext = NULL;
3155 } else if (q->stacklen >= AST_PBX_MAX_STACK) {
3156 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
3160 /* Check first to see if we've already been checked */
3161 for (x = 0; x < q->stacklen; x++) {
3162 if (!strcasecmp(q->incstack[x], context))
3166 if (bypass) { /* bypass means we only look there */
3168 } else { /* look in contexts */
3169 tmp = find_context(context);
3175 if (q->status < STATUS_NO_EXTENSION)
3176 q->status = STATUS_NO_EXTENSION;
3178 /* Do a search for matching extension */
3181 score.total_specificity = 0;
3183 score.total_length = 0;
3184 if (!tmp->pattern_tree && tmp->root_table) {
3185 create_match_char_tree(tmp);
3187 ast_debug(1, "Tree Created in context %s:\n", context);
3188 log_match_char_tree(tmp->pattern_tree," ");
3192 ast_log(LOG_NOTICE, "The Trie we are searching in:\n");
3193 log_match_char_tree(tmp->pattern_tree, ":: ");
3197 if (!ast_strlen_zero(overrideswitch)) {
3198 char *osw = ast_strdupa(overrideswitch), *name;
3199 struct ast_switch *asw;
3200 ast_switch_f *aswf = NULL;
3204 name = strsep(&osw, "/");
3205 asw = pbx_findswitch(name);
3208 ast_log(LOG_WARNING, "No such switch '%s'\n", name);
3212 if (osw && strchr(osw, '$')) {
3216 if (eval && !(tmpdata = ast_str_thread_get(&switch_data, 512))) {
3217 ast_log(LOG_WARNING, "Can't evaluate overrideswitch?!\n");
3220 /* Substitute variables now */
3221 pbx_substitute_variables_helper(chan, osw, ast_str_buffer(tmpdata), ast_str_size(tmpdata));
3222 datap = ast_str_buffer(tmpdata);
3227 /* equivalent of extension_match_core() at the switch level */
3228 if (action == E_CANMATCH)
3229 aswf = asw->canmatch;
3230 else if (action == E_MATCHMORE)
3231 aswf = asw->matchmore;
3232 else /* action == E_MATCH */
3238 ast_autoservice_start(chan);
3240 res = aswf(chan, context, exten, priority, callerid, datap);
3242 ast_autoservice_stop(chan);
3245 if (res) { /* Got a match */
3248 q->foundcontext = context;
3249 /* XXX keep status = STATUS_NO_CONTEXT ? */
3255 if (extenpatternmatchnew) {
3256 new_find_extension(exten, &score, tmp->pattern_tree, 0, 0, callerid, label, action);
3257 eroot = score.exten;
3259 if (score.last_char == '!' && action == E_MATCHMORE) {
3260 /* We match an extension ending in '!'.
3261 * The decision in this case is final and is NULL (no match).
3263 #ifdef NEED_DEBUG_HERE
3264 ast_log(LOG_NOTICE,"Returning MATCHMORE NULL with exclamation point.\n");
3269 if (!eroot && (action == E_CANMATCH || action == E_MATCHMORE) && score.canmatch_exten) {
3270 q->status = STATUS_SUCCESS;
3271 #ifdef NEED_DEBUG_HERE
3272 ast_log(LOG_NOTICE,"Returning CANMATCH exten %s\n", score.canmatch_exten->exten);
3274 return score.canmatch_exten;
3277 if ((action == E_MATCHMORE || action == E_CANMATCH) && eroot) {
3279 struct ast_exten *z = trie_find_next_match(score.node);
3281 #ifdef NEED_DEBUG_HERE
3282 ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten %s\n", z->exten);
3285 if (score.canmatch_exten) {
3286 #ifdef NEED_DEBUG_HERE
3287 ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE canmatchmatch exten %s(%p)\n", score.canmatch_exten->exten, score.canmatch_exten);
3289 return score.canmatch_exten;
3291 #ifdef NEED_DEBUG_HERE
3292 ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten NULL\n");
3298 #ifdef NEED_DEBUG_HERE
3299 ast_log(LOG_NOTICE, "Returning CANMATCH/MATCHMORE NULL (no next_match)\n");
3301 return NULL; /* according to the code, complete matches are null matches in MATCHMORE mode */
3305 /* found entry, now look for the right priority */
3306 if (q->status < STATUS_NO_PRIORITY)
3307 q->status = STATUS_NO_PRIORITY;
3309 if (action == E_FINDLABEL && label ) {