Tue Nov 4 13:20:41 2008

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"

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).
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).
ast_contextast_context_find (const char *name)
 Find a context.
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.
ast_custom_functionast_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)
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_rdlock_contexts (void)
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.
ast_extenast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority)
ast_ignorepatast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip)
ast_includeast_walk_context_includes (struct ast_context *con, struct ast_include *inc)
ast_swast_walk_context_switches (struct ast_context *con, struct ast_sw *sw)
ast_contextast_walk_contexts (struct ast_context *con)
ast_extenast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority)
int ast_wrlock_contexts (void)
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.
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(), and handle_show_function_deprecated().

#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(), 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(), ast_merge_contexts_and_delete(), 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(), and print_ext().


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 2708 of file pbx.c.

References countcalls.

Referenced by handle_chanlist(), and handle_chanlist_deprecated().

02709 {
02710    return countcalls;
02711 }

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 4585 of file pbx.c.

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

Referenced by handle_context_add_extension(), handle_context_add_extension_deprecated(), park_add_hints(), and register_peer_exten().

04588 {
04589    int ret = -1;
04590    struct ast_context *c = find_context_locked(context);
04591 
04592    if (c) {
04593       ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
04594          application, data, datad, registrar);
04595       ast_unlock_contexts();
04596    }
04597    return ret;
04598 }

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 *.

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 4794 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, errno, ext_cmp(), ext_strncpy(), ast_exten::exten, ast_exten::label, ast_context::lock, ast_exten::matchcid, ast_exten::next, 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.

Referenced by add_extensions(), ast_add_extension(), do_parking_thread(), park_call_full(), pbx_load_config(), and pbx_load_users().

04798 {
04799    /*
04800     * Sort extensions (or patterns) according to the rules indicated above.
04801     * These are implemented by the function ext_cmp()).
04802     * All priorities for the same ext/pattern/cid are kept in a list,
04803     * using the 'peer' field  as a link field..
04804     */
04805    struct ast_exten *tmp, *e, *el = NULL;
04806    int res;
04807    int length;
04808    char *p;
04809    char expand_buf[VAR_BUF_SIZE] = { 0, };
04810 
04811    /* if we are adding a hint, and there are global variables, and the hint
04812       contains variable references, then expand them
04813    */
04814    ast_mutex_lock(&globalslock);
04815    if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) {
04816       pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf));
04817       application = expand_buf;
04818    }
04819    ast_mutex_unlock(&globalslock);
04820 
04821    length = sizeof(struct ast_exten);
04822    length += strlen(extension) + 1;
04823    length += strlen(application) + 1;
04824    if (label)
04825       length += strlen(label) + 1;
04826    if (callerid)
04827       length += strlen(callerid) + 1;
04828    else
04829       length ++;  /* just the '\0' */
04830 
04831    /* Be optimistic:  Build the extension structure first */
04832    if (!(tmp = ast_calloc(1, length)))
04833       return -1;
04834 
04835    /* use p as dst in assignments, as the fields are const char * */
04836    p = tmp->stuff;
04837    if (label) {
04838       tmp->label = p;
04839       strcpy(p, label);
04840       p += strlen(label) + 1;
04841    }
04842    tmp->exten = p;
04843    p += ext_strncpy(p, extension, strlen(extension) + 1) + 1;
04844    tmp->priority = priority;
04845    tmp->cidmatch = p;   /* but use p for assignments below */
04846    if (callerid) {
04847       p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1;
04848       tmp->matchcid = 1;
04849    } else {
04850       *p++ = '\0';
04851       tmp->matchcid = 0;
04852    }
04853    tmp->app = p;
04854    strcpy(p, application);
04855    tmp->parent = con;
04856    tmp->data = data;
04857    tmp->datad = datad;
04858    tmp->registrar = registrar;
04859 
04860    ast_mutex_lock(&con->lock);
04861    res = 0; /* some compilers will think it is uninitialized otherwise */
04862    for (e = con->root; e; el = e, e = e->next) {   /* scan the extension list */
04863       res = ext_cmp(e->exten, extension);
04864       if (res == 0) { /* extension match, now look at cidmatch */
04865          if (!e->matchcid && !tmp->matchcid)
04866             res = 0;
04867          else if (tmp->matchcid && !e->matchcid)
04868             res = 1;
04869          else if (e->matchcid && !tmp->matchcid)
04870             res = -1;
04871          else
04872             res = strcasecmp(e->cidmatch, tmp->cidmatch);
04873       }
04874       if (res >= 0)
04875          break;
04876    }
04877    if (e && res == 0) { /* exact match, insert in the pri chain */
04878       res = add_pri(con, tmp, el, e, replace);
04879       ast_mutex_unlock(&con->lock);
04880       if (res < 0) {
04881          errno = EEXIST;   /* XXX do we care ? */
04882          return 0; /* XXX should we return -1 maybe ? */
04883       }
04884    } else {
04885       /*
04886        * not an exact match, this is the first entry with this pattern,
04887        * so insert in the main list right before 'e' (if any)
04888        */
04889       tmp->next = e;
04890       if (el)
04891          el->next = tmp;
04892       else
04893          con->root = tmp;
04894       ast_mutex_unlock(&con->lock);
04895       if (tmp->priority == PRIORITY_HINT)
04896          ast_add_hint(tmp);
04897    }
04898    if (option_debug) {
04899       if (tmp->matchcid) {
04900          if (option_debug)
04901             ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n",
04902                tmp->exten, tmp->priority, tmp->cidmatch, con->name);
04903       } else {
04904          if (option_debug)
04905             ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n",
04906                tmp->exten, tmp->priority, con->name);
04907       }
04908    }
04909    if (option_verbose > 2) {
04910       if (tmp->matchcid) {
04911          ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n",
04912             tmp->exten, tmp->priority, tmp->cidmatch, con->name);
04913       } else {
04914          ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n",
04915             tmp->exten, tmp->priority, con->name);
04916       }
04917    }
04918    return 0;
04919 }

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

Definition at line 4623 of file pbx.c.

References ast_channel::_state, ast_channel::amaflags, ast_cdr_discard(), 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.

Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), console_transfer_deprecated(), handle_request_bye(), handle_request_refer(), process_ast_dsp(), socket_process(), and zt_handle_dtmfup().

04624 {
04625    int res = 0;
04626 
04627    ast_channel_lock(chan);
04628 
04629    if (chan->pbx) { /* This channel is currently in the PBX */
04630       ast_explicit_goto(chan, context, exten, priority);
04631       ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
04632    } else {
04633       /* In order to do it when the channel doesn't really exist within
04634          the PBX, we have to make a new channel, masquerade, and start the PBX
04635          at the new location */
04636       struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name);
04637       if (!tmpchan) {
04638          res = -1;
04639       } else {
04640          if (chan->cdr) {
04641             ast_cdr_discard(tmpchan->cdr);
04642             tmpchan->cdr = ast_cdr_dup(chan->cdr);  /* share the love */
04643          }
04644          /* Make formats okay */
04645          tmpchan->readformat = chan->readformat;
04646          tmpchan->writeformat = chan->writeformat;
04647          /* Setup proper location */
04648          ast_explicit_goto(tmpchan,
04649             S_OR(context, chan->context), S_OR(exten, chan->exten), priority);
04650 
04651          /* Masquerade into temp channel */
04652          ast_channel_masquerade(tmpchan, chan);
04653 
04654          /* Grab the locks and get going */
04655          ast_channel_lock(tmpchan);
04656          ast_do_masquerade(tmpchan);
04657          ast_channel_unlock(tmpchan);
04658          /* Start the PBX going on our stolen channel */
04659          if (ast_pbx_start(tmpchan)) {
04660             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
04661             ast_hangup(tmpchan);
04662             res = -1;
04663          }
04664       }
04665    }
04666    ast_channel_unlock(chan);
04667    return res;
04668 }

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

Definition at line 4670 of file pbx.c.

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

04671 {
04672    struct ast_channel *chan;
04673    int res = -1;
04674 
04675    chan = ast_get_channel_by_name_locked(channame);
04676    if (chan) {
04677       res = ast_async_goto(chan, context, exten, priority);
04678       ast_channel_unlock(chan);
04679    }
04680    return res;
04681 }

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

Note:
This function will handle locking the channel as needed.

Definition at line 6482 of file pbx.c.

References __ast_goto_if_exists().

Referenced by asyncgoto_exec().

06483 {
06484    return __ast_goto_if_exists(chan, context, exten, priority, 1);
06485 }

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

Definition at line 4268 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().

Referenced by ast_context_add_include2(), iftime(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().

04269 {
04270    char info_save[256];
04271    char *info;
04272 
04273    /* Check for empty just in case */
04274    if (ast_strlen_zero(info_in))
04275       return 0;
04276    /* make a copy just in case we were passed a static string */
04277    ast_copy_string(info_save, info_in, sizeof(info_save));
04278    info = info_save;
04279    /* Assume everything except time */
04280    i->monthmask = 0xfff;   /* 12 bits */
04281    i->daymask = 0x7fffffffU; /* 31 bits */
04282    i->dowmask = 0x7f; /* 7 bits */
04283    /* on each call, use strsep() to move info to the next argument */
04284    get_timerange(i, strsep(&info, "|"));
04285    if (info)
04286       i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week");
04287    if (info)
04288       i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day");
04289    if (info)
04290       i->monthmask = get_range(strsep(&info, "|"), 12, months, "month");
04291    return 1;
04292 }

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 2330 of file pbx.c.

References E_CANMATCH, and pbx_extension_helper().

Referenced by background_detect_exec(), cb_events(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), handle_link_data(), handle_link_phone_dtmf(), local_dtmf_helper(), loopback_canmatch(), mgcp_ss(), phone_check_exception(), skinny_ss(), ss_thread(), and valid_exit().

02331 {
02332    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH);
02333 }

int ast_check_timing ( const struct ast_timing i  ) 

Definition at line 4294 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.

Referenced by iftime(), include_valid(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().

04295 {
04296    struct tm tm;
04297    time_t t = time(NULL);
04298 
04299    ast_localtime(&t, &tm, NULL);
04300 
04301    /* If it's not the right month, return */
04302    if (!(i->monthmask & (1 << tm.tm_mon)))
04303       return 0;
04304 
04305    /* If it's not that time of the month.... */
04306    /* Warning, tm_mday has range 1..31! */
04307    if (!(i->daymask & (1 << (tm.tm_mday-1))))
04308       return 0;
04309 
04310    /* If it's not the right day of the week */
04311    if (!(i->dowmask & (1 << tm.tm_wday)))
04312       return 0;
04313 
04314    /* Sanity check the hour just to be safe */
04315    if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
04316       ast_log(LOG_WARNING, "Insane time...\n");
04317       return 0;
04318    }
04319 
04320    /* Now the tough part, we calculate if it fits
04321       in the right time based on min/hour */
04322    if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
04323       return 0;
04324 
04325    /* If we got this far, then we're good */
04326    return 1;
04327 }

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 4521 of file pbx.c.

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

Referenced by handle_context_add_ignorepat(), and handle_context_add_ignorepat_deprecated().

04522 {
04523    int ret = -1;
04524    struct ast_context *c = find_context_locked(context);
04525 
04526    if (c) {
04527       ret = ast_context_add_ignorepat2(c, value, registrar);
04528       ast_unlock_contexts();
04529    }
04530    return ret;
04531 }

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

Definition at line 4533 of file pbx.c.

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

Referenced by ast_context_add_ignorepat(), and pbx_load_config().

04534 {
04535    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
04536    int length;
04537    length = sizeof(struct ast_ignorepat);
04538    length += strlen(value) + 1;
04539    if (!(ignorepat = ast_calloc(1, length)))
04540       return -1;
04541    /* The cast to char * is because we need to write the initial value.
04542     * The field is not supposed to be modified otherwise
04543     */
04544    strcpy((char *)ignorepat->pattern, value);
04545    ignorepat->next = NULL;
04546    ignorepat->registrar = registrar;
04547    ast_mutex_lock(&con->lock);
04548    for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
04549       ignorepatl = ignorepatc;
04550       if (!strcasecmp(ignorepatc->pattern, value)) {
04551          /* Already there */
04552          ast_mutex_unlock(&con->lock);
04553          errno = EEXIST;
04554          return -1;
04555       }
04556    }
04557    if (ignorepatl)
04558       ignorepatl->next = ignorepat;
04559    else
04560       con->ignorepats = ignorepat;
04561    ast_mutex_unlock(&con->lock);
04562    return 0;
04563 
04564 }

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 4074 of file pbx.c.

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

Referenced by handle_context_add_include(), and handle_context_add_include_deprecated().

04075 {
04076    int ret = -1;
04077    struct ast_context *c = find_context_locked(context);
04078 
04079    if (c) {
04080       ret = ast_context_add_include2(c, include, registrar);
04081       ast_unlock_contexts();
04082    }
04083    return ret;
04084 }

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 4336 of file pbx.c.

References ast_build_timing(), ast_calloc, ast_get_context_name(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), errno, 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.

Referenced by ast_context_add_include(), and pbx_load_config().

04338 {
04339    struct ast_include *new_include;
04340    char *c;
04341    struct ast_include *i, *il = NULL; /* include, include_last */
04342    int length;
04343    char *p;
04344 
04345    length = sizeof(struct ast_include);
04346    length += 2 * (strlen(value) + 1);
04347 
04348    /* allocate new include structure ... */
04349    if (!(new_include = ast_calloc(1, length)))
04350       return -1;
04351    /* Fill in this structure. Use 'p' for assignments, as the fields
04352     * in the structure are 'const char *'
04353     */
04354    p = new_include->stuff;
04355    new_include->name = p;
04356    strcpy(p, value);
04357    p += strlen(value) + 1;
04358    new_include->rname = p;
04359    strcpy(p, value);
04360    /* Strip off timing info, and process if it is there */
04361    if ( (c = strchr(p, '|')) ) {
04362       *c++ = '\0';
04363            new_include->hastime = ast_build_timing(&(new_include->timing), c);
04364    }
04365    new_include->next      = NULL;
04366    new_include->registrar = registrar;
04367 
04368    ast_mutex_lock(&con->lock);
04369 
04370    /* ... go to last include and check if context is already included too... */
04371    for (i = con->includes; i; i = i->next) {
04372       if (!strcasecmp(i->name, new_include->name)) {
04373          free(new_include);
04374          ast_mutex_unlock(&con->lock);
04375          errno = EEXIST;
04376          return -1;
04377       }
04378       il = i;
04379    }
04380 
04381    /* ... include new context into context list, unlock, return */
04382    if (il)
04383       il->next = new_include;
04384    else
04385       con->includes = new_include;
04386    if (option_verbose > 2)
04387       ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
04388    ast_mutex_unlock(&con->lock);
04389 
04390    return 0;
04391 }

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 4398 of file pbx.c.

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

04399 {
04400    int ret = -1;
04401    struct ast_context *c = find_context_locked(context);
04402 
04403    if (c) { /* found, add switch to this context */
04404       ret = ast_context_add_switch2(c, sw, data, eval, registrar);
04405       ast_unlock_contexts();
04406    }
04407    return ret;
04408 }

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 4417 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, errno, ast_sw::eval, free, ast_context::lock, ast_sw::name, option_verbose, ast_sw::registrar, and VERBOSE_PREFIX_3.

Referenced by ast_context_add_switch(), and pbx_load_config().

04419 {
04420    struct ast_sw *new_sw;
04421    struct ast_sw *i;
04422    int length;
04423    char *p;
04424 
04425    length = sizeof(struct ast_sw);
04426    length += strlen(value) + 1;
04427    if (data)
04428       length += strlen(data);
04429    length++;
04430 
04431    /* allocate new sw structure ... */
04432    if (!(new_sw = ast_calloc(1, length)))
04433       return -1;
04434    /* ... fill in this structure ... */
04435    p = new_sw->stuff;
04436    new_sw->name = p;
04437    strcpy(new_sw->name, value);
04438    p += strlen(value) + 1;
04439    new_sw->data = p;
04440    if (data) {
04441       strcpy(new_sw->data, data);
04442       p += strlen(data) + 1;
04443    } else {
04444       strcpy(new_sw->data, "");
04445       p++;
04446    }
04447    new_sw->eval     = eval;
04448    new_sw->registrar = registrar;
04449 
04450    /* ... try to lock this context ... */
04451    ast_mutex_lock(&con->lock);
04452 
04453    /* ... go to last sw and check if context is already swd too... */
04454    AST_LIST_TRAVERSE(&con->alts, i, list) {
04455       if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
04456          free(new_sw);
04457          ast_mutex_unlock(&con->lock);
04458          errno = EEXIST;
04459          return -1;
04460       }
04461    }
04462 
04463    /* ... sw new context into context list, unlock, return */
04464    AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
04465 
04466    if (option_verbose > 2)
04467       ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
04468 
04469    ast_mutex_unlock(&con->lock);
04470 
04471    return 0;
04472 }

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

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 3944 of file pbx.c.

References __ast_context_create().

Referenced by do_parking_thread(), park_call_full(), and set_config().

03945 {
03946    return __ast_context_create(extcontexts, name, registrar, 0);
03947 }

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 5386 of file pbx.c.

References __ast_context_destroy(), ast_unlock_contexts(), and ast_wrlock_contexts().

Referenced by cleanup_stale_contexts(), sla_destroy(), and unload_module().

05387 {
05388    ast_wrlock_contexts();
05389    __ast_context_destroy(con,registrar);
05390    ast_unlock_contexts();
05391 }

struct ast_context* ast_context_find ( const char *  name  ) 

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 917 of file pbx.c.

References ast_rdlock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().

Referenced by _macro_exec(), ast_context_verify_includes(), ast_ignore_pattern(), cleanup_stale_contexts(), do_parking_thread(), park_call_full(), park_exec(), register_peer_exten(), and set_config().

00918 {
00919    struct ast_context *tmp = NULL;
00920 
00921    ast_rdlock_contexts();
00922 
00923    while ( (tmp = ast_walk_contexts(tmp)) ) {
00924       if (!name || !strcasecmp(name, tmp->name))
00925          break;
00926    }
00927 
00928    ast_unlock_contexts();
00929 
00930    return tmp;
00931 }

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

Definition at line 3949 of file pbx.c.

References __ast_context_create().

Referenced by pbx_load_config(), and pbx_load_users().

03950 {
03951    return __ast_context_create(extcontexts, name, registrar, 1);
03952 }

int ast_context_lockmacro ( const char *  context  ) 

locks the macrolock in the given given context

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 2945 of file pbx.c.

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

Referenced by _macro_exec().

02946 {
02947    struct ast_context *c = NULL;
02948    int ret = -1;
02949 
02950    ast_rdlock_contexts();
02951 
02952    while ((c = ast_walk_contexts(c))) {
02953       if (!strcmp(ast_get_context_name(c), context)) {
02954          ret = 0;
02955          break;
02956       }
02957    }
02958 
02959    ast_unlock_contexts();
02960 
02961    /* if we found context, lock macrolock */
02962    if (ret == 0) 
02963       ret = ast_mutex_lock(&c->macrolock);
02964 
02965    return ret;
02966 }

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 2846 of file pbx.c.

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

Referenced by destroy_station(), destroy_trunk(), handle_context_remove_extension(), handle_context_remove_extension_deprecated(), and register_peer_exten().

02847 {
02848    int ret = -1; /* default error return */
02849    struct ast_context *c = find_context_locked(context);
02850 
02851    if (c) { /* ... remove extension ... */
02852       ret = ast_context_remove_extension2(c, extension, priority, registrar);
02853       ast_unlock_contexts();
02854    }
02855    return ret;
02856 }

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 2868 of file pbx.c.

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

Referenced by ast_context_remove_extension(), do_parking_thread(), and park_exec().

02869 {
02870    struct ast_exten *exten, *prev_exten = NULL;
02871    struct ast_exten *peer;
02872 
02873    ast_mutex_lock(&con->lock);
02874 
02875    /* scan the extension list to find matching extension-registrar */
02876    for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
02877       if (!strcmp(exten->exten, extension) &&
02878          (!registrar || !strcmp(exten->registrar, registrar)))
02879          break;
02880    }
02881    if (!exten) {
02882       /* we can't find right extension */
02883       ast_mutex_unlock(&con->lock);
02884       return -1;
02885    }
02886 
02887    /* should we free all peers in this extension? (priority == 0)? */
02888    if (priority == 0) {
02889       /* remove this extension from context list */
02890       if (prev_exten)
02891          prev_exten->next = exten->next;
02892       else
02893          con->root = exten->next;
02894 
02895       /* fire out all peers */
02896       while ( (peer = exten) ) {
02897          exten = peer->peer; /* prepare for next entry */
02898          destroy_exten(peer);
02899       }
02900    } else {
02901       /* scan the priority list to remove extension with exten->priority == priority */
02902       struct ast_exten *previous_peer = NULL;
02903 
02904       for (peer = exten; peer; previous_peer = peer, peer = peer->peer) {
02905          if (peer->priority == priority &&
02906                (!registrar || !strcmp(peer->registrar, registrar) ))
02907             break; /* found our priority */
02908       }
02909       if (!peer) { /* not found */
02910          ast_mutex_unlock(&con->lock);
02911          return -1;
02912       }
02913       /* we are first priority extension? */
02914       if (!previous_peer) {
02915          /*
02916           * We are first in the priority chain, so must update the extension chain.
02917           * The next node is either the next priority or the next extension
02918           */
02919          struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
02920 
02921          if (!prev_exten)  /* change the root... */
02922             con->root = next_node;
02923          else
02924             prev_exten->next = next_node; /* unlink */
02925          if (peer->peer)   /* XXX update the new head of the pri list */
02926             peer->peer->next = peer->next;
02927       } else { /* easy, we are not first priority in extension */
02928          previous_peer->peer = peer->peer;
02929       }
02930 
02931       /* now, free whole priority extension */
02932       destroy_exten(peer);
02933       /* XXX should we return -1 ? */
02934    }
02935    ast_mutex_unlock(&con->lock);
02936    return 0;
02937 }

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

Definition at line 4478 of file pbx.c.

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

Referenced by handle_context_remove_ignorepat(), and handle_context_remove_ignorepat_deprecated().

04479 {
04480    int ret = -1;
04481    struct ast_context *c = find_context_locked(context);
04482 
04483    if (c) {
04484       ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
04485       ast_unlock_contexts();
04486    }
04487    return ret;
04488 }

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

Definition at line 4490 of file pbx.c.

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

Referenced by ast_context_remove_ignorepat().

04491 {
04492    struct ast_ignorepat *ip, *ipl = NULL;
04493 
04494    ast_mutex_lock(&con->lock);
04495 
04496    for (ip = con->ignorepats; ip; ip = ip->next) {
04497       if (!strcmp(ip->pattern, ignorepat) &&
04498          (!registrar || (registrar == ip->registrar))) {
04499          if (ipl) {
04500             ipl->next = ip->next;
04501             free(ip);
04502          } else {
04503             con->ignorepats = ip->next;
04504             free(ip);
04505          }
04506          ast_mutex_unlock(&con->lock);
04507          return 0;
04508       }
04509       ipl = ip;
04510    }
04511 
04512    ast_mutex_unlock(&con->lock);
04513    errno = EINVAL;
04514    return -1;
04515 }

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 2742 of file pbx.c.

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

Referenced by handle_context_dont_include_deprecated(), and handle_context_remove_include().

02743 {
02744    int ret = -1;
02745    struct ast_context *c = find_context_locked(context);
02746 
02747    if (c) {
02748       /* found, remove include from this context ... */
02749       ret = ast_context_remove_include2(c, include, registrar);
02750       ast_unlock_contexts();
02751    }
02752    return ret;
02753 }

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 2763 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.

Referenced by ast_context_remove_include().

02764 {
02765    struct ast_include *i, *pi = NULL;
02766    int ret = -1;
02767 
02768    ast_mutex_lock(&con->lock);
02769 
02770    /* find our include */
02771    for (i = con->includes; i; pi = i, i = i->next) {
02772       if (!strcmp(i->name, include) &&
02773             (!registrar || !strcmp(i->registrar, registrar))) {
02774          /* remove from list */
02775          if (pi)
02776             pi->next = i->next;
02777          else
02778             con->includes = i->next;
02779          /* free include and return */
02780          free(i);
02781          ret = 0;
02782          break;
02783       }
02784    }
02785 
02786    ast_mutex_unlock(&con->lock);
02787    return ret;
02788 }

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

Remove a switch.

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 2795 of file pbx.c.

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

02796 {
02797    int ret = -1; /* default error return */
02798    struct ast_context *c = find_context_locked(context);
02799 
02800    if (c) {
02801       /* remove switch from this context ... */
02802       ret = ast_context_remove_switch2(c, sw, data, registrar);
02803       ast_unlock_contexts();
02804    }
02805    return ret;
02806 }

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 2816 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.

Referenced by ast_context_remove_switch().

02817 {
02818    struct ast_sw *i;
02819    int ret = -1;
02820 
02821    ast_mutex_lock(&con->lock);
02822 
02823    /* walk switches */
02824    AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
02825       if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
02826          (!registrar || !strcmp(i->registrar, registrar))) {
02827          /* found, remove from list */
02828          AST_LIST_REMOVE_CURRENT(&con->alts, list);
02829          free(i); /* free switch and return */
02830          ret = 0;
02831          break;
02832       }
02833    }
02834    AST_LIST_TRAVERSE_SAFE_END
02835 
02836    ast_mutex_unlock(&con->lock);
02837 
02838    return ret;
02839 }

int ast_context_unlockmacro ( const char *  context  ) 

Unlocks the macrolock in the given context.

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 2973 of file pbx.c.

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

Referenced by _macro_exec().

02974 {
02975    struct ast_context *c = NULL;
02976    int ret = -1;
02977 
02978    ast_rdlock_contexts();
02979 
02980    while ((c = ast_walk_contexts(c))) {
02981       if (!strcmp(ast_get_context_name(c), context)) {
02982          ret = 0;
02983          break;
02984       }
02985    }
02986 
02987    ast_unlock_contexts();
02988 
02989    /* if we found context, unlock macrolock */
02990    if (ret == 0) 
02991       ret = ast_mutex_unlock(&c->macrolock);
02992 
02993    return ret;
02994 }

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 6439 of file pbx.c.

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

Referenced by pbx_load_module().

06440 {
06441    struct ast_include *inc = NULL;
06442    int res = 0;
06443 
06444    while ( (inc = ast_walk_context_includes(con, inc)) ) {
06445       if (ast_context_find(inc->rname))
06446          continue;
06447 
06448       res = -1;
06449       ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n",
06450          ast_get_context_name(con), inc->rname);
06451       break;
06452    }
06453 
06454    return res;
06455 }

struct ast_custom_function* ast_custom_function_find ( const char *  name  ) 

Definition at line 1479 of file pbx.c.

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

Referenced by ast_custom_function_register(), ast_func_read(), ast_func_write(), handle_show_function(), and handle_show_function_deprecated().

01480 {
01481    struct ast_custom_function *acf = NULL;
01482 
01483    AST_LIST_LOCK(&acf_root);
01484    AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
01485       if (!strcmp(name, acf->name))
01486          break;
01487    }
01488    AST_LIST_UNLOCK(&acf_root);
01489 
01490    return acf;
01491 }

int ast_custom_function_register ( struct ast_custom_function acf  ) 

Reigster a custom function.

Definition at line 1515 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.

Referenced by load_module(), odbc_load_module(), and reload().

01516 {
01517    struct ast_custom_function *cur;
01518 
01519    if (!acf)
01520       return -1;
01521 
01522    AST_LIST_LOCK(&acf_root);
01523 
01524    if (ast_custom_function_find(acf->name)) {
01525       ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
01526       AST_LIST_UNLOCK(&acf_root);
01527       return -1;
01528    }
01529 
01530    /* Store in alphabetical order */
01531    AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
01532       if (strcasecmp(acf->name, cur->name) < 0) {
01533          AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist);
01534          break;
01535       }
01536    }
01537    AST_LIST_TRAVERSE_SAFE_END
01538    if (!cur)
01539       AST_LIST_INSERT_TAIL(&acf_root, acf, acflist);
01540 
01541    AST_LIST_UNLOCK(&acf_root);
01542 
01543    if (option_verbose > 1)
01544       ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name);
01545 
01546    return 0;
01547 }

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

Definition at line 1493 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.

Referenced by odbc_unload_module(), reload(), and unload_module().

01494 {
01495    struct ast_custom_function *cur;
01496 
01497    if (!acf)
01498       return -1;
01499 
01500    AST_LIST_LOCK(&acf_root);
01501    AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
01502       if (cur == acf) {
01503          AST_LIST_REMOVE_CURRENT(&acf_root, acflist);
01504          if (option_verbose > 1)
01505             ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name);
01506          break;
01507       }
01508    }
01509    AST_LIST_TRAVERSE_SAFE_END
01510    AST_LIST_UNLOCK(&acf_root);
01511 
01512    return acf ? 0 : -1;
01513 }

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 2315 of file pbx.c.

References E_MATCH, and pbx_extension_helper().

Referenced by __ast_goto_if_exists(), __ast_pbx_run(), __login_exec(), _macro_exec(), agentmonitoroutgoing_exec(), answer_call(), ast_app_dtget(), ast_pbx_outgoing_exten(), builtin_blindtransfer(), cb_events(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), disa_exec(), do_atxfer(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), handle_stimulus_message(), leave_voicemail(), local_alloc(), local_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), misdn_overlap_dial_task(), park_call_full(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), process_ast_dsp(), register_peer_exten(), skinny_ss(), socket_process(), ss_thread(), waitstream_core(), and zt_handle_dtmfup().

02316 {
02317    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH);
02318 }

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

Note:
This function will handle locking the channel as needed.

Definition at line 4600 of file pbx.c.

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

Referenced by __ast_goto_if_exists(), ast_async_goto(), ast_parseable_goto(), disa_exec(), do_atxfer(), and handle_setpriority().

04601 {
04602    if (!chan)
04603       return -1;
04604 
04605    ast_channel_lock(chan);
04606 
04607    if (!ast_strlen_zero(context))
04608       ast_copy_string(chan->context, context, sizeof(chan->context));
04609    if (!ast_strlen_zero(exten))
04610       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
04611    if (priority > -1) {
04612       chan->priority = priority;
04613       /* see flag description in channel.h for explanation */
04614       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
04615          chan->priority--;
04616    }
04617 
04618    ast_channel_unlock(chan);
04619 
04620    return 0;
04621 }

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

Definition at line 910 of file pbx.c.

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

Referenced by realtime_switch_common().

00911 {
00912    if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
00913       ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
00914    return extension_match_core(pattern, data, needmore);
00915 }

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 905 of file pbx.c.

References E_MATCH, and extension_match_core().

Referenced by ast_ignore_pattern(), do_say(), find_matching_priority(), loopback_canmatch(), loopback_exists(), loopback_matchmore(), matchcid(), misdn_cfg_is_msn_valid(), realtime_switch_common(), and show_dialplan_helper().

00906 {
00907    return extension_match_core(pattern, data, E_MATCH);
00908 }

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 2039 of file pbx.c.

References ast_extension_state2(), and ast_hint_extension().

Referenced by action_extensionstate(), and handle_request_subscribe().

02040 {
02041    struct ast_exten *e;
02042 
02043    e = ast_hint_extension(c, context, exten);   /* Do we have a hint for this extension ? */
02044    if (!e)
02045       return -1;           /* No hint, return -1 */
02046 
02047    return ast_extension_state2(e);        /* Check all devices in the hint */
02048 }

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 2027 of file pbx.c.

References extension_states.

Referenced by cb_extensionstate(), handle_request_subscribe(), and handle_show_hints().

02028 {
02029    int i;
02030 
02031    for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) {
02032       if (extension_states[i].extension_state == extension_state)
02033          return extension_states[i].text;
02034    }
02035    return "Unknown";
02036 }

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 2094 of file pbx.c.

References ast_calloc, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_state_cb::callback, ast_state_cb::data, ast_state_cb::next, and statecbs.

Referenced by handle_request_subscribe(), and init_manager().

02096 {
02097    struct ast_hint *hint;
02098    struct ast_state_cb *cblist;
02099    struct ast_exten *e;
02100 
02101    /* If there's no context and extension:  add callback to statecbs list */
02102    if (!context && !exten) {
02103       AST_LIST_LOCK(&hints);
02104 
02105       for (cblist = statecbs; cblist; cblist = cblist->next) {
02106          if (cblist->callback == callback) {
02107             cblist->data = data;
02108             AST_LIST_UNLOCK(&hints);
02109             return 0;
02110          }
02111       }
02112 
02113       /* Now insert the callback */
02114       if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
02115          AST_LIST_UNLOCK(&hints);
02116          return -1;
02117       }
02118       cblist->id = 0;
02119       cblist->callback = callback;
02120       cblist->data = data;
02121 
02122       cblist->next = statecbs;
02123       statecbs = cblist;
02124 
02125       AST_LIST_UNLOCK(&hints);
02126       return 0;
02127    }
02128 
02129    if (!context || !exten)
02130       return -1;
02131 
02132    /* This callback type is for only one hint, so get the hint */
02133    e = ast_hint_extension(NULL, context, exten);
02134    if (!e) {
02135       return -1;
02136    }
02137 
02138    /* Find the hint in the list of hints */
02139    AST_LIST_LOCK(&hints);
02140 
02141    AST_LIST_TRAVERSE(&hints, hint, list) {
02142       if (hint->exten == e)
02143          break;
02144    }
02145 
02146    if (!hint) {
02147       /* We have no hint, sorry */
02148       AST_LIST_UNLOCK(&hints);
02149       return -1;
02150    }
02151 
02152    /* Now insert the callback in the callback list  */
02153    if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
02154       AST_LIST_UNLOCK(&hints);
02155       return -1;
02156    }
02157    cblist->id = stateid++;    /* Unique ID for this callback */
02158    cblist->callback = callback;  /* Pointer to callback routine */
02159    cblist->data = data;    /* Data for the callback */
02160 
02161    cblist->next = hint->callbacks;
02162    hint->callbacks = cblist;
02163 
02164    AST_LIST_UNLOCK(&hints);
02165    return cblist->id;
02166 }

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 2169 of file pbx.c.

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

Referenced by __sip_destroy(), and handle_request_subscribe().

02170 {
02171    struct ast_state_cb **p_cur = NULL; /* address of pointer to us */
02172    int ret = -1;
02173 
02174    if (!id && !callback)
02175       return -1;
02176 
02177    AST_LIST_LOCK(&hints);
02178 
02179    if (!id) {  /* id == 0 is a callback without extension */
02180       for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) {
02181          if ((*p_cur)->callback == callback)
02182             break;
02183       }
02184    } else { /* callback with extension, find the callback based on ID */
02185       struct ast_hint *hint;
02186       AST_LIST_TRAVERSE(&hints, hint, list) {
02187          for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) {
02188             if ((*p_cur)->id == id)
02189                break;
02190          }
02191          if (*p_cur) /* found in the inner loop */
02192             break;
02193       }
02194    }
02195    if (p_cur && *p_cur) {
02196       struct ast_state_cb *cur = *p_cur;
02197       *p_cur = cur->next;
02198       free(cur);
02199       ret = 0;
02200    }
02201    AST_LIST_UNLOCK(&hints);
02202    return ret;
02203 }

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 2320 of file pbx.c.

References E_FINDLABEL, and pbx_extension_helper().

Referenced by action_originate(), action_redirect(), ast_parseable_goto(), asyncgoto_exec(), and handle_setpriority().

02321 {
02322    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL);
02323 }

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 2325 of file pbx.c.

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

02326 {
02327    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL);
02328 }

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 1569 of file pbx.c.

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

Referenced by action_getvar(), handle_getvariable(), and pbx_substitute_variables_helper_full().

01570 {
01571    char *args = func_args(function);
01572    struct ast_custom_function *acfptr = ast_custom_function_find(function);
01573 
01574    if (acfptr == NULL)
01575       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01576    else if (!acfptr->read)
01577       ast_log(LOG_ERROR, "Function %s cannot be read\n", function);
01578    else
01579       return acfptr->read(chan, function, args, workspace, len);
01580    return -1;
01581 }

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 1583 of file pbx.c.

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

Referenced by pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().

01584 {
01585    char *args = func_args(function);
01586    struct ast_custom_function *acfptr = ast_custom_function_find(function);
01587 
01588    if (acfptr == NULL)
01589       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01590    else if (!acfptr->write)
01591       ast_log(LOG_ERROR, "Function %s cannot be written to\n", function);
01592    else
01593       return acfptr->write(chan, function, args, value);
01594 
01595    return -1;
01596 }

const char* ast_get_context_name ( struct ast_context con  ) 

Definition at line 6296 of file pbx.c.

Referenced by _macro_exec(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_context_verify_includes(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper().

06297 {
06298    return con ? con->name : NULL;
06299 }

const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 6334 of file pbx.c.

References ast_context::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06335 {
06336    return c ? c->registrar : NULL;
06337 }

const char* ast_get_extension_app ( struct ast_exten e  ) 

Definition at line 6364 of file pbx.c.

References ast_exten::app.

Referenced by _macro_exec(), ast_add_hint(), ast_extension_state2(), ast_get_hint(), ast_hint_state_changed(), find_matching_endwhile(), handle_save_dialplan(), handle_show_hints(), and print_ext().

06365 {
06366    return e ? e->app : NULL;
06367 }

void* ast_get_extension_app_data ( struct ast_exten e  ) 

Definition at line 6369 of file pbx.c.

References ast_exten::data.

Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().

06370 {
06371    return e ? e->data : NULL;
06372 }

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 6359 of file pbx.c.

References ast_exten::cidmatch.

Referenced by find_matching_priority(), and handle_save_dialplan().

06360 {
06361    return e ? e->cidmatch : NULL;
06362 }

struct ast_context* ast_get_extension_context ( struct ast_exten exten  ) 

Definition at line 6301 of file pbx.c.

References exten.

Referenced by handle_show_hints().

06302 {
06303    return exten ? exten->parent : NULL;
06304 }

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 6311 of file pbx.c.

References exten.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06312 {
06313    return exten ? exten->label : NULL;
06314 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 6354 of file pbx.c.

References ast_exten::matchcid.

Referenced by find_matching_priority(), and handle_save_dialplan().

06355 {
06356    return e ? e->matchcid : 0;
06357 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 

Definition at line 6306 of file pbx.c.

References exten.

Referenced by ast_add_hint(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), dundi_precache_full(), find_matching_priority(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper().

06307 {
06308    return exten ? exten->exten : NULL;
06309 }

int ast_get_extension_priority ( struct ast_exten exten  ) 

Definition at line 6326 of file pbx.c.

References exten.

Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), handle_save_dialplan(), and print_ext().

06327 {
06328    return exten ? exten->priority : -1;
06329 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 6339 of file pbx.c.

References ast_exten::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06340 {
06341    return e ? e->registrar : NULL;
06342 }

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.

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 2298 of file pbx.c.

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

Referenced by action_extensionstate(), get_cid_name(), get_destination(), pbx_retrieve_variable(), and transmit_state_notify().

02299 {
02300    struct ast_exten *e = ast_hint_extension(c, context, exten);
02301 
02302    if (e) {
02303       if (hint)
02304          ast_copy_string(hint, ast_get_extension_app(e), hintsize);
02305       if (name) {
02306          const char *tmp = ast_get_extension_app_data(e);
02307          if (tmp)
02308             ast_copy_string(name, tmp, namesize);
02309       }
02310       return -1;
02311    }
02312    return 0;
02313 }

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 

Definition at line 6321 of file pbx.c.

References ast_ignorepat::pattern.

Referenced by complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), handle_save_dialplan(), lookup_c_ip(), and show_dialplan_helper().

06322 {
06323    return ip ? ip->pattern : NULL;
06324 }

const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

Definition at line 6349 of file pbx.c.

References ast_ignorepat::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06350 {
06351    return ip ? ip->registrar : NULL;
06352 }

const char* ast_get_include_name ( struct ast_include include  ) 

Definition at line 6316 of file pbx.c.

References ast_include::name.

Referenced by complete_context_dont_include_deprecated(), complete_context_remove_include(), find_matching_priority(), handle_save_dialplan(), lookup_ci(), and show_dialplan_helper().

06317 {
06318    return inc ? inc->name : NULL;
06319 }

const char* ast_get_include_registrar ( struct ast_include i  ) 

Definition at line 6344 of file pbx.c.

References ast_include::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06345 {
06346    return i ? i->registrar : NULL;
06347 }

const char* ast_get_switch_data ( struct ast_sw sw  ) 

Definition at line 6379 of file pbx.c.

References ast_sw::data.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06380 {
06381    return sw ? sw->data : NULL;
06382 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

Definition at line 6374 of file pbx.c.

References ast_sw::name.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06375 {
06376    return sw ? sw->name : NULL;
06377 }

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

Definition at line 6384 of file pbx.c.

References ast_sw::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06385 {
06386    return sw ? sw->registrar : NULL;
06387 }

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

Note:
This function will handle locking the channel as needed.

Definition at line 6477 of file pbx.c.

References __ast_goto_if_exists().

Referenced by aqm_exec(), background_detect_exec(), chanavail_exec(), conf_run(), controlplayback_exec(), do_directory(), hasvoicemail_exec(), leave_voicemail(), lookupblacklist_exec(), onedigit_goto(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), play_mailbox_owner(), playback_exec(), pqm_exec(), privacy_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), system_exec_helper(), transfer_exec(), upqm_exec(), valid_exit(), vm_box_exists(), vm_exec(), and wait_for_answer().

06478 {
06479    return __ast_goto_if_exists(chan, context, exten, priority, 0);
06480 }

void ast_hint_state_changed ( const char *  device  ) 

Definition at line 2050 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().

Referenced by do_state_change().

02051 {
02052    struct ast_hint *hint;
02053 
02054    AST_LIST_LOCK(&hints);
02055 
02056    AST_LIST_TRAVERSE(&hints, hint, list) {
02057       struct ast_state_cb *cblist;
02058       char buf[AST_MAX_EXTENSION];
02059       char *parse = buf;
02060       char *cur;
02061       int state;
02062 
02063       ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf));
02064       while ( (cur = strsep(&parse, "&")) ) {
02065          if (!strcasecmp(cur, device))
02066             break;
02067       }
02068       if (!cur)
02069          continue;
02070 
02071       /* Get device state for this hint */
02072       state = ast_extension_state2(hint->exten);
02073 
02074       if ((state == -1) || (state == hint->laststate))
02075          continue;
02076 
02077       /* Device state changed since last check - notify the watchers */
02078 
02079       /* For general callbacks */
02080       for (cblist = statecbs; cblist; cblist = cblist->next)
02081          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
02082 
02083       /* For extension callbacks */
02084       for (cblist = hint->callbacks; cblist; cblist = cblist->next)
02085          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
02086 
02087       hint->laststate = state;   /* record we saw the change */
02088    }
02089 
02090    AST_LIST_UNLOCK(&hints);
02091 }

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 4566 of file pbx.c.

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

Referenced by ast_app_dtget(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_enbloc_call_message(), handle_soft_key_event_message(), handle_stimulus_message(), mgcp_ss(), skinny_ss(), and ss_thread().

04567 {
04568    struct ast_context *con = ast_context_find(context);
04569    if (con) {
04570       struct ast_ignorepat *pat;
04571       for (pat = con->ignorepats; pat; pat = pat->next) {
04572          if (ast_extension_match(pat->pattern, pattern))
04573             return 1;
04574       }
04575    }
04576 
04577    return 0;
04578 }

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 6283 of file pbx.c.

References ast_mutex_lock(), and ast_context::lock.

Referenced by _macro_exec(), complete_context_dont_include_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), lookup_c_ip(), lookup_ci(), and show_dialplan_helper().

06284 {
06285    return ast_mutex_lock(&con->lock);
06286 }

int ast_lock_contexts ( void   ) 

Locks the context list.

Return values:
0 on success
-1 on error

Definition at line 6260 of file pbx.c.

References ast_rwlock_wrlock().

Referenced by find_matching_endwhile().

06261 {
06262    return ast_rwlock_wrlock(&conlock);
06263 }

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 2335 of file pbx.c.

References E_MATCHMORE, and pbx_extension_helper().

Referenced by ast_app_dtget(), collect_digits(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_stimulus_message(), loopback_matchmore(), mgcp_ss(), skinny_ss(), and ss_thread().

02336 {
02337    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE);
02338 }

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 3967 of file pbx.c.

References __ast_context_destroy(), ast_calloc, AST_EXTENSION_REMOVED, 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_unlock_contexts(), ast_wrlock_contexts(), ast_state_cb::callback, store_hint::callbacks, ast_hint::callbacks, store_hint::context, contexts, ast_state_cb::data, E_MATCH, ast_exten::exten, ast_hint::exten, store_hint::exten, free, ast_hint::laststate, store_hint::laststate, LOG_WARNING, ast_state_cb::next, ast_context::next, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_context::registrar, and pbx_find_info::stacklen.

Referenced by pbx_load_module().

03968 {
03969    struct ast_context *tmp, *lasttmp = NULL;
03970    struct store_hints store = AST_LIST_HEAD_INIT_VALUE;
03971    struct store_hint *this;
03972    struct ast_hint *hint;
03973    struct ast_exten *exten;
03974    int length;
03975    struct ast_state_cb *thiscb, *prevcb;
03976 
03977    /* it is very important that this function hold the hint list lock _and_ the conlock
03978       during its operation; not only do we need to ensure that the list of contexts
03979       and extensions does not change, but also that no hint callbacks (watchers) are
03980       added or removed during the merge/delete process
03981 
03982       in addition, the locks _must_ be taken in this order, because there are already
03983       other code paths that use this order
03984    */
03985    ast_wrlock_contexts();
03986    AST_LIST_LOCK(&hints);
03987 
03988    /* preserve all watchers for hints associated with this registrar */
03989    AST_LIST_TRAVERSE(&hints, hint, list) {
03990       if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) {
03991          length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this);
03992          if (!(this = ast_calloc(1, length)))
03993             continue;
03994          this->callbacks = hint->callbacks;
03995          hint->callbacks = NULL;
03996          this->laststate = hint->laststate;
03997          this->context = this->data;
03998          strcpy(this->data, hint->exten->parent->name);
03999          this->exten = this->data + strlen(this->context) + 1;
04000          strcpy(this->exten, hint->exten->exten);
04001          AST_LIST_INSERT_HEAD(&store, this, list);
04002       }
04003    }
04004 
04005    tmp = *extcontexts;
04006    if (registrar) {
04007       /* XXX remove previous contexts from same registrar */
04008       if (option_debug)
04009          ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar);
04010       __ast_context_destroy(NULL,registrar);
04011       while (tmp) {
04012          lasttmp = tmp;
04013          tmp = tmp->next;
04014       }
04015    } else {
04016       /* XXX remove contexts with the same name */
04017       while (tmp) {
04018          ast_log(LOG_WARNING, "must remove %s  reg %s\n", tmp->name, tmp->registrar);
04019          __ast_context_destroy(tmp,tmp->registrar);
04020          lasttmp = tmp;
04021          tmp = tmp->next;
04022       }
04023    }
04024    if (lasttmp) {
04025       lasttmp->next = contexts;
04026       contexts = *extcontexts;
04027       *extcontexts = NULL;
04028    } else
04029       ast_log(LOG_WARNING, "Requested contexts didn't get merged\n");
04030 
04031    /* restore the watchers for hints that can be found; notify those that
04032       cannot be restored
04033    */
04034    while ((this = AST_LIST_REMOVE_HEAD(&store, list))) {
04035       struct pbx_find_info q = { .stacklen = 0 };
04036       exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH);
04037       /* Find the hint in the list of hints */
04038       AST_LIST_TRAVERSE(&hints, hint, list) {
04039          if (hint->exten == exten)
04040             break;
04041       }
04042       if (!exten || !hint) {
04043          /* this hint has been removed, notify the watchers */
04044          prevcb = NULL;
04045          thiscb = this->callbacks;
04046          while (thiscb) {
04047             prevcb = thiscb;
04048             thiscb = thiscb->next;
04049             prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data);
04050             free(prevcb);
04051             }
04052       } else {
04053          thiscb = this->callbacks;
04054          while (thiscb->next)
04055             thiscb = thiscb->next;
04056          thiscb->next = hint->callbacks;
04057          hint->callbacks = this->callbacks;
04058          hint->laststate = this->laststate;
04059       }
04060       free(this);
04061    }
04062 
04063    AST_LIST_UNLOCK(&hints);
04064    ast_unlock_contexts();
04065 
04066    return;
04067 }

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

Note:
I can find neither parsable nor parseable at dictionary.com, but google gives me 169000 hits for parseable and only 49,800 for parsable

This function will handle locking the channel as needed.

Definition at line 6487 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().

Referenced by _while_exec(), check_goto_on_transfer(), gosub_exec(), ivr_dispatch(), pbx_builtin_goto(), random_exec(), return_exec(), and while_continue_exec().

06488 {
06489    char *exten, *pri, *context;
06490    char *stringp;
06491    int ipri;
06492    int mode = 0;
06493 
06494    if (ast_strlen_zero(goto_string)) {
06495       ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
06496       return -1;
06497    }
06498    stringp = ast_strdupa(goto_string);
06499    context = strsep(&stringp, "|"); /* guaranteed non-null */
06500    exten = strsep(&stringp, "|");
06501    pri = strsep(&stringp, "|");
06502    if (!exten) {  /* Only a priority in this one */
06503       pri = context;
06504       exten = NULL;
06505       context = NULL;
06506    } else if (!pri) {   /* Only an extension and priority in this one */
06507       pri = exten;
06508       exten = context;
06509       context = NULL;
06510    }
06511    if (*pri == '+') {
06512       mode = 1;
06513       pri++;
06514    } else if (*pri == '-') {
06515       mode = -1;
06516       pri++;
06517    }
06518    if (sscanf(pri, "%d", &ipri) != 1) {
06519       if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten,
06520          pri, chan->cid.cid_num)) < 1) {
06521          ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);
06522          return -1;
06523       } else
06524          mode = 0;
06525    }
06526    /* At this point we have a priority and maybe an extension and a context */
06527 
06528    if (mode)
06529       ipri = chan->priority + (ipri * mode);
06530 
06531    ast_explicit_goto(chan, context, exten, ipri);
06532    ast_cdr_update(chan);
06533    return 0;
06534 
06535 }

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 5186 of file pbx.c.

References __ast_request_and_dial(), 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, errno, free, LOG_WARNING, option_verbose, ast_channel::pbx, outgoing_helper::vars, and VERBOSE_PREFIX_4.

Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_app().

05187 {
05188    struct ast_channel *chan;
05189    struct app_tmp *tmp;
05190    int res = -1, cdr_res = -1;
05191    struct outgoing_helper oh;
05192    pthread_attr_t attr;
05193 
05194    memset(&oh, 0, sizeof(oh));
05195    oh.vars = vars;
05196    oh.account = account;
05197 
05198    if (locked_channel)
05199       *locked_channel = NULL;
05200    if (ast_strlen_zero(app)) {
05201       res = -1;
05202       goto outgoing_app_cleanup;
05203    }
05204    if (sync) {
05205       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
05206       if (chan) {
05207          if (!chan->cdr) { /* check if the channel already has a cdr record, if not give it one */
05208             chan->cdr = ast_cdr_alloc();   /* allocate a cdr for the channel */
05209             if(!chan->cdr) {
05210                /* allocation of the cdr failed */
05211                free(chan->pbx);
05212                res = -1;
05213                goto outgoing_app_cleanup;
05214             }
05215             /* allocation of the cdr was successful */
05216             ast_cdr_init(chan->cdr, chan);  /* initilize our channel's cdr */
05217             ast_cdr_start(chan->cdr);
05218          }
05219          ast_set_variables(chan, vars);
05220          if (account)
05221             ast_cdr_setaccount(chan, account);
05222          if (chan->_state == AST_STATE_UP) {
05223             res = 0;
05224             if (option_verbose > 3)
05225                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
05226             tmp = ast_calloc(1, sizeof(*tmp));
05227             if (!tmp)
05228                res = -1;
05229             else {
05230                ast_copy_string(tmp->app, app, sizeof(tmp->app));
05231                if (appdata)
05232                   ast_copy_string(tmp->data, appdata, sizeof(tmp->data));
05233                tmp->chan = chan;
05234                if (sync > 1) {
05235                   if (locked_channel)
05236                      ast_channel_unlock(chan);
05237                   ast_pbx_run_app(tmp);
05238                } else {
05239                   pthread_attr_init(&attr);
05240                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05241                   if (locked_channel)
05242                      ast_channel_lock(chan);
05243                   if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) {
05244                      ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
05245                      free(tmp);
05246                      if (locked_channel)
05247                         ast_channel_unlock(chan);
05248                      ast_hangup(chan);
05249                      res = -1;
05250                   } else {
05251                      if (locked_channel)
05252                         *locked_channel = chan;
05253                   }
05254                   pthread_attr_destroy(&attr);
05255                }
05256             }
05257          } else {
05258             if (option_verbose > 3)
05259                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
05260             if (chan->cdr) { /* update the cdr */
05261                /* here we update the status of the call, which sould be busy.
05262                 * if that fails then we set the status to failed */
05263                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
05264                   ast_cdr_failed(chan->cdr);
05265             }
05266             ast_hangup(chan);
05267          }
05268       }
05269 
05270       if (res < 0) { /* the call failed for some reason */
05271          if (*reason == 0) { /* if the call failed (not busy or no answer)
05272                         * update the cdr with the failed message */
05273             cdr_res = ast_pbx_outgoing_cdr_failed();
05274             if (cdr_res != 0) {
05275                res = cdr_res;
05276                goto outgoing_app_cleanup;
05277             }
05278          }
05279       }
05280 
05281    } else {
05282       struct async_stat *as;
05283       if (!(as = ast_calloc(1, sizeof(*as)))) {
05284          res = -1;
05285          goto outgoing_app_cleanup;
05286       }
05287       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
05288       if (!chan) {
05289          free(as);
05290          res = -1;
05291          goto outgoing_app_cleanup;
05292       }
05293       as->chan = chan;
05294       ast_copy_string(as->app, app, sizeof(as->app));
05295       if (appdata)
05296          ast_copy_string(as->appdata,  appdata, sizeof(as->appdata));
05297       as->timeout = timeout;
05298       ast_set_variables(chan, vars);
05299       if (account)
05300          ast_cdr_setaccount(chan, account);
05301       /* Start a new thread, and get something handling this channel. */
05302       pthread_attr_init(&attr);
05303       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05304       if (locked_channel)
05305          ast_channel_lock(chan);
05306       if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
05307          ast_log(LOG_WARNING, "Failed to start async wait\n");
05308          free(as);
05309          if (locked_channel)
05310             ast_channel_unlock(chan);
05311          ast_hangup(chan);
05312          res = -1;
05313          pthread_attr_destroy(&attr);
05314          goto outgoing_app_cleanup;
05315       } else {
05316          if (locked_channel)
05317             *locked_channel = chan;
05318       }
05319       pthread_attr_destroy(&attr);
05320       res = 0;
05321    }
05322 outgoing_app_cleanup:
05323    ast_variables_destroy(vars);
05324    return res;
05325 }

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 5020 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, ast_channel::context, free, ast_channel::hangupcause, LOAD_OH, LOG_ERROR, LOG_WARNING, option_verbose, pbx_builtin_setvar_helper(), set_ext_pri(), outgoing_helper::vars, and VERBOSE_PREFIX_4.

Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_exten().

05021 {
05022    struct ast_channel *chan;
05023    struct async_stat *as;
05024    int res = -1, cdr_res = -1;
05025    struct outgoing_helper oh;
05026    pthread_attr_t attr;
05027 
05028    if (sync) {
05029       LOAD_OH(oh);
05030       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
05031       if (channel) {
05032          *channel = chan;
05033          if (chan)
05034             ast_channel_lock(chan);
05035       }
05036       if (chan) {
05037          if (chan->_state == AST_STATE_UP) {
05038                res = 0;
05039             if (option_verbose > 3)
05040                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
05041 
05042             if (sync > 1) {
05043                if (channel)
05044                   ast_channel_unlock(chan);
05045                if (ast_pbx_run(chan)) {
05046                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
05047                   if (channel)
05048                      *channel = NULL;
05049                   ast_hangup(chan);
05050                   chan = NULL;
05051                   res = -1;
05052                }
05053             } else {
05054                if (ast_pbx_start(chan)) {
05055                   ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name);
05056                   if (channel) {
05057                      *channel = NULL;
05058                      ast_channel_unlock(chan);
05059                   }
05060                   ast_hangup(chan);
05061                   res = -1;
05062                }
05063                chan = NULL;
05064             }
05065          } else {
05066             if (option_verbose > 3)
05067                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
05068 
05069             if (chan->cdr) { /* update the cdr */
05070                /* here we update the status of the call, which sould be busy.
05071                 * if that fails then we set the status to failed */
05072                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
05073                   ast_cdr_failed(chan->cdr);
05074             }
05075 
05076             if (channel) {
05077                *channel = NULL;
05078                ast_channel_unlock(chan);
05079             }
05080             ast_hangup(chan);
05081             chan = NULL;
05082          }
05083       }
05084 
05085       if (res < 0) { /* the call failed for some reason */
05086          if (*reason == 0) { /* if the call failed (not busy or no answer)
05087                         * update the cdr with the failed message */
05088             cdr_res = ast_pbx_outgoing_cdr_failed();
05089             if (cdr_res != 0) {
05090                res = cdr_res;
05091                goto outgoing_exten_cleanup;
05092             }
05093          }
05094 
05095          /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */
05096          /* check if "failed" exists */
05097          if (ast_exists_extension(chan, context, "failed", 1, NULL)) {
05098             chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed");
05099             if (chan) {
05100                char failed_reason[4] = "";
05101                if (!ast_strlen_zero(context))
05102                   ast_copy_string(chan->context, context, sizeof(chan->context));
05103                set_ext_pri(chan, "failed", 1);
05104                ast_set_variables(chan, vars);
05105                snprintf(failed_reason, sizeof(failed_reason), "%d", *reason);
05106                pbx_builtin_setvar_helper(chan, "REASON", failed_reason);
05107                if (account)
05108                   ast_cdr_setaccount(chan, account);
05109                if (ast_pbx_run(chan)) {
05110                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
05111                   ast_hangup(chan);
05112                }
05113                chan = NULL;
05114             }
05115          }
05116       }
05117    } else {
05118       if (!(as = ast_calloc(1, sizeof(*as)))) {
05119          res = -1;
05120          goto outgoing_exten_cleanup;
05121       }
05122       chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
05123       if (channel) {
05124          *channel = chan;
05125          if (chan)
05126             ast_channel_lock(chan);
05127       }
05128       if (!chan) {
05129          free(as);
05130          res = -1;
05131          goto outgoing_exten_cleanup;
05132       }
05133       as->chan = chan;
05134       ast_copy_string(as->context, context, sizeof(as->context));
05135       set_ext_pri(as->chan,  exten, priority);
05136       as->timeout = timeout;
05137       ast_set_variables(chan, vars);
05138       if (account)
05139          ast_cdr_setaccount(chan, account);
05140       pthread_attr_init(&attr);
05141       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05142       if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
05143          ast_log(LOG_WARNING, "Failed to start async wait\n");
05144          free(as);
05145          if (channel) {
05146             *channel = NULL;
05147             ast_channel_unlock(chan);
05148          }
05149          ast_hangup(chan);
05150          res = -1;
05151          pthread_attr_destroy(&attr);
05152          goto outgoing_exten_cleanup;
05153       }
05154       pthread_attr_destroy(&attr);
05155       res = 0;
05156    }
05157 outgoing_exten_cleanup:
05158    ast_variables_destroy(vars);
05159    return res;
05160 }

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 2695 of file pbx.c.

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

Referenced by ast_pbx_outgoing_exten(), async_wait(), mgcp_ss(), skinny_newcall(), and ss_thread().

02696 {
02697    enum ast_pbx_result res = AST_PBX_SUCCESS;
02698 
02699    if (increase_call_count(c))
02700       return AST_PBX_CALL_LIMIT;
02701 
02702    res = __ast_pbx_run(c);
02703    decrease_call_count();
02704 
02705    return res;
02706 }

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 2669 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.

Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_exten(), check_goto_on_transfer(), do_parking_thread(), gtalk_new(), gtalk_newcall(), handle_request_invite(), local_call(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), skinny_new(), and zt_new().

02670 {
02671    pthread_t t;
02672    pthread_attr_t attr;
02673 
02674    if (!c) {
02675       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
02676       return AST_PBX_FAILED;
02677    }
02678 
02679    if (increase_call_count(c))
02680       return AST_PBX_CALL_LIMIT;
02681 
02682    /* Start a new thread, and get something handling this channel. */
02683    pthread_attr_init(&attr);
02684    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
02685    if (ast_pthread_create(&t, &attr, pbx_thread, c)) {
02686       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
02687       pthread_attr_destroy(&attr);
02688       return AST_PBX_FAILED;
02689    }
02690    pthread_attr_destroy(&attr);
02691 
02692    return AST_PBX_SUCCESS;
02693 }

int ast_rdlock_contexts ( void   ) 

Definition at line 6265 of file pbx.c.

References ast_rwlock_rdlock().

Referenced by __ast_context_create(), _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_hint_extension(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), handle_save_dialplan(), pbx_extension_helper(), and show_dialplan_helper().

06266 {
06267    return ast_rwlock_rdlock(&conlock);
06268 }

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 2997 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.

Referenced by load_module(), and load_pbx().

02998 {
02999    struct ast_app *tmp, *cur = NULL;
03000    char tmps[80];
03001    int length;
03002 
03003    AST_LIST_LOCK(&apps);
03004    AST_LIST_TRAVERSE(&apps, tmp, list) {
03005       if (!strcasecmp(app, tmp->name)) {
03006          ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
03007          AST_LIST_UNLOCK(&apps);
03008          return -1;
03009       }
03010    }
03011 
03012    length = sizeof(*tmp) + strlen(app) + 1;
03013 
03014    if (!(tmp = ast_calloc(1, length))) {
03015       AST_LIST_UNLOCK(&apps);
03016       return -1;
03017    }
03018 
03019    strcpy(tmp->name, app);
03020    tmp->execute = execute;
03021    tmp->synopsis = synopsis;
03022    tmp->description = description;
03023 
03024    /* Store in alphabetical order */
03025    AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) {
03026       if (strcasecmp(tmp->name, cur->name) < 0) {
03027          AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list);
03028          break;
03029       }
03030    }
03031    AST_LIST_TRAVERSE_SAFE_END
03032    if (!cur)
03033       AST_LIST_INSERT_TAIL(&apps, tmp, list);
03034 
03035    if (option_verbose > 1)
03036       ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
03037 
03038    AST_LIST_UNLOCK(&apps);
03039 
03040    return 0;
03041 }

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 3047 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.

Referenced by load_module().

03048 {
03049    struct ast_switch *tmp;
03050 
03051    AST_LIST_LOCK(&switches);
03052    AST_LIST_TRAVERSE(&switches, tmp, list) {
03053       if (!strcasecmp(tmp->name, sw->name)) {
03054          AST_LIST_UNLOCK(&switches);
03055          ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
03056          return -1;
03057       }
03058    }
03059    AST_LIST_INSERT_TAIL(&switches, sw, list);
03060    AST_LIST_UNLOCK(&switches);
03061 
03062    return 0;
03063 }

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 2340 of file pbx.c.

References E_SPAWN, and pbx_extension_helper().

Referenced by __ast_pbx_run(), _macro_exec(), and loopback_exec().

02341 {
02342    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN);
02343 }

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 6288 of file pbx.c.

References ast_mutex_unlock(), and ast_context::lock.

Referenced by _macro_exec(), complete_context_dont_include_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), lookup_c_ip(), lookup_ci(), and show_dialplan_helper().

06289 {
06290    return ast_mutex_unlock(&con->lock);
06291 }

int ast_unlock_contexts ( void   ) 

Unlocks contexts.

Return values:
0 on success
-1 on failure

Definition at line 6275 of file pbx.c.

References ast_rwlock_unlock().

Referenced by __ast_context_create(), _macro_exec(), ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_destroy(), ast_context_find(), ast_context_lockmacro(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_unlockmacro(), ast_hint_extension(), ast_merge_contexts_and_delete(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_save_dialplan(), pbx_extension_helper(), and show_dialplan_helper().

06276 {
06277    return ast_rwlock_unlock(&conlock);
06278 }

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 3878 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.

Referenced by __unload_module(), and unload_module().

03879 {
03880    struct ast_app *tmp;
03881 
03882    AST_LIST_LOCK(&apps);
03883    AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) {
03884       if (!strcasecmp(app, tmp->name)) {
03885          AST_LIST_REMOVE_CURRENT(&apps, list);
03886          if (option_verbose > 1)
03887             ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
03888          free(tmp);
03889          break;
03890       }
03891    }
03892    AST_LIST_TRAVERSE_SAFE_END
03893    AST_LIST_UNLOCK(&apps);
03894 
03895    return tmp ? 0 : -1;
03896 }

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 3065 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_REMOVE, and AST_LIST_UNLOCK.

Referenced by __unload_module(), and unload_module().

03066 {
03067    AST_LIST_LOCK(&switches);
03068    AST_LIST_REMOVE(&switches, sw, list);
03069    AST_LIST_UNLOCK(&switches);
03070 }

struct ast_exten* ast_walk_context_extensions ( struct ast_context con,
struct ast_exten priority 
)

Definition at line 6397 of file pbx.c.

References exten, and ast_context::root.

Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), dundi_precache_full(), find_matching_priority(), handle_save_dialplan(), pbx_find_extension(), and show_dialplan_helper().

06399 {
06400    if (!exten)
06401       return con ? con->root : NULL;
06402    else
06403       return exten->next;
06404 }

struct ast_ignorepat* ast_walk_context_ignorepats ( struct ast_context con,
struct ast_ignorepat ip 
)

Definition at line 6430 of file pbx.c.

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

Referenced by complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), handle_save_dialplan(), lookup_c_ip(), and show_dialplan_helper().

06432 {
06433    if (!ip)
06434       return con ? con->ignorepats : NULL;
06435    else
06436       return ip->next;
06437 }

struct ast_include* ast_walk_context_includes ( struct ast_context con,
struct ast_include inc 
)

Definition at line 6421 of file pbx.c.

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

Referenced by ast_context_verify_includes(), complete_context_dont_include_deprecated(), complete_context_remove_include(), find_matching_priority(), handle_save_dialplan(), lookup_ci(), and show_dialplan_helper().

06423 {
06424    if (!inc)
06425       return con ? con->includes : NULL;
06426    else
06427       return inc->next;
06428 }

struct ast_sw* ast_walk_context_switches ( struct ast_context con,
struct ast_sw sw 
)

Definition at line 6406 of file pbx.c.

References AST_LIST_FIRST, and AST_LIST_NEXT.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06408 {
06409    if (!sw)
06410       return con ? AST_LIST_FIRST(&con->alts) : NULL;
06411    else
06412       return AST_LIST_NEXT(sw, list);
06413 }

struct ast_context* ast_walk_contexts ( struct ast_context con  ) 

Definition at line 6392 of file pbx.c.

References contexts, and ast_context::next.

Referenced by _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), pbx_find_extension(), pbx_load_module(), and show_dialplan_helper().

06393 {
06394    return con ? con->next : contexts;
06395 }

struct ast_exten* ast_walk_extension_priorities ( struct ast_exten exten,
struct ast_exten priority 
)

Definition at line 6415 of file pbx.c.

References exten, and ast_exten::priority.

Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), handle_save_dialplan(), pbx_find_extension(), and show_dialplan_helper().

06417 {
06418    return priority ? priority->peer : exten;
06419 }

int ast_wrlock_contexts ( void   ) 

Definition at line 6270 of file pbx.c.

References ast_rwlock_wrlock().

Referenced by ast_context_destroy(), ast_merge_contexts_and_delete(), and complete_context_dont_include_deprecated().

06271 {
06272    return ast_rwlock_wrlock(&conlock);
06273 }

void pbx_builtin_clear_globals ( void   ) 

Definition at line 6036 of file pbx.c.

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

Referenced by handle_reload_extensions(), and reload().

06037 {
06038    struct ast_var_t *vardata;
06039 
06040    ast_mutex_lock(&globalslock);
06041    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
06042       ast_var_delete(vardata);
06043    ast_mutex_unlock(&globalslock);
06044 }

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

Note:
Will lock the channel.

Definition at line 5813 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), and ast_var_value().

Referenced by __login_exec(), _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), ast_bridge_call(), ast_channel_bridge(), ast_feature_interpret(), ast_monitor_stop(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dundi_exec(), dundi_helper(), get_also_info(), get_index(), get_refer_info(), global_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_call_full(), pickup_by_mark(), queue_exec(), real_ctx(), retrydial_exec(), return_exec(), ring_entry(), run_agi(), set_config_flags(), sip_addheader(), sla_trunk_exec(), speech_background(), try_calling(), try_suggested_sip_codec(), wait_for_answer(), zt_call(), and zt_hangup().

05814 {
05815    struct ast_var_t *variables;
05816    const char *ret = NULL;
05817    int i;
05818    struct varshead *places[2] = { NULL, &globals };
05819 
05820    if (!name)
05821       return NULL;
05822 
05823    if (chan) {
05824       ast_channel_lock(chan);
05825       places[0] = &chan->varshead;
05826    }
05827 
05828    for (i = 0; i < 2; i++) {
05829       if (!places[i])
05830          continue;
05831       if (places[i] == &globals)
05832          ast_mutex_lock(&globalslock);
05833       AST_LIST_TRAVERSE(places[i], variables, entries) {
05834          if (!strcmp(name, ast_var_name(variables))) {
05835             ret = ast_var_value(variables);
05836             break;
05837          }
05838       }
05839       if (places[i] == &globals)
05840          ast_mutex_unlock(&globalslock);
05841       if (ret)
05842          break;
05843    }
05844 
05845    if (chan)
05846       ast_channel_unlock(chan);
05847 
05848    return ret;
05849 }

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

Note:
Will lock the channel.

Definition at line 5851 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_verbose(), LOG_WARNING, option_verbose, and VERBOSE_PREFIX_2.

Referenced by acf_odbc_read(), acf_odbc_write(), and gosub_exec().

05852 {
05853    struct ast_var_t *newvariable;
05854    struct varshead *headp;
05855 
05856    if (name[strlen(name)-1] == ')') {
05857       char *function = ast_strdupa(name);
05858 
05859       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
05860       ast_func_write(chan, function, value);
05861       return;
05862    }
05863 
05864    if (chan) {
05865       ast_channel_lock(chan);
05866       headp = &chan->varshead;
05867    } else {
05868       ast_mutex_lock(&globalslock);
05869       headp = &globals;
05870    }
05871 
05872    if (value) {
05873       if ((option_verbose > 1) && (headp == &globals))
05874          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05875       newvariable = ast_var_assign(name, value);
05876       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05877    }
05878 
05879    if (chan)
05880       ast_channel_unlock(chan);
05881    else
05882       ast_mutex_unlock(&globalslock);
05883 }

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

Note:
Will lock the channel.

Definition at line 5782 of file pbx.c.

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

Referenced by dumpchan_exec(), handle_showchan(), handle_showchan_deprecated(), and vars2manager().

05783 {
05784    struct ast_var_t *variables;
05785    const char *var, *val;
05786    int total = 0;
05787 
05788    if (!chan)
05789       return 0;
05790 
05791    memset(buf, 0, size);
05792 
05793    ast_channel_lock(chan);
05794 
05795    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
05796       if ((var=ast_var_name(variables)) && (val=ast_var_value(variables))
05797          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
05798          ) {
05799          if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) {
05800             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
05801             break;
05802          } else
05803             total++;
05804       } else
05805          break;
05806    }
05807 
05808    ast_channel_unlock(chan);
05809 
05810    return total;
05811 }

int pbx_builtin_setvar ( struct ast_channel chan,
void *  data 
)

Note:
Will lock the channel.

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

Note:
Will lock the channel.

Definition at line 5885 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, 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(), option_verbose, and VERBOSE_PREFIX_2.

Referenced by __oh323_new(), _macro_exec(), _while_exec(), acf_odbc_read(), acf_odbc_write(), action_setvar(), agi_exec_full(), aji_status_exec(), app_exec(), aqm_exec(), array(), ast_bridge_call(), ast_channel_bridge(), ast_feature_request_and_dial(), ast_iax2_new(), ast_monitor_start(), ast_pbx_outgoing_exten(), ast_set_variables(), background_detect_exec(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), controlplayback_exec(), count_exec(), disa_exec(), do_waiting(), export_aoc_vars(), export_ch(), function_db_delete(), function_db_exists(), function_db_read(), global_write(), handle_request_bye(), handle_request_refer(), handle_set_global(), handle_set_global_deprecated(), handle_setvariable(), hasvoicemail_exec(), isAnsweringMachine(), leave_voicemail(), local_hangup(), lookupblacklist_exec(), misdn_call(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_exec(), parse_moved_contact(), pbx_builtin_importvar(), pbx_builtin_saydate(), pbx_builtin_saytime(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_load_config(), play_message_datetime(), playback_exec(), pop_exec(), pqm_exec(), prep_email_sub_vars(), privacy_exec(), process_ast_dsp(), read_exec(), readfile_exec(), realtime_exec(), realtime_update_exec(), record_exec(), return_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_hangup(), sip_new(), sla_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), ss_thread(), start_monitor_exec(), system_exec_helper(), transfer_exec(), try_calling(), tryexec_exec(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), zt_handle_dtmfup(), and zt_new().

05886 {
05887    struct ast_var_t *newvariable;
05888    struct varshead *headp;
05889    const char *nametail = name;
05890 
05891    if (name[strlen(name)-1] == ')') {
05892       char *function = ast_strdupa(name);
05893 
05894       ast_func_write(chan, function, value);
05895       return;
05896    }
05897 
05898    if (chan) {
05899       ast_channel_lock(chan);
05900       headp = &chan->varshead;
05901    } else {
05902       ast_mutex_lock(&globalslock);
05903       headp = &globals;
05904    }
05905 
05906    /* For comparison purposes, we have to strip leading underscores */
05907    if (*nametail == '_') {
05908       nametail++;
05909       if (*nametail == '_')
05910          nametail++;
05911    }
05912 
05913    AST_LIST_TRAVERSE (headp, newvariable, entries) {
05914       if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
05915          /* there is already such a variable, delete it */
05916          AST_LIST_REMOVE(headp, newvariable, entries);
05917          ast_var_delete(newvariable);
05918          break;
05919       }
05920    }
05921 
05922    if (value) {
05923       if ((option_verbose > 1) && (headp == &globals))
05924          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05925       newvariable = ast_var_assign(name, value);
05926       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05927    }
05928 
05929    if (chan)
05930       ast_channel_unlock(chan);
05931    else
05932       ast_mutex_unlock(&globalslock);
05933 }

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 6046 of file pbx.c.

References ast_strlen_zero().

Referenced by _macro_exec(), _while_exec(), acf_if(), execif_exec(), gosubif_exec(), macroif_exec(), and pbx_builtin_gotoif().

06047 {
06048    if (ast_strlen_zero(condition))  /* NULL or empty strings are false */
06049       return 0;
06050    else if (*condition >= '0' && *condition <= '9')   /* Numbers are evaluated for truth */
06051       return atoi(condition);
06052    else  /* Strings are true */
06053       return 1;
06054 }

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 537 of file pbx.c.

References app, ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_channel::cdr, ast_channel::data, and S_OR.

Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), milliwatt_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().

00540 {
00541    int res;
00542 
00543    const char *saved_c_appl;
00544    const char *saved_c_data;
00545 
00546    if (c->cdr && !ast_check_hangup(c))
00547       ast_cdr_setapp(c->cdr, app->name, data);
00548 
00549    /* save channel values */
00550    saved_c_appl= c->appl;
00551    saved_c_data= c->data;
00552 
00553    c->appl = app->name;
00554    c->data = data;
00555    /* XXX remember what to to when we have linked apps to modules */
00556    if (app->module) {
00557       /* XXX LOCAL_USER_ADD(app->module) */
00558    }
00559    res = app->execute(c, S_OR(data, ""));
00560    if (app->module) {
00561       /* XXX LOCAL_USER_REMOVE(app->module) */
00562    }
00563    /* restore channel values */
00564    c->appl = saved_c_appl;
00565    c->data = saved_c_data;
00566    return res;
00567 }

struct ast_app* pbx_findapp ( const char *  app  ) 

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 575 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.

Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), milliwatt_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().

00576 {
00577    struct ast_app *tmp;
00578 
00579    AST_LIST_LOCK(&apps);
00580    AST_LIST_TRAVERSE(&apps, tmp, list) {
00581       if (!strcasecmp(tmp->name, app))
00582          break;
00583    }
00584    AST_LIST_UNLOCK(&apps);
00585 
00586    return tmp;
00587 }

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 ---

Note:
Will lock the channel.

Definition at line 1173 of file pbx.c.

References ast_cause2str(), ast_channel_lock, ast_channel_unlock, 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, ast_channel::hangupcause, offset, parse_variable_name(), ast_channel::priority, s, and substring().

Referenced by action_getvar(), handle_getvariable(), and pbx_substitute_variables_helper_full().

01174 {
01175    const char not_found = '\0';
01176    char *tmpvar;
01177    const char *s; /* the result */
01178    int offset, length;
01179    int i, need_substring;
01180    struct varshead *places[2] = { headp, &globals };  /* list of places where we may look */
01181 
01182    if (c) {
01183       ast_channel_lock(c);
01184       places[0] = &c->varshead;
01185    }
01186    /*
01187     * Make a copy of var because parse_variable_name() modifies the string.
01188     * Then if called directly, we might need to run substring() on the result;
01189     * remember this for later in 'need_substring', 'offset' and 'length'
01190     */
01191    tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */
01192    need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
01193 
01194    /*
01195     * Look first into predefined variables, then into variable lists.
01196     * Variable 's' points to the result, according to the following rules:
01197     * s == &not_found (set at the beginning) means that we did not find a
01198     * matching variable and need to look into more places.
01199     * If s != &not_found, s is a valid result string as follows:
01200     * s = NULL if the variable does not have a value;
01201     * you typically do this when looking for an unset predefined variable.
01202     * s = workspace if the result has been assembled there;
01203     * typically done when the result is built e.g. with an snprintf(),
01204     * so we don't need to do an additional copy.
01205     * s != workspace in case we have a string, that needs to be copied
01206     * (the ast_copy_string is done once for all at the end).
01207     * Typically done when the result is already available in some string.
01208     */
01209    s = &not_found;   /* default value */
01210    if (c) { /* This group requires a valid channel */
01211       /* Names with common parts are looked up a piece at a time using strncmp. */
01212       if (!strncmp(var, "CALL", 4)) {
01213          if (!strncmp(var + 4, "ING", 3)) {
01214             if (!strcmp(var + 7, "PRES")) {        /* CALLINGPRES */
01215                snprintf(workspace, workspacelen, "%d", c->cid.cid_pres);
01216                s = workspace;
01217             } else if (!strcmp(var + 7, "ANI2")) {    /* CALLINGANI2 */
01218                snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2);
01219                s = workspace;
01220             } else if (!strcmp(var + 7, "TON")) {     /* CALLINGTON */
01221                snprintf(workspace, workspacelen, "%d", c->cid.cid_ton);
01222                s = workspace;
01223             } else if (!strcmp(var + 7, "TNS")) {     /* CALLINGTNS */
01224                snprintf(workspace, workspacelen, "%d", c->cid.cid_tns);
01225                s = workspace;
01226             }
01227          }
01228       } else if (!strcmp(var, "HINT")) {
01229          s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL;
01230       } else if (!strcmp(var, "HINTNAME")) {
01231          s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL;
01232       } else if (!strcmp(var, "EXTEN")) {
01233          s = c->exten;
01234       } else if (!strcmp(var, "CONTEXT")) {
01235          s = c->context;
01236       } else if (!strcmp(var, "PRIORITY")) {
01237          snprintf(workspace, workspacelen, "%d", c->priority);
01238          s = workspace;
01239       } else if (!strcmp(var, "CHANNEL")) {
01240          s = c->name;
01241       } else if (!strcmp(var, "UNIQUEID")) {
01242          s = c->uniqueid;
01243       } else if (!strcmp(var, "HANGUPCAUSE")) {
01244          snprintf(workspace, workspacelen, "%d", c->hangupcause);
01245          s = workspace;
01246       } else if (c && !strcmp(var, "HANGUPCAUSESTR")) {
01247          ast_copy_string(workspace, ast_cause2str(c->hangupcause), workspacelen);
01248          *ret = workspace;
01249       }
01250    }
01251    if (s == &not_found) { /* look for more */
01252       if (!strcmp(var, "EPOCH")) {
01253          snprintf(workspace, workspacelen, "%u",(int)time(NULL));
01254          s = workspace;
01255       } else if (!strcmp(var, "SYSTEMNAME")) {
01256          s = ast_config_AST_SYSTEM_NAME;
01257       }
01258    }
01259    /* if not found, look into chanvars or global vars */
01260    for (i = 0; s == &not_found && i < (sizeof(places) / sizeof(places[0])); i++) {
01261       struct ast_var_t *variables;
01262       if (!places[i])
01263          continue;
01264       if (places[i] == &globals)
01265          ast_mutex_lock(&globalslock);
01266       AST_LIST_TRAVERSE(places[i], variables, entries) {
01267          if (strcasecmp(ast_var_name(variables), var)==0) {
01268             s = ast_var_value(variables);
01269             break;
01270          }
01271       }
01272       if (places[i] == &globals)
01273          ast_mutex_unlock(&globalslock);
01274    }
01275    if (s == &not_found || s == NULL)
01276       *ret = NULL;
01277    else {
01278       if (s != workspace)
01279          ast_copy_string(workspace, s, workspacelen);
01280       *ret = workspace;
01281       if (need_substring)
01282          *ret = substring(*ret, offset, length, workspace, workspacelen);
01283    }
01284 
01285    if (c)
01286       ast_channel_unlock(c);
01287 }

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 2713 of file pbx.c.

References autofallthrough.

Referenced by pbx_load_module().

02714 {
02715    int oldval = autofallthrough;
02716    autofallthrough = newval;
02717    return oldval;
02718 }

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

Definition at line 1792 of file pbx.c.

References pbx_substitute_variables_helper_full(), and ast_channel::varshead.

Referenced by _macro_exec(), acf_odbc_read(), acf_odbc_write(), add_extensions(), custom_log(), cut_internal(), exec_exec(), function_eval(), function_fieldqty(), handle_getvariablefull(), launch_monitor_thread(), make_email_file(), pbx_builtin_importvar(), pbx_load_config(), pbx_substitute_variables(), realtime_exec(), rpt_do_lstats(), sendpage(), try_calling(), and tryexec_exec().

01793 {
01794    pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
01795 }

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

Definition at line 1797 of file pbx.c.

References pbx_substitute_variables_helper_full().

Referenced by ast_add_extension2(), dundi_lookup_local(), and loopback_subst().

01798 {
01799    pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
01800 }


Generated on Tue Nov 4 13:20:41 2008 for Asterisk - the Open Source PBX by  doxygen 1.4.7