Mon Mar 31 07:42:07 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"

Include dependency graph for pbx.h:

This graph shows which files directly or indirectly include this file:

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 }
 The result codes when starting the PBX on a channel with ast_pbx_start(). More...

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)
 Register a new context or find an existing one.
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
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 hint exists, return non-zero.
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)
 Support for Asterisk built-in variables and functions in the dialplan.
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)
Functions for returning values from structures

const char * ast_get_context_name (struct ast_context *con)
ast_contextast_get_extension_context (struct ast_exten *exten)
const char * ast_get_extension_name (struct ast_exten *exten)
const char * ast_get_ignorepat_name (struct ast_ignorepat *ip)
const char * ast_get_include_name (struct ast_include *include)
const char * ast_get_switch_data (struct ast_sw *sw)
const char * ast_get_switch_name (struct ast_sw *sw)
Registrar info functions ...
const char * ast_get_context_registrar (struct ast_context *c)
const char * ast_get_extension_registrar (struct ast_exten *e)
const char * ast_get_ignorepat_registrar (struct ast_ignorepat *ip)
const char * ast_get_include_registrar (struct ast_include *i)
const char * ast_get_switch_registrar (struct ast_sw *sw)
Other Extension stuff
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)
const char * ast_get_extension_label (struct ast_exten *e)
int ast_get_extension_matchcid (struct ast_exten *e)
int ast_get_extension_priority (struct ast_exten *exten)


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 69 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 83 of file pbx.h.


Enumeration Type Documentation

enum ast_extension_states

Extension states.

Note:
States can be combined
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 50 of file pbx.h.

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

enum ast_pbx_result

The result codes when starting the PBX on a channel with ast_pbx_start().

AST_PBX_CALL_LIMIT refers to the maxcalls call limit in asterisk.conf

Enumerator:
AST_PBX_SUCCESS 
AST_PBX_FAILED 
AST_PBX_CALL_LIMIT 

Definition at line 236 of file pbx.h.

00236                     {
00237    AST_PBX_SUCCESS = 0,
00238    AST_PBX_FAILED = -1,
00239    AST_PBX_CALL_LIMIT = -2,
00240 };


Function Documentation

int ast_active_calls ( void   ) 

Retrieve the number of active calls.

Definition at line 2687 of file pbx.c.

References countcalls.

Referenced by handle_chanlist(), and handle_chanlist_deprecated().

02688 {
02689    return countcalls;
02690 }

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 4564 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().

04567 {
04568    int ret = -1;
04569    struct ast_context *c = find_context_locked(context);
04570 
04571    if (c) {
04572       ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
04573          application, data, datad, registrar);
04574       ast_unlock_contexts();
04575    }
04576    return ret;
04577 }

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 4773 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().

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

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

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

04603 {
04604    int res = 0;
04605 
04606    ast_channel_lock(chan);
04607 
04608    if (chan->pbx) { /* This channel is currently in the PBX */
04609       ast_explicit_goto(chan, context, exten, priority);
04610       ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
04611    } else {
04612       /* In order to do it when the channel doesn't really exist within
04613          the PBX, we have to make a new channel, masquerade, and start the PBX
04614          at the new location */
04615       struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name);
04616       if (chan->cdr) {
04617          ast_cdr_discard(tmpchan->cdr);
04618          tmpchan->cdr = ast_cdr_dup(chan->cdr);  /* share the love */
04619       }
04620       if (!tmpchan)
04621          res = -1;
04622       else {
04623          /* Make formats okay */
04624          tmpchan->readformat = chan->readformat;
04625          tmpchan->writeformat = chan->writeformat;
04626          /* Setup proper location */
04627          ast_explicit_goto(tmpchan,
04628             S_OR(context, chan->context), S_OR(exten, chan->exten), priority);
04629 
04630          /* Masquerade into temp channel */
04631          ast_channel_masquerade(tmpchan, chan);
04632 
04633          /* Grab the locks and get going */
04634          ast_channel_lock(tmpchan);
04635          ast_do_masquerade(tmpchan);
04636          ast_channel_unlock(tmpchan);
04637          /* Start the PBX going on our stolen channel */
04638          if (ast_pbx_start(tmpchan)) {
04639             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
04640             ast_hangup(tmpchan);
04641             res = -1;
04642          }
04643       }
04644    }
04645    ast_channel_unlock(chan);
04646    return res;
04647 }

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

Definition at line 4649 of file pbx.c.

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

04650 {
04651    struct ast_channel *chan;
04652    int res = -1;
04653 
04654    chan = ast_get_channel_by_name_locked(channame);
04655    if (chan) {
04656       res = ast_async_goto(chan, context, exten, priority);
04657       ast_channel_unlock(chan);
04658    }
04659    return res;
04660 }

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

References __ast_goto_if_exists().

Referenced by asyncgoto_exec().

06368 {
06369    return __ast_goto_if_exists(chan, context, exten, priority, 1);
06370 }

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

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

04248 {
04249    char info_save[256];
04250    char *info;
04251 
04252    /* Check for empty just in case */
04253    if (ast_strlen_zero(info_in))
04254       return 0;
04255    /* make a copy just in case we were passed a static string */
04256    ast_copy_string(info_save, info_in, sizeof(info_save));
04257    info = info_save;
04258    /* Assume everything except time */
04259    i->monthmask = 0xfff;   /* 12 bits */
04260    i->daymask = 0x7fffffffU; /* 31 bits */
04261    i->dowmask = 0x7f; /* 7 bits */
04262    /* on each call, use strsep() to move info to the next argument */
04263    get_timerange(i, strsep(&info, "|"));
04264    if (info)
04265       i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week");
04266    if (info)
04267       i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day");
04268    if (info)
04269       i->monthmask = get_range(strsep(&info, "|"), 12, months, "month");
04270    return 1;
04271 }

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 2311 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(), nv_background_detect_exec(), nv_detectfax_exec(), phone_check_exception(), skinny_ss(), ss_thread(), and valid_exit().

02312 {
02313    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH);
02314 }

int ast_check_timing ( const struct ast_timing i  ) 

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

04274 {
04275    struct tm tm;
04276    time_t t = time(NULL);
04277 
04278    ast_localtime(&t, &tm, NULL);
04279 
04280    /* If it's not the right month, return */
04281    if (!(i->monthmask & (1 << tm.tm_mon)))
04282       return 0;
04283 
04284    /* If it's not that time of the month.... */
04285    /* Warning, tm_mday has range 1..31! */
04286    if (!(i->daymask & (1 << (tm.tm_mday-1))))
04287       return 0;
04288 
04289    /* If it's not the right day of the week */
04290    if (!(i->dowmask & (1 << tm.tm_wday)))
04291       return 0;
04292 
04293    /* Sanity check the hour just to be safe */
04294    if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
04295       ast_log(LOG_WARNING, "Insane time...\n");
04296       return 0;
04297    }
04298 
04299    /* Now the tough part, we calculate if it fits
04300       in the right time based on min/hour */
04301    if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
04302       return 0;
04303 
04304    /* If we got this far, then we're good */
04305    return 1;
04306 }

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 4500 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().

04501 {
04502    int ret = -1;
04503    struct ast_context *c = find_context_locked(context);
04504 
04505    if (c) {
04506       ret = ast_context_add_ignorepat2(c, value, registrar);
04507       ast_unlock_contexts();
04508    }
04509    return ret;
04510 }

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

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

04513 {
04514    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
04515    int length;
04516    length = sizeof(struct ast_ignorepat);
04517    length += strlen(value) + 1;
04518    if (!(ignorepat = ast_calloc(1, length)))
04519       return -1;
04520    /* The cast to char * is because we need to write the initial value.
04521     * The field is not supposed to be modified otherwise
04522     */
04523    strcpy((char *)ignorepat->pattern, value);
04524    ignorepat->next = NULL;
04525    ignorepat->registrar = registrar;
04526    ast_mutex_lock(&con->lock);
04527    for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
04528       ignorepatl = ignorepatc;
04529       if (!strcasecmp(ignorepatc->pattern, value)) {
04530          /* Already there */
04531          ast_mutex_unlock(&con->lock);
04532          errno = EEXIST;
04533          return -1;
04534       }
04535    }
04536    if (ignorepatl)
04537       ignorepatl->next = ignorepat;
04538    else
04539       con->ignorepats = ignorepat;
04540    ast_mutex_unlock(&con->lock);
04541    return 0;
04542 
04543 }

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 4053 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().

04054 {
04055    int ret = -1;
04056    struct ast_context *c = find_context_locked(context);
04057 
04058    if (c) {
04059       ret = ast_context_add_include2(c, include, registrar);
04060       ast_unlock_contexts();
04061    }
04062    return ret;
04063 }

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 4315 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().

04317 {
04318    struct ast_include *new_include;
04319    char *c;
04320    struct ast_include *i, *il = NULL; /* include, include_last */
04321    int length;
04322    char *p;
04323 
04324    length = sizeof(struct ast_include);
04325    length += 2 * (strlen(value) + 1);
04326 
04327    /* allocate new include structure ... */
04328    if (!(new_include = ast_calloc(1, length)))
04329       return -1;
04330    /* Fill in this structure. Use 'p' for assignments, as the fields
04331     * in the structure are 'const char *'
04332     */
04333    p = new_include->stuff;
04334    new_include->name = p;
04335    strcpy(p, value);
04336    p += strlen(value) + 1;
04337    new_include->rname = p;
04338    strcpy(p, value);
04339    /* Strip off timing info, and process if it is there */
04340    if ( (c = strchr(p, '|')) ) {
04341       *c++ = '\0';
04342            new_include->hastime = ast_build_timing(&(new_include->timing), c);
04343    }
04344    new_include->next      = NULL;
04345    new_include->registrar = registrar;
04346 
04347    ast_mutex_lock(&con->lock);
04348 
04349    /* ... go to last include and check if context is already included too... */
04350    for (i = con->includes; i; i = i->next) {
04351       if (!strcasecmp(i->name, new_include->name)) {
04352          free(new_include);
04353          ast_mutex_unlock(&con->lock);
04354          errno = EEXIST;
04355          return -1;
04356       }
04357       il = i;
04358    }
04359 
04360    /* ... include new context into context list, unlock, return */
04361    if (il)
04362       il->next = new_include;
04363    else
04364       con->includes = new_include;
04365    if (option_verbose > 2)
04366       ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
04367    ast_mutex_unlock(&con->lock);
04368 
04369    return 0;
04370 }

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

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

04378 {
04379    int ret = -1;
04380    struct ast_context *c = find_context_locked(context);
04381 
04382    if (c) { /* found, add switch to this context */
04383       ret = ast_context_add_switch2(c, sw, data, eval, registrar);
04384       ast_unlock_contexts();
04385    }
04386    return ret;
04387 }

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 4396 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().

04398 {
04399    struct ast_sw *new_sw;
04400    struct ast_sw *i;
04401    int length;
04402    char *p;
04403 
04404    length = sizeof(struct ast_sw);
04405    length += strlen(value) + 1;
04406    if (data)
04407       length += strlen(data);
04408    length++;
04409 
04410    /* allocate new sw structure ... */
04411    if (!(new_sw = ast_calloc(1, length)))
04412       return -1;
04413    /* ... fill in this structure ... */
04414    p = new_sw->stuff;
04415    new_sw->name = p;
04416    strcpy(new_sw->name, value);
04417    p += strlen(value) + 1;
04418    new_sw->data = p;
04419    if (data) {
04420       strcpy(new_sw->data, data);
04421       p += strlen(data) + 1;
04422    } else {
04423       strcpy(new_sw->data, "");
04424       p++;
04425    }
04426    new_sw->eval     = eval;
04427    new_sw->registrar = registrar;
04428 
04429    /* ... try to lock this context ... */
04430    ast_mutex_lock(&con->lock);
04431 
04432    /* ... go to last sw and check if context is already swd too... */
04433    AST_LIST_TRAVERSE(&con->alts, i, list) {
04434       if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
04435          free(new_sw);
04436          ast_mutex_unlock(&con->lock);
04437          errno = EEXIST;
04438          return -1;
04439       }
04440    }
04441 
04442    /* ... sw new context into context list, unlock, return */
04443    AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
04444 
04445    if (option_verbose > 2)
04446       ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
04447 
04448    ast_mutex_unlock(&con->lock);
04449 
04450    return 0;
04451 }

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

References __ast_context_create().

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

03924 {
03925    return __ast_context_create(extcontexts, name, registrar, 0);
03926 }

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 5365 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().

05366 {
05367    ast_wrlock_contexts();
05368    __ast_context_destroy(con,registrar);
05369    ast_unlock_contexts();
05370 }

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 897 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().

00898 {
00899    struct ast_context *tmp = NULL;
00900 
00901    ast_rdlock_contexts();
00902 
00903    while ( (tmp = ast_walk_contexts(tmp)) ) {
00904       if (!name || !strcasecmp(name, tmp->name))
00905          break;
00906    }
00907 
00908    ast_unlock_contexts();
00909 
00910    return tmp;
00911 }

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

Register a new context or find an existing one.

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

References __ast_context_create().

Referenced by pbx_load_config(), and pbx_load_users().

03929 {
03930    return __ast_context_create(extcontexts, name, registrar, 1);
03931 }

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 2924 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().

02925 {
02926    struct ast_context *c = NULL;
02927    int ret = -1;
02928 
02929    ast_rdlock_contexts();
02930 
02931    while ((c = ast_walk_contexts(c))) {
02932       if (!strcmp(ast_get_context_name(c), context)) {
02933          ret = 0;
02934          break;
02935       }
02936    }
02937 
02938    ast_unlock_contexts();
02939 
02940    /* if we found context, lock macrolock */
02941    if (ret == 0) 
02942       ret = ast_mutex_lock(&c->macrolock);
02943 
02944    return ret;
02945 }

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 2825 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().

02826 {
02827    int ret = -1; /* default error return */
02828    struct ast_context *c = find_context_locked(context);
02829 
02830    if (c) { /* ... remove extension ... */
02831       ret = ast_context_remove_extension2(c, extension, priority, registrar);
02832       ast_unlock_contexts();
02833    }
02834    return ret;
02835 }

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 2847 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().

02848 {
02849    struct ast_exten *exten, *prev_exten = NULL;
02850    struct ast_exten *peer;
02851 
02852    ast_mutex_lock(&con->lock);
02853 
02854    /* scan the extension list to find matching extension-registrar */
02855    for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
02856       if (!strcmp(exten->exten, extension) &&
02857          (!registrar || !strcmp(exten->registrar, registrar)))
02858          break;
02859    }
02860    if (!exten) {
02861       /* we can't find right extension */
02862       ast_mutex_unlock(&con->lock);
02863       return -1;
02864    }
02865 
02866    /* should we free all peers in this extension? (priority == 0)? */
02867    if (priority == 0) {
02868       /* remove this extension from context list */
02869       if (prev_exten)
02870          prev_exten->next = exten->next;
02871       else
02872          con->root = exten->next;
02873 
02874       /* fire out all peers */
02875       while ( (peer = exten) ) {
02876          exten = peer->peer; /* prepare for next entry */
02877          destroy_exten(peer);
02878       }
02879    } else {
02880       /* scan the priority list to remove extension with exten->priority == priority */
02881       struct ast_exten *previous_peer = NULL;
02882 
02883       for (peer = exten; peer; previous_peer = peer, peer = peer->peer) {
02884          if (peer->priority == priority &&
02885                (!registrar || !strcmp(peer->registrar, registrar) ))
02886             break; /* found our priority */
02887       }
02888       if (!peer) { /* not found */
02889          ast_mutex_unlock(&con->lock);
02890          return -1;
02891       }
02892       /* we are first priority extension? */
02893       if (!previous_peer) {
02894          /*
02895           * We are first in the priority chain, so must update the extension chain.
02896           * The next node is either the next priority or the next extension
02897           */
02898          struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
02899 
02900          if (!prev_exten)  /* change the root... */
02901             con->root = next_node;
02902          else
02903             prev_exten->next = next_node; /* unlink */
02904          if (peer->peer)   /* XXX update the new head of the pri list */
02905             peer->peer->next = peer->next;
02906       } else { /* easy, we are not first priority in extension */
02907          previous_peer->peer = peer->peer;
02908       }
02909 
02910       /* now, free whole priority extension */
02911       destroy_exten(peer);
02912       /* XXX should we return -1 ? */
02913    }
02914    ast_mutex_unlock(&con->lock);
02915    return 0;
02916 }

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

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

04458 {
04459    int ret = -1;
04460    struct ast_context *c = find_context_locked(context);
04461 
04462    if (c) {
04463       ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
04464       ast_unlock_contexts();
04465    }
04466    return ret;
04467 }

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

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

04470 {
04471    struct ast_ignorepat *ip, *ipl = NULL;
04472 
04473    ast_mutex_lock(&con->lock);
04474 
04475    for (ip = con->ignorepats; ip; ip = ip->next) {
04476       if (!strcmp(ip->pattern, ignorepat) &&
04477          (!registrar || (registrar == ip->registrar))) {
04478          if (ipl) {
04479             ipl->next = ip->next;
04480             free(ip);
04481          } else {
04482             con->ignorepats = ip->next;
04483             free(ip);
04484          }
04485          ast_mutex_unlock(&con->lock);
04486          return 0;
04487       }
04488       ipl = ip;
04489    }
04490 
04491    ast_mutex_unlock(&con->lock);
04492    errno = EINVAL;
04493    return -1;
04494 }

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 2721 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().

02722 {
02723    int ret = -1;
02724    struct ast_context *c = find_context_locked(context);
02725 
02726    if (c) {
02727       /* found, remove include from this context ... */
02728       ret = ast_context_remove_include2(c, include, registrar);
02729       ast_unlock_contexts();
02730    }
02731    return ret;
02732 }

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 2742 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().

02743 {
02744    struct ast_include *i, *pi = NULL;
02745    int ret = -1;
02746 
02747    ast_mutex_lock(&con->lock);
02748 
02749    /* find our include */
02750    for (i = con->includes; i; pi = i, i = i->next) {
02751       if (!strcmp(i->name, include) &&
02752             (!registrar || !strcmp(i->registrar, registrar))) {
02753          /* remove from list */
02754          if (pi)
02755             pi->next = i->next;
02756          else
02757             con->includes = i->next;
02758          /* free include and return */
02759          free(i);
02760          ret = 0;
02761          break;
02762       }
02763    }
02764 
02765    ast_mutex_unlock(&con->lock);
02766    return ret;
02767 }

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

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

02775 {
02776    int ret = -1; /* default error return */
02777    struct ast_context *c = find_context_locked(context);
02778 
02779    if (c) {
02780       /* remove switch from this context ... */
02781       ret = ast_context_remove_switch2(c, sw, data, registrar);
02782       ast_unlock_contexts();
02783    }
02784    return ret;
02785 }

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 2795 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().

02796 {
02797    struct ast_sw *i;
02798    int ret = -1;
02799 
02800    ast_mutex_lock(&con->lock);
02801 
02802    /* walk switches */
02803    AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
02804       if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
02805          (!registrar || !strcmp(i->registrar, registrar))) {
02806          /* found, remove from list */
02807          AST_LIST_REMOVE_CURRENT(&con->alts, list);
02808          free(i); /* free switch and return */
02809          ret = 0;
02810          break;
02811       }
02812    }
02813    AST_LIST_TRAVERSE_SAFE_END
02814 
02815    ast_mutex_unlock(&con->lock);
02816 
02817    return ret;
02818 }

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 2952 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().

02953 {
02954    struct ast_context *c = NULL;
02955    int ret = -1;
02956 
02957    ast_rdlock_contexts();
02958 
02959    while ((c = ast_walk_contexts(c))) {
02960       if (!strcmp(ast_get_context_name(c), context)) {
02961          ret = 0;
02962          break;
02963       }
02964    }
02965 
02966    ast_unlock_contexts();
02967 
02968    /* if we found context, unlock macrolock */
02969    if (ret == 0) 
02970       ret = ast_mutex_unlock(&c->macrolock);
02971 
02972    return ret;
02973 }

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 6324 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().

06325 {
06326    struct ast_include *inc = NULL;
06327    int res = 0;
06328 
06329    while ( (inc = ast_walk_context_includes(con, inc)) ) {
06330       if (ast_context_find(inc->rname))
06331          continue;
06332 
06333       res = -1;
06334       ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n",
06335          ast_get_context_name(con), inc->rname);
06336       break;
06337    }
06338 
06339    return res;
06340 }

struct ast_custom_function* ast_custom_function_find ( const char *  name  ) 

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

01461 {
01462    struct ast_custom_function *acf = NULL;
01463 
01464    AST_LIST_LOCK(&acf_root);
01465    AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
01466       if (!strcmp(name, acf->name))
01467          break;
01468    }
01469    AST_LIST_UNLOCK(&acf_root);
01470 
01471    return acf;
01472 }

int ast_custom_function_register ( struct ast_custom_function acf  ) 

Reigster a custom function.

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

01497 {
01498    struct ast_custom_function *cur;
01499 
01500    if (!acf)
01501       return -1;
01502 
01503    AST_LIST_LOCK(&acf_root);
01504 
01505    if (ast_custom_function_find(acf->name)) {
01506       ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
01507       AST_LIST_UNLOCK(&acf_root);
01508       return -1;
01509    }
01510 
01511    /* Store in alphabetical order */
01512    AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
01513       if (strcasecmp(acf->name, cur->name) < 0) {
01514          AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist);
01515          break;
01516       }
01517    }
01518    AST_LIST_TRAVERSE_SAFE_END
01519    if (!cur)
01520       AST_LIST_INSERT_TAIL(&acf_root, acf, acflist);
01521 
01522    AST_LIST_UNLOCK(&acf_root);
01523 
01524    if (option_verbose > 1)
01525       ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name);
01526 
01527    return 0;
01528 }

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

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

01475 {
01476    struct ast_custom_function *cur;
01477 
01478    if (!acf)
01479       return -1;
01480 
01481    AST_LIST_LOCK(&acf_root);
01482    AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
01483       if (cur == acf) {
01484          AST_LIST_REMOVE_CURRENT(&acf_root, acflist);
01485          if (option_verbose > 1)
01486             ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name);
01487          break;
01488       }
01489    }
01490    AST_LIST_TRAVERSE_SAFE_END
01491    AST_LIST_UNLOCK(&acf_root);
01492 
01493    return acf ? 0 : -1;
01494 }

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 2296 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_atxfer(), builtin_blindtransfer(), cb_events(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), disa_exec(), 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(), nv_background_detect_exec(), nv_detectfax_exec(), 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().

02297 {
02298    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH);
02299 }

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 4579 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(), builtin_atxfer(), disa_exec(), do_bridge_masquerade(), and handle_setpriority().

04580 {
04581    if (!chan)
04582       return -1;
04583 
04584    ast_channel_lock(chan);
04585 
04586    if (!ast_strlen_zero(context))
04587       ast_copy_string(chan->context, context, sizeof(chan->context));
04588    if (!ast_strlen_zero(exten))
04589       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
04590    if (priority > -1) {
04591       chan->priority = priority;
04592       /* see flag description in channel.h for explanation */
04593       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
04594          chan->priority--;
04595    }
04596 
04597    ast_channel_unlock(chan);
04598 
04599    return 0;
04600 }

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

Definition at line 890 of file pbx.c.

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

Referenced by realtime_switch_common().

00891 {
00892    if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
00893       ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
00894    return extension_match_core(pattern, data, needmore);
00895 }

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

References E_MATCH, and extension_match_core().

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

00886 {
00887    return extension_match_core(pattern, data, E_MATCH);
00888 }

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

References ast_extension_state2(), and ast_hint_extension().

Referenced by action_extensionstate(), and handle_request_subscribe().

02021 {
02022    struct ast_exten *e;
02023 
02024    e = ast_hint_extension(c, context, exten);   /* Do we have a hint for this extension ? */
02025    if (!e)
02026       return -1;           /* No hint, return -1 */
02027 
02028    return ast_extension_state2(e);        /* Check all devices in the hint */
02029 }

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

References extension_states.

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

02009 {
02010    int i;
02011 
02012    for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) {
02013       if (extension_states[i].extension_state == extension_state)
02014          return extension_states[i].text;
02015    }
02016    return "Unknown";
02017 }

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 2075 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().

02077 {
02078    struct ast_hint *hint;
02079    struct ast_state_cb *cblist;
02080    struct ast_exten *e;
02081 
02082    /* If there's no context and extension:  add callback to statecbs list */
02083    if (!context && !exten) {
02084       AST_LIST_LOCK(&hints);
02085 
02086       for (cblist = statecbs; cblist; cblist = cblist->next) {
02087          if (cblist->callback == callback) {
02088             cblist->data = data;
02089             AST_LIST_UNLOCK(&hints);
02090             return 0;
02091          }
02092       }
02093 
02094       /* Now insert the callback */
02095       if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
02096          AST_LIST_UNLOCK(&hints);
02097          return -1;
02098       }
02099       cblist->id = 0;
02100       cblist->callback = callback;
02101       cblist->data = data;
02102 
02103       cblist->next = statecbs;
02104       statecbs = cblist;
02105 
02106       AST_LIST_UNLOCK(&hints);
02107       return 0;
02108    }
02109 
02110    if (!context || !exten)
02111       return -1;
02112 
02113    /* This callback type is for only one hint, so get the hint */
02114    e = ast_hint_extension(NULL, context, exten);
02115    if (!e) {
02116       return -1;
02117    }
02118 
02119    /* Find the hint in the list of hints */
02120    AST_LIST_LOCK(&hints);
02121 
02122    AST_LIST_TRAVERSE(&hints, hint, list) {
02123       if (hint->exten == e)
02124          break;
02125    }
02126 
02127    if (!hint) {
02128       /* We have no hint, sorry */
02129       AST_LIST_UNLOCK(&hints);
02130       return -1;
02131    }
02132 
02133    /* Now insert the callback in the callback list  */
02134    if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
02135       AST_LIST_UNLOCK(&hints);
02136       return -1;
02137    }
02138    cblist->id = stateid++;    /* Unique ID for this callback */
02139    cblist->callback = callback;  /* Pointer to callback routine */
02140    cblist->data = data;    /* Data for the callback */
02141 
02142    cblist->next = hint->callbacks;
02143    hint->callbacks = cblist;
02144 
02145    AST_LIST_UNLOCK(&hints);
02146    return cblist->id;
02147 }

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 2150 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().

02151 {
02152    struct ast_state_cb **p_cur = NULL; /* address of pointer to us */
02153    int ret = -1;
02154 
02155    if (!id && !callback)
02156       return -1;
02157 
02158    AST_LIST_LOCK(&hints);
02159 
02160    if (!id) {  /* id == 0 is a callback without extension */
02161       for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) {
02162          if ((*p_cur)->callback == callback)
02163             break;
02164       }
02165    } else { /* callback with extension, find the callback based on ID */
02166       struct ast_hint *hint;
02167       AST_LIST_TRAVERSE(&hints, hint, list) {
02168          for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) {
02169             if ((*p_cur)->id == id)
02170                break;
02171          }
02172          if (*p_cur) /* found in the inner loop */
02173             break;
02174       }
02175    }
02176    if (p_cur && *p_cur) {
02177       struct ast_state_cb *cur = *p_cur;
02178       *p_cur = cur->next;
02179       free(cur);
02180       ret = 0;
02181    }
02182    AST_LIST_UNLOCK(&hints);
02183    return ret;
02184 }

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 2301 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().

02302 {
02303    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL);
02304 }

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

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

02307 {
02308    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL);
02309 }

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 1550 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().

01551 {
01552    char *args = func_args(function);
01553    struct ast_custom_function *acfptr = ast_custom_function_find(function);
01554 
01555    if (acfptr == NULL)
01556       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01557    else if (!acfptr->read)
01558       ast_log(LOG_ERROR, "Function %s cannot be read\n", function);
01559    else
01560       return acfptr->read(chan, function, args, workspace, len);
01561    return -1;
01562 }

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 1564 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().

01565 {
01566    char *args = func_args(function);
01567    struct ast_custom_function *acfptr = ast_custom_function_find(function);
01568 
01569    if (acfptr == NULL)
01570       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01571    else if (!acfptr->write)
01572       ast_log(LOG_ERROR, "Function %s cannot be written to\n", function);
01573    else
01574       return acfptr->write(chan, function, args, value);
01575 
01576    return -1;
01577 }

const char* ast_get_context_name ( struct ast_context con  ) 

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

06182 {
06183    return con ? con->name : NULL;
06184 }

const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 6219 of file pbx.c.

References ast_context::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06220 {
06221    return c ? c->registrar : NULL;
06222 }

const char* ast_get_extension_app ( struct ast_exten e  ) 

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

06250 {
06251    return e ? e->app : NULL;
06252 }

void* ast_get_extension_app_data ( struct ast_exten e  ) 

Definition at line 6254 of file pbx.c.

References ast_exten::data.

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

06255 {
06256    return e ? e->data : NULL;
06257 }

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 6244 of file pbx.c.

References ast_exten::cidmatch.

Referenced by find_matching_priority(), and handle_save_dialplan().

06245 {
06246    return e ? e->cidmatch : NULL;
06247 }

struct ast_context* ast_get_extension_context ( struct ast_exten exten  ) 

Definition at line 6186 of file pbx.c.

References exten.

Referenced by handle_show_hints().

06187 {
06188    return exten ? exten->parent : NULL;
06189 }

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 6196 of file pbx.c.

References exten.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06197 {
06198    return exten ? exten->label : NULL;
06199 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 6239 of file pbx.c.

References ast_exten::matchcid.

Referenced by find_matching_priority(), and handle_save_dialplan().

06240 {
06241    return e ? e->matchcid : 0;
06242 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 

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

06192 {
06193    return exten ? exten->exten : NULL;
06194 }

int ast_get_extension_priority ( struct ast_exten exten  ) 

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

06212 {
06213    return exten ? exten->priority : -1;
06214 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 6224 of file pbx.c.

References ast_exten::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06225 {
06226    return e ? e->registrar : NULL;
06227 }

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 hint 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 2279 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().

02280 {
02281    struct ast_exten *e = ast_hint_extension(c, context, exten);
02282 
02283    if (e) {
02284       if (hint)
02285          ast_copy_string(hint, ast_get_extension_app(e), hintsize);
02286       if (name) {
02287          const char *tmp = ast_get_extension_app_data(e);
02288          if (tmp)
02289             ast_copy_string(name, tmp, namesize);
02290       }
02291       return -1;
02292    }
02293    return 0;
02294 }

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 

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

06207 {
06208    return ip ? ip->pattern : NULL;
06209 }

const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

Definition at line 6234 of file pbx.c.

References ast_ignorepat::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06235 {
06236    return ip ? ip->registrar : NULL;
06237 }

const char* ast_get_include_name ( struct ast_include include  ) 

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

06202 {
06203    return inc ? inc->name : NULL;
06204 }

const char* ast_get_include_registrar ( struct ast_include i  ) 

Definition at line 6229 of file pbx.c.

References ast_include::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06230 {
06231    return i ? i->registrar : NULL;
06232 }

const char* ast_get_switch_data ( struct ast_sw sw  ) 

Definition at line 6264 of file pbx.c.

References ast_sw::data.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06265 {
06266    return sw ? sw->data : NULL;
06267 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

Definition at line 6259 of file pbx.c.

References ast_sw::name.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06260 {
06261    return sw ? sw->name : NULL;
06262 }

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

Definition at line 6269 of file pbx.c.

References ast_sw::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06270 {
06271    return sw ? sw->registrar : NULL;
06272 }

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 6362 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().

06363 {
06364    return __ast_goto_if_exists(chan, context, exten, priority, 0);
06365 }

void ast_hint_state_changed ( const char *  device  ) 

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

02032 {
02033    struct ast_hint *hint;
02034 
02035    AST_LIST_LOCK(&hints);
02036 
02037    AST_LIST_TRAVERSE(&hints, hint, list) {
02038       struct ast_state_cb *cblist;
02039       char buf[AST_MAX_EXTENSION];
02040       char *parse = buf;
02041       char *cur;
02042       int state;
02043 
02044       ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf));
02045       while ( (cur = strsep(&parse, "&")) ) {
02046          if (!strcasecmp(cur, device))
02047             break;
02048       }
02049       if (!cur)
02050          continue;
02051 
02052       /* Get device state for this hint */
02053       state = ast_extension_state2(hint->exten);
02054 
02055       if ((state == -1) || (state == hint->laststate))
02056          continue;
02057 
02058       /* Device state changed since last check - notify the watchers */
02059 
02060       /* For general callbacks */
02061       for (cblist = statecbs; cblist; cblist = cblist->next)
02062          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
02063 
02064       /* For extension callbacks */
02065       for (cblist = hint->callbacks; cblist; cblist = cblist->next)
02066          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
02067 
02068       hint->laststate = state;   /* record we saw the change */
02069    }
02070 
02071    AST_LIST_UNLOCK(&hints);
02072 }

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 4545 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().

04546 {
04547    struct ast_context *con = ast_context_find(context);
04548    if (con) {
04549       struct ast_ignorepat *pat;
04550       for (pat = con->ignorepats; pat; pat = pat->next) {
04551          if (ast_extension_match(pat->pattern, pattern))
04552             return 1;
04553       }
04554    }
04555 
04556    return 0;
04557 }

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 6168 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().

06169 {
06170    return ast_mutex_lock(&con->lock);
06171 }

int ast_lock_contexts ( void   ) 

Locks the context list.

Return values:
0 on success
-1 on error

Definition at line 6145 of file pbx.c.

References ast_rwlock_wrlock().

Referenced by find_matching_endwhile().

06146 {
06147    return ast_rwlock_wrlock(&conlock);
06148 }

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 2316 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().

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

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 3946 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().

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

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 6372 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().

06373 {
06374    char *exten, *pri, *context;
06375    char *stringp;
06376    int ipri;
06377    int mode = 0;
06378 
06379    if (ast_strlen_zero(goto_string)) {
06380       ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
06381       return -1;
06382    }
06383    stringp = ast_strdupa(goto_string);
06384    context = strsep(&stringp, "|"); /* guaranteed non-null */
06385    exten = strsep(&stringp, "|");
06386    pri = strsep(&stringp, "|");
06387    if (!exten) {  /* Only a priority in this one */
06388       pri = context;
06389       exten = NULL;
06390       context = NULL;
06391    } else if (!pri) {   /* Only an extension and priority in this one */
06392       pri = exten;
06393       exten = context;
06394       context = NULL;
06395    }
06396    if (*pri == '+') {
06397       mode = 1;
06398       pri++;
06399    } else if (*pri == '-') {
06400       mode = -1;
06401       pri++;
06402    }
06403    if (sscanf(pri, "%d", &ipri) != 1) {
06404       if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten,
06405          pri, chan->cid.cid_num)) < 1) {
06406          ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);
06407          return -1;
06408       } else
06409          mode = 0;
06410    }
06411    /* At this point we have a priority and maybe an extension and a context */
06412 
06413    if (mode)
06414       ipri = chan->priority + (ipri * mode);
06415 
06416    ast_explicit_goto(chan, context, exten, ipri);
06417    ast_cdr_update(chan);
06418    return 0;
06419 
06420 }

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 5165 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().

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

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 4999 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().

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

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 2674 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().

02675 {
02676    enum ast_pbx_result res = AST_PBX_SUCCESS;
02677 
02678    if (increase_call_count(c))
02679       return AST_PBX_CALL_LIMIT;
02680 
02681    res = __ast_pbx_run(c);
02682    decrease_call_count();
02683 
02684    return res;
02685 }

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 2648 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_bridge_call_thread(), ast_iax2_new(), ast_pbx_outgoing_exten(), bridge_exec(), 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().

02649 {
02650    pthread_t t;
02651    pthread_attr_t attr;
02652 
02653    if (!c) {
02654       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
02655       return AST_PBX_FAILED;
02656    }
02657 
02658    if (increase_call_count(c))
02659       return AST_PBX_CALL_LIMIT;
02660 
02661    /* Start a new thread, and get something handling this channel. */
02662    pthread_attr_init(&attr);
02663    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
02664    if (ast_pthread_create(&t, &attr, pbx_thread, c)) {
02665       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
02666       pthread_attr_destroy(&attr);
02667       return AST_PBX_FAILED;
02668    }
02669    pthread_attr_destroy(&attr);
02670 
02671    return AST_PBX_SUCCESS;
02672 }

int ast_rdlock_contexts ( void   ) 

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

06151 {
06152    return ast_rwlock_rdlock(&conlock);
06153 }

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 2976 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().

02977 {
02978    struct ast_app *tmp, *cur = NULL;
02979    char tmps[80];
02980    int length;
02981 
02982    AST_LIST_LOCK(&apps);
02983    AST_LIST_TRAVERSE(&apps, tmp, list) {
02984       if (!strcasecmp(app, tmp->name)) {
02985          ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
02986          AST_LIST_UNLOCK(&apps);
02987          return -1;
02988       }
02989    }
02990 
02991    length = sizeof(*tmp) + strlen(app) + 1;
02992 
02993    if (!(tmp = ast_calloc(1, length))) {
02994       AST_LIST_UNLOCK(&apps);
02995       return -1;
02996    }
02997 
02998    strcpy(tmp->name, app);
02999    tmp->execute = execute;
03000    tmp->synopsis = synopsis;
03001    tmp->description = description;
03002 
03003    /* Store in alphabetical order */
03004    AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) {
03005       if (strcasecmp(tmp->name, cur->name) < 0) {
03006          AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list);
03007          break;
03008       }
03009    }
03010    AST_LIST_TRAVERSE_SAFE_END
03011    if (!cur)
03012       AST_LIST_INSERT_TAIL(&apps, tmp, list);
03013 
03014    if (option_verbose > 1)
03015       ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
03016 
03017    AST_LIST_UNLOCK(&apps);
03018 
03019    return 0;
03020 }

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 3026 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().

03027 {
03028    struct ast_switch *tmp;
03029 
03030    AST_LIST_LOCK(&switches);
03031    AST_LIST_TRAVERSE(&switches, tmp, list) {
03032       if (!strcasecmp(tmp->name, sw->name)) {
03033          AST_LIST_UNLOCK(&switches);
03034          ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
03035          return -1;
03036       }
03037    }
03038    AST_LIST_INSERT_TAIL(&switches, sw, list);
03039    AST_LIST_UNLOCK(&switches);
03040 
03041    return 0;
03042 }

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

References E_SPAWN, and pbx_extension_helper().

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

02322 {
02323    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN);
02324 }

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 6173 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().

06174 {
06175    return ast_mutex_unlock(&con->lock);
06176 }

int ast_unlock_contexts ( void   ) 

Unlocks contexts.

Return values:
0 on success
-1 on failure

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

06161 {
06162    return ast_rwlock_unlock(&conlock);
06163 }

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 3857 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().

03858 {
03859    struct ast_app *tmp;
03860 
03861    AST_LIST_LOCK(&apps);
03862    AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) {
03863       if (!strcasecmp(app, tmp->name)) {
03864          AST_LIST_REMOVE_CURRENT(&apps, list);
03865          if (option_verbose > 1)
03866             ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
03867          free(tmp);
03868          break;
03869       }
03870    }
03871    AST_LIST_TRAVERSE_SAFE_END
03872    AST_LIST_UNLOCK(&apps);
03873 
03874    return tmp ? 0 : -1;
03875 }

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

References AST_LIST_LOCK, AST_LIST_REMOVE, and AST_LIST_UNLOCK.

Referenced by __unload_module(), and unload_module().

03045 {
03046    AST_LIST_LOCK(&switches);
03047    AST_LIST_REMOVE(&switches, sw, list);
03048    AST_LIST_UNLOCK(&switches);
03049 }

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

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

06284 {
06285    if (!exten)
06286       return con ? con->root : NULL;
06287    else
06288       return exten->next;
06289 }

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

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

06317 {
06318    if (!ip)
06319       return con ? con->ignorepats : NULL;
06320    else
06321       return ip->next;
06322 }

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

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

06308 {
06309    if (!inc)
06310       return con ? con->includes : NULL;
06311    else
06312       return inc->next;
06313 }

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

Definition at line 6291 of file pbx.c.

References AST_LIST_FIRST, and AST_LIST_NEXT.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06293 {
06294    if (!sw)
06295       return con ? AST_LIST_FIRST(&con->alts) : NULL;
06296    else
06297       return AST_LIST_NEXT(sw, list);
06298 }

struct ast_context* ast_walk_contexts ( struct ast_context con  ) 

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

06278 {
06279    return con ? con->next : contexts;
06280 }

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

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

06302 {
06303    return priority ? priority->peer : exten;
06304 }

int ast_wrlock_contexts ( void   ) 

Definition at line 6155 of file pbx.c.

References ast_rwlock_wrlock().

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

06156 {
06157    return ast_rwlock_wrlock(&conlock);
06158 }

void pbx_builtin_clear_globals ( void   ) 

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

06022 {
06023    struct ast_var_t *vardata;
06024 
06025    ast_mutex_lock(&globalslock);
06026    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
06027       ast_var_delete(vardata);
06028    ast_mutex_unlock(&globalslock);
06029 }

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

Note:
Will lock the channel.

Definition at line 5798 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(), pop_exec(), queue_exec(), real_ctx(), retrydial_exec(), return_exec(), run_agi(), rxfax_exec(), set_config_flags(), sip_addheader(), sla_trunk_exec(), speech_background(), try_calling(), try_suggested_sip_codec(), txfax_exec(), wait_for_answer(), zt_call(), and zt_hangup().

05799 {
05800    struct ast_var_t *variables;
05801    const char *ret = NULL;
05802    int i;
05803    struct varshead *places[2] = { NULL, &globals };
05804 
05805    if (!name)
05806       return NULL;
05807 
05808    if (chan) {
05809       ast_channel_lock(chan);
05810       places[0] = &chan->varshead;
05811    }
05812 
05813    for (i = 0; i < 2; i++) {
05814       if (!places[i])
05815          continue;
05816       if (places[i] == &globals)
05817          ast_mutex_lock(&globalslock);
05818       AST_LIST_TRAVERSE(places[i], variables, entries) {
05819          if (!strcmp(name, ast_var_name(variables))) {
05820             ret = ast_var_value(variables);
05821             break;
05822          }
05823       }
05824       if (places[i] == &globals)
05825          ast_mutex_unlock(&globalslock);
05826       if (ret)
05827          break;
05828    }
05829 
05830    if (chan)
05831       ast_channel_unlock(chan);
05832 
05833    return ret;
05834 }

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

Note:
Will lock the channel.

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

05837 {
05838    struct ast_var_t *newvariable;
05839    struct varshead *headp;
05840 
05841    if (name[strlen(name)-1] == ')') {
05842       char *function = ast_strdupa(name);
05843 
05844       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
05845       ast_func_write(chan, function, value);
05846       return;
05847    }
05848 
05849    if (chan) {
05850       ast_channel_lock(chan);
05851       headp = &chan->varshead;
05852    } else {
05853       ast_mutex_lock(&globalslock);
05854       headp = &globals;
05855    }
05856 
05857    if (value) {
05858       if ((option_verbose > 1) && (headp == &globals))
05859          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05860       newvariable = ast_var_assign(name, value);
05861       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05862    }
05863 
05864    if (chan)
05865       ast_channel_unlock(chan);
05866    else
05867       ast_mutex_unlock(&globalslock);
05868 }

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

Note:
Will lock the channel.

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

05768 {
05769    struct ast_var_t *variables;
05770    const char *var, *val;
05771    int total = 0;
05772 
05773    if (!chan)
05774       return 0;
05775 
05776    memset(buf, 0, size);
05777 
05778    ast_channel_lock(chan);
05779 
05780    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
05781       if ((var=ast_var_name(variables)) && (val=ast_var_value(variables))
05782          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
05783          ) {
05784          if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) {
05785             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
05786             break;
05787          } else
05788             total++;
05789       } else
05790          break;
05791    }
05792 
05793    ast_channel_unlock(chan);
05794 
05795    return total;
05796 }

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 5870 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(), aMYSQL_fetch(), 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(), bridge_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(), mwanalyze_exec(), MYSQL_exec(), nv_background_detect_exec(), nv_detectfax_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_exec(), parse_moved_contact(), pbx_builtin_importvar(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_load_config(), phase_e_handler(), pickdown_channel(), pickup_channel(), 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_asterisk_int(), 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(), steal_channel(), system_exec_helper(), transfer_exec(), try_calling(), tryexec_exec(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), zt_handle_dtmfup(), and zt_new().

05871 {
05872    struct ast_var_t *newvariable;
05873    struct varshead *headp;
05874    const char *nametail = name;
05875 
05876    if (name[strlen(name)-1] == ')') {
05877       char *function = ast_strdupa(name);
05878 
05879       ast_func_write(chan, function, value);
05880       return;
05881    }
05882 
05883    if (chan) {
05884       ast_channel_lock(chan);
05885       headp = &chan->varshead;
05886    } else {
05887       ast_mutex_lock(&globalslock);
05888       headp = &globals;
05889    }
05890 
05891    /* For comparison purposes, we have to strip leading underscores */
05892    if (*nametail == '_') {
05893       nametail++;
05894       if (*nametail == '_')
05895          nametail++;
05896    }
05897 
05898    AST_LIST_TRAVERSE (headp, newvariable, entries) {
05899       if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
05900          /* there is already such a variable, delete it */
05901          AST_LIST_REMOVE(headp, newvariable, entries);
05902          ast_var_delete(newvariable);
05903          break;
05904       }
05905    }
05906 
05907    if (value) {
05908       if ((option_verbose > 1) && (headp == &globals))
05909          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05910       newvariable = ast_var_assign(name, value);
05911       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05912    }
05913 
05914    if (chan)
05915       ast_channel_unlock(chan);
05916    else
05917       ast_mutex_unlock(&globalslock);
05918 }

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 6031 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().

06032 {
06033    if (ast_strlen_zero(condition))  /* NULL or empty strings are false */
06034       return 0;
06035    else if (*condition >= '0' && *condition <= '9')   /* Numbers are evaluated for truth */
06036       return atoi(condition);
06037    else  /* Strings are true */
06038       return 1;
06039 }

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 517 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(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().

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

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 555 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(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().

00556 {
00557    struct ast_app *tmp;
00558 
00559    AST_LIST_LOCK(&apps);
00560    AST_LIST_TRAVERSE(&apps, tmp, list) {
00561       if (!strcasecmp(tmp->name, app))
00562          break;
00563    }
00564    AST_LIST_UNLOCK(&apps);
00565 
00566    return tmp;
00567 }

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

Support for Asterisk built-in variables and functions in the dialplan.

Note:
See also

Definition at line 1157 of file pbx.c.

References 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(), function_fieldqty(), handle_getvariable(), and pbx_substitute_variables_helper_full().

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

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

References autofallthrough.

Referenced by pbx_load_module().

02693 {
02694    int oldval = autofallthrough;
02695    autofallthrough = newval;
02696    return oldval;
02697 }

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

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

01774 {
01775    pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
01776 }

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

Definition at line 1778 of file pbx.c.

References pbx_substitute_variables_helper_full().

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

01779 {
01780    pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
01781 }


Generated on Mon Mar 31 07:42:09 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1