2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2006, 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>
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35 #if defined(HAVE_SYSINFO)
36 #include <sys/sysinfo.h>
39 #include <sys/loadavg.h>
42 #include "asterisk/lock.h"
43 #include "asterisk/cli.h"
44 #include "asterisk/pbx.h"
45 #include "asterisk/channel.h"
46 #include "asterisk/options.h"
47 #include "asterisk/logger.h"
48 #include "asterisk/file.h"
49 #include "asterisk/callerid.h"
50 #include "asterisk/cdr.h"
51 #include "asterisk/config.h"
52 #include "asterisk/term.h"
53 #include "asterisk/manager.h"
54 #include "asterisk/ast_expr.h"
55 #include "asterisk/linkedlists.h"
56 #define SAY_STUBS /* generate declarations and stubs for say methods */
57 #include "asterisk/say.h"
58 #include "asterisk/utils.h"
59 #include "asterisk/causes.h"
60 #include "asterisk/musiconhold.h"
61 #include "asterisk/app.h"
62 #include "asterisk/devicestate.h"
63 #include "asterisk/stringfields.h"
64 #include "asterisk/event.h"
65 #include "asterisk/hashtab.h"
66 #include "asterisk/module.h"
67 #include "asterisk/indications.h"
70 * \note I M P O R T A N T :
72 * The speed of extension handling will likely be among the most important
73 * aspects of this PBX. The switching scheme as it exists right now isn't
74 * terribly bad (it's O(N+M), where N is the # of extensions and M is the avg #
75 * of priorities, but a constant search time here would be great ;-)
77 * A new algorithm to do searching based on a 'compiled' pattern tree is introduced
78 * here, and shows a fairly flat (constant) search time, even for over
79 * 1000 patterns. Might Still needs some work-- there are some fine points of the matching
80 * spec about tie-breaking based on the characters in character sets, but this
81 * should be do-able via the weight system currently being used.
83 * Also, using a hash table for context/priority name lookup can help prevent
84 * the find_extension routines from absorbing exponential cpu cycles. I've tested
85 * find_extension with red-black trees, which have O(log2(n)) speed. Right now,
86 * I'm using hash tables, which do searches (ideally) in O(1) time.
91 #define EXT_DATA_SIZE 256
93 #define EXT_DATA_SIZE 8192
96 #define SWITCH_DATA_LENGTH 256
98 #define VAR_BUF_SIZE 4096
101 #define VAR_SOFTTRAN 2
102 #define VAR_HARDTRAN 3
104 #define BACKGROUND_SKIP (1 << 0)
105 #define BACKGROUND_NOANSWER (1 << 1)
106 #define BACKGROUND_MATCHEXTEN (1 << 2)
107 #define BACKGROUND_PLAYBACK (1 << 3)
109 AST_APP_OPTIONS(background_opts, {
110 AST_APP_OPTION('s', BACKGROUND_SKIP),
111 AST_APP_OPTION('n', BACKGROUND_NOANSWER),
112 AST_APP_OPTION('m', BACKGROUND_MATCHEXTEN),
113 AST_APP_OPTION('p', BACKGROUND_PLAYBACK),
116 #define WAITEXTEN_MOH (1 << 0)
117 #define WAITEXTEN_DIALTONE (1 << 1)
119 AST_APP_OPTIONS(waitexten_opts, {
120 AST_APP_OPTION_ARG('m', WAITEXTEN_MOH, 0),
121 AST_APP_OPTION_ARG('d', WAITEXTEN_DIALTONE, 0),
128 \brief ast_exten: An extension
129 The dialplan is saved as a linked list with each context
130 having it's own linked list of extensions - one item per
134 char *exten; /*!< Extension name */
135 int matchcid; /*!< Match caller id ? */
136 const char *cidmatch; /*!< Caller id to match for this extension */
137 int priority; /*!< Priority */
138 const char *label; /*!< Label */
139 struct ast_context *parent; /*!< The context this extension belongs to */
140 const char *app; /*!< Application to execute */
141 struct ast_app *cached_app; /*!< Cached location of application */
142 void *data; /*!< Data to use (arguments) */
143 void (*datad)(void *); /*!< Data destructor */
144 struct ast_exten *peer; /*!< Next higher priority with our extension */
145 struct ast_hashtab *peer_tree; /*!< Priorities list in tree form -- only on the head of the peer list */
146 struct ast_hashtab *peer_label_tree; /*!< labeled priorities in the peer list -- only on the head of the peer list */
147 const char *registrar; /*!< Registrar */
148 struct ast_exten *next; /*!< Extension with a greater ID */
152 /*! \brief ast_include: include= support in extensions.conf */
155 const char *rname; /*!< Context to include */
156 const char *registrar; /*!< Registrar */
157 int hastime; /*!< If time construct exists */
158 struct ast_timing timing; /*!< time construct */
159 struct ast_include *next; /*!< Link them together */
163 /*! \brief ast_sw: Switch statement in extensions.conf */
166 const char *registrar; /*!< Registrar */
167 char *data; /*!< Data load */
169 AST_LIST_ENTRY(ast_sw) list;
174 /*! \brief ast_ignorepat: Ignore patterns in dial plan */
175 struct ast_ignorepat {
176 const char *registrar;
177 struct ast_ignorepat *next;
178 const char pattern[0];
181 /*! \brief match_char: forms a syntax tree for quick matching of extension patterns */
184 int is_pattern; /* the pattern started with '_' */
185 int deleted; /* if this is set, then... don't return it */
186 char *x; /* the pattern itself-- matches a single char */
187 int specificity; /* simply the strlen of x, or 10 for X, 9 for Z, and 8 for N; and '.' and '!' will add 11 ? */
188 struct match_char *alt_char;
189 struct match_char *next_char;
190 struct ast_exten *exten; /* attached to last char of a pattern for exten */
193 struct scoreboard /* make sure all fields are 0 before calling new_find_extension */
195 int total_specificity;
197 char last_char; /* set to ! or . if they are the end of the pattern */
198 int canmatch; /* if the string to match was just too short */
199 struct ast_exten *canmatch_exten;
200 struct ast_exten *exten;
203 /*! \brief ast_context: An extension context */
205 ast_rwlock_t lock; /*!< A lock to prevent multiple threads from clobbering the context */
206 struct ast_exten *root; /*!< The root of the list of extensions */
207 struct ast_hashtab *root_tree; /*!< For exact matches on the extensions in the pattern tree, and for traversals of the pattern_tree */
208 struct match_char *pattern_tree; /*!< A tree to speed up extension pattern matching */
209 struct ast_context *next; /*!< Link them together */
210 struct ast_include *includes; /*!< Include other contexts */
211 struct ast_ignorepat *ignorepats; /*!< Patterns for which to continue playing dialtone */
212 const char *registrar; /*!< Registrar */
213 AST_LIST_HEAD_NOLOCK(, ast_sw) alts; /*!< Alternative switches */
214 ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
215 char name[0]; /*!< Name of the context */
219 /*! \brief ast_app: A registered application */
221 int (*execute)(struct ast_channel *chan, void *data);
222 const char *synopsis; /*!< Synopsis text for 'show applications' */
223 const char *description; /*!< Description (help text) for 'show application <name>' */
224 AST_RWLIST_ENTRY(ast_app) list; /*!< Next app in list */
225 struct ast_module *module; /*!< Module this app belongs to */
226 char name[0]; /*!< Name of the application */
229 /*! \brief ast_state_cb: An extension state notify register item */
230 struct ast_state_cb {
233 ast_state_cb_type callback;
234 struct ast_state_cb *next;
237 /*! \brief Structure for dial plan hints
239 \note Hints are pointers from an extension in the dialplan to one or
240 more devices (tech/name)
241 - See \ref AstExtState
244 struct ast_exten *exten; /*!< Extension */
245 int laststate; /*!< Last known state */
246 struct ast_state_cb *callbacks; /*!< Callback list for this extension */
247 AST_RWLIST_ENTRY(ast_hint) list;/*!< Pointer to next hint in list */
250 static const struct cfextension_states {
252 const char * const text;
253 } extension_states[] = {
254 { AST_EXTENSION_NOT_INUSE, "Idle" },
255 { AST_EXTENSION_INUSE, "InUse" },
256 { AST_EXTENSION_BUSY, "Busy" },
257 { AST_EXTENSION_UNAVAILABLE, "Unavailable" },
258 { AST_EXTENSION_RINGING, "Ringing" },
259 { AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" },
260 { AST_EXTENSION_ONHOLD, "Hold" },
261 { AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD, "InUse&Hold" }
265 AST_LIST_ENTRY(statechange) entry;
270 * \brief Data used by the device state thread
273 /*! Set to 1 to stop the thread */
275 /*! The device state monitoring thread */
277 /*! Lock for the state change queue */
279 /*! Condition for the state change queue */
281 /*! Queue of state changes */
282 AST_LIST_HEAD_NOLOCK(, statechange) state_change_q;
284 .thread = AST_PTHREADT_NULL,
287 struct pbx_exception {
288 AST_DECLARE_STRING_FIELDS(
289 AST_STRING_FIELD(context); /*!< Context associated with this exception */
290 AST_STRING_FIELD(exten); /*!< Exten associated with this exception */
291 AST_STRING_FIELD(reason); /*!< The exception reason */
294 int priority; /*!< Priority associated with this exception */
297 static int pbx_builtin_answer(struct ast_channel *, void *);
298 static int pbx_builtin_goto(struct ast_channel *, void *);
299 static int pbx_builtin_hangup(struct ast_channel *, void *);
300 static int pbx_builtin_background(struct ast_channel *, void *);
301 static int pbx_builtin_wait(struct ast_channel *, void *);
302 static int pbx_builtin_waitexten(struct ast_channel *, void *);
303 static int pbx_builtin_keepalive(struct ast_channel *, void *);
304 static int pbx_builtin_resetcdr(struct ast_channel *, void *);
305 static int pbx_builtin_setamaflags(struct ast_channel *, void *);
306 static int pbx_builtin_ringing(struct ast_channel *, void *);
307 static int pbx_builtin_progress(struct ast_channel *, void *);
308 static int pbx_builtin_congestion(struct ast_channel *, void *);
309 static int pbx_builtin_busy(struct ast_channel *, void *);
310 static int pbx_builtin_noop(struct ast_channel *, void *);
311 static int pbx_builtin_gotoif(struct ast_channel *, void *);
312 static int pbx_builtin_gotoiftime(struct ast_channel *, void *);
313 static int pbx_builtin_execiftime(struct ast_channel *, void *);
314 static int pbx_builtin_saynumber(struct ast_channel *, void *);
315 static int pbx_builtin_saydigits(struct ast_channel *, void *);
316 static int pbx_builtin_saycharacters(struct ast_channel *, void *);
317 static int pbx_builtin_sayphonetic(struct ast_channel *, void *);
318 int pbx_builtin_setvar(struct ast_channel *, void *);
319 static int pbx_builtin_setvar_multiple(struct ast_channel *, void *);
320 static int pbx_builtin_importvar(struct ast_channel *, void *);
321 static void set_ext_pri(struct ast_channel *c, const char *exten, int pri);
322 void new_find_extension(const char *str, struct scoreboard *score, struct match_char *tree, int length, int spec, const char *callerid);
323 struct match_char *already_in_tree(struct match_char *current, char *pat);
324 struct match_char *add_exten_to_pattern_tree(struct ast_context *con, struct ast_exten *e1);
325 struct match_char *add_pattern_node(struct ast_context *con, struct match_char *current, char *pattern, int is_pattern, int already, int specificity);
326 void create_match_char_tree(struct ast_context *con);
327 struct ast_exten *get_canmatch_exten(struct match_char *node);
328 void destroy_pattern_tree(struct match_char *pattern_tree);
329 static int hashtab_compare_contexts(const void *ah_a, const void *ah_b);
330 static int hashtab_compare_extens(const void *ha_a, const void *ah_b);
331 static int hashtab_compare_exten_numbers(const void *ah_a, const void *ah_b);
332 static int hashtab_compare_exten_labels(const void *ah_a, const void *ah_b);
333 static unsigned int hashtab_hash_contexts(const void *obj);
334 static unsigned int hashtab_hash_extens(const void *obj);
335 static unsigned int hashtab_hash_priority(const void *obj);
336 static unsigned int hashtab_hash_labels(const void *obj);
338 /* labels, contexts are case sensitive priority numbers are ints */
339 static int hashtab_compare_contexts(const void *ah_a, const void *ah_b)
341 const struct ast_context *ac = ah_a;
342 const struct ast_context *bc = ah_b;
343 /* assume context names are registered in a string table! */
344 return strcmp(ac->name, bc->name);
347 static int hashtab_compare_extens(const void *ah_a, const void *ah_b)
349 const struct ast_exten *ac = ah_a;
350 const struct ast_exten *bc = ah_b;
351 int x = strcmp(ac->exten, bc->exten);
352 if (x) /* if exten names are diff, then return */
354 /* but if they are the same, do the cidmatch values match? */
355 if (ac->matchcid && bc->matchcid) {
356 return strcmp(ac->cidmatch,bc->cidmatch);
357 } else if (!ac->matchcid && !bc->matchcid) {
358 return 0; /* if there's no matchcid on either side, then this is a match */
360 return 1; /* if there's matchcid on one but not the other, they are different */
364 static int hashtab_compare_exten_numbers(const void *ah_a, const void *ah_b)
366 const struct ast_exten *ac = ah_a;
367 const struct ast_exten *bc = ah_b;
368 return ac->priority != bc->priority;
371 static int hashtab_compare_exten_labels(const void *ah_a, const void *ah_b)
373 const struct ast_exten *ac = ah_a;
374 const struct ast_exten *bc = ah_b;
375 return strcmp(ac->label, bc->label);
378 static unsigned int hashtab_hash_contexts(const void *obj)
380 const struct ast_context *ac = obj;
381 return ast_hashtab_hash_string(ac->name);
384 static unsigned int hashtab_hash_extens(const void *obj)
386 const struct ast_exten *ac = obj;
387 unsigned int x = ast_hashtab_hash_string(ac->exten);
390 y = ast_hashtab_hash_string(ac->cidmatch);
394 static unsigned int hashtab_hash_priority(const void *obj)
396 const struct ast_exten *ac = obj;
397 return ast_hashtab_hash_int(ac->priority);
400 static unsigned int hashtab_hash_labels(const void *obj)
402 const struct ast_exten *ac = obj;
403 return ast_hashtab_hash_string(ac->label);
407 AST_RWLOCK_DEFINE_STATIC(globalslock);
408 static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
410 static int autofallthrough = 1;
412 /*! \brief Subscription for device state change events */
413 static struct ast_event_sub *device_state_sub;
415 AST_MUTEX_DEFINE_STATIC(maxcalllock);
416 static int countcalls;
418 static AST_RWLIST_HEAD_STATIC(acf_root, ast_custom_function);
420 /*! \brief Declaration of builtin applications */
421 static struct pbx_builtin {
422 char name[AST_MAX_APP];
423 int (*execute)(struct ast_channel *chan, void *data);
428 /* These applications are built into the PBX core and do not
429 need separate modules */
431 { "Answer", pbx_builtin_answer,
432 "Answer a channel if ringing",
433 " Answer([delay]): If the call has not been answered, this application will\n"
434 "answer it. Otherwise, it has no effect on the call. If a delay is specified,\n"
435 "Asterisk will wait this number of milliseconds before returning to\n"
436 "the dialplan after answering the call.\n"
439 { "BackGround", pbx_builtin_background,
440 "Play an audio file while waiting for digits of an extension to go to.",
441 " Background(filename1[&filename2...][,options[,langoverride][,context]]):\n"
442 "This application will play the given list of files while waiting for an\n"
443 "extension to be dialed by the calling channel. To continue waiting for digits\n"
444 "after this application has finished playing files, the WaitExten application\n"
445 "should be used. The 'langoverride' option explicitly specifies which language\n"
446 "to attempt to use for the requested sound files. If a 'context' is specified,\n"
447 "this is the dialplan context that this application will use when exiting to a\n"
449 " If one of the requested sound files does not exist, call processing will be\n"
452 " s - Causes the playback of the message to be skipped\n"
453 " if the channel is not in the 'up' state (i.e. it\n"
454 " hasn't been answered yet). If this happens, the\n"
455 " application will return immediately.\n"
456 " n - Don't answer the channel before playing the files.\n"
457 " m - Only break if a digit hit matches a one digit\n"
458 " extension in the destination context.\n"
459 "This application sets the following channel variable upon completion:\n"
460 " BACKGROUNDSTATUS The status of the background attempt as a text string, one of\n"
461 " SUCCESS | FAILED\n"
464 { "Busy", pbx_builtin_busy,
465 "Indicate the Busy condition",
466 " Busy([timeout]): This application will indicate the busy condition to\n"
467 "the calling channel. If the optional timeout is specified, the calling channel\n"
468 "will be hung up after the specified number of seconds. Otherwise, this\n"
469 "application will wait until the calling channel hangs up.\n"
472 { "Congestion", pbx_builtin_congestion,
473 "Indicate the Congestion condition",
474 " Congestion([timeout]): This application will indicate the congestion\n"
475 "condition to the calling channel. If the optional timeout is specified, the\n"
476 "calling channel will be hung up after the specified number of seconds.\n"
477 "Otherwise, this application will wait until the calling channel hangs up.\n"
480 { "ExecIfTime", pbx_builtin_execiftime,
481 "Conditional application execution based on the current time",
482 " ExecIfTime(<times>,<weekdays>,<mdays>,<months>?appname[(appargs)]):\n"
483 "This application will execute the specified dialplan application, with optional\n"
484 "arguments, if the current time matches the given time specification.\n"
487 { "Goto", pbx_builtin_goto,
488 "Jump to a particular priority, extension, or context",
489 " Goto([[context,]extension,]priority): This application will set the current\n"
490 "context, extension, and priority in the channel structure. After it completes, the\n"
491 "pbx engine will continue dialplan execution at the specified location.\n"
492 "If no specific extension, or extension and context, are specified, then this\n"
493 "application will just set the specified priority of the current extension.\n"
494 " At least a priority is required as an argument, or the goto will return a -1,\n"
495 "and the channel and call will be terminated.\n"
496 " If the location that is put into the channel information is bogus, and asterisk cannot\n"
497 "find that location in the dialplan,\n"
498 "then the execution engine will try to find and execute the code in the 'i' (invalid)\n"
499 "extension in the current context. If that does not exist, it will try to execute the\n"
500 "'h' extension. If either or neither the 'h' or 'i' extensions have been defined, the\n"
501 "channel is hung up, and the execution of instructions on the channel is terminated.\n"
502 "What this means is that, for example, you specify a context that does not exist, then\n"
503 "it will not be possible to find the 'h' or 'i' extensions, and the call will terminate!\n"
506 { "GotoIf", pbx_builtin_gotoif,
508 " GotoIf(condition?[labeliftrue]:[labeliffalse]): This application will set the current\n"
509 "context, extension, and priority in the channel structure based on the evaluation of\n"
510 "the given condition. After this application completes, the\n"
511 "pbx engine will continue dialplan execution at the specified location in the dialplan.\n"
512 "The channel will continue at\n"
513 "'labeliftrue' if the condition is true, or 'labeliffalse' if the condition is\n"
514 "false. The labels are specified with the same syntax as used within the Goto\n"
515 "application. If the label chosen by the condition is omitted, no jump is\n"
516 "performed, and the execution passes to the next instruction.\n"
517 "If the target location is bogus, and does not exist, the execution engine will try \n"
518 "to find and execute the code in the 'i' (invalid)\n"
519 "extension in the current context. If that does not exist, it will try to execute the\n"
520 "'h' extension. If either or neither the 'h' or 'i' extensions have been defined, the\n"
521 "channel is hung up, and the execution of instructions on the channel is terminated.\n"
522 "Remember that this command can set the current context, and if the context specified\n"
523 "does not exist, then it will not be able to find any 'h' or 'i' extensions there, and\n"
524 "the channel and call will both be terminated!\n"
527 { "GotoIfTime", pbx_builtin_gotoiftime,
528 "Conditional Goto based on the current time",
529 " GotoIfTime(<times>,<weekdays>,<mdays>,<months>?[[context,]exten,]priority):\n"
530 "This application will set the context, extension, and priority in the channel structure\n"
531 "if the current time matches the given time specification. Otherwise, nothing is done.\n"
532 "Further information on the time specification can be found in examples\n"
533 "illustrating how to do time-based context includes in the dialplan.\n"
534 "If the target jump location is bogus, the same actions would be taken as for Goto.\n"
537 { "ImportVar", pbx_builtin_importvar,
538 "Import a variable from a channel into a new variable",
539 " ImportVar(newvar=channelname,variable): This application imports a variable\n"
540 "from the specified channel (as opposed to the current one) and stores it as\n"
541 "a variable in the current channel (the channel that is calling this\n"
542 "application). Variables created by this application have the same inheritance\n"
543 "properties as those created with the Set application. See the documentation for\n"
544 "Set for more information.\n"
547 { "Hangup", pbx_builtin_hangup,
548 "Hang up the calling channel",
549 " Hangup([causecode]): This application will hang up the calling channel.\n"
550 "If a causecode is given the channel's hangup cause will be set to the given\n"
554 { "NoOp", pbx_builtin_noop,
555 "Do Nothing (No Operation)",
556 " NoOp(): This application does nothing. However, it is useful for debugging\n"
557 "purposes. Any text that is provided as arguments to this application can be\n"
558 "viewed at the Asterisk CLI. This method can be used to see the evaluations of\n"
559 "variables or functions without having any effect. Alternatively, see the\n"
560 "Verbose() application for finer grain control of output at custom verbose levels.\n"
563 { "Progress", pbx_builtin_progress,
565 " Progress(): This application will request that in-band progress information\n"
566 "be provided to the calling channel.\n"
569 { "RaiseException", pbx_builtin_raise_exception,
570 "Handle an exceptional condition",
571 " RaiseException(<reason>): This application will jump to the \"e\" extension\n"
572 "in the current context, setting the dialplan function EXCEPTION(). If the \"e\"\n"
573 "extension does not exist, the call will hangup.\n"
576 { "ResetCDR", pbx_builtin_resetcdr,
577 "Resets the Call Data Record",
578 " ResetCDR([options]): This application causes the Call Data Record to be\n"
581 " w -- Store the current CDR record before resetting it.\n"
582 " a -- Store any stacked records.\n"
583 " v -- Save CDR variables.\n"
586 { "Ringing", pbx_builtin_ringing,
587 "Indicate ringing tone",
588 " Ringing(): This application will request that the channel indicate a ringing\n"
589 "tone to the user.\n"
592 { "SayAlpha", pbx_builtin_saycharacters,
594 " SayAlpha(string): This application will play the sounds that correspond to\n"
595 "the letters of the given string.\n"
598 { "SayDigits", pbx_builtin_saydigits,
600 " SayDigits(digits): This application will play the sounds that correspond\n"
601 "to the digits of the given number. This will use the language that is currently\n"
602 "set for the channel. See the LANGUAGE function for more information on setting\n"
603 "the language for the channel.\n"
606 { "SayNumber", pbx_builtin_saynumber,
608 " SayNumber(digits[,gender]): This application will play the sounds that\n"
609 "correspond to the given number. Optionally, a gender may be specified.\n"
610 "This will use the language that is currently set for the channel. See the\n"
611 "LANGUAGE function for more information on setting the language for the channel.\n"
614 { "SayPhonetic", pbx_builtin_sayphonetic,
616 " SayPhonetic(string): This application will play the sounds from the phonetic\n"
617 "alphabet that correspond to the letters in the given string.\n"
620 { "Set", pbx_builtin_setvar,
621 "Set channel variable or function value",
623 "This function can be used to set the value of channel variables or dialplan\n"
624 "functions. When setting variables, if the variable name is prefixed with _,\n"
625 "the variable will be inherited into channels created from the current\n"
626 "channel. If the variable name is prefixed with __, the variable will be\n"
627 "inherited into channels created from the current channel and all children\n"
631 { "MSet", pbx_builtin_setvar_multiple,
632 "Set channel variable(s) or function value(s)",
633 " MSet(name1=value1,name2=value2,...)\n"
634 "This function can be used to set the value of channel variables or dialplan\n"
635 "functions. When setting variables, if the variable name is prefixed with _,\n"
636 "the variable will be inherited into channels created from the current\n"
637 "channel. If the variable name is prefixed with __, the variable will be\n"
638 "inherited into channels created from the current channel and all children\n"
640 "MSet behaves in a similar fashion to the way Set worked in 1.2/1.4 and is thus\n"
641 "prone to doing things that you may not expect. Avoid its use if possible.\n"
644 { "SetAMAFlags", pbx_builtin_setamaflags,
646 " SetAMAFlags([flag]): This application will set the channel's AMA Flags for\n"
647 " billing purposes.\n"
650 { "Wait", pbx_builtin_wait,
651 "Waits for some time",
652 " Wait(seconds): This application waits for a specified number of seconds.\n"
653 "Then, dialplan execution will continue at the next priority.\n"
654 " Note that the seconds can be passed with fractions of a second. For example,\n"
655 "'1.5' will ask the application to wait for 1.5 seconds.\n"
658 { "WaitExten", pbx_builtin_waitexten,
659 "Waits for an extension to be entered",
660 " WaitExten([seconds][,options]): This application waits for the user to enter\n"
661 "a new extension for a specified number of seconds.\n"
662 " Note that the seconds can be passed with fractions of a second. For example,\n"
663 "'1.5' will ask the application to wait for 1.5 seconds.\n"
665 " m[(x)] - Provide music on hold to the caller while waiting for an extension.\n"
666 " Optionally, specify the class for music on hold within parenthesis.\n"
669 { "KeepAlive", pbx_builtin_keepalive,
670 "returns AST_PBX_KEEPALIVE value",
671 " KeepAlive(): This application is chiefly meant for internal use with Gosubs.\n"
672 "Please do not run it alone from the dialplan!\n"
677 static struct ast_context *contexts;
678 static struct ast_hashtab *contexts_tree = NULL;
680 AST_RWLOCK_DEFINE_STATIC(conlock); /*!< Lock for the ast_context list */
682 static AST_RWLIST_HEAD_STATIC(apps, ast_app);
684 static AST_RWLIST_HEAD_STATIC(switches, ast_switch);
686 static int stateid = 1;
688 When holding this list's lock, do _not_ do anything that will cause conlock
689 to be taken, unless you _already_ hold it. The ast_merge_contexts_and_delete
690 function will take the locks in conlock/hints order, so any other
691 paths that require both locks must also take them in that order.
693 static AST_RWLIST_HEAD_STATIC(hints, ast_hint);
694 struct ast_state_cb *statecbs;
697 \note This function is special. It saves the stack so that no matter
698 how many times it is called, it returns to the same place */
699 int pbx_exec(struct ast_channel *c, /*!< Channel */
700 struct ast_app *app, /*!< Application */
701 void *data) /*!< Data for execution */
704 struct ast_module_user *u = NULL;
705 const char *saved_c_appl;
706 const char *saved_c_data;
708 if (c->cdr && !ast_check_hangup(c))
709 ast_cdr_setapp(c->cdr, app->name, data);
711 /* save channel values */
712 saved_c_appl= c->appl;
713 saved_c_data= c->data;
718 u = __ast_module_user_add(app->module, c);
719 res = app->execute(c, data);
720 if (app->module && u)
721 __ast_module_user_remove(app->module, u);
722 /* restore channel values */
723 c->appl = saved_c_appl;
724 c->data = saved_c_data;
729 /*! Go no deeper than this through includes (not counting loops) */
730 #define AST_PBX_MAX_STACK 128
732 /*! \brief Find application handle in linked list
734 struct ast_app *pbx_findapp(const char *app)
738 AST_RWLIST_RDLOCK(&apps);
739 AST_RWLIST_TRAVERSE(&apps, tmp, list) {
740 if (!strcasecmp(tmp->name, app))
743 AST_RWLIST_UNLOCK(&apps);
748 static struct ast_switch *pbx_findswitch(const char *sw)
750 struct ast_switch *asw;
752 AST_RWLIST_RDLOCK(&switches);
753 AST_RWLIST_TRAVERSE(&switches, asw, list) {
754 if (!strcasecmp(asw->name, sw))
757 AST_RWLIST_UNLOCK(&switches);
762 static inline int include_valid(struct ast_include *i)
767 return ast_check_timing(&(i->timing));
770 static void pbx_destroy(struct ast_pbx *p)
775 /* form a tree that fully describes all the patterns in a context's extensions
776 * in this tree, a "node" consists of a series of match_char structs linked in a chain
777 * via the alt_char pointers. More than one pattern can share the same parts of the
778 * tree as other extensions with the same pattern to that point. The algorithm to
779 * find which pattern best matches a string, would follow **all** matching paths. As
780 * complete matches are found, a "max" match record would be updated if the match first involves
781 * a longer string, then, on a tie, a smaller total of specificity. This can be accomplished
782 * by recursive calls affecting a shared scoreboard.
783 * As and example, consider these 4 extensions:
789 * In the above, between (a) and (d), (a) is a more specific pattern than (d), and would win over
790 * most numbers. For all numbers beginning with 307754, (b) should always win.
792 * These pattern should form a tree that looks like this:
793 * { "N" } --next--> { "X" } --next--> { "X" } --next--> { "N" } --next--> { "X" } ... blah ... --> { "X" exten_match: (a) }
797 * | { "X" } --next--> { "X" } ... blah ... --> { "X" exten_match: (d) }
799 * { "3" } --next--> { "0" } --next--> { "7" } --next--> { "7" } --next--> { "5" } ... blah ... --> { "X" exten_match: (b) }
803 * { "f" } --next--> { "a" } --next--> { "x" exten_match: (c) }
805 * In the above, I could easily turn "N" into "23456789", but I think that a quick "if( *z >= '2' && *z <= '9' )" might take
806 * fewer CPU cycles than a call to index("23456789",*z), where *z is the char to match...
808 * traversal is pretty simple: one routine merely traverses the alt list, and for each match in the pattern, it calls itself
809 * on the corresponding next pointer, incrementing also the pointer of the string to be matched, and passing the total specificity and length.
810 * We pass a pointer to a scoreboard down through, also.
811 * When an exten_match pointer is set, or a '.' or a '!' is encountered, we update the scoreboard only if the length is greater, or in case
812 * of equal length, if the specificity is lower, and return. Hope the limit on stack depth won't be a problem... this routine should
813 * be pretty lean as far a stack usage goes. Any non-match terminates the recursion down a branch.
815 * In the above example, with the number "3077549999" as the pattern, the traversor should match extensions a, b and d. All are
816 * of length 10; but they have total specificities of 96, 46, and 98, respectively. (b) wins with its lower specificity number!
818 * Just how much time this algorithm might save over a plain linear traversal over all possible patterns is unknown. But, it should
819 * be pretty close to optimal for this sort of overall algorithm.
823 /* you only really update the scoreboard, if the new score is BETTER than the
824 * one stored there. ignore it otherwise.
828 static void update_scoreboard(struct scoreboard *board, int length, int spec, struct ast_exten *exten, char last, const char *callerid, int deleted)
830 /* doing a matchcid() check here would be easy and cheap, but...
831 unfortunately, it only works if an extension can have only one
832 cid to match. That's not real life. CID patterns need to exist
833 in the tree for this sort of thing to work properly. */
835 /* if this extension is marked as deleted, then skip this -- if it never shows
836 on the scoreboard, it will never be found */
840 if (length > board->total_length) {
841 board->total_specificity = spec;
842 board->total_length = length;
843 board->exten = exten;
844 board->last_char = last;
845 } else if (length == board->total_length && spec < board->total_specificity) {
846 board->total_specificity = spec;
847 board->total_length = length;
848 board->exten = exten;
849 board->last_char = last;
854 static void log_match_char_tree(struct match_char *node, char *prefix)
856 char my_prefix[1024];
858 ast_log(LOG_DEBUG,"%s%s:%c:%d:%s\n", prefix, node->x, node->is_pattern ? 'Y':'N', node->specificity, node->exten? "EXTEN":"");
859 strcpy(my_prefix,prefix);
860 strcat(my_prefix,"+ ");
862 print_match_char_tree(node->next_char, my_prefix);
864 print_match_char_tree(node->alt_char, prefix);
868 static void cli_match_char_tree(struct match_char *node, char *prefix, int fd)
870 char my_prefix[1024];
871 if (strlen(node->x) > 1 )
872 ast_cli(fd, "%s[%s]:%c:%d:%s%s\n", prefix, node->x, node->is_pattern ? 'Y':'N', node->specificity, node->exten? "EXTEN:":"", node->exten ? node->exten->exten : "");
874 ast_cli(fd, "%s%s:%c:%d:%s%s\n", prefix, node->x, node->is_pattern ? 'Y':'N', node->specificity, node->exten? "EXTEN:":"", node->exten ? node->exten->exten : "");
875 strcpy(my_prefix,prefix);
876 strcat(my_prefix,"+ ");
878 cli_match_char_tree(node->next_char, my_prefix, fd);
880 cli_match_char_tree(node->alt_char, prefix, fd);
883 struct ast_exten *get_canmatch_exten(struct match_char *node)
885 /* find the exten at the end of the rope */
886 struct match_char *node2 = node;
887 for (node2 = node; node2; node2 = node2->next_char)
893 void new_find_extension(const char *str, struct scoreboard *score, struct match_char *tree, int length, int spec, const char *callerid)
895 struct match_char *p; /* note minimal stack storage requirements */
896 for (p=tree; p; p=p->alt_char) {
897 if (p->x[0] == 'N' && p->x[1] == 0 && *str >= '2' && *str <= '9' ) {
898 if (p->exten) /* if a shorter pattern matches along the way, might as well report it */
899 update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid, p->deleted);
901 if (p->next_char && ( *(str+1) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
903 new_find_extension(str+1, score, p->next_char, length+1, spec+p->specificity, callerid);
905 new_find_extension("/", score, p->next_char, length+1, spec+p->specificity, callerid);
906 } else if (p->next_char && !*(str+1)) {
908 score->canmatch_exten = get_canmatch_exten(p);
912 } else if (p->x[0] == 'Z' && p->x[1] == 0 && *str >= '1' && *str <= '9' ) {
913 if (p->exten) /* if a shorter pattern matches along the way, might as well report it */
914 update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid, p->deleted);
916 if (p->next_char && ( *(str+1) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
918 new_find_extension(str+1, score, p->next_char, length+1, spec+p->specificity, callerid);
920 new_find_extension("/", score, p->next_char, length+1, spec+p->specificity, callerid);
921 } else if (p->next_char && !*(str+1)) {
923 score->canmatch_exten = get_canmatch_exten(p);
927 } else if (p->x[0] == 'X' && p->x[1] == 0 && *str >= '0' && *str <= '9' ) {
928 if (p->exten) /* if a shorter pattern matches along the way, might as well report it */
929 update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid, p->deleted);
931 if (p->next_char && ( *(str+1) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
933 new_find_extension(str+1, score, p->next_char, length+1, spec+p->specificity, callerid);
935 new_find_extension("/", score, p->next_char, length+1, spec+p->specificity, callerid);
936 } else if (p->next_char && !*(str+1)) {
938 score->canmatch_exten = get_canmatch_exten(p);
942 } else if (p->x[0] == '.' && p->x[1] == 0) {
943 /* how many chars will the . match against? */
949 update_scoreboard(score, length+i, spec+(i*p->specificity), p->exten, '.', callerid, p->deleted);
950 if (p->next_char && p->next_char->x[0] == '/' && p->next_char->x[1] == 0) {
951 new_find_extension("/", score, p->next_char, length+i, spec+(p->specificity*i), callerid);
954 } else if (p->x[0] == '!' && p->x[1] == 0) {
955 /* how many chars will the . match against? */
961 update_scoreboard(score, length+1, spec+(p->specificity*i), p->exten, '!', callerid, p->deleted);
962 if (p->next_char && p->next_char->x[0] == '/' && p->next_char->x[1] == 0) {
963 new_find_extension("/", score, p->next_char, length+i, spec+(p->specificity*i), callerid);
966 } else if (p->x[0] == '/' && p->x[1] == 0) {
967 /* the pattern in the tree includes the cid match! */
968 if (p->next_char && callerid && *callerid) {
969 new_find_extension(callerid, score, p->next_char, length+1, spec, callerid);
971 } else if (index(p->x, *str)) {
972 if (p->exten) /* if a shorter pattern matches along the way, might as well report it */
973 update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid, p->deleted);
976 if (p->next_char && ( *(str+1) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
978 new_find_extension(str+1, score, p->next_char, length+1, spec+p->specificity, callerid);
980 new_find_extension("/", score, p->next_char, length+1, spec+p->specificity, callerid);
982 } else if (p->next_char && !*(str+1)) {
984 score->canmatch_exten = get_canmatch_exten(p);
992 /* the algorithm for forming the extension pattern tree is also a bit simple; you
993 * traverse all the extensions in a context, and for each char of the extension,
994 * you see if it exists in the tree; if it doesn't, you add it at the appropriate
995 * spot. What more can I say? At the end of the list, you cap it off by adding the
996 * address of the extension involved. Duplicate patterns will be complained about.
998 * Ideally, this would be done for each context after it is created and fully
999 * filled. It could be done as a finishing step after extensions.conf or .ael is
1000 * loaded, or it could be done when the first search is encountered. It should only
1001 * have to be done once, until the next unload or reload.
1003 * I guess forming this pattern tree would be analogous to compiling a regex.
1007 struct match_char *already_in_tree(struct match_char *current, char *pat)
1009 struct match_char *t;
1012 for (t=current; t; t=t->alt_char) {
1013 if (strcmp(pat,t->x) == 0) /* uh, we may want to sort exploded [] contents to make matching easy */
1019 struct match_char *add_pattern_node(struct ast_context *con, struct match_char *current, char *pattern, int is_pattern, int already, int specificity)
1021 struct match_char *m = ast_calloc(1,sizeof(struct match_char));
1022 m->x = ast_strdup(pattern);
1023 m->is_pattern = is_pattern;
1024 if (specificity == 1 && is_pattern && pattern[0] == 'N')
1025 m->specificity = 98;
1026 else if (specificity == 1 && is_pattern && pattern[0] == 'Z')
1027 m->specificity = 99;
1028 else if (specificity == 1 && is_pattern && pattern[0] == 'X')
1029 m->specificity = 100;
1030 else if (specificity == 1 && is_pattern && pattern[0] == '.')
1031 m->specificity = 200;
1032 else if (specificity == 1 && is_pattern && pattern[0] == '!')
1033 m->specificity = 200;
1035 m->specificity = specificity;
1037 if (!con->pattern_tree) {
1038 con->pattern_tree = m;
1040 if (already) { /* switch to the new regime (traversing vs appending)*/
1041 m->alt_char = current->alt_char;
1042 current->alt_char = m;
1044 if (current->next_char) {
1045 m->alt_char = current->next_char->alt_char;
1046 current->next_char = m;
1048 current->next_char = m;
1055 struct match_char *add_exten_to_pattern_tree(struct ast_context *con, struct ast_exten *e1)
1057 struct match_char *m1=0,*m2=0;
1063 char *s1 = extenbuf;
1064 int l1 = strlen(e1->exten) + strlen(e1->cidmatch) + 2;
1067 strncpy(extenbuf,e1->exten,sizeof(extenbuf));
1068 if (e1->matchcid && l1 <= sizeof(extenbuf)) {
1069 strcat(extenbuf,"/");
1070 strcat(extenbuf,e1->cidmatch);
1071 } else if (l1 > sizeof(extenbuf)) {
1072 ast_log(LOG_ERROR,"The pattern %s/%s is too big to deal with: it will be ignored! Disaster!\n", e1->exten, e1->cidmatch);
1076 ast_log(LOG_DEBUG,"Adding exten %s%c%s to tree\n", s1, e1->matchcid? '/':' ', e1->matchcid? e1->cidmatch : "");
1078 m1 = con->pattern_tree; /* each pattern starts over at the root of the pattern tree */
1086 if (pattern && *s1 == '[' && *(s1-1) != '\\') {
1089 s1++; /* get past the '[' */
1090 while (*s1 != ']' && *(s1-1) != '\\' ) {
1092 if (*(s1+1) == ']') {
1095 } else if (*(s1+1) == '\\') {
1098 } else if (*(s1+1) == '-') {
1101 } else if (*(s1+1) == '[') {
1105 } else if (*s1 == '-') { /* remember to add some error checking to all this! */
1108 for (s3++; s3 <= s4; s3++) {
1116 *s2 = 0; /* null terminate the exploded range */
1117 specif = strlen(buf);
1129 if (already && (m2=already_in_tree(m1,buf)) && m2->next_char) {
1130 if (!(*(s1+1))) /* if this is the end of the pattern, but not the end of the tree, then mark this node with the exten...
1131 a shorter pattern might win if the longer one doesn't match */
1133 m1 = m2->next_char; /* m1 points to the node to compare against */
1138 m1 = add_pattern_node(con, m1, buf, pattern, already,specif); /* m1 is the node just added */
1143 s1++; /* advance to next char */
1148 void create_match_char_tree(struct ast_context *con)
1150 struct ast_hashtab_iter *t1;
1151 struct ast_exten *e1;
1153 int biggest_bucket, resizes, numobjs, numbucks;
1155 ast_log(LOG_DEBUG,"Creating Extension Trie for context %s\n", con->name);
1156 ast_hashtab_get_stats(con->root_tree, &biggest_bucket, &resizes, &numobjs, &numbucks);
1157 ast_log(LOG_DEBUG,"This tree has %d objects in %d bucket lists, longest list=%d objects, and has resized %d times\n",
1158 numobjs, numbucks, biggest_bucket, resizes);
1160 t1 = ast_hashtab_start_traversal(con->root_tree);
1161 while( (e1 = ast_hashtab_next(t1)) ) {
1163 add_exten_to_pattern_tree(con, e1);
1165 ast_log(LOG_ERROR,"Attempt to create extension with no extension name.\n");
1167 ast_hashtab_end_traversal(t1);
1170 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! */
1172 /* destroy all the alternates */
1173 if (pattern_tree->alt_char) {
1174 destroy_pattern_tree(pattern_tree->alt_char);
1175 pattern_tree->alt_char = 0;
1177 /* destroy all the nexts */
1178 if (pattern_tree->next_char) {
1179 destroy_pattern_tree(pattern_tree->next_char);
1180 pattern_tree->next_char = 0;
1182 pattern_tree->exten = 0; /* never hurts to make sure there's no pointers laying around */
1183 if (pattern_tree->x)
1184 free(pattern_tree->x);
1189 * Special characters used in patterns:
1190 * '_' underscore is the leading character of a pattern.
1191 * In other position it is treated as a regular char.
1192 * ' ' '-' space and '-' are separator and ignored.
1193 * . one or more of any character. Only allowed at the end of
1195 * ! zero or more of anything. Also impacts the result of CANMATCH
1196 * and MATCHMORE. Only allowed at the end of a pattern.
1197 * In the core routine, ! causes a match with a return code of 2.
1198 * In turn, depending on the search mode: (XXX check if it is implemented)
1199 * - E_MATCH retuns 1 (does match)
1200 * - E_MATCHMORE returns 0 (no match)
1201 * - E_CANMATCH returns 1 (does match)
1203 * / should not appear as it is considered the separator of the CID info.
1204 * XXX at the moment we may stop on this char.
1206 * X Z N match ranges 0-9, 1-9, 2-9 respectively.
1207 * [ denotes the start of a set of character. Everything inside
1208 * is considered literally. We can have ranges a-d and individual
1209 * characters. A '[' and '-' can be considered literally if they
1210 * are just before ']'.
1211 * XXX currently there is no way to specify ']' in a range, nor \ is
1212 * considered specially.
1214 * When we compare a pattern with a specific extension, all characters in the extension
1215 * itself are considered literally with the only exception of '-' which is considered
1216 * as a separator and thus ignored.
1217 * XXX do we want to consider space as a separator as well ?
1218 * XXX do we want to consider the separators in non-patterns as well ?
1222 * \brief helper functions to sort extensions and patterns in the desired way,
1223 * so that more specific patterns appear first.
1225 * ext_cmp1 compares individual characters (or sets of), returning
1226 * an int where bits 0-7 are the ASCII code of the first char in the set,
1227 * while bit 8-15 are the cardinality of the set minus 1.
1228 * This way more specific patterns (smaller cardinality) appear first.
1229 * Wildcards have a special value, so that we can directly compare them to
1230 * sets by subtracting the two values. In particular:
1231 * 0x000xx one character, xx
1232 * 0x0yyxx yy character set starting with xx
1233 * 0x10000 '.' (one or more of anything)
1234 * 0x20000 '!' (zero or more of anything)
1235 * 0x30000 NUL (end of string)
1236 * 0x40000 error in set.
1237 * The pointer to the string is advanced according to needs.
1239 * 1. the empty set is equivalent to NUL.
1240 * 2. given that a full set has always 0 as the first element,
1241 * we could encode the special cases as 0xffXX where XX
1242 * is 1, 2, 3, 4 as used above.
1244 static int ext_cmp1(const char **p)
1247 int c, cmin = 0xff, count = 0;
1250 /* load, sign extend and advance pointer until we find
1251 * a valid character.
1253 while ( (c = *(*p)++) && (c == ' ' || c == '-') )
1254 ; /* ignore some characters */
1256 /* always return unless we have a set of chars */
1258 default: /* ordinary character */
1259 return 0x0000 | (c & 0xff);
1261 case 'N': /* 2..9 */
1262 return 0x0700 | '2' ;
1264 case 'X': /* 0..9 */
1265 return 0x0900 | '0';
1267 case 'Z': /* 1..9 */
1268 return 0x0800 | '1';
1270 case '.': /* wildcard */
1273 case '!': /* earlymatch */
1274 return 0x20000; /* less specific than NULL */
1276 case '\0': /* empty string */
1280 case '[': /* pattern */
1283 /* locate end of set */
1284 end = strchr(*p, ']');
1287 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
1288 return 0x40000; /* XXX make this entry go last... */
1291 bzero(chars, sizeof(chars)); /* clear all chars in the set */
1292 for (; *p < end ; (*p)++) {
1293 unsigned char c1, c2; /* first-last char in range */
1294 c1 = (unsigned char)((*p)[0]);
1295 if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */
1296 c2 = (unsigned char)((*p)[2]);
1297 *p += 2; /* skip a total of 3 chars */
1298 } else /* individual character */
1302 for (; c1 <= c2; c1++) {
1303 uint32_t mask = 1 << (c1 % 32);
1304 if ( (chars[ c1 / 32 ] & mask) == 0)
1306 chars[ c1 / 32 ] |= mask;
1310 return count == 0 ? 0x30000 : (count | cmin);
1314 * \brief the full routine to compare extensions in rules.
1316 static int ext_cmp(const char *a, const char *b)
1318 /* make sure non-patterns come first.
1319 * If a is not a pattern, it either comes first or
1320 * we use strcmp to compare the strings.
1325 return (b[0] == '_') ? -1 : strcmp(a, b);
1327 /* Now we know a is a pattern; if b is not, a comes first */
1330 #if 0 /* old mode for ext matching */
1331 return strcmp(a, b);
1333 /* ok we need full pattern sorting routine */
1334 while (!ret && a && b)
1335 ret = ext_cmp1(&a) - ext_cmp1(&b);
1339 return (ret > 0) ? 1 : -1;
1342 int ast_extension_cmp(const char *a, const char *b)
1344 return ext_cmp(a, b);
1349 * \brief used ast_extension_{match|close}
1350 * mode is as follows:
1351 * E_MATCH success only on exact match
1352 * E_MATCHMORE success only on partial match (i.e. leftover digits in pattern)
1353 * E_CANMATCH either of the above.
1354 * \retval 0 on no-match
1355 * \retval 1 on match
1356 * \retval 2 on early match.
1359 static int _extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
1361 mode &= E_MATCH_MASK; /* only consider the relevant bits */
1363 if ( (mode == E_MATCH) && (pattern[0] == '_') && (strcasecmp(pattern,data)==0) ) /* note: if this test is left out, then _x. will not match _x. !!! */
1366 if (pattern[0] != '_') { /* not a pattern, try exact or partial match */
1367 int ld = strlen(data), lp = strlen(pattern);
1369 if (lp < ld) /* pattern too short, cannot match */
1371 /* depending on the mode, accept full or partial match or both */
1372 if (mode == E_MATCH)
1373 return !strcmp(pattern, data); /* 1 on match, 0 on fail */
1374 if (ld == 0 || !strncasecmp(pattern, data, ld)) /* partial or full match */
1375 return (mode == E_MATCHMORE) ? lp > ld : 1; /* XXX should consider '!' and '/' ? */
1379 pattern++; /* skip leading _ */
1381 * XXX below we stop at '/' which is a separator for the CID info. However we should
1382 * not store '/' in the pattern at all. When we insure it, we can remove the checks.
1384 while (*data && *pattern && *pattern != '/') {
1387 if (*data == '-') { /* skip '-' in data (just a separator) */
1391 switch (toupper(*pattern)) {
1392 case '[': /* a range */
1393 end = strchr(pattern+1, ']'); /* XXX should deal with escapes ? */
1395 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
1396 return 0; /* unconditional failure */
1398 for (pattern++; pattern != end; pattern++) {
1399 if (pattern+2 < end && pattern[1] == '-') { /* this is a range */
1400 if (*data >= pattern[0] && *data <= pattern[2])
1401 break; /* match found */
1403 pattern += 2; /* skip a total of 3 chars */
1406 } else if (*data == pattern[0])
1407 break; /* match found */
1411 pattern = end; /* skip and continue */
1414 if (*data < '2' || *data > '9')
1418 if (*data < '0' || *data > '9')
1422 if (*data < '1' || *data > '9')
1425 case '.': /* Must match, even with more digits */
1427 case '!': /* Early match */
1430 case '-': /* Ignore these in patterns */
1431 data--; /* compensate the final data++ */
1434 if (*data != *pattern)
1440 if (*data) /* data longer than pattern, no match */
1443 * match so far, but ran off the end of the data.
1444 * Depending on what is next, determine match or not.
1446 if (*pattern == '\0' || *pattern == '/') /* exact match */
1447 return (mode == E_MATCHMORE) ? 0 : 1; /* this is a failure for E_MATCHMORE */
1448 else if (*pattern == '!') /* early match */
1450 else /* partial match */
1451 return (mode == E_MATCH) ? 0 : 1; /* this is a failure for E_MATCH */
1455 * Wrapper around _extension_match_core() to do performance measurement
1456 * using the profiling code.
1458 static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
1461 static int prof_id = -2; /* marker for 'unallocated' id */
1463 prof_id = ast_add_profile("ext_match", 0);
1464 ast_mark(prof_id, 1);
1465 i = _extension_match_core(pattern, data, mode);
1466 ast_mark(prof_id, 0);
1470 int ast_extension_match(const char *pattern, const char *data)
1472 return extension_match_core(pattern, data, E_MATCH);
1475 int ast_extension_close(const char *pattern, const char *data, int needmore)
1477 if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
1478 ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
1479 return extension_match_core(pattern, data, needmore);
1482 struct fake_context /* this struct is purely for matching in the hashtab */
1485 struct ast_exten *root;
1486 struct ast_hashtab *root_tree;
1487 struct match_char *pattern_tree;
1488 struct ast_context *next;
1489 struct ast_include *includes;
1490 struct ast_ignorepat *ignorepats;
1491 const char *registrar;
1492 AST_LIST_HEAD_NOLOCK(, ast_sw) alts;
1493 ast_mutex_t macrolock;
1497 struct ast_context *ast_context_find(const char *name)
1499 struct ast_context *tmp = NULL;
1500 struct fake_context item;
1501 strncpy(item.name,name,256);
1502 ast_rdlock_contexts();
1503 if( contexts_tree ) {
1504 tmp = ast_hashtab_lookup(contexts_tree,&item);
1506 while ( (tmp = ast_walk_contexts(tmp)) ) {
1507 if (!name || !strcasecmp(name, tmp->name))
1511 ast_unlock_contexts();
1515 #define STATUS_NO_CONTEXT 1
1516 #define STATUS_NO_EXTENSION 2
1517 #define STATUS_NO_PRIORITY 3
1518 #define STATUS_NO_LABEL 4
1519 #define STATUS_SUCCESS 5
1521 struct ast_exten *pbx_find_extension(struct ast_channel *chan,
1522 struct ast_context *bypass, struct pbx_find_info *q,
1523 const char *context, const char *exten, int priority,
1524 const char *label, const char *callerid, enum ext_match_t action)
1527 struct ast_context *tmp=0;
1528 struct ast_exten *e=0, *eroot=0;
1529 struct ast_include *i = 0;
1530 struct ast_sw *sw = 0;
1531 struct ast_exten pattern = {0};
1532 struct scoreboard score = {0};
1534 pattern.label = label;
1535 pattern.priority = priority;
1538 /* Initialize status if appropriate */
1539 if (q->stacklen == 0) {
1540 q->status = STATUS_NO_CONTEXT;
1543 q->foundcontext = NULL;
1544 } else if (q->stacklen >= AST_PBX_MAX_STACK) {
1545 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
1549 /* Check first to see if we've already been checked */
1550 for (x = 0; x < q->stacklen; x++) {
1551 if (!strcasecmp(q->incstack[x], context))
1555 if (bypass) /* bypass means we only look there */
1557 else { /* look in contexts */
1558 struct fake_context item;
1559 strncpy(item.name,context,256);
1560 tmp = ast_hashtab_lookup(contexts_tree,&item);
1563 while ((tmp = ast_walk_contexts(tmp)) ) {
1564 if (!strcmp(tmp->name, context))
1572 if (q->status < STATUS_NO_EXTENSION)
1573 q->status = STATUS_NO_EXTENSION;
1575 /* Do a search for matching extension */
1577 score.total_specificity = 0;
1579 score.total_length = 0;
1580 if (!tmp->pattern_tree && tmp->root_tree)
1582 create_match_char_tree(tmp);
1584 ast_log(LOG_DEBUG,"Tree Created in context %s:\n", context);
1585 print_match_char_tree(tmp->pattern_tree," ");
1589 new_find_extension(exten, &score, tmp->pattern_tree, 0, 0, callerid);
1590 eroot = score.exten;
1592 if (score.last_char == '!' && action == E_MATCHMORE) {
1593 /* We match an extension ending in '!'.
1594 * The decision in this case is final and is NULL (no match).
1599 if (!eroot && (action == E_CANMATCH || action == E_MATCHMORE) && score.canmatch_exten) {
1600 q->status = STATUS_SUCCESS;
1601 return score.canmatch_exten;
1604 if (action == E_MATCHMORE && eroot)
1605 return NULL; /* according to the code, complete matches are null matches in MATCHMORE mode */
1608 /* found entry, now look for the right priority */
1609 if (q->status < STATUS_NO_PRIORITY)
1610 q->status = STATUS_NO_PRIORITY;
1612 if (action == E_FINDLABEL && label ) {
1613 if (q->status < STATUS_NO_LABEL)
1614 q->status = STATUS_NO_LABEL;
1615 e = ast_hashtab_lookup(eroot->peer_label_tree, &pattern);
1617 e = ast_hashtab_lookup(eroot->peer_tree, &pattern);
1619 if (e) { /* found a valid match */
1620 q->status = STATUS_SUCCESS;
1621 q->foundcontext = context;
1627 /* scan the list trying to match extension and CID */
1629 while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) {
1630 int match = extension_match_core(eroot->exten, exten, action);
1631 /* 0 on fail, 1 on match, 2 on earlymatch */
1633 if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid)))
1634 continue; /* keep trying */
1635 if (match == 2 && action == E_MATCHMORE) {
1636 /* We match an extension ending in '!'.
1637 * The decision in this case is final and is NULL (no match).
1641 /* found entry, now look for the right priority */
1642 if (q->status < STATUS_NO_PRIORITY)
1643 q->status = STATUS_NO_PRIORITY;
1645 if (action == E_FINDLABEL && label ) {
1646 if (q->status < STATUS_NO_LABEL)
1647 q->status = STATUS_NO_LABEL;
1648 e = ast_hashtab_lookup(eroot->peer_label_tree, &pattern);
1650 e = ast_hashtab_lookup(eroot->peer_tree, &pattern);
1653 while ( (e = ast_walk_extension_priorities(eroot, e)) ) {
1654 /* Match label or priority */
1655 if (action == E_FINDLABEL) {
1656 if (q->status < STATUS_NO_LABEL)
1657 q->status = STATUS_NO_LABEL;
1658 if (label && e->label && !strcmp(label, e->label))
1659 break; /* found it */
1660 } else if (e->priority == priority) {
1661 break; /* found it */
1662 } /* else keep searching */
1665 if (e) { /* found a valid match */
1666 q->status = STATUS_SUCCESS;
1667 q->foundcontext = context;
1672 /* Check alternative switches */
1673 AST_LIST_TRAVERSE(&tmp->alts, sw, list) {
1674 struct ast_switch *asw = pbx_findswitch(sw->name);
1675 ast_switch_f *aswf = NULL;
1679 ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name);
1682 /* Substitute variables now */
1685 pbx_substitute_variables_helper(chan, sw->data, sw->tmpdata, SWITCH_DATA_LENGTH - 1);
1687 /* equivalent of extension_match_core() at the switch level */
1688 if (action == E_CANMATCH)
1689 aswf = asw->canmatch;
1690 else if (action == E_MATCHMORE)
1691 aswf = asw->matchmore;
1692 else /* action == E_MATCH */
1694 datap = sw->eval ? sw->tmpdata : sw->data;
1695 res = !aswf ? 0 : aswf(chan, context, exten, priority, callerid, datap);
1696 if (res) { /* Got a match */
1699 q->foundcontext = context;
1700 /* XXX keep status = STATUS_NO_CONTEXT ? */
1704 q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */
1705 /* Now try any includes we have in this context */
1706 for (i = tmp->includes; i; i = i->next) {
1707 if (include_valid(i)) {
1708 if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action)))
1718 * \brief extract offset:length from variable name.
1719 * \return 1 if there is a offset:length part, which is
1720 * trimmed off (values go into variables)
1722 static int parse_variable_name(char *var, int *offset, int *length, int *isfunc)
1729 for (; *var; var++) {
1733 } else if (*var == ')') {
1735 } else if (*var == ':' && parens == 0) {
1737 sscanf(var, "%d:%d", offset, length);
1738 return 1; /* offset:length valid */
1745 *\brief takes a substring. It is ok to call with value == workspace.
1747 * \param offset < 0 means start from the end of the string and set the beginning
1748 * to be that many characters back.
1749 * \param length is the length of the substring, a value less than 0 means to leave
1750 * that many off the end.
1752 * \param workspace_len
1753 * Always return a copy in workspace.
1755 static char *substring(const char *value, int offset, int length, char *workspace, size_t workspace_len)
1757 char *ret = workspace;
1758 int lr; /* length of the input string after the copy */
1760 ast_copy_string(workspace, value, workspace_len); /* always make a copy */
1762 lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */
1764 /* Quick check if no need to do anything */
1765 if (offset == 0 && length >= lr) /* take the whole string */
1768 if (offset < 0) { /* translate negative offset into positive ones */
1769 offset = lr + offset;
1770 if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */
1774 /* too large offset result in empty string so we know what to return */
1776 return ret + lr; /* the final '\0' */
1778 ret += offset; /* move to the start position */
1779 if (length >= 0 && length < lr - offset) /* truncate if necessary */
1781 else if (length < 0) {
1782 if (lr > offset - length) /* After we remove from the front and from the rear, is there anything left? */
1783 ret[lr + length - offset] = '\0';
1791 /*! \brief Support for Asterisk built-in variables in the dialplan
1794 - \ref AstVar Channel variables
1795 - \ref AstCauses The HANGUPCAUSE variable
1797 void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
1799 const char not_found = '\0';
1801 const char *s; /* the result */
1803 int i, need_substring;
1804 struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */
1807 ast_channel_lock(c);
1808 places[0] = &c->varshead;
1811 * Make a copy of var because parse_variable_name() modifies the string.
1812 * Then if called directly, we might need to run substring() on the result;
1813 * remember this for later in 'need_substring', 'offset' and 'length'
1815 tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */
1816 need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
1819 * Look first into predefined variables, then into variable lists.
1820 * Variable 's' points to the result, according to the following rules:
1821 * s == ¬_found (set at the beginning) means that we did not find a
1822 * matching variable and need to look into more places.
1823 * If s != ¬_found, s is a valid result string as follows:
1824 * s = NULL if the variable does not have a value;
1825 * you typically do this when looking for an unset predefined variable.
1826 * s = workspace if the result has been assembled there;
1827 * typically done when the result is built e.g. with an snprintf(),
1828 * so we don't need to do an additional copy.
1829 * s != workspace in case we have a string, that needs to be copied
1830 * (the ast_copy_string is done once for all at the end).
1831 * Typically done when the result is already available in some string.
1833 s = ¬_found; /* default value */
1834 if (c) { /* This group requires a valid channel */
1835 /* Names with common parts are looked up a piece at a time using strncmp. */
1836 if (!strncmp(var, "CALL", 4)) {
1837 if (!strncmp(var + 4, "ING", 3)) {
1838 if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */
1839 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres);
1841 } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */
1842 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2);
1844 } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */
1845 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton);
1847 } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */
1848 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns);
1852 } else if (!strcmp(var, "HINT")) {
1853 s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL;
1854 } else if (!strcmp(var, "HINTNAME")) {
1855 s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL;
1856 } else if (!strcmp(var, "EXTEN")) {
1858 } else if (!strcmp(var, "CONTEXT")) {
1860 } else if (!strcmp(var, "PRIORITY")) {
1861 snprintf(workspace, workspacelen, "%d", c->priority);
1863 } else if (!strcmp(var, "CHANNEL")) {
1865 } else if (!strcmp(var, "UNIQUEID")) {
1867 } else if (!strcmp(var, "HANGUPCAUSE")) {
1868 snprintf(workspace, workspacelen, "%d", c->hangupcause);
1872 if (s == ¬_found) { /* look for more */
1873 if (!strcmp(var, "EPOCH")) {
1874 snprintf(workspace, workspacelen, "%u",(int)time(NULL));
1876 } else if (!strcmp(var, "SYSTEMNAME")) {
1877 s = ast_config_AST_SYSTEM_NAME;
1880 /* if not found, look into chanvars or global vars */
1881 for (i = 0; s == ¬_found && i < (sizeof(places) / sizeof(places[0])); i++) {
1882 struct ast_var_t *variables;
1885 if (places[i] == &globals)
1886 ast_rwlock_rdlock(&globalslock);
1887 AST_LIST_TRAVERSE(places[i], variables, entries) {
1888 if (strcasecmp(ast_var_name(variables), var)==0) {
1889 s = ast_var_value(variables);
1893 if (places[i] == &globals)
1894 ast_rwlock_unlock(&globalslock);
1896 if (s == ¬_found || s == NULL)
1900 ast_copy_string(workspace, s, workspacelen);
1903 *ret = substring(*ret, offset, length, workspace, workspacelen);
1907 ast_channel_unlock(c);
1910 static void exception_store_free(void *data)
1912 struct pbx_exception *exception = data;
1913 ast_string_field_free_memory(exception);
1914 ast_free(exception);
1917 static struct ast_datastore_info exception_store_info = {
1918 .type = "EXCEPTION",
1919 .destroy = exception_store_free,
1922 int pbx_builtin_raise_exception(struct ast_channel *chan, void *vreason)
1924 const char *reason = vreason;
1925 struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL);
1926 struct pbx_exception *exception = NULL;
1929 ds = ast_channel_datastore_alloc(&exception_store_info, NULL);
1932 exception = ast_calloc(1, sizeof(struct pbx_exception));
1934 ast_channel_datastore_free(ds);
1937 if (ast_string_field_init(exception, 128)) {
1938 ast_free(exception);
1939 ast_channel_datastore_free(ds);
1942 ds->data = exception;
1943 ast_channel_datastore_add(chan, ds);
1945 exception = ds->data;
1947 ast_string_field_set(exception, reason, reason);
1948 ast_string_field_set(exception, context, chan->context);
1949 ast_string_field_set(exception, exten, chan->exten);
1950 exception->priority = chan->priority;
1951 set_ext_pri(chan, "e", 0);
1955 static int acf_exception_read(struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
1957 struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL);
1958 struct pbx_exception *exception = NULL;
1959 if (!ds || !ds->data)
1961 exception = ds->data;
1962 if (!strcasecmp(data, "REASON"))
1963 ast_copy_string(buf, exception->reason, buflen);
1964 else if (!strcasecmp(data, "CONTEXT"))
1965 ast_copy_string(buf, exception->context, buflen);
1966 else if (!strncasecmp(data, "EXTEN", 5))
1967 ast_copy_string(buf, exception->exten, buflen);
1968 else if (!strcasecmp(data, "PRIORITY"))
1969 snprintf(buf, buflen, "%d", exception->priority);
1975 static struct ast_custom_function exception_function = {
1976 .name = "EXCEPTION",
1977 .synopsis = "Retrieve the details of the current dialplan exception",
1979 "The following fields are available for retrieval:\n"
1980 " reason INVALID, ERROR, RESPONSETIMEOUT, ABSOLUTETIMEOUT, or custom\n"
1981 " value set by the RaiseException() application\n"
1982 " context The context executing when the exception occurred\n"
1983 " exten The extension executing when the exception occurred\n"
1984 " priority The numeric priority executing when the exception occurred\n",
1985 .syntax = "EXCEPTION(<field>)",
1986 .read = acf_exception_read,
1989 static char *handle_show_functions(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1991 struct ast_custom_function *acf;
1997 e->command = "core show functions [like]";
1999 "Usage: core show functions [like <text>]\n"
2000 " List builtin functions, optionally only those matching a given string\n";
2006 if (a->argc == 5 && (!strcmp(a->argv[3], "like")) ) {
2008 } else if (a->argc != 3) {
2009 return CLI_SHOWUSAGE;
2012 ast_cli(a->fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed");
2014 AST_RWLIST_RDLOCK(&acf_root);
2015 AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) {
2016 if (!like || strstr(acf->name, a->argv[4])) {
2018 ast_cli(a->fd, "%-20.20s %-35.35s %s\n", acf->name, acf->syntax, acf->synopsis);
2021 AST_RWLIST_UNLOCK(&acf_root);
2023 ast_cli(a->fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : "");
2028 static char *handle_show_function(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2030 struct ast_custom_function *acf;
2031 /* Maximum number of characters added by terminal coloring is 22 */
2032 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40];
2033 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL;
2034 char stxtitle[40], *syntax = NULL;
2035 int synopsis_size, description_size, syntax_size;
2042 e->command = "core show function";
2044 "Usage: core show function <function>\n"
2045 " Describe a particular dialplan function.\n";
2048 wordlen = strlen(a->word);
2049 /* case-insensitive for convenience in this 'complete' function */
2050 AST_RWLIST_RDLOCK(&acf_root);
2051 AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) {
2052 if (!strncasecmp(a->word, acf->name, wordlen) && ++which > a->n) {
2053 ret = ast_strdup(acf->name);
2057 AST_RWLIST_UNLOCK(&acf_root);
2063 return CLI_SHOWUSAGE;
2065 if (!(acf = ast_custom_function_find(a->argv[3]))) {
2066 ast_cli(a->fd, "No function by that name registered.\n");
2072 synopsis_size = strlen(acf->synopsis) + 23;
2074 synopsis_size = strlen("Not available") + 23;
2075 synopsis = alloca(synopsis_size);
2078 description_size = strlen(acf->desc) + 23;
2080 description_size = strlen("Not available") + 23;
2081 description = alloca(description_size);
2084 syntax_size = strlen(acf->syntax) + 23;
2086 syntax_size = strlen("Not available") + 23;
2087 syntax = alloca(syntax_size);
2089 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about function '%s' =- \n\n", acf->name);
2090 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22);
2091 term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
2092 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
2093 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
2095 acf->syntax ? acf->syntax : "Not available",
2096 COLOR_CYAN, 0, syntax_size);
2097 term_color(synopsis,
2098 acf->synopsis ? acf->synopsis : "Not available",
2099 COLOR_CYAN, 0, synopsis_size);
2100 term_color(description,
2101 acf->desc ? acf->desc : "Not available",
2102 COLOR_CYAN, 0, description_size);
2104 ast_cli(a->fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description);
2109 struct ast_custom_function *ast_custom_function_find(const char *name)
2111 struct ast_custom_function *acf = NULL;
2113 AST_RWLIST_RDLOCK(&acf_root);
2114 AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) {
2115 if (!strcmp(name, acf->name))
2118 AST_RWLIST_UNLOCK(&acf_root);
2123 int ast_custom_function_unregister(struct ast_custom_function *acf)
2125 struct ast_custom_function *cur;
2130 AST_RWLIST_WRLOCK(&acf_root);
2131 if ((cur = AST_RWLIST_REMOVE(&acf_root, acf, acflist)))
2132 ast_verb(2, "Unregistered custom function %s\n", cur->name);
2133 AST_RWLIST_UNLOCK(&acf_root);
2135 return cur ? 0 : -1;
2138 int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_module *mod)
2140 struct ast_custom_function *cur;
2147 AST_RWLIST_WRLOCK(&acf_root);
2149 AST_RWLIST_TRAVERSE(&acf_root, cur, acflist) {
2150 if (!strcmp(acf->name, cur->name)) {
2151 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
2152 AST_RWLIST_UNLOCK(&acf_root);
2157 /* Store in alphabetical order */
2158 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
2159 if (strcasecmp(acf->name, cur->name) < 0) {
2160 AST_RWLIST_INSERT_BEFORE_CURRENT(acf, acflist);
2164 AST_RWLIST_TRAVERSE_SAFE_END;
2166 AST_RWLIST_INSERT_TAIL(&acf_root, acf, acflist);
2168 AST_RWLIST_UNLOCK(&acf_root);
2170 ast_verb(2, "Registered custom function %s\n", acf->name);
2175 /*! \brief return a pointer to the arguments of the function,
2176 * and terminates the function name with '\\0'
2178 static char *func_args(char *function)
2180 char *args = strchr(function, '(');
2183 ast_log(LOG_WARNING, "Function doesn't contain parentheses. Assuming null argument.\n");
2187 if ((p = strrchr(args, ')')) )
2190 ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n");
2195 int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
2197 char *copy = ast_strdupa(function);
2198 char *args = func_args(copy);
2199 struct ast_custom_function *acfptr = ast_custom_function_find(copy);
2202 ast_log(LOG_ERROR, "Function %s not registered\n", copy);
2203 else if (!acfptr->read)
2204 ast_log(LOG_ERROR, "Function %s cannot be read\n", copy);
2207 struct ast_module_user *u = NULL;
2209 u = __ast_module_user_add(acfptr->mod, chan);
2210 res = acfptr->read(chan, copy, args, workspace, len);
2211 if (acfptr->mod && u)
2212 __ast_module_user_remove(acfptr->mod, u);
2218 int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
2220 char *copy = ast_strdupa(function);
2221 char *args = func_args(copy);
2222 struct ast_custom_function *acfptr = ast_custom_function_find(copy);
2225 ast_log(LOG_ERROR, "Function %s not registered\n", copy);
2226 else if (!acfptr->write)
2227 ast_log(LOG_ERROR, "Function %s cannot be written to\n", copy);
2230 struct ast_module_user *u = NULL;
2232 u = __ast_module_user_add(acfptr->mod, chan);
2233 res = acfptr->write(chan, copy, args, value);
2234 if (acfptr->mod && u)
2235 __ast_module_user_remove(acfptr->mod, u);
2242 static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count)
2244 /* Substitutes variables into cp2, based on string cp1, cp2 NO LONGER NEEDS TO BE ZEROED OUT!!!! */
2246 const char *tmp, *whereweare;
2247 int length, offset, offset2, isfunction;
2248 char *workspace = NULL;
2249 char *ltmp = NULL, *var = NULL;
2250 char *nextvar, *nextexp, *nextthing;
2252 int pos, brackets, needsub, len;
2254 *cp2 = 0; /* just in case nothing ends up there */
2256 while (!ast_strlen_zero(whereweare) && count) {
2257 /* Assume we're copying the whole remaining string */
2258 pos = strlen(whereweare);
2261 nextthing = strchr(whereweare, '$');
2263 switch (nextthing[1]) {
2265 nextvar = nextthing;
2266 pos = nextvar - whereweare;
2269 nextexp = nextthing;
2270 pos = nextexp - whereweare;
2278 /* Can't copy more than 'count' bytes */
2282 /* Copy that many bytes */
2283 memcpy(cp2, whereweare, pos);
2292 /* We have a variable. Find the start and end, and determine
2293 if we are going to have to recursively call ourselves on the
2295 vars = vare = nextvar + 2;
2299 /* Find the end of it */
2300 while (brackets && *vare) {
2301 if ((vare[0] == '$') && (vare[1] == '{')) {
2303 } else if (vare[0] == '{') {
2305 } else if (vare[0] == '}') {
2307 } else if ((vare[0] == '$') && (vare[1] == '['))
2312 ast_log(LOG_NOTICE, "Error in extension logic (missing '}')\n");
2313 len = vare - vars - 1;
2315 /* Skip totally over variable string */
2316 whereweare += (len + 3);
2319 var = alloca(VAR_BUF_SIZE);
2321 /* Store variable name (and truncate) */
2322 ast_copy_string(var, vars, len + 1);
2324 /* Substitute if necessary */
2327 ltmp = alloca(VAR_BUF_SIZE);
2329 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1);
2336 workspace = alloca(VAR_BUF_SIZE);
2338 workspace[0] = '\0';
2340 parse_variable_name(vars, &offset, &offset2, &isfunction);
2342 /* Evaluate function */
2344 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
2346 struct varshead old;
2347 struct ast_channel *c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/%p", vars);
2349 memcpy(&old, &c->varshead, sizeof(old));
2350 memcpy(&c->varshead, headp, sizeof(c->varshead));
2351 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
2352 /* Don't deallocate the varshead that was passed in */
2353 memcpy(&c->varshead, &old, sizeof(c->varshead));
2354 ast_channel_free(c);
2356 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n");
2358 ast_debug(1, "Function result is '%s'\n", cp4 ? cp4 : "(null)");
2360 /* Retrieve variable value */
2361 pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp);
2364 cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE);
2366 length = strlen(cp4);
2369 memcpy(cp2, cp4, length);
2374 } else if (nextexp) {
2375 /* We have an expression. Find the start and end, and determine
2376 if we are going to have to recursively call ourselves on the
2378 vars = vare = nextexp + 2;
2382 /* Find the end of it */
2383 while (brackets && *vare) {
2384 if ((vare[0] == '$') && (vare[1] == '[')) {
2388 } else if (vare[0] == '[') {
2390 } else if (vare[0] == ']') {
2392 } else if ((vare[0] == '$') && (vare[1] == '{')) {
2399 ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n");
2400 len = vare - vars - 1;
2402 /* Skip totally over expression */
2403 whereweare += (len + 3);
2406 var = alloca(VAR_BUF_SIZE);
2408 /* Store variable name (and truncate) */
2409 ast_copy_string(var, vars, len + 1);
2411 /* Substitute if necessary */
2414 ltmp = alloca(VAR_BUF_SIZE);
2416 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1);
2422 length = ast_expr(vars, cp2, count, c);
2425 ast_debug(1, "Expression result is '%s'\n", cp2);
2434 void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
2436 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
2439 void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1, char *cp2, int count)
2441 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
2444 static void pbx_substitute_variables(char *passdata, int datalen, struct ast_channel *c, struct ast_exten *e)
2448 /* Nothing more to do */
2452 /* No variables or expressions in e->data, so why scan it? */
2453 if ((!(tmp = strchr(e->data, '$'))) || (!strstr(tmp, "${") && !strstr(tmp, "$["))) {
2454 ast_copy_string(passdata, e->data, datalen);
2458 pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1);
2461 /*! \brief The return value depends on the action:
2463 * E_MATCH, E_CANMATCH, E_MATCHMORE require a real match,
2464 * and return 0 on failure, -1 on match;
2465 * E_FINDLABEL maps the label to a priority, and returns
2466 * the priority on success, ... XXX
2467 * E_SPAWN, spawn an application,
2469 * \retval 0 on success.
2470 * \retval -1 on failure.
2472 static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con,
2473 const char *context, const char *exten, int priority,
2474 const char *label, const char *callerid, enum ext_match_t action, int *found, int combined_find_spawn)
2476 struct ast_exten *e;
2477 struct ast_app *app;
2479 struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
2480 char passdata[EXT_DATA_SIZE];
2482 int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE);
2484 ast_rdlock_contexts();
2487 e = pbx_find_extension(c, con, &q, context, exten, priority, label, callerid, action);
2491 if (matching_action) {
2492 ast_unlock_contexts();
2493 return -1; /* success, we found it */
2494 } else if (action == E_FINDLABEL) { /* map the label to a priority */
2496 ast_unlock_contexts();
2497 return res; /* the priority we were looking for */
2498 } else { /* spawn */
2500 e->cached_app = pbx_findapp(e->app);
2501 app = e->cached_app;
2502 ast_unlock_contexts();
2504 ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority);
2507 if (c->context != context)
2508 ast_copy_string(c->context, context, sizeof(c->context));
2509 if (c->exten != exten)
2510 ast_copy_string(c->exten, exten, sizeof(c->exten));
2511 c->priority = priority;
2512 pbx_substitute_variables(passdata, sizeof(passdata), c, e);
2515 char atmp2[EXT_DATA_SIZE+100];
2516 ast_debug(1, "Launching '%s'\n", app->name);
2517 snprintf(atmp, sizeof(atmp), "STACK-%s-%s-%d", context, exten, priority);
2518 snprintf(atmp2, sizeof(atmp2), "%s(\"%s\", \"%s\") %s",
2519 app->name, c->name, passdata, "in new stack");
2520 pbx_builtin_setvar_helper(c, atmp, atmp2);
2522 if (option_verbose > 2) {
2523 char tmp[80], tmp2[80], tmp3[EXT_DATA_SIZE];
2524 ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\") %s\n",
2525 exten, context, priority,
2526 term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)),
2527 term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
2528 term_color(tmp3, passdata, COLOR_BRMAGENTA, 0, sizeof(tmp3)),
2531 manager_event(EVENT_FLAG_CALL, "Newexten",
2536 "Application: %s\r\n"
2539 c->name, c->context, c->exten, c->priority, app->name, passdata, c->uniqueid);
2540 return pbx_exec(c, app, passdata); /* 0 on success, -1 on failure */
2542 } else if (q.swo) { /* not found here, but in another switch */
2543 ast_unlock_contexts();
2544 if (matching_action)
2548 ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name);
2551 return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data);
2553 } else { /* not found anywhere, see what happened */
2554 ast_unlock_contexts();
2556 case STATUS_NO_CONTEXT:
2557 if (!matching_action && !combined_find_spawn)
2558 ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context);
2560 case STATUS_NO_EXTENSION:
2561 if (!matching_action && !combined_find_spawn)
2562 ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context);
2564 case STATUS_NO_PRIORITY:
2565 if (!matching_action && !combined_find_spawn)
2566 ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context);
2568 case STATUS_NO_LABEL:
2569 if (context && !combined_find_spawn)
2570 ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, context);
2573 ast_debug(1, "Shouldn't happen!\n");
2576 return (matching_action) ? 0 : -1;
2580 /*! \brief Find hint for given extension in context */
2581 static struct ast_exten *ast_hint_extension(struct ast_channel *c, const char *context, const char *exten)
2583 struct ast_exten *e;
2584 struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */
2586 ast_rdlock_contexts();
2587 e = pbx_find_extension(c, NULL, &q, context, exten, PRIORITY_HINT, NULL, "", E_MATCH);
2588 ast_unlock_contexts();
2593 /*! \brief Check state of extension by using hints */
2594 static int ast_extension_state2(struct ast_exten *e)
2596 char hint[AST_MAX_EXTENSION];
2598 int allunavailable = 1, allbusy = 1, allfree = 1, allonhold = 1;
2599 int busy = 0, inuse = 0, ring = 0;
2604 ast_copy_string(hint, ast_get_extension_app(e), sizeof(hint));
2606 rest = hint; /* One or more devices separated with a & character */
2607 while ( (cur = strsep(&rest, "&")) ) {
2608 int res = ast_device_state(cur);
2610 case AST_DEVICE_NOT_INUSE:
2615 case AST_DEVICE_INUSE:
2621 case AST_DEVICE_RINGING:
2627 case AST_DEVICE_RINGINUSE:
2634 case AST_DEVICE_ONHOLD:
2638 case AST_DEVICE_BUSY:
2644 case AST_DEVICE_UNAVAILABLE:
2645 case AST_DEVICE_INVALID:
2659 return AST_EXTENSION_RINGING;
2661 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING);
2663 return AST_EXTENSION_INUSE;
2665 return AST_EXTENSION_NOT_INUSE;
2667 return AST_EXTENSION_ONHOLD;
2669 return AST_EXTENSION_BUSY;
2671 return AST_EXTENSION_UNAVAILABLE;
2673 return AST_EXTENSION_INUSE;
2675 return AST_EXTENSION_NOT_INUSE;
2678 /*! \brief Return extension_state as string */
2679 const char *ast_extension_state2str(int extension_state)
2683 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) {
2684 if (extension_states[i].extension_state == extension_state)
2685 return extension_states[i].text;
2690 /*! \brief Check extension state for an extension by using hint */
2691 int ast_extension_state(struct ast_channel *c, const char *context, const char *exten)
2693 struct ast_exten *e;
2695 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */
2697 return -1; /* No hint, return -1 */
2699 return ast_extension_state2(e); /* Check all devices in the hint */
2702 static void handle_statechange(const char *device)
2704 struct ast_hint *hint;
2706 AST_RWLIST_RDLOCK(&hints);
2708 AST_RWLIST_TRAVERSE(&hints, hint, list) {
2709 struct ast_state_cb *cblist;
2710 char buf[AST_MAX_EXTENSION];
2715 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf));
2716 while ( (cur = strsep(&parse, "&")) ) {
2717 if (!strcasecmp(cur, device))
2723 /* Get device state for this hint */
2724 state = ast_extension_state2(hint->exten);
2726 if ((state == -1) || (state == hint->laststate))
2729 /* Device state changed since last check - notify the watchers */
2731 /* For general callbacks */
2732 for (cblist = statecbs; cblist; cblist = cblist->next)
2733 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
2735 /* For extension callbacks */
2736 for (cblist = hint->callbacks; cblist; cblist = cblist->next)
2737 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
2739 hint->laststate = state; /* record we saw the change */
2742 AST_RWLIST_UNLOCK(&hints);
2745 static int statechange_queue(const char *dev)
2747 struct statechange *sc;
2749 if (!(sc = ast_calloc(1, sizeof(*sc) + strlen(dev) + 1)))
2752 strcpy(sc->dev, dev);
2754 ast_mutex_lock(&device_state.lock);
2755 AST_LIST_INSERT_TAIL(&device_state.state_change_q, sc, entry);
2756 ast_cond_signal(&device_state.cond);
2757 ast_mutex_unlock(&device_state.lock);
2762 static void *device_state_thread(void *data)
2764 struct statechange *sc;
2766 while (!device_state.stop) {
2767 ast_mutex_lock(&device_state.lock);
2768 while (!(sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry))) {
2769 ast_cond_wait(&device_state.cond, &device_state.lock);
2770 /* Check to see if we were woken up to see the request to stop */
2771 if (device_state.stop) {
2772 ast_mutex_unlock(&device_state.lock);
2776 ast_mutex_unlock(&device_state.lock);
2778 handle_statechange(sc->dev);
2786 /*! \brief Add watcher for extension states */
2787 int ast_extension_state_add(const char *context, const char *exten,
2788 ast_state_cb_type callback, void *data)
2790 struct ast_hint *hint;
2791 struct ast_state_cb *cblist;
2792 struct ast_exten *e;
2794 /* If there's no context and extension: add callback to statecbs list */
2795 if (!context && !exten) {
2796 AST_RWLIST_WRLOCK(&hints);
2798 for (cblist = statecbs; cblist; cblist = cblist->next) {
2799 if (cblist->callback == callback) {
2800 cblist->data = data;
2801 AST_RWLIST_UNLOCK(&hints);
2806 /* Now insert the callback */
2807 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
2808 AST_RWLIST_UNLOCK(&hints);
2812 cblist->callback = callback;
2813 cblist->data = data;
2815 cblist->next = statecbs;
2818 AST_RWLIST_UNLOCK(&hints);
2822 if (!context || !exten)
2825 /* This callback type is for only one hint, so get the hint */
2826 e = ast_hint_extension(NULL, context, exten);
2831 /* Find the hint in the list of hints */
2832 AST_RWLIST_WRLOCK(&hints);
2834 AST_RWLIST_TRAVERSE(&hints, hint, list) {
2835 if (hint->exten == e)
2840 /* We have no hint, sorry */
2841 AST_RWLIST_UNLOCK(&hints);
2845 /* Now insert the callback in the callback list */
2846 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
2847 AST_RWLIST_UNLOCK(&hints);
2850 cblist->id = stateid++; /* Unique ID for this callback */
2851 cblist->callback = callback; /* Pointer to callback routine */
2852 cblist->data = data; /* Data for the callback */
2854 cblist->next = hint->callbacks;
2855 hint->callbacks = cblist;
2857 AST_RWLIST_UNLOCK(&hints);
2861 /*! \brief Remove a watcher from the callback list */
2862 int ast_extension_state_del(int id, ast_state_cb_type callback)
2864 struct ast_state_cb **p_cur = NULL; /* address of pointer to us */
2867 if (!id && !callback)
2870 AST_RWLIST_WRLOCK(&hints);
2872 if (!id) { /* id == 0 is a callback without extension */
2873 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) {
2874 if ((*p_cur)->callback == callback)
2877 } else { /* callback with extension, find the callback based on ID */
2878 struct ast_hint *hint;
2879 AST_RWLIST_TRAVERSE(&hints, hint, list) {
2880 for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) {
2881 if ((*p_cur)->id == id)
2884 if (*p_cur) /* found in the inner loop */
2888 if (p_cur && *p_cur) {
2889 struct ast_state_cb *cur = *p_cur;
2894 AST_RWLIST_UNLOCK(&hints);
2898 /*! \brief Add hint to hint list, check initial extension state */
2899 static int ast_add_hint(struct ast_exten *e)
2901 struct ast_hint *hint;
2906 AST_RWLIST_WRLOCK(&hints);
2908 /* Search if hint exists, do nothing */
2909 AST_RWLIST_TRAVERSE(&hints, hint, list) {
2910 if (hint->exten == e) {
2911 AST_RWLIST_UNLOCK(&hints);
2912 ast_debug(2, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e));
2917 ast_debug(2, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e));
2919 if (!(hint = ast_calloc(1, sizeof(*hint)))) {
2920 AST_RWLIST_UNLOCK(&hints);
2923 /* Initialize and insert new item at the top */
2925 hint->laststate = ast_extension_state2(e);
2926 AST_RWLIST_INSERT_HEAD(&hints, hint, list);
2928 AST_RWLIST_UNLOCK(&hints);
2932 /*! \brief Change hint for an extension */
2933 static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
2935 struct ast_hint *hint;
2938 AST_RWLIST_WRLOCK(&hints);
2939 AST_RWLIST_TRAVERSE(&hints, hint, list) {
2940 if (hint->exten == oe) {
2946 AST_RWLIST_UNLOCK(&hints);
2951 /*! \brief Remove hint from extension */
2952 static int ast_remove_hint(struct ast_exten *e)
2954 /* Cleanup the Notifys if hint is removed */
2955 struct ast_hint *hint;
2956 struct ast_state_cb *cblist, *cbprev;
2962 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&hints, hint, list) {
2963 if (hint->exten == e) {
2965 cblist = hint->callbacks;
2967 /* Notify with -1 and remove all callbacks */
2969 cblist = cblist->next;
2970 cbprev->callback(hint->exten->parent->name, hint->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data);
2973 hint->callbacks = NULL;
2974 AST_RWLIST_REMOVE_CURRENT(list);
2980 AST_RWLIST_TRAVERSE_SAFE_END;
2986 /*! \brief Get hint for channel */
2987 int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
2989 struct ast_exten *e = ast_hint_extension(c, context, exten);
2993 ast_copy_string(hint, ast_get_extension_app(e), hintsize);
2995 const char *tmp = ast_get_extension_app_data(e);
2997 ast_copy_string(name, tmp, namesize);
3004 int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
3006 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0, 0);
3009 int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
3011 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
3014 int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
3016 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
3019 int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
3021 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0, 0);
3024 int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
3026 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0);
3029 int ast_spawn_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid, int *found, int combined_find_spawn)
3031 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn);
3034 /*! helper function to set extension and priority */
3035 static void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
3037 ast_copy_string(c->exten, exten, sizeof(c->exten));
3042 * \brief collect digits from the channel into the buffer.
3043 * \retval 0 on timeout or done.
3044 * \retval -1 on error.
3046 static int collect_digits(struct ast_channel *c, int waittime, char *buf, int buflen, int pos)
3050 buf[pos] = '\0'; /* make sure it is properly terminated */
3051 while (ast_matchmore_extension(c, c->context, buf, 1, c->cid.cid_num)) {
3052 /* As long as we're willing to wait, and as long as it's not defined,
3053 keep reading digits until we can't possibly get a right answer anymore. */
3054 digit = ast_waitfordigit(c, waittime * 1000);
3055 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
3058 if (!digit) /* No entry */
3060 if (digit < 0) /* Error, maybe a hangup */
3062 if (pos < buflen - 1) { /* XXX maybe error otherwise ? */
3066 waittime = c->pbx->dtimeout;
3072 static int __ast_pbx_run(struct ast_channel *c)
3074 int found = 0; /* set if we find at least one match */
3077 int error = 0; /* set an error conditions */
3079 /* A little initial setup here */
3081 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name);
3082 /* XXX and now what ? */
3085 if (!(c->pbx = ast_calloc(1, sizeof(*c->pbx))))
3089 c->cdr = ast_cdr_alloc();
3091 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
3095 ast_cdr_init(c->cdr, c);
3098 /* Set reasonable defaults */
3099 c->pbx->rtimeout = 10;
3100 c->pbx->dtimeout = 5;
3102 autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */
3103 ast_set_flag(c, AST_FLAG_IN_AUTOLOOP);
3105 /* Start by trying whatever the channel is set to */
3106 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
3107 /* If not successful fall back to 's' */
3108 ast_verb(2, "Starting %s at %s,%s,%d failed so falling back to exten 's'\n", c->name, c->context, c->exten, c->priority);
3109 /* XXX the original code used the existing priority in the call to
3110 * ast_exists_extension(), and reset it to 1 afterwards.
3111 * I believe the correct thing is to set it to 1 immediately.
3113 set_ext_pri(c, "s", 1);
3114 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
3115 /* JK02: And finally back to default if everything else failed */
3116 ast_verb(2, "Starting %s at %s,%s,%d still failed so falling back to context 'default'\n", c->name, c->context, c->exten, c->priority);
3117 ast_copy_string(c->context, "default", sizeof(c->context));
3120 if (c->cdr && ast_tvzero(c->cdr->start))
3121 ast_cdr_start(c->cdr);
3123 char dst_exten[256]; /* buffer to accumulate digits */
3124 int pos = 0; /* XXX should check bounds */
3127 /* loop on priorities in this context/exten */
3128 while ( !(res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num, &found,1))) {
3129 if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c, c->context, "T", 1, c->cid.cid_num)) {
3130 set_ext_pri(c, "T", 0); /* 0 will become 1 with the c->priority++; at the end */
3131 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
3132 c->whentohangup = 0;
3133 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
3134 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
3135 pbx_builtin_raise_exception(c, "ABSOLUTETIMEOUT");
3136 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
3137 c->whentohangup = 0;
3138 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
3139 } else if (ast_check_hangup(c)) {
3140 ast_debug(1, "Extension %s, priority %d returned normally even though call was hung up\n",
3141 c->exten, c->priority);
3146 } /* end while - from here on we can use 'break' to go out */
3148 /* Something bad happened, or a hangup has been requested. */
3149 if (strchr("0123456789ABCDEF*#", res)) {
3150 ast_debug(1, "Oooh, got something to jump out with ('%c')!\n", res);
3152 dst_exten[pos++] = digit = res;
3153 dst_exten[pos] = '\0';
3154 } else if (res == AST_PBX_KEEPALIVE) {
3155 ast_debug(1, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
3156 ast_verb(2, "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
3159 ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
3160 ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
3162 if ((res == AST_PBX_ERROR) && ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
3163 /* if we are already on the 'e' exten, don't jump to it again */
3164 if (!strcmp(c->exten, "e")) {
3165 if (option_verbose > 1)
3166 ast_verbose(VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited ERROR while already on 'e' exten on '%s'\n", c->context, c->exten, c->priority, c->name);
3169 pbx_builtin_raise_exception(c, "ERROR");
3174 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
3176 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
3177 /* atimeout, nothing bad */
3190 * We get here on a failure of some kind: non-existing extension or
3191 * hangup. We have options, here. We can either catch the failure
3192 * and continue, or we can drop out entirely. */
3194 if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) {
3196 * If there is no match at priority 1, it is not a valid extension anymore.
3197 * Try to continue at "i" (for invalid) or "e" (for exception) or exit if
3200 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
3201 ast_verb(3, "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name);
3202 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten);
3203 set_ext_pri(c, "i", 1);
3204 } else if (ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
3205 pbx_builtin_raise_exception(c, "INVALID");
3207 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n",
3208 c->name, c->exten, c->context);
3209 error = 1; /* we know what to do with it */
3212 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
3213 /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */
3215 } else { /* keypress received, get more digits for a full extension */
3218 waittime = c->pbx->dtimeout;
3219 else if (!autofallthrough)
3220 waittime = c->pbx->rtimeout;
3222 const char *status = pbx_builtin_getvar_helper(c, "DIALSTATUS");
3225 ast_verb(3, "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status);
3226 if (!strcasecmp(status, "CONGESTION"))
3227 res = pbx_builtin_congestion(c, "10");
3228 else if (!strcasecmp(status, "CHANUNAVAIL"))
3229 res = pbx_builtin_congestion(c, "10");
3230 else if (!strcasecmp(status, "BUSY"))
3231 res = pbx_builtin_busy(c, "10");
3232 error = 1; /* XXX disable message */
3233 break; /* exit from the 'for' loop */
3236 if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos))
3238 if (ast_exists_extension(c, c->context, dst_exten, 1, c->cid.cid_num)) /* Prepare the next cycle */
3239 set_ext_pri(c, dst_exten, 1);
3241 /* No such extension */
3242 if (!ast_strlen_zero(dst_exten)) {
3243 /* An invalid extension */
3244 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
3245 ast_verb(3, "Invalid extension '%s' in context '%s' on %s\n", dst_exten, c->context, c->name);
3246 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten);
3247 set_ext_pri(c, "i", 1);
3248 } else if (ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
3249 pbx_builtin_raise_exception(c, "INVALID");
3251 ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", dst_exten, c->context);
3252 found = 1; /* XXX disable message */
3256 /* A simple timeout */
3257 if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) {
3258 ast_verb(3, "Timeout on %s\n", c->name);
3259 set_ext_pri(c, "t", 1);
3260 } else if (ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
3261 pbx_builtin_raise_exception(c, "RESPONSETIMEOUT");
3263 ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context);
3264 found = 1; /* XXX disable message */
3270 ast_verb(2, "CDR updated on %s\n",c->name);
3275 if (!found && !error)
3276 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
3277 if (res != AST_PBX_KEEPALIVE)
3278 ast_softhangup(c, c->hangupcause ? c->hangupcause : AST_CAUSE_NORMAL_CLEARING);
3279 if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) {
3280 if (c->cdr && ast_opt_end_cdr_before_h_exten)
3281 ast_cdr_end(c->cdr);
3282 set_ext_pri(c, "h", 1);
3283 while ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num, &found, 1)) == 0) {
3287 /* Something bad happened, or a hangup has been requested. */
3288 ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
3289 ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
3292 ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP);
3294 pbx_destroy(c->pbx);
3296 if (res != AST_PBX_KEEPALIVE)
3302 * \brief Increase call count for channel
3303 * \retval 0 on success
3304 * \retval non-zero if a configured limit (maxcalls, maxload, minmemfree) was reached
3306 static int increase_call_count(const struct ast_channel *c)
3310 #if defined(HAVE_SYSINFO)
3312 struct sysinfo sys_info;
3315 ast_mutex_lock(&maxcalllock);
3316 if (option_maxcalls) {
3317 if (countcalls >= option_maxcalls) {
3318 ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name);
3322 if (option_maxload) {
3323 getloadavg(&curloadavg, 1);
3324 if (curloadavg >= option_maxload) {
3325 ast_log(LOG_NOTICE, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg);
3329 #if defined(HAVE_SYSINFO)
3330 if (option_minmemfree) {
3331 if (!sysinfo(&sys_info)) {
3332 /* make sure that the free system memory is above the configured low watermark
3333 * convert the amount of freeram from mem_units to MB */
3334 curfreemem = sys_info.freeram / sys_info.mem_unit;
3335 curfreemem /= 1024*1024;
3336 if (curfreemem < option_minmemfree) {
3337 ast_log(LOG_WARNING, "Available system memory (~%ldMB) is below the configured low watermark (%ldMB)\n", curfreemem, option_minmemfree);
3346 ast_mutex_unlock(&maxcalllock);
3351 static void decrease_call_count(void)
3353 ast_mutex_lock(&maxcalllock);
3356 ast_mutex_unlock(&maxcalllock);
3359 static void destroy_exten(struct ast_exten *e)
3361 if (e->priority == PRIORITY_HINT)
3365 ast_hashtab_destroy(e->peer_tree,0);
3366 if (e->peer_label_tree)
3367 ast_hashtab_destroy(e->peer_label_tree, 0);
3373 static void *pbx_thread(void *data)
3375 /* Oh joyeous kernel, we're a new thread, with nothing to do but
3376 answer this channel and get it going.
3379 The launcher of this function _MUST_ increment 'countcalls'
3380 before invoking the function; it will be decremented when the
3381 PBX has finished running on the channel
3383 struct ast_channel *c = data;
3386 decrease_call_count();
3393 enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
3398 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
3399 return AST_PBX_FAILED;
3402 if (increase_call_count(c))
3403 return AST_PBX_CALL_LIMIT;
3405 /* Start a new thread, and get something handling this channel. */
3406 if (ast_pthread_create_detached(&t, NULL, pbx_thread, c)) {
3407 ast_log(LOG_WARNING, "Failed to create new channel thread\n");
3408 return AST_PBX_FAILED;
3411 return AST_PBX_SUCCESS;
3414 enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
3416 enum ast_pbx_result res = AST_PBX_SUCCESS;
3418 if (increase_call_count(c))
3419 return AST_PBX_CALL_LIMIT;
3421 res = __ast_pbx_run(c);
3422 decrease_call_count();
3427 int ast_active_calls(void)
3432 int pbx_set_autofallthrough(int newval)
3434 int oldval = autofallthrough;
3435 autofallthrough = newval;
3440 * \brief lookup for a context with a given name,
3441 * \retval with conlock held if found.
3442 * \retval NULL if not found.
3444 static struct ast_context *find_context_locked(const char *context)
3446 struct ast_context *c = NULL;
3447 struct fake_context item;
3448 strncpy(item.name, context, 256);
3449 ast_rdlock_contexts();
3450 c = ast_hashtab_lookup(contexts_tree,&item);
3454 while ( (c = ast_walk_contexts(c)) ) {
3455 if (!strcmp(ast_get_context_name(c), context))
3459 ast_unlock_contexts();
3465 * \brief Remove included contexts.
3466 * This function locks contexts list by &conlist, search for the right context
3467 * structure, leave context list locked and call ast_context_remove_include2
3468 * which removes include, unlock contexts list and return ...
3470 int ast_context_remove_include(const char *context, const char *include, const char *registrar)
3473 struct ast_context *c = find_context_locked(context);
3476 /* found, remove include from this context ... */
3477 ret = ast_context_remove_include2(c, include, registrar);
3478 ast_unlock_contexts();
3484 * \brief Locks context, remove included contexts, unlocks context.
3485 * When we call this function, &conlock lock must be locked, because when
3486 * we giving *con argument, some process can remove/change this context
3487 * and after that there can be segfault.
3489 * \retval 0 on success.
3490 * \retval -1 on failure.
3492 int ast_context_remove_include2(struct ast_context *con, const char *include, const char *registrar)
3494 struct ast_include *i, *pi = NULL;
3497 ast_wrlock_context(con);
3499 /* find our include */
3500 for (i = con->includes; i; pi = i, i = i->next) {
3501 if (!strcmp(i->name, include) &&
3502 (!registrar || !strcmp(i->registrar, registrar))) {
3503 /* remove from list */
3507 con->includes = i->next;
3508 /* free include and return */
3515 ast_unlock_context(con);
3521 * \note This function locks contexts list by &conlist, search for the rigt context
3522 * structure, leave context list locked and call ast_context_remove_switch2
3523 * which removes switch, unlock contexts list and return ...
3525 int ast_context_remove_switch(const char *context, const char *sw, const char *data, const char *registrar)
3527 int ret = -1; /* default error return */
3528 struct ast_context *c = find_context_locked(context);
3531 /* remove switch from this context ... */
3532 ret = ast_context_remove_switch2(c, sw, data, registrar);
3533 ast_unlock_contexts();
3539 * \brief This function locks given context, removes switch, unlock context and
3541 * \note When we call this function, &conlock lock must be locked, because when
3542 * we giving *con argument, some process can remove/change this context
3543 * and after that there can be segfault.
3546 int ast_context_remove_switch2(struct ast_context *con, const char *sw, const char *data, const char *registrar)
3551 ast_wrlock_context(con);
3554 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
3555 if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
3556 (!registrar || !strcmp(i->registrar, registrar))) {
3557 /* found, remove from list */
3558 AST_LIST_REMOVE_CURRENT(list);
3559 ast_free(i); /* free switch and return */