Sat Nov 1 06:28:34 2008

Asterisk developer's documentation


pbx.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Core PBX routines.
00022  *
00023  * \author Mark Spencer <markster@digium.com>
00024  */
00025 
00026 #include "asterisk.h"
00027 
00028 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 144758 $")
00029 
00030 #include <sys/types.h>
00031 #include <string.h>
00032 #include <unistd.h>
00033 #include <stdlib.h>
00034 #include <stdio.h>
00035 #include <ctype.h>
00036 #include <errno.h>
00037 #include <time.h>
00038 #include <sys/time.h>
00039 #include <limits.h>
00040 
00041 #include "asterisk/lock.h"
00042 #include "asterisk/cli.h"
00043 #include "asterisk/pbx.h"
00044 #include "asterisk/channel.h"
00045 #include "asterisk/options.h"
00046 #include "asterisk/logger.h"
00047 #include "asterisk/file.h"
00048 #include "asterisk/callerid.h"
00049 #include "asterisk/cdr.h"
00050 #include "asterisk/config.h"
00051 #include "asterisk/term.h"
00052 #include "asterisk/manager.h"
00053 #include "asterisk/ast_expr.h"
00054 #include "asterisk/linkedlists.h"
00055 #define  SAY_STUBS   /* generate declarations and stubs for say methods */
00056 #include "asterisk/say.h"
00057 #include "asterisk/utils.h"
00058 #include "asterisk/causes.h"
00059 #include "asterisk/musiconhold.h"
00060 #include "asterisk/app.h"
00061 #include "asterisk/devicestate.h"
00062 #include "asterisk/stringfields.h"
00063 #include "asterisk/threadstorage.h"
00064 
00065 /*!
00066  * \note I M P O R T A N T :
00067  *
00068  *    The speed of extension handling will likely be among the most important
00069  * aspects of this PBX.  The switching scheme as it exists right now isn't
00070  * terribly bad (it's O(N+M), where N is the # of extensions and M is the avg #
00071  * of priorities, but a constant search time here would be great ;-)
00072  *
00073  */
00074 
00075 #ifdef LOW_MEMORY
00076 #define EXT_DATA_SIZE 256
00077 #else
00078 #define EXT_DATA_SIZE 8192
00079 #endif
00080 
00081 #define SWITCH_DATA_LENGTH 256
00082 
00083 #define VAR_BUF_SIZE 4096
00084 
00085 #define  VAR_NORMAL     1
00086 #define  VAR_SOFTTRAN   2
00087 #define  VAR_HARDTRAN   3
00088 
00089 #define BACKGROUND_SKIP    (1 << 0)
00090 #define BACKGROUND_NOANSWER   (1 << 1)
00091 #define BACKGROUND_MATCHEXTEN (1 << 2)
00092 #define BACKGROUND_PLAYBACK   (1 << 3)
00093 
00094 AST_APP_OPTIONS(background_opts, {
00095    AST_APP_OPTION('s', BACKGROUND_SKIP),
00096    AST_APP_OPTION('n', BACKGROUND_NOANSWER),
00097    AST_APP_OPTION('m', BACKGROUND_MATCHEXTEN),
00098    AST_APP_OPTION('p', BACKGROUND_PLAYBACK),
00099 });
00100 
00101 #define WAITEXTEN_MOH      (1 << 0)
00102 
00103 AST_APP_OPTIONS(waitexten_opts, {
00104    AST_APP_OPTION_ARG('m', WAITEXTEN_MOH, 0),
00105 });
00106 
00107 struct ast_context;
00108 
00109 AST_THREADSTORAGE(switch_data, switch_data_init);
00110 
00111 /*!
00112    \brief ast_exten: An extension
00113    The dialplan is saved as a linked list with each context
00114    having it's own linked list of extensions - one item per
00115    priority.
00116 */
00117 struct ast_exten {
00118    char *exten;         /*!< Extension name */
00119    int matchcid;        /*!< Match caller id ? */
00120    const char *cidmatch;      /*!< Caller id to match for this extension */
00121    int priority;        /*!< Priority */
00122    const char *label;      /*!< Label */
00123    struct ast_context *parent;   /*!< The context this extension belongs to  */
00124    const char *app;     /*!< Application to execute */
00125    void *data;       /*!< Data to use (arguments) */
00126    void (*datad)(void *);     /*!< Data destructor */
00127    struct ast_exten *peer;    /*!< Next higher priority with our extension */
00128    const char *registrar;     /*!< Registrar */
00129    struct ast_exten *next;    /*!< Extension with a greater ID */
00130    char stuff[0];
00131 };
00132 
00133 /*! \brief ast_include: include= support in extensions.conf */
00134 struct ast_include {
00135    const char *name;
00136    const char *rname;         /*!< Context to include */
00137    const char *registrar;        /*!< Registrar */
00138    int hastime;            /*!< If time construct exists */
00139    struct ast_timing timing;               /*!< time construct */
00140    struct ast_include *next;     /*!< Link them together */
00141    char stuff[0];
00142 };
00143 
00144 /*! \brief ast_sw: Switch statement in extensions.conf */
00145 struct ast_sw {
00146    char *name;
00147    const char *registrar;        /*!< Registrar */
00148    char *data;          /*!< Data load */
00149    int eval;
00150    AST_LIST_ENTRY(ast_sw) list;
00151    char stuff[0];
00152 };
00153 
00154 /*! \brief ast_ignorepat: Ignore patterns in dial plan */
00155 struct ast_ignorepat {
00156    const char *registrar;
00157    struct ast_ignorepat *next;
00158    const char pattern[0];
00159 };
00160 
00161 /*! \brief ast_context: An extension context */
00162 struct ast_context {
00163    ast_mutex_t lock;          /*!< A lock to prevent multiple threads from clobbering the context */
00164    struct ast_exten *root;       /*!< The root of the list of extensions */
00165    struct ast_context *next;     /*!< Link them together */
00166    struct ast_include *includes;    /*!< Include other contexts */
00167    struct ast_ignorepat *ignorepats;   /*!< Patterns for which to continue playing dialtone */
00168    const char *registrar;        /*!< Registrar */
00169    AST_LIST_HEAD_NOLOCK(, ast_sw) alts;   /*!< Alternative switches */
00170    ast_mutex_t macrolock;        /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
00171    char name[0];           /*!< Name of the context */
00172 };
00173 
00174 
00175 /*! \brief ast_app: A registered application */
00176 struct ast_app {
00177    int (*execute)(struct ast_channel *chan, void *data);
00178    const char *synopsis;         /*!< Synopsis text for 'show applications' */
00179    const char *description;      /*!< Description (help text) for 'show application &lt;name&gt;' */
00180    AST_LIST_ENTRY(ast_app) list;    /*!< Next app in list */
00181    struct module *module;        /*!< Module this app belongs to */
00182    char name[0];           /*!< Name of the application */
00183 };
00184 
00185 /*! \brief ast_state_cb: An extension state notify register item */
00186 struct ast_state_cb {
00187    int id;
00188    void *data;
00189    ast_state_cb_type callback;
00190    struct ast_state_cb *next;
00191 };
00192 
00193 /*! \brief Structure for dial plan hints
00194 
00195   \note Hints are pointers from an extension in the dialplan to one or
00196   more devices (tech/name) */
00197 struct ast_hint {
00198    struct ast_exten *exten;   /*!< Extension */
00199    int laststate;          /*!< Last known state */
00200    struct ast_state_cb *callbacks;  /*!< Callback list for this extension */
00201    AST_LIST_ENTRY(ast_hint) list;   /*!< Pointer to next hint in list */
00202 };
00203 
00204 static const struct cfextension_states {
00205    int extension_state;
00206    const char * const text;
00207 } extension_states[] = {
00208    { AST_EXTENSION_NOT_INUSE,                     "Idle" },
00209    { AST_EXTENSION_INUSE,                         "InUse" },
00210    { AST_EXTENSION_BUSY,                          "Busy" },
00211    { AST_EXTENSION_UNAVAILABLE,                   "Unavailable" },
00212    { AST_EXTENSION_RINGING,                       "Ringing" },
00213    { AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" },
00214    { AST_EXTENSION_ONHOLD,                        "Hold" },
00215    { AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD,  "InUse&Hold" }
00216 };
00217 
00218 static int pbx_builtin_answer(struct ast_channel *, void *);
00219 static int pbx_builtin_goto(struct ast_channel *, void *);
00220 static int pbx_builtin_hangup(struct ast_channel *, void *);
00221 static int pbx_builtin_background(struct ast_channel *, void *);
00222 static int pbx_builtin_wait(struct ast_channel *, void *);
00223 static int pbx_builtin_waitexten(struct ast_channel *, void *);
00224 static int pbx_builtin_resetcdr(struct ast_channel *, void *);
00225 static int pbx_builtin_setamaflags(struct ast_channel *, void *);
00226 static int pbx_builtin_ringing(struct ast_channel *, void *);
00227 static int pbx_builtin_progress(struct ast_channel *, void *);
00228 static int pbx_builtin_congestion(struct ast_channel *, void *);
00229 static int pbx_builtin_busy(struct ast_channel *, void *);
00230 static int pbx_builtin_setglobalvar(struct ast_channel *, void *);
00231 static int pbx_builtin_noop(struct ast_channel *, void *);
00232 static int pbx_builtin_gotoif(struct ast_channel *, void *);
00233 static int pbx_builtin_gotoiftime(struct ast_channel *, void *);
00234 static int pbx_builtin_execiftime(struct ast_channel *, void *);
00235 static int pbx_builtin_saynumber(struct ast_channel *, void *);
00236 static int pbx_builtin_saydigits(struct ast_channel *, void *);
00237 static int pbx_builtin_saycharacters(struct ast_channel *, void *);
00238 static int pbx_builtin_sayphonetic(struct ast_channel *, void *);
00239 int pbx_builtin_setvar(struct ast_channel *, void *);
00240 static int pbx_builtin_importvar(struct ast_channel *, void *);
00241 
00242 AST_MUTEX_DEFINE_STATIC(globalslock);
00243 static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
00244 
00245 static int autofallthrough = 1;
00246 
00247 AST_MUTEX_DEFINE_STATIC(maxcalllock);
00248 static int countcalls;
00249 
00250 static AST_LIST_HEAD_STATIC(acf_root, ast_custom_function);
00251 
00252 /*! \brief Declaration of builtin applications */
00253 static struct pbx_builtin {
00254    char name[AST_MAX_APP];
00255    int (*execute)(struct ast_channel *chan, void *data);
00256    char *synopsis;
00257    char *description;
00258 } builtins[] =
00259 {
00260    /* These applications are built into the PBX core and do not
00261       need separate modules */
00262 
00263    { "Answer", pbx_builtin_answer,
00264    "Answer a channel if ringing",
00265    "  Answer([delay]): If the call has not been answered, this application will\n"
00266    "answer it. Otherwise, it has no effect on the call. If a delay is specified,\n"
00267    "Asterisk will wait this number of milliseconds before returning to\n"
00268    "the dialplan after answering the call.\n"
00269    },
00270 
00271    { "BackGround", pbx_builtin_background,
00272    "Play an audio file while waiting for digits of an extension to go to.",
00273    "  Background(filename1[&filename2...][|options[|langoverride][|context]]):\n"
00274    "This application will play the given list of files (do not put extension)\n"
00275    "while waiting for an extension to be dialed by the calling channel. To\n"
00276    "continue waiting for digits after this application has finished playing\n"
00277    "files, the WaitExten application should be used. The 'langoverride' option\n"
00278    "explicitly specifies which language to attempt to use for the requested sound\n"
00279    "files. If a 'context' is specified, this is the dialplan context that this\n"
00280    "application will use when exiting to a dialed extension."
00281    "  If one of the requested sound files does not exist, call processing will be\n"
00282    "terminated.\n"
00283    "  Options:\n"
00284    "    s - Causes the playback of the message to be skipped\n"
00285    "          if the channel is not in the 'up' state (i.e. it\n"
00286    "          hasn't been answered yet). If this happens, the\n"
00287    "          application will return immediately.\n"
00288    "    n - Don't answer the channel before playing the files.\n"
00289    "    m - Only break if a digit hit matches a one digit\n"
00290    "          extension in the destination context.\n"
00291    "See Also: Playback (application) -- Play sound file(s) to the channel,\n"
00292     "                                    that cannot be interrupted\n"
00293    },
00294 
00295    { "Busy", pbx_builtin_busy,
00296    "Indicate the Busy condition",
00297    "  Busy([timeout]): This application will indicate the busy condition to\n"
00298    "the calling channel. If the optional timeout is specified, the calling channel\n"
00299    "will be hung up after the specified number of seconds. Otherwise, this\n"
00300    "application will wait until the calling channel hangs up.\n"
00301    },
00302 
00303    { "Congestion", pbx_builtin_congestion,
00304    "Indicate the Congestion condition",
00305    "  Congestion([timeout]): This application will indicate the congestion\n"
00306    "condition to the calling channel. If the optional timeout is specified, the\n"
00307    "calling channel will be hung up after the specified number of seconds.\n"
00308    "Otherwise, this application will wait until the calling channel hangs up.\n"
00309    },
00310 
00311    { "Goto", pbx_builtin_goto,
00312    "Jump to a particular priority, extension, or context",
00313    "  Goto([[context|]extension|]priority): This application will set the current\n"
00314    "context, extension, and priority in the channel structure. After it completes, the\n"
00315    "pbx engine will continue dialplan execution at the specified location.\n"
00316    "If no specific extension, or extension and context, are specified, then this\n"
00317    "application will just set the specified priority of the current extension.\n"
00318    "  At least a priority is required as an argument, or the goto will return a -1,\n"
00319    "and the channel and call will be terminated.\n"
00320    "  If the location that is put into the channel information is bogus, and asterisk cannot\n"
00321         "find that location in the dialplan,\n"
00322    "then the execution engine will try to find and execute the code in the 'i' (invalid)\n"
00323    "extension in the current context. If that does not exist, it will try to execute the\n"
00324    "'h' extension. If either or neither the 'h' or 'i' extensions have been defined, the\n"
00325    "channel is hung up, and the execution of instructions on the channel is terminated.\n"
00326    "What this means is that, for example, you specify a context that does not exist, then\n"
00327    "it will not be possible to find the 'h' or 'i' extensions, and the call will terminate!\n"
00328    },
00329 
00330    { "GotoIf", pbx_builtin_gotoif,
00331    "Conditional goto",
00332    "  GotoIf(condition?[labeliftrue]:[labeliffalse]): This application will set the current\n"
00333    "context, extension, and priority in the channel structure based on the evaluation of\n"
00334    "the given condition. After this application completes, the\n"
00335    "pbx engine will continue dialplan execution at the specified location in the dialplan.\n"
00336    "The channel will continue at\n"
00337    "'labeliftrue' if the condition is true, or 'labeliffalse' if the condition is\n"
00338    "false. The labels are specified with the same syntax as used within the Goto\n"
00339    "application.  If the label chosen by the condition is omitted, no jump is\n"
00340    "performed, and the execution passes to the next instruction.\n"
00341    "If the target location is bogus, and does not exist, the execution engine will try \n"
00342    "to find and execute the code in the 'i' (invalid)\n"
00343    "extension in the current context. If that does not exist, it will try to execute the\n"
00344    "'h' extension. If either or neither the 'h' or 'i' extensions have been defined, the\n"
00345    "channel is hung up, and the execution of instructions on the channel is terminated.\n"
00346    "Remember that this command can set the current context, and if the context specified\n"
00347    "does not exist, then it will not be able to find any 'h' or 'i' extensions there, and\n"
00348    "the channel and call will both be terminated!\n"
00349    },
00350 
00351    { "GotoIfTime", pbx_builtin_gotoiftime,
00352    "Conditional Goto based on the current time",
00353    "  GotoIfTime(<times>|<weekdays>|<mdays>|<months>?[[context|]exten|]priority):\n"
00354    "This application will set the context, extension, and priority in the channel structure\n"
00355    "if the current time matches the given time specification. Otherwise, nothing is done.\n"
00356         "Further information on the time specification can be found in examples\n"
00357         "illustrating how to do time-based context includes in the dialplan.\n" 
00358    "If the target jump location is bogus, the same actions would be taken as for Goto.\n"
00359    },
00360 
00361    { "ExecIfTime", pbx_builtin_execiftime,
00362    "Conditional application execution based on the current time",
00363    "  ExecIfTime(<times>|<weekdays>|<mdays>|<months>?appname[|appargs]):\n"
00364    "This application will execute the specified dialplan application, with optional\n"
00365    "arguments, if the current time matches the given time specification.\n"
00366    },
00367 
00368    { "Hangup", pbx_builtin_hangup,
00369    "Hang up the calling channel",
00370    "  Hangup([causecode]): This application will hang up the calling channel.\n"
00371    "If a causecode is given the channel's hangup cause will be set to the given\n"
00372    "value.\n"
00373    },
00374 
00375    { "NoOp", pbx_builtin_noop,
00376    "Do Nothing",
00377    "  NoOp(): This applicatiion does nothing. However, it is useful for debugging\n"
00378    "purposes. Any text that is provided as arguments to this application can be\n"
00379    "viewed at the Asterisk CLI. This method can be used to see the evaluations of\n"
00380    "variables or functions without having any effect."
00381    },
00382 
00383    { "Progress", pbx_builtin_progress,
00384    "Indicate progress",
00385    "  Progress(): This application will request that in-band progress information\n"
00386    "be provided to the calling channel.\n"
00387    },
00388 
00389    { "ResetCDR", pbx_builtin_resetcdr,
00390    "Resets the Call Data Record",
00391    "  ResetCDR([options]):  This application causes the Call Data Record to be\n"
00392    "reset.\n"
00393    "  Options:\n"
00394    "    w -- Store the current CDR record before resetting it.\n"
00395    "    a -- Store any stacked records.\n"
00396    "    v -- Save CDR variables.\n"
00397    },
00398 
00399    { "Ringing", pbx_builtin_ringing,
00400    "Indicate ringing tone",
00401    "  Ringing(): This application will request that the channel indicate a ringing\n"
00402    "tone to the user.\n"
00403    },
00404 
00405    { "SayNumber", pbx_builtin_saynumber,
00406    "Say Number",
00407    "  SayNumber(digits[,gender]): This application will play the sounds that\n"
00408    "correspond to the given number. Optionally, a gender may be specified.\n"
00409    "This will use the language that is currently set for the channel. See the\n"
00410    "LANGUAGE function for more information on setting the language for the channel.\n"
00411    },
00412 
00413    { "SayDigits", pbx_builtin_saydigits,
00414    "Say Digits",
00415    "  SayDigits(digits): This application will play the sounds that correspond\n"
00416    "to the digits of the given number. This will use the language that is currently\n"
00417    "set for the channel. See the LANGUAGE function for more information on setting\n"
00418    "the language for the channel.\n"
00419    },
00420 
00421    { "SayAlpha", pbx_builtin_saycharacters,
00422    "Say Alpha",
00423    "  SayAlpha(string): This application will play the sounds that correspond to\n"
00424    "the letters of the given string.\n"
00425    },
00426 
00427    { "SayPhonetic", pbx_builtin_sayphonetic,
00428    "Say Phonetic",
00429    "  SayPhonetic(string): This application will play the sounds from the phonetic\n"
00430    "alphabet that correspond to the letters in the given string.\n"
00431    },
00432 
00433    { "SetAMAFlags", pbx_builtin_setamaflags,
00434    "Set the AMA Flags",
00435    "  SetAMAFlags([flag]): This application will set the channel's AMA Flags for\n"
00436    "  billing purposes.\n"
00437    },
00438 
00439    { "SetGlobalVar", pbx_builtin_setglobalvar,
00440    "Set a global variable to a given value",
00441    "  SetGlobalVar(variable=value): This application sets a given global variable to\n"
00442    "the specified value.\n"
00443    "\n\nThis application is deprecated in favor of Set(GLOBAL(var)=value)\n"
00444    },
00445 
00446    { "Set", pbx_builtin_setvar,
00447    "Set channel variable(s) or function value(s)",
00448    "  Set(name1=value1|name2=value2|..[|options])\n"
00449    "This function can be used to set the value of channel variables or dialplan\n"
00450    "functions. It will accept up to 24 name/value pairs. When setting variables,\n"
00451    "if the variable name is prefixed with _, the variable will be inherited into\n"
00452    "channels created from the current channel. If the variable name is prefixed\n"
00453    "with __, the variable will be inherited into channels created from the current\n"
00454    "channel and all children channels.\n"
00455    "  Options:\n"
00456    "    g - Set variable globally instead of on the channel\n"
00457    "        (applies only to variables, not functions)\n"
00458    "\n\nThe use of Set to set multiple variables at once and the g flag have both\n"
00459    "been deprecated.  Please use multiple Set calls and the GLOBAL() dialplan\n"
00460    "function instead.\n"
00461    },
00462 
00463    { "ImportVar", pbx_builtin_importvar,
00464    "Import a variable from a channel into a new variable",
00465    "  ImportVar(newvar=channelname|variable): This application imports a variable\n"
00466    "from the specified channel (as opposed to the current one) and stores it as\n"
00467    "a variable in the current channel (the channel that is calling this\n"
00468    "application). Variables created by this application have the same inheritance\n"
00469    "properties as those created with the Set application. See the documentation for\n"
00470    "Set for more information.\n"
00471    },
00472 
00473    { "Wait", pbx_builtin_wait,
00474    "Waits for some time",
00475    "  Wait(seconds): This application waits for a specified number of seconds.\n"
00476    "Then, dialplan execution will continue at the next priority.\n"
00477    "  Note that the seconds can be passed with fractions of a second. For example,\n"
00478    "'1.5' will ask the application to wait for 1.5 seconds.\n"
00479    },
00480 
00481    { "WaitExten", pbx_builtin_waitexten,
00482    "Waits for an extension to be entered",
00483    "  WaitExten([seconds][|options]): This application waits for the user to enter\n"
00484    "a new extension for a specified number of seconds.\n"
00485    "  Note that the seconds can be passed with fractions of a second. For example,\n"
00486    "'1.5' will ask the application to wait for 1.5 seconds.\n"
00487    "  Options:\n"
00488    "    m[(x)] - Provide music on hold to the caller while waiting for an extension.\n"
00489    "               Optionally, specify the class for music on hold within parenthesis.\n"
00490    "See Also: Playback(application), Background(application).\n"
00491    },
00492 
00493 };
00494 
00495 static struct ast_context *contexts;
00496 AST_RWLOCK_DEFINE_STATIC(conlock);     /*!< Lock for the ast_context list */
00497 
00498 static AST_LIST_HEAD_STATIC(apps, ast_app);
00499 
00500 static AST_LIST_HEAD_STATIC(switches, ast_switch);
00501 
00502 static int stateid = 1;
00503 /* WARNING:
00504    When holding this list's lock, do _not_ do anything that will cause conlock
00505    to be taken, unless you _already_ hold it. The ast_merge_contexts_and_delete
00506    function will take the locks in conlock/hints order, so any other
00507    paths that require both locks must also take them in that order.
00508 */
00509 static AST_LIST_HEAD_STATIC(hints, ast_hint);
00510 struct ast_state_cb *statecbs;
00511 
00512 /*
00513    \note This function is special. It saves the stack so that no matter
00514    how many times it is called, it returns to the same place */
00515 int pbx_exec(struct ast_channel *c,       /*!< Channel */
00516         struct ast_app *app,     /*!< Application */
00517         void *data)        /*!< Data for execution */
00518 {
00519    int res;
00520 
00521    const char *saved_c_appl;
00522    const char *saved_c_data;
00523 
00524    if (c->cdr && !ast_check_hangup(c))
00525       ast_cdr_setapp(c->cdr, app->name, data);
00526 
00527    /* save channel values */
00528    saved_c_appl= c->appl;
00529    saved_c_data= c->data;
00530 
00531    c->appl = app->name;
00532    c->data = data;
00533    /* XXX remember what to to when we have linked apps to modules */
00534    if (app->module) {
00535       /* XXX LOCAL_USER_ADD(app->module) */
00536    }
00537    res = app->execute(c, S_OR(data, ""));
00538    if (app->module) {
00539       /* XXX LOCAL_USER_REMOVE(app->module) */
00540    }
00541    /* restore channel values */
00542    c->appl = saved_c_appl;
00543    c->data = saved_c_data;
00544    return res;
00545 }
00546 
00547 
00548 /*! Go no deeper than this through includes (not counting loops) */
00549 #define AST_PBX_MAX_STACK  128
00550 
00551 /*! \brief Find application handle in linked list
00552  */
00553 struct ast_app *pbx_findapp(const char *app)
00554 {
00555    struct ast_app *tmp;
00556 
00557    AST_LIST_LOCK(&apps);
00558    AST_LIST_TRAVERSE(&apps, tmp, list) {
00559       if (!strcasecmp(tmp->name, app))
00560          break;
00561    }
00562    AST_LIST_UNLOCK(&apps);
00563 
00564    return tmp;
00565 }
00566 
00567 static struct ast_switch *pbx_findswitch(const char *sw)
00568 {
00569    struct ast_switch *asw;
00570 
00571    AST_LIST_LOCK(&switches);
00572    AST_LIST_TRAVERSE(&switches, asw, list) {
00573       if (!strcasecmp(asw->name, sw))
00574          break;
00575    }
00576    AST_LIST_UNLOCK(&switches);
00577 
00578    return asw;
00579 }
00580 
00581 static inline int include_valid(struct ast_include *i)
00582 {
00583    if (!i->hastime)
00584       return 1;
00585 
00586    return ast_check_timing(&(i->timing));
00587 }
00588 
00589 static void pbx_destroy(struct ast_pbx *p)
00590 {
00591    free(p);
00592 }
00593 
00594 /*
00595  * Special characters used in patterns:
00596  * '_'   underscore is the leading character of a pattern.
00597  *    In other position it is treated as a regular char.
00598  * ' ' '-'  space and '-' are separator and ignored.
00599  * .  one or more of any character. Only allowed at the end of
00600  *    a pattern.
00601  * !  zero or more of anything. Also impacts the result of CANMATCH
00602  *    and MATCHMORE. Only allowed at the end of a pattern.
00603  *    In the core routine, ! causes a match with a return code of 2.
00604  *    In turn, depending on the search mode: (XXX check if it is implemented)
00605  *    - E_MATCH retuns 1 (does match)
00606  *    - E_MATCHMORE returns 0 (no match)
00607  *    - E_CANMATCH returns 1 (does match)
00608  *
00609  * /  should not appear as it is considered the separator of the CID info.
00610  *    XXX at the moment we may stop on this char.
00611  *
00612  * X Z N match ranges 0-9, 1-9, 2-9 respectively.
00613  * [  denotes the start of a set of character. Everything inside
00614  *    is considered literally. We can have ranges a-d and individual
00615  *    characters. A '[' and '-' can be considered literally if they
00616  *    are just before ']'.
00617  *    XXX currently there is no way to specify ']' in a range, nor \ is
00618  *    considered specially.
00619  *
00620  * When we compare a pattern with a specific extension, all characters in the extension
00621  * itself are considered literally with the only exception of '-' which is considered
00622  * as a separator and thus ignored.
00623  * XXX do we want to consider space as a separator as well ?
00624  * XXX do we want to consider the separators in non-patterns as well ?
00625  */
00626 
00627 /*!
00628  * \brief helper functions to sort extensions and patterns in the desired way,
00629  * so that more specific patterns appear first.
00630  *
00631  * ext_cmp1 compares individual characters (or sets of), returning
00632  * an int where bits 0-7 are the ASCII code of the first char in the set,
00633  * while bit 8-15 are the cardinality of the set minus 1.
00634  * This way more specific patterns (smaller cardinality) appear first.
00635  * Wildcards have a special value, so that we can directly compare them to
00636  * sets by subtracting the two values. In particular:
00637  *    0x000xx     one character, xx
00638  *    0x0yyxx     yy character set starting with xx
00639  *    0x10000     '.' (one or more of anything)
00640  *    0x20000     '!' (zero or more of anything)
00641  *    0x30000     NUL (end of string)
00642  *    0x40000     error in set.
00643  * The pointer to the string is advanced according to needs.
00644  * NOTES:
00645  * 1. the empty set is equivalent to NUL.
00646  * 2. given that a full set has always 0 as the first element,
00647  *    we could encode the special cases as 0xffXX where XX
00648  *    is 1, 2, 3, 4 as used above.
00649  */
00650 static int ext_cmp1(const char **p)
00651 {
00652    uint32_t chars[8];
00653    int c, cmin = 0xff, count = 0;
00654    const char *end;
00655 
00656    /* load, sign extend and advance pointer until we find
00657     * a valid character.
00658     */
00659    while ( (c = *(*p)++) && (c == ' ' || c == '-') )
00660       ;  /* ignore some characters */
00661 
00662    /* always return unless we have a set of chars */
00663    switch (c) {
00664    default: /* ordinary character */
00665       return 0x0000 | (c & 0xff);
00666 
00667    case 'N':   /* 2..9 */
00668       return 0x0700 | '2' ;
00669 
00670    case 'X':   /* 0..9 */
00671       return 0x0900 | '0';
00672 
00673    case 'Z':   /* 1..9 */
00674       return 0x0800 | '1';
00675 
00676    case '.':   /* wildcard */
00677       return 0x10000;
00678 
00679    case '!':   /* earlymatch */
00680       return 0x20000;   /* less specific than NULL */
00681 
00682    case '\0':  /* empty string */
00683       *p = NULL;
00684       return 0x30000;
00685 
00686    case '[':   /* pattern */
00687       break;
00688    }
00689    /* locate end of set */
00690    end = strchr(*p, ']');  
00691 
00692    if (end == NULL) {
00693       ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
00694       return 0x40000;   /* XXX make this entry go last... */
00695    }
00696 
00697    bzero(chars, sizeof(chars));  /* clear all chars in the set */
00698    for (; *p < end  ; (*p)++) {
00699       unsigned char c1, c2;   /* first-last char in range */
00700       c1 = (unsigned char)((*p)[0]);
00701       if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */
00702          c2 = (unsigned char)((*p)[2]);
00703          *p += 2; /* skip a total of 3 chars */
00704       } else         /* individual character */
00705          c2 = c1;
00706       if (c1 < cmin)
00707          cmin = c1;
00708       for (; c1 <= c2; c1++) {
00709          uint32_t mask = 1 << (c1 % 32);
00710          if ( (chars[ c1 / 32 ] & mask) == 0)
00711             count += 0x100;
00712          chars[ c1 / 32 ] |= mask;
00713       }
00714    }
00715    (*p)++;
00716    return count == 0 ? 0x30000 : (count | cmin);
00717 }
00718 
00719 /*!
00720  * \brief the full routine to compare extensions in rules.
00721  */
00722 static int ext_cmp(const char *a, const char *b)
00723 {
00724    /* make sure non-patterns come first.
00725     * If a is not a pattern, it either comes first or
00726     * we use strcmp to compare the strings.
00727     */
00728    int ret = 0;
00729 
00730    if (a[0] != '_')
00731       return (b[0] == '_') ? -1 : strcmp(a, b);
00732 
00733    /* Now we know a is a pattern; if b is not, a comes first */
00734    if (b[0] != '_')
00735       return 1;
00736 #if 0 /* old mode for ext matching */
00737    return strcmp(a, b);
00738 #endif
00739    /* ok we need full pattern sorting routine */
00740    while (!ret && a && b)
00741       ret = ext_cmp1(&a) - ext_cmp1(&b);
00742    if (ret == 0)
00743       return 0;
00744    else
00745       return (ret > 0) ? 1 : -1;
00746 }
00747 
00748 /*!
00749  * When looking up extensions, we can have different requests
00750  * identified by the 'action' argument, as follows.
00751  * Note that the coding is such that the low 4 bits are the
00752  * third argument to extension_match_core.
00753  */
00754 enum ext_match_t {
00755    E_MATCHMORE =  0x00, /* extension can match but only with more 'digits' */
00756    E_CANMATCH =   0x01, /* extension can match with or without more 'digits' */
00757    E_MATCH =   0x02, /* extension is an exact match */
00758    E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */
00759    E_SPAWN =   0x12, /* want to spawn an extension. Requires exact match */
00760    E_FINDLABEL =  0x22  /* returns the priority for a given label. Requires exact match */
00761 };
00762 
00763 /*
00764  * Internal function for ast_extension_{match|close}
00765  * return 0 on no-match, 1 on match, 2 on early match.
00766  * mode is as follows:
00767  * E_MATCH     success only on exact match
00768  * E_MATCHMORE success only on partial match (i.e. leftover digits in pattern)
00769  * E_CANMATCH  either of the above.
00770  */
00771 
00772 static int _extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
00773 {
00774    mode &= E_MATCH_MASK;   /* only consider the relevant bits */
00775 
00776    if ( (mode == E_MATCH) && (pattern[0] == '_') && (strcasecmp(pattern,data)==0) ) /* note: if this test is left out, then _x. will not match _x. !!! */
00777       return 1;
00778 
00779    if (pattern[0] != '_') { /* not a pattern, try exact or partial match */
00780       int ld = strlen(data), lp = strlen(pattern);
00781 
00782       if (lp < ld)      /* pattern too short, cannot match */
00783          return 0;
00784       /* depending on the mode, accept full or partial match or both */
00785       if (mode == E_MATCH)
00786          return !strcmp(pattern, data); /* 1 on match, 0 on fail */
00787       if (ld == 0 || !strncasecmp(pattern, data, ld)) /* partial or full match */
00788          return (mode == E_MATCHMORE) ? lp > ld : 1; /* XXX should consider '!' and '/' ? */
00789       else
00790          return 0;
00791    }
00792    pattern++; /* skip leading _ */
00793    /*
00794     * XXX below we stop at '/' which is a separator for the CID info. However we should
00795     * not store '/' in the pattern at all. When we insure it, we can remove the checks.
00796     */
00797    while (*data && *pattern && *pattern != '/') {
00798       const char *end;
00799 
00800       if (*data == '-') { /* skip '-' in data (just a separator) */
00801          data++;
00802          continue;
00803       }
00804       switch (toupper(*pattern)) {
00805       case '[':   /* a range */
00806          end = strchr(pattern+1, ']'); /* XXX should deal with escapes ? */
00807          if (end == NULL) {
00808             ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
00809             return 0;   /* unconditional failure */
00810          }
00811          for (pattern++; pattern != end; pattern++) {
00812             if (pattern+2 < end && pattern[1] == '-') { /* this is a range */
00813                if (*data >= pattern[0] && *data <= pattern[2])
00814                   break;   /* match found */
00815                else {
00816                   pattern += 2; /* skip a total of 3 chars */
00817                   continue;
00818                }
00819             } else if (*data == pattern[0])
00820                break;   /* match found */
00821          }
00822          if (pattern == end)
00823             return 0;
00824          pattern = end; /* skip and continue */
00825          break;
00826       case 'N':
00827          if (*data < '2' || *data > '9')
00828             return 0;
00829          break;
00830       case 'X':
00831          if (*data < '0' || *data > '9')
00832             return 0;
00833          break;
00834       case 'Z':
00835          if (*data < '1' || *data > '9')
00836             return 0;
00837          break;
00838       case '.':   /* Must match, even with more digits */
00839          return 1;
00840       case '!':   /* Early match */
00841          return 2;
00842       case ' ':
00843       case '-':   /* Ignore these in patterns */
00844          data--; /* compensate the final data++ */
00845          break;
00846       default:
00847          if (*data != *pattern)
00848             return 0;
00849       }
00850       data++;
00851       pattern++;
00852    }
00853    if (*data)        /* data longer than pattern, no match */
00854       return 0;
00855    /*
00856     * match so far, but ran off the end of the data.
00857     * Depending on what is next, determine match or not.
00858     */
00859    if (*pattern == '\0' || *pattern == '/')  /* exact match */
00860       return (mode == E_MATCHMORE) ? 0 : 1;  /* this is a failure for E_MATCHMORE */
00861    else if (*pattern == '!')        /* early match */
00862       return 2;
00863    else                 /* partial match */
00864       return (mode == E_MATCH) ? 0 : 1;   /* this is a failure for E_MATCH */
00865 }
00866 
00867 /*
00868  * Wrapper around _extension_match_core() to do performance measurement
00869  * using the profiling code.
00870  */
00871 static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
00872 {
00873    int i;
00874    static int prof_id = -2;   /* marker for 'unallocated' id */
00875    if (prof_id == -2)
00876       prof_id = ast_add_profile("ext_match", 0);
00877    ast_mark(prof_id, 1);
00878    i = _extension_match_core(pattern, data, mode);
00879    ast_mark(prof_id, 0);
00880    return i;
00881 }
00882 
00883 int ast_extension_match(const char *pattern, const char *data)
00884 {
00885    return extension_match_core(pattern, data, E_MATCH);
00886 }
00887 
00888 int ast_extension_close(const char *pattern, const char *data, int needmore)
00889 {
00890    if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
00891       ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
00892    return extension_match_core(pattern, data, needmore);
00893 }
00894 
00895 struct ast_context *ast_context_find(const char *name)
00896 {
00897    struct ast_context *tmp = NULL;
00898 
00899    ast_rdlock_contexts();
00900 
00901    while ( (tmp = ast_walk_contexts(tmp)) ) {
00902       if (!name || !strcasecmp(name, tmp->name))
00903          break;
00904    }
00905 
00906    ast_unlock_contexts();
00907 
00908    return tmp;
00909 }
00910 
00911 #define STATUS_NO_CONTEXT  1
00912 #define STATUS_NO_EXTENSION   2
00913 #define STATUS_NO_PRIORITY 3
00914 #define STATUS_NO_LABEL    4
00915 #define STATUS_SUCCESS     5
00916 
00917 static int matchcid(const char *cidpattern, const char *callerid)
00918 {
00919    /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so
00920       failing to get a number should count as a match, otherwise not */
00921 
00922    if (ast_strlen_zero(callerid))
00923       return ast_strlen_zero(cidpattern) ? 1 : 0;
00924 
00925    return ast_extension_match(cidpattern, callerid);
00926 }
00927 
00928 /* request and result for pbx_find_extension */
00929 struct pbx_find_info {
00930 #if 0
00931    const char *context;
00932    const char *exten;
00933    int priority;
00934 #endif
00935 
00936    char *incstack[AST_PBX_MAX_STACK];      /* filled during the search */
00937    int stacklen;                   /* modified during the search */
00938    int status;                     /* set on return */
00939    struct ast_switch *swo;         /* set on return */
00940    const char *data;               /* set on return */
00941    const char *foundcontext;       /* set on return */
00942 };
00943 
00944 static struct ast_exten *pbx_find_extension(struct ast_channel *chan,
00945    struct ast_context *bypass, struct pbx_find_info *q,
00946    const char *context, const char *exten, int priority,
00947    const char *label, const char *callerid, enum ext_match_t action)
00948 {
00949    int x, res;
00950    struct ast_context *tmp;
00951    struct ast_exten *e, *eroot;
00952    struct ast_include *i;
00953    struct ast_sw *sw;
00954    char *tmpdata = NULL;
00955 
00956    /* Initialize status if appropriate */
00957    if (q->stacklen == 0) {
00958       q->status = STATUS_NO_CONTEXT;
00959       q->swo = NULL;
00960       q->data = NULL;
00961       q->foundcontext = NULL;
00962    }
00963    /* Check for stack overflow */
00964    if (q->stacklen >= AST_PBX_MAX_STACK) {
00965       ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
00966       return NULL;
00967    }
00968    /* Check first to see if we've already been checked */
00969    for (x = 0; x < q->stacklen; x++) {
00970       if (!strcasecmp(q->incstack[x], context))
00971          return NULL;
00972    }
00973    if (bypass) /* bypass means we only look there */
00974       tmp = bypass;
00975    else {   /* look in contexts */
00976       tmp = NULL;
00977       while ((tmp = ast_walk_contexts(tmp)) ) {
00978          if (!strcmp(tmp->name, context))
00979             break;
00980       }
00981       if (!tmp)
00982          return NULL;
00983    }
00984    if (q->status < STATUS_NO_EXTENSION)
00985       q->status = STATUS_NO_EXTENSION;
00986 
00987    /* scan the list trying to match extension and CID */
00988    eroot = NULL;
00989    while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) {
00990       int