Asterisk - The Open Source Telephony Project  GIT-master-a24979a
pbx.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2008, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*! \file
20  *
21  * \brief Core PBX routines.
22  *
23  * \author Mark Spencer <markster@digium.com>
24  */
25 
26 /*** MODULEINFO
27  <support_level>core</support_level>
28  ***/
29 
30 #include "asterisk.h"
31 
32 #include "asterisk/_private.h"
33 #include "asterisk/paths.h" /* use ast_config_AST_SYSTEM_NAME */
34 #include <ctype.h>
35 #include <time.h>
36 #include <sys/time.h>
37 #if defined(HAVE_SYSINFO)
38 #include <sys/sysinfo.h>
39 #endif
40 #if defined(SOLARIS)
41 #include <sys/loadavg.h>
42 #endif
43 
44 #include "asterisk/lock.h"
45 #include "asterisk/cli.h"
46 #include "asterisk/pbx.h"
47 #include "asterisk/channel.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/time.h"
54 #include "asterisk/manager.h"
55 #include "asterisk/ast_expr.h"
56 #include "asterisk/linkedlists.h"
57 #define SAY_STUBS /* generate declarations and stubs for say methods */
58 #include "asterisk/say.h"
59 #include "asterisk/utils.h"
60 #include "asterisk/causes.h"
61 #include "asterisk/musiconhold.h"
62 #include "asterisk/app.h"
63 #include "asterisk/devicestate.h"
64 #include "asterisk/presencestate.h"
65 #include "asterisk/hashtab.h"
66 #include "asterisk/module.h"
67 #include "asterisk/indications.h"
68 #include "asterisk/taskprocessor.h"
69 #include "asterisk/xmldoc.h"
70 #include "asterisk/astobj2.h"
72 #include "asterisk/dial.h"
73 #include "asterisk/vector.h"
74 #include "pbx_private.h"
75 
76 /*!
77  * \note I M P O R T A N T :
78  *
79  * The speed of extension handling will likely be among the most important
80  * aspects of this PBX. The switching scheme as it exists right now isn't
81  * terribly bad (it's O(N+M), where N is the # of extensions and M is the avg #
82  * of priorities, but a constant search time here would be great ;-)
83  *
84  * A new algorithm to do searching based on a 'compiled' pattern tree is introduced
85  * here, and shows a fairly flat (constant) search time, even for over
86  * 10000 patterns.
87  *
88  * Also, using a hash table for context/priority name lookup can help prevent
89  * the find_extension routines from absorbing exponential cpu cycles as the number
90  * of contexts/priorities grow. I've previously tested find_extension with red-black trees,
91  * which have O(log2(n)) speed. Right now, I'm using hash tables, which do
92  * searches (ideally) in O(1) time. While these techniques do not yield much
93  * speed in small dialplans, they are worth the trouble in large dialplans.
94  *
95  */
96 
97 /*** DOCUMENTATION
98  <function name="EXCEPTION" language="en_US">
99  <synopsis>
100  Retrieve the details of the current dialplan exception.
101  </synopsis>
102  <syntax>
103  <parameter name="field" required="true">
104  <para>The following fields are available for retrieval:</para>
105  <enumlist>
106  <enum name="reason">
107  <para>INVALID, ERROR, RESPONSETIMEOUT, ABSOLUTETIMEOUT, or custom
108  value set by the RaiseException() application</para>
109  </enum>
110  <enum name="context">
111  <para>The context executing when the exception occurred.</para>
112  </enum>
113  <enum name="exten">
114  <para>The extension executing when the exception occurred.</para>
115  </enum>
116  <enum name="priority">
117  <para>The numeric priority executing when the exception occurred.</para>
118  </enum>
119  </enumlist>
120  </parameter>
121  </syntax>
122  <description>
123  <para>Retrieve the details (specified <replaceable>field</replaceable>) of the current dialplan exception.</para>
124  </description>
125  <see-also>
126  <ref type="application">RaiseException</ref>
127  </see-also>
128  </function>
129  <function name="TESTTIME" language="en_US">
130  <synopsis>
131  Sets a time to be used with the channel to test logical conditions.
132  </synopsis>
133  <syntax>
134  <parameter name="date" required="true" argsep=" ">
135  <para>Date in ISO 8601 format</para>
136  </parameter>
137  <parameter name="time" required="true" argsep=" ">
138  <para>Time in HH:MM:SS format (24-hour time)</para>
139  </parameter>
140  <parameter name="zone" required="false">
141  <para>Timezone name</para>
142  </parameter>
143  </syntax>
144  <description>
145  <para>To test dialplan timing conditions at times other than the current time, use
146  this function to set an alternate date and time. For example, you may wish to evaluate
147  whether a location will correctly identify to callers that the area is closed on Christmas
148  Day, when Christmas would otherwise fall on a day when the office is normally open.</para>
149  </description>
150  <see-also>
151  <ref type="application">GotoIfTime</ref>
152  </see-also>
153  </function>
154  <manager name="ShowDialPlan" language="en_US">
155  <synopsis>
156  Show dialplan contexts and extensions
157  </synopsis>
158  <syntax>
159  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
160  <parameter name="Extension">
161  <para>Show a specific extension.</para>
162  </parameter>
163  <parameter name="Context">
164  <para>Show a specific context.</para>
165  </parameter>
166  </syntax>
167  <description>
168  <para>Show dialplan contexts and extensions. Be aware that showing the full dialplan
169  may take a lot of capacity.</para>
170  </description>
171  </manager>
172  <manager name="ExtensionStateList" language="en_US">
173  <synopsis>
174  List the current known extension states.
175  </synopsis>
176  <syntax>
177  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
178  </syntax>
179  <description>
180  <para>This will list out all known extension states in a
181  sequence of <replaceable>ExtensionStatus</replaceable> events.
182  When finished, a <replaceable>ExtensionStateListComplete</replaceable> event
183  will be emitted.</para>
184  </description>
185  <see-also>
186  <ref type="manager">ExtensionState</ref>
187  <ref type="function">HINT</ref>
188  <ref type="function">EXTENSION_STATE</ref>
189  </see-also>
190  <responses>
191  <list-elements>
192  <xi:include xpointer="xpointer(/docs/managerEvent[@name='ExtensionStatus'])" />
193  </list-elements>
194  <managerEvent name="ExtensionStateListComplete" language="en_US">
195  <managerEventInstance class="EVENT_FLAG_COMMAND">
196  <synopsis>
197  Indicates the end of the list the current known extension states.
198  </synopsis>
199  <syntax>
200  <parameter name="EventList">
201  <para>Conveys the status of the event list.</para>
202  </parameter>
203  <parameter name="ListItems">
204  <para>Conveys the number of statuses reported.</para>
205  </parameter>
206  </syntax>
207  </managerEventInstance>
208  </managerEvent>
209  </responses>
210  </manager>
211  ***/
212 
213 #ifdef LOW_MEMORY
214 #define EXT_DATA_SIZE 256
215 #else
216 #define EXT_DATA_SIZE 8192
217 #endif
218 
219 #define SWITCH_DATA_LENGTH 256
220 
221 #define VAR_NORMAL 1
222 #define VAR_SOFTTRAN 2
223 #define VAR_HARDTRAN 3
224 
225 struct ast_context;
226 struct ast_app;
227 
230 
231 /*!
232  \brief ast_exten: An extension
233  The dialplan is saved as a linked list with each context
234  having it's own linked list of extensions - one item per
235  priority.
236 */
237 struct ast_exten {
238  char *exten; /*!< Clean Extension id */
239  char *name; /*!< Extension name (may include '-' eye candy) */
240  int matchcid; /*!< Match caller id ? */
241  const char *cidmatch; /*!< Caller id to match for this extension */
242  const char *cidmatch_display; /*!< Caller id to match (display version) */
243  int priority; /*!< Priority */
244  const char *label; /*!< Label */
245  struct ast_context *parent; /*!< The context this extension belongs to */
246  const char *app; /*!< Application to execute */
247  struct ast_app *cached_app; /*!< Cached location of application */
248  void *data; /*!< Data to use (arguments) */
249  void (*datad)(void *); /*!< Data destructor */
250  struct ast_exten *peer; /*!< Next higher priority with our extension */
251  struct ast_hashtab *peer_table; /*!< Priorities list in hashtab form -- only on the head of the peer list */
252  struct ast_hashtab *peer_label_table; /*!< labeled priorities in the peers -- only on the head of the peer list */
253  const char *registrar; /*!< Registrar */
254  const char *registrar_file; /*!< File name used to register extension */
255  int registrar_line; /*!< Line number the extension was registered in text */
256  struct ast_exten *next; /*!< Extension with a greater ID */
257  char stuff[0];
258 };
259 
260 /*! \brief match_char: forms a syntax tree for quick matching of extension patterns */
262 {
263  int is_pattern; /* the pattern started with '_' */
264  int deleted; /* if this is set, then... don't return it */
265  int specificity; /* simply the strlen of x, or 10 for X, 9 for Z, and 8 for N; and '.' and '!' will add 11 ? */
268  struct ast_exten *exten; /* attached to last char of a pattern for exten */
269  char x[1]; /* the pattern itself-- matches a single char */
270 };
271 
272 struct scoreboard /* make sure all fields are 0 before calling new_find_extension */
273 {
276  char last_char; /* set to ! or . if they are the end of the pattern */
277  int canmatch; /* if the string to match was just too short */
278  struct match_char *node;
280  struct ast_exten *exten;
281 };
282 
283 /*! \brief ast_context: An extension context - must remain in sync with fake_context */
284 struct ast_context {
285  ast_rwlock_t lock; /*!< A lock to prevent multiple threads from clobbering the context */
286  struct ast_exten *root; /*!< The root of the list of extensions */
287  struct ast_hashtab *root_table; /*!< For exact matches on the extensions in the pattern tree, and for traversals of the pattern_tree */
288  struct match_char *pattern_tree; /*!< A tree to speed up extension pattern matching */
289  struct ast_context *next; /*!< Link them together */
290  struct ast_includes includes; /*!< Include other contexts */
291  struct ast_ignorepats ignorepats; /*!< Patterns for which to continue playing dialtone */
292  struct ast_sws alts; /*!< Alternative switches */
293  char *registrar; /*!< Registrar -- make sure you malloc this, as the registrar may have to survive module unloads */
294  int refcount; /*!< each module that would have created this context should inc/dec this as appropriate */
295  int autohints; /*!< Whether autohints support is enabled or not */
296  ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
297  char name[0]; /*!< Name of the context */
298 };
299 
300 /*! \brief ast_state_cb: An extension state notify register item */
301 struct ast_state_cb {
302  /*! Watcher ID returned when registered. */
303  int id;
304  /*! Arbitrary data passed for callbacks. */
305  void *data;
306  /*! Flag if this callback is an extended callback containing detailed device status */
307  int extended;
308  /*! Callback when state changes. */
310  /*! Callback when destroyed so any resources given by the registerer can be freed. */
312  /*! \note Only used by ast_merge_contexts_and_delete */
314 };
315 
316 /*!
317  * \brief Structure for dial plan hints
318  *
319  * \note Hints are pointers from an extension in the dialplan to
320  * one or more devices (tech/name)
321  *
322  * See \ref AstExtState
323  */
324 struct ast_hint {
325  /*!
326  * \brief Hint extension
327  *
328  * \note
329  * Will never be NULL while the hint is in the hints container.
330  */
331  struct ast_exten *exten;
332  struct ao2_container *callbacks; /*!< Device state callback container for this extension */
333 
334  /*! Dev state variables */
335  int laststate; /*!< Last known device state */
336 
337  /*! Presence state variables */
338  int last_presence_state; /*!< Last known presence state */
339  char *last_presence_subtype; /*!< Last known presence subtype string */
340  char *last_presence_message; /*!< Last known presence message string */
341 
342  char context_name[AST_MAX_CONTEXT];/*!< Context of destroyed hint extension. */
343  char exten_name[AST_MAX_EXTENSION];/*!< Extension of destroyed hint extension. */
344 
345  AST_VECTOR(, char *) devices; /*!< Devices associated with the hint */
346 };
347 
348 STASIS_MESSAGE_TYPE_DEFN_LOCAL(hint_change_message_type);
349 STASIS_MESSAGE_TYPE_DEFN_LOCAL(hint_remove_message_type);
350 
351 #define HINTDEVICE_DATA_LENGTH 16
353 
354 /* --- Hash tables of various objects --------*/
355 #ifdef LOW_MEMORY
356 #define HASH_EXTENHINT_SIZE 17
357 #else
358 #define HASH_EXTENHINT_SIZE 563
359 #endif
360 
361 
362 /*! \brief Container for hint devices */
363 static struct ao2_container *hintdevices;
364 
365 /*!
366  * \brief Structure for dial plan hint devices
367  * \note hintdevice is one device pointing to a hint.
368  */
370  /*!
371  * \brief Hint this hintdevice belongs to.
372  * \note Holds a reference to the hint object.
373  */
374  struct ast_hint *hint;
375  /*! Name of the hint device. */
376  char hintdevice[1];
377 };
378 
379 /*! \brief Container for autohint contexts */
380 static struct ao2_container *autohints;
381 
382 /*!
383  * \brief Structure for dial plan autohints
384  */
385 struct ast_autohint {
386  /*! \brief Name of the registrar */
387  char *registrar;
388  /*! \brief Name of the context */
389  char context[1];
390 };
391 
392 /*!
393  * \note Using the device for hash
394  */
395 static int hintdevice_hash_cb(const void *obj, const int flags)
396 {
397  const struct ast_hintdevice *ext;
398  const char *key;
399 
400  switch (flags & OBJ_SEARCH_MASK) {
401  case OBJ_SEARCH_KEY:
402  key = obj;
403  break;
404  case OBJ_SEARCH_OBJECT:
405  ext = obj;
406  key = ext->hintdevice;
407  break;
408  default:
409  ast_assert(0);
410  return 0;
411  }
412 
413  return ast_str_case_hash(key);
414 }
415 
416 /*!
417  * \note Devices on hints are not unique so no CMP_STOP is returned
418  * Dont use ao2_find against hintdevices container cause there always
419  * could be more than one result.
420  */
421 static int hintdevice_cmp_multiple(void *obj, void *arg, int flags)
422 {
423  struct ast_hintdevice *left = obj;
424  struct ast_hintdevice *right = arg;
425  const char *right_key = arg;
426  int cmp;
427 
428  switch (flags & OBJ_SEARCH_MASK) {
429  case OBJ_SEARCH_OBJECT:
430  right_key = right->hintdevice;
431  /* Fall through */
432  case OBJ_SEARCH_KEY:
433  cmp = strcasecmp(left->hintdevice, right_key);
434  break;
436  /*
437  * We could also use a partial key struct containing a length
438  * so strlen() does not get called for every comparison instead.
439  */
440  cmp = strncmp(left->hintdevice, right_key, strlen(right_key));
441  break;
442  default:
443  ast_assert(0);
444  cmp = 0;
445  break;
446  }
447  return cmp ? 0 : CMP_MATCH;
448 }
449 
450 /*!
451  * \note Using the context name for hash
452  */
453 static int autohint_hash_cb(const void *obj, const int flags)
454 {
455  const struct ast_autohint *autohint;
456  const char *key;
457 
458  switch (flags & OBJ_SEARCH_MASK) {
459  case OBJ_SEARCH_KEY:
460  key = obj;
461  break;
462  case OBJ_SEARCH_OBJECT:
463  autohint = obj;
464  key = autohint->context;
465  break;
466  default:
467  ast_assert(0);
468  return 0;
469  }
470 
471  return ast_str_case_hash(key);
472 }
473 
474 static int autohint_cmp(void *obj, void *arg, int flags)
475 {
476  struct ast_autohint *left = obj;
477  struct ast_autohint *right = arg;
478  const char *right_key = arg;
479  int cmp;
480 
481  switch (flags & OBJ_SEARCH_MASK) {
482  case OBJ_SEARCH_OBJECT:
483  right_key = right->context;
484  /* Fall through */
485  case OBJ_SEARCH_KEY:
486  cmp = strcasecmp(left->context, right_key);
487  break;
489  /*
490  * We could also use a partial key struct containing a length
491  * so strlen() does not get called for every comparison instead.
492  */
493  cmp = strncmp(left->context, right_key, strlen(right_key));
494  break;
495  default:
496  ast_assert(0);
497  cmp = 0;
498  break;
499  }
500  return cmp ? 0 : CMP_MATCH | CMP_STOP;
501 }
502 
503 /*! \internal \brief \c ao2_callback function to remove hintdevices */
504 static int hintdevice_remove_cb(void *obj, void *arg, void *data, int flags)
505 {
506  struct ast_hintdevice *candidate = obj;
507  char *device = arg;
508  struct ast_hint *hint = data;
509 
510  if (!strcasecmp(candidate->hintdevice, device)
511  && candidate->hint == hint) {
512  return CMP_MATCH;
513  }
514  return 0;
515 }
516 
517 static int remove_hintdevice(struct ast_hint *hint)
518 {
519  while (AST_VECTOR_SIZE(&hint->devices) > 0) {
520  char *device = AST_VECTOR_GET(&hint->devices, 0);
521 
523  hintdevice_remove_cb, device, hint, "Remove device from container");
525  ast_free(device);
526  }
527 
528  return 0;
529 }
530 
531 static char *parse_hint_device(struct ast_str *hint_args);
532 /*!
533  * \internal
534  * \brief Destroy the given hintdevice object.
535  *
536  * \param obj Hint device to destroy.
537  */
538 static void hintdevice_destroy(void *obj)
539 {
540  struct ast_hintdevice *doomed = obj;
541 
542  if (doomed->hint) {
543  ao2_ref(doomed->hint, -1);
544  doomed->hint = NULL;
545  }
546 }
547 
548 /*! \brief add hintdevice structure and link it into the container.
549  */
550 static int add_hintdevice(struct ast_hint *hint, const char *devicelist)
551 {
552  struct ast_str *str;
553  char *parse;
554  char *cur;
555  struct ast_hintdevice *device;
556  int devicelength;
557 
558  if (!hint || !devicelist) {
559  /* Trying to add garbage? Don't bother. */
560  return 0;
561  }
562  if (!(str = ast_str_thread_get(&hintdevice_data, 16))) {
563  return -1;
564  }
565  ast_str_set(&str, 0, "%s", devicelist);
567 
568  /* Spit on '&' and ',' to handle presence hints as well */
569  while ((cur = strsep(&parse, "&,"))) {
570  char *device_name;
571 
572  devicelength = strlen(cur);
573  if (!devicelength) {
574  continue;
575  }
576 
577  device_name = ast_strdup(cur);
578  if (!device_name) {
579  return -1;
580  }
581 
582  device = ao2_t_alloc(sizeof(*device) + devicelength, hintdevice_destroy,
583  "allocating a hintdevice structure");
584  if (!device) {
585  ast_free(device_name);
586  return -1;
587  }
588  strcpy(device->hintdevice, cur);
589  ao2_ref(hint, +1);
590  device->hint = hint;
591  if (AST_VECTOR_APPEND(&hint->devices, device_name)) {
592  ast_free(device_name);
593  ao2_ref(device, -1);
594  return -1;
595  }
596  ao2_t_link(hintdevices, device, "Linking device into hintdevice container.");
597  ao2_t_ref(device, -1, "hintdevice is linked so we can unref");
598  }
599 
600  return 0;
601 }
602 
603 
604 static const struct cfextension_states {
606  const char * const text;
607 } extension_states[] = {
608  { AST_EXTENSION_NOT_INUSE, "Idle" },
609  { AST_EXTENSION_INUSE, "InUse" },
610  { AST_EXTENSION_BUSY, "Busy" },
611  { AST_EXTENSION_UNAVAILABLE, "Unavailable" },
612  { AST_EXTENSION_RINGING, "Ringing" },
613  { AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" },
614  { AST_EXTENSION_ONHOLD, "Hold" },
615  { AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD, "InUse&Hold" }
616 };
617 
620  AST_STRING_FIELD(context); /*!< Context associated with this exception */
621  AST_STRING_FIELD(exten); /*!< Exten associated with this exception */
622  AST_STRING_FIELD(reason); /*!< The exception reason */
623  );
624 
625  int priority; /*!< Priority associated with this exception */
626 };
627 
628 static int matchcid(const char *cidpattern, const char *callerid);
629 #ifdef NEED_DEBUG
630 static void log_match_char_tree(struct match_char *node, char *prefix); /* for use anywhere */
631 #endif
632 static void new_find_extension(const char *str, struct scoreboard *score,
633  struct match_char *tree, int length, int spec, const char *callerid,
634  const char *label, enum ext_match_t action);
635 static struct match_char *already_in_tree(struct match_char *current, char *pat, int is_pattern);
636 static struct match_char *add_exten_to_pattern_tree(struct ast_context *con,
637  struct ast_exten *e1, int findonly);
638 static void create_match_char_tree(struct ast_context *con);
639 static struct ast_exten *get_canmatch_exten(struct match_char *node);
640 static void destroy_pattern_tree(struct match_char *pattern_tree);
641 static int hashtab_compare_extens(const void *ha_a, const void *ah_b);
642 static int hashtab_compare_exten_numbers(const void *ah_a, const void *ah_b);
643 static int hashtab_compare_exten_labels(const void *ah_a, const void *ah_b);
644 static unsigned int hashtab_hash_extens(const void *obj);
645 static unsigned int hashtab_hash_priority(const void *obj);
646 static unsigned int hashtab_hash_labels(const void *obj);
647 static void __ast_internal_context_destroy( struct ast_context *con);
648 static int ast_add_extension_nolock(const char *context, int replace, const char *extension,
649  int priority, const char *label, const char *callerid,
650  const char *application, void *data, void (*datad)(void *), const char *registrar);
652  int replace, const char *extension, int priority, const char *label, const char *callerid,
653  const char *application, void *data, void (*datad)(void *),
654  const char *registrar, const char *registrar_file, int registrar_line,
655  int lock_context);
656 static struct ast_context *find_context_locked(const char *context);
657 static struct ast_context *find_context(const char *context);
659 static unsigned int ext_strncpy(char *dst, const char *src, size_t dst_size, int nofluff);
660 
661 /*!
662  * \internal
663  * \brief Character array comparison function for qsort.
664  *
665  * \param a Left side object.
666  * \param b Right side object.
667  *
668  * \retval <0 if a < b
669  * \retval =0 if a = b
670  * \retval >0 if a > b
671  */
672 static int compare_char(const void *a, const void *b)
673 {
674  const unsigned char *ac = a;
675  const unsigned char *bc = b;
676 
677  return *ac - *bc;
678 }
679 
680 /* labels, contexts are case sensitive priority numbers are ints */
681 int ast_hashtab_compare_contexts(const void *ah_a, const void *ah_b)
682 {
683  const struct ast_context *ac = ah_a;
684  const struct ast_context *bc = ah_b;
685  if (!ac || !bc) /* safety valve, but it might prevent a crash you'd rather have happen */
686  return 1;
687  /* assume context names are registered in a string table! */
688  return strcmp(ac->name, bc->name);
689 }
690 
691 static int hashtab_compare_extens(const void *ah_a, const void *ah_b)
692 {
693  const struct ast_exten *ac = ah_a;
694  const struct ast_exten *bc = ah_b;
695  int x = strcmp(ac->exten, bc->exten);
696  if (x) { /* if exten names are diff, then return */
697  return x;
698  }
699 
700  /* but if they are the same, do the cidmatch values match? */
701  /* not sure which side may be using ast_ext_matchcid_types, so check both */
702  if (ac->matchcid == AST_EXT_MATCHCID_ANY || bc->matchcid == AST_EXT_MATCHCID_ANY) {
703  return 0;
704  }
705  if (ac->matchcid == AST_EXT_MATCHCID_OFF && bc->matchcid == AST_EXT_MATCHCID_OFF) {
706  return 0;
707  }
708  if (ac->matchcid != bc->matchcid) {
709  return 1;
710  }
711  /* all other cases already disposed of, match now required on callerid string (cidmatch) */
712  /* although ast_add_extension2_lockopt() enforces non-zero ptr, caller may not have */
713  if (ast_strlen_zero(ac->cidmatch) && ast_strlen_zero(bc->cidmatch)) {
714  return 0;
715  }
716  return strcmp(ac->cidmatch, bc->cidmatch);
717 }
718 
719 static int hashtab_compare_exten_numbers(const void *ah_a, const void *ah_b)
720 {
721  const struct ast_exten *ac = ah_a;
722  const struct ast_exten *bc = ah_b;
723  return ac->priority != bc->priority;
724 }
725 
726 static int hashtab_compare_exten_labels(const void *ah_a, const void *ah_b)
727 {
728  const struct ast_exten *ac = ah_a;
729  const struct ast_exten *bc = ah_b;
730  return strcmp(S_OR(ac->label, ""), S_OR(bc->label, ""));
731 }
732 
733 unsigned int ast_hashtab_hash_contexts(const void *obj)
734 {
735  const struct ast_context *ac = obj;
736  return ast_hashtab_hash_string(ac->name);
737 }
738 
739 static unsigned int hashtab_hash_extens(const void *obj)
740 {
741  const struct ast_exten *ac = obj;
742  unsigned int x = ast_hashtab_hash_string(ac->exten);
743  unsigned int y = 0;
744  if (ac->matchcid == AST_EXT_MATCHCID_ON)
746  return x+y;
747 }
748 
749 static unsigned int hashtab_hash_priority(const void *obj)
750 {
751  const struct ast_exten *ac = obj;
752  return ast_hashtab_hash_int(ac->priority);
753 }
754 
755 static unsigned int hashtab_hash_labels(const void *obj)
756 {
757  const struct ast_exten *ac = obj;
758  return ast_hashtab_hash_string(S_OR(ac->label, ""));
759 }
760 
761 static int autofallthrough = 1;
762 static int extenpatternmatchnew = 0;
763 static char *overrideswitch = NULL;
764 
765 /*! \brief Subscription for device state change events */
767 /*! \brief Subscription for presence state change events */
769 
771 static int countcalls;
772 static int totalcalls;
773 
774 static struct ast_context *contexts;
775 static struct ast_hashtab *contexts_table = NULL;
776 
777 /*!
778  * \brief Lock for the ast_context list
779  * \note
780  * This lock MUST be recursive, or a deadlock on reload may result. See
781  * https://issues.asterisk.org/view.php?id=17643
782  */
784 
785 /*!
786  * \brief Lock to hold off restructuring of hints by ast_merge_contexts_and_delete.
787  */
789 
790 static int stateid = 1;
791 /*!
792  * \note When holding this container's lock, do _not_ do
793  * anything that will cause conlock to be taken, unless you
794  * _already_ hold it. The ast_merge_contexts_and_delete function
795  * will take the locks in conlock/hints order, so any other
796  * paths that require both locks must also take them in that
797  * order.
798  */
799 static struct ao2_container *hints;
800 
801 static struct ao2_container *statecbs;
802 
803 #ifdef CONTEXT_DEBUG
804 
805 /* these routines are provided for doing run-time checks
806  on the extension structures, in case you are having
807  problems, this routine might help you localize where
808  the problem is occurring. It's kinda like a debug memory
809  allocator's arena checker... It'll eat up your cpu cycles!
810  but you'll see, if you call it in the right places,
811  right where your problems began...
812 */
813 
814 /* you can break on the check_contexts_trouble()
815 routine in your debugger to stop at the moment
816 there's a problem */
817 void check_contexts_trouble(void);
818 
819 void check_contexts_trouble(void)
820 {
821  int x = 1;
822  x = 2;
823 }
824 
825 int check_contexts(char *, int);
826 
827 int check_contexts(char *file, int line )
828 {
829  struct ast_hashtab_iter *t1;
830  struct ast_context *c1, *c2;
831  int found = 0;
832  struct ast_exten *e1, *e2, *e3;
833  struct ast_exten ex;
834 
835  /* try to find inconsistencies */
836  /* is every context in the context table in the context list and vice-versa ? */
837 
838  if (!contexts_table) {
839  ast_log(LOG_NOTICE,"Called from: %s:%d: No contexts_table!\n", file, line);
840  usleep(500000);
841  }
842 
844  while( (c1 = ast_hashtab_next(t1))) {
845  for(c2=contexts;c2;c2=c2->next) {
846  if (!strcmp(c1->name, c2->name)) {
847  found = 1;
848  break;
849  }
850  }
851  if (!found) {
852  ast_log(LOG_NOTICE,"Called from: %s:%d: Could not find the %s context in the linked list\n", file, line, c1->name);
853  check_contexts_trouble();
854  }
855  }
857  for(c2=contexts;c2;c2=c2->next) {
858  c1 = find_context_locked(c2->name);
859  if (!c1) {
860  ast_log(LOG_NOTICE,"Called from: %s:%d: Could not find the %s context in the hashtab\n", file, line, c2->name);
861  check_contexts_trouble();
862  } else
864  }
865 
866  /* loop thru all contexts, and verify the exten structure compares to the
867  hashtab structure */
868  for(c2=contexts;c2;c2=c2->next) {
869  c1 = find_context_locked(c2->name);
870  if (c1) {
872 
873  /* is every entry in the root list also in the root_table? */
874  for(e1 = c1->root; e1; e1=e1->next)
875  {
876  char dummy_name[1024];
877  ex.exten = dummy_name;
878  ex.matchcid = e1->matchcid;
879  ex.cidmatch = e1->cidmatch;
880  ast_copy_string(dummy_name, e1->exten, sizeof(dummy_name));
881  e2 = ast_hashtab_lookup(c1->root_table, &ex);
882  if (!e2) {
883  if (e1->matchcid == AST_EXT_MATCHCID_ON) {
884  ast_log(LOG_NOTICE, "Called from: %s:%d: The %s context records "
885  "the exten %s (CID match: %s) but it is not in its root_table\n",
886  file, line, c2->name, dummy_name, e1->cidmatch_display);
887  } else {
888  ast_log(LOG_NOTICE, "Called from: %s:%d: The %s context records "
889  "the exten %s but it is not in its root_table\n",
890  file, line, c2->name, dummy_name);
891  }
892  check_contexts_trouble();
893  }
894  }
895 
896  /* is every entry in the root_table also in the root list? */
897  if (!c2->root_table) {
898  if (c2->root) {
899  ast_log(LOG_NOTICE,"Called from: %s:%d: No c2->root_table for context %s!\n", file, line, c2->name);
900  usleep(500000);
901  }
902  } else {
904  while( (e2 = ast_hashtab_next(t1)) ) {
905  for(e1=c2->root;e1;e1=e1->next) {
906  if (!strcmp(e1->exten, e2->exten)) {
907  found = 1;
908  break;
909  }
910  }
911  if (!found) {
912  ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context records the exten %s but it is not in its root_table\n", file, line, c2->name, e2->exten);
913  check_contexts_trouble();
914  }
915 
916  }
918  }
919  }
920  /* is every priority reflected in the peer_table at the head of the list? */
921 
922  /* is every entry in the root list also in the root_table? */
923  /* are the per-extension peer_tables in the right place? */
924 
925  for(e1 = c2->root; e1; e1 = e1->next) {
926 
927  for(e2=e1;e2;e2=e2->peer) {
928  ex.priority = e2->priority;
929  if (e2 != e1 && e2->peer_table) {
930  ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority has a peer_table entry, and shouldn't!\n", file, line, c2->name, e1->exten, e2->priority );
931  check_contexts_trouble();
932  }
933 
934  if (e2 != e1 && e2->peer_label_table) {
935  ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority has a peer_label_table entry, and shouldn't!\n", file, line, c2->name, e1->exten, e2->priority );
936  check_contexts_trouble();
937  }
938 
939  if (e2 == e1 && !e2->peer_table){
940  ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority doesn't have a peer_table!\n", file, line, c2->name, e1->exten, e2->priority );
941  check_contexts_trouble();
942  }
943 
944  if (e2 == e1 && !e2->peer_label_table) {
945  ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority doesn't have a peer_label_table!\n", file, line, c2->name, e1->exten, e2->priority );
946  check_contexts_trouble();
947  }
948 
949 
950  e3 = ast_hashtab_lookup(e1->peer_table, &ex);
951  if (!e3) {
952  ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority is not reflected in the peer_table\n", file, line, c2->name, e1->exten, e2->priority );
953  check_contexts_trouble();
954  }
955  }
956 
957  if (!e1->peer_table){
958  ast_log(LOG_NOTICE,"Called from: %s:%d: No e1->peer_table!\n", file, line);
959  usleep(500000);
960  }
961 
962  /* is every entry in the peer_table also in the peer list? */
964  while( (e2 = ast_hashtab_next(t1)) ) {
965  for(e3=e1;e3;e3=e3->peer) {
966  if (e3->priority == e2->priority) {
967  found = 1;
968  break;
969  }
970  }
971  if (!found) {
972  ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority is not reflected in the peer list\n", file, line, c2->name, e1->exten, e2->priority );
973  check_contexts_trouble();
974  }
975  }
977  }
978  }
979  return 0;
980 }
981 #endif
982 
983 static void pbx_destroy(struct ast_pbx *p)
984 {
985  ast_free(p);
986 }
987 
988 /* form a tree that fully describes all the patterns in a context's extensions
989  * in this tree, a "node" represents an individual character or character set
990  * meant to match the corresponding character in a dial string. The tree
991  * consists of a series of match_char structs linked in a chain
992  * via the alt_char pointers. More than one pattern can share the same parts of the
993  * tree as other extensions with the same pattern to that point.
994  * My first attempt to duplicate the finding of the 'best' pattern was flawed in that
995  * I misunderstood the general algorithm. I thought that the 'best' pattern
996  * was the one with lowest total score. This was not true. Thus, if you have
997  * patterns "1XXXXX" and "X11111", you would be tempted to say that "X11111" is
998  * the "best" match because it has fewer X's, and is therefore more specific,
999  * but this is not how the old algorithm works. It sorts matching patterns
1000  * in a similar collating sequence as sorting alphabetic strings, from left to
1001  * right. Thus, "1XXXXX" comes before "X11111", and would be the "better" match,
1002  * because "1" is more specific than "X".
1003  * So, to accomodate this philosophy, I sort the tree branches along the alt_char
1004  * line so they are lowest to highest in specificity numbers. This way, as soon
1005  * as we encounter our first complete match, we automatically have the "best"
1006  * match and can stop the traversal immediately. Same for CANMATCH/MATCHMORE.
1007  * If anyone would like to resurrect the "wrong" pattern trie searching algorithm,
1008  * they are welcome to revert pbx to before 1 Apr 2008.
1009  * As an example, consider these 4 extensions:
1010  * (a) NXXNXXXXXX
1011  * (b) 307754XXXX
1012  * (c) fax
1013  * (d) NXXXXXXXXX
1014  *
1015  * In the above, between (a) and (d), (a) is a more specific pattern than (d), and would win over
1016  * most numbers. For all numbers beginning with 307754, (b) should always win.
1017  *
1018  * These pattern should form a (sorted) tree that looks like this:
1019  * { "3" } --next--> { "0" } --next--> { "7" } --next--> { "7" } --next--> { "5" } ... blah ... --> { "X" exten_match: (b) }
1020  * |
1021  * |alt
1022  * |
1023  * { "f" } --next--> { "a" } --next--> { "x" exten_match: (c) }
1024  * { "N" } --next--> { "X" } --next--> { "X" } --next--> { "N" } --next--> { "X" } ... blah ... --> { "X" exten_match: (a) }
1025  * | |
1026  * | |alt
1027  * |alt |
1028  * | { "X" } --next--> { "X" } ... blah ... --> { "X" exten_match: (d) }
1029  * |
1030  * NULL
1031  *
1032  * In the above, I could easily turn "N" into "23456789", but I think that a quick "if( *z >= '2' && *z <= '9' )" might take
1033  * fewer CPU cycles than a call to strchr("23456789",*z), where *z is the char to match...
1034  *
1035  * traversal is pretty simple: one routine merely traverses the alt list, and for each matching char in the pattern, it calls itself
1036  * on the corresponding next pointer, incrementing also the pointer of the string to be matched, and passing the total specificity and length.
1037  * We pass a pointer to a scoreboard down through, also.
1038  * The scoreboard isn't as necessary to the revised algorithm, but I kept it as a handy way to return the matched extension.
1039  * The first complete match ends the traversal, which should make this version of the pattern matcher faster
1040  * the previous. The same goes for "CANMATCH" or "MATCHMORE"; the first such match ends the traversal. In both
1041  * these cases, the reason we can stop immediately, is because the first pattern match found will be the "best"
1042  * according to the sort criteria.
1043  * Hope the limit on stack depth won't be a problem... this routine should
1044  * be pretty lean as far a stack usage goes. Any non-match terminates the recursion down a branch.
1045  *
1046  * In the above example, with the number "3077549999" as the pattern, the traverser could match extensions a, b and d. All are
1047  * of length 10; they have total specificities of 24580, 10246, and 25090, respectively, not that this matters
1048  * at all. (b) wins purely because the first character "3" is much more specific (lower specificity) than "N". I have
1049  * left the specificity totals in the code as an artifact; at some point, I will strip it out.
1050  *
1051  * Just how much time this algorithm might save over a plain linear traversal over all possible patterns is unknown,
1052  * because it's a function of how many extensions are stored in a context. With thousands of extensions, the speedup
1053  * can be very noticeable. The new matching algorithm can run several hundreds of times faster, if not a thousand or
1054  * more times faster in extreme cases.
1055  *
1056  * MatchCID patterns are also supported, and stored in the tree just as the extension pattern is. Thus, you
1057  * can have patterns in your CID field as well.
1058  *
1059  * */
1060 
1061 
1062 static void update_scoreboard(struct scoreboard *board, int length, int spec, struct ast_exten *exten, char last, const char *callerid, int deleted, struct match_char *node)
1063 {
1064  /* if this extension is marked as deleted, then skip this -- if it never shows
1065  on the scoreboard, it will never be found, nor will halt the traversal. */
1066  if (deleted)
1067  return;
1068  board->total_specificity = spec;
1069  board->total_length = length;
1070  board->exten = exten;
1071  board->last_char = last;
1072  board->node = node;
1073 #ifdef NEED_DEBUG_HERE
1074  ast_log(LOG_NOTICE,"Scoreboarding (LONGER) %s, len=%d, score=%d\n", exten->exten, length, spec);
1075 #endif
1076 }
1077 
1078 #ifdef NEED_DEBUG
1079 static void log_match_char_tree(struct match_char *node, char *prefix)
1080 {
1081  char extenstr[40];
1082  struct ast_str *my_prefix = ast_str_alloca(1024);
1083 
1084  extenstr[0] = '\0';
1085 
1086  if (node && node->exten)
1087  snprintf(extenstr, sizeof(extenstr), "(%p)", node->exten);
1088 
1089  if (strlen(node->x) > 1) {
1090  ast_debug(1, "%s[%s]:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y':'N',
1091  node->deleted? 'D':'-', node->specificity, node->exten? "EXTEN:":"",
1092  node->exten ? node->exten->exten : "", extenstr);
1093  } else {
1094  ast_debug(1, "%s%s:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y':'N',
1095  node->deleted? 'D':'-', node->specificity, node->exten? "EXTEN:":"",
1096  node->exten ? node->exten->exten : "", extenstr);
1097  }
1098 
1099  ast_str_set(&my_prefix, 0, "%s+ ", prefix);
1100 
1101  if (node->next_char)
1102  log_match_char_tree(node->next_char, ast_str_buffer(my_prefix));
1103 
1104  if (node->alt_char)
1105  log_match_char_tree(node->alt_char, prefix);
1106 }
1107 #endif
1108 
1109 static void cli_match_char_tree(struct match_char *node, char *prefix, int fd)
1110 {
1111  char extenstr[40];
1112  struct ast_str *my_prefix = ast_str_alloca(1024);
1113 
1114  extenstr[0] = '\0';
1115 
1116  if (node->exten) {
1117  snprintf(extenstr, sizeof(extenstr), "(%p)", node->exten);
1118  }
1119 
1120  if (strlen(node->x) > 1) {
1121  ast_cli(fd, "%s[%s]:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y' : 'N',
1122  node->deleted ? 'D' : '-', node->specificity, node->exten? "EXTEN:" : "",
1123  node->exten ? node->exten->name : "", extenstr);
1124  } else {
1125  ast_cli(fd, "%s%s:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y' : 'N',
1126  node->deleted ? 'D' : '-', node->specificity, node->exten? "EXTEN:" : "",
1127  node->exten ? node->exten->name : "", extenstr);
1128  }
1129 
1130  ast_str_set(&my_prefix, 0, "%s+ ", prefix);
1131 
1132  if (node->next_char)
1133  cli_match_char_tree(node->next_char, ast_str_buffer(my_prefix), fd);
1134 
1135  if (node->alt_char)
1136  cli_match_char_tree(node->alt_char, prefix, fd);
1137 }
1138 
1140 {
1141  /* find the exten at the end of the rope */
1142  struct match_char *node2 = node;
1143 
1144  for (node2 = node; node2; node2 = node2->next_char) {
1145  if (node2->exten) {
1146 #ifdef NEED_DEBUG_HERE
1147  ast_log(LOG_NOTICE,"CanMatch_exten returns exten %s(%p)\n", node2->exten->exten, node2->exten);
1148 #endif
1149  return node2->exten;
1150  }
1151  }
1152 #ifdef NEED_DEBUG_HERE
1153  ast_log(LOG_NOTICE,"CanMatch_exten returns NULL, match_char=%s\n", node->x);
1154 #endif
1155  return 0;
1156 }
1157 
1159 {
1160  struct match_char *m3;
1161  struct match_char *m4;
1162  struct ast_exten *e3;
1163 
1164  if (node && node->x[0] == '.' && !node->x[1]) { /* dot and ! will ALWAYS be next match in a matchmore */
1165  return node->exten;
1166  }
1167 
1168  if (node && node->x[0] == '!' && !node->x[1]) {
1169  return node->exten;
1170  }
1171 
1172  if (!node || !node->next_char) {
1173  return NULL;
1174  }
1175 
1176  m3 = node->next_char;
1177 
1178  if (m3->exten) {
1179  return m3->exten;
1180  }
1181  for (m4 = m3->alt_char; m4; m4 = m4->alt_char) {
1182  if (m4->exten) {
1183  return m4->exten;
1184  }
1185  }
1186  for (m4 = m3; m4; m4 = m4->alt_char) {
1187  e3 = trie_find_next_match(m3);
1188  if (e3) {
1189  return e3;
1190  }
1191  }
1192 
1193  return NULL;
1194 }
1195 
1196 #ifdef DEBUG_THIS
1197 static char *action2str(enum ext_match_t action)
1198 {
1199  switch (action) {
1200  case E_MATCH:
1201  return "MATCH";
1202  case E_CANMATCH:
1203  return "CANMATCH";
1204  case E_MATCHMORE:
1205  return "MATCHMORE";
1206  case E_FINDLABEL:
1207  return "FINDLABEL";
1208  case E_SPAWN:
1209  return "SPAWN";
1210  default:
1211  return "?ACTION?";
1212  }
1213 }
1214 
1215 #endif
1216 
1217 static const char *candidate_exten_advance(const char *str)
1218 {
1219  str++;
1220  while (*str == '-') {
1221  str++;
1222  }
1223  return str;
1224 }
1225 
1226 #define MORE(s) (*candidate_exten_advance(s))
1227 #define ADVANCE(s) candidate_exten_advance(s)
1228 
1229 static void new_find_extension(const char *str, struct scoreboard *score, struct match_char *tree, int length, int spec, const char *callerid, const char *label, enum ext_match_t action)
1230 {
1231  struct match_char *p; /* note minimal stack storage requirements */
1232  struct ast_exten pattern = { .label = label };
1233 #ifdef DEBUG_THIS
1234  if (tree)
1235  ast_log(LOG_NOTICE,"new_find_extension called with %s on (sub)tree %s action=%s\n", str, tree->x, action2str(action));
1236  else
1237  ast_log(LOG_NOTICE,"new_find_extension called with %s on (sub)tree NULL action=%s\n", str, action2str(action));
1238 #endif
1239  for (p = tree; p; p = p->alt_char) {
1240  if (p->is_pattern) {
1241  if (p->x[0] == 'N') {
1242  if (p->x[1] == 0 && *str >= '2' && *str <= '9' ) {
1243 #define NEW_MATCHER_CHK_MATCH \
1244  if (p->exten && !MORE(str)) { /* if a shorter pattern matches along the way, might as well report it */ \
1245  if (action == E_MATCH || action == E_SPAWN || action == E_FINDLABEL) { /* if in CANMATCH/MATCHMORE, don't let matches get in the way */ \
1246  update_scoreboard(score, length + 1, spec + p->specificity, p->exten, 0, callerid, p->deleted, p); \
1247  if (!p->deleted) { \
1248  if (action == E_FINDLABEL) { \
1249  if (ast_hashtab_lookup(score->exten->peer_label_table, &pattern)) { \
1250  ast_debug(4, "Found label in preferred extension\n"); \
1251  return; \
1252  } \
1253  } else { \
1254  ast_debug(4, "returning an exact match-- first found-- %s\n", p->exten->name); \
1255  return; /* the first match, by definition, will be the best, because of the sorted tree */ \
1256  } \
1257  } \
1258  } \
1259  }
1260 
1261 #define NEW_MATCHER_RECURSE \
1262  if (p->next_char && (MORE(str) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0) \
1263  || p->next_char->x[0] == '!')) { \
1264  if (MORE(str) || p->next_char->x[0] == '!') { \
1265  new_find_extension(ADVANCE(str), score, p->next_char, length + 1, spec + p->specificity, callerid, label, action); \
1266  if (score->exten) { \
1267  ast_debug(4 ,"returning an exact match-- %s\n", score->exten->name); \
1268  return; /* the first match is all we need */ \
1269  } \
1270  } else { \
1271  new_find_extension("/", score, p->next_char, length + 1, spec + p->specificity, callerid, label, action); \
1272  if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) { \
1273  ast_debug(4,"returning a (can/more) match--- %s\n", score->exten ? score->exten->name : \
1274  "NULL"); \
1275  return; /* the first match is all we need */ \
1276  } \
1277  } \
1278  } else if ((p->next_char || action == E_CANMATCH) && !MORE(str)) { \
1279  score->canmatch = 1; \
1280  score->canmatch_exten = get_canmatch_exten(p); \
1281  if (action == E_CANMATCH || action == E_MATCHMORE) { \
1282  ast_debug(4, "returning a canmatch/matchmore--- str=%s\n", str); \
1283  return; \
1284  } \
1285  }
1286 
1289  }
1290  } else if (p->x[0] == 'Z') {
1291  if (p->x[1] == 0 && *str >= '1' && *str <= '9' ) {
1294  }
1295  } else if (p->x[0] == 'X') {
1296  if (p->x[1] == 0 && *str >= '0' && *str <= '9' ) {
1299  }
1300  } else if (p->x[0] == '.' && p->x[1] == 0) {
1301  /* how many chars will the . match against? */
1302  int i = 0;
1303  const char *str2 = str;
1304  while (*str2 && *str2 != '/') {
1305  str2++;
1306  i++;
1307  }
1308  if (p->exten && *str2 != '/') {
1309  update_scoreboard(score, length + i, spec + (i * p->specificity), p->exten, '.', callerid, p->deleted, p);
1310  if (score->exten) {
1311  ast_debug(4, "return because scoreboard has a match with '/'--- %s\n",
1312  score->exten->name);
1313  return; /* the first match is all we need */
1314  }
1315  }
1316  if (p->next_char && p->next_char->x[0] == '/' && p->next_char->x[1] == 0) {
1317  new_find_extension("/", score, p->next_char, length + i, spec+(p->specificity*i), callerid, label, action);
1318  if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) {
1319  ast_debug(4, "return because scoreboard has exact match OR "
1320  "CANMATCH/MATCHMORE & canmatch set--- %s\n",
1321  score->exten ? score->exten->name : "NULL");
1322  return; /* the first match is all we need */
1323  }
1324  }
1325  } else if (p->x[0] == '!' && p->x[1] == 0) {
1326  /* how many chars will the . match against? */
1327  int i = 1;
1328  const char *str2 = str;
1329  while (*str2 && *str2 != '/') {
1330  str2++;
1331  i++;
1332  }
1333  if (p->exten && *str2 != '/') {
1334  update_scoreboard(score, length + 1, spec + (p->specificity * i), p->exten, '!', callerid, p->deleted, p);
1335  if (score->exten) {
1336  ast_debug(4, "return because scoreboard has a '!' match--- %s\n",
1337  score->exten->name);
1338  return; /* the first match is all we need */
1339  }
1340  }
1341  if (p->next_char && p->next_char->x[0] == '/' && p->next_char->x[1] == 0) {
1342  new_find_extension("/", score, p->next_char, length + i, spec + (p->specificity * i), callerid, label, action);
1343  if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) {
1344  ast_debug(4, "return because scoreboard has exact match OR "
1345  "CANMATCH/MATCHMORE & canmatch set with '/' and '!'--- %s\n",
1346  score->exten ? score->exten->name : "NULL");
1347  return; /* the first match is all we need */
1348  }
1349  }
1350  } else if (p->x[0] == '/' && p->x[1] == 0) {
1351  /* the pattern in the tree includes the cid match! */
1352  if (p->next_char && callerid && *callerid) {
1353  new_find_extension(callerid, score, p->next_char, length + 1, spec, callerid, label, action);
1354  if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) {
1355  ast_debug(4, "return because scoreboard has exact match OR "
1356  "CANMATCH/MATCHMORE & canmatch set with '/'--- %s\n",
1357  score->exten ? score->exten->name : "NULL");
1358  return; /* the first match is all we need */
1359  }
1360  }
1361  } else if (strchr(p->x, *str)) {
1362  ast_debug(4, "Nothing strange about this match\n");
1365  }
1366  } else if (strchr(p->x, *str)) {
1367  ast_debug(4, "Nothing strange about this match\n");
1370  }
1371  }
1372  ast_debug(4, "return at end of func\n");
1373 }
1374 
1375 #undef MORE
1376 #undef ADVANCE
1377 
1378 /* the algorithm for forming the extension pattern tree is also a bit simple; you
1379  * traverse all the extensions in a context, and for each char of the extension,
1380  * you see if it exists in the tree; if it doesn't, you add it at the appropriate
1381  * spot. What more can I say? At the end of each exten, you cap it off by adding the
1382  * address of the extension involved. Duplicate patterns will be complained about.
1383  *
1384  * Ideally, this would be done for each context after it is created and fully
1385  * filled. It could be done as a finishing step after extensions.conf or .ael is
1386  * loaded, or it could be done when the first search is encountered. It should only
1387  * have to be done once, until the next unload or reload.
1388  *
1389  * I guess forming this pattern tree would be analogous to compiling a regex. Except
1390  * that a regex only handles 1 pattern, really. This trie holds any number
1391  * of patterns. Well, really, it **could** be considered a single pattern,
1392  * where the "|" (or) operator is allowed, I guess, in a way, sort of...
1393  */
1394 
1395 static struct match_char *already_in_tree(struct match_char *current, char *pat, int is_pattern)
1396 {
1397  struct match_char *t;
1398 
1399  if (!current) {
1400  return 0;
1401  }
1402 
1403  for (t = current; t; t = t->alt_char) {
1404  if (is_pattern == t->is_pattern && !strcmp(pat, t->x)) {/* uh, we may want to sort exploded [] contents to make matching easy */
1405  return t;
1406  }
1407  }
1408 
1409  return 0;
1410 }
1411 
1412 /* The first arg is the location of the tree ptr, or the
1413  address of the next_char ptr in the node, so we can mess
1414  with it, if we need to insert at the beginning of the list */
1415 
1416 static void insert_in_next_chars_alt_char_list(struct match_char **parent_ptr, struct match_char *node)
1417 {
1418  struct match_char *curr, *lcurr;
1419 
1420  /* insert node into the tree at "current", so the alt_char list from current is
1421  sorted in increasing value as you go to the leaves */
1422  if (!(*parent_ptr)) {
1423  *parent_ptr = node;
1424  return;
1425  }
1426 
1427  if ((*parent_ptr)->specificity > node->specificity) {
1428  /* insert at head */
1429  node->alt_char = (*parent_ptr);
1430  *parent_ptr = node;
1431  return;
1432  }
1433 
1434  lcurr = *parent_ptr;
1435  for (curr = (*parent_ptr)->alt_char; curr; curr = curr->alt_char) {
1436  if (curr->specificity > node->specificity) {
1437  node->alt_char = curr;
1438  lcurr->alt_char = node;
1439  break;
1440  }
1441  lcurr = curr;
1442  }
1443 
1444  if (!curr) {
1445  lcurr->alt_char = node;
1446  }
1447 
1448 }
1449 
1451  /*! Pattern node specificity */
1452  int specif;
1453  /*! Pattern node match characters. */
1454  char buf[256];
1455 };
1456 
1457 static struct match_char *add_pattern_node(struct ast_context *con, struct match_char *current, const struct pattern_node *pattern, int is_pattern, int already, struct match_char **nextcharptr)
1458 {
1459  struct match_char *m;
1460 
1461  if (!(m = ast_calloc(1, sizeof(*m) + strlen(pattern->buf)))) {
1462  return NULL;
1463  }
1464 
1465  /* strcpy is safe here since we know its size and have allocated
1466  * just enough space for when we allocated m
1467  */
1468  strcpy(m->x, pattern->buf);
1469 
1470  /* the specificity scores are the same as used in the old
1471  pattern matcher. */
1472  m->is_pattern = is_pattern;
1473  if (pattern->specif == 1 && is_pattern && pattern->buf[0] == 'N') {
1474  m->specificity = 0x0832;
1475  } else if (pattern->specif == 1 && is_pattern && pattern->buf[0] == 'Z') {
1476  m->specificity = 0x0931;
1477  } else if (pattern->specif == 1 && is_pattern && pattern->buf[0] == 'X') {
1478  m->specificity = 0x0a30;
1479  } else if (pattern->specif == 1 && is_pattern && pattern->buf[0] == '.') {
1480  m->specificity = 0x18000;
1481  } else if (pattern->specif == 1 && is_pattern && pattern->buf[0] == '!') {
1482  m->specificity = 0x28000;
1483  } else {
1484  m->specificity = pattern->specif;
1485  }
1486 
1487  if (!con->pattern_tree) {
1489  } else {
1490  if (already) { /* switch to the new regime (traversing vs appending)*/
1491  insert_in_next_chars_alt_char_list(nextcharptr, m);
1492  } else {
1494  }
1495  }
1496 
1497  return m;
1498 }
1499 
1500 /*!
1501  * \internal
1502  * \brief Extract the next exten pattern node.
1503  *
1504  * \param node Pattern node to fill.
1505  * \param src Next source character to read.
1506  * \param pattern TRUE if the exten is a pattern.
1507  * \param extenbuf Original exten buffer to use in diagnostic messages.
1508  *
1509  * \retval Ptr to next extenbuf pos to read.
1510  */
1511 static const char *get_pattern_node(struct pattern_node *node, const char *src, int pattern, const char *extenbuf)
1512 {
1513 #define INC_DST_OVERFLOW_CHECK \
1514  do { \
1515  if (dst - node->buf < sizeof(node->buf) - 1) { \
1516  ++dst; \
1517  } else { \
1518  overflow = 1; \
1519  } \
1520  } while (0)
1521 
1522  node->specif = 0;
1523  node->buf[0] = '\0';
1524  while (*src) {
1525  if (*src == '[' && pattern) {
1526  char *dst = node->buf;
1527  const char *src_next;
1528  int length;
1529  int overflow = 0;
1530 
1531  /* get past the '[' */
1532  ++src;
1533  for (;;) {
1534  if (*src == '\\') {
1535  /* Escaped character. */
1536  ++src;
1537  if (*src == '[' || *src == '\\' || *src == '-' || *src == ']') {
1538  *dst = *src++;
1540  }
1541  } else if (*src == '-') {
1542  unsigned char first;
1543  unsigned char last;
1544 
1545  src_next = src;
1546  first = *(src_next - 1);
1547  last = *++src_next;
1548 
1549  if (last == '\\') {
1550  /* Escaped character. */
1551  last = *++src_next;
1552  }
1553 
1554  /* Possible char range. */
1555  if (node->buf[0] && last) {
1556  /* Expand the char range. */
1557  while (++first <= last) {
1558  *dst = first;
1560  }
1561  src = src_next + 1;
1562  } else {
1563  /*
1564  * There was no left or right char for the range.
1565  * It is just a '-'.
1566  */
1567  *dst = *src++;
1569  }
1570  } else if (*src == '\0') {
1572  "A matching ']' was not found for '[' in exten pattern '%s'\n",
1573  extenbuf);
1574  break;
1575  } else if (*src == ']') {
1576  ++src;
1577  break;
1578  } else {
1579  *dst = *src++;
1581  }
1582  }
1583  /* null terminate the exploded range */
1584  *dst = '\0';
1585 
1586  if (overflow) {
1588  "Expanded character set too large to deal with in exten pattern '%s'. Ignoring character set.\n",
1589  extenbuf);
1590  node->buf[0] = '\0';
1591  continue;
1592  }
1593 
1594  /* Sort the characters in character set. */
1595  length = strlen(node->buf);
1596  if (!length) {
1597  ast_log(LOG_WARNING, "Empty character set in exten pattern '%s'. Ignoring.\n",
1598  extenbuf);
1599  node->buf[0] = '\0';
1600  continue;
1601  }
1602  qsort(node->buf, length, 1, compare_char);
1603 
1604  /* Remove duplicate characters from character set. */
1605  dst = node->buf;
1606  src_next = node->buf;
1607  while (*src_next++) {
1608  if (*dst != *src_next) {
1609  *++dst = *src_next;
1610  }
1611  }
1612 
1613  length = strlen(node->buf);
1614  length <<= 8;
1615  node->specif = length | (unsigned char) node->buf[0];
1616  break;
1617  } else if (*src == '-') {
1618  /* Skip dashes in all extensions. */
1619  ++src;
1620  } else {
1621  if (*src == '\\') {
1622  /*
1623  * XXX The escape character here does not remove any special
1624  * meaning to characters except the '[', '\\', and '-'
1625  * characters since they are special only in this function.
1626  */
1627  node->buf[0] = *++src;
1628  if (!node->buf[0]) {
1629  break;
1630  }
1631  } else {
1632  node->buf[0] = *src;
1633  if (pattern) {
1634  /* make sure n,x,z patterns are canonicalized to N,X,Z */
1635  if (node->buf[0] == 'n') {
1636  node->buf[0] = 'N';
1637  } else if (node->buf[0] == 'x') {
1638  node->buf[0] = 'X';
1639  } else if (node->buf[0] == 'z') {
1640  node->buf[0] = 'Z';
1641  }
1642  }
1643  }
1644  node->buf[1] = '\0';
1645  node->specif = 1;
1646  ++src;
1647  break;
1648  }
1649  }
1650  return src;
1651 
1652 #undef INC_DST_OVERFLOW_CHECK
1653 }
1654 
1655 #define MAX_EXTENBUF_SIZE 512
1656 static struct match_char *add_exten_to_pattern_tree(struct ast_context *con, struct ast_exten *e1, int findonly)
1657 {
1658  struct match_char *m1 = NULL;
1659  struct match_char *m2 = NULL;
1660  struct match_char **m0;
1661  const char *pos;
1662  int already;
1663  int pattern = 0;
1664  int idx_cur;
1665  int idx_next;
1666  char extenbuf[MAX_EXTENBUF_SIZE];
1667  volatile size_t required_space = strlen(e1->exten) + 1;
1668  struct pattern_node pat_node[2];
1669 
1670  if (e1->matchcid) {
1671  required_space += (strlen(e1->cidmatch) + 2 /* '/' + NULL */);
1672  if (required_space > MAX_EXTENBUF_SIZE) {
1674  "The pattern %s/%s is too big to deal with: it will be ignored! Disaster!\n",
1675  e1->exten, e1->cidmatch);
1676  return NULL;
1677  }
1678  sprintf(extenbuf, "%s/%s", e1->exten, e1->cidmatch);/* Safe. We just checked. */
1679  } else {
1680  if (required_space > MAX_EXTENBUF_SIZE) {
1682  "The pattern %s/%s is too big to deal with: it will be ignored! Disaster!\n",
1683  e1->exten, e1->cidmatch);
1684  return NULL;
1685  }
1686  ast_copy_string(extenbuf, e1->exten, required_space);
1687  }
1688 
1689 #ifdef NEED_DEBUG
1690  ast_debug(1, "Adding exten %s to tree\n", extenbuf);
1691 #endif
1692  m1 = con->pattern_tree; /* each pattern starts over at the root of the pattern tree */
1693  m0 = &con->pattern_tree;
1694  already = 1;
1695 
1696  pos = extenbuf;
1697  if (*pos == '_') {
1698  pattern = 1;
1699  ++pos;
1700  }
1701  idx_cur = 0;
1702  pos = get_pattern_node(&pat_node[idx_cur], pos, pattern, extenbuf);
1703  for (; pat_node[idx_cur].buf[0]; idx_cur = idx_next) {
1704  idx_next = (idx_cur + 1) % ARRAY_LEN(pat_node);
1705  pos = get_pattern_node(&pat_node[idx_next], pos, pattern, extenbuf);
1706 
1707  /* See about adding node to tree. */
1708  m2 = NULL;
1709  if (already && (m2 = already_in_tree(m1, pat_node[idx_cur].buf, pattern))
1710  && m2->next_char) {
1711  if (!pat_node[idx_next].buf[0]) {
1712  /*
1713  * This is the end of the pattern, but not the end of the tree.
1714  * Mark this node with the exten... a shorter pattern might win
1715  * if the longer one doesn't match.
1716  */
1717  if (findonly) {
1718  return m2;
1719  }
1720  if (m2->exten) {
1721  ast_log(LOG_WARNING, "Found duplicate exten. Had %s found %s\n",
1722  m2->deleted ? "(deleted/invalid)" : m2->exten->name, e1->name);
1723  }
1724  m2->exten = e1;
1725  m2->deleted = 0;
1726  }
1727  m1 = m2->next_char; /* m1 points to the node to compare against */
1728  m0 = &m2->next_char; /* m0 points to the ptr that points to m1 */
1729  } else { /* not already OR not m2 OR nor m2->next_char */
1730  if (m2) {
1731  if (findonly) {
1732  return m2;
1733  }
1734  m1 = m2; /* while m0 stays the same */
1735  } else {
1736  if (findonly) {
1737  return m1;
1738  }
1739  m1 = add_pattern_node(con, m1, &pat_node[idx_cur], pattern, already, m0);
1740  if (!m1) { /* m1 is the node just added */
1741  return NULL;
1742  }
1743  m0 = &m1->next_char;
1744  }
1745  if (!pat_node[idx_next].buf[0]) {
1746  if (m2 && m2->exten) {
1747  ast_log(LOG_WARNING, "Found duplicate exten. Had %s found %s\n",
1748  m2->deleted ? "(deleted/invalid)" : m2->exten->name, e1->name);
1749  }
1750  m1->deleted = 0;
1751  m1->exten = e1;
1752  }
1753 
1754  /* The 'already' variable is a mini-optimization designed to make it so that we
1755  * don't have to call already_in_tree when we know it will return false.
1756  */
1757  already = 0;
1758  }
1759  }
1760  return m1;
1761 }
1762 
1763 static void create_match_char_tree(struct ast_context *con)
1764 {
1765  struct ast_hashtab_iter *t1;
1766  struct ast_exten *e1;
1767 #ifdef NEED_DEBUG
1768  int biggest_bucket, resizes, numobjs, numbucks;
1769 
1770  ast_debug(1, "Creating Extension Trie for context %s(%p)\n", con->name, con);
1771  ast_hashtab_get_stats(con->root_table, &biggest_bucket, &resizes, &numobjs, &numbucks);
1772  ast_debug(1, "This tree has %d objects in %d bucket lists, longest list=%d objects, and has resized %d times\n",
1773  numobjs, numbucks, biggest_bucket, resizes);
1774 #endif
1776  while ((e1 = ast_hashtab_next(t1))) {
1777  if (e1->exten) {
1778  add_exten_to_pattern_tree(con, e1, 0);
1779  } else {
1780  ast_log(LOG_ERROR, "Attempt to create extension with no extension name.\n");
1781  }
1782  }
1784 }
1785 
1786 static void destroy_pattern_tree(struct match_char *pattern_tree) /* pattern tree is a simple binary tree, sort of, so the proper way to destroy it is... recursively! */
1787 {
1788  /* destroy all the alternates */
1789  if (pattern_tree->alt_char) {
1790  destroy_pattern_tree(pattern_tree->alt_char);
1791  pattern_tree->alt_char = 0;
1792  }
1793  /* destroy all the nexts */
1794  if (pattern_tree->next_char) {
1795  destroy_pattern_tree(pattern_tree->next_char);
1796  pattern_tree->next_char = 0;
1797  }
1798  pattern_tree->exten = 0; /* never hurts to make sure there's no pointers laying around */
1799  ast_free(pattern_tree);
1800 }
1801 
1802 /*!
1803  * \internal
1804  * \brief Get the length of the exten string.
1805  *
1806  * \param str Exten to get length.
1807  *
1808  * \retval strlen of exten.
1809  */
1810 static int ext_cmp_exten_strlen(const char *str)
1811 {
1812  int len;
1813 
1814  len = 0;
1815  for (;;) {
1816  /* Ignore '-' chars as eye candy fluff. */
1817  while (*str == '-') {
1818  ++str;
1819  }
1820  if (!*str) {
1821  break;
1822  }
1823  ++str;
1824  ++len;
1825  }
1826  return len;
1827 }
1828 
1829 /*!
1830  * \internal
1831  * \brief Partial comparison of non-pattern extens.
1832  *
1833  * \param left Exten to compare.
1834  * \param right Exten to compare. Also matches if this string ends first.
1835  *
1836  * \retval <0 if left < right
1837  * \retval =0 if left == right
1838  * \retval >0 if left > right
1839  */
1840 static int ext_cmp_exten_partial(const char *left, const char *right)
1841 {
1842  int cmp;
1843 
1844  for (;;) {
1845  /* Ignore '-' chars as eye candy fluff. */
1846  while (*left == '-') {
1847  ++left;
1848  }
1849  while (*right == '-') {
1850  ++right;
1851  }
1852 
1853  if (!*right) {
1854  /*
1855  * Right ended first for partial match or both ended at the same
1856  * time for a match.
1857  */
1858  cmp = 0;
1859  break;
1860  }
1861 
1862  cmp = *left - *right;
1863  if (cmp) {
1864  break;
1865  }
1866  ++left;
1867  ++right;
1868  }
1869  return cmp;
1870 }
1871 
1872 /*!
1873  * \internal
1874  * \brief Comparison of non-pattern extens.
1875  *
1876  * \param left Exten to compare.
1877  * \param right Exten to compare.
1878  *
1879  * \retval <0 if left < right
1880  * \retval =0 if left == right
1881  * \retval >0 if left > right
1882  */
1883 static int ext_cmp_exten(const char *left, const char *right)
1884 {
1885  int cmp;
1886 
1887  for (;;) {
1888  /* Ignore '-' chars as eye candy fluff. */
1889  while (*left == '-') {
1890  ++left;
1891  }
1892  while (*right == '-') {
1893  ++right;
1894  }
1895 
1896  cmp = *left - *right;
1897  if (cmp) {
1898  break;
1899  }
1900  if (!*left) {
1901  /*
1902  * Get here only if both strings ended at the same time. cmp
1903  * would be non-zero if only one string ended.
1904  */
1905  break;
1906  }
1907  ++left;
1908  ++right;
1909  }
1910  return cmp;
1911 }
1912 
1913 /*
1914  * Special characters used in patterns:
1915  * '_' underscore is the leading character of a pattern.
1916  * In other position it is treated as a regular char.
1917  * '-' The '-' is a separator and ignored. Why? So patterns like NXX-XXX-XXXX work.
1918  * . one or more of any character. Only allowed at the end of
1919  * a pattern.
1920  * ! zero or more of anything. Also impacts the result of CANMATCH
1921  * and MATCHMORE. Only allowed at the end of a pattern.
1922  * In the core routine, ! causes a match with a return code of 2.
1923  * In turn, depending on the search mode: (XXX check if it is implemented)
1924  * - E_MATCH returns 1 (does match)
1925  * - E_MATCHMORE returns 0 (no match)
1926  * - E_CANMATCH returns 1 (does match)
1927  *
1928  * / should not appear as it is considered the separator of the CID info.
1929  * XXX at the moment we may stop on this char.
1930  *
1931  * X Z N match ranges 0-9, 1-9, 2-9 respectively.
1932  * [ denotes the start of a set of character. Everything inside
1933  * is considered literally. We can have ranges a-d and individual
1934  * characters. A '[' and '-' can be considered literally if they
1935  * are just before ']'.
1936  * XXX currently there is no way to specify ']' in a range, nor \ is
1937  * considered specially.
1938  *
1939  * When we compare a pattern with a specific extension, all characters in the extension
1940  * itself are considered literally.
1941  * XXX do we want to consider space as a separator as well ?
1942  * XXX do we want to consider the separators in non-patterns as well ?
1943  */
1944 
1945 /*!
1946  * \brief helper functions to sort extension patterns in the desired way,
1947  * so that more specific patterns appear first.
1948  *
1949  * \details
1950  * The function compares individual characters (or sets of), returning
1951  * an int where bits 0-7 are the ASCII code of the first char in the set,
1952  * bits 8-15 are the number of characters in the set, and bits 16-20 are
1953  * for special cases.
1954  * This way more specific patterns (smaller character sets) appear first.
1955  * Wildcards have a special value, so that we can directly compare them to
1956  * sets by subtracting the two values. In particular:
1957  * 0x001xx one character, character set starting with xx
1958  * 0x0yyxx yy characters, character set starting with xx
1959  * 0x18000 '.' (one or more of anything)
1960  * 0x28000 '!' (zero or more of anything)
1961  * 0x30000 NUL (end of string)
1962  * 0x40000 error in set.
1963  * The pointer to the string is advanced according to needs.
1964  * NOTES:
1965  * 1. the empty set is ignored.
1966  * 2. given that a full set has always 0 as the first element,
1967  * we could encode the special cases as 0xffXX where XX
1968  * is 1, 2, 3, 4 as used above.
1969  */
1970 static int ext_cmp_pattern_pos(const char **p, unsigned char *bitwise)
1971 {
1972 #define BITS_PER 8 /* Number of bits per unit (byte). */
1973  unsigned char c;
1974  unsigned char cmin;
1975  int count;
1976  const char *end;
1977 
1978  do {
1979  /* Get character and advance. (Ignore '-' chars as eye candy fluff.) */
1980  do {
1981  c = *(*p)++;
1982  } while (c == '-');
1983 
1984  /* always return unless we have a set of chars */
1985  switch (c) {
1986  default:
1987  /* ordinary character */
1988  bitwise[c / BITS_PER] = 1 << ((BITS_PER - 1) - (c % BITS_PER));
1989  return 0x0100 | c;
1990 
1991  case 'n':
1992  case 'N':
1993  /* 2..9 */
1994  bitwise[6] = 0x3f;
1995  bitwise[7] = 0xc0;
1996  return 0x0800 | '2';
1997 
1998  case 'x':
1999  case 'X':
2000  /* 0..9 */
2001  bitwise[6] = 0xff;
2002  bitwise[7] = 0xc0;
2003  return 0x0A00 | '0';
2004 
2005  case 'z':
2006  case 'Z':
2007  /* 1..9 */
2008  bitwise[6] = 0x7f;
2009  bitwise[7] = 0xc0;
2010  return 0x0900 | '1';
2011 
2012  case '.':
2013  /* wildcard */
2014  return 0x18000;
2015 
2016  case '!':
2017  /* earlymatch */
2018  return 0x28000; /* less specific than '.' */
2019 
2020  case '\0':
2021  /* empty string */
2022  *p = NULL;
2023  return 0x30000;
2024 
2025  case '[':
2026  /* char set */
2027  break;
2028  }
2029  /* locate end of set */
2030  end = strchr(*p, ']');
2031 
2032  if (!end) {
2033  ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
2034  return 0x40000; /* XXX make this entry go last... */
2035  }
2036 
2037  count = 0;
2038  cmin = 0xFF;
2039  for (; *p < end; ++*p) {
2040  unsigned char c1; /* first char in range */
2041  unsigned char c2; /* last char in range */
2042 
2043  c1 = (*p)[0];
2044  if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */
2045  c2 = (*p)[2];
2046  *p += 2; /* skip a total of 3 chars */
2047  } else { /* individual character */
2048  c2 = c1;
2049  }
2050  if (c1 < cmin) {
2051  cmin = c1;
2052  }
2053  for (; c1 <= c2; ++c1) {
2054  unsigned char mask = 1 << ((BITS_PER - 1) - (c1 % BITS_PER));
2055 
2056  /*
2057  * Note: If two character sets score the same, the one with the
2058  * lowest ASCII values will compare as coming first. Must fill
2059  * in most significant bits for lower ASCII values to accomplish
2060  * the desired sort order.
2061  */
2062  if (!(bitwise[c1 / BITS_PER] & mask)) {
2063  /* Add the character to the set. */
2064  bitwise[c1 / BITS_PER] |= mask;
2065  count += 0x100;
2066  }
2067  }
2068  }
2069  ++*p;
2070  } while (!count);/* While the char set was empty. */
2071  return count | cmin;
2072 }
2073 
2074 /*!
2075  * \internal
2076  * \brief Comparison of exten patterns.
2077  *
2078  * \param left Pattern to compare.
2079  * \param right Pattern to compare.
2080  *
2081  * \retval <0 if left < right
2082  * \retval =0 if left == right
2083  * \retval >0 if left > right
2084  */
2085 static int ext_cmp_pattern(const char *left, const char *right)
2086 {
2087  int cmp;
2088  int left_pos;
2089  int right_pos;
2090 
2091  for (;;) {
2092  unsigned char left_bitwise[32] = { 0, };
2093  unsigned char right_bitwise[32] = { 0, };
2094 
2095  left_pos = ext_cmp_pattern_pos(&left, left_bitwise);
2096  right_pos = ext_cmp_pattern_pos(&right, right_bitwise);
2097  cmp = left_pos - right_pos;
2098  if (!cmp) {
2099  /*
2100  * Are the character sets different, even though they score the same?
2101  *
2102  * Note: Must swap left and right to get the sense of the
2103  * comparison correct. Otherwise, we would need to multiply by
2104  * -1 instead.
2105  */
2106  cmp = memcmp(right_bitwise, left_bitwise, ARRAY_LEN(left_bitwise));
2107  }
2108  if (cmp) {
2109  break;
2110  }
2111  if (!left) {
2112  /*
2113  * Get here only if both patterns ended at the same time. cmp
2114  * would be non-zero if only one pattern ended.
2115  */
2116  break;
2117  }
2118  }
2119  return cmp;
2120 }
2121 
2122 /*!
2123  * \internal
2124  * \brief Comparison of dialplan extens for sorting purposes.
2125  *
2126  * \param left Exten/pattern to compare.
2127  * \param right Exten/pattern to compare.
2128  *
2129  * \retval <0 if left < right
2130  * \retval =0 if left == right
2131  * \retval >0 if left > right
2132  */
2133 static int ext_cmp(const char *left, const char *right)
2134 {
2135  /* Make sure non-pattern extens come first. */
2136  if (left[0] != '_') {
2137  if (right[0] == '_') {
2138  return -1;
2139  }
2140  /* Compare two non-pattern extens. */
2141  return ext_cmp_exten(left, right);
2142  }
2143  if (right[0] != '_') {
2144  return 1;
2145  }
2146 
2147  /*
2148  * OK, we need full pattern sorting routine.
2149  *
2150  * Skip past the underscores
2151  */
2152  return ext_cmp_pattern(left + 1, right + 1);
2153 }
2154 
2155 static int ext_fluff_count(const char *exten)
2156 {
2157  int fluff = 0;
2158 
2159  if (*exten != '_') {
2160  /* not a pattern, simple check. */
2161  while (*exten) {
2162  if (*exten == '-') {
2163  fluff++;
2164  }
2165  exten++;
2166  }
2167 
2168  return fluff;
2169  }
2170 
2171  /* do pattern check */
2172  while (*exten) {
2173  if (*exten == '-') {
2174  fluff++;
2175  } else if (*exten == '[') {
2176  /* skip set, dashes here matter. */
2177  exten = strchr(exten, ']');
2178 
2179  if (!exten) {
2180  /* we'll end up warning about this later, don't spam logs */
2181  return fluff;
2182  }
2183  }
2184  exten++;
2185  }
2186 
2187  return fluff;
2188 }
2189 
2190 int ast_extension_cmp(const char *a, const char *b)
2191 {
2192  int cmp;
2193 
2194  cmp = ext_cmp(a, b);
2195  if (cmp < 0) {
2196  return -1;
2197  }
2198  if (cmp > 0) {
2199  return 1;
2200  }
2201  return 0;
2202 }
2203 
2204 /*!
2205  * \internal
2206  * \brief used ast_extension_{match|close}
2207  * mode is as follows:
2208  * E_MATCH success only on exact match
2209  * E_MATCHMORE success only on partial match (i.e. leftover digits in pattern)
2210  * E_CANMATCH either of the above.
2211  * \retval 0 on no-match
2212  * \retval 1 on match
2213  * \retval 2 on early match.
2214  */
2215 
2216 static int _extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
2217 {
2218  mode &= E_MATCH_MASK; /* only consider the relevant bits */
2219 
2220 #ifdef NEED_DEBUG_HERE
2221  ast_log(LOG_NOTICE,"match core: pat: '%s', dat: '%s', mode=%d\n", pattern, data, (int)mode);
2222 #endif
2223 
2224  if (pattern[0] != '_') { /* not a pattern, try exact or partial match */
2225  int lp = ext_cmp_exten_strlen(pattern);
2226  int ld = ext_cmp_exten_strlen(data);
2227 
2228  if (lp < ld) { /* pattern too short, cannot match */
2229 #ifdef NEED_DEBUG_HERE
2230  ast_log(LOG_NOTICE,"return (0) - pattern too short, cannot match\n");
2231 #endif
2232  return 0;
2233  }
2234  /* depending on the mode, accept full or partial match or both */
2235  if (mode == E_MATCH) {
2236 #ifdef NEED_DEBUG_HERE
2237  ast_log(LOG_NOTICE,"return (!ext_cmp_exten(%s,%s) when mode== E_MATCH)\n", pattern, data);
2238 #endif
2239  return !ext_cmp_exten(pattern, data); /* 1 on match, 0 on fail */
2240  }
2241  if (ld == 0 || !ext_cmp_exten_partial(pattern, data)) { /* partial or full match */
2242 #ifdef NEED_DEBUG_HERE
2243  ast_log(LOG_NOTICE,"return (mode(%d) == E_MATCHMORE ? lp(%d) > ld(%d) : 1)\n", mode, lp, ld);
2244 #endif
2245  return (mode == E_MATCHMORE) ? lp > ld : 1; /* XXX should consider '!' and '/' ? */
2246  } else {
2247 #ifdef NEED_DEBUG_HERE
2248  ast_log(LOG_NOTICE,"return (0) when ld(%d) > 0 && pattern(%s) != data(%s)\n", ld, pattern, data);
2249 #endif
2250  return 0;
2251  }
2252  }
2253  if (mode == E_MATCH && data[0] == '_') {
2254  /*
2255  * XXX It is bad design that we don't know if we should be
2256  * comparing data and pattern as patterns or comparing data if
2257  * it conforms to pattern when the function is called. First,
2258  * assume they are both patterns. If they don't match then try
2259  * to see if data conforms to the given pattern.
2260  *
2261  * note: if this test is left out, then _x. will not match _x. !!!
2262  */
2263 #ifdef NEED_DEBUG_HERE
2264  ast_log(LOG_NOTICE, "Comparing as patterns first. pattern:%s data:%s\n", pattern, data);
2265 #endif
2266  if (!ext_cmp_pattern(pattern + 1, data + 1)) {
2267 #ifdef NEED_DEBUG_HERE
2268  ast_log(LOG_NOTICE,"return (1) - pattern matches pattern\n");
2269 #endif
2270  return 1;
2271  }
2272  }
2273 
2274  ++pattern; /* skip leading _ */
2275  /*
2276  * XXX below we stop at '/' which is a separator for the CID info. However we should
2277  * not store '/' in the pattern at all. When we insure it, we can remove the checks.
2278  */
2279  for (;;) {
2280  const char *end;
2281 
2282  /* Ignore '-' chars as eye candy fluff. */
2283  while (*data == '-') {
2284  ++data;
2285  }
2286  while (*pattern == '-') {
2287  ++pattern;
2288  }
2289  if (!*data || !*pattern || *pattern == '/') {
2290  break;
2291  }
2292 
2293  switch (*pattern) {
2294  case '[': /* a range */
2295  ++pattern;
2296  end = strchr(pattern, ']'); /* XXX should deal with escapes ? */
2297  if (!end) {
2298  ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
2299  return 0; /* unconditional failure */
2300  }
2301  if (pattern == end) {
2302  /* Ignore empty character sets. */
2303  ++pattern;
2304  continue;
2305  }
2306  for (; pattern < end; ++pattern) {
2307  if (pattern+2 < end && pattern[1] == '-') { /* this is a range */
2308  if (*data >= pattern[0] && *data <= pattern[2])
2309  break; /* match found */
2310  else {
2311  pattern += 2; /* skip a total of 3 chars */
2312  continue;
2313  }
2314  } else if (*data == pattern[0])
2315  break; /* match found */
2316  }
2317  if (pattern >= end) {
2318 #ifdef NEED_DEBUG_HERE
2319  ast_log(LOG_NOTICE,"return (0) when pattern>=end\n");
2320 #endif
2321  return 0;
2322  }
2323  pattern = end; /* skip and continue */
2324  break;
2325  case 'n':
2326  case 'N':
2327  if (*data < '2' || *data > '9') {
2328 #ifdef NEED_DEBUG_HERE
2329  ast_log(LOG_NOTICE,"return (0) N is not matched\n");
2330 #endif
2331  return 0;
2332  }
2333  break;
2334  case 'x':
2335  case 'X':
2336  if (*data < '0' || *data > '9') {
2337 #ifdef NEED_DEBUG_HERE
2338  ast_log(LOG_NOTICE,"return (0) X is not matched\n");
2339 #endif
2340  return 0;
2341  }
2342  break;
2343  case 'z':
2344  case 'Z':
2345  if (*data < '1' || *data > '9') {
2346 #ifdef NEED_DEBUG_HERE
2347  ast_log(LOG_NOTICE,"return (0) Z is not matched\n");
2348 #endif
2349  return 0;
2350  }
2351  break;
2352  case '.': /* Must match, even with more digits */
2353 #ifdef NEED_DEBUG_HERE
2354  ast_log(LOG_NOTICE, "return (1) when '.' is matched\n");
2355 #endif
2356  return 1;
2357  case '!': /* Early match */
2358 #ifdef NEED_DEBUG_HERE
2359  ast_log(LOG_NOTICE, "return (2) when '!' is matched\n");
2360 #endif
2361  return 2;
2362  default:
2363  if (*data != *pattern) {
2364 #ifdef NEED_DEBUG_HERE
2365  ast_log(LOG_NOTICE, "return (0) when *data(%c) != *pattern(%c)\n", *data, *pattern);
2366 #endif
2367  return 0;
2368  }
2369  break;
2370  }
2371  ++data;
2372  ++pattern;
2373  }
2374  if (*data) /* data longer than pattern, no match */ {
2375 #ifdef NEED_DEBUG_HERE
2376  ast_log(LOG_NOTICE, "return (0) when data longer than pattern\n");
2377 #endif
2378  return 0;
2379  }
2380 
2381  /*
2382  * match so far, but ran off the end of data.
2383  * Depending on what is next, determine match or not.
2384  */
2385  if (*pattern == '\0' || *pattern == '/') { /* exact match */
2386 #ifdef NEED_DEBUG_HERE
2387  ast_log(LOG_NOTICE, "at end, return (%d) in 'exact match'\n", (mode==E_MATCHMORE) ? 0 : 1);
2388 #endif
2389  return (mode == E_MATCHMORE) ? 0 : 1; /* this is a failure for E_MATCHMORE */
2390  } else if (*pattern == '!') { /* early match */
2391 #ifdef NEED_DEBUG_HERE
2392  ast_log(LOG_NOTICE, "at end, return (2) when '!' is matched\n");
2393 #endif
2394  return 2;
2395  } else { /* partial match */
2396 #ifdef NEED_DEBUG_HERE
2397  ast_log(LOG_NOTICE, "at end, return (%d) which deps on E_MATCH\n", (mode == E_MATCH) ? 0 : 1);
2398 #endif
2399  return (mode == E_MATCH) ? 0 : 1; /* this is a failure for E_MATCH */
2400  }
2401 }
2402 
2403 /*
2404  * Wrapper around _extension_match_core() to do performance measurement
2405  * using the profiling code.
2406  */
2407 static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
2408 {
2409  int i;
2410  static int prof_id = -2; /* marker for 'unallocated' id */
2411  if (prof_id == -2) {
2412  prof_id = ast_add_profile("ext_match", 0);
2413  }
2414  ast_mark(prof_id, 1);
2415  i = _extension_match_core(ast_strlen_zero(pattern) ? "" : pattern, ast_strlen_zero(data) ? "" : data, mode);
2416  ast_mark(prof_id, 0);
2417  return i;
2418 }
2419 
2420 int ast_extension_match(const char *pattern, const char *extension)
2421 {
2422  return extension_match_core(pattern, extension, E_MATCH);
2423 }
2424 
2425 int ast_extension_close(const char *pattern, const char *data, int needmore)
2426 {
2427  if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
2428  ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
2429  return extension_match_core(pattern, data, needmore);
2430 }
2431 
2432 /* This structure must remain in sync with ast_context for proper hashtab matching */
2433 struct fake_context /* this struct is purely for matching in the hashtab */
2434 {
2436  struct ast_exten *root;
2440  struct ast_includes includes;
2441  struct ast_ignorepats ignorepats;
2442  struct ast_sws alts;
2443  const char *registrar;
2447  char name[256];
2448 };
2449 
2450 struct ast_context *ast_context_find(const char *name)
2451 {
2452  struct ast_context *tmp;
2453  struct fake_context item;
2454 
2455  if (!name) {
2456  return NULL;
2457  }
2459  if (contexts_table) {
2460  ast_copy_string(item.name, name, sizeof(item.name));
2462  } else {
2463  tmp = NULL;
2464  while ((tmp = ast_walk_contexts(tmp))) {
2465  if (!strcasecmp(name, tmp->name)) {
2466  break;
2467  }
2468  }
2469  }
2471  return tmp;
2472 }
2473 
2474 #define STATUS_NO_CONTEXT 1
2475 #define STATUS_NO_EXTENSION 2
2476 #define STATUS_NO_PRIORITY 3
2477 #define STATUS_NO_LABEL 4
2478 #define STATUS_SUCCESS 5
2479 
2480 static int matchcid(const char *cidpattern, const char *callerid)
2481 {
2482  /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so
2483  failing to get a number should count as a match, otherwise not */
2484 
2485  if (ast_strlen_zero(callerid)) {
2486  return ast_strlen_zero(cidpattern) ? 1 : 0;
2487  }
2488 
2489  return ast_extension_match(cidpattern, callerid);
2490 }
2491 
2493  struct ast_context *bypass, struct pbx_find_info *q,
2494  const char *context, const char *exten, int priority,
2495  const char *label, const char *callerid, enum ext_match_t action)
2496 {
2497  int x, res;
2498  struct ast_context *tmp = NULL;
2499  struct ast_exten *e = NULL, *eroot = NULL;
2500  struct ast_exten pattern = {NULL, };
2501  struct scoreboard score = {0, };
2502  struct ast_str *tmpdata = NULL;
2503  int idx;
2504 
2505  pattern.label = label;
2506  pattern.priority = priority;
2507 #ifdef NEED_DEBUG_HERE
2508  ast_log(LOG_NOTICE, "Looking for cont/ext/prio/label/action = %s/%s/%d/%s/%d\n", context, exten, priority, label, (int) action);
2509 #endif
2510 
2511  /* Initialize status if appropriate */
2512  if (q->stacklen == 0) {
2514  q->swo = NULL;
2515  q->data = NULL;
2516  q->foundcontext = NULL;
2517  } else if (q->stacklen >= AST_PBX_MAX_STACK) {
2518  ast_log(LOG_WARNING, "Maximum PBX stack (%d) exceeded. Too many includes?\n", AST_PBX_MAX_STACK);
2519  return NULL;
2520  }
2521 
2522  /* Check first to see if we've already been checked */
2523  for (x = 0; x < q->stacklen; x++) {
2524  if (!strcasecmp(q->incstack[x], context))
2525  return NULL;
2526  }
2527 
2528  if (bypass) { /* bypass means we only look there */
2529  tmp = bypass;
2530  } else { /* look in contexts */
2532  if (!tmp) {
2533  return NULL;
2534  }
2535  }
2536 
2537  if (q->status < STATUS_NO_EXTENSION)
2539 
2540  /* Do a search for matching extension */
2541 
2542  eroot = NULL;
2543  score.total_specificity = 0;
2544  score.exten = 0;
2545  score.total_length = 0;
2546  if (!tmp->pattern_tree && tmp->root_table) {
2548 #ifdef NEED_DEBUG
2549  ast_debug(1, "Tree Created in context %s:\n", context);
2550  log_match_char_tree(tmp->pattern_tree," ");
2551 #endif
2552  }
2553 #ifdef NEED_DEBUG
2554  ast_log(LOG_NOTICE, "The Trie we are searching in:\n");
2555  log_match_char_tree(tmp->pattern_tree, ":: ");
2556 #endif
2557 
2558  do {
2560  char *osw = ast_strdupa(overrideswitch), *name;
2561  struct ast_switch *asw;
2562  ast_switch_f *aswf = NULL;
2563  char *datap;
2564  int eval = 0;
2565 
2566  name = strsep(&osw, "/");
2567  asw = pbx_findswitch(name);
2568 
2569  if (!asw) {
2570  ast_log(LOG_WARNING, "No such switch '%s'\n", name);
2571  break;
2572  }
2573 
2574  if (osw && strchr(osw, '$')) {
2575  eval = 1;
2576  }
2577 
2578  if (eval && !(tmpdata = ast_str_thread_get(&switch_data, 512))) {
2579  ast_log(LOG_WARNING, "Can't evaluate overrideswitch?!\n");
2580  break;
2581  } else if (eval) {
2582  /* Substitute variables now */
2583  pbx_substitute_variables_helper(chan, osw, ast_str_buffer(tmpdata), ast_str_size(tmpdata));
2584  datap = ast_str_buffer(tmpdata);
2585  } else {
2586  datap = osw;
2587  }
2588 
2589  /* equivalent of extension_match_core() at the switch level */
2590  if (action == E_CANMATCH)
2591  aswf = asw->canmatch;
2592  else if (action == E_MATCHMORE)
2593  aswf = asw->matchmore;
2594  else /* action == E_MATCH */
2595  aswf = asw->exists;
2596  if (!aswf) {
2597  res = 0;
2598  } else {
2599  if (chan) {
2600  ast_autoservice_start(chan);
2601  }
2602  res = aswf(chan, context, exten, priority, callerid, datap);
2603  if (chan) {
2604  ast_autoservice_stop(chan);
2605  }
2606  }
2607  if (res) { /* Got a match */
2608  q->swo = asw;
2609  q->data = datap;
2610  q->foundcontext = context;
2611  /* XXX keep status = STATUS_NO_CONTEXT ? */
2612  return NULL;
2613  }
2614  }
2615  } while (0);
2616 
2617  if (extenpatternmatchnew) {
2618  new_find_extension(exten, &score, tmp->pattern_tree, 0, 0, callerid, label, action);
2619  eroot = score.exten;
2620 
2621  if (score.last_char == '!' && action == E_MATCHMORE) {
2622  /* We match an extension ending in '!'.
2623  * The decision in this case is final and is NULL (no match).
2624  */
2625 #ifdef NEED_DEBUG_HERE
2626  ast_log(LOG_NOTICE,"Returning MATCHMORE NULL with exclamation point.\n");
2627 #endif
2628  return NULL;
2629  }
2630 
2631  if (!eroot && (action == E_CANMATCH || action == E_MATCHMORE) && score.canmatch_exten) {
2632  q->status = STATUS_SUCCESS;
2633 #ifdef NEED_DEBUG_HERE
2634  ast_log(LOG_NOTICE,"Returning CANMATCH exten %s\n", score.canmatch_exten->exten);
2635 #endif
2636  return score.canmatch_exten;
2637  }
2638 
2639  if ((action == E_MATCHMORE || action == E_CANMATCH) && eroot) {
2640  if (score.node) {
2641  struct ast_exten *z = trie_find_next_match(score.node);
2642  if (z) {
2643 #ifdef NEED_DEBUG_HERE
2644  ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten %s\n", z->exten);
2645 #endif
2646  } else {
2647  if (score.canmatch_exten) {
2648 #ifdef NEED_DEBUG_HERE
2649  ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE canmatchmatch exten %s(%p)\n", score.canmatch_exten->exten, score.canmatch_exten);
2650 #endif
2651  return score.canmatch_exten;
2652  } else {
2653 #ifdef NEED_DEBUG_HERE
2654  ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten NULL\n");
2655 #endif
2656  }
2657  }
2658  return z;
2659  }
2660 #ifdef NEED_DEBUG_HERE
2661  ast_log(LOG_NOTICE, "Returning CANMATCH/MATCHMORE NULL (no next_match)\n");
2662 #endif
2663  return NULL; /* according to the code, complete matches are null matches in MATCHMORE mode */
2664  }
2665 
2666  if (eroot) {
2667  /* found entry, now look for the right priority */
2668  if (q->status < STATUS_NO_PRIORITY)
2670  e = NULL;
2671  if (action == E_FINDLABEL && label ) {
2672  if (q->status < STATUS_NO_LABEL)
2673  q->status = STATUS_NO_LABEL;
2674  e = ast_hashtab_lookup(eroot->peer_label_table, &pattern);
2675  } else {
2676  e = ast_hashtab_lookup(eroot->peer_table, &pattern);
2677  }
2678  if (e) { /* found a valid match */
2679  q->status = STATUS_SUCCESS;
2680  q->foundcontext = context;
2681 #ifdef NEED_DEBUG_HERE
2682  ast_log(LOG_NOTICE,"Returning complete match of exten %s\n", e->exten);
2683 #endif
2684  return e;
2685  }
2686  }
2687  } else { /* the old/current default exten pattern match algorithm */
2688 
2689  /* scan the list trying to match extension and CID */
2690  eroot = NULL;
2691  while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) {
2692  int match = extension_match_core(eroot->exten, exten, action);
2693  /* 0 on fail, 1 on match, 2 on earlymatch */
2694 
2695  if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid)))
2696  continue; /* keep trying */
2697  if (match == 2 && action == E_MATCHMORE) {
2698  /* We match an extension ending in '!'.
2699  * The decision in this case is final and is NULL (no match).
2700  */
2701  return NULL;
2702  }
2703  /* found entry, now look for the right priority */
2704  if (q->status < STATUS_NO_PRIORITY)
2706  e = NULL;
2707  if (action == E_FINDLABEL && label ) {
2708  if (q->status < STATUS_NO_LABEL)
2709  q->status = STATUS_NO_LABEL;
2710  e = ast_hashtab_lookup(eroot->peer_label_table, &pattern);
2711  } else {
2712  e = ast_hashtab_lookup(eroot->peer_table, &pattern);
2713  }
2714  if (e) { /* found a valid match */
2715  q->status = STATUS_SUCCESS;
2716  q->foundcontext = context;
2717  return e;
2718  }
2719  }
2720  }
2721 
2722  /* Check alternative switches */
2723  for (idx = 0; idx < ast_context_switches_count(tmp); idx++) {
2724  const struct ast_sw *sw = ast_context_switches_get(tmp, idx);
2725  struct ast_switch *asw = pbx_findswitch(ast_get_switch_name(sw));
2726  ast_switch_f *aswf = NULL;
2727  const char *datap;
2728 
2729  if (!asw) {
2730  ast_log(LOG_WARNING, "No such switch '%s'\n", ast_get_switch_name(sw));
2731  continue;
2732  }
2733 
2734  /* Substitute variables now */
2735  if (ast_get_switch_eval(sw)) {
2736  if (!(tmpdata = ast_str_thread_get(&switch_data, 512))) {
2737  ast_log(LOG_WARNING, "Can't evaluate switch?!\n");
2738  continue;
2739  }
2741  ast_str_buffer(tmpdata), ast_str_size(tmpdata));
2742  datap = ast_str_buffer(tmpdata);
2743  } else {
2744  datap = ast_get_switch_data(sw);
2745  }
2746 
2747  /* equivalent of extension_match_core() at the switch level */
2748  if (action == E_CANMATCH)
2749  aswf = asw->canmatch;
2750  else if (action == E_MATCHMORE)
2751  aswf = asw->matchmore;
2752  else /* action == E_MATCH */
2753  aswf = asw->exists;
2754  if (!aswf)
2755  res = 0;
2756  else {
2757  if (chan)
2758  ast_autoservice_start(chan);
2759  res = aswf(chan, context, exten, priority, callerid, datap);
2760  if (chan)
2761  ast_autoservice_stop(chan);
2762  }
2763  if (res) { /* Got a match */
2764  q->swo = asw;
2765  q->data = datap;
2766  q->foundcontext = context;
2767  /* XXX keep status = STATUS_NO_CONTEXT ? */
2768  return NULL;
2769  }
2770  }
2771  q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */
2772  /* Now try any includes we have in this context */
2773  for (idx = 0; idx < ast_context_includes_count(tmp); idx++) {
2774  const struct ast_include *i = ast_context_includes_get(tmp, idx);
2775 
2776  if (include_valid(i)) {
2777  if ((e = pbx_find_extension(chan, bypass, q, include_rname(i), exten, priority, label, callerid, action))) {
2778 #ifdef NEED_DEBUG_HERE
2779  ast_log(LOG_NOTICE,"Returning recursive match of %s\n", e->exten);
2780 #endif
2781  return e;
2782  }
2783  if (q->swo)
2784  return NULL;
2785  }
2786  }
2787  return NULL;
2788 }
2789 
2790 static void exception_store_free(void *data)
2791 {
2792  struct pbx_exception *exception = data;
2793  ast_string_field_free_memory(exception);
2794  ast_free(exception);
2795 }
2796 
2797 static const struct ast_datastore_info exception_store_info = {
2798  .type = "EXCEPTION",
2799  .destroy = exception_store_free,
2800 };
2801 
2802 /*!
2803  * \internal
2804  * \brief Set the PBX to execute the exception extension.
2805  *
2806  * \param chan Channel to raise the exception on.
2807  * \param reason Reason exception is raised.
2808  * \param priority Dialplan priority to set.
2809  *
2810  * \retval 0 on success.
2811  * \retval -1 on error.
2812  */
2813 int raise_exception(struct ast_channel *chan, const char *reason, int priority)
2814 {
2816  struct pbx_exception *exception = NULL;
2817 
2818  if (!ds) {
2820  if (!ds)
2821  return -1;
2822  if (!(exception = ast_calloc_with_stringfields(1, struct pbx_exception, 128))) {
2823  ast_datastore_free(ds);
2824  return -1;
2825  }
2826  ds->data = exception;
2827  ast_channel_datastore_add(chan, ds);
2828  } else
2829  exception = ds->data;
2830 
2831  ast_string_field_set(exception, reason, reason);
2833  ast_string_field_set(exception, exten, ast_channel_exten(chan));
2834  exception->priority = ast_channel_priority(chan);
2835  set_ext_pri(chan, "e", priority);
2836  return 0;
2837 }
2838 
2839 static int acf_exception_read(struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
2840 {
2842  struct pbx_exception *exception = NULL;
2843  if (!ds || !ds->data)
2844  return -1;
2845  exception = ds->data;
2846  if (!strcasecmp(data, "REASON"))
2847  ast_copy_string(buf, exception->reason, buflen);
2848  else if (!strcasecmp(data, "CONTEXT"))
2849  ast_copy_string(buf, exception->context, buflen);
2850  else if (!strncasecmp(data, "EXTEN", 5))
2851  ast_copy_string(buf, exception->exten, buflen);
2852  else if (!strcasecmp(data, "PRIORITY"))
2853  snprintf(buf, buflen, "%d", exception->priority);
2854  else
2855  return -1;
2856  return 0;
2857 }
2858 
2859 static struct ast_custom_function exception_function = {
2860  .name = "EXCEPTION",
2861  .read = acf_exception_read,
2862 };
2863 
2864 /*!
2865  * \brief The return value depends on the action:
2866  *
2867  * E_MATCH, E_CANMATCH, E_MATCHMORE require a real match,
2868  * and return 0 on failure, -1 on match;
2869  * E_FINDLABEL maps the label to a priority, and returns
2870  * the priority on success, ... XXX
2871  * E_SPAWN, spawn an application,
2872  *
2873  * \retval 0 on success.
2874  * \retval -1 on failure.
2875  *
2876  * \note The channel is auto-serviced in this function, because doing an extension
2877  * match may block for a long time. For example, if the lookup has to use a network
2878  * dialplan switch, such as DUNDi or IAX2, it may take a while. However, the channel
2879  * auto-service code will queue up any important signalling frames to be processed
2880  * after this is done.
2881  */
2882 static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con,
2883  const char *context, const char *exten, int priority,
2884  const char *label, const char *callerid, enum ext_match_t action, int *found, int combined_find_spawn)
2885 {
2886  struct ast_exten *e;
2887  struct ast_app *app;
2888  char *substitute = NULL;
2889  struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
2890  char passdata[EXT_DATA_SIZE];
2891  int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE);
2892 
2894 
2895  if (!context) {
2896  context = con->name;
2897  }
2898 
2899  if (found)
2900  *found = 0;
2901 
2902  e = pbx_find_extension(c, con, &q, context, exten, priority, label, callerid, action);
2903  if (e) {
2904  if (found)
2905  *found = 1;
2906  if (matching_action) {
2908  return -1; /* success, we found it */
2909  } else if (action == E_FINDLABEL) { /* map the label to a priority */
2910  int res = e->priority;
2911 
2913 
2914  /* the priority we were looking for */
2915  return res;
2916  } else { /* spawn */
2917  if (!e->cached_app)
2918  e->cached_app = pbx_findapp(e->app);
2919  app = e->cached_app;
2920  if (ast_strlen_zero(e->data)) {
2921  *passdata = '\0';
2922  } else {
2923  const char *tmp;
2924  if ((!(tmp = strchr(e->data, '$'))) || (!strstr(tmp, "${") && !strstr(tmp, "$["))) {
2925  /* no variables to substitute, copy on through */
2926  ast_copy_string(passdata, e->data, sizeof(passdata));
2927  } else {
2928  /* save e->data on stack for later processing after lock released */
2929  substitute = ast_strdupa(e->data);
2930  }
2931  }
2933  if (!app) {
2934  ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority);
2935  return -1;
2936  }
2937  if (ast_channel_context(c) != context)
2939  if (ast_channel_exten(c) != exten)
2942  if (substitute) {
2943  pbx_substitute_variables_helper(c, substitute, passdata, sizeof(passdata)-1);
2944  }
2945  ast_debug(1, "Launching '%s'\n", app_name(app));
2946  if (VERBOSITY_ATLEAST(3)) {
2947  ast_verb(3, "Executing [%s@%s:%d] " COLORIZE_FMT "(\"" COLORIZE_FMT "\", \"" COLORIZE_FMT "\") %s\n",
2951  COLORIZE(COLOR_BRMAGENTA, 0, passdata),
2952  "in new stack");
2953  }
2954  return pbx_exec(c, app, passdata); /* 0 on success, -1 on failure */
2955  }
2956  } else if (q.swo) { /* not found here, but in another switch */
2957  if (found)
2958  *found = 1;
2960  if (matching_action) {
2961  return -1;
2962  } else {
2963  if (!q.swo->exec) {
2964  ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name);
2965  return -1;
2966  }
2967  return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data);
2968  }
2969  } else { /* not found anywhere, see what happened */
2971  /* Using S_OR here because Solaris doesn't like NULL being passed to ast_log */
2972  switch (q.status) {
2973  case STATUS_NO_CONTEXT:
2974  if (!matching_action && !combined_find_spawn)
2975  ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", S_OR(context, ""));
2976  break;
2977  case STATUS_NO_EXTENSION:
2978  if (!matching_action && !combined_find_spawn)
2979  ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, S_OR(context, ""));
2980  break;
2981  case STATUS_NO_PRIORITY:
2982  if (!matching_action && !combined_find_spawn)
2983  ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, S_OR(context, ""));
2984  break;
2985  case STATUS_NO_LABEL:
2986  if (context && !combined_find_spawn)
2987  ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, S_OR(context, ""));
2988  break;
2989  default:
2990  ast_debug(1, "Shouldn't happen!\n");
2991  }
2992 
2993  return (matching_action) ? 0 : -1;
2994  }
2995 }
2996 
2997 /*! \brief Find hint for given extension in context */
2998 static struct ast_exten *ast_hint_extension_nolock(struct ast_channel *c, const char *context, const char *exten)
2999 {
3000  struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */
3002 }
3003 
3004 static struct ast_exten *ast_hint_extension(struct ast_channel *c, const char *context, const char *exten)
3005 {
3006  struct ast_exten *e;
3010  return e;
3011 }
3012 
3014 {
3015  switch (devstate) {
3016  case AST_DEVICE_ONHOLD:
3017  return AST_EXTENSION_ONHOLD;
3018  case AST_DEVICE_BUSY:
3019  return AST_EXTENSION_BUSY;
3020  case AST_DEVICE_UNKNOWN:
3021  return AST_EXTENSION_NOT_INUSE;
3023  case AST_DEVICE_INVALID:
3025  case AST_DEVICE_RINGINUSE:
3027  case AST_DEVICE_RINGING:
3028  return AST_EXTENSION_RINGING;
3029  case AST_DEVICE_INUSE:
3030  return AST_EXTENSION_INUSE;
3031  case AST_DEVICE_NOT_INUSE:
3032  return AST_EXTENSION_NOT_INUSE;
3033  case AST_DEVICE_TOTAL: /* not a device state, included for completeness */
3034  break;
3035  }
3036 
3037  return AST_EXTENSION_NOT_INUSE;
3038 }
3039 
3040 /*!
3041  * \internal
3042  * \brief Parse out the presence portion of the hint string
3043  */
3044 static char *parse_hint_presence(struct ast_str *hint_args)
3045 {
3046  char *copy = ast_strdupa(ast_str_buffer(hint_args));
3047  char *tmp = "";
3048 
3049  if ((tmp = strrchr(copy, ','))) {
3050  *tmp = '\0';
3051  tmp++;
3052  } else {
3053  return NULL;
3054  }
3055  ast_str_set(&hint_args, 0, "%s", tmp);
3056  return ast_str_buffer(hint_args);
3057 }
3058 
3059 /*!
3060  * \internal
3061  * \brief Parse out the device portion of the hint string
3062  */
3063 static char *parse_hint_device(struct ast_str *hint_args)
3064 {
3065  char *copy = ast_strdupa(ast_str_buffer(hint_args));
3066  char *tmp;
3067 
3068  if ((tmp = strrchr(copy, ','))) {
3069  *tmp = '\0';
3070  }
3071 
3072  ast_str_set(&hint_args, 0, "%s", copy);
3073  return ast_str_buffer(hint_args);
3074 }
3075 
3076 static void device_state_info_dt(void *obj)
3077 {
3078  struct ast_device_state_info *info = obj;
3079 
3080  ao2_cleanup(info->causing_channel);
3081 }
3082 
3084 {
3086 }
3087 
3088 static int ast_extension_state3(struct ast_str *hint_app, struct ao2_container *device_state_info)
3089 {
3090  char *cur;
3091  char *rest;
3092  struct ast_devstate_aggregate agg;
3093 
3094  /* One or more devices separated with a & character */
3095  rest = parse_hint_device(hint_app);
3096 
3098  while ((cur = strsep(&rest, "&"))) {
3100 
3102  if (device_state_info) {
3103  struct ast_device_state_info *obj;
3104 
3105  obj = ao2_alloc_options(sizeof(*obj) + strlen(cur), device_state_info_dt, AO2_ALLOC_OPT_LOCK_NOLOCK);
3106  /* if failed we cannot add this device */
3107  if (obj) {
3108  obj->device_state = state;
3109  strcpy(obj->device_name, cur);
3110  ao2_link(device_state_info, obj);
3111  ao2_ref(obj, -1);
3112  }
3113  }
3114  }
3115 
3117 }
3118 
3119 /*! \brief Check state of extension by using hints */
3120 static int ast_extension_state2(struct ast_exten *e, struct ao2_container *device_state_info)
3121 {
3122  struct ast_str *hint_app = ast_str_thread_get(&extensionstate_buf, 32);
3123 
3124  if (!e || !hint_app) {
3125  return -1;
3126  }
3127 
3128  ast_str_set(&hint_app, 0, "%s", ast_get_extension_app(e));
3129  return ast_extension_state3(hint_app, device_state_info);
3130 }
3131 
3132 /*! \brief Return extension_state as string */
3133 const char *ast_extension_state2str(int extension_state)
3134 {
3135  int i;
3136 
3137  for (i = 0; (i < ARRAY_LEN(extension_states)); i++) {
3138  if (extension_states[i].extension_state == extension_state)
3139  return extension_states[i].text;
3140  }
3141  return "Unknown";
3142 }
3143 
3144 /*!
3145  * \internal
3146  * \brief Check extension state for an extension by using hint
3147  */
3148 static int internal_extension_state_extended(struct ast_channel *c, const char *context, const char *exten,
3149  struct ao2_container *device_state_info)
3150 {
3151  struct ast_exten *e;
3152 
3153  if (!(e = ast_hint_extension(c, context, exten))) { /* Do we have a hint for this extension ? */
3154  return -1; /* No hint, return -1 */
3155  }
3156 
3157  if (e->exten[0] == '_') {
3158  /* Create this hint on-the-fly, we explicitly lock hints here to ensure the
3159  * same locking order as if this were done through configuration file - that is
3160  * hints is locked first and then (if needed) contexts is locked
3161  */
3162  ao2_lock(hints);
3163  ast_add_extension(e->parent->name, 0, exten, e->priority, e->label,
3164  e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr,
3165  e->registrar);
3166  ao2_unlock(hints);
3167  if (!(e = ast_hint_extension(c, context, exten))) {
3168  /* Improbable, but not impossible */
3169  return -1;
3170  }
3171  }
3172 
3173  return ast_extension_state2(e, device_state_info); /* Check all devices in the hint */
3174 }
3175 
3176 /*! \brief Check extension state for an extension by using hint */
3177 int ast_extension_state(struct ast_channel *c, const char *context, const char *exten)
3178 {
3180 }
3181 
3182 /*! \brief Check extended extension state for an extension by using hint */
3183 int ast_extension_state_extended(struct ast_channel *c, const char *context, const char *exten,
3184  struct ao2_container **device_state_info)
3185 {
3186  struct ao2_container *container = NULL;
3187  int ret;
3188 
3189  if (device_state_info) {
3191  }
3192 
3194  if (ret < 0 && container) {
3195  ao2_ref(container, -1);
3196  container = NULL;
3197  }
3198 
3199  if (device_state_info) {
3201  *device_state_info = container;
3202  }
3203 
3204  return ret;
3205 }
3206 
3207 static int extension_presence_state_helper(struct ast_exten *e, char **subtype, char **message)
3208 {
3209  struct ast_str *hint_app = ast_str_thread_get(&extensionstate_buf, 32);
3210  char *presence_provider;
3211  const char *app;
3212 
3213  if (!e || !hint_app) {
3214  return -1;
3215  }
3216 
3218  if (ast_strlen_zero(app)) {
3219  return -1;
3220  }
3221 
3222  ast_str_set(&hint_app, 0, "%s", app);
3223  presence_provider = parse_hint_presence(hint_app);
3224 
3225  if (ast_strlen_zero(presence_provider)) {
3226  /* No presence string in the hint */
3227  return 0;
3228  }
3229 
3230  return ast_presence_state(presence_provider, subtype, message);
3231 }
3232 
3233 int ast_hint_presence_state(struct ast_channel *c, const char *context, const char *exten, char **subtype, char **message)
3234 {
3235  struct ast_exten *e;
3236 
3237  if (!(e = ast_hint_extension(c, context, exten))) { /* Do we have a hint for this extension ? */
3238  return -1; /* No hint, return -1 */
3239  }
3240 
3241  if (e->exten[0] == '_') {
3242  /* Create this hint on-the-fly */
3243  ao2_lock(hints);
3244  ast_add_extension(e->parent->name, 0, exten, e->priority, e->label,
3245  e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr,
3246  e->registrar);
3247  ao2_unlock(hints);
3248  if (!(e = ast_hint_extension(c, context, exten))) {
3249  /* Improbable, but not impossible */
3250  return -1;
3251  }
3252  }
3253 
3254  return extension_presence_state_helper(e, subtype, message);
3255 }
3256 
3258  const char *context,
3259  const char *exten,
3260  void *data,
3261  enum ast_state_cb_update_reason reason,
3262  struct ast_hint *hint,
3263  struct ao2_container *device_state_info)
3264 {
3265  int res = 0;
3266  struct ast_state_cb_info info = { 0, };
3267 
3268  info.reason = reason;
3269 
3270  /* Copy over current hint data */
3271  if (hint) {
3272  ao2_lock(hint);
3273  info.exten_state = hint->laststate;
3274  info.device_state_info = device_state_info;
3275  info.presence_state = hint->last_presence_state;
3276  if (!(ast_strlen_zero(hint->last_presence_subtype))) {
3277  info.presence_subtype = ast_strdupa(hint->last_presence_subtype);
3278  } else {
3279  info.presence_subtype = "";
3280  }
3281  if (!(ast_strlen_zero(hint->last_presence_message))) {
3282  info.presence_message = ast_strdupa(hint->last_presence_message);
3283  } else {
3284  info.presence_message = "";
3285  }
3286  ao2_unlock(hint);
3287  } else {
3288  info.exten_state = AST_EXTENSION_REMOVED;
3289  }
3290 
3291  res = cb(context, exten, &info, data);
3292 
3293  return res;
3294 }
3295 
3296 /*!
3297  * \internal
3298  * \brief Identify a channel for every device which is supposedly responsible for the device state.
3299  *
3300  * Especially when the device is ringing, the oldest ringing channel is chosen.
3301  * For all other cases the first encountered channel in the specific state is chosen.
3302  */
3304 {
3305  struct ao2_iterator iter;
3306  struct ast_device_state_info *info;
3307  struct ast_channel *chan;
3308 
3309  if (!c || !ao2_container_count(c)) {
3310  return;
3311  }
3312  iter = ao2_iterator_init(c, 0);
3313  for (; (info = ao2_iterator_next(&iter)); ao2_ref(info, -1)) {
3314  enum ast_channel_state search_state = 0; /* prevent false uninit warning */
3315  char match[AST_CHANNEL_NAME];
3316  struct ast_channel_iterator *chan_iter;
3317  struct timeval chantime = {0, }; /* prevent false uninit warning */
3318 
3319  switch (info->device_state) {
3320  case AST_DEVICE_RINGING:
3321  case AST_DEVICE_RINGINUSE:
3322  /* find ringing channel */
3323  search_state = AST_STATE_RINGING;
3324  break;
3325  case AST_DEVICE_BUSY:
3326  /* find busy channel */
3327  search_state = AST_STATE_BUSY;
3328  break;
3329  case AST_DEVICE_ONHOLD:
3330  case AST_DEVICE_INUSE:
3331  /* find up channel */
3332  search_state = AST_STATE_UP;
3333  break;
3334  case AST_DEVICE_UNKNOWN:
3335  case AST_DEVICE_NOT_INUSE:
3336  case AST_DEVICE_INVALID:
3338  case AST_DEVICE_TOTAL /* not a state */:
3339  /* no channels are of interest */
3340  continue;
3341  }
3342 
3343  /* iterate over all channels of the device */
3344  snprintf(match, sizeof(match), "%s-", info->device_name);
3345  chan_iter = ast_channel_iterator_by_name_new(match, strlen(match));
3346  for (; (chan = ast_channel_iterator_next(chan_iter)); ast_channel_unref(chan)) {
3347  ast_channel_lock(chan);
3348  /* this channel's state doesn't match */
3349  if (search_state != ast_channel_state(chan)) {
3350  ast_channel_unlock(chan);
3351  continue;
3352  }
3353  /* any non-ringing channel will fit */
3354  if (search_state != AST_STATE_RINGING) {
3355  ast_channel_unlock(chan);
3356  info->causing_channel = chan; /* is kept ref'd! */
3357  break;
3358  }
3359  /* but we need the oldest ringing channel of the device to match with undirected pickup */
3360  if (!info->causing_channel) {
3361  chantime = ast_channel_creationtime(chan);
3362  ast_channel_ref(chan); /* must ref it! */
3363  info->causing_channel = chan;
3364  } else if (ast_tvcmp(ast_channel_creationtime(chan), chantime) < 0) {
3365  chantime = ast_channel_creationtime(chan);
3366  ast_channel_unref(info->causing_channel);
3367  ast_channel_ref(chan); /* must ref it! */
3368  info->causing_channel = chan;
3369  }
3370  ast_channel_unlock(chan);
3371  }
3372  ast_channel_iterator_destroy(chan_iter);
3373  }
3374  ao2_iterator_destroy(&iter);
3375 }
3376 
3377 static void device_state_notify_callbacks(struct ast_hint *hint, struct ast_str **hint_app)
3378 {
3379  struct ao2_iterator cb_iter;
3380  struct ast_state_cb *state_cb;
3381  int state;
3382  int same_state;
3383  struct ao2_container *device_state_info;
3384  int first_extended_cb_call = 1;
3387 
3388  ao2_lock(hint);
3389  if (!hint->exten) {
3390  /* The extension has already been destroyed */
3391  ao2_unlock(hint);
3392  return;
3393  }
3394 
3395  /*
3396  * Save off strings in case the hint extension gets destroyed
3397  * while we are notifying the watchers.
3398  */
3401  sizeof(context_name));
3403  sizeof(exten_name));
3404  ast_str_set(hint_app, 0, "%s", ast_get_extension_app(hint->exten));
3405  ao2_unlock(hint);
3406 
3407  /*
3408  * Get device state for this hint.
3409  *
3410  * NOTE: We cannot hold any locks while determining the hint
3411  * device state or notifying the watchers without causing a
3412  * deadlock. (conlock, hints, and hint)
3413  */
3414 
3415  /* Make a container so state3 can fill it if we wish.
3416  * If that failed we simply do not provide the extended state info.
3417  */
3418  device_state_info = alloc_device_state_info();
3419 
3420  state = ast_extension_state3(*hint_app, device_state_info);
3421  same_state = state == hint->laststate;
3422  if (same_state && (~state & AST_EXTENSION_RINGING)) {
3423  ao2_cleanup(device_state_info);
3424  return;
3425  }
3426 
3427  /* Device state changed since last check - notify the watchers. */
3428  hint->laststate = state; /* record we saw the change */
3429 
3430  /* For general callbacks */
3431  if (!same_state) {
3432  cb_iter = ao2_iterator_init(statecbs, 0);
3433  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
3435  context_name,
3436  exten_name,
3437  state_cb->data,
3439  hint,
3440  NULL);
3441  }
3442  ao2_iterator_destroy(&cb_iter);
3443  }
3444 
3445  /* For extension callbacks */
3446  /* extended callbacks are called when the state changed or when AST_STATE_RINGING is
3447  * included. Normal callbacks are only called when the state changed.
3448  */
3449  cb_iter = ao2_iterator_init(hint->callbacks, 0);
3450  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
3451  if (state_cb->extended && first_extended_cb_call) {
3452  /* Fill detailed device_state_info now that we know it is used by extd. callback */
3453  first_extended_cb_call = 0;
3454  get_device_state_causing_channels(device_state_info);
3455  }
3456  if (state_cb->extended || !same_state) {
3458  context_name,
3459  exten_name,
3460  state_cb->data,
3462  hint,
3463  state_cb->extended ? device_state_info : NULL);
3464  }
3465  }
3466  ao2_iterator_destroy(&cb_iter);
3467 
3468  ao2_cleanup(device_state_info);
3469 }
3470 
3471 static void presence_state_notify_callbacks(struct ast_hint *hint, struct ast_str **hint_app,
3472  struct ast_presence_state_message *presence_state)
3473 {
3474  struct ao2_iterator cb_iter;
3475  struct ast_state_cb *state_cb;
3478 
3479  ao2_lock(hint);
3480  if (!hint->exten) {
3481  /* The extension has already been destroyed */
3482  ao2_unlock(hint);
3483  return;
3484  }
3485 
3486  /*
3487  * Save off strings in case the hint extension gets destroyed
3488  * while we are notifying the watchers.
3489  */
3492  sizeof(context_name));
3494  sizeof(exten_name));
3495  ast_str_set(hint_app, 0, "%s", ast_get_extension_app(hint->exten));
3496  ao2_unlock(hint);
3497 
3498  /* Check to see if update is necessary */
3499  if ((hint->last_presence_state == presence_state->state) &&
3500  ((hint->last_presence_subtype && presence_state->subtype &&
3501  !strcmp(hint->last_presence_subtype, presence_state->subtype)) ||
3502  (!hint->last_presence_subtype && !presence_state->subtype)) &&
3503  ((hint->last_presence_message && presence_state->message &&
3504  !strcmp(hint->last_presence_message, presence_state->message)) ||
3505  (!hint->last_presence_message && !presence_state->message))) {
3506  /* this update is the same as the last, do nothing */
3507  return;
3508  }
3509 
3510  /* update new values */
3513  hint->last_presence_state = presence_state->state;
3514  hint->last_presence_subtype = presence_state->subtype ? ast_strdup(presence_state->subtype) : NULL;
3515  hint->last_presence_message = presence_state->message ? ast_strdup(presence_state->message) : NULL;
3516 
3517  /* For general callbacks */
3518  cb_iter = ao2_iterator_init(statecbs, 0);
3519  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
3521  context_name,
3522  exten_name,
3523  state_cb->data,
3525  hint,
3526  NULL);
3527  }
3528  ao2_iterator_destroy(&cb_iter);
3529 
3530  /* For extension callbacks */
3531  cb_iter = ao2_iterator_init(hint->callbacks, 0);
3532  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_cleanup(state_cb)) {
3534  context_name,
3535  exten_name,
3536  state_cb->data,
3538  hint,
3539  NULL);
3540  }
3541  ao2_iterator_destroy(&cb_iter);
3542 }
3543 
3545 {
3546  struct ast_hint *hint;
3547  struct ast_str *hint_app;
3548 
3549  if (hint_change_message_type() != stasis_message_type(msg)) {
3550  return 0;
3551  }
3552 
3553  if (!(hint_app = ast_str_create(1024))) {
3554  return -1;
3555  }
3556 
3557  hint = stasis_message_data(msg);
3558 
3559  switch (reason) {
3561  device_state_notify_callbacks(hint, &hint_app);
3562  break;
3564  {
3565  char *presence_subtype = NULL;
3566  char *presence_message = NULL;
3567  int state;
3568 
3570  hint->exten, &presence_subtype, &presence_message);
3571  {
3572  struct ast_presence_state_message presence_state = {
3574  .subtype = presence_subtype,
3575  .message = presence_message
3576  };
3577 
3578  presence_state_notify_callbacks(hint, &hint_app, &presence_state);
3579  }
3580 
3581  ast_free(presence_subtype);
3582  ast_free(presence_message);
3583  }
3584  break;
3585  }
3586 
3587  ast_free(hint_app);
3588  return 1;
3589 }
3590 
3591 static void device_state_cb(void *unused, struct stasis_subscription *sub, struct stasis_message *msg)
3592 {
3593  struct ast_device_state_message *dev_state;
3594  struct ast_str *hint_app;
3595  struct ast_hintdevice *device;
3596  struct ast_hintdevice *cmpdevice;
3597  struct ao2_iterator *dev_iter;
3598  struct ao2_iterator auto_iter;
3599  struct ast_autohint *autohint;
3600  char *virtual_device;
3601  char *type;
3602  char *device_name;
3603 
3605  return;
3606  }
3607 
3608  if (hint_remove_message_type() == stasis_message_type(msg)) {
3609  /* The extension has already been destroyed */
3610  struct ast_state_cb *state_cb;
3611  struct ao2_iterator cb_iter;
3612  struct ast_hint *hint = stasis_message_data(msg);
3613 
3614  ao2_lock(hint);
3616  ao2_unlock(hint);
3617 
3618  cb_iter = ao2_iterator_init(hint->callbacks, 0);
3619  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
3621  hint->context_name,
3622  hint->exten_name,
3623  state_cb->data,
3625  hint,
3626  NULL);
3627  }
3628  ao2_iterator_destroy(&cb_iter);
3629  return;
3630  }
3631 
3633  return;
3634  }
3635 
3636  dev_state = stasis_message_data(msg);
3637  if (dev_state->eid) {
3638  /* ignore non-aggregate states */
3639  return;
3640  }
3641 
3643  /* There are no hints monitoring devices. */
3644  return;
3645  }
3646 
3647  hint_app = ast_str_create(1024);
3648  if (!hint_app) {
3649  return;
3650  }
3651 
3652  cmpdevice = ast_alloca(sizeof(*cmpdevice) + strlen(dev_state->device));
3653  strcpy(cmpdevice->hintdevice, dev_state->device);
3654 
3655  ast_mutex_lock(&context_merge_lock);/* Hold off ast_merge_contexts_and_delete */
3656 
3657  /* Initially we find all hints for the device and notify them */
3658  dev_iter = ao2_t_callback(hintdevices,
3661  cmpdevice,
3662  "find devices in container");
3663  if (dev_iter) {
3664  for (; (device = ao2_iterator_next(dev_iter)); ao2_t_ref(device, -1, "Next device")) {
3665  if (device->hint) {
3666  device_state_notify_callbacks(device->hint, &hint_app);
3667  }
3668  }
3669  ao2_iterator_destroy(dev_iter);
3670  }
3671 
3672  /* Second stage we look for any autohint contexts and if the device is not already in the hints
3673  * we create it.
3674  */
3675  type = ast_strdupa(dev_state->device);
3676  if (ast_strlen_zero(type)) {
3677  goto end;
3678  }
3679 
3680  /* Determine if this is a virtual/custom device or a real device */
3681  virtual_device = strchr(type, ':');
3682  device_name = strchr(type, '/');
3683  if (virtual_device && (!device_name || (virtual_device < device_name))) {
3684  device_name = virtual_device;
3685  }
3686 
3687  /* Invalid device state name - not a virtual/custom device and not a real device */
3688  if (ast_strlen_zero(device_name)) {
3689  goto end;
3690  }
3691 
3692  *device_name++ = '\0';
3693 
3694  auto_iter = ao2_iterator_init(autohints, 0);
3695  for (; (autohint = ao2_iterator_next(&auto_iter)); ao2_t_ref(autohint, -1, "Next autohint")) {
3696  if (ast_get_hint(NULL, 0, NULL, 0, NULL, autohint->context, device_name)) {
3697  continue;
3698  }
3699 
3700  /* The device has no hint in the context referenced by this autohint so create one */
3701  ast_add_extension(autohint->context, 0, device_name,
3702  PRIORITY_HINT, NULL, NULL, dev_state->device,
3703  ast_strdup(dev_state->device), ast_free_ptr, autohint->registrar);
3704 
3705  /* Since this hint was just created there are no watchers, so we don't need to notify anyone */
3706  }
3707  ao2_iterator_destroy(&auto_iter);
3708 
3709 end:
3711  ast_free(hint_app);
3712  return;
3713 }
3714 
3715 /*!
3716  * \internal
3717  * \brief Destroy the given state callback object.
3718  *
3719  * \param doomed State callback to destroy.
3720  */
3721 static void destroy_state_cb(void *doomed)
3722 {
3723  struct ast_state_cb *state_cb = doomed;
3724 
3725  if (state_cb->destroy_cb) {
3726  state_cb->destroy_cb(state_cb->id, state_cb->data);
3727  }
3728 }
3729 
3730 /*!
3731  * \internal
3732  * \brief Add watcher for extension states with destructor
3733  */
3734 static int extension_state_add_destroy(const char *context, const char *exten,
3736 {
3737  struct ast_hint *hint;
3738  struct ast_state_cb *state_cb;
3739  struct ast_exten *e;
3740  int id;
3741 
3742  /* If there's no context and extension: add callback to statecbs list */
3743  if (!context && !exten) {
3744  /* Prevent multiple adds from adding the same change_cb at the same time. */
3745  ao2_lock(statecbs);
3746 
3747  /* Remove any existing change_cb. */
3748  ao2_find(statecbs, change_cb, OBJ_UNLINK | OBJ_NODATA);
3749 
3750  /* Now insert the change_cb */
3751  if (!(state_cb = ao2_alloc(sizeof(*state_cb), destroy_state_cb))) {
3753  return -1;
3754  }
3755  state_cb->id = 0;
3756  state_cb->change_cb = change_cb;
3757  state_cb->destroy_cb = destroy_cb;
3758  state_cb->data = data;
3759  state_cb->extended = extended;
3760  ao2_link(statecbs, state_cb);
3761 
3762  ao2_ref(state_cb, -1);
3764  return 0;
3765  }
3766 
3767  if (!context || !exten)
3768  return -1;
3769 
3770  /* This callback type is for only one hint, so get the hint */
3772  if (!e) {
3773  return -1;
3774  }
3775 
3776  /* If this is a pattern, dynamically create a new extension for this
3777  * particular match. Note that this will only happen once for each
3778  * individual extension, because the pattern will no longer match first.
3779  */
3780  if (e->exten[0] == '_') {
3781  ao2_lock(hints);
3782  ast_add_extension(e->parent->name, 0, exten, e->priority, e->label,
3783  e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr,
3784  e->registrar);
3785  ao2_unlock(hints);
3787  if (!e || e->exten[0] == '_') {
3788  return -1;
3789  }
3790  }
3791 
3792  /* Find the hint in the hints container */
3793  ao2_lock(hints);/* Locked to hold off ast_merge_contexts_and_delete */
3794  hint = ao2_find(hints, e, 0);
3795  if (!hint) {
3796  ao2_unlock(hints);
3797  return -1;
3798  }
3799 
3800  /* Now insert the callback in the callback list */
3801  if (!(state_cb = ao2_alloc(sizeof(*state_cb), destroy_state_cb))) {
3802  ao2_ref(hint, -1);
3803  ao2_unlock(hints);
3804  return -1;
3805  }
3806  do {
3807  id = stateid++; /* Unique ID for this callback */
3808  /* Do not allow id to ever be -1 or 0. */
3809  } while (id == -1 || id == 0);
3810  state_cb->id = id;
3811  state_cb->change_cb = change_cb; /* Pointer to callback routine */
3812  state_cb->destroy_cb = destroy_cb;
3813  state_cb->data = data; /* Data for the callback */
3814  state_cb->extended = extended;
3815  ao2_link(hint->callbacks, state_cb);
3816 
3817  ao2_ref(state_cb, -1);
3818  ao2_ref(hint, -1);
3819  ao2_unlock(hints);
3820 
3821  return id;
3822 }
3823 
3824 int ast_extension_state_add_destroy(const char *context, const char *exten,
3825  ast_state_cb_type change_cb, ast_state_cb_destroy_type destroy_cb, void *data)
3826 {
3827  return extension_state_add_destroy(context, exten, change_cb, destroy_cb, data, 0);
3828 }
3829 
3830 int ast_extension_state_add(const char *context, const char *exten,
3831  ast_state_cb_type change_cb, void *data)
3832 {
3833  return extension_state_add_destroy(context, exten, change_cb, NULL, data, 0);
3834 }
3835 
3837  ast_state_cb_type change_cb, ast_state_cb_destroy_type destroy_cb, void *data)
3838 {
3839  return extension_state_add_destroy(context, exten, change_cb, destroy_cb, data, 1);
3840 }
3841 
3842 int ast_extension_state_add_extended(const char *context, const char *exten,
3843  ast_state_cb_type change_cb, void *data)
3844 {
3845  return extension_state_add_destroy(context, exten, change_cb, NULL, data, 1);
3846 }
3847 
3848 /*! \brief Find Hint by callback id */
3849 static int find_hint_by_cb_id(void *obj, void *arg, int flags)
3850 {
3851  struct ast_state_cb *state_cb;
3852  const struct ast_hint *hint = obj;
3853  int *id = arg;
3854 
3855  if ((state_cb = ao2_find(hint->callbacks, id, 0))) {
3856  ao2_ref(state_cb, -1);
3857  return CMP_MATCH | CMP_STOP;
3858  }
3859 
3860  return 0;
3861 }
3862 
3864 {
3865  struct ast_state_cb *p_cur;
3866  int ret = -1;
3867 
3868  if (!id) { /* id == 0 is a callback without extension */
3869  if (!change_cb) {
3870  return ret;
3871  }
3873  if (p_cur) {
3874  ret = 0;
3875  ao2_ref(p_cur, -1);
3876  }
3877  } else { /* callback with extension, find the callback based on ID */
3878  struct ast_hint *hint;
3879 
3880  ao2_lock(hints);/* Locked to hold off ast_merge_contexts_and_delete */
3881  hint = ao2_callback(hints, 0, find_hint_by_cb_id, &id);
3882  if (hint) {
3883  p_cur = ao2_find(hint->callbacks, &id, OBJ_UNLINK);
3884  if (p_cur) {
3885  ret = 0;
3886  ao2_ref(p_cur, -1);
3887  }
3888  ao2_ref(hint, -1);
3889  }
3890  ao2_unlock(hints);
3891  }
3892 
3893  return ret;
3894 }
3895 
3896 static int hint_id_cmp(void *obj, void *arg, int flags)
3897 {
3898  const struct ast_state_cb *cb = obj;
3899  int *id = arg;
3900 
3901  return (cb->id == *id) ? CMP_MATCH | CMP_STOP : 0;
3902 }
3903 
3904 /*!
3905  * \internal
3906  * \brief Destroy the given hint object.
3907  *
3908  * \param obj Hint to destroy.
3909  */
3910 static void destroy_hint(void *obj)
3911 {
3912  struct ast_hint *hint = obj;
3913  int i;
3914 
3915  ao2_cleanup(hint->callbacks);
3916 
3917  for (i = 0; i < AST_VECTOR_SIZE(&hint->devices); i++) {
3918  char *device = AST_VECTOR_GET(&hint->devices, i);
3919  ast_free(device);
3920  }
3921  AST_VECTOR_FREE(&hint->devices);
3924 }
3925 
3926 /*! \brief Publish a hint removed event */
3927 static int publish_hint_remove(struct ast_hint *hint)
3928 {
3929  struct stasis_message *message;
3930 
3931  if (!hint_remove_message_type()) {
3932  return -1;
3933  }
3934 
3935  if (!(message = stasis_message_create(hint_remove_message_type(), hint))) {
3936  ao2_ref(hint, -1);
3937  return -1;
3938  }
3939 
3941 
3942  ao2_ref(message, -1);
3943 
3944  return 0;
3945 }
3946 
3947 /*! \brief Remove hint from extension */
3948 static int ast_remove_hint(struct ast_exten *e)
3949 {
3950  /* Cleanup the Notifys if hint is removed */
3951  struct ast_hint *hint;
3952 
3953  if (!e) {
3954  return -1;
3955  }
3956 
3957  hint = ao2_find(hints, e, OBJ_UNLINK);
3958  if (!hint) {
3959  return -1;
3960  }
3961 
3962  remove_hintdevice(hint);
3963 
3964  /*
3965  * The extension is being destroyed so we must save some
3966  * information to notify that the extension is deactivated.
3967  */
3968  ao2_lock(hint);
3971  sizeof(hint->context_name));
3973  sizeof(hint->exten_name));
3974  hint->exten = NULL;
3975  ao2_unlock(hint);
3976 
3977  publish_hint_remove(hint);
3978 
3979  ao2_ref(hint, -1);
3980 
3981  return 0;
3982 }
3983 
3984 /*! \brief Add hint to hint list, check initial extension state */
3985 static int ast_add_hint(struct ast_exten *e)
3986 {
3987  struct ast_hint *hint_new;
3988  struct ast_hint *hint_found;
3989  char *message = NULL;
3990  char *subtype = NULL;
3991  int presence_state;
3992 
3993  if (!e) {
3994  return -1;
3995  }
3996 
3997  /*
3998  * We must create the hint we wish to add before determining if
3999  * it is already in the hints container to avoid possible
4000  * deadlock when getting the current extension state.
4001  */
4002  hint_new = ao2_alloc(sizeof(*hint_new), destroy_hint);
4003  if (!hint_new) {
4004  return -1;
4005  }
4006  AST_VECTOR_INIT(&hint_new->devices, 8);
4007 
4008  /* Initialize new hint. */
4010  if (!hint_new->callbacks) {
4011  ao2_ref(hint_new, -1);
4012  return -1;
4013  }
4014  hint_new->exten = e;
4015  if (strstr(e->app, "${") && e->exten[0] == '_') {
4016  /* The hint is dynamic and hasn't been evaluated yet */
4017  hint_new->laststate = AST_DEVICE_INVALID;
4019  } else {
4020  hint_new->laststate = ast_extension_state2(e, NULL);
4021  if ((presence_state = extension_presence_state_helper(e, &subtype, &message)) > 0) {
4022  hint_new->last_presence_state = presence_state;
4023  hint_new->last_presence_subtype = subtype;
4024  hint_new->last_presence_message = message;
4025  }
4026  }
4027 
4028  /* Prevent multiple add hints from adding the same hint at the same time. */
4029  ao2_lock(hints);
4030 
4031  /* Search if hint exists, do nothing */
4032  hint_found = ao2_find(hints, e, 0);
4033  if (hint_found) {
4034  ao2_ref(hint_found, -1);
4035  ao2_unlock(hints);
4036  ao2_ref(hint_new, -1);
4037  ast_debug(2, "HINTS: Not re-adding existing hint %s: %s\n",
4039  return -1;
4040  }
4041 
4042  /* Add new hint to the hints container */
4043  ast_debug(2, "HINTS: Adding hint %s: %s\n",
4045  ao2_link(hints, hint_new);
4046  if (add_hintdevice(hint_new, ast_get_extension_app(e))) {
4047  ast_log(LOG_WARNING, "Could not add devices for hint: %s@%s.\n",
4050  }
4051 
4052  /* if not dynamic */
4053  if (!(strstr(e->app, "${") && e->exten[0] == '_')) {
4054  struct ast_state_cb *state_cb;
4055  struct ao2_iterator cb_iter;
4056 
4057  /* For general callbacks */
4058  cb_iter = ao2_iterator_init(statecbs, 0);
4059  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
4063  state_cb->data,
4065  hint_new,
4066  NULL);
4067  }
4068  ao2_iterator_destroy(&cb_iter);
4069  }
4070  ao2_unlock(hints);
4071  ao2_ref(hint_new, -1);
4072 
4073  return 0;
4074 }
4075 
4076 /*! \brief Publish a hint changed event */
4077 static int publish_hint_change(struct ast_hint *hint, struct ast_exten *ne)
4078 {
4079  struct stasis_message *message;
4080 
4081  if (!hint_change_message_type()) {
4082  return -1;
4083  }
4084 
4085  if (!(message = stasis_message_create(hint_change_message_type(), hint))) {
4086  ao2_ref(hint, -1);
4087  return -1;
4088  }
4089 
4092 
4093  ao2_ref(message, -1);
4094 
4095  return 0;
4096 }
4097 
4098 /*! \brief Change hint for an extension */
4099 static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
4100 {
4101  struct ast_hint *hint;
4102 
4103  if (!oe || !ne) {
4104  return -1;
4105  }
4106 
4107  ao2_lock(hints);/* Locked to hold off others while we move the hint around. */
4108 
4109  /*
4110  * Unlink the hint from the hints container as the extension
4111  * name (which is the hash value) could change.
4112  */
4113  hint = ao2_find(hints, oe, OBJ_UNLINK);
4114  if (!hint) {
4115  ao2_unlock(hints);
4117  return -1;
4118  }
4119 
4120  remove_hintdevice(hint);
4121 
4122  /* Update the hint and put it back in the hints container. */
4123  ao2_lock(hint);
4124  hint->exten = ne;
4125 
4126  ao2_unlock(hint);
4127 
4128  ao2_link(hints, hint);
4129  if (add_hintdevice(hint, ast_get_extension_app(ne))) {
4130  ast_log(LOG_WARNING, "Could not add devices for hint: %s@%s.\n",
4133  }
4134  ao2_unlock(hints);
4135 
4136  publish_hint_change(hint, ne);
4137 
4138  ao2_ref(hint, -1);
4139 
4140  return 0;
4141 }
4142 
4143 /*! \brief Get hint for channel */
4144 int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
4145 {
4146  struct ast_exten *e = ast_hint_extension(c, context, exten);
4147 
4148  if (e) {
4149  if (hint)
4150  ast_copy_string(hint, ast_get_extension_app(e), hintsize);
4151  if (name) {
4152  const char *tmp = ast_get_extension_app_data(e);
4153  if (tmp)
4154  ast_copy_string(name, tmp, namesize);
4155  }
4156  return -1;
4157  }
4158  return 0;
4159 }
4160 
4161 /*! \brief Get hint for channel */
4162 int ast_str_get_hint(struct ast_str **hint, ssize_t hintsize, struct ast_str **name, ssize_t namesize, struct ast_channel *c, const char *context, const char *exten)
4163 {
4164  struct ast_exten *e = ast_hint_extension(c, context, exten);
4165 
4166  if (!e) {
4167  return 0;
4168  }
4169 
4170  if (hint) {
4171  ast_str_set(hint, hintsize, "%s", ast_get_extension_app(e));
4172  }
4173  if (name) {
4174  const char *tmp = ast_get_extension_app_data(e);
4175  if (tmp) {
4176  ast_str_set(name, namesize, "%s", tmp);
4177  }
4178  }
4179  return -1;
4180 }
4181 
4182 int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
4183 {
4184  return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0, 0);
4185 }
4186 
4187 int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
4188 {
4189  return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
4190 }
4191 
4192 int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
4193 {
4194  return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
4195 }
4196 
4197 int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
4198 {
4199  return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0, 0);
4200 }
4201 
4202 int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
4203 {
4204  return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0);
4205 }
4206 
4207 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)
4208 {
4209  return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn);
4210 }
4211 
4212 void ast_pbx_h_exten_run(struct ast_channel *chan, const char *context)
4213 {
4214  int autoloopflag;
4215  int found;
4216  int spawn_error;
4217 
4218  ast_channel_lock(chan);
4219 
4220  /*
4221  * Make sure that the channel is marked as hungup since we are
4222  * going to run the h exten on it.
4223  */
4225 
4226  /* Set h exten location */
4227  if (context != ast_channel_context(chan)) {
4229  }
4230  ast_channel_exten_set(chan, "h");
4231  ast_channel_priority_set(chan, 1);
4232 
4233  /* Save autoloop flag */
4234  autoloopflag = ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP);
4236  ast_channel_unlock(chan);
4237 
4238  for (;;) {
4239  spawn_error = ast_spawn_extension(chan, ast_channel_context(chan),
4241  S_COR(ast_channel_caller(chan)->id.number.valid,
4242  ast_channel_caller(chan)->id.number.str, NULL), &found, 1);
4243 
4244  ast_channel_lock(chan);
4245  if (spawn_error) {
4246  /* The code after the loop needs the channel locked. */
4247  break;
4248  }
4250  ast_channel_unlock(chan);
4251  }
4252  if (found && spawn_error) {
4253  /* Something bad happened, or a hangup has been requested. */
4254  ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n",
4256  ast_channel_priority(chan), ast_channel_name(chan));
4257  ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n",
4259  ast_channel_priority(chan), ast_channel_name(chan));
4260  }
4261 
4262  /* An "h" exten has been run, so indicate that one has been run. */
4264 
4265  /* Restore autoloop flag */
4267  ast_channel_unlock(chan);
4268 }
4269 
4270 /*! helper function to set extension and priority */
4271 void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
4272 {
4277 }
4278 
4279 /*!
4280  * \brief collect digits from the channel into the buffer.
4281  * \param c, buf, buflen, pos
4282  * \param waittime is in milliseconds
4283  * \retval 0 on timeout or done.
4284  * \retval -1 on error.
4285 */
4286 static int collect_digits(struct ast_channel *c, int waittime, char *buf, int buflen, int pos)
4287 {
4288  int digit;
4289 
4290  buf[pos] = '\0'; /* make sure it is properly terminated */
4292  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4293  /* As long as we're willing to wait, and as long as it's not defined,
4294  keep reading digits until we can't possibly get a right answer anymore. */
4295  digit = ast_waitfordigit(c, waittime);
4298  } else {
4299  if (!digit) /* No entry */
4300  break;
4301  if (digit < 0) /* Error, maybe a hangup */
4302  return -1;
4303  if (pos < buflen - 1) { /* XXX maybe error otherwise ? */
4304  buf[pos++] = digit;
4305  buf[pos] = '\0';
4306  }
4307  waittime = ast_channel_pbx(c)->dtimeoutms;
4308  }
4309  }
4310  return 0;
4311 }
4312 
4313 static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
4314  struct ast_pbx_args *args)
4315 {
4316  int found = 0; /* set if we find at least one match */
4317  int res = 0;
4318  int autoloopflag;
4319  int error = 0; /* set an error conditions */
4320  struct ast_pbx *pbx;
4321  ast_callid callid;
4322 
4323  /* A little initial setup here */
4324  if (ast_channel_pbx(c)) {
4325  ast_log(LOG_WARNING, "%s already has PBX structure??\n", ast_channel_name(c));
4326  /* XXX and now what ? */
4328  }
4329  if (!(pbx = ast_calloc(1, sizeof(*pbx)))) {
4330  return AST_PBX_FAILED;
4331  }
4332 
4333  callid = ast_read_threadstorage_callid();
4334  /* If the thread isn't already associated with a callid, we should create that association. */
4335  if (!callid) {
4336  /* Associate new PBX thread with the channel call id if it is availble.
4337  * If not, create a new one instead.
4338  */
4339  callid = ast_channel_callid(c);
4340  if (!callid) {
4341  callid = ast_create_callid();
4342  if (callid) {
4344  ast_channel_callid_set(c, callid);
4346  }
4347  }
4349  callid = 0;
4350  }
4351 
4352  ast_channel_pbx_set(c, pbx);
4353  /* Set reasonable defaults */
4354  ast_channel_pbx(c)->rtimeoutms = 10000;
4355  ast_channel_pbx(c)->dtimeoutms = 5000;
4356 
4358  autoloopflag = ast_test_flag(ast_channel_flags(c), AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */
4361 
4363  /* If not successful fall back to 's' - but only if there is no given exten */
4364  ast_verb(2, "Starting %s at %s,%s,%d failed so falling back to exten 's'\n", ast_channel_name(c), ast_channel_context(c), ast_channel_exten(c), ast_channel_priority(c));
4365  /* XXX the original code used the existing priority in the call to
4366  * ast_exists_extension(), and reset it to 1 afterwards.
4367  * I believe the correct thing is to set it to 1 immediately.
4368  */
4369  set_ext_pri(c, "s", 1);
4370  }
4371 
4372  for (;;) {
4373  char dst_exten[256]; /* buffer to accumulate digits */
4374  int pos = 0; /* XXX should check bounds */
4375  int digit = 0;
4376  int invalid = 0;
4377  int timeout = 0;
4378 
4379  /* No digits pressed yet */
4380  dst_exten[pos] = '\0';
4381 
4382  /* loop on priorities in this context/exten */
4385  &found, 1))) {
4386 
4387  if (!ast_check_hangup(c)) {
4389  continue;
4390  }
4391 
4392  /* Check softhangup flags. */
4395  continue;
4396  }
4399  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4400  set_ext_pri(c, "T", 1);
4401  /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
4402  memset(ast_channel_whentohangup(c), 0, sizeof(*ast_channel_whentohangup(c)));
4404  continue;
4405  } else if (ast_exists_extension(c, ast_channel_context(c), "e", 1,
4406  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4407  raise_exception(c, "ABSOLUTETIMEOUT", 1);
4408  /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
4409  memset(ast_channel_whentohangup(c), 0, sizeof(*ast_channel_whentohangup(c)));
4411  continue;
4412  }
4413 
4414  /* Call timed out with no special extension to jump to. */
4415  error = 1;
4416  break;
4417  }
4418  ast_debug(1, "Extension %s, priority %d returned normally even though call was hung up\n",
4420  error = 1;
4421  break;
4422  } /* end while - from here on we can use 'break' to go out */
4423  if (found && res) {
4424  /* Something bad happened, or a hangup has been requested. */
4425  if (strchr("0123456789ABCDEF*#", res)) {
4426  ast_debug(1, "Oooh, got something to jump out with ('%c')!\n", res);
4427  pos = 0;
4428  dst_exten[pos++] = digit = res;
4429  dst_exten[pos] = '\0';
4430  } else if (res == AST_PBX_INCOMPLETE) {
4431  ast_debug(1, "Spawn extension (%s,%s,%d) exited INCOMPLETE on '%s'\n", ast_channel_context(c), ast_channel_exten(c), ast_channel_priority(c), ast_channel_name(c));
4432  ast_verb(2, "Spawn extension (%s, %s, %d) exited INCOMPLETE on '%s'\n", ast_channel_context(c), ast_channel_exten(c), ast_channel_priority(c), ast_channel_name(c));
4433 
4434  /* Don't cycle on incomplete - this will happen if the only extension that matches is our "incomplete" extension */
4436  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4437  invalid = 1;
4438  } else {
4439  ast_copy_string(dst_exten, ast_channel_exten(c), sizeof(dst_exten));
4440  digit = 1;
4441  pos = strlen(dst_exten);
4442  }
4443  } else {
4444  ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", ast_channel_context(c), ast_channel_exten(c), ast_channel_priority(c), ast_channel_name(c));
4445  ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", ast_channel_context(c), ast_channel_exten(c), ast_channel_priority(c), ast_channel_name(c));
4446 
4447  if ((res == AST_PBX_ERROR)
4449  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4450  /* if we are already on the 'e' exten, don't jump to it again */
4451  if (!strcmp(ast_channel_exten(c), "e")) {
4452  ast_verb(2, "Spawn extension (%s, %s, %d) exited ERROR while already on 'e' exten on '%s'\n", ast_channel_context(c), ast_channel_exten(c), ast_channel_priority(c), ast_channel_name(c));
4453  error = 1;
4454  } else {
4455  raise_exception(c, "ERROR", 1);
4456  continue;
4457  }
4458  }
4459 
4462  continue;
4463  }
4466  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4467  set_ext_pri(c, "T", 1);
4468  /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
4469  memset(ast_channel_whentohangup(c), 0, sizeof(*ast_channel_whentohangup(c)));
4471  continue;
4472  } else if (ast_exists_extension(c, ast_channel_context(c), "e", 1,
4473  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4474  raise_exception(c, "ABSOLUTETIMEOUT", 1);
4475  /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
4476  memset(ast_channel_whentohangup(c), 0, sizeof(*ast_channel_whentohangup(c)));
4478  continue;
4479  }
4480  /* Call timed out with no special extension to jump to. */
4481  }
4482  error = 1;
4483  break;
4484  }
4485  }
4486  if (error)
4487  break;
4488 
4489  /*!\note
4490  * We get here on a failure of some kind: non-existing extension or
4491  * hangup. We have options, here. We can either catch the failure
4492  * and continue, or we can drop out entirely. */
4493 
4494  if (invalid
4495  || (ast_strlen_zero(dst_exten) &&
4497  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL)))) {
4498  /*!\note
4499  * If there is no match at priority 1, it is not a valid extension anymore.
4500  * Try to continue at "i" (for invalid) or "e" (for exception) or exit if
4501  * neither exist.
4502  */
4504  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4505  ast_verb(3, "Channel '%s' sent to invalid extension: context,exten,priority=%s,%s,%d\n",
4507  pbx_builtin_setvar_helper(c, "INVALID_EXTEN", ast_channel_exten(c));
4508  set_ext_pri(c, "i", 1);
4509  } else if (ast_exists_extension(c, ast_channel_context(c), "e", 1,
4510  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4511  raise_exception(c, "INVALID", 1);
4512  } else {
4513  ast_log(LOG_WARNING, "Channel '%s' sent to invalid extension but no invalid handler: context,exten,priority=%s,%s,%d\n",
4515  error = 1; /* we know what to do with it */
4516  break;
4517  }
4519  /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */
4521  } else { /* keypress received, get more digits for a full extension */
4522  int waittime = 0;
4523  if (digit)
4524  waittime = ast_channel_pbx(c)->dtimeoutms;
4525  else if (!autofallthrough)
4526  waittime = ast_channel_pbx(c)->rtimeoutms;
4527  if (!waittime) {
4528  const char *status = pbx_builtin_getvar_helper(c, "DIALSTATUS");
4529  if (!status)
4530  status = "UNKNOWN";
4531  ast_verb(3, "Auto fallthrough, channel '%s' status is '%s'\n", ast_channel_name(c), status);
4532  if (!strcasecmp(status, "CONGESTION"))
4533  res = indicate_congestion(c, "10");
4534  else if (!strcasecmp(status, "CHANUNAVAIL"))
4535  res = indicate_congestion(c, "10");
4536  else if (!strcasecmp(status, "BUSY"))
4537  res = indicate_busy(c, "10");
4538  error = 1; /* XXX disable message */
4539  break; /* exit from the 'for' loop */
4540  }
4541 
4542  if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos))
4543  break;
4544  if (res == AST_PBX_INCOMPLETE && ast_strlen_zero(&dst_exten[pos]))
4545  timeout = 1;
4546  if (!timeout
4547  && ast_exists_extension(c, ast_channel_context(c), dst_exten, 1,
4548  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) { /* Prepare the next cycle */
4549  set_ext_pri(c, dst_exten, 1);
4550  } else {
4551  /* No such extension */
4552  if (!timeout && !ast_strlen_zero(dst_exten)) {
4553  /* An invalid extension */
4555  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4556  ast_verb(3, "Invalid extension '%s' in context '%s' on %s\n", dst_exten, ast_channel_context(c), ast_channel_name(c));
4557  pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten);
4558  set_ext_pri(c, "i", 1);
4559  } else if (ast_exists_extension(c, ast_channel_context(c), "e", 1,
4560  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4561  raise_exception(c, "INVALID", 1);
4562  } else {
4564  "Invalid extension '%s', but no rule 'i' or 'e' in context '%s'\n",
4565  dst_exten, ast_channel_context(c));
4566  found = 1; /* XXX disable message */
4567  break;
4568  }
4569  } else {
4570  /* A simple timeout */
4572  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4573  ast_verb(3, "Timeout on %s\n", ast_channel_name(c));
4574  set_ext_pri(c, "t", 1);
4575  } else if (ast_exists_extension(c, ast_channel_context(c), "e", 1,
4576  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4577  raise_exception(c, "RESPONSETIMEOUT", 1);
4578  } else {
4580  "Timeout, but no rule 't' or 'e' in context '%s'\n",
4582  found = 1; /* XXX disable message */
4583  break;
4584  }
4585  }
4586  }
4587  }
4588  }
4589 
4590  if (!found && !error) {
4591  ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", ast_channel_name(c));
4592  }
4593 
4594  if (!args || !args->no_hangup_chan) {
4598  S_COR(ast_channel_caller(c)->id.number.valid,
4599  ast_channel_caller(c)->id.number.str, NULL))) {
4601  }
4603  }
4604 
4607  ast_clear_flag(ast_channel_flags(c), AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */
4611 
4612  if (!args || !args->no_hangup_chan) {
4613  ast_hangup(c);
4614  }
4615 
4616  return AST_PBX_SUCCESS;
4617 }
4618 
4619 /*!
4620  * \brief Increase call count for channel
4621  * \retval 0 on success
4622  * \retval non-zero if a configured limit (maxcalls, maxload, minmemfree) was reached
4623 */
4624 static int increase_call_count(const struct ast_channel *c)
4625 {
4626  int failed = 0;
4627  double curloadavg;
4628 #if defined(HAVE_SYSINFO)
4629  struct sysinfo sys_info;
4630 #endif
4631 
4633  if (ast_option_maxcalls) {
4635  ast_log(LOG_WARNING, "Maximum call limit of %d calls exceeded by '%s'!\n", ast_option_maxcalls, ast_channel_name(c));
4636  failed = -1;
4637  }
4638  }
4639  if (ast_option_maxload) {
4640  getloadavg(&curloadavg, 1);
4641  if (curloadavg >= ast_option_maxload) {
4642  ast_log(LOG_WARNING, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", ast_option_maxload, ast_channel_name(c), curloadavg);
4643  failed = -1;
4644  }
4645  }
4646 #if defined(HAVE_SYSINFO)
4647  if (option_minmemfree) {
4648  /* Make sure that the free system memory is above the configured low watermark */
4649  if (!sysinfo(&sys_info)) {
4650  /* Convert the amount of available RAM from mem_units to MB. The calculation
4651  * was done this way to avoid overflow problems */
4652  uint64_t curfreemem = sys_info.freeram + sys_info.bufferram;
4653  curfreemem *= sys_info.mem_unit;
4654  curfreemem /= 1024 * 1024;
4655  if (curfreemem < option_minmemfree) {
4656  ast_log(LOG_WARNING, "Available system memory (~%" PRIu64 "MB) is below the configured low watermark (%ldMB)\n",
4657  curfreemem, option_minmemfree);
4658  failed = -1;
4659  }
4660  }
4661  }
4662 #endif
4663 
4664  if (!failed) {
4665  countcalls++;
4666  totalcalls++;
4667  }
4669 
4670  return failed;
4671 }
4672 
4673 static void decrease_call_count(void)
4674 {
4676  if (countcalls > 0)
4677  countcalls--;
4679 }
4680 
4681 static void destroy_exten(struct ast_exten *e)
4682 {
4683  if (e->priority == PRIORITY_HINT)
4684  ast_remove_hint(e);
4685 
4686  if (e->peer_table)
4688  if (e->peer_label_table)
4690  if (e->datad)
4691  e->datad(e->data);
4692  ast_free(e);
4693 }
4694 
4695 static void *pbx_thread(void *data)
4696 {
4697  /* Oh joyous kernel, we're a new thread, with nothing to do but
4698  answer this channel and get it going.
4699  */
4700  /* NOTE:
4701  The launcher of this function _MUST_ increment 'countcalls'
4702  before invoking the function; it will be decremented when the
4703  PBX has finished running on the channel
4704  */
4705  struct ast_channel *c = data;
4706 
4707  __ast_pbx_run(c, NULL);
4709 
4710  pthread_exit(NULL);
4711 
4712  return NULL;
4713 }
4714 
4716 {
4717  pthread_t t;
4718 
4719  if (!c) {
4720  ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
4721  return AST_PBX_FAILED;
4722  }
4723 
4725  ast_log(LOG_WARNING, "PBX requires Asterisk to be fully booted\n");
4726  return AST_PBX_FAILED;
4727  }
4728 
4729