Fri Jul 24 00:41:52 2009

Asterisk developer's documentation


pbx.h File Reference

Core PBX routines and definitions. More...

#include "asterisk/sched.h"
#include "asterisk/chanvars.h"
#include "asterisk/hashtab.h"

Go to the source code of this file.

Data Structures

struct  ast_custom_function
 Data structure associated with a custom dialplan function. More...
struct  ast_pbx
struct  ast_pbx_args
 Options for ast_pbx_run(). More...
struct  ast_switch
struct  ast_timing
struct  pbx_find_info
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)
int ast_get_switch_eval (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)

Defines

#define ast_custom_function_register(acf)   __ast_custom_function_register(acf, ast_module_info->self)
 Register a custom function.
#define AST_MAX_APP   32
#define AST_PBX_ERROR   1
#define AST_PBX_HANGUP   -1
 Special return values from applications to the PBX {.
#define AST_PBX_INCOMPLETE   12
#define AST_PBX_KEEP   0
#define AST_PBX_MAX_STACK   128
#define AST_PBX_OK   0
#define AST_PBX_REPLACE   1
#define PRIORITY_HINT   -1
#define STATUS_NO_CONTEXT   1
#define STATUS_NO_EXTENSION   2
#define STATUS_NO_LABEL   4
#define STATUS_NO_PRIORITY   3
#define STATUS_SUCCESS   5

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 channelwith. More...
enum  ext_match_t {
  E_MATCHMORE = 0x00, E_CANMATCH = 0x01, E_MATCH = 0x02, E_MATCH_MASK = 0x03,
  E_SPAWN = 0x12, E_FINDLABEL = 0x22
}

Functions

int __ast_custom_function_register (struct ast_custom_function *acf, struct ast_module *mod)
 Register a custom function.
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_async_parseable_goto (struct ast_channel *chan, const char *goto_string)
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).
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, struct ast_hashtab *exttable, 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, int already_locked)
 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_extension_callerid (const char *context, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar)
int ast_context_remove_extension_callerid2 (struct ast_context *con, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar, int already_locked)
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_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_cmp (const char *a, const char *b)
 Determine if one extension should match before another.
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, const char *function, char *workspace, size_t len)
 executes a read operation on a function
int ast_func_write (struct ast_channel *chan, const 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)
int ast_hashtab_compare_contexts (const void *ah_a, const void *ah_b)
unsigned int ast_hashtab_hash_contexts (const void *obj)
int ast_ignore_pattern (const char *context, const char *pattern)
 Checks to see if a number should be ignored.
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, struct ast_hashtab *exttable, 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_run_args (struct ast_channel *c, struct ast_pbx_args *args)
 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_processed_calls (void)
 Retrieve the total number of calls processed through the PBX since last restart.
int ast_rdlock_context (struct ast_context *con)
 Read locks a given context.
int ast_rdlock_contexts (void)
 Read locks the context list.
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, int *found, int combined_find_spawn)
 Launch a new extension (i.e. new stack).
int ast_unlock_context (struct ast_context *con)
int ast_unlock_contexts (void)
 Unlocks contexts.
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_context (struct ast_context *con)
 Write locks a given context.
int ast_wrlock_contexts (void)
 Write locks the context list.
int ast_wrlock_contexts_version (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_raise_exception (struct ast_channel *chan, void *data)
int pbx_builtin_serialize_variables (struct ast_channel *chan, struct ast_str **buf)
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_builtin_setvar_multiple (struct ast_channel *chan, void *data)
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_extenpbx_find_extension (struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
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 in the dialplan.
int pbx_set_autofallthrough (int newval)
int pbx_set_extenpatternmatchnew (int newval)
void pbx_set_overrideswitch (const char *newval)
void pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count)
void pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count)


Detailed Description

Core PBX routines and definitions.

Definition in file pbx.h.


Define Documentation

#define ast_custom_function_register ( acf   )     __ast_custom_function_register(acf, ast_module_info->self)

Register a custom function.

Definition at line 968 of file pbx.h.

Referenced by load_module(), and reload().

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

#define AST_PBX_ERROR   1

Jump to the 'e' exten

Definition at line 42 of file pbx.h.

#define AST_PBX_HANGUP   -1

Special return values from applications to the PBX {.

Jump to the 'h' exten

Definition at line 40 of file pbx.h.

#define AST_PBX_INCOMPLETE   12

Return to PBX matching, allowing more digits for the extension

Definition at line 43 of file pbx.h.

Referenced by dial_exec_full(), pbx_builtin_incomplete(), and retrydial_exec().

#define AST_PBX_KEEP   0

Definition at line 36 of file pbx.h.

#define AST_PBX_MAX_STACK   128

Definition at line 1033 of file pbx.h.

#define AST_PBX_OK   0

No errors

Definition at line 41 of file pbx.h.

#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 46 of file pbx.h.

Referenced by ast_add_extension2_lockopt(), ast_hint_extension_nolock(), ast_merge_contexts_and_delete(), destroy_exten(), destroy_station(), handle_cli_dialplan_add_extension(), handle_cli_dialplan_remove_extension(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), park_add_hints(), pbx_load_config(), and print_ext().

#define STATUS_NO_CONTEXT   1

Definition at line 1028 of file pbx.h.

#define STATUS_NO_EXTENSION   2

Definition at line 1029 of file pbx.h.

#define STATUS_NO_LABEL   4

Definition at line 1031 of file pbx.h.

#define STATUS_NO_PRIORITY   3

Definition at line 1030 of file pbx.h.

#define STATUS_SUCCESS   5

Definition at line 1032 of file pbx.h.


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 71 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 86 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 52 of file pbx.h.

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

enum ast_pbx_result

The result codes when starting the PBX on a channelwith.

See also:
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 228 of file pbx.h.

00228                     {
00229    AST_PBX_SUCCESS = 0,
00230    AST_PBX_FAILED = -1,
00231    AST_PBX_CALL_LIMIT = -2,
00232 };

enum ext_match_t

When looking up extensions, we can have different requests identified by the 'action' argument, as follows. Note that the coding is such that the low 4 bits are the third argument to extension_match_core.

Enumerator:
E_MATCHMORE 
E_CANMATCH 
E_MATCH 
E_MATCH_MASK 
E_SPAWN 
E_FINDLABEL 

Definition at line 1019 of file pbx.h.

01019                  {
01020    E_MATCHMORE =  0x00, /* extension can match but only with more 'digits' */
01021    E_CANMATCH =   0x01, /* extension can match with or without more 'digits' */
01022    E_MATCH =   0x02, /* extension is an exact match */
01023    E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */
01024    E_SPAWN =   0x12, /* want to spawn an extension. Requires exact match */
01025    E_FINDLABEL =  0x22  /* returns the priority for a given label. Requires exact match */
01026 };


Function Documentation

int __ast_custom_function_register ( struct ast_custom_function acf,
struct ast_module mod 
)

Register a custom function.

Definition at line 2792 of file pbx.c.

References ast_custom_function::acflist, ast_log(), AST_RWLIST_INSERT_BEFORE_CURRENT, AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, COLOR_BRCYAN, LOG_ERROR, ast_custom_function::mod, ast_custom_function::name, and term_color().

Referenced by load_pbx().

02793 {
02794    struct ast_custom_function *cur;
02795    char tmps[80];
02796 
02797    if (!acf)
02798       return -1;
02799 
02800    acf->mod = mod;
02801 
02802    AST_RWLIST_WRLOCK(&acf_root);
02803 
02804    AST_RWLIST_TRAVERSE(&acf_root, cur, acflist) {
02805       if (!strcmp(acf->name, cur->name)) {
02806          ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
02807          AST_RWLIST_UNLOCK(&acf_root);
02808          return -1;
02809       }
02810    }
02811 
02812    /* Store in alphabetical order */
02813    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
02814       if (strcasecmp(acf->name, cur->name) < 0) {
02815          AST_RWLIST_INSERT_BEFORE_CURRENT(acf, acflist);
02816          break;
02817       }
02818    }
02819    AST_RWLIST_TRAVERSE_SAFE_END;
02820    if (!cur)
02821       AST_RWLIST_INSERT_TAIL(&acf_root, acf, acflist);
02822 
02823    AST_RWLIST_UNLOCK(&acf_root);
02824 
02825    ast_verb(2, "Registered custom function '%s'\n", term_color(tmps, acf->name, COLOR_BRCYAN, 0, sizeof(tmps)));
02826 
02827    return 0;
02828 }

int ast_active_calls ( void   ) 

Retrieve the number of active calls.

Definition at line 4074 of file pbx.c.

References countcalls.

Referenced by handle_chanlist(), handle_showcalls(), and sysinfo_helper().

04075 {
04076    return countcalls;
04077 }

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

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

Referenced by ast_extension_state_add(), handle_cli_dialplan_add_extension(), park_add_hints(), register_exten(), register_peer_exten(), and RegisterExtension().

06694 {
06695    int ret = -1;
06696    struct ast_context *c = find_context_locked(context);
06697 
06698    if (c) {
06699       ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
06700          application, data, datad, registrar);
06701       ast_unlock_contexts();
06702    }
06703    
06704    return ret;
06705 }

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

References ast_add_extension2_lockopt().

Referenced by ast_add_extension(), ast_park_call_full(), build_parkinglot(), context_merge(), load_module(), manage_parkinglot(), pbx_load_config(), and pbx_load_users().

07013 {
07014    return ast_add_extension2_lockopt(con, replace, extension, priority, label, callerid, application, data, datad, registrar, 1, 1);
07015 }

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

Definition at line 6730 of file pbx.c.

References ast_channel::_state, ast_channel::accountcode, 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, chan, ast_channel::context, ast_channel::exten, LOG_WARNING, ast_channel::name, 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(), dahdi_handle_dtmfup(), handle_request_bye(), handle_request_refer(), pbx_parseable_goto(), process_ast_dsp(), and socket_process().

06731 {
06732    int res = 0;
06733 
06734    ast_channel_lock(chan);
06735 
06736    if (chan->pbx) { /* This channel is currently in the PBX */
06737       ast_explicit_goto(chan, context, exten, priority + 1);
06738       ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
06739    } else {
06740       /* In order to do it when the channel doesn't really exist within
06741          the PBX, we have to make a new channel, masquerade, and start the PBX
06742          at the new location */
06743       struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name);
06744       if (!tmpchan) {
06745          res = -1;
06746       } else {
06747          if (chan->cdr) {
06748             ast_cdr_discard(tmpchan->cdr);
06749             tmpchan->cdr = ast_cdr_dup(chan->cdr);  /* share the love */
06750          }
06751          /* Make formats okay */
06752          tmpchan->readformat = chan->readformat;
06753          tmpchan->writeformat = chan->writeformat;
06754          /* Setup proper location */
06755          ast_explicit_goto(tmpchan,
06756             S_OR(context, chan->context), S_OR(exten, chan->exten), priority);
06757 
06758          /* Masquerade into temp channel */
06759          if (ast_channel_masquerade(tmpchan, chan)) {
06760             /* Failed to set up the masquerade.  It's probably chan_local
06761              * in the middle of optimizing itself out.  Sad. :( */
06762             ast_hangup(tmpchan);
06763             tmpchan = NULL;
06764             res = -1;
06765          } else {
06766             /* Grab the locks and get going */
06767             ast_channel_lock(tmpchan);
06768             ast_do_masquerade(tmpchan);
06769             ast_channel_unlock(tmpchan);
06770             /* Start the PBX going on our stolen channel */
06771             if (ast_pbx_start(tmpchan)) {
06772                ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
06773                ast_hangup(tmpchan);
06774                res = -1;
06775             }
06776          }
06777       }
06778    }
06779    ast_channel_unlock(chan);
06780    return res;
06781 }

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

Definition at line 6783 of file pbx.c.

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

06784 {
06785    struct ast_channel *chan;
06786    int res = -1;
06787 
06788    chan = ast_get_channel_by_name_locked(channame);
06789    if (chan) {
06790       res = ast_async_goto(chan, context, exten, priority);
06791       ast_channel_unlock(chan);
06792    }
06793    return res;
06794 }

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

References __ast_goto_if_exists(), and chan.

08904 {
08905    return __ast_goto_if_exists(chan, context, exten, priority, 1);
08906 }

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

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

Definition at line 8966 of file pbx.c.

References chan, and pbx_parseable_goto().

Referenced by asyncgoto_exec().

08967 {
08968    return pbx_parseable_goto(chan, goto_string, 1);
08969 }

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

Definition at line 6351 of file pbx.c.

References ast_copy_string(), 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().

06352 {
06353    char info_save[256];
06354    char *info;
06355 
06356    /* Check for empty just in case */
06357    if (ast_strlen_zero(info_in))
06358       return 0;
06359    /* make a copy just in case we were passed a static string */
06360    ast_copy_string(info_save, info_in, sizeof(info_save));
06361    info = info_save;
06362    /* Assume everything except time */
06363    i->monthmask = 0xfff;   /* 12 bits */
06364    i->daymask = 0x7fffffffU; /* 31 bits */
06365    i->dowmask = 0x7f; /* 7 bits */
06366    /* on each call, use strsep() to move info to the next argument */
06367    get_timerange(i, strsep(&info, "|,"));
06368    if (info)
06369       i->dowmask = get_range(strsep(&info, "|,"), 7, days, "day of week");
06370    if (info)
06371       i->daymask = get_range(strsep(&info, "|,"), 31, NULL, "day");
06372    if (info)
06373       i->monthmask = get_range(strsep(&info, "|,"), 12, months, "month");
06374    return 1;
06375 }

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
Note:
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
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 3636 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(), leave_voicemail(), local_dtmf_helper(), loopback_canmatch(), mgcp_ss(), phone_check_exception(), skinny_ss(), ss_thread(), and valid_exit().

03637 {
03638    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0, 0);
03639 }

int ast_check_timing ( const struct ast_timing i  ) 

Definition at line 6377 of file pbx.c.

References ast_localtime(), ast_log(), ast_tvnow(), ast_timing::daymask, ast_timing::dowmask, LOG_WARNING, ast_timing::minmask, ast_timing::monthmask, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, and ast_tm::tm_wday.

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

06378 {
06379    struct ast_tm tm;
06380    struct timeval now = ast_tvnow();
06381 
06382    ast_localtime(&now, &tm, NULL);
06383 
06384    /* If it's not the right month, return */
06385    if (!(i->monthmask & (1 << tm.tm_mon)))
06386       return 0;
06387 
06388    /* If it's not that time of the month.... */
06389    /* Warning, tm_mday has range 1..31! */
06390    if (!(i->daymask & (1 << (tm.tm_mday-1))))
06391       return 0;
06392 
06393    /* If it's not the right day of the week */
06394    if (!(i->dowmask & (1 << tm.tm_wday)))
06395       return 0;
06396 
06397    /* Sanity check the hour just to be safe */
06398    if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
06399       ast_log(LOG_WARNING, "Insane time...\n");
06400       return 0;
06401    }
06402 
06403    /* Now the tough part, we calculate if it fits
06404       in the right time based on min/hour */
06405    if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
06406       return 0;
06407 
06408    /* If we got this far, then we're good */
06409    return 1;
06410 }

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

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

Referenced by handle_cli_dialplan_add_ignorepat().

06604 {
06605    int ret = -1;
06606    struct ast_context *c = find_context_locked(context);
06607 
06608    if (c) {
06609       ret = ast_context_add_ignorepat2(c, value, registrar);
06610       ast_unlock_contexts();
06611    }
06612    return ret;
06613 }

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

Definition at line 6615 of file pbx.c.

References ast_calloc, ast_unlock_context(), ast_wrlock_context(), errno, ast_context::ignorepats, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.

Referenced by ast_context_add_ignorepat(), context_merge_incls_swits_igps_other_registrars(), and pbx_load_config().

06616 {
06617    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
06618    int length;
06619    char *pattern;
06620    length = sizeof(struct ast_ignorepat);
06621    length += strlen(value) + 1;
06622    if (!(ignorepat = ast_calloc(1, length)))
06623       return -1;
06624    /* The cast to char * is because we need to write the initial value.
06625     * The field is not supposed to be modified otherwise.  Also, gcc 4.2
06626     * sees the cast as dereferencing a type-punned pointer and warns about
06627     * it.  This is the workaround (we're telling gcc, yes, that's really
06628     * what we wanted to do).
06629     */
06630    pattern = (char *) ignorepat->pattern;
06631    strcpy(pattern, value);
06632    ignorepat->next = NULL;
06633    ignorepat->registrar = registrar;
06634    ast_wrlock_context(con);
06635    for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
06636       ignorepatl = ignorepatc;
06637       if (!strcasecmp(ignorepatc->pattern, value)) {
06638          /* Already there */
06639          ast_unlock_context(con);
06640          errno = EEXIST;
06641          return -1;
06642       }
06643    }
06644    if (ignorepatl)
06645       ignorepatl->next = ignorepat;
06646    else
06647       con->ignorepats = ignorepat;
06648    ast_unlock_context(con);
06649    return 0;
06650 
06651 }

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

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

Referenced by handle_cli_dialplan_add_include().

06158 {
06159    int ret = -1;
06160    struct ast_context *c = find_context_locked(context);
06161 
06162    if (c) {
06163       ret = ast_context_add_include2(c, include, registrar);
06164       ast_unlock_contexts();
06165    }
06166    return ret;
06167 }

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

References ast_build_timing(), ast_calloc, ast_free, ast_get_context_name(), ast_unlock_context(), ast_verb, ast_wrlock_context(), errno, ast_include::hastime, ast_context::includes, ast_include::name, ast_include::next, ast_include::registrar, ast_include::rname, ast_include::stuff, and ast_include::timing.

Referenced by ast_context_add_include(), context_merge_incls_swits_igps_other_registrars(), and pbx_load_config().

06421 {
06422    struct ast_include *new_include;
06423    char *c;
06424    struct ast_include *i, *il = NULL; /* include, include_last */
06425    int length;
06426    char *p;
06427 
06428    length = sizeof(struct ast_include);
06429    length += 2 * (strlen(value) + 1);
06430 
06431    /* allocate new include structure ... */
06432    if (!(new_include = ast_calloc(1, length)))
06433       return -1;
06434    /* Fill in this structure. Use 'p' for assignments, as the fields
06435     * in the structure are 'const char *'
06436     */
06437    p = new_include->stuff;
06438    new_include->name = p;
06439    strcpy(p, value);
06440    p += strlen(value) + 1;
06441    new_include->rname = p;
06442    strcpy(p, value);
06443    /* Strip off timing info, and process if it is there */
06444    if ( (c = strchr(p, ',')) ) {
06445       *c++ = '\0';
06446            new_include->hastime = ast_build_timing(&(new_include->timing), c);
06447    }
06448    new_include->next      = NULL;
06449    new_include->registrar = registrar;
06450 
06451    ast_wrlock_context(con);
06452 
06453    /* ... go to last include and check if context is already included too... */
06454    for (i = con->includes; i; i = i->next) {
06455       if (!strcasecmp(i->name, new_include->name)) {
06456          ast_free(new_include);
06457          ast_unlock_context(con);
06458          errno = EEXIST;
06459          return -1;
06460       }
06461       il = i;
06462    }
06463 
06464    /* ... include new context into context list, unlock, return */
06465    if (il)
06466       il->next = new_include;
06467    else
06468       con->includes = new_include;
06469    ast_verb(3, "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
06470 
06471    ast_unlock_context(con);
06472 
06473    return 0;
06474 }

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

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

06482 {
06483    int ret = -1;
06484    struct ast_context *c = find_context_locked(context);
06485 
06486    if (c) { /* found, add switch to this context */
06487       ret = ast_context_add_switch2(c, sw, data, eval, registrar);
06488       ast_unlock_contexts();
06489    }
06490    return ret;
06491 }

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

References ast_context::alts, ast_calloc, ast_free, ast_get_context_name(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_sw::data, errno, ast_sw::eval, store_hint::list, ast_sw::name, ast_sw::registrar, and ast_sw::stuff.

Referenced by ast_context_add_switch(), context_merge_incls_swits_igps_other_registrars(), lua_register_switches(), and pbx_load_config().

06502 {
06503    struct ast_sw *new_sw;
06504    struct ast_sw *i;
06505    int length;
06506    char *p;
06507 
06508    length = sizeof(struct ast_sw);
06509    length += strlen(value) + 1;
06510    if (data)
06511       length += strlen(data);
06512    length++;
06513 
06514    /* allocate new sw structure ... */
06515    if (!(new_sw = ast_calloc(1, length)))
06516       return -1;
06517    /* ... fill in this structure ... */
06518    p = new_sw->stuff;
06519    new_sw->name = p;
06520    strcpy(new_sw->name, value);
06521    p += strlen(value) + 1;
06522    new_sw->data = p;
06523    if (data) {
06524       strcpy(new_sw->data, data);
06525       p += strlen(data) + 1;
06526    } else {
06527       strcpy(new_sw->data, "");
06528       p++;
06529    }
06530    new_sw->eval     = eval;
06531    new_sw->registrar = registrar;
06532 
06533    /* ... try to lock this context ... */
06534    ast_wrlock_context(con);
06535 
06536    /* ... go to last sw and check if context is already swd too... */
06537    AST_LIST_TRAVERSE(&con->alts, i, list) {
06538       if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
06539          ast_free(new_sw);
06540          ast_unlock_context(con);
06541          errno = EEXIST;
06542          return -1;
06543       }
06544    }
06545 
06546    /* ... sw new context into context list, unlock, return */
06547    AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
06548 
06549    ast_verb(3, "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
06550 
06551    ast_unlock_context(con);
06552 
06553    return 0;
06554 }

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

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

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

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

References ast_copy_string(), ast_hashtab_lookup(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), contexts_table, ast_context::name, and fake_context::name.

Referenced by __unload_module(), _macro_exec(), ast_context_verify_includes(), ast_ignore_pattern(), cleanup_stale_contexts(), isexten_function_read(), manage_parkinglot(), park_exec_full(), parkinglot_destroy(), register_exten(), register_peer_exten(), unload_module(), and unregister_exten().

02013 {
02014    struct ast_context *tmp = NULL;
02015    struct fake_context item;
02016 
02017    ast_copy_string(item.name, name, sizeof(item.name));
02018 
02019    ast_rdlock_contexts();
02020    if( contexts_table ) {
02021       tmp = ast_hashtab_lookup(contexts_table,&item);
02022    } else {
02023       while ( (tmp = ast_walk_contexts(tmp)) ) {
02024          if (!name || !strcasecmp(name, tmp->name))
02025             break;
02026       }
02027    }
02028    ast_unlock_contexts();
02029    return tmp;
02030 }

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

Register a new context or find an existing one.

Parameters:
extcontexts pointer to the ast_context structure pointer
exttable pointer to the hashtable that contains all the elements in extcontexts
name name of the new context
registrar registrar of the context
This function allows you to play in two environments: the global contexts (active dialplan) or an external context set of your choosing. To act on the external set, make sure extcontexts and exttable are set; for the globals, make sure both extcontexts and exttable are NULL.

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

References ast_calloc, ast_copy_string(), ast_debug, ast_hashtab_compare_contexts(), ast_hashtab_create(), ast_hashtab_hash_contexts(), ast_hashtab_insert_immediate(), ast_hashtab_insert_safe(), ast_hashtab_lookup(), ast_hashtab_newsize_java(), ast_hashtab_resize_java(), ast_log(), ast_mutex_init(), ast_rdlock_contexts(), ast_rwlock_init(), ast_strdup, ast_unlock_contexts(), ast_verb, ast_wrlock_contexts(), contexts, contexts_table, ast_context::ignorepats, ast_context::includes, local_contexts, ast_context::lock, LOG_ERROR, ast_context::macrolock, ast_context::name, fake_context::name, name, ast_context::next, ast_context::refcount, ast_context::registrar, ast_context::root, and ast_context::root_table.

Referenced by ast_park_call_full(), build_parkinglot(), context_merge(), load_module(), lua_register_switches(), manage_parkinglot(), pbx_load_config(), pbx_load_users(), reload_config(), and set_config().

05815 {
05816    struct ast_context *tmp, **local_contexts;
05817    struct fake_context search;
05818    int length = sizeof(struct ast_context) + strlen(name) + 1;
05819 
05820    if (!contexts_table) {
05821       contexts_table = ast_hashtab_create(17,
05822                                  ast_hashtab_compare_contexts, 
05823                                  ast_hashtab_resize_java,
05824                                  ast_hashtab_newsize_java,
05825                                  ast_hashtab_hash_contexts,
05826                                  0);
05827    }
05828    
05829    ast_copy_string(search.name, name, sizeof(search.name));
05830    if (!extcontexts) {
05831       ast_rdlock_contexts();
05832       local_contexts = &contexts;
05833       tmp = ast_hashtab_lookup(contexts_table, &search);
05834       ast_unlock_contexts();
05835       if (tmp) {
05836          tmp->refcount++;
05837          return tmp;
05838       }
05839    } else { /* local contexts just in a linked list; search there for the new context; slow, linear search, but not frequent */
05840       local_contexts = extcontexts;
05841       tmp = ast_hashtab_lookup(exttable, &search);
05842       if (tmp) {
05843          tmp->refcount++;
05844          return tmp;
05845       }
05846    }
05847    
05848    if ((tmp = ast_calloc(1, length))) {
05849       ast_rwlock_init(&tmp->lock);
05850       ast_mutex_init(&tmp->macrolock);
05851       strcpy(tmp->name, name);
05852       tmp->root = NULL;
05853       tmp->root_table = NULL;
05854       tmp->registrar = ast_strdup(registrar);
05855       tmp->includes = NULL;
05856       tmp->ignorepats = NULL;
05857       tmp->refcount = 1;
05858    } else {
05859       ast_log(LOG_ERROR, "Danger! We failed to allocate a context for %s!\n", name);
05860       return NULL;
05861    }
05862    
05863    if (!extcontexts) {
05864       ast_wrlock_contexts();
05865       tmp->next = *local_contexts;
05866       *local_contexts = tmp;
05867       ast_hashtab_insert_safe(contexts_table, tmp); /*put this context into the tree */
05868       ast_unlock_contexts();
05869       ast_debug(1, "Registered context '%s'(%p) in table %p registrar: %s\n", tmp->name, tmp, contexts_table, registrar);
05870       ast_verb(3, "Registered extension context '%s' (%p) in table %p; registrar: %s\n", tmp->name, tmp, contexts_table, registrar);
05871    } else {
05872       tmp->next = *local_contexts;
05873       if (exttable)
05874          ast_hashtab_insert_immediate(exttable, tmp); /*put this context into the tree */
05875       
05876       *local_contexts = tmp;
05877       ast_debug(1, "Registered context '%s'(%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar);
05878       ast_verb(3, "Registered extension context '%s' (%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar);
05879    }
05880    return tmp;
05881 }

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

References ast_copy_string(), ast_get_context_name(), ast_hashtab_lookup(), ast_mutex_lock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), contexts_table, ast_context::macrolock, and fake_context::name.

Referenced by _macro_exec().

04462 {
04463    struct ast_context *c = NULL;
04464    int ret = -1;
04465    struct fake_context item;
04466 
04467    ast_rdlock_contexts();
04468 
04469    ast_copy_string(item.name, context, sizeof(item.name));
04470 
04471    c = ast_hashtab_lookup(contexts_table,&item);
04472    if (c)
04473       ret = 0;
04474 
04475 
04476 #ifdef NOTNOW
04477 
04478    while ((c = ast_walk_contexts(c))) {
04479       if (!strcmp(ast_get_context_name(c), context)) {
04480          ret = 0;
04481          break;
04482       }
04483    }
04484 
04485 #endif
04486    ast_unlock_contexts();
04487 
04488    /* if we found context, lock macrolock */
04489    if (ret == 0) 
04490       ret = ast_mutex_lock(&c->macrolock);
04491 
04492    return ret;
04493 }

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 (0 to remove all)
callerid NULL to remove all; non-NULL to match a single record per priority
matchcid non-zero to match callerid element (if non-NULL); 0 to match default case
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 4268 of file pbx.c.

References ast_context_remove_extension_callerid().

Referenced by destroy_station(), destroy_trunk(), register_peer_exten(), unregister_exten(), and UnregisterExtension().

04269 {
04270    return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar);
04271 }

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

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

References ast_context_remove_extension_callerid2().

Referenced by manage_parkinglot(), park_exec_full(), and unload_module().

04296 {
04297    return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar, already_locked);
04298 }

int ast_context_remove_extension_callerid ( const char *  context,
const char *  extension,
int  priority,
const char *  callerid,
int  matchcid,
const char *  registrar 
)

Definition at line 4273 of file pbx.c.

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

Referenced by ast_context_remove_extension(), and handle_cli_dialplan_remove_extension().

04274 {
04275    int ret = -1; /* default error return */
04276    struct ast_context *c = find_context_locked(context);
04277 
04278    if (c) { /* ... remove extension ... */
04279       ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcallerid, registrar, 1);
04280       ast_unlock_contexts();
04281    }
04282    return ret;
04283 }

int ast_context_remove_extension_callerid2 ( struct ast_context con,
const char *  extension,
int  priority,
const char *  callerid,
int  matchcid,
const char *  registrar,
int  already_locked 
)

Definition at line 4300 of file pbx.c.

References add_exten_to_pattern_tree(), ast_copy_string(), ast_hashtab_insert_immediate(), ast_hashtab_lookup(), ast_hashtab_remove_this_object(), ast_hashtab_size(), ast_log(), ast_strlen_zero(), ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_exten::cidmatch, destroy_exten(), ast_exten::exten, exten, ast_exten::label, LOG_ERROR, log_match_char_tree(), LOG_NOTICE, LOG_WARNING, ast_exten::matchcid, ast_exten::next, ast_exten::peer, ast_exten::peer_label_table, ast_exten::peer_table, ast_exten::priority, ast_exten::registrar, and match_char::x.

Referenced by __ast_context_destroy(), ast_context_remove_extension2(), and ast_context_remove_extension_callerid().

04301 {
04302    struct ast_exten *exten, *prev_exten = NULL;
04303    struct ast_exten *peer;
04304    struct ast_exten ex, *exten2, *exten3;
04305    char dummy_name[1024];
04306    struct ast_exten *previous_peer = NULL;
04307    struct ast_exten *next_peer = NULL;
04308    int found = 0;
04309 
04310    if (!already_locked)
04311       ast_wrlock_context(con);
04312 
04313    /* Handle this is in the new world */
04314 
04315    /* FIXME For backwards compatibility, if callerid==NULL, then remove ALL
04316     * peers, not just those matching the callerid. */
04317 #ifdef NEED_DEBUG
04318    ast_verb(3,"Removing %s/%s/%d%s%s from trees, registrar=%s\n", con->name, extension, priority, matchcallerid ? "/" : "", matchcallerid ? callerid : "", registrar);
04319 #endif
04320 #ifdef CONTEXT_DEBUG
04321    check_contexts(__FILE__, __LINE__);
04322 #endif
04323    /* find this particular extension */
04324    ex.exten = dummy_name;
04325    ex.matchcid = matchcallerid && !ast_strlen_zero(callerid); /* don't say match if there's no callerid */
04326    ex.cidmatch = callerid;
04327    ast_copy_string(dummy_name, extension, sizeof(dummy_name));
04328    exten = ast_hashtab_lookup(con->root_table, &ex);
04329    if (exten) {
04330       if (priority == 0) {
04331          exten2 = ast_hashtab_remove_this_object(con->root_table, exten);
04332          if (!exten2)
04333             ast_log(LOG_ERROR,"Trying to delete the exten %s from context %s, but could not remove from the root_table\n", extension, con->name);
04334          if (con->pattern_tree) {
04335             
04336             struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
04337             
04338             if (x->exten) { /* this test for safety purposes */
04339                x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
04340                x->exten = 0; /* get rid of what will become a bad pointer */
04341             } else {
04342                ast_log(LOG_WARNING,"Trying to delete an exten from a context, but the pattern tree node returned isn't a full extension\n");
04343             }
04344          }
04345       } else {
04346          ex.priority = priority;
04347          exten2 = ast_hashtab_lookup(exten->peer_table, &ex);
04348          if (exten2) {
04349             
04350             if (exten2->label) { /* if this exten has a label, remove that, too */
04351                exten3 = ast_hashtab_remove_this_object(exten->peer_label_table,exten2);
04352                if (!exten3)
04353                   ast_log(LOG_ERROR,"Did not remove this priority label (%d/%s) from the peer_label_table of context %s, extension %s!\n", priority, exten2->label, con->name, exten2->exten);
04354             }
04355          
04356             exten3 = ast_hashtab_remove_this_object(exten->peer_table, exten2);
04357             if (!exten3)
04358                ast_log(LOG_ERROR,"Did not remove this priority (%d) from the peer_table of context %s, extension %s!\n", priority, con->name, exten2->exten);
04359             if (exten2 == exten && exten2->peer) {
04360                exten2 = ast_hashtab_remove_this_object(con->root_table, exten);
04361                ast_hashtab_insert_immediate(con->root_table, exten2->peer);
04362             }
04363             if (ast_hashtab_size(exten->peer_table) == 0) {
04364                /* well, if the last priority of an exten is to be removed,
04365                   then, the extension is removed, too! */
04366                exten3 = ast_hashtab_remove_this_object(con->root_table, exten);
04367                if (!exten3)
04368                   ast_log(LOG_ERROR,"Did not remove this exten (%s) from the context root_table (%s) (priority %d)\n", exten->exten, con->name, priority);
04369                if (con->pattern_tree) {
04370                   struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
04371                   if (x->exten) { /* this test for safety purposes */
04372                      x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
04373                      x->exten = 0; /* get rid of what will become a bad pointer */
04374                   }
04375                }
04376             }
04377          } else {
04378             ast_log(LOG_ERROR,"Could not find priority %d of exten %s in context %s!\n",
04379                   priority, exten->exten, con->name);
04380          }
04381       }
04382    } else {
04383       /* hmmm? this exten is not in this pattern tree? */
04384       ast_log(LOG_WARNING,"Cannot find extension %s in root_table in context %s\n",
04385             extension, con->name);
04386    }
04387 #ifdef NEED_DEBUG
04388    if (con->pattern_tree) {
04389       ast_log(LOG_NOTICE,"match char tree after exten removal:\n");
04390       log_match_char_tree(con->pattern_tree, " ");
04391    }
04392 #endif
04393 
04394    /* scan the extension list to find first matching extension-registrar */
04395    for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
04396       if (!strcmp(exten->exten, extension) &&
04397          (!registrar || !strcmp(exten->registrar, registrar)) &&
04398          (!matchcallerid || (!ast_strlen_zero(callerid) && !ast_strlen_zero(exten->cidmatch) && !strcmp(exten->cidmatch, callerid)) || (ast_strlen_zero(callerid) && ast_strlen_zero(exten->cidmatch))))
04399          break;
04400    }
04401    if (!exten) {
04402       /* we can't find right extension */
04403       if (!already_locked)
04404          ast_unlock_context(con);
04405       return -1;
04406    }
04407 
04408    /* scan the priority list to remove extension with exten->priority == priority */
04409    for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next;
04410        peer && !strcmp(peer->exten, extension) && (!matchcallerid || (!ast_strlen_zero(callerid) && !ast_strlen_zero(peer->cidmatch) && !strcmp(peer->cidmatch,callerid)) || (ast_strlen_zero(callerid) && ast_strlen_zero(peer->cidmatch)));
04411          peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) {
04412       if ((priority == 0 || peer->priority == priority) &&
04413             (!callerid || !matchcallerid || (matchcallerid && !strcmp(peer->cidmatch, callerid))) &&
04414             (!registrar || !strcmp(peer->registrar, registrar) )) {
04415          found = 1;
04416 
04417          /* we are first priority extension? */
04418          if (!previous_peer) {
04419             /*
04420              * We are first in the priority chain, so must update the extension chain.
04421              * The next node is either the next priority or the next extension
04422              */
04423             struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
04424             if (peer->peer) {
04425                /* move the peer_table and peer_label_table down to the next peer, if
04426                   it is there */
04427                peer->peer->peer_table = peer->peer_table;
04428                peer->peer->peer_label_table = peer->peer_label_table;
04429                peer->peer_table = NULL;
04430                peer->peer_label_table = NULL;
04431             }
04432             if (!prev_exten) {   /* change the root... */
04433                con->root = next_node;
04434             } else {
04435                prev_exten->next = next_node; /* unlink */
04436             }
04437             if (peer->peer)   { /* update the new head of the pri list */
04438                peer->peer->next = peer->next;
04439             }
04440          } else { /* easy, we are not first priority in extension */
04441             previous_peer->peer = peer->peer;
04442          }
04443 
04444          /* now, free whole priority extension */
04445          destroy_exten(peer);
04446       } else {
04447          previous_peer = peer;
04448       }
04449    }
04450    if (!already_locked)
04451       ast_unlock_context(con);
04452    return found ? 0 : -1;
04453 }

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

Definition at line 6560 of file pbx.c.

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

Referenced by handle_cli_dialplan_remove_ignorepat().

06561 {
06562    int ret = -1;
06563    struct ast_context *c = find_context_locked(context);
06564 
06565    if (c) {
06566       ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
06567       ast_unlock_contexts();
06568    }
06569    return ret;
06570 }

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

Definition at line 6572 of file pbx.c.

References ast_free, ast_unlock_context(), ast_wrlock_context(), errno, ast_context::ignorepats, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.

Referenced by ast_context_remove_ignorepat().

06573 {
06574    struct ast_ignorepat *ip, *ipl = NULL;
06575 
06576    ast_wrlock_context(con);
06577 
06578    for (ip = con->ignorepats; ip; ip = ip->next) {
06579       if (!strcmp(ip->pattern, ignorepat) &&
06580          (!registrar || (registrar == ip->registrar))) {
06581          if (ipl) {
06582             ipl->next = ip->next;
06583             ast_free(ip);
06584          } else {
06585             con->ignorepats = ip->next;
06586             ast_free(ip);
06587          }
06588          ast_unlock_context(con);
06589          return 0;
06590       }
06591       ipl = ip;
06592    }
06593 
06594    ast_unlock_context(con);
06595    errno = EINVAL;
06596    return -1;
06597 }

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

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

Referenced by handle_cli_dialplan_remove_include().

04161 {
04162    int ret = -1;
04163    struct ast_context *c = find_context_locked(context);
04164 
04165    if (c) {
04166       /* found, remove include from this context ... */
04167       ret = ast_context_remove_include2(c, include, registrar);
04168       ast_unlock_contexts();
04169    }
04170    return ret;
04171 }

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

Removes an include by an ast_context structure.

Return values:
0 on success.
-1 on failure.

Definition at line 4182 of file pbx.c.

References ast_free, ast_get_context_name(), ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_context::includes, ast_include::name, ast_include::next, and ast_include::registrar.

Referenced by ast_context_remove_include().

04183 {
04184    struct ast_include *i, *pi = NULL;
04185    int ret = -1;
04186 
04187    ast_wrlock_context(con);
04188 
04189    /* find our include */
04190    for (i = con->includes; i; pi = i, i = i->next) {
04191       if (!strcmp(i->name, include) &&
04192             (!registrar || !strcmp(i->registrar, registrar))) {
04193          /* remove from list */
04194          ast_verb(3, "Removing inclusion of context '%s' in context '%s; registrar=%s'\n", include, ast_get_context_name(con), registrar);
04195          if (pi)
04196             pi->next = i->next;
04197          else
04198             con->includes = i->next;
04199          /* free include and return */
04200          ast_free(i);
04201          ret = 0;
04202          break;
04203       }
04204    }
04205 
04206    ast_unlock_context(con);
04207 
04208    return ret;
04209 }

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

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

04217 {
04218    int ret = -1; /* default error return */
04219    struct ast_context *c = find_context_locked(context);
04220 
04221    if (c) {
04222       /* remove switch from this context ... */
04223       ret = ast_context_remove_switch2(c, sw, data, registrar);
04224       ast_unlock_contexts();
04225    }
04226    return ret;
04227 }

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

References ast_context::alts, ast_free, ast_get_context_name(), AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_sw::data, ast_sw::list, ast_sw::name, and ast_sw::registrar.

Referenced by ast_context_remove_switch().

04238 {
04239    struct ast_sw *i;
04240    int ret = -1;
04241 
04242    ast_wrlock_context(con);
04243 
04244    /* walk switches */
04245    AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
04246       if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
04247          (!registrar || !strcmp(i->registrar, registrar))) {
04248          /* found, remove from list */
04249          ast_verb(3, "Removing switch '%s' from context '%s; registrar=%s'\n", sw, ast_get_context_name(con), registrar);
04250          AST_LIST_REMOVE_CURRENT(list);
04251          ast_free(i); /* free switch and return */
04252          ret = 0;
04253          break;
04254       }
04255    }
04256    AST_LIST_TRAVERSE_SAFE_END;
04257 
04258    ast_unlock_context(con);
04259 
04260    return ret;
04261 }

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

References ast_copy_string(), ast_get_context_name(), ast_hashtab_lookup(), ast_mutex_unlock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), contexts_table, ast_context::macrolock, and fake_context::name.

Referenced by _macro_exec().

04501 {
04502    struct ast_context *c = NULL;
04503    int ret = -1;
04504    struct fake_context item;
04505 
04506    ast_rdlock_contexts();
04507 
04508    ast_copy_string(item.name, context, sizeof(item.name));
04509 
04510    c = ast_hashtab_lookup(contexts_table,&item);
04511    if (c)
04512       ret = 0;
04513 #ifdef NOTNOW
04514 
04515    while ((c = ast_walk_contexts(c))) {
04516       if (!strcmp(ast_get_context_name(c), context)) {
04517          ret = 0;
04518          break;
04519       }
04520    }
04521 
04522 #endif
04523    ast_unlock_contexts();
04524 
04525    /* if we found context, unlock macrolock */
04526    if (ret == 0) 
04527       ret = ast_mutex_unlock(&c->macrolock);
04528 
04529    return ret;
04530 }

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

08861 {
08862    struct ast_include *inc = NULL;
08863    int res = 0;
08864 
08865    while ( (inc = ast_walk_context_includes(con, inc)) ) {
08866       if (ast_context_find(inc->rname))
08867          continue;
08868 
08869       res = -1;
08870       ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n",
08871          ast_get_context_name(con), inc->rname);
08872       break;
08873    }
08874 
08875    return res;
08876 }

struct ast_custom_function* ast_custom_function_find ( const char *  name  ) 

Definition at line 2763 of file pbx.c.

References ast_custom_function::acflist, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, and ast_custom_function::name.

Referenced by ast_func_read(), ast_func_write(), config_curl(), destroy_curl(), handle_show_function(), op_func(), realtime_curl(), realtime_multi_curl(), require_curl(), store_curl(), and update_curl().

02764 {
02765    struct ast_custom_function *acf = NULL;
02766 
02767    AST_RWLIST_RDLOCK(&acf_root);
02768    AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) {
02769       if (!strcmp(name, acf->name))
02770          break;
02771    }
02772    AST_RWLIST_UNLOCK(&acf_root);
02773 
02774    return acf;
02775 }

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

Definition at line 2777 of file pbx.c.

References ast_custom_function::acflist, AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, and ast_custom_function::name.

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

02778 {
02779    struct ast_custom_function *cur;
02780 
02781    if (!acf)
02782       return -1;
02783 
02784    AST_RWLIST_WRLOCK(&acf_root);
02785    if ((cur = AST_RWLIST_REMOVE(&acf_root, acf, acflist)))
02786       ast_verb(2, "Unregistered custom function %s\n", cur->name);
02787    AST_RWLIST_UNLOCK(&acf_root);
02788 
02789    return cur ? 0 : -1;
02790 }

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
Note:
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
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 3621 of file pbx.c.

References E_MATCH, and pbx_extension_helper().

Referenced by __ast_goto_if_exists(), __ast_pbx_run(), _macro_exec(), acf_isexten_exec(), answer_call(), ast_app_dtget(), ast_bridge_call(), ast_pbx_outgoing_exten(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), cli_console_dial(), conf_run(), console_dial(), console_transfer(), dahdi_handle_dtmfup(), dial_exec_full(), disa_exec(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), gosub_exec(), handle_gosub(), handle_link_data(), handle_link_phone_dtmf(), handle_stimulus_message(), isexten_function_read(), leave_voicemail(), local_alloc(), local_call(), local_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), minivm_greet_exec(), misdn_overlap_dial_task(), park_space_reserve(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), pri_dchannel(), privacy_exec(), process_ast_dsp(), readexten_exec(), register_peer_exten(), rpt_exec(), show_debug_helper(), skinny_ss(), socket_process(), ss_thread(), and waitstream_core().

03622 {
03623    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0, 0);
03624 }

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

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

Referenced by __ast_goto_if_exists(), ast_async_goto(), builtin_atxfer(), do_bridge_masquerade(), handle_setpriority(), pbx_parseable_goto(), and return_exec().

06708 {
06709    if (!chan)
06710       return -1;
06711 
06712    ast_channel_lock(chan);
06713 
06714    if (!ast_strlen_zero(context))
06715       ast_copy_string(chan->context, context, sizeof(chan->context));
06716    if (!ast_strlen_zero(exten))
06717       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
06718    if (priority > -1) {
06719       chan->priority = priority;
06720       /* see flag description in channel.h for explanation */
06721       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
06722          chan->priority--;
06723    }
06724 
06725    ast_channel_unlock(chan);
06726 
06727    return 0;
06728 }

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

Definition at line 1989 of file pbx.c.

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

Referenced by lua_find_extension(), and realtime_switch_common().

01990 {
01991    if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
01992       ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
01993    return extension_match_core(pattern, data, needmore);
01994 }

int ast_extension_cmp ( const char *  a,
const char *  b 
)

Determine if one extension should match before another.

Parameters:
a extension to compare with b
b extension to compare with a
Checks whether or extension a should match before extension b

Return values:
0 if the two extensions have equal matching priority
1 on a > b
-1 on a < b

Definition at line 1791 of file pbx.c.

References ext_cmp().

Referenced by lua_extension_cmp().

01792 {
01793    return ext_cmp(a, b);
01794 }

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

References E_MATCH, and extension_match_core().

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

01985 {
01986    return extension_match_core(pattern, data, E_MATCH);
01987 }

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

References ast_extension_state2(), and ast_hint_extension().

Referenced by action_extensionstate(), extstate_read(), and handle_request_subscribe().

03314 {
03315    struct ast_exten *e;
03316 
03317    e = ast_hint_extension(c, context, exten);   /* Do we have a hint for this extension ? */
03318    if (!e)
03319       return -1;           /* No hint, return -1 */
03320 
03321    return ast_extension_state2(e);        /* Check all devices in the hint */
03322 }

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

References ARRAY_LEN, extension_states, and cfextension_states::text.

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

03302 {
03303    int i;
03304 
03305    for (i = 0; (i < ARRAY_LEN(extension_states)); i++) {
03306       if (extension_states[i].extension_state == extension_state)
03307          return extension_states[i].text;
03308    }
03309    return "Unknown";
03310 }

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

References ast_exten::app, ast_add_extension(), ast_calloc, ast_free_ptr, ast_hint_extension(), AST_LIST_INSERT_HEAD, AST_LIST_TRAVERSE, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_state_cb::callback, ast_hint::callbacks, ast_exten::cidmatch, ast_exten::data, ast_state_cb::data, ast_hint::exten, ast_exten::exten, ast_exten::label, ast_context::name, ast_exten::parent, ast_exten::priority, ast_exten::registrar, and stateid.

Referenced by __init_manager(), handle_request_subscribe(), and skinny_register().

03376 {
03377    struct ast_hint *hint;
03378    struct ast_state_cb *cblist;
03379    struct ast_exten *e;
03380 
03381    /* If there's no context and extension:  add callback to statecbs list */
03382    if (!context && !exten) {
03383       AST_RWLIST_WRLOCK(&hints);
03384 
03385       AST_LIST_TRAVERSE(&statecbs, cblist, entry) {
03386          if (cblist->callback == callback) {
03387             cblist->data = data;
03388             AST_RWLIST_UNLOCK(&hints);
03389             return 0;
03390          }
03391       }
03392 
03393       /* Now insert the callback */
03394       if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
03395          AST_RWLIST_UNLOCK(&hints);
03396          return -1;
03397       }
03398       cblist->id = 0;
03399       cblist->callback = callback;
03400       cblist->data = data;
03401 
03402       AST_LIST_INSERT_HEAD(&statecbs, cblist, entry);
03403 
03404       AST_RWLIST_UNLOCK(&hints);
03405 
03406       return 0;
03407    }
03408 
03409    if (!context || !exten)
03410       return -1;
03411 
03412    /* This callback type is for only one hint, so get the hint */
03413    e = ast_hint_extension(NULL, context, exten);
03414    if (!e) {
03415       return -1;
03416    }
03417 
03418    /* If this is a pattern, dynamically create a new extension for this
03419     * particular match.  Note that this will only happen once for each
03420     * individual extension, because the pattern will no longer match first.
03421     */
03422    if (e->exten[0] == '_') {
03423       ast_add_extension(e->parent->name, 0, exten, e->priority, e->label,
03424          e->cidmatch, e->app, ast_strdup(e->data), ast_free_ptr,
03425          e->registrar);
03426       e = ast_hint_extension(NULL, context, exten);
03427       if (!e || e->exten[0] == '_') {
03428          return -1;
03429       }
03430    }
03431 
03432    /* Find the hint in the list of hints */
03433    AST_RWLIST_WRLOCK(&hints);
03434 
03435    AST_RWLIST_TRAVERSE(&hints, hint, list) {
03436       if (hint->exten == e)
03437          break;
03438    }
03439 
03440    if (!hint) {
03441       /* We have no hint, sorry */
03442       AST_RWLIST_UNLOCK(&hints);
03443       return -1;
03444    }
03445 
03446    /* Now insert the callback in the callback list  */
03447    if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
03448       AST_RWLIST_UNLOCK(&hints);
03449       return -1;
03450    }
03451 
03452    cblist->id = stateid++;    /* Unique ID for this callback */
03453    cblist->callback = callback;  /* Pointer to callback routine */
03454    cblist->data = data;    /* Data for the callback */
03455 
03456    AST_LIST_INSERT_HEAD(&hint->callbacks, cblist, entry);
03457 
03458    AST_RWLIST_UNLOCK(&hints);
03459 
03460    return cblist->id;
03461 }

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

References ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::entry, ast_state_cb::id, and ast_hint::list.

Referenced by dialog_unlink_all(), handle_request_subscribe(), and skinny_unregister().

03465 {
03466    struct ast_state_cb *p_cur = NULL;
03467    int ret = -1;
03468 
03469    if (!id && !callback)
03470       return -1;
03471 
03472    AST_RWLIST_WRLOCK(&hints);
03473 
03474    if (!id) {  /* id == 0 is a callback without extension */
03475       AST_LIST_TRAVERSE_SAFE_BEGIN(&statecbs, p_cur, entry) {
03476          if (p_cur->callback == callback) {
03477             AST_LIST_REMOVE_CURRENT(entry);
03478             break;
03479          }
03480       }
03481       AST_LIST_TRAVERSE_SAFE_END;
03482    } else { /* callback with extension, find the callback based on ID */
03483       struct ast_hint *hint;
03484       AST_RWLIST_TRAVERSE(&hints, hint, list) {
03485          AST_LIST_TRAVERSE_SAFE_BEGIN(&hint->callbacks, p_cur, entry) {
03486             if (p_cur->id == id) {
03487                AST_LIST_REMOVE_CURRENT(entry);
03488                break;
03489             }
03490          }
03491          AST_LIST_TRAVERSE_SAFE_END;
03492 
03493          if (p_cur)
03494             break;
03495       }
03496    }
03497 
03498    if (p_cur) {
03499       ast_free(p_cur);
03500    }
03501 
03502    AST_RWLIST_UNLOCK(&hints);
03503 
03504    return ret;
03505 }

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
Note:
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
Return values:
the priority which matches the given label in the extension
-1 if not found.

Definition at line 3626 of file pbx.c.

References E_FINDLABEL, and pbx_extension_helper().

Referenced by action_originate(), action_redirect(), handle_gosub(), handle_setpriority(), isexten_function_read(), and pbx_parseable_goto().

03627 {
03628    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
03629 }

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:
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur

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

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

03632 {
03633    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
03634 }

int ast_func_read ( struct ast_channel chan,
const 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 2850 of file pbx.c.

References __ast_module_user_add(), __ast_module_user_remove(), ast_custom_function_find(), ast_log(), ast_strdupa, chan, copy(), func_args(), LOG_ERROR, ast_custom_function::mod, and ast_custom_function::read.

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

02851 {
02852    char *copy = ast_strdupa(function);
02853    char *args = func_args(copy);
02854    struct ast_custom_function *acfptr = ast_custom_function_find(copy);
02855 
02856    if (acfptr == NULL)
02857       ast_log(LOG_ERROR, "Function %s not registered\n", copy);
02858    else if (!acfptr->read)
02859       ast_log(LOG_ERROR, "Function %s cannot be read\n", copy);
02860    else {
02861       int res;
02862       struct ast_module_user *u = NULL;
02863       if (acfptr->mod)
02864          u = __ast_module_user_add(acfptr->mod, chan);
02865       res = acfptr->read(chan, copy, args, workspace, len);
02866       if (acfptr->mod && u)
02867          __ast_module_user_remove(acfptr->mod, u);
02868       return res;
02869    }
02870    return -1;
02871 }

int ast_func_write ( struct ast_channel chan,
const 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 2873 of file pbx.c.

References __ast_module_user_add(), __ast_module_user_remove(), ast_custom_function_find(), ast_log(), ast_strdupa, chan, copy(), func_args(), LOG_ERROR, ast_custom_function::mod, and ast_custom_function::write.

Referenced by pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().

02874 {
02875    char *copy = ast_strdupa(function);
02876    char *args = func_args(copy);
02877    struct ast_custom_function *acfptr = ast_custom_function_find(copy);
02878 
02879    if (acfptr == NULL)
02880       ast_log(LOG_ERROR, "Function %s not registered\n", copy);
02881    else if (!acfptr->write)
02882       ast_log(LOG_ERROR, "Function %s cannot be written to\n", copy);
02883    else {
02884       int res;
02885       struct ast_module_user *u = NULL;
02886       if (acfptr->mod)
02887          u = __ast_module_user_add(acfptr->mod, chan);
02888       res = acfptr->write(chan, copy, args, value);
02889       if (acfptr->mod && u)
02890          __ast_module_user_remove(acfptr->mod, u);
02891       return res;
02892    }
02893 
02894    return -1;
02895 }

const char* ast_get_context_name ( struct ast_context con  ) 

Definition at line 8712 of file pbx.c.

References ast_context::name.

Referenced by _macro_exec(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_lockmacro(), ast_context_remove_include2(), ast_context_remove_switch2(), ast_context_unlockmacro(), ast_context_verify_includes(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), context_merge_incls_swits_igps_other_registrars(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_cli_dialplan_save(), handle_show_hint(), handle_show_hints(), manager_show_dialplan_helper(), show_debug_helper(), and show_dialplan_helper().

08713 {
08714    return con ? con->name : NULL;
08715 }

const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 8750 of file pbx.c.

References ast_context::registrar.

Referenced by handle_cli_dialplan_save(), show_debug_helper(), and show_dialplan_helper().

08751 {
08752    return c ? c->registrar : NULL;
08753 }

const char* ast_get_extension_app ( struct ast_exten e  ) 

Definition at line 8780 of file pbx.c.

References ast_exten::app.

Referenced by _macro_exec(), ast_add_hint_nolock(), ast_extension_state2(), ast_get_hint(), find_matching_endwhile(), handle_cli_dialplan_save(), handle_show_hint(), handle_show_hints(), handle_statechange(), manager_show_dialplan_helper(), and print_ext().

08781 {
08782    return e ? e->app : NULL;
08783 }

void* ast_get_extension_app_data ( struct ast_exten e  ) 

Definition at line 8785 of file pbx.c.

References ast_exten::data.

Referenced by _macro_exec(), ast_get_hint(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and print_ext().

08786 {
08787    return e ? e->data : NULL;
08788 }

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 8775 of file pbx.c.

References ast_exten::cidmatch.

Referenced by complete_dialplan_remove_extension(), find_matching_priority(), and handle_cli_dialplan_save().

08776 {
08777    return e ? e->cidmatch : NULL;
08778 }

struct ast_context* ast_get_extension_context ( struct ast_exten exten  ) 

Definition at line 8717 of file pbx.c.

References exten.

Referenced by handle_show_hint(), and handle_show_hints().

08718 {
08719    return exten ? exten->parent : NULL;
08720 }

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 8727 of file pbx.c.

References exten.

Referenced by handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().

08728 {
08729    return exten ? exten->label : NULL;
08730 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 8770 of file pbx.c.

References ast_exten::matchcid.

Referenced by complete_dialplan_remove_extension(), find_matching_priority(), and handle_cli_dialplan_save().

08771 {
08772    return e ? e->matchcid : 0;
08773 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 

Definition at line 8722 of file pbx.c.

References exten.

Referenced by ast_add_hint_nolock(), complete_core_show_hint(), complete_dialplan_remove_extension(), dundi_precache_full(), find_matching_priority(), handle_cli_dialplan_save(), handle_show_hint(), handle_show_hints(), manager_show_dialplan_helper(), and show_dialplan_helper().

08723 {
08724    return exten ? exten->exten : NULL;
08725 }

int ast_get_extension_priority ( struct ast_exten exten  ) 

Definition at line 8742 of file pbx.c.

References exten.

Referenced by complete_dialplan_remove_extension(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and print_ext().

08743 {
08744    return exten ? exten->priority : -1;
08745 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 8755 of file pbx.c.

References ast_exten::registrar.

Referenced by handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().

08756 {
08757    return e ? e->registrar : NULL;
08758 }

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

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

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

03605 {
03606    struct ast_exten *e = ast_hint_extension(c, context, exten);
03607 
03608    if (e) {
03609       if (hint)
03610          ast_copy_string(hint, ast_get_extension_app(e), hintsize);
03611       if (name) {
03612          const char *tmp = ast_get_extension_app_data(e);
03613          if (tmp)
03614             ast_copy_string(name, tmp, namesize);
03615       }
03616       return -1;
03617    }
03618    return 0;
03619 }

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 

Definition at line 8737 of file pbx.c.

References ast_ignorepat::pattern.

Referenced by complete_dialplan_remove_ignorepat(), context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), lookup_c_ip(), manager_show_dialplan_helper(), and show_dialplan_helper().

08738 {
08739    return ip ? ip->pattern : NULL;
08740 }

const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

Definition at line 8765 of file pbx.c.

References ast_ignorepat::registrar.

Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().

08766 {
08767    return ip ? ip->registrar : NULL;
08768 }

const char* ast_get_include_name ( struct ast_include include  ) 

Definition at line 8732 of file pbx.c.

References ast_include::name.

Referenced by complete_dialplan_remove_include(), context_merge_incls_swits_igps_other_registrars(), find_matching_priority(), handle_cli_dialplan_save(), lookup_ci(), manager_show_dialplan_helper(), and show_dialplan_helper().

08733 {
08734    return inc ? inc->name : NULL;
08735 }

const char* ast_get_include_registrar ( struct ast_include i  ) 

Definition at line 8760 of file pbx.c.

References ast_include::registrar.

Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().

08761 {
08762    return i ? i->registrar : NULL;
08763 }

const char* ast_get_switch_data ( struct ast_sw sw  ) 

Definition at line 8795 of file pbx.c.

References ast_sw::data.

Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().

08796 {
08797    return sw ? sw->data : NULL;
08798 }

int ast_get_switch_eval ( struct ast_sw sw  ) 

Definition at line 8800 of file pbx.c.

References ast_sw::eval.

Referenced by context_merge_incls_swits_igps_other_registrars().

08801 {
08802    return sw->eval;
08803 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

Definition at line 8790 of file pbx.c.

References ast_sw::name.

Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().

08791 {
08792    return sw ? sw->name : NULL;
08793 }

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

Definition at line 8805 of file pbx.c.

References ast_sw::registrar.

Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().

08806 {
08807    return sw ? sw->registrar : NULL;
08808 }

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

References __ast_goto_if_exists(), and chan.

Referenced by background_detect_exec(), channel_spy(), common_exec(), conf_run(), goto_exten(), onedigit_goto(), priority_jump(), select_entry(), and valid_exit().

08899 {
08900    return __ast_goto_if_exists(chan, context, exten, priority, 0);
08901 }

int ast_hashtab_compare_contexts ( const void *  ah_a,
const void *  ah_b 
)

unsigned int ast_hashtab_hash_contexts ( const void *  obj  ) 

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

06654 {
06655    struct ast_context *con = ast_context_find(context);
06656    if (con) {
06657       struct ast_ignorepat *pat;
06658       for (pat = con->ignorepats; pat; pat = pat->next) {
06659          if (ast_extension_match(pat->pattern, pattern))
06660             return 1;
06661       }
06662    }
06663 
06664    return 0;
06665 }

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
Note:
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
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 3641 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_link_data(), handle_link_phone_dtmf(), local_dtmf_helper(), loopback_matchmore(), mgcp_ss(), readexten_exec(), skinny_ss(), and ss_thread().

03642 {
03643    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0);
03644 }

void ast_merge_contexts_and_delete ( struct ast_context **  extcontexts,
struct ast_hashtab exttable,
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
exttable pointer to the ast_hashtab structure that contains all the elements in extcontexts
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 6013 of file pbx.c.

References __ast_internal_context_destroy(), ast_add_extension_nolock(), ast_calloc, AST_EXTENSION_REMOVED, ast_free, ast_free_ptr, ast_hashtab_destroy(), ast_hashtab_end_traversal(), ast_hashtab_next(), ast_hashtab_start_traversal(), ast_hint_extension_nolock(), AST_LIST_APPEND_LIST, AST_LIST_EMPTY, AST_LIST_HEAD_INIT_VALUE, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_rdlock_contexts(), AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_tvdiff_us(), ast_tvnow(), ast_unlock_contexts(), ast_verb, ast_wrlock_contexts(), ast_wrlock_contexts_version(), ast_state_cb::callback, ast_hint::callbacks, context_merge(), contexts, contexts_table, ast_state_cb::data, E_MATCH, ast_exten::exten, ast_hint::exten, store_hint::exten, ast_hint::laststate, store_hint::list, LOG_WARNING, ast_context::name, ast_context::next, store_hint::next, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_context::registrar, and pbx_find_info::stacklen.

Referenced by lua_reload_extensions(), and pbx_load_module().

06014 {
06015    double ft;
06016    struct ast_context *tmp, *oldcontextslist;
06017    struct ast_hashtab *oldtable;
06018    struct store_hints store = AST_LIST_HEAD_INIT_VALUE;
06019    struct store_hint *this;
06020    struct ast_hint *hint;
06021    struct ast_exten *exten;
06022    int length;
06023    struct ast_state_cb *thiscb;
06024    struct ast_hashtab_iter *iter;
06025    
06026    /* it is very important that this function hold the hint list lock _and_ the conlock
06027       during its operation; not only do we need to ensure that the list of contexts
06028       and extensions does not change, but also that no hint callbacks (watchers) are
06029       added or removed during the merge/delete process
06030 
06031       in addition, the locks _must_ be taken in this order, because there are already
06032       other code paths that use this order
06033    */
06034    
06035    struct timeval begintime, writelocktime, endlocktime, enddeltime;
06036    int wrlock_ver;
06037    
06038    begintime = ast_tvnow();
06039    ast_rdlock_contexts();
06040    iter = ast_hashtab_start_traversal(contexts_table);
06041    while ((tmp = ast_hashtab_next(iter))) {
06042       context_merge(extcontexts, exttable, tmp, registrar);
06043    }
06044    ast_hashtab_end_traversal(iter);
06045    wrlock_ver = ast_wrlock_contexts_version();
06046    
06047    ast_unlock_contexts(); /* this feels real retarded, but you must do
06048                        what you must do If this isn't done, the following 
06049                         wrlock is a guraranteed deadlock */
06050    ast_wrlock_contexts();
06051    if (ast_wrlock_contexts_version() > wrlock_ver+1) {
06052       ast_log(LOG_WARNING,"==================!!!!!!!!!!!!!!!Something changed the contexts in the middle of merging contexts!\n");
06053    }
06054    
06055    AST_RWLIST_WRLOCK(&hints);
06056    writelocktime = ast_tvnow();
06057 
06058    /* preserve all watchers for hints associated with this registrar */
06059    AST_RWLIST_TRAVERSE(&hints, hint, list) {
06060       if (!AST_LIST_EMPTY(&hint->callbacks) && !strcmp(registrar, hint->exten->parent->registrar)) {
06061          length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this);
06062          if (!(this = ast_calloc(1, length)))
06063             continue;
06064          AST_LIST_APPEND_LIST(&this->callbacks, &hint->callbacks, entry);
06065          this->laststate = hint->laststate;
06066          this->context = this->data;
06067          strcpy(this->data, hint->exten->parent->name);
06068          this->exten = this->data + strlen(this->context) + 1;
06069          strcpy(this->exten, hint->exten->exten);
06070          AST_LIST_INSERT_HEAD(&store, this, list);
06071       }
06072    }
06073 
06074    /* save the old table and list */
06075    oldtable = contexts_table;
06076    oldcontextslist = contexts;
06077 
06078    /* move in the new table and list */
06079    contexts_table = exttable;
06080    contexts = *extcontexts;
06081    
06082    /* restore the watchers for hints that can be found; notify those that
06083       cannot be restored
06084    */
06085    while ((this = AST_LIST_REMOVE_HEAD(&store, list))) {
06086       struct pbx_find_info q = { .stacklen = 0 };
06087       exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH);
06088       /* If this is a pattern, dynamically create a new extension for this
06089        * particular match.  Note that this will only happen once for each
06090        * individual extension, because the pattern will no longer match first.
06091        */
06092       if (exten && exten->exten[0] == '_') {
06093          ast_add_extension_nolock(exten->parent->name, 0, this->exten, PRIORITY_HINT, NULL,
06094             0, exten->app, ast_strdup(exten->data), ast_free_ptr, registrar);
06095          /* rwlocks are not recursive locks */
06096          exten = ast_hint_extension_nolock(NULL, this->context, this->exten);
06097       }
06098 
06099       /* Find the hint in the list of hints */
06100       AST_RWLIST_TRAVERSE(&hints, hint, list) {
06101          if (hint->exten == exten)
06102             break;
06103       }
06104       if (!exten || !hint) {
06105          /* this hint has been removed, notify the watchers */
06106          while ((thiscb = AST_LIST_REMOVE_HEAD(&this->callbacks, entry))) {
06107             thiscb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, thiscb->data);
06108             ast_free(thiscb);
06109          }
06110       } else {
06111          AST_LIST_APPEND_LIST(&hint->callbacks, &this->callbacks, entry);
06112          hint->laststate = this->laststate;
06113       }
06114       ast_free(this);
06115    }
06116 
06117    AST_RWLIST_UNLOCK(&hints);
06118    ast_unlock_contexts();
06119    endlocktime = ast_tvnow();
06120    
06121    /* the old list and hashtab no longer are relevant, delete them while the rest of asterisk
06122       is now freely using the new stuff instead */
06123    
06124    ast_hashtab_destroy(oldtable, NULL);
06125    
06126    for (tmp = oldcontextslist; tmp; ) {
06127       struct ast_context *next;  /* next starting point */
06128       next = tmp->next;
06129       __ast_internal_context_destroy(tmp);
06130       tmp = next;
06131    }
06132    enddeltime = ast_tvnow();
06133    
06134    ft = ast_tvdiff_us(writelocktime, begintime);
06135    ft /= 1000000.0;
06136    ast_verb(3,"Time to scan old dialplan and merge leftovers back into the new: %8.6f sec\n", ft);
06137    
06138    ft = ast_tvdiff_us(endlocktime, writelocktime);
06139    ft /= 1000000.0;
06140    ast_verb(3,"Time to restore hints and swap in new dialplan: %8.6f sec\n", ft);
06141 
06142    ft = ast_tvdiff_us(enddeltime, endlocktime);
06143    ft /= 1000000.0;
06144    ast_verb(3,"Time to delete the old dialplan: %8.6f sec\n", ft);
06145 
06146    ft = ast_tvdiff_us(enddeltime, begintime);
06147    ft /= 1000000.0;
06148    ast_verb(3,"Total time merge_contexts_delete: %8.6f sec\n", ft);
06149    return;
06150 }

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

References chan, and pbx_parseable_goto().

Referenced by _while_exec(), check_goto_on_transfer(), dial_exec_full(), gosub_exec(), ivr_dispatch(), parkandannounce_exec(), pbx_builtin_goto(), and while_continue_exec().

08962 {
08963    return pbx_parseable_goto(chan, goto_string, 0);
08964 }

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

References __ast_request_and_dial(), ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_free, ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create_detached, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verb, async_wait(), chan, errno, LOG_WARNING, and outgoing_helper::vars.

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

07490 {
07491    struct ast_channel *chan;
07492    struct app_tmp *tmp;
07493    int res = -1, cdr_res = -1;
07494    struct outgoing_helper oh;
07495 
07496    memset(&oh, 0, sizeof(oh));
07497    oh.vars = vars;
07498    oh.account = account;
07499 
07500    if (locked_channel)
07501       *locked_channel = NULL;
07502    if (ast_strlen_zero(app)) {
07503       res = -1;
07504       goto outgoing_app_cleanup;
07505    }
07506    if (synchronous) {
07507       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
07508       if (chan) {
07509          ast_set_variables(chan, vars);
07510          if (account)
07511             ast_cdr_setaccount(chan, account);
07512          if (chan->_state == AST_STATE_UP) {
07513             res = 0;
07514             ast_verb(4, "Channel %s was answered.\n", chan->name);
07515             tmp = ast_calloc(1, sizeof(*tmp));
07516             if (!tmp)
07517                res = -1;
07518             else {
07519                ast_copy_string(tmp->app, app, sizeof(tmp->app));
07520                if (appdata)
07521                   ast_copy_string(tmp->data, appdata, sizeof(tmp->data));
07522                tmp->chan = chan;
07523                if (synchronous > 1) {
07524                   if (locked_channel)
07525                      ast_channel_unlock(chan);
07526                   ast_pbx_run_app(tmp);
07527                } else {
07528                   if (locked_channel)
07529                      ast_channel_lock(chan);
07530                   if (ast_pthread_create_detached(&tmp->t, NULL, ast_pbx_run_app, tmp)) {
07531                      ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
07532                      ast_free(tmp);
07533                      if (locked_channel)
07534                         ast_channel_unlock(chan);
07535                      ast_hangup(chan);
07536                      res = -1;
07537                   } else {
07538                      if (locked_channel)
07539                         *locked_channel = chan;
07540                   }
07541                }
07542             }
07543          } else {
07544             ast_verb(4, "Channel %s was never answered.\n", chan->name);
07545             if (chan->cdr) { /* update the cdr */
07546                /* here we update the status of the call, which sould be busy.
07547                 * if that fails then we set the status to failed */
07548                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
07549                   ast_cdr_failed(chan->cdr);
07550             }
07551             ast_hangup(chan);
07552          }
07553       }
07554 
07555       if (res < 0) { /* the call failed for some reason */
07556          if (*reason == 0) { /* if the call failed (not busy or no answer)
07557                         * update the cdr with the failed message */
07558             cdr_res = ast_pbx_outgoing_cdr_failed();
07559             if (cdr_res != 0) {
07560                res = cdr_res;
07561                goto outgoing_app_cleanup;
07562             }
07563          }
07564       }
07565 
07566    } else {
07567       struct async_stat *as;
07568       if (!(as = ast_calloc(1, sizeof(*as)))) {
07569          res = -1;
07570          goto outgoing_app_cleanup;
07571       }
07572       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
07573       if (!chan) {
07574          ast_free(as);
07575          res = -1;
07576          goto outgoing_app_cleanup;
07577       }
07578       as->chan = chan;
07579       ast_copy_string(as->app, app, sizeof(as->app));
07580       if (appdata)
07581          ast_copy_string(as->appdata,  appdata, sizeof(as->appdata));
07582       as->timeout = timeout;
07583       ast_set_variables(chan, vars);
07584       if (account)
07585          ast_cdr_setaccount(chan, account);
07586       /* Start a new thread, and get something handling this channel. */
07587       if (locked_channel)
07588          ast_channel_lock(chan);
07589       if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) {
07590          ast_log(LOG_WARNING, "Failed to start async wait\n");
07591          ast_free(as);
07592          if (locked_channel)
07593             ast_channel_unlock(chan);
07594          ast_hangup(chan);
07595          res = -1;
07596          goto outgoing_app_cleanup;
07597       } else {
07598          if (locked_channel)
07599             *locked_channel = chan;
07600       }
07601       res = 0;
07602    }
07603 outgoing_app_cleanup:
07604    ast_variables_destroy(vars);
07605    return res;
07606 }

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

References __ast_request_and_dial(), ast_channel::_state, outgoing_helper::account, ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_alloc(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_exists_extension(), ast_free, ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create_detached, ast_request_and_dial(), ast_set_variables(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verb, async_wait(), ast_channel::cdr, chan, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::context, outgoing_helper::context, outgoing_helper::exten, ast_channel::hangupcause, LOG_ERROR, LOG_WARNING, ast_channel::name, outgoing_helper::parent_channel, pbx_builtin_setvar_helper(), outgoing_helper::priority, set_ext_pri(), and outgoing_helper::vars.

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

07324 {
07325    struct ast_channel *chan;
07326    struct async_stat *as;
07327    int res = -1, cdr_res = -1;
07328    struct outgoing_helper oh;
07329 
07330    if (synchronous) {
07331       oh.context = context;
07332       oh.exten = exten;
07333       oh.priority = priority;
07334       oh.cid_num = cid_num;
07335       oh.cid_name = cid_name;
07336       oh.account = account;
07337       oh.vars = vars;
07338       oh.parent_channel = NULL;
07339 
07340       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
07341       if (channel) {
07342          *channel = chan;
07343          if (chan)
07344             ast_channel_lock(chan);
07345       }
07346       if (chan) {
07347          if (chan->_state == AST_STATE_UP) {
07348                res = 0;
07349             ast_verb(4, "Channel %s was answered.\n", chan->name);
07350 
07351             if (synchronous > 1) {
07352                if (channel)
07353                   ast_channel_unlock(chan);
07354                if (ast_pbx_run(chan)) {
07355                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
07356                   if (channel)
07357                      *channel = NULL;
07358                   ast_hangup(chan);
07359                   chan = NULL;
07360                   res = -1;
07361                }
07362             } else {
07363                if (ast_pbx_start(chan)) {
07364                   ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name);
07365                   if (channel) {
07366                      *channel = NULL;
07367                      ast_channel_unlock(chan);
07368                   }
07369                   ast_hangup(chan);
07370                   res = -1;
07371                }
07372                chan = NULL;
07373             }
07374          } else {
07375             ast_verb(4, "Channel %s was never answered.\n", chan->name);
07376 
07377             if (chan->cdr) { /* update the cdr */
07378                /* here we update the status of the call, which sould be busy.
07379                 * if that fails then we set the status to failed */
07380                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
07381                   ast_cdr_failed(chan->cdr);
07382             }
07383 
07384             if (channel) {
07385                *channel = NULL;
07386                ast_channel_unlock(chan);
07387             }
07388             ast_hangup(chan);
07389             chan = NULL;
07390          }
07391       }
07392 
07393       if (res < 0) { /* the call failed for some reason */
07394          if (*reason == 0) { /* if the call failed (not busy or no answer)
07395                         * update the cdr with the failed message */
07396             cdr_res = ast_pbx_outgoing_cdr_failed();
07397             if (cdr_res != 0) {
07398                res = cdr_res;
07399                goto outgoing_exten_cleanup;
07400             }
07401          }
07402 
07403          /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */
07404          /* check if "failed" exists */
07405          if (ast_exists_extension(chan, context, "failed", 1, NULL)) {
07406             chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed");
07407             if (chan) {
07408                char failed_reason[4] = "";
07409                if (!ast_strlen_zero(context))
07410                   ast_copy_string(chan->context, context, sizeof(chan->context));
07411                set_ext_pri(chan, "failed", 1);
07412                ast_set_variables(chan, vars);
07413                snprintf(failed_reason, sizeof(failed_reason), "%d", *reason);
07414                pbx_builtin_setvar_helper(chan, "REASON", failed_reason);
07415                if (account)
07416                   ast_cdr_setaccount(chan, account);
07417                if (ast_pbx_run(chan)) {
07418                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
07419                   ast_hangup(chan);
07420                }
07421                chan = NULL;
07422             }
07423          }
07424       }
07425    } else {
07426       if (!(as = ast_calloc(1, sizeof(*as)))) {
07427          res = -1;
07428          goto outgoing_exten_cleanup;
07429       }
07430       chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
07431       if (channel) {
07432          *channel = chan;
07433          if (chan)
07434             ast_channel_lock(chan);
07435       }
07436       if (!chan) {
07437          ast_free(as);
07438          res = -1;
07439          goto outgoing_exten_cleanup;
07440       }
07441       as->chan = chan;
07442       ast_copy_string(as->context, context, sizeof(as->context));
07443       set_ext_pri(as->chan,  exten, priority);
07444       as->timeout = timeout;
07445       ast_set_variables(chan, vars);
07446       if (account)
07447          ast_cdr_setaccount(chan, account);
07448       if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) {
07449          ast_log(LOG_WARNING, "Failed to start async wait\n");
07450          ast_free(as);
07451          if (channel) {
07452             *channel = NULL;
07453             ast_channel_unlock(chan);
07454          }
07455          ast_hangup(chan);
07456          res = -1;
07457          goto outgoing_exten_cleanup;
07458       }
07459       res = 0;
07460    }
07461 outgoing_exten_cleanup:
07462    ast_variables_destroy(vars);
07463    return res;
07464 }

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.

Return values:
Zero on success
non-zero on failure

Definition at line 4069 of file pbx.c.

References ast_pbx_run_args().

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

04070 {
04071    return ast_pbx_run_args(c, NULL);
04072 }

enum ast_pbx_result ast_pbx_run_args ( struct ast_channel c,
struct ast_pbx_args args 
)

Execute the PBX in the current thread.

Parameters:
c channel to run the pbx on
args options for the pbx
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.

Return values:
Zero on success
non-zero on failure

Definition at line 4054 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_run(), dial_exec_full(), handle_gosub(), and try_calling().

04055 {
04056    enum ast_pbx_result res = AST_PBX_SUCCESS;
04057 
04058    if (increase_call_count(c)) {
04059       return AST_PBX_CALL_LIMIT;
04060    }
04061 
04062    res = __ast_pbx_run(c, args);
04063 
04064    decrease_call_count();
04065 
04066    return res;
04067 }

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 also:
ast_pbx_run for a synchronous function to run the PBX in the current thread, as opposed to starting a new one.
Return values:
Zero on success
non-zero on failure

Definition at line 4032 of file pbx.c.

References ast_log(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_pthread_create_detached, decrease_call_count(), increase_call_count(), LOG_WARNING, and pbx_thread().

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(), console_new(), dahdi_new(), dial_exec_full(), gtalk_new(), gtalk_newcall(), handle_request_invite(), jingle_new(), jingle_newcall(), local_call(), manage_parkinglot(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), skinny_new(), unistim_new(), and usbradio_new().

04033 {
04034    pthread_t t;
04035 
04036    if (!c) {
04037       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
04038       return AST_PBX_FAILED;
04039    }
04040 
04041    if (increase_call_count(c))
04042       return AST_PBX_CALL_LIMIT;
04043 
04044    /* Start a new thread, and get something handling this channel. */
04045    if (ast_pthread_create_detached(&t, NULL, pbx_thread, c)) {
04046       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
04047       decrease_call_count();
04048       return AST_PBX_FAILED;
04049    }
04050 
04051    return AST_PBX_SUCCESS;
04052 }

int ast_processed_calls ( void   ) 

Retrieve the total number of calls processed through the PBX since last restart.

Definition at line 4079 of file pbx.c.

References totalcalls.

Referenced by handle_chanlist(), and handle_showcalls().

04080 {
04081    return totalcalls;
04082 }

int ast_rdlock_context ( struct ast_context con  ) 

Read locks a given context.

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

Definition at line 8699 of file pbx.c.

References ast_rwlock_rdlock(), and ast_context::lock.

Referenced by _macro_exec(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_cli_dialplan_save(), lookup_c_ip(), lookup_ci(), manager_show_dialplan_helper(), show_debug_helper(), and show_dialplan_helper().

08700 {
08701    return ast_rwlock_rdlock(&con->lock);
08702 }

int ast_rdlock_contexts ( void   ) 

Read locks the context list.

Return values:
0 on success
-1 on error

Definition at line 8681 of file pbx.c.

References ast_rwlock_rdlock(), and conlock.

Referenced by _macro_exec(), ast_context_find(), ast_context_find_or_create(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_hint_extension(), ast_merge_contexts_and_delete(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_cli_dialplan_save(), handle_statechange(), manager_show_dialplan_helper(), pbx_extension_helper(), show_debug_helper(), show_dialplan_helper(), and unreference_cached_app().

08682 {
08683    return ast_rwlock_rdlock(&conlock);
08684 }

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

References ast_log(), AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_switch::list, LOG_WARNING, and ast_switch::name.

Referenced by load_module().

04585 {
04586    struct ast_switch *tmp;
04587 
04588    AST_RWLIST_WRLOCK(&switches);
04589    AST_RWLIST_TRAVERSE(&switches, tmp, list) {
04590       if (!strcasecmp(tmp->name, sw->name)) {
04591          AST_RWLIST_UNLOCK(&switches);
04592          ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
04593          return -1;
04594       }
04595    }
04596    AST_RWLIST_INSERT_TAIL(&switches, sw, list);
04597    AST_RWLIST_UNLOCK(&switches);
04598 
04599    return 0;
04600 }

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

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
found 
combined_find_spawn 
This adds a new extension to the asterisk extension list.

Note:
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
Return values:
0 on success
-1 on failure.

Definition at line 3646 of file pbx.c.

References E_SPAWN, and pbx_extension_helper().

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

03647 {
03648    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn);
03649 }

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

References ast_rwlock_unlock(), and ast_context::lock.

Referenced by __ast_context_destroy(), _macro_exec(), ast_add_extension2_lockopt(), ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_remove_extension_callerid2(), ast_context_remove_ignorepat2(), ast_context_remove_include2(), ast_context_remove_switch2(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_cli_dialplan_save(), lookup_c_ip(), lookup_ci(), manager_show_dialplan_helper(), show_debug_helper(), and show_dialplan_helper().

08705 {
08706    return ast_rwlock_unlock(&con->lock);
08707 }

int ast_unlock_contexts ( void   ) 

Unlocks contexts.

Return values:
0 on success
-1 on failure

Definition at line 8686 of file pbx.c.

References ast_rwlock_unlock(), and conlock.

Referenced by _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_find_or_create(), ast_context_lockmacro(), ast_context_remove_extension_callerid(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_unlockmacro(), ast_hint_extension(), ast_merge_contexts_and_delete(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_cli_dialplan_save(), handle_statechange(), manager_show_dialplan_helper(), pbx_extension_helper(), show_debug_helper(), show_dialplan_helper(), and unreference_cached_app().

08687 {
08688    return ast_rwlock_unlock(&conlock);
08689 }

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

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and ast_switch::list.

Referenced by __unload_module(), and unload_module().

04603 {
04604    AST_RWLIST_WRLOCK(&switches);
04605    AST_RWLIST_REMOVE(&switches, sw, list);
04606    AST_RWLIST_UNLOCK(&switches);
04607 }

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

Definition at line 8818 of file pbx.c.

References exten, and ast_context::root.

Referenced by complete_dialplan_remove_extension(), dundi_precache_full(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), pbx_find_extension(), show_dialplan_helper(), and unreference_cached_app().

08820 {
08821    if (!exten)
08822       return con ? con->root : NULL;
08823    else
08824       return exten->next;
08825 }

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

Definition at line 8851 of file pbx.c.

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

Referenced by complete_dialplan_remove_ignorepat(), context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), lookup_c_ip(), manager_show_dialplan_helper(), and show_dialplan_helper().

08853 {
08854    if (!ip)
08855       return con ? con->ignorepats : NULL;
08856    else
08857       return ip->next;
08858 }

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

Definition at line 8842 of file pbx.c.

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

Referenced by ast_context_verify_includes(), complete_dialplan_remove_include(), context_merge_incls_swits_igps_other_registrars(), find_matching_priority(), handle_cli_dialplan_save(), lookup_ci(), manager_show_dialplan_helper(), and show_dialplan_helper().

08844 {
08845    if (!inc)
08846       return con ? con->includes : NULL;
08847    else
08848       return inc->next;
08849 }

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

Definition at line 8827 of file pbx.c.

References ast_context::alts, AST_LIST_FIRST, AST_LIST_NEXT, and ast_sw::list.

Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().

08829 {
08830    if (!sw)
08831       return con ? AST_LIST_FIRST(&con->alts) : NULL;
08832    else
08833       return AST_LIST_NEXT(sw, list);
08834 }

struct ast_context* ast_walk_contexts ( struct ast_context con  ) 

Definition at line 8813 of file pbx.c.

References contexts, and ast_context::next.

Referenced by _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), pbx_find_extension(), pbx_load_module(), show_debug_helper(), show_dialplan_helper(), and unreference_cached_app().

08814 {
08815    return con ? con->next : contexts;
08816 }

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

Definition at line 8836 of file pbx.c.

References exten, and ast_exten::priority.

Referenced by complete_dialplan_remove_extension(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), pbx_find_extension(), show_dialplan_helper(), and unreference_cached_app().

08838 {
08839    return priority ? priority->peer : exten;
08840 }

int ast_wrlock_context ( struct ast_context con  ) 

Write locks a given context.

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

Definition at line 8694 of file pbx.c.

References ast_rwlock_wrlock(), and ast_context::lock.

Referenced by __ast_context_destroy(), ast_add_extension2_lockopt(), ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_remove_extension_callerid2(), ast_context_remove_ignorepat2(), ast_context_remove_include2(), and ast_context_remove_switch2().

08695 {
08696    return ast_rwlock_wrlock(&con->lock);
08697 }

int ast_wrlock_contexts ( void   ) 

Write locks the context list.

Return values:
0 on success
-1 on error

Definition at line 8673 of file pbx.c.

References ast_atomic_fetchadd_int(), ast_rwlock_wrlock(), and conlock.

Referenced by ast_context_destroy(), ast_context_find_or_create(), ast_merge_contexts_and_delete(), and complete_dialplan_remove_include().

08674 {
08675    int res = ast_rwlock_wrlock(&conlock);
08676    if (!res)
08677       ast_atomic_fetchadd_int(&conlock_wrlock_version, 1);
08678    return res;
08679 }

int ast_wrlock_contexts_version ( void   ) 

Definition at line 8665 of file pbx.c.

Referenced by ast_merge_contexts_and_delete().

08666 {
08667    return conlock_wrlock_version;
08668 }

void pbx_builtin_clear_globals ( void   ) 

Definition at line 8510 of file pbx.c.

References AST_LIST_REMOVE_HEAD, ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_var_delete(), ast_var_t::entries, globals, and globalslock.

Referenced by handle_cli_dialplan_reload(), and reload().

08511 {
08512    struct ast_var_t *vardata;
08513 
08514    ast_rwlock_wrlock(&globalslock);
08515    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
08516       ast_var_delete(vardata);
08517    ast_rwlock_unlock(&globalslock);
08518 }

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

Note:
Will lock the channel.

This function will return a pointer to the buffer inside the channel variable. This value should only be accessed with the channel locked. If the value needs to be kept around, it should be done by using the following thread-safe code:

      const char *var;

      ast_channel_lock(chan);
      if ((var = pbx_builtin_getvar_helper(chan, "MYVAR"))) {
         var = ast_strdupa(var);
      }
      ast_channel_unlock(chan);

Definition at line 8280 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_var_name(), ast_var_value(), chan, globals, and globalslock.

Referenced by _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), array(), ast_bridge_call(), ast_eivr_getvariable(), ast_feature_interpret(), ast_monitor_stop(), ast_park_call_full(), bridge_play_sounds(), builtin_atxfer(), builtin_automixmonitor(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dahdi_call(), dahdi_hangup(), dial_exec_full(), do_forward(), do_timelimit(), dundi_exec(), dundi_helper(), findparkinglotname(), get_also_info(), get_index(), get_refer_info(), global_read(), hash_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), local_read(), login_exec(), macro_fixup(), minivm_delete_exec(), minivm_notify_exec(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_space_reserve(), pickup_by_mark(), queue_exec(), real_ctx(), retrydial_exec(), ring_entry(), run_agi(), set_config_flags(), set_local_info(), sip_addheader(), sla_trunk_exec(), speech_background(), try_calling(), try_suggested_sip_codec(), and update_bridge_vars().

08281 {
08282    struct ast_var_t *variables;
08283    const char *ret = NULL;
08284    int i;
08285    struct varshead *places[2] = { NULL, &globals };
08286 
08287    if (!name)
08288       return NULL;
08289 
08290    if (chan) {
08291       ast_channel_lock(chan);
08292       places[0] = &chan->varshead;
08293    }
08294 
08295    for (i = 0; i < 2; i++) {
08296       if (!places[i])
08297          continue;
08298       if (places[i] == &globals)
08299          ast_rwlock_rdlock(&globalslock);
08300       AST_LIST_TRAVERSE(places[i], variables, entries) {
08301          if (!strcmp(name, ast_var_name(variables))) {
08302             ret = ast_var_value(variables);
08303             break;
08304          }
08305       }
08306       if (places[i] == &globals)
08307          ast_rwlock_unlock(&globalslock);
08308       if (ret)
08309          break;
08310    }
08311 
08312    if (chan)
08313       ast_channel_unlock(chan);
08314 
08315    return ret;
08316 }

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

Note:
Will lock the channel.

Definition at line 8318 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_strdupa, ast_var_assign(), ast_verb, chan, globals, globalslock, and LOG_WARNING.

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

08319 {
08320    struct ast_var_t *newvariable;
08321    struct varshead *headp;
08322 
08323    if (name[strlen(name)-1] == ')') {
08324       char *function = ast_strdupa(name);
08325 
08326       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
08327       ast_func_write(chan, function, value);
08328       return;
08329    }
08330 
08331    if (chan) {
08332       ast_channel_lock(chan);
08333       headp = &chan->varshead;
08334    } else {
08335       ast_rwlock_wrlock(&globalslock);
08336       headp = &globals;
08337    }
08338 
08339    if (value) {
08340       if (headp == &globals)
08341          ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value);
08342       newvariable = ast_var_assign(name, value);
08343       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
08344    }
08345 
08346    if (chan)
08347       ast_channel_unlock(chan);
08348    else
08349       ast_rwlock_unlock(&globalslock);
08350 }

int pbx_builtin_raise_exception ( struct ast_channel chan,
void *  data 
)

Definition at line 2576 of file pbx.c.

References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc(), ast_datastore_free(), ast_free, ast_string_field_init, ast_string_field_set, chan, ast_channel::context, ast_datastore::data, exception_store_info, ast_channel::exten, exten, ast_channel::priority, pbx_exception::priority, and set_ext_pri().

Referenced by __ast_pbx_run().

02577 {
02578    const char *reason = vreason;
02579    struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL);
02580    struct pbx_exception *exception = NULL;
02581 
02582    if (!ds) {
02583       ds = ast_datastore_alloc(&exception_store_info, NULL);
02584       if (!ds)
02585          return -1;
02586       exception = ast_calloc(1, sizeof(struct pbx_exception));
02587       if (!exception) {
02588          ast_datastore_free(ds);
02589          return -1;
02590       }
02591       if (ast_string_field_init(exception, 128)) {
02592          ast_free(exception);
02593          ast_datastore_free(ds);
02594          return -1;
02595       }
02596       ds->data = exception;
02597       ast_channel_datastore_add(chan, ds);
02598    } else
02599       exception = ds->data;
02600 
02601    ast_string_field_set(exception, reason, reason);
02602    ast_string_field_set(exception, context, chan->context);
02603    ast_string_field_set(exception, exten, chan->exten);
02604    exception->priority = chan->priority;
02605    set_ext_pri(chan, "e", 0);
02606    return 0;
02607 }

int pbx_builtin_serialize_variables ( struct ast_channel chan,
struct ast_str **  buf 
)

Note:
Will lock the channel.

Definition at line 8248 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_str_append(), ast_var_name(), ast_var_value(), buf, chan, ast_var_t::entries, LOG_ERROR, total, var, and ast_channel::varshead.

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

08249 {
08250    struct ast_var_t *variables;
08251    const char *var, *val;
08252    int total = 0;
08253 
08254    if (!chan)
08255       return 0;
08256 
08257    (*buf)->used = 0;
08258    (*buf)->str[0] = '\0';
08259 
08260    ast_channel_lock(chan);
08261 
08262    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
08263       if ((var = ast_var_name(variables)) && (val = ast_var_value(variables))
08264          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
08265          ) {
08266          if (ast_str_append(buf, 0, "%s=%s\n", var, val) < 0) {
08267             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
08268             break;
08269          } else
08270             total++;
08271       } else
08272          break;
08273    }
08274 
08275    ast_channel_unlock(chan);
08276 
08277    return total;
08278 }

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 8352 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_rwlock_unlock(), ast_rwlock_wrlock(), ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verb, chan, EVENT_FLAG_DIALPLAN, globals, globalslock, manager_event, ast_channel::name, and ast_channel::uniqueid.

Referenced by __oh323_new(), _macro_exec(), _while_exec(), acf_fetch(), acf_odbc_read(), acf_odbc_write(), action_atxfer(), action_setvar(), agi_exec_full(), aji_status_exec(), aqm_exec(), array(), ast_bridge_call(), ast_eivr_setvariable(), ast_feature_request_and_dial(), ast_iax2_new(), ast_monitor_start(), ast_pbx_outgoing_exten(), ast_rtp_set_vars(), ast_set_variables(), asyncgoto_exec(), background_detect_exec(), bridge_exec(), bridge_play_sounds(), builtin_atxfer(), builtin_automixmonitor(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), channel_spy(), conf_run(), controlplayback_exec(), count_exec(), dahdi_handle_dtmfup(), dahdi_new(), dial_exec_full(), do_waiting(), end_bridge_callback(), export_aoc_vars(), export_ch(), frame_set_var(), function_db_delete(), function_db_exists(), function_db_read(), function_realtime_store(), get_rdnis(), get_refer_info(), global_write(), gosub_release_frame(), handle_request_bye(), handle_request_refer(), handle_set_chanvar(), handle_set_global(), handle_setvariable(), hash_read(), hash_write(), isAnsweringMachine(), leave_voicemail(), local_hangup(), lua_set_variable(), lua_set_variable_value(), macro_fixup(), manage_parkinglot(), minivm_accmess_exec(), minivm_delete_exec(), minivm_greet_exec(), minivm_notify_exec(), minivm_record_exec(), misdn_call(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_exec_full(), parse_moved_contact(), pbx_builtin_background(), pbx_builtin_importvar(), pbx_builtin_setvar(), pbx_builtin_setvar_multiple(), pbx_load_config(), phase_e_handler(), play_message_datetime(), playback_exec(), pqm_exec(), prep_email_sub_vars(), process_ast_dsp(), read_exec(), readexten_exec(), readfile_exec(), record_exec(), return_exec(), rotate_file(), rpt_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_hangup(), sip_new(), skinny_new(), sla_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), ss_thread(), start_monitor_exec(), system_exec_helper(), transfer_exec(), transmit(), tryexec_exec(), update_bridge_vars(), update_qe_rule(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), waituntil_exec(), and zapateller_exec().

08353 {
08354    struct ast_var_t *newvariable;
08355    struct varshead *headp;
08356    const char *nametail = name;
08357 
08358    if (name[strlen(name) - 1] == ')') {
08359       char *function = ast_strdupa(name);
08360 
08361       ast_func_write(chan, function, value);
08362       return;
08363    }
08364 
08365    if (chan) {
08366       ast_channel_lock(chan);
08367       headp = &chan->varshead;
08368    } else {
08369       ast_rwlock_wrlock(&globalslock);
08370       headp = &globals;
08371    }
08372 
08373    /* For comparison purposes, we have to strip leading underscores */
08374    if (*nametail == '_') {
08375       nametail++;
08376       if (*nametail == '_')
08377          nametail++;
08378    }
08379 
08380    AST_LIST_TRAVERSE (headp, newvariable, entries) {
08381       if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
08382          /* there is already such a variable, delete it */
08383          AST_LIST_REMOVE(headp, newvariable, entries);
08384          ast_var_delete(newvariable);
08385          break;
08386       }
08387    }
08388 
08389    if (value) {
08390       if (headp == &globals)
08391          ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value);
08392       newvariable = ast_var_assign(name, value);
08393       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
08394       manager_event(EVENT_FLAG_DIALPLAN, "VarSet", 
08395          "Channel: %s\r\n"
08396          "Variable: %s\r\n"
08397          "Value: %s\r\n"
08398          "Uniqueid: %s\r\n", 
08399          chan ? chan->name : "none", name, value, 
08400          chan ? chan->uniqueid : "none");
08401    }
08402 
08403    if (chan)
08404       ast_channel_unlock(chan);
08405    else
08406       ast_rwlock_unlock(&globalslock);
08407 }

int pbx_builtin_setvar_multiple ( struct ast_channel chan,
void *  data 
)

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

08521 {
08522    int res;
08523    if (ast_strlen_zero(condition)) {                /* NULL or empty strings are false */
08524       return 0;
08525    } else if (sscanf(condition, "%d", &res) == 1) { /* Numbers are evaluated for truth */
08526       return res;
08527    } else {                                         /* Strings are true */
08528       return 1;
08529    }
08530 }

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

References __ast_module_user_add(), __ast_module_user_remove(), app, ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_log(), ast_strlen_zero(), ast_channel::cdr, ast_channel::data, LOG_WARNING, ast_channel::name, and S_OR.

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

00935 {
00936    int res;
00937    struct ast_module_user *u = NULL;
00938    const char *saved_c_appl;
00939    const char *saved_c_data;
00940 
00941    if (c->cdr && !ast_check_hangup(c))
00942       ast_cdr_setapp(c->cdr, app->name, data);
00943 
00944    /* save channel values */
00945    saved_c_appl= c->appl;
00946    saved_c_data= c->data;
00947 
00948    c->appl = app->name;
00949    c->data = data;
00950    if (app->module)
00951       u = __ast_module_user_add(app->module, c);
00952    if (!ast_strlen_zero(data) && strchr(data, '|') && !strchr(data, ',')) {
00953       ast_log(LOG_WARNING, "The application delimiter is now the comma, not "
00954          "the pipe.  Did you forget to convert your dialplan?  (%s(%s))\n",
00955          app->name, (char *) data);
00956    }
00957    res = app->execute(c, S_OR(data, ""));
00958    if (app->module && u)
00959       __ast_module_user_remove(app->module, u);
00960    /* restore channel values */
00961    c->appl = saved_c_appl;
00962    c->data = saved_c_data;
00963    return res;
00964 }

struct ast_exten* pbx_find_extension ( struct ast_channel chan,
struct ast_context bypass,
struct pbx_find_info q,
const char *  context,
const char *  exten,
int  priority,
const char *  label,
const char *  callerid,
enum ext_match_t  action 
)

Definition at line 2049 of file pbx.c.

References ast_context::alts, ast_autoservice_start(), ast_autoservice_stop(), ast_copy_string(), ast_hashtab_lookup(), AST_LIST_TRAVERSE, ast_log(), AST_PBX_MAX_STACK, ast_str_thread_get(), ast_strdupa, ast_strlen_zero(), ast_walk_context_extensions(), ast_walk_contexts(), ast_walk_extension_priorities(), ast_switch::canmatch, scoreboard::canmatch_exten, chan, contexts_table, create_match_char_tree(), ast_sw::data, pbx_find_info::data, E_CANMATCH, E_FINDLABEL, E_MATCHMORE, ast_sw::eval, ast_switch::exists, ast_exten::exten, scoreboard::exten, extenpatternmatchnew, extension_match_core(), pbx_find_info::foundcontext, include_valid(), ast_context::includes, pbx_find_info::incstack, ast_exten::label, scoreboard::last_char, ast_str::len, LOG_DEBUG, log_match_char_tree(), LOG_NOTICE, LOG_WARNING, match(), matchcid(), ast_switch::matchmore, ast_sw::name, ast_context::name, fake_context::name, new_find_extension(), ast_include::next, scoreboard::node, overrideswitch, ast_context::pattern_tree, pbx_find_extension(), pbx_findswitch(), pbx_substitute_variables_helper(), ast_exten::priority, ast_include::rname, ast_context::root_table, pbx_find_info::stacklen, pbx_find_info::status, STATUS_NO_CONTEXT, STATUS_NO_EXTENSION, STATUS_NO_LABEL, STATUS_NO_PRIORITY, STATUS_SUCCESS, ast_str::str, strsep(), switch_data, pbx_find_info::swo, scoreboard::total_length, scoreboard::total_specificity, and trie_find_next_match().

Referenced by ast_hint_extension_nolock(), ast_merge_contexts_and_delete(), pbx_extension_helper(), pbx_find_extension(), and register_peer_exten().

02053 {
02054    int x, res;
02055    struct ast_context *tmp = NULL;
02056    struct ast_exten *e = NULL, *eroot = NULL;
02057    struct ast_include *i = NULL;
02058    struct ast_sw *sw = NULL;
02059    struct ast_exten pattern = {NULL, };
02060    struct scoreboard score = {0, };
02061    struct ast_str *tmpdata = NULL;
02062 
02063    pattern.label = label;
02064    pattern.priority = priority;
02065 #ifdef NEED_DEBUG_HERE
02066    ast_log(LOG_NOTICE,"Looking for cont/ext/prio/label/action = %s/%s/%d/%s/%d\n", context, exten, priority, label, (int)action);
02067 #endif
02068 
02069    /* Initialize status if appropriate */
02070    if (q->stacklen == 0) {
02071       q->status = STATUS_NO_CONTEXT;
02072       q->swo = NULL;
02073       q->data = NULL;
02074       q->foundcontext = NULL;
02075    } else if (q->stacklen >= AST_PBX_MAX_STACK) {
02076       ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
02077       return NULL;
02078    }
02079 
02080    /* Check first to see if we've already been checked */
02081    for (x = 0; x < q->stacklen; x++) {
02082       if (!strcasecmp(q->incstack[x], context))
02083          return NULL;
02084    }
02085 
02086    if (bypass) /* bypass means we only look there */
02087       tmp = bypass;
02088    else {   /* look in contexts */
02089       struct fake_context item;
02090 
02091       ast_copy_string(item.name, context, sizeof(item.name));
02092 
02093       tmp = ast_hashtab_lookup(contexts_table, &item);
02094 #ifdef NOTNOW
02095       tmp = NULL;
02096       while ((tmp = ast_walk_contexts(tmp)) ) {
02097          if (!strcmp(tmp->name, context))
02098             break;
02099       }
02100 #endif
02101       if (!tmp)
02102          return NULL;
02103       
02104    }
02105 
02106    if (q->status < STATUS_NO_EXTENSION)
02107       q->status = STATUS_NO_EXTENSION;
02108    
02109    /* Do a search for matching extension */
02110 
02111    eroot = NULL;
02112    score.total_specificity = 0;
02113    score.exten = 0;
02114    score.total_length = 0;
02115    if (!tmp->pattern_tree && tmp->root_table)
02116    {
02117       create_match_char_tree(tmp);
02118 #ifdef NEED_DEBUG
02119       ast_log(LOG_DEBUG,"Tree Created in context %s:\n", context);
02120       log_match_char_tree(tmp->pattern_tree," ");
02121 #endif
02122    }
02123 #ifdef NEED_DEBUG
02124    ast_log(LOG_NOTICE,"The Trie we are searching in:\n");
02125    log_match_char_tree(tmp->pattern_tree, "::  ");
02126 #endif
02127 
02128    do {
02129       if (!ast_strlen_zero(overrideswitch)) {
02130          char *osw = ast_strdupa(overrideswitch), *name;
02131          struct ast_switch *asw;
02132          ast_switch_f *aswf = NULL;
02133          char *datap;
02134          int eval = 0;
02135 
02136          name = strsep(&osw, "/");
02137          asw = pbx_findswitch(name);
02138 
02139          if (!asw) {
02140             ast_log(LOG_WARNING, "No such switch '%s'\n", name);
02141             break;
02142          }
02143 
02144          if (osw && strchr(osw, '$')) {
02145             eval = 1;
02146          }
02147 
02148          if (eval && !(tmpdata = ast_str_thread_get(&switch_data, 512))) {
02149             ast_log(LOG_WARNING, "Can't evaluate overrideswitch?!");
02150             break;
02151          } else if (eval) {
02152             /* Substitute variables now */
02153             pbx_substitute_variables_helper(chan, osw, tmpdata->str, tmpdata->len);
02154             datap = tmpdata->str;
02155          } else {
02156             datap = osw;
02157          }
02158 
02159          /* equivalent of extension_match_core() at the switch level */
02160          if (action == E_CANMATCH)
02161             aswf = asw->canmatch;
02162          else if (action == E_MATCHMORE)
02163             aswf = asw->matchmore;
02164          else /* action == E_MATCH */
02165             aswf = asw->exists;
02166          if (!aswf) {
02167             res = 0;
02168          } else {
02169             if (chan) {
02170                ast_autoservice_start(chan);
02171             }
02172             res = aswf(chan, context, exten, priority, callerid, datap);
02173             if (chan) {
02174                ast_autoservice_stop(chan);
02175             }
02176          }
02177          if (res) {  /* Got a match */
02178             q->swo = asw;
02179             q->data = datap;
02180             q->foundcontext = context;
02181             /* XXX keep status = STATUS_NO_CONTEXT ? */
02182             return NULL;
02183          }
02184       }
02185    } while (0);
02186 
02187    if (extenpatternmatchnew) {
02188       new_find_extension(exten, &score, tmp->pattern_tree, 0, 0, callerid, label, action);
02189       eroot = score.exten;
02190       
02191       if (score.last_char == '!' && action == E_MATCHMORE) {
02192          /* We match an extension ending in '!'.
02193           * The decision in this case is final and is NULL (no match).
02194           */
02195 #ifdef NEED_DEBUG_HERE
02196          ast_log(LOG_NOTICE,"Returning MATCHMORE NULL with exclamation point.\n");
02197 #endif
02198          return NULL;
02199       }
02200       
02201       if (!eroot && (action == E_CANMATCH || action == E_MATCHMORE) && score.canmatch_exten) {
02202          q->status = STATUS_SUCCESS;
02203 #ifdef NEED_DEBUG_HERE
02204          ast_log(LOG_NOTICE,"Returning CANMATCH exten %s\n", score.canmatch_exten->exten);
02205 #endif
02206          return score.canmatch_exten;
02207       }
02208       
02209       if ((action == E_MATCHMORE || action == E_CANMATCH)  && eroot) {
02210          if (score.node) {
02211             struct ast_exten *z = trie_find_next_match(score.node);
02212             if (z) {
02213 #ifdef NEED_DEBUG_HERE
02214                ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten %s\n", z->exten);
02215 #endif
02216             } else {
02217                if (score.canmatch_exten) {
02218 #ifdef NEED_DEBUG_HERE
02219                   ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE canmatchmatch exten %s(%p)\n", score.canmatch_exten->exten, score.canmatch_exten);
02220 #endif
02221                   return score.canmatch_exten;
02222                } else {
02223 #ifdef NEED_DEBUG_HERE
02224                   ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten NULL\n");
02225 #endif
02226                }
02227             }
02228             return z;
02229          }
02230 #ifdef NEED_DEBUG_HERE
02231          ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE NULL (no next_match)\n");
02232 #endif
02233          return NULL;  /* according to the code, complete matches are null matches in MATCHMORE mode */
02234       }
02235       
02236       if (eroot) {
02237          /* found entry, now look for the right priority */
02238          if (q->status < STATUS_NO_PRIORITY)
02239             q->status = STATUS_NO_PRIORITY;
02240          e = NULL;
02241          if (action == E_FINDLABEL && label ) {
02242             if (q->status < STATUS_NO_LABEL)
02243                q->status = STATUS_NO_LABEL;
02244             e = ast_hashtab_lookup(eroot->peer_label_table, &pattern);
02245          } else {
02246             e = ast_hashtab_lookup(eroot->peer_table, &pattern);
02247          }
02248          if (e) { /* found a valid match */
02249             q->status = STATUS_SUCCESS;
02250             q->foundcontext = context;
02251 #ifdef NEED_DEBUG_HERE
02252             ast_log(LOG_NOTICE,"Returning complete match of exten %s\n", e->exten);
02253 #endif
02254             return e;
02255          }
02256       }
02257    } else {   /* the old/current default exten pattern match algorithm */
02258       
02259       /* scan the list trying to match extension and CID */
02260       eroot = NULL;
02261       while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) {
02262          int match = extension_match_core(eroot->exten, exten, action);
02263          /* 0 on fail, 1 on match, 2 on earlymatch */
02264          
02265          if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid)))
02266             continue;   /* keep trying */
02267          if (match == 2 && action == E_MATCHMORE) {
02268             /* We match an extension ending in '!'.
02269              * The decision in this case is final and is NULL (no match).
02270              */
02271             return NULL;
02272          }
02273          /* found entry, now look for the right priority */
02274          if (q->status < STATUS_NO_PRIORITY)
02275             q->status = STATUS_NO_PRIORITY;
02276          e = NULL;
02277          if (action == E_FINDLABEL && label ) {
02278             if (q->status < STATUS_NO_LABEL)
02279                q->status = STATUS_NO_LABEL;
02280             e = ast_hashtab_lookup(eroot->peer_label_table, &pattern);
02281          } else {
02282             e = ast_hashtab_lookup(eroot->peer_table, &pattern);
02283          }
02284 #ifdef NOTNOW
02285          while ( (e = ast_walk_extension_priorities(eroot, e)) ) {
02286             /* Match label or priority */
02287             if (action == E_FINDLABEL) {
02288                if (q->status < STATUS_NO_LABEL)
02289                   q->status = STATUS_NO_LABEL;
02290                if (label && e->label && !strcmp(label, e->label))
02291                   break;   /* found it */
02292             } else if (e->priority == priority) {
02293                break;   /* found it */
02294             } /* else keep searching */
02295          }
02296 #endif
02297          if (e) { /* found a valid match */
02298             q->status = STATUS_SUCCESS;
02299             q->foundcontext = context;
02300             return e;
02301          }
02302       }
02303    }
02304    
02305    
02306    /* Check alternative switches */
02307    AST_LIST_TRAVERSE(&tmp->alts, sw, list) {
02308       struct ast_switch *asw = pbx_findswitch(sw->name);
02309       ast_switch_f *aswf = NULL;
02310       char *datap;
02311 
02312       if (!asw) {
02313          ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name);
02314          continue;
02315       }
02316       /* Substitute variables now */
02317       
02318       if (sw->eval) {
02319          if (!(tmpdata = ast_str_thread_get(&switch_data, 512))) {
02320             ast_log(LOG_WARNING, "Can't evaluate switch?!");
02321             continue;
02322          }
02323          pbx_substitute_variables_helper(chan, sw->data, tmpdata->str, tmpdata->len);
02324       }
02325 
02326       /* equivalent of extension_match_core() at the switch level */
02327       if (action == E_CANMATCH)
02328          aswf = asw->canmatch;
02329       else if (action == E_MATCHMORE)
02330          aswf = asw->matchmore;
02331       else /* action == E_MATCH */
02332          aswf = asw->exists;
02333       datap = sw->eval ? tmpdata->str : sw->data;
02334       if (!aswf)
02335          res = 0;
02336       else {
02337          if (chan)
02338             ast_autoservice_start(chan);
02339          res = aswf(chan, context, exten, priority, callerid, datap);
02340          if (chan)
02341             ast_autoservice_stop(chan);
02342       }
02343       if (res) {  /* Got a match */
02344          q->swo = asw;
02345          q->data = datap;
02346          q->foundcontext = context;
02347          /* XXX keep status = STATUS_NO_CONTEXT ? */
02348          return NULL;
02349       }
02350    }
02351    q->incstack[q->stacklen++] = tmp->name;   /* Setup the stack */
02352    /* Now try any includes we have in this context */
02353    for (i = tmp->includes; i; i = i->next) {
02354       if (include_valid(i)) {
02355          if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action))) {
02356 #ifdef NEED_DEBUG_HERE
02357             ast_log(LOG_NOTICE,"Returning recursive match of %s\n", e->exten);
02358 #endif
02359             return e;
02360          }
02361          if (q->swo)
02362             return NULL;
02363       }
02364    }
02365    return NULL;
02366 }

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

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_app::list, and ast_app::name.

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

00973 {
00974    struct ast_app *tmp;
00975 
00976    AST_RWLIST_RDLOCK(&apps);
00977    AST_RWLIST_TRAVERSE(&apps, tmp, list) {
00978       if (!strcasecmp(tmp->name, app))
00979          break;
00980    }
00981    AST_RWLIST_UNLOCK(&apps);
00982 
00983    return tmp;
00984 }

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 in the dialplan.

Note:
See also

Definition at line 2448 of file pbx.c.

References ARRAY_LEN, ast_channel_lock, ast_channel_unlock, ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_eid_default, ast_eid_to_str(), ast_get_hint(), AST_LIST_TRAVERSE, ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_strdupa, ast_var_name(), ast_var_value(), ast_channel::cid, ast_callerid::cid_ani2, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, globals, globalslock, ast_channel::hangupcause, ast_channel::name, parse_variable_name(), ast_channel::priority, s, substring(), and ast_channel::uniqueid.

Referenced by action_getvar(), action_status(), handle_getvariable(), lua_get_variable(), lua_get_variable_value(), and pbx_substitute_variables_helper_full().

02449 {
02450    const char not_found = '\0';
02451    char *tmpvar;
02452    const char *s; /* the result */
02453    int offset, length;
02454    int i, need_substring;
02455    struct varshead *places[2] = { headp, &globals };  /* list of places where we may look */
02456 
02457    if (c) {
02458       ast_channel_lock(c);
02459       places[0] = &c->varshead;
02460    }
02461    /*
02462     * Make a copy of var because parse_variable_name() modifies the string.
02463     * Then if called directly, we might need to run substring() on the result;
02464     * remember this for later in 'need_substring', 'offset' and 'length'
02465     */
02466    tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */
02467    need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
02468 
02469    /*
02470     * Look first into predefined variables, then into variable lists.
02471     * Variable 's' points to the result, according to the following rules:
02472     * s == &not_found (set at the beginning) means that we did not find a
02473     * matching variable and need to look into more places.
02474     * If s != &not_found, s is a valid result string as follows:
02475     * s = NULL if the variable does not have a value;
02476     * you typically do this when looking for an unset predefined variable.
02477     * s = workspace if the result has been assembled there;
02478     * typically done when the result is built e.g. with an snprintf(),
02479     * so we don't need to do an additional copy.
02480     * s != workspace in case we have a string, that needs to be copied
02481     * (the ast_copy_string is done once for all at the end).
02482     * Typically done when the result is already available in some string.
02483     */
02484    s = &not_found;   /* default value */
02485    if (c) { /* This group requires a valid channel */
02486       /* Names with common parts are looked up a piece at a time using strncmp. */
02487       if (!strncmp(var, "CALL", 4)) {
02488          if (!strncmp(var + 4, "ING", 3)) {
02489             if (!strcmp(var + 7, "PRES")) {        /* CALLINGPRES */
02490                snprintf(workspace, workspacelen, "%d", c->cid.cid_pres);
02491                s = workspace;
02492             } else if (!strcmp(var + 7, "ANI2")) {    /* CALLINGANI2 */
02493                snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2);
02494                s = workspace;
02495             } else if (!strcmp(var + 7, "TON")) {     /* CALLINGTON */
02496                snprintf(workspace, workspacelen, "%d", c->cid.cid_ton);
02497                s = workspace;
02498             } else if (!strcmp(var + 7, "TNS")) {     /* CALLINGTNS */
02499                snprintf(workspace, workspacelen, "%d", c->cid.cid_tns);
02500                s = workspace;
02501             }
02502          }
02503       } else if (!strcmp(var, "HINT")) {
02504          s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL;
02505       } else if (!strcmp(var, "HINTNAME")) {
02506          s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL;
02507       } else if (!strcmp(var, "EXTEN")) {
02508          s = c->exten;
02509       } else if (!strcmp(var, "CONTEXT")) {
02510          s = c->context;
02511       } else if (!strcmp(var, "PRIORITY")) {
02512          snprintf(workspace, workspacelen, "%d", c->priority);
02513          s = workspace;
02514       } else if (!strcmp(var, "CHANNEL")) {
02515          s = c->name;
02516       } else if (!strcmp(var, "UNIQUEID")) {
02517          s = c->uniqueid;
02518       } else if (!strcmp(var, "HANGUPCAUSE")) {
02519          snprintf(workspace, workspacelen, "%d", c->hangupcause);
02520          s = workspace;
02521       }
02522    }
02523    if (s == &not_found) { /* look for more */
02524       if (!strcmp(var, "EPOCH")) {
02525          snprintf(workspace, workspacelen, "%u",(int)time(NULL));
02526          s = workspace;
02527       } else if (!strcmp(var, "SYSTEMNAME")) {
02528          s = ast_config_AST_SYSTEM_NAME;
02529       } else if (!strcmp(var, "ENTITYID")) {
02530          ast_eid_to_str(workspace, workspacelen, &ast_eid_default);
02531          s = workspace;
02532       }
02533    }
02534    /* if not found, look into chanvars or global vars */
02535    for (i = 0; s == &not_found && i < ARRAY_LEN(places); i++) {
02536       struct ast_var_t *variables;
02537       if (!places[i])
02538          continue;
02539       if (places[i] == &globals)
02540          ast_rwlock_rdlock(&globalslock);
02541       AST_LIST_TRAVERSE(places[i], variables, entries) {
02542          if (!strcasecmp(ast_var_name(variables), var)) {
02543             s = ast_var_value(variables);
02544             break;
02545          }
02546       }
02547       if (places[i] == &globals)
02548          ast_rwlock_unlock(&globalslock);
02549    }
02550    if (s == &not_found || s == NULL)
02551       *ret = NULL;
02552    else {
02553       if (s != workspace)
02554          ast_copy_string(workspace, s, workspacelen);
02555       *ret = workspace;
02556       if (need_substring)
02557          *ret = substring(*ret, offset, length, workspace, workspacelen);
02558    }
02559 
02560    if (c)
02561       ast_channel_unlock(c);
02562 }

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

References autofallthrough.

Referenced by pbx_load_module().

04085 {
04086    int oldval = autofallthrough;
04087    autofallthrough = newval;
04088    return oldval;
04089 }

int pbx_set_extenpatternmatchnew ( int  newval  ) 

Set "extenpatternmatchnew" flag, if newval is <0, does not acutally set. If set to 1, sets to use the new Trie-based pattern matcher. If newval set to 0, sets to use the old linear-search algorithm. Returns previous value.

Definition at line 4091 of file pbx.c.

References extenpatternmatchnew.

Referenced by handle_set_extenpatternmatchnew(), handle_unset_extenpatternmatchnew(), and pbx_load_module().

04092 {
04093    int oldval = extenpatternmatchnew;
04094    extenpatternmatchnew = newval;
04095    return oldval;
04096 }

void pbx_set_overrideswitch ( const char *  newval  ) 

Set "overrideswitch" field. If set and of nonzero length, all contexts will be tried directly through the named switch prior to any other matching within that context.

Since:
1.6.1

Definition at line 4098 of file pbx.c.

References ast_free, ast_strdup, ast_strlen_zero(), and overrideswitch.

Referenced by pbx_load_module().

04099 {
04100    if (overrideswitch) {
04101       ast_free(overrideswitch);
04102    }
04103    if (!ast_strlen_zero(newval)) {
04104       overrideswitch = ast_strdup(newval);
04105    } else {
04106       overrideswitch = NULL;
04107    }
04108 }

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

Definition at line 3089 of file pbx.c.

References pbx_substitute_variables_helper_full(), and ast_channel::varshead.

Referenced by _macro_exec(), acf_import(), acf_odbc_read(), acf_odbc_write(), ast_add_extension2_lockopt(), config_curl(), custom_log(), cut_internal(), destroy_curl(), exec_exec(), function_eval(), function_fieldqty(), get_mapping_weight(), handle_getvariablefull(), launch_monitor_thread(), make_email_file(), manager_log(), pbx_builtin_importvar(), pbx_find_extension(), pbx_load_config(), pbx_substitute_variables(), realtime_curl(), realtime_multi_curl(), require_curl(), rotate_file(), rpt_do_lstats(), rpt_exec(), sendmail(), sendpage(), sqlite3_log(), store_curl(), substituted(), try_calling(), tryexec_exec(), and update_curl().

03090 {
03091    pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
03092 }

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

Definition at line 3094 of file pbx.c.

References pbx_substitute_variables_helper_full().

Referenced by add_user_extension(), build_user_routes(), dundi_lookup_local(), loopback_subst(), phoneprov_callback(), pp_each_extension_exec(), and pp_each_user_exec().

03095 {
03096    pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
03097 }


Generated on Fri Jul 24 00:41:53 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7