Wed Aug 15 01:25:23 2007

Asterisk developer's documentation


pbx.h File Reference

Core PBX routines and definitions. More...

#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/linkedlists.h"

Include dependency graph for pbx.h:

Go to the source code of this file.

Data Structures

struct  ast_custom_function
 Data structure associated with a custom dialplan function. More...
struct  ast_pbx
struct  ast_switch
struct  ast_timing

Defines

#define AST_MAX_APP   32
#define AST_PBX_KEEP   0
#define AST_PBX_KEEPALIVE   10
 Special return values from applications to the PBX {.
#define AST_PBX_NO_HANGUP_PEER   11
#define AST_PBX_REPLACE   1
#define PRIORITY_HINT   -1

Typedefs

typedef int(* ast_state_cb_type )(char *context, char *id, enum ast_extension_states state, void *data)
 Typedef for devicestate and hint callbacks.
typedef int( ast_switch_f )(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 All switch functions have the same interface, so define a type for them.

Enumerations

enum  ast_extension_states {
  AST_EXTENSION_REMOVED = -2, AST_EXTENSION_DEACTIVATED = -1, AST_EXTENSION_NOT_INUSE = 0, AST_EXTENSION_INUSE = 1 << 0,
  AST_EXTENSION_BUSY = 1 << 1, AST_EXTENSION_UNAVAILABLE = 1 << 2, AST_EXTENSION_RINGING = 1 << 3, AST_EXTENSION_ONHOLD = 1 << 4
}
 Extension states. More...
enum  ast_pbx_result { AST_PBX_SUCCESS = 0, AST_PBX_FAILED = -1, AST_PBX_CALL_LIMIT = -2 }

Functions

int ast_active_calls (void)
 Retrieve the number of active calls.
int ast_add_extension (const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 Add and extension to an extension context.
int ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 Add an extension to an extension context, this time with an ast_context *.
int ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_async_goto_by_name (const char *chan, const char *context, const char *exten, int priority)
int ast_async_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_build_timing (struct ast_timing *i, const char *info)
int ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Looks for a valid matching extension.
int ast_check_timing (const struct ast_timing *i)
int ast_context_add_ignorepat (const char *context, const char *ignorepat, const char *registrar)
 Add an ignorepat.
int ast_context_add_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar)
int ast_context_add_include (const char *context, const char *include, const char *registrar)
 Add a context include.
int ast_context_add_include2 (struct ast_context *con, const char *include, const char *registrar)
 Add a context include.
int ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar)
 Add a switch.
int ast_context_add_switch2 (struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar)
 Adds a switch (first param is a ast_context).
struct ast_contextast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar)
 Register a new context.
void ast_context_destroy (struct ast_context *con, const char *registrar)
 Destroy a context (matches the specified context (or ANY context if NULL).
struct ast_contextast_context_find (const char *name)
 Find a context.
struct ast_contextast_context_find_or_create (struct ast_context **extcontexts, const char *name, const char *registrar)
int ast_context_lockmacro (const char *macrocontext)
 locks the macrolock in the given given context
int ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar)
 Simply remove extension from context.
int ast_context_remove_extension2 (struct ast_context *con, const char *extension, int priority, const char *registrar)
 This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return.
int ast_context_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar)
int ast_context_remove_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar)
int ast_context_remove_include (const char *context, const char *include, const char *registrar)
 Remove a context include.
int ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar)
 Removes an include by an ast_context structure.
int ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar)
 Remove a switch.
int ast_context_remove_switch2 (struct ast_context *con, const char *sw, const char *data, const char *registrar)
 This function locks given context, removes switch, unlock context and return.
int ast_context_unlockmacro (const char *macrocontext)
 Unlocks the macrolock in the given context.
int ast_context_verify_includes (struct ast_context *con)
 Verifies includes in an ast_contect structure.
struct
ast_custom_function
ast_custom_function_find (const char *name)
int ast_custom_function_register (struct ast_custom_function *acf)
 Reigster a custom function.
int ast_custom_function_unregister (struct ast_custom_function *acf)
 Unregister a custom function.
int ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Determine whether an extension exists.
int ast_explicit_goto (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_extension_close (const char *pattern, const char *data, int needmore)
int ast_extension_match (const char *pattern, const char *extension)
 Determine if a given extension matches a given pattern (in NXX format).
int ast_extension_patmatch (const char *pattern, const char *data)
int ast_extension_state (struct ast_channel *c, const char *context, const char *exten)
 Uses hint and devicestate callback to get the state of an extension.
const char * ast_extension_state2str (int extension_state)
 Return string representation of the state of an extension.
int ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data)
 Registers a state change callback.
int ast_extension_state_del (int id, ast_state_cb_type callback)
 Deletes a registered state change callback by ID.
int ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
 Find the priority of an extension that has the specified label.
int ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
 Find the priority of an extension that has the specified label.
int ast_func_read (struct ast_channel *chan, char *function, char *workspace, size_t len)
 executes a read operation on a function
int ast_func_write (struct ast_channel *chan, char *function, const char *value)
 executes a write operation on a function
const char * ast_get_context_name (struct ast_context *con)
const char * ast_get_context_registrar (struct ast_context *c)
const char * ast_get_extension_app (struct ast_exten *e)
void * ast_get_extension_app_data (struct ast_exten *e)
const char * ast_get_extension_cidmatch (struct ast_exten *e)
struct ast_contextast_get_extension_context (struct ast_exten *exten)
const char * ast_get_extension_label (struct ast_exten *e)
int ast_get_extension_matchcid (struct ast_exten *e)
const char * ast_get_extension_name (struct ast_exten *exten)
int ast_get_extension_priority (struct ast_exten *exten)
const char * ast_get_extension_registrar (struct ast_exten *e)
int ast_get_hint (char *hint, int maxlen, char *name, int maxnamelen, struct ast_channel *c, const char *context, const char *exten)
 If an extension exists, return non-zero.
const char * ast_get_ignorepat_name (struct ast_ignorepat *ip)
const char * ast_get_ignorepat_registrar (struct ast_ignorepat *ip)
const char * ast_get_include_name (struct ast_include *include)
const char * ast_get_include_registrar (struct ast_include *i)
const char * ast_get_switch_data (struct ast_sw *sw)
const char * ast_get_switch_name (struct ast_sw *sw)
const char * ast_get_switch_registrar (struct ast_sw *sw)
int ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority)
void ast_hint_state_changed (const char *device)
int ast_ignore_pattern (const char *context, const char *pattern)
 Checks to see if a number should be ignored.
int ast_lock_context (struct ast_context *con)
 Locks a given context.
int ast_lock_contexts (void)
 Locks the context list.
int ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Looks to see if adding anything to this extension might match something. (exists ^ canmatch).
void ast_merge_contexts_and_delete (struct ast_context **extcontexts, const char *registrar)
 Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added.
int ast_parseable_goto (struct ast_channel *chan, const char *goto_string)
int ast_pbx_outgoing_app (const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
int ast_pbx_outgoing_exten (const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
enum ast_pbx_result ast_pbx_run (struct ast_channel *c)
 Execute the PBX in the current thread.
enum ast_pbx_result ast_pbx_start (struct ast_channel *c)
 Create a new thread and start the PBX.
int ast_register_application (const char *app, int(*execute)(struct ast_channel *, void *), const char *synopsis, const char *description)
 Register an application.
int ast_register_switch (struct ast_switch *sw)
 Register an alternative dialplan switch.
int ast_spawn_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Launch a new extension (i.e. new stack).
int ast_unlock_context (struct ast_context *con)
int ast_unlock_contexts (void)
 Unlocks contexts.
int ast_unregister_application (const char *app)
 Unregister an application.
void ast_unregister_switch (struct ast_switch *sw)
 Unregister an alternative switch.
struct ast_extenast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority)
struct ast_ignorepatast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip)
struct ast_includeast_walk_context_includes (struct ast_context *con, struct ast_include *inc)
struct ast_swast_walk_context_switches (struct ast_context *con, struct ast_sw *sw)
struct ast_contextast_walk_contexts (struct ast_context *con)
struct ast_extenast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority)
void pbx_builtin_clear_globals (void)
const char * pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name)
void pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value)
int pbx_builtin_serialize_variables (struct ast_channel *chan, char *buf, size_t size)
int pbx_builtin_setvar (struct ast_channel *chan, void *data)
void pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value)
int pbx_checkcondition (const char *condition)
 Evaluate a condition.
int pbx_exec (struct ast_channel *c, struct ast_app *app, void *data)
 Execute an application.
struct ast_apppbx_findapp (const char *app)
 Look up an application.
void pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
 pbx_retrieve_variable: Support for Asterisk built-in variables ---
int pbx_set_autofallthrough (int newval)
void pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count)
void pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count)


Detailed Description

Core PBX routines and definitions.

Definition in file pbx.h.


Define Documentation

#define AST_MAX_APP   32

Max length of an application

Definition at line 34 of file pbx.h.

Referenced by destroy_station(), handle_show_application(), handle_show_application_deprecated(), handle_show_function(), handle_show_function_deprecated(), and sla_build_station().

#define AST_PBX_KEEP   0

Definition at line 36 of file pbx.h.

#define AST_PBX_KEEPALIVE   10

Special return values from applications to the PBX {.

Destroy the thread, but don't hang up the channel

Definition at line 40 of file pbx.h.

Referenced by __ast_pbx_run(), _macro_exec(), agi_handle_command(), builtin_blindtransfer(), builtin_parkcall(), feature_exec_app(), park_call_exec(), queue_exec(), rpt_exec(), and run_agi().

#define AST_PBX_NO_HANGUP_PEER   11

Definition at line 41 of file pbx.h.

Referenced by builtin_blindtransfer(), builtin_parkcall(), feature_exec_app(), park_exec(), and try_calling().

#define AST_PBX_REPLACE   1

Definition at line 37 of file pbx.h.

#define PRIORITY_HINT   -1

} Special Priority for a hint

Definition at line 44 of file pbx.h.

Referenced by add_extensions(), add_pri(), ast_add_extension2(), ast_hint_extension(), destroy_exten(), destroy_station(), handle_context_add_extension(), handle_context_add_extension_deprecated(), handle_context_remove_extension(), handle_context_remove_extension_deprecated(), handle_save_dialplan(), park_add_hints(), pbx_load_config(), print_ext(), and sla_build_station().


Typedef Documentation

typedef int(* ast_state_cb_type)(char *context, char *id, enum ast_extension_states state, void *data)

Typedef for devicestate and hint callbacks.

Definition at line 66 of file pbx.h.

typedef int( ast_switch_f)(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)

All switch functions have the same interface, so define a type for them.

Data structure associated with an Asterisk switch

Definition at line 80 of file pbx.h.


Enumeration Type Documentation

enum ast_extension_states

Extension states.

Enumerator:
AST_EXTENSION_REMOVED  Extension removed
AST_EXTENSION_DEACTIVATED  Extension hint removed
AST_EXTENSION_NOT_INUSE  No device INUSE or BUSY
AST_EXTENSION_INUSE  One or more devices INUSE
AST_EXTENSION_BUSY  All devices BUSY
AST_EXTENSION_UNAVAILABLE  All devices UNAVAILABLE/UNREGISTERED
AST_EXTENSION_RINGING  All devices RINGING
AST_EXTENSION_ONHOLD  All devices ONHOLD

Definition at line 47 of file pbx.h.

00047                           {
00048    AST_EXTENSION_REMOVED = -2,   /*!< Extension removed */
00049    AST_EXTENSION_DEACTIVATED = -1,  /*!< Extension hint removed */
00050    AST_EXTENSION_NOT_INUSE = 0,  /*!< No device INUSE or BUSY  */
00051    AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */
00052    AST_EXTENSION_BUSY = 1 << 1,  /*!< All devices BUSY */
00053    AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */
00054    AST_EXTENSION_RINGING = 1 << 3,  /*!< All devices RINGING */
00055    AST_EXTENSION_ONHOLD = 1 << 4,   /*!< All devices ONHOLD */
00056 };

enum ast_pbx_result

Enumerator:
AST_PBX_SUCCESS 
AST_PBX_FAILED 
AST_PBX_CALL_LIMIT 

Definition at line 214 of file pbx.h.

00214                     {
00215    AST_PBX_SUCCESS = 0,
00216    AST_PBX_FAILED = -1,
00217    AST_PBX_CALL_LIMIT = -2,
00218 };


Function Documentation

int ast_active_calls ( void   ) 

Retrieve the number of active calls.

Definition at line 2650 of file pbx.c.

References countcalls.

02651 {
02652    return countcalls;
02653 }

int ast_add_extension ( const char *  context,
int  replace,
const char *  extension,
int  priority,
const char *  label,
const char *  callerid,
const char *  application,
void *  data,
void(*)(void *)  datad,
const char *  registrar 
)

Add and extension to an extension context.

Parameters:
context context to add the extension to
replace 
extension extension to add
priority priority level of extension addition
label extension label
callerid pattern to match CallerID, or NULL to match any CallerID
application application to run on the extension with that priority level
data data to pass to the application
datad 
registrar who registered the extension
Return values:
0 success
-1 failure

Definition at line 4530 of file pbx.c.

References ast_add_extension2(), ast_unlock_contexts(), and find_context_locked().

04533 {
04534    int ret = -1;
04535    struct ast_context *c = find_context_locked(context);
04536 
04537    if (c) {
04538       ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
04539          application, data, datad, registrar);
04540       ast_unlock_contexts();
04541    }
04542    return ret;
04543 }

int ast_add_extension2 ( struct ast_context con,
int  replace,
const char *  extension,
int  priority,
const char *  label,
const char *  callerid,
const char *  application,
void *  data,
void(*)(void *)  datad,
const char *  registrar 
)

Add an extension to an extension context, this time with an ast_context *.

Note:
For details about the arguments, check ast_add_extension()
Add an extension to an extension context, this time with an ast_context *.

We sort extensions in order of matching preference, so that we can stop the search as soon as we find a suitable match. This ordering also takes care of wildcards such as '.' (meaning "one or more of any character") and '!' (which is 'earlymatch', meaning "zero or more of any character" but also impacts the return value from CANMATCH and EARLYMATCH.

The extension match rules defined in the devmeeting 2006.05.05 are quite simple: WE SELECT THE LONGEST MATCH. In detail, "longest" means the number of matched characters in the extension. In case of ties (e.g. _XXX and 333) in the length of a pattern, we give priority to entries with the smallest cardinality (e.g, [5-9] comes before [2-8] before the former has only 5 elements, while the latter has 7, etc. In case of same cardinality, the first element in the range counts. If we still have a tie, any final '!' will make this as a possibly less specific pattern.

EBUSY - can't lock EEXIST - extension with the same priority exist and no replace is set

Definition at line 4734 of file pbx.c.

References add_pri(), ast_exten::app, ast_add_hint(), ast_calloc, AST_LIST_FIRST, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_exten::cidmatch, ast_exten::data, ast_exten::datad, el, ext_cmp(), ext_strncpy(), ast_exten::exten, globals, ast_exten::label, ast_context::lock, LOG_DEBUG, ast_exten::matchcid, ast_exten::next, option_debug, option_verbose, ast_exten::parent, pbx_substitute_variables_varshead(), ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, ast_context::root, ast_exten::stuff, VAR_BUF_SIZE, and VERBOSE_PREFIX_3.

04738 {
04739    /*
04740     * Sort extensions (or patterns) according to the rules indicated above.
04741     * These are implemented by the function ext_cmp()).
04742     * All priorities for the same ext/pattern/cid are kept in a list,
04743     * using the 'peer' field  as a link field..
04744     */
04745    struct ast_exten *tmp, *e, *el = NULL;
04746    int res;
04747    int length;
04748    char *p;
04749    char expand_buf[VAR_BUF_SIZE] = { 0, };
04750 
04751    /* if we are adding a hint, and there are global variables, and the hint
04752       contains variable references, then expand them
04753    */
04754    ast_mutex_lock(&globalslock);
04755    if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) {
04756       pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf));
04757       application = expand_buf;
04758    }
04759    ast_mutex_unlock(&globalslock);
04760 
04761    length = sizeof(struct ast_exten);
04762    length += strlen(extension) + 1;
04763    length += strlen(application) + 1;
04764    if (label)
04765       length += strlen(label) + 1;
04766    if (callerid)
04767       length += strlen(callerid) + 1;
04768    else
04769       length ++;  /* just the '\0' */
04770 
04771    /* Be optimistic:  Build the extension structure first */
04772    if (!(tmp = ast_calloc(1, length)))
04773       return -1;
04774 
04775    /* use p as dst in assignments, as the fields are const char * */
04776    p = tmp->stuff;
04777    if (label) {
04778       tmp->label = p;
04779       strcpy(p, label);
04780       p += strlen(label) + 1;
04781    }
04782    tmp->exten = p;
04783    p += ext_strncpy(p, extension, strlen(extension) + 1) + 1;
04784    tmp->priority = priority;
04785    tmp->cidmatch = p;   /* but use p for assignments below */
04786    if (callerid) {
04787       p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1;
04788       tmp->matchcid = 1;
04789    } else {
04790       *p++ = '\0';
04791       tmp->matchcid = 0;
04792    }
04793    tmp->app = p;
04794    strcpy(p, application);
04795    tmp->parent = con;
04796    tmp->data = data;
04797    tmp->datad = datad;
04798    tmp->registrar = registrar;
04799 
04800    ast_mutex_lock(&con->lock);
04801    res = 0; /* some compilers will think it is uninitialized otherwise */
04802    for (e = con->root; e; el = e, e = e->next) {   /* scan the extension list */
04803       res = ext_cmp(e->exten, extension);
04804       if (res == 0) { /* extension match, now look at cidmatch */
04805          if (!e->matchcid && !tmp->matchcid)
04806             res = 0;
04807          else if (tmp->matchcid && !e->matchcid)
04808             res = 1;
04809          else if (e->matchcid && !tmp->matchcid)
04810             res = -1;
04811          else
04812             res = strcasecmp(e->cidmatch, tmp->cidmatch);
04813       }
04814       if (res >= 0)
04815          break;
04816    }
04817    if (e && res == 0) { /* exact match, insert in the pri chain */
04818       res = add_pri(con, tmp, el, e, replace);
04819       ast_mutex_unlock(&con->lock);
04820       if (res < 0) {
04821          errno = EEXIST;   /* XXX do we care ? */
04822          return 0; /* XXX should we return -1 maybe ? */
04823       }
04824    } else {
04825       /*
04826        * not an exact match, this is the first entry with this pattern,
04827        * so insert in the main list right before 'e' (if any)
04828        */
04829       tmp->next = e;
04830       if (el)
04831          el->next = tmp;
04832       else
04833          con->root = tmp;
04834       ast_mutex_unlock(&con->lock);
04835       if (tmp->priority == PRIORITY_HINT)
04836          ast_add_hint(tmp);
04837    }
04838    if (option_debug) {
04839       if (tmp->matchcid) {
04840          if (option_debug)
04841             ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n",
04842                tmp->exten, tmp->priority, tmp->cidmatch, con->name);
04843       } else {
04844          if (option_debug)
04845             ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n",
04846                tmp->exten, tmp->priority, con->name);
04847       }
04848    }
04849    if (option_verbose > 2) {
04850       if (tmp->matchcid) {
04851          ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n",
04852             tmp->exten, tmp->priority, tmp->cidmatch, con->name);
04853       } else {
04854          ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n",
04855             tmp->exten, tmp->priority, con->name);
04856       }
04857    }
04858    return 0;
04859 }

int ast_async_goto ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority 
)

Definition at line 4564 of file pbx.c.

References ast_channel::_state, ast_channel::amaflags, ast_cdr_dup(), ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_unlock, ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_pbx_start(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_channel::cdr, ast_channel::context, ast_channel::exten, LOG_WARNING, ast_channel::pbx, ast_channel::readformat, S_OR, and ast_channel::writeformat.

04565 {
04566    int res = 0;
04567 
04568    ast_channel_lock(chan);
04569 
04570    if (chan->pbx) { /* This channel is currently in the PBX */
04571       ast_explicit_goto(chan, context, exten, priority);
04572       ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
04573    } else {
04574       /* In order to do it when the channel doesn't really exist within
04575          the PBX, we have to make a new channel, masquerade, and start the PBX
04576          at the new location */
04577       struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name);
04578       if (chan->cdr) {
04579          tmpchan->cdr = ast_cdr_dup(chan->cdr);
04580       }
04581       if (!tmpchan)
04582          res = -1;
04583       else {
04584          /* Make formats okay */
04585          tmpchan->readformat = chan->readformat;
04586          tmpchan->writeformat = chan->writeformat;
04587          /* Setup proper location */
04588          ast_explicit_goto(tmpchan,
04589             S_OR(context, chan->context), S_OR(exten, chan->exten), priority);
04590 
04591          /* Masquerade into temp channel */
04592          ast_channel_masquerade(tmpchan, chan);
04593 
04594          /* Grab the locks and get going */
04595          ast_channel_lock(tmpchan);
04596          ast_do_masquerade(tmpchan);
04597          ast_channel_unlock(tmpchan);
04598          /* Start the PBX going on our stolen channel */
04599          if (ast_pbx_start(tmpchan)) {
04600             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
04601             ast_hangup(tmpchan);
04602             res = -1;
04603          }
04604       }
04605    }
04606    ast_channel_unlock(chan);
04607    return res;
04608 }

int ast_async_goto_by_name ( const char *  chan,
const char *  context,
const char *  exten,
int  priority 
)

Definition at line 4610 of file pbx.c.

References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().

04611 {
04612    struct ast_channel *chan;
04613    int res = -1;
04614 
04615    chan = ast_get_channel_by_name_locked(channame);
04616    if (chan) {
04617       res = ast_async_goto(chan, context, exten, priority);
04618       ast_channel_unlock(chan);
04619    }
04620    return res;
04621 }

int ast_async_goto_if_exists ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority 
)

Definition at line 6269 of file pbx.c.

References __ast_goto_if_exists().

06270 {
06271    return __ast_goto_if_exists(chan, context, exten, priority, 1);
06272 }

int ast_build_timing ( struct ast_timing i,
const char *  info 
)

Definition at line 4206 of file pbx.c.

References ast_strlen_zero(), ast_timing::daymask, days, ast_timing::dowmask, get_range(), get_timerange(), ast_timing::monthmask, months, and strsep().

04207 {
04208    char info_save[256];
04209    char *info;
04210 
04211    /* Check for empty just in case */
04212    if (ast_strlen_zero(info_in))
04213       return 0;
04214    /* make a copy just in case we were passed a static string */
04215    ast_copy_string(info_save, info_in, sizeof(info_save));
04216    info = info_save;
04217    /* Assume everything except time */
04218    i->monthmask = 0xfff;   /* 12 bits */
04219    i->daymask = 0x7fffffffU; /* 31 bits */
04220    i->dowmask = 0x7f; /* 7 bits */
04221    /* on each call, use strsep() to move info to the next argument */
04222    get_timerange(i, strsep(&info, "|"));
04223    if (info)
04224       i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week");
04225    if (info)
04226       i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day");
04227    if (info)
04228       i->monthmask = get_range(strsep(&info, "|"), 12, months, "month");
04229    return 1;
04230 }

int ast_canmatch_extension ( struct ast_channel c,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid 
)

Looks for a valid matching extension.

Parameters:
c not really important
context context to serach within
exten extension to check
priority priority of extension path
callerid callerid of extension being searched for
Returns:
If "exten" *could be* a valid extension in this context with or without some more digits, return non-zero. Basically, when this returns 0, no matter what you add to exten, it's not going to be a valid extension anymore

Definition at line 2276 of file pbx.c.

References E_CANMATCH, and pbx_extension_helper().

02277 {
02278    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH);
02279 }

int ast_check_timing ( const struct ast_timing i  ) 

Definition at line 4232 of file pbx.c.

References ast_localtime(), ast_log(), ast_timing::daymask, ast_timing::dowmask, LOG_WARNING, ast_timing::minmask, ast_timing::monthmask, and t.

04233 {
04234    struct tm tm;
04235    time_t t = time(NULL);
04236 
04237    ast_localtime(&t, &tm, NULL);
04238 
04239    /* If it's not the right month, return */
04240    if (!(i->monthmask & (1 << tm.tm_mon)))
04241       return 0;
04242 
04243    /* If it's not that time of the month.... */
04244    /* Warning, tm_mday has range 1..31! */
04245    if (!(i->daymask & (1 << (tm.tm_mday-1))))
04246       return 0;
04247 
04248    /* If it's not the right day of the week */
04249    if (!(i->dowmask & (1 << tm.tm_wday)))
04250       return 0;
04251 
04252    /* Sanity check the hour just to be safe */
04253    if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
04254       ast_log(LOG_WARNING, "Insane time...\n");
04255       return 0;
04256    }
04257 
04258    /* Now the tough part, we calculate if it fits
04259       in the right time based on min/hour */
04260    if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
04261       return 0;
04262 
04263    /* If we got this far, then we're good */
04264    return 1;
04265 }

int ast_context_add_ignorepat ( const char *  context,
const char *  ignorepat,
const char *  registrar 
)

Add an ignorepat.

Parameters:
context which context to add the ignorpattern to
ignorepat ignorepattern to set up for the extension
registrar registrar of the ignore pattern
Adds an ignore pattern to a particular context.

Return values:
0 on success
-1 on failure

Definition at line 4466 of file pbx.c.

References ast_context_add_ignorepat2(), ast_unlock_contexts(), and find_context_locked().

04467 {
04468    int ret = -1;
04469    struct ast_context *c = find_context_locked(context);
04470 
04471    if (c) {
04472       ret = ast_context_add_ignorepat2(c, value, registrar);
04473       ast_unlock_contexts();
04474    }
04475    return ret;
04476 }

int ast_context_add_ignorepat2 ( struct ast_context con,
const char *  ignorepat,
const char *  registrar 
)

Definition at line 4478 of file pbx.c.

References ast_calloc, ast_mutex_lock(), ast_mutex_unlock(), ast_context::ignorepats, ast_context::lock, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.

04479 {
04480    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
04481    int length;
04482    length = sizeof(struct ast_ignorepat);
04483    length += strlen(value) + 1;
04484    if (!(ignorepat = ast_calloc(1, length)))
04485       return -1;
04486    /* The cast to char * is because we need to write the initial value.
04487     * The field is not supposed to be modified otherwise
04488     */
04489    strcpy((char *)ignorepat->pattern, value);
04490    ignorepat->next = NULL;
04491    ignorepat->registrar = registrar;
04492    ast_mutex_lock(&con->lock);
04493    for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
04494       ignorepatl = ignorepatc;
04495       if (!strcasecmp(ignorepatc->pattern, value)) {
04496          /* Already there */
04497          ast_mutex_unlock(&con->lock);
04498          errno = EEXIST;
04499          return -1;
04500       }
04501    }
04502    if (ignorepatl)
04503       ignorepatl->next = ignorepat;
04504    else
04505       con->ignorepats = ignorepat;
04506    ast_mutex_unlock(&con->lock);
04507    return 0;
04508 
04509 }

int ast_context_add_include ( const char *  context,
const char *  include,
const char *  registrar 
)

Add a context include.

Parameters:
context context to add include to
include new include to add
registrar who's registering it
Adds an include taking a char * string as the context parameter

Return values:
0 on success
-1 on error

Definition at line 4012 of file pbx.c.

References ast_context_add_include2(), ast_unlock_contexts(), and find_context_locked().

04013 {
04014    int ret = -1;
04015    struct ast_context *c = find_context_locked(context);
04016 
04017    if (c) {
04018       ret = ast_context_add_include2(c, include, registrar);
04019       ast_unlock_contexts();
04020    }
04021    return ret;
04022 }

int ast_context_add_include2 ( struct ast_context con,
const char *  include,
const char *  registrar 
)

Add a context include.

Parameters:
con context to add the include to
include include to add
registrar who registered the context
Adds an include taking a struct ast_context as the first parameter

Return values:
0 on success
-1 on failure

Definition at line 4274 of file pbx.c.

References ast_build_timing(), ast_calloc, ast_get_context_name(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, ast_include::hastime, ast_context::includes, ast_context::lock, ast_include::name, ast_include::next, option_verbose, ast_include::registrar, ast_include::rname, ast_include::stuff, ast_include::timing, and VERBOSE_PREFIX_3.

04276 {
04277    struct ast_include *new_include;
04278    char *c;
04279    struct ast_include *i, *il = NULL; /* include, include_last */
04280    int length;
04281    char *p;
04282 
04283    length = sizeof(struct ast_include);
04284    length += 2 * (strlen(value) + 1);
04285 
04286    /* allocate new include structure ... */
04287    if (!(new_include = ast_calloc(1, length)))
04288       return -1;
04289    /* Fill in this structure. Use 'p' for assignments, as the fields
04290     * in the structure are 'const char *'
04291     */
04292    p = new_include->stuff;
04293    new_include->name = p;
04294    strcpy(p, value);
04295    p += strlen(value) + 1;
04296    new_include->rname = p;
04297    strcpy(p, value);
04298    /* Strip off timing info, and process if it is there */
04299    if ( (c = strchr(p, '|')) ) {
04300       *c++ = '\0';
04301            new_include->hastime = ast_build_timing(&(new_include->timing), c);
04302    }
04303    new_include->next      = NULL;
04304    new_include->registrar = registrar;
04305 
04306    ast_mutex_lock(&con->lock);
04307 
04308    /* ... go to last include and check if context is already included too... */
04309    for (i = con->includes; i; i = i->next) {
04310       if (!strcasecmp(i->name, new_include->name)) {
04311          free(new_include);
04312          ast_mutex_unlock(&con->lock);
04313          errno = EEXIST;
04314          return -1;
04315       }
04316       il = i;
04317    }
04318 
04319    /* ... include new context into context list, unlock, return */
04320    if (il)
04321       il->next = new_include;
04322    else
04323       con->includes = new_include;
04324    if (option_verbose > 2)
04325       ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
04326    ast_mutex_unlock(&con->lock);
04327 
04328    return 0;
04329 }

int ast_context_add_switch ( const char *  context,
const char *  sw,
const char *  data,
int  eval,
const char *  registrar 
)

Add a switch.

Parameters:
context context to which to add the switch
sw switch to add
data data to pass to switch
eval whether to evaluate variables when running switch
registrar whoever registered the switch
This function registers a switch with the asterisk switch architecture

Return values:
0 on success
-1 on failure

Definition at line 4336 of file pbx.c.

References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().

04337 {
04338    int ret = -1;
04339    struct ast_context *c = find_context_locked(context);
04340 
04341    if (c) { /* found, add switch to this context */
04342       ret = ast_context_add_switch2(c, sw, data, eval, registrar);
04343       ast_unlock_contexts();
04344    }
04345    return ret;
04346 }

int ast_context_add_switch2 ( struct ast_context con,
const char *  sw,
const char *  data,
int  eval,
const char *  registrar 
)

Adds a switch (first param is a ast_context).

Note:
See ast_context_add_switch() for argument information, with the exception of the first argument. In this case, it's a pointer to an ast_context structure as opposed to the name.

Definition at line 4355 of file pbx.c.

References ast_calloc, ast_get_context_name(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_sw::data, ast_sw::eval, free, ast_context::lock, ast_sw::name, option_verbose, ast_sw::registrar, SWITCH_DATA_LENGTH, and VERBOSE_PREFIX_3.

04357 {
04358    struct ast_sw *new_sw;
04359    struct ast_sw *i;
04360    int length;
04361    char *p;
04362 
04363    length = sizeof(struct ast_sw);
04364    length += strlen(value) + 1;
04365    if (data)
04366       length += strlen(data);
04367    length++;
04368    if (eval) {
04369       /* Create buffer for evaluation of variables */
04370       length += SWITCH_DATA_LENGTH;
04371       length++;
04372    }
04373 
04374    /* allocate new sw structure ... */
04375    if (!(new_sw = ast_calloc(1, length)))
04376       return -1;
04377    /* ... fill in this structure ... */
04378    p = new_sw->stuff;
04379    new_sw->name = p;
04380    strcpy(new_sw->name, value);
04381    p += strlen(value) + 1;
04382    new_sw->data = p;
04383    if (data) {
04384       strcpy(new_sw->data, data);
04385       p += strlen(data) + 1;
04386    } else {
04387       strcpy(new_sw->data, "");
04388       p++;
04389    }
04390    if (eval)
04391       new_sw->tmpdata = p;
04392    new_sw->eval     = eval;
04393    new_sw->registrar = registrar;
04394 
04395    /* ... try to lock this context ... */
04396    ast_mutex_lock(&con->lock);
04397 
04398    /* ... go to last sw and check if context is already swd too... */
04399    AST_LIST_TRAVERSE(&con->alts, i, list) {
04400       if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
04401          free(new_sw);
04402          ast_mutex_unlock(&con->lock);
04403          errno = EEXIST;
04404          return -1;
04405       }
04406    }
04407 
04408    /* ... sw new context into context list, unlock, return */
04409    AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
04410 
04411    if (option_verbose > 2)
04412       ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
04413 
04414    ast_mutex_unlock(&con->lock);
04415 
04416    return 0;
04417 }

struct ast_context* ast_context_create ( struct ast_context **  extcontexts,
const char *  name,
const char *  registrar 
) [read]

Register a new context.

Parameters:
extcontexts pointer to the ast_context structure pointer
name name of the new context
registrar registrar of the context
This will first search for a context with your name. If it exists already, it will not create a new one. If it does not exist, it will create a new one with the given name and registrar.

Returns:
NULL on failure, and an ast_context structure on success

Definition at line 3883 of file pbx.c.

References __ast_context_create().

03884 {
03885    return __ast_context_create(extcontexts, name, registrar, 0);
03886 }

void ast_context_destroy ( struct ast_context con,
const char *  registrar 
)

Destroy a context (matches the specified context (or ANY context if NULL).

Parameters:
con context to destroy
registrar who registered it
You can optionally leave out either parameter. It will find it based on either the ast_context or the registrar name.

Returns:
nothing

Definition at line 5320 of file pbx.c.

References __ast_context_destroy().

05321 {
05322    __ast_context_destroy(con,registrar);
05323 }

struct ast_context* ast_context_find ( const char *  name  )  [read]

Find a context.

Parameters:
name name of the context to find
Will search for the context with the given name.

Returns:
the ast_context on success, NULL on failure.

Definition at line 890 of file pbx.c.

References ast_mutex_lock(), ast_mutex_unlock(), and ast_walk_contexts().

00891 {
00892    struct ast_context *tmp = NULL;
00893    ast_mutex_lock(&conlock);
00894    while ( (tmp = ast_walk_contexts(tmp)) ) {
00895       if (!name || !strcasecmp(name, tmp->name))
00896          break;
00897    }
00898    ast_mutex_unlock(&conlock);
00899    return tmp;
00900 }

struct ast_context* ast_context_find_or_create ( struct ast_context **  extcontexts,
const char *  name,
const char *  registrar 
) [read]

Definition at line 3888 of file pbx.c.

References __ast_context_create().

03889 {
03890    return __ast_context_create(extcontexts, name, registrar, 1);
03891 }

int ast_context_lockmacro ( const char *  context  ) 

locks the macrolock in the given given context

Parameters:
macrocontext name of the macro-context to lock
Locks the given macro-context to ensure only one thread (call) can execute it at a time

Return values:
0 on success
-1 on failure
Note:
This function locks contexts list by &conlist, searches for the right context structure, and locks the macrolock mutex in that context. macrolock is used to limit a macro to be executed by one call at a time.

Definition at line 2887 of file pbx.c.

References ast_get_context_name(), ast_lock_contexts(), ast_mutex_lock(), ast_unlock_contexts(), and ast_walk_contexts().

02888 {
02889    struct ast_context *c = NULL;
02890    int ret = -1;
02891 
02892    ast_lock_contexts();
02893 
02894    while ((c = ast_walk_contexts(c))) {
02895       if (!strcmp(ast_get_context_name(c), context)) {
02896          ret = 0;
02897          break;
02898       }
02899    }
02900 
02901    ast_unlock_contexts();
02902 
02903    /* if we found context, lock macrolock */
02904    if (ret == 0) 
02905       ret = ast_mutex_lock(&c->macrolock);
02906 
02907    return ret;
02908 }

int ast_context_remove_extension ( const char *  context,
const char *  extension,
int  priority,
const char *  registrar 
)

Simply remove extension from context.

Parameters:
context context to remove extension from
extension which extension to remove
priority priority of extension to remove
registrar registrar of the extension
This function removes an extension from a given context.

Return values:
0 on success
-1 on failure

Definition at line 2788 of file pbx.c.

References ast_context_remove_extension2(), ast_unlock_contexts(), and find_context_locked().

02789 {
02790    int ret = -1; /* default error return */
02791    struct ast_context *c = find_context_locked(context);
02792 
02793    if (c) { /* ... remove extension ... */
02794       ret = ast_context_remove_extension2(c, extension, priority, registrar);
02795       ast_unlock_contexts();
02796    }
02797    return ret;
02798 }

int ast_context_remove_extension2 ( struct ast_context con,
const char *  extension,
int  priority,
const char *  registrar 
)

This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return.

Note:
When do you want to call this function, make sure that &conlock is locked, because some process can handle with your *con context before you lock it.

Definition at line 2810 of file pbx.c.

References ast_mutex_lock(), ast_mutex_unlock(), destroy_exten(), ast_exten::exten, exten, ast_context::lock, ast_exten::next, ast_exten::peer, ast_exten::registrar, and ast_context::root.

02811 {
02812    struct ast_exten *exten, *prev_exten = NULL;
02813    struct ast_exten *peer;
02814 
02815    ast_mutex_lock(&con->lock);
02816 
02817    /* scan the extension list to find matching extension-registrar */
02818    for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
02819       if (!strcmp(exten->exten, extension) &&
02820          (!registrar || !strcmp(exten->registrar, registrar)))
02821          break;
02822    }
02823    if (!exten) {
02824       /* we can't find right extension */
02825       ast_mutex_unlock(&con->lock);
02826       return -1;
02827    }
02828 
02829    /* should we free all peers in this extension? (priority == 0)? */
02830    if (priority == 0) {
02831       /* remove this extension from context list */
02832       if (prev_exten)
02833          prev_exten->next = exten->next;
02834       else
02835          con->root = exten->next;
02836 
02837       /* fire out all peers */
02838       while ( (peer = exten) ) {
02839          exten = peer->peer; /* prepare for next entry */
02840          destroy_exten(peer);
02841       }
02842    } else {
02843       /* scan the priority list to remove extension with exten->priority == priority */
02844       struct ast_exten *previous_peer = NULL;
02845 
02846       for (peer = exten; peer; previous_peer = peer, peer = peer->peer) {
02847          if (peer->priority == priority &&
02848                (!registrar || !strcmp(peer->registrar, registrar) ))
02849             break; /* found our priority */
02850       }
02851       if (!peer) { /* not found */
02852          ast_mutex_unlock(&con->lock);
02853          return -1;
02854       }
02855       /* we are first priority extension? */
02856       if (!previous_peer) {
02857          /*
02858           * We are first in the priority chain, so must update the extension chain.
02859           * The next node is either the next priority or the next extension
02860           */
02861          struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
02862 
02863          if (!prev_exten)  /* change the root... */
02864             con->root = next_node;
02865          else
02866             prev_exten->next = next_node; /* unlink */
02867          if (peer->peer)   /* XXX update the new head of the pri list */
02868             peer->peer->next = peer->next;
02869       } else { /* easy, we are not first priority in extension */
02870          previous_peer->peer = peer->peer;
02871       }
02872 
02873       /* now, free whole priority extension */
02874       destroy_exten(peer);
02875       /* XXX should we return -1 ? */
02876    }
02877    ast_mutex_unlock(&con->lock);
02878    return 0;
02879 }

int ast_context_remove_ignorepat ( const char *  context,
const char *  ignorepat,
const char *  registrar 
)

Definition at line 4423 of file pbx.c.

References ast_context_remove_ignorepat2(), ast_unlock_contexts(), and find_context_locked().

04424 {
04425    int ret = -1;
04426    struct ast_context *c = find_context_locked(context);
04427 
04428    if (c) {
04429       ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
04430       ast_unlock_contexts();
04431    }
04432    return ret;
04433 }

int ast_context_remove_ignorepat2 ( struct ast_context con,
const char *  ignorepat,
const char *  registrar 
)

Definition at line 4435 of file pbx.c.

References ast_mutex_lock(), ast_mutex_unlock(), free, ast_context::ignorepats, ast_context::lock, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.

04436 {
04437    struct ast_ignorepat *ip, *ipl = NULL;
04438 
04439    ast_mutex_lock(&con->lock);
04440 
04441    for (ip = con->ignorepats; ip; ip = ip->next) {
04442       if (!strcmp(ip->pattern, ignorepat) &&
04443          (!registrar || (registrar == ip->registrar))) {
04444          if (ipl) {
04445             ipl->next = ip->next;
04446             free(ip);
04447          } else {
04448             con->ignorepats = ip->next;
04449             free(ip);
04450          }
04451          ast_mutex_unlock(&con->lock);
04452          return 0;
04453       }
04454       ipl = ip;
04455    }
04456 
04457    ast_mutex_unlock(&con->lock);
04458    errno = EINVAL;
04459    return -1;
04460 }

int ast_context_remove_include ( const char *  context,
const char *  include,
const char *  registrar 
)

Remove a context include.

Note:
See ast_context_add_include for information on arguments
Return values:
0 on success
-1 on failure

Definition at line 2684 of file pbx.c.

References ast_context_remove_include2(), ast_unlock_contexts(), and find_context_locked().

02685 {
02686    int ret = -1;
02687    struct ast_context *c = find_context_locked(context);
02688 
02689    if (c) {
02690       /* found, remove include from this context ... */
02691       ret = ast_context_remove_include2(c, include, registrar);
02692       ast_unlock_contexts();
02693    }
02694    return ret;
02695 }

int ast_context_remove_include2 ( struct ast_context con,
const char *  include,
const char *  registrar 
)

Removes an include by an ast_context structure.

Note:
See ast_context_add_include2 for information on arguments
Return values:
0 on success
-1 on success

Definition at line 2705 of file pbx.c.

References ast_mutex_lock(), ast_mutex_unlock(), free, ast_context::includes, ast_context::lock, ast_include::name, ast_include::next, and ast_include::registrar.

02706 {
02707    struct ast_include *i, *pi = NULL;
02708    int ret = -1;
02709 
02710    ast_mutex_lock(&con->lock);
02711 
02712    /* find our include */
02713    for (i = con->includes; i; pi = i, i = i->next) {
02714       if (!strcmp(i->name, include) &&
02715             (!registrar || !strcmp(i->registrar, registrar))) {
02716          /* remove from list */
02717          if (pi)
02718             pi->next = i->next;
02719          else
02720             con->includes = i->next;
02721          /* free include and return */
02722          free(i);
02723          ret = 0;
02724          break;
02725       }
02726    }
02727 
02728    ast_mutex_unlock(&con->lock);
02729    return ret;
02730 }

int ast_context_remove_switch ( const char *  context,
const char *  sw,
const char *  data,
const char *  registrar 
)

Remove a switch.

Removes a switch with the given parameters

Return values:
0 on success
-1 on failure
Note:
This function locks contexts list by &conlist, search for the rigt context structure, leave context list locked and call ast_context_remove_switch2 which removes switch, unlock contexts list and return ...

Definition at line 2737 of file pbx.c.

References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().

02738 {
02739    int ret = -1; /* default error return */
02740    struct ast_context *c = find_context_locked(context);
02741 
02742    if (c) {
02743       /* remove switch from this context ... */
02744       ret = ast_context_remove_switch2(c, sw, data, registrar);
02745       ast_unlock_contexts();
02746    }
02747    return ret;
02748 }

int ast_context_remove_switch2 ( struct ast_context con,
const char *  sw,
const char *  data,
const char *  registrar 
)

This function locks given context, removes switch, unlock context and return.

Note:
When we call this function, &conlock lock must be locked, because when we giving *con argument, some process can remove/change this context and after that there can be segfault.

Definition at line 2758 of file pbx.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), ast_sw::data, free, ast_context::lock, ast_sw::name, and ast_sw::registrar.

02759 {
02760    struct ast_sw *i;
02761    int ret = -1;
02762 
02763    ast_mutex_lock(&con->lock);
02764 
02765    /* walk switches */
02766    AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
02767       if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
02768          (!registrar || !strcmp(i->registrar, registrar))) {
02769          /* found, remove from list */
02770          AST_LIST_REMOVE_CURRENT(&con->alts, list);
02771          free(i); /* free switch and return */
02772          ret = 0;
02773          break;
02774       }
02775    }
02776    AST_LIST_TRAVERSE_SAFE_END
02777 
02778    ast_mutex_unlock(&con->lock);
02779 
02780    return ret;
02781 }

int ast_context_unlockmacro ( const char *  context  ) 

Unlocks the macrolock in the given context.

Parameters:
macrocontext name of the macro-context to unlock
Unlocks the given macro-context so that another thread (call) can execute it

Return values:
0 on success
-1 on failure
Note:
This function locks contexts list by &conlist, searches for the right context structure, and unlocks the macrolock mutex in that context. macrolock is used to limit a macro to be executed by one call at a time.

Definition at line 2915 of file pbx.c.

References ast_get_context_name(), ast_lock_contexts(), ast_mutex_unlock(), ast_unlock_contexts(), and ast_walk_contexts().

02916 {
02917    struct ast_context *c = NULL;
02918    int ret = -1;
02919 
02920    ast_lock_contexts();
02921 
02922    while ((c = ast_walk_contexts(c))) {
02923       if (!strcmp(ast_get_context_name(c), context)) {
02924          ret = 0;
02925          break;
02926       }
02927    }
02928 
02929    ast_unlock_contexts();
02930 
02931    /* if we found context, unlock macrolock */
02932    if (ret == 0) 
02933       ret = ast_mutex_unlock(&c->macrolock);
02934 
02935    return ret;
02936 }

int ast_context_verify_includes ( struct ast_context con  ) 

Verifies includes in an ast_contect structure.

Parameters:
con context in which to verify the includes
Return values:
0 if no problems found
-1 if there were any missing context

Definition at line 6230 of file pbx.c.

References ast_context_find(), ast_get_context_name(), ast_log(), ast_walk_context_includes(), LOG_WARNING, and ast_include::rname.

06231 {
06232    struct ast_include *inc = NULL;
06233    int res = 0;
06234 
06235    while ( (inc = ast_walk_context_includes(con, inc)) )
06236       if (!ast_context_find(inc->rname)) {
06237          res = -1;
06238          ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n",
06239                ast_get_context_name(con), inc->rname);
06240       }
06241    return res;
06242 }

struct ast_custom_function* ast_custom_function_find ( const char *  name  )  [read]

Definition at line 1427 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_custom_function::name.

01428 {
01429    struct ast_custom_function *acf = NULL;
01430 
01431    AST_LIST_LOCK(&acf_root);
01432    AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
01433       if (!strcmp(name, acf->name))
01434          break;
01435    }
01436    AST_LIST_UNLOCK(&acf_root);
01437 
01438    return acf;
01439 }

int ast_custom_function_register ( struct ast_custom_function acf  ) 

Reigster a custom function.

Definition at line 1463 of file pbx.c.

References ast_custom_function_find(), AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), LOG_ERROR, ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.

01464 {
01465    struct ast_custom_function *cur;
01466 
01467    if (!acf)
01468       return -1;
01469 
01470    AST_LIST_LOCK(&acf_root);
01471 
01472    if (ast_custom_function_find(acf->name)) {
01473       ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
01474       AST_LIST_UNLOCK(&acf_root);
01475       return -1;
01476    }
01477 
01478    /* Store in alphabetical order */
01479    AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
01480       if (strcasecmp(acf->name, cur->name) < 0) {
01481          AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist);
01482          break;
01483       }
01484    }
01485    AST_LIST_TRAVERSE_SAFE_END
01486    if (!cur)
01487       AST_LIST_INSERT_TAIL(&acf_root, acf, acflist);
01488 
01489    AST_LIST_UNLOCK(&acf_root);
01490 
01491    if (option_verbose > 1)
01492       ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name);
01493 
01494    return 0;
01495 }

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

Definition at line 1441 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.

01442 {
01443    struct ast_custom_function *cur;
01444 
01445    if (!acf)
01446       return -1;
01447 
01448    AST_LIST_LOCK(&acf_root);
01449    AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
01450       if (cur == acf) {
01451          AST_LIST_REMOVE_CURRENT(&acf_root, acflist);
01452          if (option_verbose > 1)
01453             ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name);
01454          break;
01455       }
01456    }
01457    AST_LIST_TRAVERSE_SAFE_END
01458    AST_LIST_UNLOCK(&acf_root);
01459 
01460    return acf ? 0 : -1;
01461 }

int ast_exists_extension ( struct ast_channel c,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid 
)

Determine whether an extension exists.

Parameters:
c this is not important
context which context to look in
exten which extension to search for
priority priority of the action within the extension
callerid callerid to search for
Returns:
If an extension within the given context(or callerid) with the given priority is found a non zero value will be returned. Otherwise, 0 is returned.

Definition at line 2261 of file pbx.c.

References E_MATCH, and pbx_extension_helper().

02262 {
02263    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH);
02264 }

int ast_explicit_goto ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority 
)

Definition at line 4545 of file pbx.c.

References AST_FLAG_IN_AUTOLOOP, ast_strlen_zero(), ast_test_flag, ast_channel::context, ast_channel::exten, and ast_channel::priority.

04546 {
04547    if (!chan)
04548       return -1;
04549 
04550    if (!ast_strlen_zero(context))
04551       ast_copy_string(chan->context, context, sizeof(chan->context));
04552    if (!ast_strlen_zero(exten))
04553       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
04554    if (priority > -1) {
04555       chan->priority = priority;
04556       /* see flag description in channel.h for explanation */
04557       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
04558          chan->priority--;
04559    }
04560 
04561    return 0;
04562 }

int ast_extension_close ( const char *  pattern,
const char *  data,
int  needmore 
)

Definition at line 883 of file pbx.c.

References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.

00884 {
00885    if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
00886       ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
00887    return extension_match_core(pattern, data, needmore);
00888 }

int ast_extension_match ( const char *  pattern,
const char *  extension 
)

Determine if a given extension matches a given pattern (in NXX format).

Parameters:
pattern pattern to match
extension extension to check against the pattern.
Checks whether or not the given extension matches the given pattern.

Return values:
1 on match
0 on failure

Definition at line 878 of file pbx.c.

References E_MATCH, and extension_match_core().

00879 {
00880    return extension_match_core(pattern, data, E_MATCH);
00881 }

int ast_extension_patmatch ( const char *  pattern,
const char *  data 
)

int ast_extension_state ( struct ast_channel c,
const char *  context,
const char *  exten 
)

Uses hint and devicestate callback to get the state of an extension.

Parameters:
c this is not important
context which context to look in
exten which extension to get state
Returns:
extension state as defined in the ast_extension_states enum

Definition at line 1985 of file pbx.c.

References ast_extension_state2(), and ast_hint_extension().

01986 {
01987    struct ast_exten *e;
01988 
01989    e = ast_hint_extension(c, context, exten);   /* Do we have a hint for this extension ? */
01990    if (!e)
01991       return -1;           /* No hint, return -1 */
01992 
01993    return ast_extension_state2(e);        /* Check all devices in the hint */
01994 }

const char* ast_extension_state2str ( int  extension_state  ) 

Return string representation of the state of an extension.

Parameters:
extension_state is the numerical state delivered by ast_extension_state
Returns:
the state of an extension as string

Definition at line 1973 of file pbx.c.

References extension_states, and cfextension_states::text.

01974 {
01975    int i;
01976 
01977    for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) {
01978       if (extension_states[i].extension_state == extension_state)
01979          return extension_states[i].text;
01980    }
01981    return "Unknown";
01982 }

int ast_extension_state_add ( const char *  context,
const char *  exten,
ast_state_cb_type  callback,
void *  data 
)

Registers a state change callback.

Parameters:
context which context to look in
exten which extension to get state
callback callback to call if state changed
data to pass to callback
The callback is called if the state of an extension is changed.

Return values:
-1 on failure
ID on success

Definition at line 2040 of file pbx.c.

References ast_calloc, ast_hint_extension(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_hint::exten, ast_state_cb::id, ast_state_cb::next, statecbs, and stateid.

02042 {
02043    struct ast_hint *hint;
02044    struct ast_state_cb *cblist;
02045    struct ast_exten *e;
02046 
02047    /* If there's no context and extension:  add callback to statecbs list */
02048    if (!context && !exten) {
02049       AST_LIST_LOCK(&hints);
02050 
02051       for (cblist = statecbs; cblist; cblist = cblist->next) {
02052          if (cblist->callback == callback) {
02053             cblist->data = data;
02054             AST_LIST_UNLOCK(&hints);
02055             return 0;
02056          }
02057       }
02058 
02059       /* Now insert the callback */
02060       if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
02061          AST_LIST_UNLOCK(&hints);
02062          return -1;
02063       }
02064       cblist->id = 0;
02065       cblist->callback = callback;
02066       cblist->data = data;
02067 
02068       cblist->next = statecbs;
02069       statecbs = cblist;
02070 
02071       AST_LIST_UNLOCK(&hints);
02072       return 0;
02073    }
02074 
02075    if (!context || !exten)
02076       return -1;
02077 
02078    /* This callback type is for only one hint, so get the hint */
02079    e = ast_hint_extension(NULL, context, exten);
02080    if (!e) {
02081       return -1;
02082    }
02083 
02084    /* Find the hint in the list of hints */
02085    AST_LIST_LOCK(&hints);
02086 
02087    AST_LIST_TRAVERSE(&hints, hint, list) {
02088       if (hint->exten == e)
02089          break;
02090    }
02091 
02092    if (!hint) {
02093       /* We have no hint, sorry */
02094       AST_LIST_UNLOCK(&hints);
02095       return -1;
02096    }
02097 
02098    /* Now insert the callback in the callback list  */
02099    if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
02100       AST_LIST_UNLOCK(&hints);
02101       return -1;
02102    }
02103    cblist->id = stateid++;    /* Unique ID for this callback */
02104    cblist->callback = callback;  /* Pointer to callback routine */
02105    cblist->data = data;    /* Data for the callback */
02106 
02107    cblist->next = hint->callbacks;
02108    hint->callbacks = cblist;
02109 
02110    AST_LIST_UNLOCK(&hints);
02111    return cblist->id;
02112 }

int ast_extension_state_del ( int  id,
ast_state_cb_type  callback 
)

Deletes a registered state change callback by ID.

Parameters:
id of the callback to delete
callback callback
Removes the callback from list of callbacks

Return values:
0 success
-1 failure

Definition at line 2115 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_hint::callbacks, free, ast_state_cb::next, and statecbs.

02116 {
02117    struct ast_state_cb **p_cur = NULL; /* address of pointer to us */
02118    int ret = -1;
02119 
02120    if (!id && !callback)
02121       return -1;
02122 
02123    AST_LIST_LOCK(&hints);
02124 
02125    if (!id) {  /* id == 0 is a callback without extension */
02126       for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) {
02127          if ((*p_cur)->callback == callback)
02128             break;
02129       }
02130    } else { /* callback with extension, find the callback based on ID */
02131       struct ast_hint *hint;
02132       AST_LIST_TRAVERSE(&hints, hint, list) {
02133          for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) {
02134             if ((*p_cur)->id == id)
02135                break;
02136          }
02137          if (*p_cur) /* found in the inner loop */
02138             break;
02139       }
02140    }
02141    if (p_cur && *p_cur) {
02142       struct ast_state_cb *cur = *p_cur;
02143       *p_cur = cur->next;
02144       free(cur);
02145       ret = 0;
02146    }
02147    AST_LIST_UNLOCK(&hints);
02148    return ret;
02149 }

int ast_findlabel_extension ( struct ast_channel c,
const char *  context,
const char *  exten,
const char *  label,
const char *  callerid 
)

Find the priority of an extension that has the specified label.

Parameters:
c this is not important
context which context to look in
exten which extension to search for
label label of the action within the extension to match to priority
callerid callerid to search for
Returns:
the priority which matches the given label in the extension or -1 if not found.

Definition at line 2266 of file pbx.c.

References E_FINDLABEL, and pbx_extension_helper().

02267 {
02268    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL);
02269 }

int ast_findlabel_extension2 ( struct ast_channel c,
struct ast_context con,
const char *  exten,
const char *  label,
const char *  callerid 
)

Find the priority of an extension that has the specified label.

Note:
This function is the same as ast_findlabel_extension, except that it accepts a pointer to an ast_context structure to specify the context instead of the name of the context. Otherwise, the functions behave the same.

Definition at line 2271 of file pbx.c.

References E_FINDLABEL, and pbx_extension_helper().

02272 {
02273    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL);
02274 }

int ast_func_read ( struct ast_channel chan,
char *  function,
char *  workspace,
size_t  len 
)

executes a read operation on a function

Parameters:
chan Channel to execute on
function Data containing the function call string (will be modified)
workspace A pointer to safe memory to use for a return value
len the number of bytes in workspace
This application executes a function in read mode on a given channel.

Returns:
zero on success, non-zero on failure

Definition at line 1517 of file pbx.c.

References ast_custom_function_find(), ast_log(), func_args(), LOG_ERROR, and ast_custom_function::read.

01518 {
01519    char *args = func_args(function);
01520    struct ast_custom_function *acfptr = ast_custom_function_find(function);
01521 
01522    if (acfptr == NULL)
01523       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01524    else if (!acfptr->read)
01525       ast_log(LOG_ERROR, "Function %s cannot be read\n", function);
01526    else
01527       return acfptr->read(chan, function, args, workspace, len);
01528    return -1;
01529 }

int ast_func_write ( struct ast_channel chan,
char *  function,
const char *  value 
)

executes a write operation on a function

Parameters:
chan Channel to execute on
function Data containing the function call string (will be modified)
value A value parameter to pass for writing
This application executes a function in write mode on a given channel.

Returns:
zero on success, non-zero on failure

Definition at line 1531 of file pbx.c.

References ast_custom_function_find(), ast_log(), func_args(), LOG_ERROR, and ast_custom_function::write.

01532 {
01533    char *args = func_args(function);
01534    struct ast_custom_function *acfptr = ast_custom_function_find(function);
01535 
01536    if (acfptr == NULL)
01537       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01538    else if (!acfptr->write)
01539       ast_log(LOG_ERROR, "Function %s cannot be written to\n", function);
01540    else
01541       return acfptr->write(chan, function, args, value);
01542 
01543    return -1;
01544 }

const char* ast_get_context_name ( struct ast_context con  ) 

Definition at line 6087 of file pbx.c.

06088 {
06089    return con ? con->name : NULL;
06090 }

const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 6125 of file pbx.c.

References ast_context::registrar.

06126 {
06127    return c ? c->registrar : NULL;
06128 }

const char* ast_get_extension_app ( struct ast_exten e  ) 

Definition at line 6155 of file pbx.c.

References ast_exten::app.

06156 {
06157    return e ? e->app : NULL;
06158 }

void* ast_get_extension_app_data ( struct ast_exten e  ) 

Definition at line 6160 of file pbx.c.

References ast_exten::data.

06161 {
06162    return e ? e->data : NULL;
06163 }

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 6150 of file pbx.c.

References ast_exten::cidmatch.

06151 {
06152    return e ? e->cidmatch : NULL;
06153 }

struct ast_context* ast_get_extension_context ( struct ast_exten exten  )  [read]

Definition at line 6092 of file pbx.c.

References ast_exten::parent.

06093 {
06094    return exten ? exten->parent : NULL;
06095 }

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 6102 of file pbx.c.

References ast_exten::label.

06103 {
06104    return exten ? exten->label : NULL;
06105 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 6145 of file pbx.c.

References ast_exten::matchcid.

06146 {
06147    return e ? e->matchcid : 0;
06148 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 

Definition at line 6097 of file pbx.c.

References ast_exten::exten.

06098 {
06099    return exten ? exten->exten : NULL;
06100 }

int ast_get_extension_priority ( struct ast_exten exten  ) 

Definition at line 6117 of file pbx.c.

References ast_exten::priority.

06118 {
06119    return exten ? exten->priority : -1;
06120 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 6130 of file pbx.c.

References ast_exten::registrar.

06131 {
06132    return e ? e->registrar : NULL;
06133 }

int ast_get_hint ( char *  hint,
int  hintsize,
char *  name,
int  namesize,
struct ast_channel c,
const char *  context,
const char *  exten 
)

If an extension exists, return non-zero.

Parameters:
hint buffer for hint
maxlen size of hint buffer
name buffer for name portion of hint
maxnamelen size of name buffer
c this is not important
context which context to look in
exten which extension to search for
Returns:
If an extension within the given context with the priority PRIORITY_HINT is found a non zero value will be returned. Otherwise, 0 is returned.

Definition at line 2244 of file pbx.c.

References ast_get_extension_app(), ast_get_extension_app_data(), and ast_hint_extension().

02245 {
02246    struct ast_exten *e = ast_hint_extension(c, context, exten);
02247 
02248    if (e) {
02249       if (hint)
02250          ast_copy_string(hint, ast_get_extension_app(e), hintsize);
02251       if (name) {
02252          const char *tmp = ast_get_extension_app_data(e);
02253          if (tmp)
02254             ast_copy_string(name, tmp, namesize);
02255       }
02256       return -1;
02257    }
02258    return 0;
02259 }

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 

Definition at line 6112 of file pbx.c.

References ast_ignorepat::pattern.

06113 {
06114    return ip ? ip->pattern : NULL;
06115 }

const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

Definition at line 6140 of file pbx.c.

References ast_ignorepat::registrar.

06141 {
06142    return ip ? ip->registrar : NULL;
06143 }

const char* ast_get_include_name ( struct ast_include include  ) 

Definition at line 6107 of file pbx.c.

References ast_include::name.

06108 {
06109    return inc ? inc->name : NULL;
06110 }

const char* ast_get_include_registrar ( struct ast_include i  ) 

Definition at line 6135 of file pbx.c.

References ast_include::registrar.

06136 {
06137    return i ? i->registrar : NULL;
06138 }

const char* ast_get_switch_data ( struct ast_sw sw  ) 

Definition at line 6170 of file pbx.c.

References ast_sw::data.

06171 {
06172    return sw ? sw->data : NULL;
06173 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

Definition at line 6165 of file pbx.c.

References ast_sw::name.

06166 {
06167    return sw ? sw->name : NULL;
06168 }

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

Definition at line 6175 of file pbx.c.

References ast_sw::registrar.

06176 {
06177    return sw ? sw->registrar : NULL;
06178 }

int ast_goto_if_exists ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority 
)

Definition at line 6264 of file pbx.c.

References __ast_goto_if_exists().

06265 {
06266    return __ast_goto_if_exists(chan, context, exten, priority, 0);
06267 }

void ast_hint_state_changed ( const char *  device  ) 

Definition at line 1996 of file pbx.c.

References ast_extension_state2(), ast_get_extension_app(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, AST_MAX_EXTENSION, ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_exten::exten, ast_hint::exten, ast_hint::laststate, ast_state_cb::next, ast_exten::parent, parse(), statecbs, and strsep().

01997 {
01998    struct ast_hint *hint;
01999 
02000    AST_LIST_LOCK(&hints);
02001 
02002    AST_LIST_TRAVERSE(&hints, hint, list) {
02003       struct ast_state_cb *cblist;
02004       char buf[AST_MAX_EXTENSION];
02005       char *parse = buf;
02006       char *cur;
02007       int state;
02008 
02009       ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf));
02010       while ( (cur = strsep(&parse, "&")) ) {
02011          if (!strcasecmp(cur, device))
02012             break;
02013       }
02014       if (!cur)
02015          continue;
02016 
02017       /* Get device state for this hint */
02018       state = ast_extension_state2(hint->exten);
02019 
02020       if ((state == -1) || (state == hint->laststate))
02021          continue;
02022 
02023       /* Device state changed since last check - notify the watchers */
02024 
02025       /* For general callbacks */
02026       for (cblist = statecbs; cblist; cblist = cblist->next)
02027          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
02028 
02029       /* For extension callbacks */
02030       for (cblist = hint->callbacks; cblist; cblist = cblist->next)
02031          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
02032 
02033       hint->laststate = state;   /* record we saw the change */
02034    }
02035 
02036    AST_LIST_UNLOCK(&hints);
02037 }

int ast_ignore_pattern ( const char *  context,
const char *  pattern 
)

Checks to see if a number should be ignored.

Parameters:
context context to search within
pattern to check whether it should be ignored or not
Check if a number should be ignored with respect to dialtone cancellation.

Return values:
0 if the pattern should not be ignored
non-zero if the pattern should be ignored

Definition at line 4511 of file pbx.c.

References ast_context_find(), ast_extension_match(), ast_context::ignorepats, ast_ignorepat::next, and ast_ignorepat::pattern.

04512 {
04513    struct ast_context *con = ast_context_find(context);
04514    if (con) {
04515       struct ast_ignorepat *pat;
04516       for (pat = con->ignorepats; pat; pat = pat->next) {
04517          if (ast_extension_match(pat->pattern, pattern))
04518             return 1;
04519       }
04520    }
04521 
04522    return 0;
04523 }

int ast_lock_context ( struct ast_context con  ) 

Locks a given context.

Parameters:
con context to lock
Return values:
0 on success
-1 on failure

Definition at line 6074 of file pbx.c.

References ast_mutex_lock(), and ast_context::lock.

06075 {
06076    return ast_mutex_lock(&con->lock);
06077 }

int ast_lock_contexts ( void   ) 

Locks the context list.

Return values:
0 on success
-1 on error

Definition at line 6061 of file pbx.c.

References ast_mutex_lock().

06062 {
06063    return ast_mutex_lock(&conlock);
06064 }

int ast_matchmore_extension ( struct ast_channel c,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid 
)

Looks to see if adding anything to this extension might match something. (exists ^ canmatch).

Parameters:
c not really important XXX
context context to serach within
exten extension to check
priority priority of extension path
callerid callerid of extension being searched for
Returns:
If "exten" *could match* a valid extension in this context with some more digits, return non-zero. Does NOT return non-zero if this is an exact-match only. Basically, when this returns 0, no matter what you add to exten, it's not going to be a valid extension anymore

Definition at line 2281 of file pbx.c.

References E_MATCHMORE, and pbx_extension_helper().

02282 {
02283    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE);
02284 }

void ast_merge_contexts_and_delete ( struct ast_context **  extcontexts,
const char *  registrar 
)

Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added.

Parameters:
extcontexts pointer to the ast_context structure pointer
registrar of the context; if it's set the routine will delete all contexts that belong to that registrar; if NULL only the contexts that are specified in extcontexts

Definition at line 3906 of file pbx.c.

References __ast_context_destroy(), ast_calloc, AST_EXTENSION_REMOVED, ast_hint_extension(), AST_LIST_HEAD_INIT_VALUE, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_hint::callbacks, context, contexts, ast_state_cb::data, ast_exten::exten, ast_hint::exten, exten, free, ast_hint::laststate, LOG_DEBUG, LOG_WARNING, ast_state_cb::next, ast_context::next, option_debug, ast_exten::parent, and ast_context::registrar.

03907 {
03908    struct ast_context *tmp, *lasttmp = NULL;
03909    struct store_hints store = AST_LIST_HEAD_INIT_VALUE;
03910    struct store_hint *this;
03911    struct ast_hint *hint;
03912    struct ast_exten *exten;
03913    int length;
03914    struct ast_state_cb *thiscb, *prevcb;
03915 
03916    /* it is very important that this function hold the hint list lock _and_ the conlock
03917       during its operation; not only do we need to ensure that the list of contexts
03918       and extensions does not change, but also that no hint callbacks (watchers) are
03919       added or removed during the merge/delete process
03920 
03921       in addition, the locks _must_ be taken in this order, because there are already
03922       other code paths that use this order
03923    */
03924    ast_mutex_lock(&conlock);
03925    AST_LIST_LOCK(&hints);
03926 
03927    /* preserve all watchers for hints associated with this registrar */
03928    AST_LIST_TRAVERSE(&hints, hint, list) {
03929       if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) {
03930          length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this);
03931          if (!(this = ast_calloc(1, length)))
03932             continue;
03933          this->callbacks = hint->callbacks;
03934          hint->callbacks = NULL;
03935          this->laststate = hint->laststate;
03936          this->context = this->data;
03937          strcpy(this->data, hint->exten->parent->name);
03938          this->exten = this->data + strlen(this->context) + 1;
03939          strcpy(this->exten, hint->exten->exten);
03940          AST_LIST_INSERT_HEAD(&store, this, list);
03941       }
03942    }
03943 
03944    tmp = *extcontexts;
03945    if (registrar) {
03946       /* XXX remove previous contexts from same registrar */
03947       if (option_debug)
03948          ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar);
03949       __ast_context_destroy(NULL,registrar);
03950       while (tmp) {
03951          lasttmp = tmp;
03952          tmp = tmp->next;
03953       }
03954    } else {
03955       /* XXX remove contexts with the same name */
03956       while (tmp) {
03957          ast_log(LOG_WARNING, "must remove %s  reg %s\n", tmp->name, tmp->registrar);
03958          __ast_context_destroy(tmp,tmp->registrar);
03959          lasttmp = tmp;
03960          tmp = tmp->next;
03961       }
03962    }
03963    if (lasttmp) {
03964       lasttmp->next = contexts;
03965       contexts = *extcontexts;
03966       *extcontexts = NULL;
03967    } else
03968       ast_log(LOG_WARNING, "Requested contexts didn't get merged\n");
03969 
03970    /* restore the watchers for hints that can be found; notify those that
03971       cannot be restored
03972    */
03973    while ((this = AST_LIST_REMOVE_HEAD(&store, list))) {
03974       exten = ast_hint_extension(NULL, this->context, this->exten);
03975       /* Find the hint in the list of hints */
03976       AST_LIST_TRAVERSE(&hints, hint, list) {
03977          if (hint->exten == exten)
03978             break;
03979       }
03980       if (!exten || !hint) {
03981          /* this hint has been removed, notify the watchers */
03982          prevcb = NULL;
03983          thiscb = this->callbacks;
03984          while (thiscb) {
03985             prevcb = thiscb;
03986             thiscb = thiscb->next;
03987             prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data);
03988             free(prevcb);
03989             }
03990       } else {
03991          thiscb = this->callbacks;
03992          while (thiscb->next)
03993             thiscb = thiscb->next;
03994          thiscb->next = hint->callbacks;
03995          hint->callbacks = this->callbacks;
03996          hint->laststate = this->laststate;
03997       }
03998       free(this);
03999    }
04000 
04001    AST_LIST_UNLOCK(&hints);
04002    ast_mutex_unlock(&conlock);
04003 
04004    return;
04005 }

int ast_parseable_goto ( struct ast_channel chan,
const char *  goto_string 
)

Definition at line 6274 of file pbx.c.

References ast_cdr_update(), ast_explicit_goto(), ast_findlabel_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, exten, LOG_WARNING, ast_channel::priority, and strsep().

06275 {
06276    char *exten, *pri, *context;
06277    char *stringp;
06278    int ipri;
06279    int mode = 0;
06280 
06281    if (ast_strlen_zero(goto_string)) {
06282       ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
06283       return -1;
06284    }
06285    stringp = ast_strdupa(goto_string);
06286    context = strsep(&stringp, "|"); /* guaranteed non-null */
06287    exten = strsep(&stringp, "|");
06288    pri = strsep(&stringp, "|");
06289    if (!exten) {  /* Only a priority in this one */
06290       pri = context;
06291       exten = NULL;
06292       context = NULL;
06293    } else if (!pri) {   /* Only an extension and priority in this one */
06294       pri = exten;
06295       exten = context;
06296       context = NULL;
06297    }
06298    if (*pri == '+') {
06299       mode = 1;
06300       pri++;
06301    } else if (*pri == '-') {
06302       mode = -1;
06303       pri++;
06304    }
06305    if (sscanf(pri, "%d", &ipri) != 1) {
06306       if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten,
06307          pri, chan->cid.cid_num)) < 1) {
06308          ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);
06309          return -1;
06310       } else
06311          mode = 0;
06312    }
06313    /* At this point we have a priority and maybe an extension and a context */
06314 
06315    if (mode)
06316       ipri = chan->priority + (ipri * mode);
06317 
06318    ast_explicit_goto(chan, context, exten, ipri);
06319    ast_cdr_update(chan);
06320    return 0;
06321 
06322 }

int ast_pbx_outgoing_app ( const char *  type,
int  format,
void *  data,
int  timeout,
const char *  app,
const char *  appdata,
int *  reason,
int  sync,
const char *  cid_num,
const char *  cid_name,
struct ast_variable vars,
const char *  account,
struct ast_channel **  locked_channel 
)

Synchronously or asynchronously make an outbound call and send it to a particular application with given extension

Definition at line 5116 of file pbx.c.

References __ast_request_and_dial(), ast_channel::_state, outgoing_helper::account, async_stat::app, app_tmp::app, async_stat::appdata, ast_calloc, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), ast_channel_lock, ast_channel_unlock, ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, async_stat::chan, app_tmp::chan, app_tmp::data, free, ast_channel::hangupcause, LOG_WARNING, option_verbose, async_stat::p, ast_channel::pbx, app_tmp::t, async_stat::timeout, outgoing_helper::vars, and VERBOSE_PREFIX_4.

05117 {
05118    struct ast_channel *chan;
05119    struct app_tmp *tmp;
05120    int res = -1, cdr_res = -1;
05121    struct outgoing_helper oh;
05122    pthread_attr_t attr;
05123 
05124    memset(&oh, 0, sizeof(oh));
05125    oh.vars = vars;
05126    oh.account = account;
05127 
05128    if (locked_channel)
05129       *locked_channel = NULL;
05130    if (ast_strlen_zero(app)) {
05131       res = -1;
05132       goto outgoing_app_cleanup;
05133    }
05134    if (sync) {
05135       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
05136       if (chan) {
05137          if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */
05138             ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name);
05139          } else {
05140             chan->cdr = ast_cdr_alloc();   /* allocate a cdr for the channel */
05141             if(!chan->cdr) {
05142                /* allocation of the cdr failed */
05143                free(chan->pbx);
05144                res = -1;
05145                goto outgoing_app_cleanup;
05146             }
05147             /* allocation of the cdr was successful */
05148             ast_cdr_init(chan->cdr, chan);  /* initilize our channel's cdr */
05149             ast_cdr_start(chan->cdr);
05150          }
05151          ast_set_variables(chan, vars);
05152          if (account)
05153             ast_cdr_setaccount(chan, account);
05154          if (chan->_state == AST_STATE_UP) {
05155             res = 0;
05156             if (option_verbose > 3)
05157                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
05158             tmp = ast_calloc(1, sizeof(*tmp));
05159             if (!tmp)
05160                res = -1;
05161             else {
05162                ast_copy_string(tmp->app, app, sizeof(tmp->app));
05163                if (appdata)
05164                   ast_copy_string(tmp->data, appdata, sizeof(tmp->data));
05165                tmp->chan = chan;
05166                if (sync > 1) {
05167                   if (locked_channel)
05168                      ast_channel_unlock(chan);
05169                   ast_pbx_run_app(tmp);
05170                } else {
05171                   pthread_attr_init(&attr);
05172                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05173                   if (locked_channel)
05174                      ast_channel_lock(chan);
05175                   if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) {
05176                      ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
05177                      free(tmp);
05178                      if (locked_channel)
05179                         ast_channel_unlock(chan);
05180                      ast_hangup(chan);
05181                      res = -1;
05182                   } else {
05183                      if (locked_channel)
05184                         *locked_channel = chan;
05185                   }
05186                   pthread_attr_destroy(&attr);
05187                }
05188             }
05189          } else {
05190             if (option_verbose > 3)
05191                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
05192             if (chan->cdr) { /* update the cdr */
05193                /* here we update the status of the call, which sould be busy.
05194                 * if that fails then we set the status to failed */
05195                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
05196                   ast_cdr_failed(chan->cdr);
05197             }
05198             ast_hangup(chan);
05199          }
05200       }
05201 
05202       if (res < 0) { /* the call failed for some reason */
05203          if (*reason == 0) { /* if the call failed (not busy or no answer)
05204                         * update the cdr with the failed message */
05205             cdr_res = ast_pbx_outgoing_cdr_failed();
05206             if (cdr_res != 0) {
05207                res = cdr_res;
05208                goto outgoing_app_cleanup;
05209             }
05210          }
05211       }
05212 
05213    } else {
05214       struct async_stat *as;
05215       if (!(as = ast_calloc(1, sizeof(*as)))) {
05216          res = -1;
05217          goto outgoing_app_cleanup;
05218       }
05219       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
05220       if (!chan) {
05221          free(as);
05222          res = -1;
05223          goto outgoing_app_cleanup;
05224       }
05225       as->chan = chan;
05226       ast_copy_string(as->app, app, sizeof(as->app));
05227       if (appdata)
05228          ast_copy_string(as->appdata,  appdata, sizeof(as->appdata));
05229       as->timeout = timeout;
05230       ast_set_variables(chan, vars);
05231       if (account)
05232          ast_cdr_setaccount(chan, account);
05233       /* Start a new thread, and get something handling this channel. */
05234       pthread_attr_init(&attr);
05235       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05236       if (locked_channel)
05237          ast_channel_lock(chan);
05238       if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
05239          ast_log(LOG_WARNING, "Failed to start async wait\n");
05240          free(as);
05241          if (locked_channel)
05242             ast_channel_unlock(chan);
05243          ast_hangup(chan);
05244          res = -1;
05245          pthread_attr_destroy(&attr);
05246          goto outgoing_app_cleanup;
05247       } else {
05248          if (locked_channel)
05249             *locked_channel = chan;
05250       }
05251       pthread_attr_destroy(&attr);
05252       res = 0;
05253    }
05254 outgoing_app_cleanup:
05255    ast_variables_destroy(vars);
05256    return res;
05257 }

int ast_pbx_outgoing_exten ( const char *  type,
int  format,
void *  data,
int  timeout,
const char *  context,
const char *  exten,
int  priority,
int *  reason,
int  sync,
const char *  cid_num,
const char *  cid_name,
struct ast_variable vars,
const char *  account,
struct ast_channel **  locked_channel 
)

Synchronously or asynchronously make an outbound call and send it to a particular extension

Definition at line 4960 of file pbx.c.

References __ast_request_and_dial(), ast_channel::_state, ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_alloc(), ast_channel_lock, ast_channel_unlock, ast_exists_extension(), ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create, ast_request_and_dial(), ast_set_variables(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, async_stat::chan, async_stat::context, ast_channel::context, free, ast_channel::hangupcause, LOAD_OH, LOG_ERROR, LOG_WARNING, option_verbose, async_stat::p, set_ext_pri(), async_stat::timeout, and VERBOSE_PREFIX_4.

04961 {
04962    struct ast_channel *chan;
04963    struct async_stat *as;
04964    int res = -1, cdr_res = -1;
04965    struct outgoing_helper oh;
04966    pthread_attr_t attr;
04967 
04968    if (sync) {
04969       LOAD_OH(oh);
04970       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
04971       if (channel) {
04972          *channel = chan;
04973          if (chan)
04974             ast_channel_lock(chan);
04975       }
04976       if (chan) {
04977          if (chan->_state == AST_STATE_UP) {
04978                res = 0;
04979             if (option_verbose > 3)
04980                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
04981 
04982             if (sync > 1) {
04983                if (channel)
04984                   ast_channel_unlock(chan);
04985                if (ast_pbx_run(chan)) {
04986                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
04987                   if (channel)
04988                      *channel = NULL;
04989                   ast_hangup(chan);
04990                   res = -1;
04991                }
04992             } else {
04993                if (ast_pbx_start(chan)) {
04994                   ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name);
04995                   if (channel) {
04996                      *channel = NULL;
04997                      ast_channel_unlock(chan);
04998                   }
04999                   ast_hangup(chan);
05000                   res = -1;
05001                }
05002             }
05003          } else {
05004             if (option_verbose > 3)
05005                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
05006 
05007             if (chan->cdr) { /* update the cdr */
05008                /* here we update the status of the call, which sould be busy.
05009                 * if that fails then we set the status to failed */
05010                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
05011                   ast_cdr_failed(chan->cdr);
05012             }
05013 
05014             if (channel) {
05015                *channel = NULL;
05016                ast_channel_unlock(chan);
05017             }
05018             ast_hangup(chan);
05019          }
05020       }
05021 
05022       if (res < 0) { /* the call failed for some reason */
05023          if (*reason == 0) { /* if the call failed (not busy or no answer)
05024                         * update the cdr with the failed message */
05025             cdr_res = ast_pbx_outgoing_cdr_failed();
05026             if (cdr_res != 0) {
05027                res = cdr_res;
05028                goto outgoing_exten_cleanup;
05029             }
05030          }
05031 
05032          /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */
05033          /* check if "failed" exists */
05034          if (ast_exists_extension(chan, context, "failed", 1, NULL)) {
05035             chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed");
05036             if (chan) {
05037                if (!ast_strlen_zero(context))
05038                   ast_copy_string(chan->context, context, sizeof(chan->context));
05039                set_ext_pri(chan, "failed", 1);
05040                ast_set_variables(chan, vars);
05041                if (account)
05042                   ast_cdr_setaccount(chan, account);
05043                ast_pbx_run(chan);
05044             }
05045          }
05046       }
05047    } else {
05048       if (!(as = ast_calloc(1, sizeof(*as)))) {
05049          res = -1;
05050          goto outgoing_exten_cleanup;
05051       }
05052       chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
05053       if (channel) {
05054          *channel = chan;
05055          if (chan)
05056             ast_channel_lock(chan);
05057       }
05058       if (!chan) {
05059          free(as);
05060          res = -1;
05061          goto outgoing_exten_cleanup;
05062       }
05063       as->chan = chan;
05064       ast_copy_string(as->context, context, sizeof(as->context));
05065       set_ext_pri(as->chan,  exten, priority);
05066       as->timeout = timeout;
05067       ast_set_variables(chan, vars);
05068       if (account)
05069          ast_cdr_setaccount(chan, account);
05070       pthread_attr_init(&attr);
05071       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05072       if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
05073          ast_log(LOG_WARNING, "Failed to start async wait\n");
05074          free(as);
05075          if (channel) {
05076             *channel = NULL;
05077             ast_channel_unlock(chan);
05078          }
05079          ast_hangup(chan);
05080          res = -1;
05081          pthread_attr_destroy(&attr);
05082          goto outgoing_exten_cleanup;
05083       }
05084       pthread_attr_destroy(&attr);
05085       res = 0;
05086    }
05087 outgoing_exten_cleanup:
05088    ast_variables_destroy(vars);
05089    return res;
05090 }

enum ast_pbx_result ast_pbx_run ( struct ast_channel c  ) 

Execute the PBX in the current thread.

Parameters:
c channel to run the pbx on
This executes the PBX on a given channel. It allocates a new PBX structure for the channel, and provides all PBX functionality. See ast_pbx_start for an asynchronous function to run the PBX in a new thread as opposed to the current one.

Returns:
Zero on success, non-zero on failure

Definition at line 2637 of file pbx.c.

References __ast_pbx_run(), AST_PBX_CALL_LIMIT, AST_PBX_SUCCESS, decrease_call_count(), and increase_call_count().

02638 {
02639    enum ast_pbx_result res = AST_PBX_SUCCESS;
02640 
02641    if (increase_call_count(c))
02642       return AST_PBX_CALL_LIMIT;
02643 
02644    res = __ast_pbx_run(c);
02645    decrease_call_count();
02646 
02647    return res;
02648 }

enum ast_pbx_result ast_pbx_start ( struct ast_channel c  ) 

Create a new thread and start the PBX.

Parameters:
c channel to start the pbx on
See ast_pbx_run for a synchronous function to run the PBX in the current thread, as opposed to starting a new one.

Returns:
Zero on success, non-zero on failure

Definition at line 2611 of file pbx.c.

References ast_log(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_pthread_create, increase_call_count(), LOG_WARNING, pbx_thread(), and t.

02612 {
02613    pthread_t t;
02614    pthread_attr_t attr;
02615 
02616    if (!c) {
02617       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
02618       return AST_PBX_FAILED;
02619    }
02620 
02621    if (increase_call_count(c))
02622       return AST_PBX_CALL_LIMIT;
02623 
02624    /* Start a new thread, and get something handling this channel. */
02625    pthread_attr_init(&attr);
02626    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
02627    if (ast_pthread_create(&t, &attr, pbx_thread, c)) {
02628       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
02629       pthread_attr_destroy(&attr);
02630       return AST_PBX_FAILED;
02631    }
02632    pthread_attr_destroy(&attr);
02633 
02634    return AST_PBX_SUCCESS;
02635 }

int ast_register_application ( const char *  app,
int(*)(struct ast_channel *, void *)  execute,
const char *  synopsis,
const char *  description 
)

Register an application.

Parameters:
app Short name of the application
execute a function callback to execute the application. It should return non-zero if the channel needs to be hung up.
synopsis a short description (one line synopsis) of the application
description long description with all of the details about the use of the application
This registers an application with Asterisk's internal application list.
Note:
The individual applications themselves are responsible for registering and unregistering and unregistering their own CLI commands.
Return values:
0 success
-1 failure.

Definition at line 2939 of file pbx.c.

References ast_calloc, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), COLOR_BRCYAN, ast_app::description, ast_app::execute, LOG_WARNING, option_verbose, ast_app::synopsis, term_color(), and VERBOSE_PREFIX_2.

02940 {
02941    struct ast_app *tmp, *cur = NULL;
02942    char tmps[80];
02943    int length;
02944 
02945    AST_LIST_LOCK(&apps);
02946    AST_LIST_TRAVERSE(&apps, tmp, list) {
02947       if (!strcasecmp(app, tmp->name)) {
02948          ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
02949          AST_LIST_UNLOCK(&apps);
02950          return -1;
02951       }
02952    }
02953 
02954    length = sizeof(*tmp) + strlen(app) + 1;
02955 
02956    if (!(tmp = ast_calloc(1, length))) {
02957       AST_LIST_UNLOCK(&apps);
02958       return -1;
02959    }
02960 
02961    strcpy(tmp->name, app);
02962    tmp->execute = execute;
02963    tmp->synopsis = synopsis;
02964    tmp->description = description;
02965 
02966    /* Store in alphabetical order */
02967    AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) {
02968       if (strcasecmp(tmp->name, cur->name) < 0) {
02969          AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list);
02970          break;
02971       }
02972    }
02973    AST_LIST_TRAVERSE_SAFE_END
02974    if (!cur)
02975       AST_LIST_INSERT_TAIL(&apps, tmp, list);
02976 
02977    if (option_verbose > 1)
02978       ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
02979 
02980    AST_LIST_UNLOCK(&apps);
02981 
02982    return 0;
02983 }

int ast_register_switch ( struct ast_switch sw  ) 

Register an alternative dialplan switch.

Parameters:
sw switch to register
This function registers a populated ast_switch structure with the asterisk switching architecture.

Returns:
0 on success, and other than 0 on failure

Definition at line 2989 of file pbx.c.

References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), LOG_WARNING, and ast_switch::name.

02990 {
02991    struct ast_switch *tmp;
02992 
02993    AST_LIST_LOCK(&switches);
02994    AST_LIST_TRAVERSE(&switches, tmp, list) {
02995       if (!strcasecmp(tmp->name, sw->name)) {
02996          AST_LIST_UNLOCK(&switches);
02997          ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
02998          return -1;
02999       }
03000    }
03001    AST_LIST_INSERT_TAIL(&switches, sw, list);
03002    AST_LIST_UNLOCK(&switches);
03003 
03004    return 0;
03005 }

int ast_spawn_extension ( struct ast_channel c,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid 
)

Launch a new extension (i.e. new stack).

Parameters:
c not important
context which context to generate the extension within
exten new extension to add
priority priority of new extension
callerid callerid of extension
This adds a new extension to the asterisk extension list.

Return values:
0 on success
-1 on failure.

Definition at line 2286 of file pbx.c.

References E_SPAWN, and pbx_extension_helper().

02287 {
02288    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN);
02289 }

int ast_unlock_context ( struct ast_context con  ) 

Return values:
Unlocks the given context
Parameters:
con context to unlock
Return values:
0 on success
-1 on failure

Definition at line 6079 of file pbx.c.

References ast_mutex_unlock(), and ast_context::lock.

06080 {
06081    return ast_mutex_unlock(&con->lock);
06082 }

int ast_unlock_contexts ( void   ) 

Unlocks contexts.

Return values:
0 on success
-1 on failure

Definition at line 6066 of file pbx.c.

References ast_mutex_unlock().

06067 {
06068    return ast_mutex_unlock(&conlock);
06069 }

int ast_unregister_application ( const char *  app  ) 

Unregister an application.

Parameters:
app name of the application (does not have to be the same string as the one that was registered)
This unregisters an application from Asterisk's internal application list.

Return values:
0 success
-1 failure

Definition at line 3820 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), free, option_verbose, and VERBOSE_PREFIX_2.

03821 {
03822    struct ast_app *tmp;
03823 
03824    AST_LIST_LOCK(&apps);
03825    AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) {
03826       if (!strcasecmp(app, tmp->name)) {
03827          AST_LIST_REMOVE_CURRENT(&apps, list);
03828          if (option_verbose > 1)
03829             ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
03830          free(tmp);
03831          break;
03832       }
03833    }
03834    AST_LIST_TRAVERSE_SAFE_END
03835    AST_LIST_UNLOCK(&apps);
03836 
03837    return tmp ? 0 : -1;
03838 }

void ast_unregister_switch ( struct ast_switch sw  ) 

Unregister an alternative switch.

Parameters:
sw switch to unregister
Unregisters a switch from asterisk.

Returns:
nothing

Definition at line 3007 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_REMOVE, and AST_LIST_UNLOCK.

03008 {
03009    AST_LIST_LOCK(&switches);
03010    AST_LIST_REMOVE(&switches, sw, list);
03011    AST_LIST_UNLOCK(&switches);
03012 }

struct ast_exten* ast_walk_context_extensions ( struct ast_context con,
struct ast_exten priority 
) [read]

Definition at line 6188 of file pbx.c.

References ast_exten::next, and ast_context::root.

06190 {
06191    if (!exten)
06192       return con ? con->root : NULL;
06193    else
06194       return exten->next;
06195 }

struct ast_ignorepat* ast_walk_context_ignorepats ( struct ast_context con,
struct ast_ignorepat ip 
) [read]

Definition at line 6221 of file pbx.c.

References ast_context::ignorepats, and ast_ignorepat::next.

06223 {
06224    if (!ip)
06225       return con ? con->ignorepats : NULL;
06226    else
06227       return ip->next;
06228 }

struct ast_include* ast_walk_context_includes ( struct ast_context con,
struct ast_include inc 
) [read]

Definition at line 6212 of file pbx.c.

References ast_context::includes, and ast_include::next.

06214 {
06215    if (!inc)
06216       return con ? con->includes : NULL;
06217    else
06218       return inc->next;
06219 }

struct ast_sw* ast_walk_context_switches ( struct ast_context con,
struct ast_sw sw 
) [read]

Definition at line 6197 of file pbx.c.

References AST_LIST_FIRST, and AST_LIST_NEXT.

06199 {
06200    if (!sw)
06201       return con ? AST_LIST_FIRST(&con->alts) : NULL;
06202    else
06203       return AST_LIST_NEXT(sw, list);
06204 }

struct ast_context* ast_walk_contexts ( struct ast_context con  )  [read]

Definition at line 6183 of file pbx.c.

References contexts, and ast_context::next.

06184 {
06185    return con ? con->next : contexts;
06186 }

struct ast_exten* ast_walk_extension_priorities ( struct ast_exten exten,
struct ast_exten priority 
) [read]

Definition at line 6206 of file pbx.c.

References ast_exten::peer.

06208 {
06209    return priority ? priority->peer : exten;
06210 }

void pbx_builtin_clear_globals ( void   ) 

Definition at line 5937 of file pbx.c.

References AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), ast_var_delete(), and globals.

05938 {
05939    struct ast_var_t *vardata;
05940 
05941    ast_mutex_lock(&globalslock);
05942    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
05943       ast_var_delete(vardata);
05944    ast_mutex_unlock(&globalslock);
05945 }

const char* pbx_builtin_getvar_helper ( struct ast_channel chan,
const char *  name 
)

Definition at line 5737 of file pbx.c.

References AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), globals, and ast_channel::varshead.

05738 {
05739    struct ast_var_t *variables;
05740    const char *ret = NULL;
05741    int i;
05742    struct varshead *places[2] = { NULL, &globals };
05743 
05744    if (!name)
05745       return NULL;
05746    if (chan)
05747       places[0] = &chan->varshead;
05748 
05749    for (i = 0; i < 2; i++) {
05750       if (!places[i])
05751          continue;
05752       if (places[i] == &globals)
05753          ast_mutex_lock(&globalslock);
05754       AST_LIST_TRAVERSE(places[i], variables, entries) {
05755          if (!strcmp(name, ast_var_name(variables))) {
05756             ret = ast_var_value(variables);
05757             break;
05758          }
05759       }
05760       if (places[i] == &globals)
05761          ast_mutex_unlock(&globalslock);
05762       if (ret)
05763          break;
05764    }
05765 
05766    return ret;
05767 }

void pbx_builtin_pushvar_helper ( struct ast_channel chan,
const char *  name,
const char *  value 
)

Definition at line 5769 of file pbx.c.

References ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_verbose(), globals, LOG_WARNING, option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2.

05770 {
05771    struct ast_var_t *newvariable;
05772    struct varshead *headp;
05773 
05774    if (name[strlen(name)-1] == ')') {
05775       char *function = ast_strdupa(name);
05776 
05777       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
05778       ast_func_write(chan, function, value);
05779       return;
05780    }
05781 
05782    headp = (chan) ? &chan->varshead : &globals;
05783 
05784    if (value) {
05785       if ((option_verbose > 1) && (headp == &globals))
05786          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05787       newvariable = ast_var_assign(name, value);
05788       if (headp == &globals)
05789          ast_mutex_lock(&globalslock);
05790       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05791       if (headp == &globals)
05792          ast_mutex_unlock(&globalslock);
05793    }
05794 }

int pbx_builtin_serialize_variables ( struct ast_channel chan,
char *  buf,
size_t  size 
)

Definition at line 5710 of file pbx.c.

References ast_build_string(), AST_LIST_TRAVERSE, ast_log(), ast_var_name(), ast_var_value(), LOG_ERROR, total, var, and ast_channel::varshead.

05711 {
05712    struct ast_var_t *variables;
05713    const char *var, *val;
05714    int total = 0;
05715 
05716    if (!chan)
05717       return 0;
05718 
05719    memset(buf, 0, size);
05720 
05721    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
05722       if ((var=ast_var_name(variables)) && (val=ast_var_value(variables))
05723          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
05724          ) {
05725          if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) {
05726             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
05727             break;
05728          } else
05729             total++;
05730       } else
05731          break;
05732    }
05733 
05734    return total;
05735 }

int pbx_builtin_setvar ( struct ast_channel chan,
void *  data 
)

void pbx_builtin_setvar_helper ( struct ast_channel chan,
const char *  name,
const char *  value 
)

Definition at line 5796 of file pbx.c.

References ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verbose(), globals, option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2.

05797 {
05798    struct ast_var_t *newvariable;
05799    struct varshead *headp;
05800    const char *nametail = name;
05801 
05802    /* XXX may need locking on the channel ? */
05803    if (name[strlen(name)-1] == ')') {
05804       char *function = ast_strdupa(name);
05805 
05806       ast_func_write(chan, function, value);
05807       return;
05808    }
05809 
05810    headp = (chan) ? &chan->varshead : &globals;
05811 
05812    /* For comparison purposes, we have to strip leading underscores */
05813    if (*nametail == '_') {
05814       nametail++;
05815       if (*nametail == '_')
05816          nametail++;
05817    }
05818 
05819    if (headp == &globals)
05820       ast_mutex_lock(&globalslock);
05821    AST_LIST_TRAVERSE (headp, newvariable, entries) {
05822       if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
05823          /* there is already such a variable, delete it */
05824          AST_LIST_REMOVE(headp, newvariable, entries);
05825          ast_var_delete(newvariable);
05826          break;
05827       }
05828    }
05829 
05830    if (value) {
05831       if ((option_verbose > 1) && (headp == &globals))
05832          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05833       newvariable = ast_var_assign(name, value);
05834       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05835    }
05836 
05837    if (headp == &globals)
05838       ast_mutex_unlock(&globalslock);
05839 }

int pbx_checkcondition ( const char *  condition  ) 

Evaluate a condition.

Return values:
0 if the condition is NULL or of zero length
int If the string is an integer, the integer representation of the integer is returned
1 Any other non-empty string

Definition at line 5947 of file pbx.c.

References ast_strlen_zero().

05948 {
05949    if (ast_strlen_zero(condition))  /* NULL or empty strings are false */
05950       return 0;
05951    else if (*condition >= '0' && *condition <= '9')   /* Numbers are evaluated for truth */
05952       return atoi(condition);
05953    else  /* Strings are true */
05954       return 1;
05955 }

int pbx_exec ( struct ast_channel c,
struct ast_app app,
void *  data 
)

Execute an application.

Parameters:
c channel to execute on
app which app to execute
data the data passed into the app
This application executes an application on a given channel. It saves the stack and executes the given appliation passing in the given data.

Returns:
0 on success, and -1 on failure
Parameters:
c  Channel
app  Application
data  Data for execution

Definition at line 510 of file pbx.c.

References ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_channel::cdr, ast_channel::data, and ast_app::execute.

00513 {
00514    int res;
00515 
00516    const char *saved_c_appl;
00517    const char *saved_c_data;
00518 
00519    if (c->cdr &&  !ast_check_hangup(c))
00520       ast_cdr_setapp(c->cdr, app->name, data);
00521 
00522    /* save channel values */
00523    saved_c_appl= c->appl;
00524    saved_c_data= c->data;
00525 
00526    c->appl = app->name;
00527    c->data = data;
00528    /* XXX remember what to to when we have linked apps to modules */
00529    if (app->module) {
00530       /* XXX LOCAL_USER_ADD(app->module) */
00531    }
00532    res = app->execute(c, data);
00533    if (app->module) {
00534       /* XXX LOCAL_USER_REMOVE(app->module) */
00535    }
00536    /* restore channel values */
00537    c->appl = saved_c_appl;
00538    c->data = saved_c_data;
00539    return res;
00540 }

struct ast_app* pbx_findapp ( const char *  app  )  [read]

Look up an application.

Parameters:
app name of the app
This function searches for the ast_app structure within the apps that are registered for the one with the name you passed in.

Returns:
the ast_app structure that matches on success, or NULL on failure

Definition at line 548 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.

00549 {
00550    struct ast_app *tmp;
00551 
00552    AST_LIST_LOCK(&apps);
00553    AST_LIST_TRAVERSE(&apps, tmp, list) {
00554       if (!strcasecmp(tmp->name, app))
00555          break;
00556    }
00557    AST_LIST_UNLOCK(&apps);
00558 
00559    return tmp;
00560 }

void pbx_retrieve_variable ( struct ast_channel c,
const char *  var,
char **  ret,
char *  workspace,
int  workspacelen,
struct varshead *  headp 
)

pbx_retrieve_variable: Support for Asterisk built-in variables ---

Definition at line 1128 of file pbx.c.

References ast_config_AST_SYSTEM_NAME, ast_get_hint(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_name(), ast_var_value(), ast_channel::cid, ast_callerid::cid_ani2, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, globals, ast_channel::hangupcause, offset, parse_variable_name(), ast_channel::priority, s, substring(), and ast_channel::varshead.

01129 {
01130    const char not_found = '\0';
01131    char *tmpvar;
01132    const char *s; /* the result */
01133    int offset, length;
01134    int i, need_substring;
01135    struct varshead *places[2] = { headp, &globals };  /* list of places where we may look */
01136 
01137    if (c) {
01138       places[0] = &c->varshead;
01139    }
01140    /*
01141     * Make a copy of var because parse_variable_name() modifies the string.
01142     * Then if called directly, we might need to run substring() on the result;
01143     * remember this for later in 'need_substring', 'offset' and 'length'
01144     */
01145    tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */
01146    need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
01147 
01148    /*
01149     * Look first into predefined variables, then into variable lists.
01150     * Variable 's' points to the result, according to the following rules:
01151     * s == &not_found (set at the beginning) means that we did not find a
01152     * matching variable and need to look into more places.
01153     * If s != &not_found, s is a valid result string as follows:
01154     * s = NULL if the variable does not have a value;
01155     * you typically do this when looking for an unset predefined variable.
01156     * s = workspace if the result has been assembled there;
01157     * typically done when the result is built e.g. with an snprintf(),
01158     * so we don't need to do an additional copy.
01159     * s != workspace in case we have a string, that needs to be copied
01160     * (the ast_copy_string is done once for all at the end).
01161     * Typically done when the result is already available in some string.
01162     */
01163    s = &not_found;   /* default value */
01164    if (c) { /* This group requires a valid channel */
01165       /* Names with common parts are looked up a piece at a time using strncmp. */
01166       if (!strncmp(var, "CALL", 4)) {
01167          if (!strncmp(var + 4, "ING", 3)) {
01168             if (!strcmp(var + 7, "PRES")) {        /* CALLINGPRES */
01169                snprintf(workspace, workspacelen, "%d", c->cid.cid_pres);
01170                s = workspace;
01171             } else if (!strcmp(var + 7, "ANI2")) {    /* CALLINGANI2 */
01172                snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2);
01173                s = workspace;
01174             } else if (!strcmp(var + 7, "TON")) {     /* CALLINGTON */
01175                snprintf(workspace, workspacelen, "%d", c->cid.cid_ton);
01176                s = workspace;
01177             } else if (!strcmp(var + 7, "TNS")) {     /* CALLINGTNS */
01178                snprintf(workspace, workspacelen, "%d", c->cid.cid_tns);
01179                s = workspace;
01180             }
01181          }
01182       } else if (!strcmp(var, "HINT")) {
01183          s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL;
01184       } else if (!strcmp(var, "HINTNAME")) {
01185          s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL;
01186       } else if (!strcmp(var, "EXTEN")) {
01187          s = c->exten;
01188       } else if (!strcmp(var, "CONTEXT")) {
01189          s = c->context;
01190       } else if (!strcmp(var, "PRIORITY")) {
01191          snprintf(workspace, workspacelen, "%d", c->priority);
01192          s = workspace;
01193       } else if (!strcmp(var, "CHANNEL")) {
01194          s = c->name;
01195       } else if (!strcmp(var, "UNIQUEID")) {
01196          s = c->uniqueid;
01197       } else if (!strcmp(var, "HANGUPCAUSE")) {
01198          snprintf(workspace, workspacelen, "%d", c->hangupcause);
01199          s = workspace;
01200       }
01201    }
01202    if (s == &not_found) { /* look for more */
01203       if (!strcmp(var, "EPOCH")) {
01204          snprintf(workspace, workspacelen, "%u",(int)time(NULL));
01205          s = workspace;
01206       } else if (!strcmp(var, "SYSTEMNAME")) {
01207          s = ast_config_AST_SYSTEM_NAME;
01208       }
01209    }
01210    /* if not found, look into chanvars or global vars */
01211    for (i = 0; s == &not_found && i < (sizeof(places) / sizeof(places[0])); i++) {
01212       struct ast_var_t *variables;
01213       if (!places[i])
01214          continue;
01215       if (places[i] == &globals)
01216          ast_mutex_lock(&globalslock);
01217       AST_LIST_TRAVERSE(places[i], variables, entries) {
01218          if (strcasecmp(ast_var_name(variables), var)==0) {
01219             s = ast_var_value(variables);
01220             break;
01221          }
01222       }
01223       if (places[i] == &globals)
01224          ast_mutex_unlock(&globalslock);
01225    }
01226    if (s == &not_found || s == NULL)
01227       *ret = NULL;
01228    else {
01229       if (s != workspace)
01230          ast_copy_string(workspace, s, workspacelen);
01231       *ret = workspace;
01232       if (need_substring)
01233          *ret = substring(*ret, offset, length, workspace, workspacelen);
01234    }
01235 }

int pbx_set_autofallthrough ( int  newval  ) 

Set "autofallthrough" flag, if newval is <0, does not acutally set. If set to 1, sets to auto fall through. If newval set to 0, sets to no auto fall through (reads extension instead). Returns previous value.

Definition at line 2655 of file pbx.c.

References autofallthrough.

02656 {
02657    int oldval = autofallthrough;
02658    autofallthrough = newval;
02659    return oldval;
02660 }

void pbx_substitute_variables_helper ( struct ast_channel c,
const char *  cp1,
char *  cp2,
int  count 
)

Definition at line 1739 of file pbx.c.

References pbx_substitute_variables_helper_full(), and ast_channel::varshead.

01740 {
01741    pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
01742 }

void pbx_substitute_variables_varshead ( struct varshead *  headp,
const char *  cp1,
char *  cp2,
int  count 
)

Definition at line 1744 of file pbx.c.

References pbx_substitute_variables_helper_full().

01745 {
01746    pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
01747 }


Generated on Wed Aug 15 01:25:23 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.3