Tue Mar 2 17:34:07 2010

Asterisk developer's documentation


pbx.h File Reference

Core PBX routines and definitions. More...

#include "asterisk/sched.h"
#include "asterisk/devicestate.h"
#include "asterisk/chanvars.h"
#include "asterisk/hashtab.h"
Include dependency graph for pbx.h:

Go to the source code of this file.

Data Structures

struct  ast_custom_function
 Data structure associated with a custom dialplan function. More...
struct  ast_pbx
struct  ast_pbx_args
 Options for ast_pbx_run(). More...
struct  ast_switch
struct  ast_timing
struct  pbx_find_info

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, 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).
struct ast_contextast_context_find (const char *name)
 Find a context.
struct 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.
struct ast_custom_functionast_custom_function_find (const char *name)
int ast_custom_function_unregister (struct ast_custom_function *acf)
 Unregister a custom function.
enum ast_extension_states ast_devstate_to_extenstate (enum ast_device_state devstate)
 Map devstate to an extension state.
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.
struct ast_extenast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority)
struct ast_ignorepatast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip)
struct ast_includeast_walk_context_includes (struct ast_context *con, struct ast_include *inc)
struct ast_swast_walk_context_switches (struct ast_context *con, struct ast_sw *sw)
struct ast_contextast_walk_contexts (struct ast_context *con)
struct ast_extenast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority)
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.
struct 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)
struct ast_apppbx_findapp (const char *app)
 Look up an application.
void pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
 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)

Functions for returning values from structures



const char * ast_get_context_name (struct ast_context *con)
struct 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)

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

Referenced by load_module(), and reload().

#define AST_MAX_APP   32

Max length of an application

Definition at line 35 of file pbx.h.

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

#define AST_PBX_ERROR   1

Jump to the 'e' exten

Definition at line 43 of file pbx.h.

Referenced by __ast_pbx_run().

#define AST_PBX_HANGUP   -1

Special return values from applications to the PBX {.

Jump to the 'h' exten

Definition at line 41 of file pbx.h.

#define AST_PBX_INCOMPLETE   12

Return to PBX matching, allowing more digits for the extension

Definition at line 44 of file pbx.h.

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

#define AST_PBX_KEEP   0

Definition at line 37 of file pbx.h.

#define AST_PBX_MAX_STACK   128

Definition at line 1042 of file pbx.h.

#define AST_PBX_OK   0

No errors

Definition at line 42 of file pbx.h.

#define AST_PBX_REPLACE   1

Definition at line 38 of file pbx.h.

#define PRIORITY_HINT   -1
#define STATUS_NO_CONTEXT   1

Definition at line 1037 of file pbx.h.

#define STATUS_NO_EXTENSION   2

Definition at line 1038 of file pbx.h.

#define STATUS_NO_LABEL   4

Definition at line 1040 of file pbx.h.

#define STATUS_NO_PRIORITY   3

Definition at line 1039 of file pbx.h.

#define STATUS_SUCCESS   5

Definition at line 1041 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 72 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 87 of file pbx.h.


Enumeration Type Documentation

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

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

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

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

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 
E_MATCHMORE 
E_CANMATCH 
E_MATCH 
E_MATCH_MASK 
E_SPAWN 
E_FINDLABEL 

Definition at line 1028 of file pbx.h.

01028                  {
01029    E_MATCHMORE =  0x00, /* extension can match but only with more 'digits' */
01030    E_CANMATCH =   0x01, /* extension can match with or without more 'digits' */
01031    E_MATCH =   0x02, /* extension is an exact match */
01032    E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */
01033    E_SPAWN =   0x12, /* want to spawn an extension. Requires exact match */
01034    E_FINDLABEL =  0x22  /* returns the priority for a given label. Requires exact match */
01035 };


Function Documentation

int __ast_custom_function_register ( struct ast_custom_function acf,
struct ast_module mod 
)

Register a custom function.

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

02812 {
02813    struct ast_custom_function *cur;
02814    char tmps[80];
02815 
02816    if (!acf)
02817       return -1;
02818 
02819    acf->mod = mod;
02820 
02821    AST_RWLIST_WRLOCK(&acf_root);
02822 
02823    AST_RWLIST_TRAVERSE(&acf_root, cur, acflist) {
02824       if (!strcmp(acf->name, cur->name)) {
02825          ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
02826          AST_RWLIST_UNLOCK(&acf_root);
02827          return -1;
02828       }
02829    }
02830 
02831    /* Store in alphabetical order */
02832    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
02833       if (strcasecmp(acf->name, cur->name) < 0) {
02834          AST_RWLIST_INSERT_BEFORE_CURRENT(acf, acflist);
02835          break;
02836       }
02837    }
02838    AST_RWLIST_TRAVERSE_SAFE_END;
02839    if (!cur)
02840       AST_RWLIST_INSERT_TAIL(&acf_root, acf, acflist);
02841 
02842    AST_RWLIST_UNLOCK(&acf_root);
02843 
02844    ast_verb(2, "Registered custom function '%s'\n", term_color(tmps, acf->name, COLOR_BRCYAN, 0, sizeof(tmps)));
02845 
02846    return 0;
02847 }

int ast_active_calls ( void   ) 

Retrieve the number of active calls.

Definition at line 4099 of file pbx.c.

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

04100 {
04101    return countcalls;
04102 }

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

06753 {
06754    int ret = -1;
06755    struct ast_context *c = find_context_locked(context);
06756 
06757    if (c) {
06758       ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
06759          application, data, datad, registrar);
06760       ast_unlock_contexts();
06761    }
06762    
06763    return ret;
06764 }

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

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

Note:
For details about the arguments, check ast_add_extension()

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

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

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

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

Definition at line 7068 of file pbx.c.

References ast_add_extension2_lockopt().

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

07072 {
07073    return ast_add_extension2_lockopt(con, replace, extension, priority, label, callerid, application, data, datad, registrar, 1, 1);
07074 }

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

Definition at line 6789 of file pbx.c.

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

Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), dahdi_handle_dtmfup(), handle_request_bye(), handle_request_refer(), pbx_parseable_goto(), process_ast_dsp(), sip_read(), and socket_process().

06790 {
06791    int res = 0;
06792 
06793    ast_channel_lock(chan);
06794 
06795    if (chan->pbx) { /* This channel is currently in the PBX */
06796       ast_explicit_goto(chan, context, exten, priority + 1);
06797       ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
06798    } else {
06799       /* In order to do it when the channel doesn't really exist within
06800          the PBX, we have to make a new channel, masquerade, and start the PBX
06801          at the new location */
06802       struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name);
06803       if (!tmpchan) {
06804          res = -1;
06805       } else {
06806          if (chan->cdr) {
06807             ast_cdr_discard(tmpchan->cdr);
06808             tmpchan->cdr = ast_cdr_dup(chan->cdr);  /* share the love */
06809          }
06810          /* Make formats okay */
06811          tmpchan->readformat = chan->readformat;
06812          tmpchan->writeformat = chan->writeformat;
06813          /* Setup proper location */
06814          ast_explicit_goto(tmpchan,
06815             S_OR(context, chan->context), S_OR(exten, chan->exten), priority);
06816 
06817          /* Masquerade into temp channel */
06818          if (ast_channel_masquerade(tmpchan, chan)) {
06819             /* Failed to set up the masquerade.  It's probably chan_local
06820              * in the middle of optimizing itself out.  Sad. :( */
06821             ast_hangup(tmpchan);
06822             tmpchan = NULL;
06823             res = -1;
06824          } else {
06825             /* Grab the locks and get going */
06826             ast_channel_lock(tmpchan);
06827             ast_do_masquerade(tmpchan);
06828             ast_channel_unlock(tmpchan);
06829             /* Start the PBX going on our stolen channel */
06830             if (ast_pbx_start(tmpchan)) {
06831                ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
06832                ast_hangup(tmpchan);
06833                res = -1;
06834             }
06835          }
06836       }
06837    }
06838    ast_channel_unlock(chan);
06839    return res;
06840 }

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

Definition at line 6842 of file pbx.c.

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

06843 {
06844    struct ast_channel *chan;
06845    int res = -1;
06846 
06847    chan = ast_get_channel_by_name_locked(channame);
06848    if (chan) {
06849       res = ast_async_goto(chan, context, exten, priority);
06850       ast_channel_unlock(chan);
06851    }
06852    return res;
06853 }

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

References __ast_goto_if_exists().

08993 {
08994    return __ast_goto_if_exists(chan, context, exten, priority, 1);
08995 }

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

References pbx_parseable_goto().

Referenced by asyncgoto_exec().

09056 {
09057    return pbx_parseable_goto(chan, goto_string, 1);
09058 }

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

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

06411 {
06412    char info_save[256];
06413    char *info;
06414 
06415    /* Check for empty just in case */
06416    if (ast_strlen_zero(info_in))
06417       return 0;
06418    /* make a copy just in case we were passed a static string */
06419    ast_copy_string(info_save, info_in, sizeof(info_save));
06420    info = info_save;
06421    /* Assume everything except time */
06422    i->monthmask = 0xfff;   /* 12 bits */
06423    i->daymask = 0x7fffffffU; /* 31 bits */
06424    i->dowmask = 0x7f; /* 7 bits */
06425    /* on each call, use strsep() to move info to the next argument */
06426    get_timerange(i, strsep(&info, "|,"));
06427    if (info)
06428       i->dowmask = get_range(strsep(&info, "|,"), 7, days, "day of week");
06429    if (info)
06430       i->daymask = get_range(strsep(&info, "|,"), 31, NULL, "day");
06431    if (info)
06432       i->monthmask = get_range(strsep(&info, "|,"), 12, months, "month");
06433    return 1;
06434 }

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

References E_CANMATCH, and pbx_extension_helper().

Referenced by background_detect_exec(), cb_events(), do_immediate_setup(), 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(), pbx_builtin_background(), phone_check_exception(), pri_dchannel(), skinny_ss(), ss_thread(), and valid_exit().

03662 {
03663    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0, 0);
03664 }

int ast_check_timing ( const struct ast_timing i  ) 

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

06437 {
06438    struct ast_tm tm;
06439    struct timeval now = ast_tvnow();
06440 
06441    ast_localtime(&now, &tm, NULL);
06442 
06443    /* If it's not the right month, return */
06444    if (!(i->monthmask & (1 << tm.tm_mon)))
06445       return 0;
06446 
06447    /* If it's not that time of the month.... */
06448    /* Warning, tm_mday has range 1..31! */
06449    if (!(i->daymask & (1 << (tm.tm_mday-1))))
06450       return 0;
06451 
06452    /* If it's not the right day of the week */
06453    if (!(i->dowmask & (1 << tm.tm_wday)))
06454       return 0;
06455 
06456    /* Sanity check the hour just to be safe */
06457    if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
06458       ast_log(LOG_WARNING, "Insane time...\n");
06459       return 0;
06460    }
06461 
06462    /* Now the tough part, we calculate if it fits
06463       in the right time based on min/hour */
06464    if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
06465       return 0;
06466 
06467    /* If we got this far, then we're good */
06468    return 1;
06469 }

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

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

Referenced by handle_cli_dialplan_add_ignorepat().

06663 {
06664    int ret = -1;
06665    struct ast_context *c = find_context_locked(context);
06666 
06667    if (c) {
06668       ret = ast_context_add_ignorepat2(c, value, registrar);
06669       ast_unlock_contexts();
06670    }
06671    return ret;
06672 }

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

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

06675 {
06676    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
06677    int length;
06678    char *pattern;
06679    length = sizeof(struct ast_ignorepat);
06680    length += strlen(value) + 1;
06681    if (!(ignorepat = ast_calloc(1, length)))
06682       return -1;
06683    /* The cast to char * is because we need to write the initial value.
06684     * The field is not supposed to be modified otherwise.  Also, gcc 4.2
06685     * sees the cast as dereferencing a type-punned pointer and warns about
06686     * it.  This is the workaround (we're telling gcc, yes, that's really
06687     * what we wanted to do).
06688     */
06689    pattern = (char *) ignorepat->pattern;
06690    strcpy(pattern, value);
06691    ignorepat->next = NULL;
06692    ignorepat->registrar = registrar;
06693    ast_wrlock_context(con);
06694    for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
06695       ignorepatl = ignorepatc;
06696       if (!strcasecmp(ignorepatc->pattern, value)) {
06697          /* Already there */
06698          ast_unlock_context(con);
06699          errno = EEXIST;
06700          return -1;
06701       }
06702    }
06703    if (ignorepatl)
06704       ignorepatl->next = ignorepat;
06705    else
06706       con->ignorepats = ignorepat;
06707    ast_unlock_context(con);
06708    return 0;
06709 
06710 }

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

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

Referenced by handle_cli_dialplan_add_include().

06217 {
06218    int ret = -1;
06219    struct ast_context *c = find_context_locked(context);
06220 
06221    if (c) {
06222       ret = ast_context_add_include2(c, include, registrar);
06223       ast_unlock_contexts();
06224    }
06225    return ret;
06226 }

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

06480 {
06481    struct ast_include *new_include;
06482    char *c;
06483    struct ast_include *i, *il = NULL; /* include, include_last */
06484    int length;
06485    char *p;
06486 
06487    length = sizeof(struct ast_include);
06488    length += 2 * (strlen(value) + 1);
06489 
06490    /* allocate new include structure ... */
06491    if (!(new_include = ast_calloc(1, length)))
06492       return -1;
06493    /* Fill in this structure. Use 'p' for assignments, as the fields
06494     * in the structure are 'const char *'
06495     */
06496    p = new_include->stuff;
06497    new_include->name = p;
06498    strcpy(p, value);
06499    p += strlen(value) + 1;
06500    new_include->rname = p;
06501    strcpy(p, value);
06502    /* Strip off timing info, and process if it is there */
06503    if ( (c = strchr(p, ',')) ) {
06504       *c++ = '\0';
06505            new_include->hastime = ast_build_timing(&(new_include->timing), c);
06506    }
06507    new_include->next      = NULL;
06508    new_include->registrar = registrar;
06509 
06510    ast_wrlock_context(con);
06511 
06512    /* ... go to last include and check if context is already included too... */
06513    for (i = con->includes; i; i = i->next) {
06514       if (!strcasecmp(i->name, new_include->name)) {
06515          ast_free(new_include);
06516          ast_unlock_context(con);
06517          errno = EEXIST;
06518          return -1;
06519       }
06520       il = i;
06521    }
06522 
06523    /* ... include new context into context list, unlock, return */
06524    if (il)
06525       il->next = new_include;
06526    else
06527       con->includes = new_include;
06528    ast_verb(3, "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
06529 
06530    ast_unlock_context(con);
06531 
06532    return 0;
06533 }

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

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

06541 {
06542    int ret = -1;
06543    struct ast_context *c = find_context_locked(context);
06544 
06545    if (c) { /* found, add switch to this context */
06546       ret = ast_context_add_switch2(c, sw, data, eval, registrar);
06547       ast_unlock_contexts();
06548    }
06549    return ret;
06550 }

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

References 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, ast_sw::name, and ast_sw::registrar.

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

06561 {
06562    struct ast_sw *new_sw;
06563    struct ast_sw *i;
06564    int length;
06565    char *p;
06566 
06567    length = sizeof(struct ast_sw);
06568    length += strlen(value) + 1;
06569    if (data)
06570       length += strlen(data);
06571    length++;
06572 
06573    /* allocate new sw structure ... */
06574    if (!(new_sw = ast_calloc(1, length)))
06575       return -1;
06576    /* ... fill in this structure ... */
06577    p = new_sw->stuff;
06578    new_sw->name = p;
06579    strcpy(new_sw->name, value);
06580    p += strlen(value) + 1;
06581    new_sw->data = p;
06582    if (data) {
06583       strcpy(new_sw->data, data);
06584       p += strlen(data) + 1;
06585    } else {
06586       strcpy(new_sw->data, "");
06587       p++;
06588    }
06589    new_sw->eval     = eval;
06590    new_sw->registrar = registrar;
06591 
06592    /* ... try to lock this context ... */
06593    ast_wrlock_context(con);
06594 
06595    /* ... go to last sw and check if context is already swd too... */
06596    AST_LIST_TRAVERSE(&con->alts, i, list) {
06597       if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
06598          ast_free(new_sw);
06599          ast_unlock_context(con);
06600          errno = EEXIST;
06601          return -1;
06602       }
06603    }
06604 
06605    /* ... sw new context into context list, unlock, return */
06606    AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
06607 
06608    ast_verb(3, "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
06609 
06610    ast_unlock_context(con);
06611 
06612    return 0;
06613 }

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

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

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

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

Find a context.

Parameters:
name name of the context to find

Will search for the context with the given name.

Returns:
the ast_context on success, NULL on failure.

Definition at line 2031 of file pbx.c.

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

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

02032 {
02033    struct ast_context *tmp = NULL;
02034    struct fake_context item;
02035 
02036    ast_copy_string(item.name, name, sizeof(item.name));
02037 
02038    ast_rdlock_contexts();
02039    if( contexts_table ) {
02040       tmp = ast_hashtab_lookup(contexts_table,&item);
02041    } else {
02042       while ( (tmp = ast_walk_contexts(tmp)) ) {
02043          if (!name || !strcasecmp(name, tmp->name))
02044             break;
02045       }
02046    }
02047    ast_unlock_contexts();
02048    return tmp;
02049 }

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

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 5872 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(), ast_context::ignorepats, ast_context::includes, local_contexts, ast_context::lock, LOG_ERROR, 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_config(), load_module(), lua_register_switches(), manage_parkinglot(), pbx_load_config(), pbx_load_users(), reload_config(), set_config(), sla_build_station(), and sla_build_trunk().

05873 {
05874    struct ast_context *tmp, **local_contexts;
05875    struct fake_context search;
05876    int length = sizeof(struct ast_context) + strlen(name) + 1;
05877 
05878    if (!contexts_table) {
05879       contexts_table = ast_hashtab_create(17,
05880                                  ast_hashtab_compare_contexts, 
05881                                  ast_hashtab_resize_java,
05882                                  ast_hashtab_newsize_java,
05883                                  ast_hashtab_hash_contexts,
05884                                  0);
05885    }
05886    
05887    ast_copy_string(search.name, name, sizeof(search.name));
05888    if (!extcontexts) {
05889       ast_rdlock_contexts();
05890       local_contexts = &contexts;
05891       tmp = ast_hashtab_lookup(contexts_table, &search);
05892       ast_unlock_contexts();
05893       if (tmp) {
05894          tmp->refcount++;
05895          return tmp;
05896       }
05897    } else { /* local contexts just in a linked list; search there for the new context; slow, linear search, but not frequent */
05898       local_contexts = extcontexts;
05899       tmp = ast_hashtab_lookup(exttable, &search);
05900       if (tmp) {
05901          tmp->refcount++;
05902          return tmp;
05903       }
05904    }
05905    
05906    if ((tmp = ast_calloc(1, length))) {
05907       ast_rwlock_init(&tmp->lock);
05908       ast_mutex_init(&tmp->macrolock);
05909       strcpy(tmp->name, name);
05910       tmp->root = NULL;
05911       tmp->root_table = NULL;
05912       tmp->registrar = ast_strdup(registrar);
05913       tmp->includes = NULL;
05914       tmp->ignorepats = NULL;
05915       tmp->refcount = 1;
05916    } else {
05917       ast_log(LOG_ERROR, "Danger! We failed to allocate a context for %s!\n", name);
05918       return NULL;
05919    }
05920    
05921    if (!extcontexts) {
05922       ast_wrlock_contexts();
05923       tmp->next = *local_contexts;
05924       *local_contexts = tmp;
05925       ast_hashtab_insert_safe(contexts_table, tmp); /*put this context into the tree */
05926       ast_unlock_contexts();
05927       ast_debug(1, "Registered context '%s'(%p) in table %p registrar: %s\n", tmp->name, tmp, contexts_table, registrar);
05928       ast_verb(3, "Registered extension context '%s' (%p) in table %p; registrar: %s\n", tmp->name, tmp, contexts_table, registrar);
05929    } else {
05930       tmp->next = *local_contexts;
05931       if (exttable)
05932          ast_hashtab_insert_immediate(exttable, tmp); /*put this context into the tree */
05933       
05934       *local_contexts = tmp;
05935       ast_debug(1, "Registered context '%s'(%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar);
05936       ast_verb(3, "Registered extension context '%s' (%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar);
05937    }
05938    return tmp;
05939 }

int ast_context_lockmacro ( const char *  context  ) 

locks the macrolock in the given given context

Parameters:
macrocontext name of the macro-context to lock

Locks the given macro-context to ensure only one thread (call) can execute it at a time

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

Definition at line 4486 of file pbx.c.

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

Referenced by _macro_exec().

04487 {
04488    struct ast_context *c = NULL;
04489    int ret = -1;
04490    struct fake_context item;
04491 
04492    ast_rdlock_contexts();
04493 
04494    ast_copy_string(item.name, context, sizeof(item.name));
04495 
04496    c = ast_hashtab_lookup(contexts_table,&item);
04497    if (c)
04498       ret = 0;
04499 
04500 
04501 #ifdef NOTNOW
04502 
04503    while ((c = ast_walk_contexts(c))) {
04504       if (!strcmp(ast_get_context_name(c), context)) {
04505          ret = 0;
04506          break;
04507       }
04508    }
04509 
04510 #endif
04511    ast_unlock_contexts();
04512 
04513    /* if we found context, lock macrolock */
04514    if (ret == 0) 
04515       ret = ast_mutex_lock(&c->macrolock);
04516 
04517    return ret;
04518 }

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

References ast_context_remove_extension_callerid().

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

04294 {
04295    return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar);
04296 }

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

References ast_context_remove_extension_callerid2().

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

04321 {
04322    return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar, already_locked);
04323 }

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

04299 {
04300    int ret = -1; /* default error return */
04301    struct ast_context *c = find_context_locked(context);
04302 
04303    if (c) { /* ... remove extension ... */
04304       ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcallerid, registrar, 1);
04305       ast_unlock_contexts();
04306    }
04307    return ret;
04308 }

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 4325 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, match_char::deleted, destroy_exten(), match_char::exten, ast_exten::exten, ast_exten::label, LOG_ERROR, log_match_char_tree(), LOG_NOTICE, LOG_WARNING, ast_exten::matchcid, ast_exten::next, ast_context::pattern_tree, ast_exten::peer, ast_exten::peer_label_table, ast_exten::peer_table, ast_exten::priority, ast_exten::registrar, ast_context::root, ast_context::root_table, and match_char::x.

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

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

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

Definition at line 6619 of file pbx.c.

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

Referenced by handle_cli_dialplan_remove_ignorepat().

06620 {
06621    int ret = -1;
06622    struct ast_context *c = find_context_locked(context);
06623 
06624    if (c) {
06625       ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
06626       ast_unlock_contexts();
06627    }
06628    return ret;
06629 }

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

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

06632 {
06633    struct ast_ignorepat *ip, *ipl = NULL;
06634 
06635    ast_wrlock_context(con);
06636 
06637    for (ip = con->ignorepats; ip; ip = ip->next) {
06638       if (!strcmp(ip->pattern, ignorepat) &&
06639          (!registrar || (registrar == ip->registrar))) {
06640          if (ipl) {
06641             ipl->next = ip->next;
06642             ast_free(ip);
06643          } else {
06644             con->ignorepats = ip->next;
06645             ast_free(ip);
06646          }
06647          ast_unlock_context(con);
06648          return 0;
06649       }
06650       ipl = ip;
06651    }
06652 
06653    ast_unlock_context(con);
06654    errno = EINVAL;
06655    return -1;
06656 }

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

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

Referenced by handle_cli_dialplan_remove_include().

04186 {
04187    int ret = -1;
04188    struct ast_context *c = find_context_locked(context);
04189 
04190    if (c) {
04191       /* found, remove include from this context ... */
04192       ret = ast_context_remove_include2(c, include, registrar);
04193       ast_unlock_contexts();
04194    }
04195    return ret;
04196 }

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

Removes an include by an ast_context structure.

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

Removes an include by an ast_context structure.

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

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

04208 {
04209    struct ast_include *i, *pi = NULL;
04210    int ret = -1;
04211 
04212    ast_wrlock_context(con);
04213 
04214    /* find our include */
04215    for (i = con->includes; i; pi = i, i = i->next) {
04216       if (!strcmp(i->name, include) &&
04217             (!registrar || !strcmp(i->registrar, registrar))) {
04218          /* remove from list */
04219          ast_verb(3, "Removing inclusion of context '%s' in context '%s; registrar=%s'\n", include, ast_get_context_name(con), registrar);
04220          if (pi)
04221             pi->next = i->next;
04222          else
04223             con->includes = i->next;
04224          /* free include and return */
04225          ast_free(i);
04226          ret = 0;
04227          break;
04228       }
04229    }
04230 
04231    ast_unlock_context(con);
04232 
04233    return ret;
04234 }

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

Remove a switch.

Removes a switch with the given parameters

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

Definition at line 4241 of file pbx.c.

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

04242 {
04243    int ret = -1; /* default error return */
04244    struct ast_context *c = find_context_locked(context);
04245 
04246    if (c) {
04247       /* remove switch from this context ... */
04248       ret = ast_context_remove_switch2(c, sw, data, registrar);
04249       ast_unlock_contexts();
04250    }
04251    return ret;
04252 }

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

References 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::name, and ast_sw::registrar.

Referenced by ast_context_remove_switch().

04263 {
04264    struct ast_sw *i;
04265    int ret = -1;
04266 
04267    ast_wrlock_context(con);
04268 
04269    /* walk switches */
04270    AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
04271       if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
04272          (!registrar || !strcmp(i->registrar, registrar))) {
04273          /* found, remove from list */
04274          ast_verb(3, "Removing switch '%s' from context '%s; registrar=%s'\n", sw, ast_get_context_name(con), registrar);
04275          AST_LIST_REMOVE_CURRENT(list);
04276          ast_free(i); /* free switch and return */
04277          ret = 0;
04278          break;
04279       }
04280    }
04281    AST_LIST_TRAVERSE_SAFE_END;
04282 
04283    ast_unlock_context(con);
04284 
04285    return ret;
04286 }

int ast_context_unlockmacro ( const char *  context  ) 

Unlocks the macrolock in the given context.

Parameters:
macrocontext name of the macro-context to unlock

Unlocks the given macro-context so that another thread (call) can execute it

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

Definition at line 4525 of file pbx.c.

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

Referenced by _macro_exec().

04526 {
04527    struct ast_context *c = NULL;
04528    int ret = -1;
04529    struct fake_context item;
04530 
04531    ast_rdlock_contexts();
04532 
04533    ast_copy_string(item.name, context, sizeof(item.name));
04534 
04535    c = ast_hashtab_lookup(contexts_table,&item);
04536    if (c)
04537       ret = 0;
04538 #ifdef NOTNOW
04539 
04540    while ((c = ast_walk_contexts(c))) {
04541       if (!strcmp(ast_get_context_name(c), context)) {
04542          ret = 0;
04543          break;
04544       }
04545    }
04546 
04547 #endif
04548    ast_unlock_contexts();
04549 
04550    /* if we found context, unlock macrolock */
04551    if (ret == 0) 
04552       ret = ast_mutex_unlock(&c->macrolock);
04553 
04554    return ret;
04555 }

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

08950 {
08951    struct ast_include *inc = NULL;
08952    int res = 0;
08953 
08954    while ( (inc = ast_walk_context_includes(con, inc)) ) {
08955       if (ast_context_find(inc->rname))
08956          continue;
08957 
08958       res = -1;
08959       ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n",
08960          ast_get_context_name(con), inc->rname);
08961       break;
08962    }
08963 
08964    return res;
08965 }

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

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

02783 {
02784    struct ast_custom_function *acf = NULL;
02785 
02786    AST_RWLIST_RDLOCK(&acf_root);
02787    AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) {
02788       if (!strcmp(name, acf->name))
02789          break;
02790    }
02791    AST_RWLIST_UNLOCK(&acf_root);
02792 
02793    return acf;
02794 }

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

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

02797 {
02798    struct ast_custom_function *cur;
02799 
02800    if (!acf)
02801       return -1;
02802 
02803    AST_RWLIST_WRLOCK(&acf_root);
02804    if ((cur = AST_RWLIST_REMOVE(&acf_root, acf, acflist)))
02805       ast_verb(2, "Unregistered custom function %s\n", cur->name);
02806    AST_RWLIST_UNLOCK(&acf_root);
02807 
02808    return cur ? 0 : -1;
02809 }

enum ast_extension_states ast_devstate_to_extenstate ( enum ast_device_state  devstate  ) 

Map devstate to an extension state.

Parameters:
[in] device state
Returns:
the extension state mapping.

Definition at line 3276 of file pbx.c.

References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_TOTAL, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, AST_EXTENSION_BUSY, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_RINGING, and AST_EXTENSION_UNAVAILABLE.

Referenced by ast_extension_state2().

03277 {
03278    switch (devstate) {
03279    case AST_DEVICE_ONHOLD:
03280       return AST_EXTENSION_ONHOLD;
03281    case AST_DEVICE_BUSY:
03282       return AST_EXTENSION_BUSY;
03283    case AST_DEVICE_UNAVAILABLE:
03284    case AST_DEVICE_UNKNOWN:
03285    case AST_DEVICE_INVALID:
03286       return AST_EXTENSION_UNAVAILABLE;
03287    case AST_DEVICE_RINGINUSE:
03288       return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING);
03289    case AST_DEVICE_RINGING:
03290       return AST_EXTENSION_RINGING;
03291    case AST_DEVICE_INUSE:
03292       return AST_EXTENSION_INUSE;
03293    case AST_DEVICE_NOT_INUSE:
03294       return AST_EXTENSION_NOT_INUSE;
03295    case AST_DEVICE_TOTAL: /* not a device state, included for completeness */
03296       break;
03297    }
03298 
03299    return AST_EXTENSION_NOT_INUSE;
03300 }

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 3646 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(), sip_read(), skinny_ss(), socket_process(), ss7_linkset(), ss_thread(), and waitstream_core().

03647 {
03648    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0, 0);
03649 }

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

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

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

06767 {
06768    if (!chan)
06769       return -1;
06770 
06771    ast_channel_lock(chan);
06772 
06773    if (!ast_strlen_zero(context))
06774       ast_copy_string(chan->context, context, sizeof(chan->context));
06775    if (!ast_strlen_zero(exten))
06776       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
06777    if (priority > -1) {
06778       chan->priority = priority;
06779       /* see flag description in channel.h for explanation */
06780       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
06781          chan->priority--;
06782    }
06783 
06784    ast_channel_unlock(chan);
06785 
06786    return 0;
06787 }

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

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

02009 {
02010    if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
02011       ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
02012    return extension_match_core(pattern, data, needmore);
02013 }

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

References ext_cmp().

Referenced by lua_extension_cmp().

01811 {
01812    return ext_cmp(a, b);
01813 }

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

02004 {
02005    return extension_match_core(pattern, data, E_MATCH);
02006 }

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

References ast_extension_state2(), and ast_hint_extension().

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

03339 {
03340    struct ast_exten *e;
03341 
03342    e = ast_hint_extension(c, context, exten);   /* Do we have a hint for this extension ? */
03343    if (!e)
03344       return -1;           /* No hint, return -1 */
03345 
03346    return ast_extension_state2(e);        /* Check all devices in the hint */
03347 }

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

03327 {
03328    int i;
03329 
03330    for (i = 0; (i < ARRAY_LEN(extension_states)); i++) {
03331       if (extension_states[i].extension_state == extension_state)
03332          return extension_states[i].text;
03333    }
03334    return "Unknown";
03335 }

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 3399 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_exten::cidmatch, ast_exten::data, ast_state_cb::data, ast_hint::exten, ast_exten::exten, ast_state_cb::id, ast_exten::label, ast_exten::parent, ast_exten::priority, and ast_exten::registrar.

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

03401 {
03402    struct ast_hint *hint;
03403    struct ast_state_cb *cblist;
03404    struct ast_exten *e;
03405 
03406    /* If there's no context and extension:  add callback to statecbs list */
03407    if (!context && !exten) {
03408       AST_RWLIST_WRLOCK(&hints);
03409 
03410       AST_LIST_TRAVERSE(&statecbs, cblist, entry) {
03411          if (cblist->callback == callback) {
03412             cblist->data = data;
03413             AST_RWLIST_UNLOCK(&hints);
03414             return 0;
03415          }
03416       }
03417 
03418       /* Now insert the callback */
03419       if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
03420          AST_RWLIST_UNLOCK(&hints);
03421          return -1;
03422       }
03423       cblist->id = 0;
03424       cblist->callback = callback;
03425       cblist->data = data;
03426 
03427       AST_LIST_INSERT_HEAD(&statecbs, cblist, entry);
03428 
03429       AST_RWLIST_UNLOCK(&hints);
03430 
03431       return 0;
03432    }
03433 
03434    if (!context || !exten)
03435       return -1;
03436 
03437    /* This callback type is for only one hint, so get the hint */
03438    e = ast_hint_extension(NULL, context, exten);
03439    if (!e) {
03440       return -1;
03441    }
03442 
03443    /* If this is a pattern, dynamically create a new extension for this
03444     * particular match.  Note that this will only happen once for each
03445     * individual extension, because the pattern will no longer match first.
03446     */
03447    if (e->exten[0] == '_') {
03448       ast_add_extension(e->parent->name, 0, exten, e->priority, e->label,
03449          e->cidmatch, e->app, ast_strdup(e->data), ast_free_ptr,
03450          e->registrar);
03451       e = ast_hint_extension(NULL, context, exten);
03452       if (!e || e->exten[0] == '_') {
03453          return -1;
03454       }
03455    }
03456 
03457    /* Find the hint in the list of hints */
03458    AST_RWLIST_WRLOCK(&hints);
03459 
03460    AST_RWLIST_TRAVERSE(&hints, hint, list) {
03461       if (hint->exten == e)
03462          break;
03463    }
03464 
03465    if (!hint) {
03466       /* We have no hint, sorry */
03467       AST_RWLIST_UNLOCK(&hints);
03468       return -1;
03469    }
03470 
03471    /* Now insert the callback in the callback list  */
03472    if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
03473       AST_RWLIST_UNLOCK(&hints);
03474       return -1;
03475    }
03476 
03477    cblist->id = stateid++;    /* Unique ID for this callback */
03478    cblist->callback = callback;  /* Pointer to callback routine */
03479    cblist->data = data;    /* Data for the callback */
03480 
03481    AST_LIST_INSERT_HEAD(&hint->callbacks, cblist, entry);
03482 
03483    AST_RWLIST_UNLOCK(&hints);
03484 
03485    return cblist->id;
03486 }

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 3489 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, and ast_state_cb::id.

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

03490 {
03491    struct ast_state_cb *p_cur = NULL;
03492    int ret = -1;
03493 
03494    if (!id && !callback)
03495       return -1;
03496 
03497    AST_RWLIST_WRLOCK(&hints);
03498 
03499    if (!id) {  /* id == 0 is a callback without extension */
03500       AST_LIST_TRAVERSE_SAFE_BEGIN(&statecbs, p_cur, entry) {
03501          if (p_cur->callback == callback) {
03502             AST_LIST_REMOVE_CURRENT(entry);
03503             break;
03504          }
03505       }
03506       AST_LIST_TRAVERSE_SAFE_END;
03507    } else { /* callback with extension, find the callback based on ID */
03508       struct ast_hint *hint;
03509       AST_RWLIST_TRAVERSE(&hints, hint, list) {
03510          AST_LIST_TRAVERSE_SAFE_BEGIN(&hint->callbacks, p_cur, entry) {
03511             if (p_cur->id == id) {
03512                AST_LIST_REMOVE_CURRENT(entry);
03513                break;
03514             }
03515          }
03516          AST_LIST_TRAVERSE_SAFE_END;
03517 
03518          if (p_cur)
03519             break;
03520       }
03521    }
03522 
03523    if (p_cur) {
03524       ast_free(p_cur);
03525    }
03526 
03527    AST_RWLIST_UNLOCK(&hints);
03528 
03529    return ret;
03530 }

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

03652 {
03653    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
03654 }

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

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

03657 {
03658    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
03659 }

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

References __ast_module_user_add(), __ast_module_user_remove(), ast_custom_function_find(), ast_log(), ast_strdupa, 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().

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

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

References __ast_module_user_add(), __ast_module_user_remove(), ast_custom_function_find(), ast_log(), ast_strdupa, 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().

02893 {
02894    char *copy = ast_strdupa(function);
02895    char *args = func_args(copy);
02896    struct ast_custom_function *acfptr = ast_custom_function_find(copy);
02897 
02898    if (acfptr == NULL)
02899       ast_log(LOG_ERROR, "Function %s not registered\n", copy);
02900    else if (!acfptr->write)
02901       ast_log(LOG_ERROR, "Function %s cannot be written to\n", copy);
02902    else {
02903       int res;
02904       struct ast_module_user *u = NULL;
02905       if (acfptr->mod)
02906          u = __ast_module_user_add(acfptr->mod, chan);
02907       res = acfptr->write(chan, copy, args, value);
02908       if (acfptr->mod && u)
02909          __ast_module_user_remove(acfptr->mod, u);
02910       return res;
02911    }
02912 
02913    return -1;
02914 }

const char* ast_get_context_name ( struct ast_context con  ) 
const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 8839 of file pbx.c.

References ast_context::registrar.

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

08840 {
08841    return c ? c->registrar : NULL;
08842 }

const char* ast_get_extension_app ( struct ast_exten e  ) 
void* ast_get_extension_app_data ( struct ast_exten e  ) 

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

08875 {
08876    return e ? e->data : NULL;
08877 }

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 8864 of file pbx.c.

References ast_exten::cidmatch.

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

08865 {
08866    return e ? e->cidmatch : NULL;
08867 }

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

Definition at line 8806 of file pbx.c.

References ast_exten::parent.

Referenced by handle_show_hint(), and handle_show_hints().

08807 {
08808    return exten ? exten->parent : NULL;
08809 }

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 8816 of file pbx.c.

References ast_exten::label.

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

08817 {
08818    return exten ? exten->label : NULL;
08819 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 8859 of file pbx.c.

References ast_exten::matchcid.

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

08860 {
08861    return e ? e->matchcid : 0;
08862 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 
int ast_get_extension_priority ( struct ast_exten exten  ) 

Definition at line 8831 of file pbx.c.

References ast_exten::priority.

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

08832 {
08833    return exten ? exten->priority : -1;
08834 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 8844 of file pbx.c.

References ast_exten::registrar.

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

08845 {
08846    return e ? e->registrar : NULL;
08847 }

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

If an extension 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 3629 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().

03630 {
03631    struct ast_exten *e = ast_hint_extension(c, context, exten);
03632 
03633    if (e) {
03634       if (hint)
03635          ast_copy_string(hint, ast_get_extension_app(e), hintsize);
03636       if (name) {
03637          const char *tmp = ast_get_extension_app_data(e);
03638          if (tmp)
03639             ast_copy_string(name, tmp, namesize);
03640       }
03641       return -1;
03642    }
03643    return 0;
03644 }

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 
const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

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

08855 {
08856    return ip ? ip->registrar : NULL;
08857 }

const char* ast_get_include_name ( struct ast_include include  ) 
const char* ast_get_include_registrar ( struct ast_include i  ) 

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

08850 {
08851    return i ? i->registrar : NULL;
08852 }

const char* ast_get_switch_data ( struct ast_sw sw  ) 

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

08885 {
08886    return sw ? sw->data : NULL;
08887 }

int ast_get_switch_eval ( struct ast_sw sw  ) 

Definition at line 8889 of file pbx.c.

References ast_sw::eval.

Referenced by context_merge_incls_swits_igps_other_registrars().

08890 {
08891    return sw->eval;
08892 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

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

08880 {
08881    return sw ? sw->name : NULL;
08882 }

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

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

08895 {
08896    return sw ? sw->registrar : NULL;
08897 }

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

References __ast_goto_if_exists().

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

08988 {
08989    return __ast_goto_if_exists(chan, context, exten, priority, 0);
08990 }

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

Definition at line 351 of file pbx.c.

Referenced by ast_context_find_or_create(), lua_register_switches(), and pbx_load_module().

00352 {
00353    const struct ast_context *ac = ah_a;
00354    const struct ast_context *bc = ah_b;
00355    if (!ac || !bc) /* safety valve, but it might prevent a crash you'd rather have happen */
00356       return 1;
00357    /* assume context names are registered in a string table! */
00358    return strcmp(ac->name, bc->name);
00359 }

unsigned int ast_hashtab_hash_contexts ( const void *  obj  ) 

Definition at line 394 of file pbx.c.

References ast_hashtab_hash_string().

Referenced by ast_context_find_or_create(), lua_register_switches(), and pbx_load_module().

00395 {
00396    const struct ast_context *ac = obj;
00397    return ast_hashtab_hash_string(ac->name);
00398 }

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

06713 {
06714    struct ast_context *con = ast_context_find(context);
06715    if (con) {
06716       struct ast_ignorepat *pat;
06717       for (pat = con->ignorepats; pat; pat = pat->next) {
06718          if (ast_extension_match(pat->pattern, pattern))
06719             return 1;
06720       }
06721    }
06722 
06723    return 0;
06724 }

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

References E_MATCHMORE, and pbx_extension_helper().

Referenced by __ast_pbx_run(), 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(), pbx_builtin_background(), pri_dchannel(), readexten_exec(), skinny_ss(), and ss_thread().

03667 {
03668    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0);
03669 }

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

References __ast_internal_context_destroy(), ast_exten::app, 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, context_merge(), ast_state_cb::data, ast_exten::data, E_MATCH, ast_exten::exten, ast_hint::exten, ast_hint::laststate, LOG_WARNING, ast_context::next, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_exten::registrar, and pbx_find_info::stacklen.

Referenced by lua_reload_extensions(), and pbx_load_module().

06072 {
06073    double ft;
06074    struct ast_context *tmp, *oldcontextslist;
06075    struct ast_hashtab *oldtable;
06076    struct store_hints store = AST_LIST_HEAD_INIT_VALUE;
06077    struct store_hint *this;
06078    struct ast_hint *hint;
06079    struct ast_exten *exten;
06080    int length;
06081    struct ast_state_cb *thiscb;
06082    struct ast_hashtab_iter *iter;
06083    
06084    /* it is very important that this function hold the hint list lock _and_ the conlock
06085       during its operation; not only do we need to ensure that the list of contexts
06086       and extensions does not change, but also that no hint callbacks (watchers) are
06087       added or removed during the merge/delete process
06088 
06089       in addition, the locks _must_ be taken in this order, because there are already
06090       other code paths that use this order
06091    */
06092    
06093    struct timeval begintime, writelocktime, endlocktime, enddeltime;
06094    int wrlock_ver;
06095    
06096    begintime = ast_tvnow();
06097    ast_rdlock_contexts();
06098    iter = ast_hashtab_start_traversal(contexts_table);
06099    while ((tmp = ast_hashtab_next(iter))) {
06100       context_merge(extcontexts, exttable, tmp, registrar);
06101    }
06102    ast_hashtab_end_traversal(iter);
06103    wrlock_ver = ast_wrlock_contexts_version();
06104    
06105    ast_unlock_contexts(); /* this feels real retarded, but you must do
06106                        what you must do If this isn't done, the following 
06107                         wrlock is a guraranteed deadlock */
06108    ast_wrlock_contexts();
06109    if (ast_wrlock_contexts_version() > wrlock_ver+1) {
06110       ast_log(LOG_WARNING,"==================!!!!!!!!!!!!!!!Something changed the contexts in the middle of merging contexts!\n");
06111    }
06112    
06113    AST_RWLIST_WRLOCK(&hints);
06114    writelocktime = ast_tvnow();
06115 
06116    /* preserve all watchers for hints */
06117    AST_RWLIST_TRAVERSE(&hints, hint, list) {
06118       if (!AST_LIST_EMPTY(&hint->callbacks)) {
06119          length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this);
06120          if (!(this = ast_calloc(1, length)))
06121             continue;
06122          /* this removes all the callbacks from the hint into this. */
06123          AST_LIST_APPEND_LIST(&this->callbacks, &hint->callbacks, entry);
06124          this->laststate = hint->laststate;
06125          this->context = this->data;
06126          strcpy(this->data, hint->exten->parent->name);
06127          this->exten = this->data + strlen(this->context) + 1;
06128          strcpy(this->exten, hint->exten->exten);
06129          AST_LIST_INSERT_HEAD(&store, this, list);
06130       }
06131    }
06132 
06133    /* save the old table and list */
06134    oldtable = contexts_table;
06135    oldcontextslist = contexts;
06136 
06137    /* move in the new table and list */
06138    contexts_table = exttable;
06139    contexts = *extcontexts;
06140    
06141    /* restore the watchers for hints that can be found; notify those that
06142       cannot be restored
06143    */
06144    while ((this = AST_LIST_REMOVE_HEAD(&store, list))) {
06145       struct pbx_find_info q = { .stacklen = 0 };
06146       exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH);
06147       /* If this is a pattern, dynamically create a new extension for this
06148        * particular match.  Note that this will only happen once for each
06149        * individual extension, because the pattern will no longer match first.
06150        */
06151       if (exten && exten->exten[0] == '_') {
06152          ast_add_extension_nolock(exten->parent->name, 0, this->exten, PRIORITY_HINT, NULL,
06153             0, exten->app, ast_strdup(exten->data), ast_free_ptr, exten->registrar);
06154          /* rwlocks are not recursive locks */
06155          exten = ast_hint_extension_nolock(NULL, this->context, this->exten);
06156       }
06157 
06158       /* Find the hint in the list of hints */
06159       AST_RWLIST_TRAVERSE(&hints, hint, list) {
06160          if (hint->exten == exten)
06161             break;
06162       }
06163       if (!exten || !hint) {
06164          /* this hint has been removed, notify the watchers */
06165          while ((thiscb = AST_LIST_REMOVE_HEAD(&this->callbacks, entry))) {
06166             thiscb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, thiscb->data);
06167             ast_free(thiscb);
06168          }
06169       } else {
06170          AST_LIST_APPEND_LIST(&hint->callbacks, &this->callbacks, entry);
06171          hint->laststate = this->laststate;
06172       }
06173       ast_free(this);
06174    }
06175 
06176    AST_RWLIST_UNLOCK(&hints);
06177    ast_unlock_contexts();
06178    endlocktime = ast_tvnow();
06179    
06180    /* the old list and hashtab no longer are relevant, delete them while the rest of asterisk
06181       is now freely using the new stuff instead */
06182    
06183    ast_hashtab_destroy(oldtable, NULL);
06184    
06185    for (tmp = oldcontextslist; tmp; ) {
06186       struct ast_context *next;  /* next starting point */
06187       next = tmp->next;
06188       __ast_internal_context_destroy(tmp);
06189       tmp = next;
06190    }
06191    enddeltime = ast_tvnow();
06192    
06193    ft = ast_tvdiff_us(writelocktime, begintime);
06194    ft /= 1000000.0;
06195    ast_verb(3,"Time to scan old dialplan and merge leftovers back into the new: %8.6f sec\n", ft);
06196    
06197    ft = ast_tvdiff_us(endlocktime, writelocktime);
06198    ft /= 1000000.0;
06199    ast_verb(3,"Time to restore hints and swap in new dialplan: %8.6f sec\n", ft);
06200 
06201    ft = ast_tvdiff_us(enddeltime, endlocktime);
06202    ft /= 1000000.0;
06203    ast_verb(3,"Time to delete the old dialplan: %8.6f sec\n", ft);
06204 
06205    ft = ast_tvdiff_us(enddeltime, begintime);
06206    ft /= 1000000.0;
06207    ast_verb(3,"Total time merge_contexts_delete: %8.6f sec\n", ft);
06208    return;
06209 }

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

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

09051 {
09052    return pbx_parseable_goto(chan, goto_string, 0);
09053 }

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

References __ast_request_and_dial(), ast_channel::_state, outgoing_helper::account, async_stat::app, app_tmp::app, async_stat::appdata, ast_calloc, ast_cdr_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(), ast_channel::cdr, async_stat::chan, app_tmp::chan, app_tmp::data, errno, ast_channel::hangupcause, LOG_WARNING, async_stat::p, app_tmp::t, async_stat::timeout, and outgoing_helper::vars.

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

07549 {
07550    struct ast_channel *chan;
07551    struct app_tmp *tmp;
07552    int res = -1, cdr_res = -1;
07553    struct outgoing_helper oh;
07554 
07555    memset(&oh, 0, sizeof(oh));
07556    oh.vars = vars;
07557    oh.account = account;
07558 
07559    if (locked_channel)
07560       *locked_channel = NULL;
07561    if (ast_strlen_zero(app)) {
07562       res = -1;
07563       goto outgoing_app_cleanup;
07564    }
07565    if (synchronous) {
07566       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
07567       if (chan) {
07568          ast_set_variables(chan, vars);
07569          if (account)
07570             ast_cdr_setaccount(chan, account);
07571          if (chan->_state == AST_STATE_UP) {
07572             res = 0;
07573             ast_verb(4, "Channel %s was answered.\n", chan->name);
07574             tmp = ast_calloc(1, sizeof(*tmp));
07575             if (!tmp)
07576                res = -1;
07577             else {
07578                ast_copy_string(tmp->app, app, sizeof(tmp->app));
07579                if (appdata)
07580                   ast_copy_string(tmp->data, appdata, sizeof(tmp->data));
07581                tmp->chan = chan;
07582                if (synchronous > 1) {
07583                   if (locked_channel)
07584                      ast_channel_unlock(chan);
07585                   ast_pbx_run_app(tmp);
07586                } else {
07587                   if (locked_channel)
07588                      ast_channel_lock(chan);
07589                   if (ast_pthread_create_detached(&tmp->t, NULL, ast_pbx_run_app, tmp)) {
07590                      ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
07591                      ast_free(tmp);
07592                      if (locked_channel)
07593                         ast_channel_unlock(chan);
07594                      ast_hangup(chan);
07595                      res = -1;
07596                   } else {
07597                      if (locked_channel)
07598                         *locked_channel = chan;
07599                   }
07600                }
07601             }
07602          } else {
07603             ast_verb(4, "Channel %s was never answered.\n", chan->name);
07604             if (chan->cdr) { /* update the cdr */
07605                /* here we update the status of the call, which sould be busy.
07606                 * if that fails then we set the status to failed */
07607                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
07608                   ast_cdr_failed(chan->cdr);
07609             }
07610             ast_hangup(chan);
07611          }
07612       }
07613 
07614       if (res < 0) { /* the call failed for some reason */
07615          if (*reason == 0) { /* if the call failed (not busy or no answer)
07616                         * update the cdr with the failed message */
07617             cdr_res = ast_pbx_outgoing_cdr_failed();
07618             if (cdr_res != 0) {
07619                res = cdr_res;
07620                goto outgoing_app_cleanup;
07621             }
07622          }
07623       }
07624 
07625    } else {
07626       struct async_stat *as;
07627       if (!(as = ast_calloc(1, sizeof(*as)))) {
07628          res = -1;
07629          goto outgoing_app_cleanup;
07630       }
07631       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
07632       if (!chan) {
07633          ast_free(as);
07634          res = -1;
07635          goto outgoing_app_cleanup;
07636       }
07637       as->chan = chan;
07638       ast_copy_string(as->app, app, sizeof(as->app));
07639       if (appdata)
07640          ast_copy_string(as->appdata,  appdata, sizeof(as->appdata));
07641       as->timeout = timeout;
07642       ast_set_variables(chan, vars);
07643       if (account)
07644          ast_cdr_setaccount(chan, account);
07645       /* Start a new thread, and get something handling this channel. */
07646       if (locked_channel)
07647          ast_channel_lock(chan);
07648       if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) {
07649          ast_log(LOG_WARNING, "Failed to start async wait\n");
07650          ast_free(as);
07651          if (locked_channel)
07652             ast_channel_unlock(chan);
07653          ast_hangup(chan);
07654          res = -1;
07655          goto outgoing_app_cleanup;
07656       } else {
07657          if (locked_channel)
07658             *locked_channel = chan;
07659       }
07660       res = 0;
07661    }
07662 outgoing_app_cleanup:
07663    ast_variables_destroy(vars);
07664    return res;
07665 }

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 7382 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, async_stat::chan, outgoing_helper::cid_name, outgoing_helper::cid_num, async_stat::context, ast_channel::context, outgoing_helper::context, outgoing_helper::exten, ast_channel::hangupcause, LOG_ERROR, LOG_WARNING, async_stat::p, outgoing_helper::parent_channel, pbx_builtin_setvar_helper(), outgoing_helper::priority, set_ext_pri(), async_stat::timeout, and outgoing_helper::vars.

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

07383 {
07384    struct ast_channel *chan;
07385    struct async_stat *as;
07386    int res = -1, cdr_res = -1;
07387    struct outgoing_helper oh;
07388 
07389    if (synchronous) {
07390       oh.context = context;
07391       oh.exten = exten;
07392       oh.priority = priority;
07393       oh.cid_num = cid_num;
07394       oh.cid_name = cid_name;
07395       oh.account = account;
07396       oh.vars = vars;
07397       oh.parent_channel = NULL;
07398 
07399       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
07400       if (channel) {
07401          *channel = chan;
07402          if (chan)
07403             ast_channel_lock(chan);
07404       }
07405       if (chan) {
07406          if (chan->_state == AST_STATE_UP) {
07407                res = 0;
07408             ast_verb(4, "Channel %s was answered.\n", chan->name);
07409 
07410             if (synchronous > 1) {
07411                if (channel)
07412                   ast_channel_unlock(chan);
07413                if (ast_pbx_run(chan)) {
07414                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
07415                   if (channel)
07416                      *channel = NULL;
07417                   ast_hangup(chan);
07418                   chan = NULL;
07419                   res = -1;
07420                }
07421             } else {
07422                if (ast_pbx_start(chan)) {
07423                   ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name);
07424                   if (channel) {
07425                      *channel = NULL;
07426                      ast_channel_unlock(chan);
07427                   }
07428                   ast_hangup(chan);
07429                   res = -1;
07430                }
07431                chan = NULL;
07432             }
07433          } else {
07434             ast_verb(4, "Channel %s was never answered.\n", chan->name);
07435 
07436             if (chan->cdr) { /* update the cdr */
07437                /* here we update the status of the call, which sould be busy.
07438                 * if that fails then we set the status to failed */
07439                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
07440                   ast_cdr_failed(chan->cdr);
07441             }
07442 
07443             if (channel) {
07444                *channel = NULL;
07445                ast_channel_unlock(chan);
07446             }
07447             ast_hangup(chan);
07448             chan = NULL;
07449          }
07450       }
07451 
07452       if (res < 0) { /* the call failed for some reason */
07453          if (*reason == 0) { /* if the call failed (not busy or no answer)
07454                         * update the cdr with the failed message */
07455             cdr_res = ast_pbx_outgoing_cdr_failed();
07456             if (cdr_res != 0) {
07457                res = cdr_res;
07458                goto outgoing_exten_cleanup;
07459             }
07460          }
07461 
07462          /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */
07463          /* check if "failed" exists */
07464          if (ast_exists_extension(chan, context, "failed", 1, NULL)) {
07465             chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed");
07466             if (chan) {
07467                char failed_reason[4] = "";
07468                if (!ast_strlen_zero(context))
07469                   ast_copy_string(chan->context, context, sizeof(chan->context));
07470                set_ext_pri(chan, "failed", 1);
07471                ast_set_variables(chan, vars);
07472                snprintf(failed_reason, sizeof(failed_reason), "%d", *reason);
07473                pbx_builtin_setvar_helper(chan, "REASON", failed_reason);
07474                if (account)
07475                   ast_cdr_setaccount(chan, account);
07476                if (ast_pbx_run(chan)) {
07477                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
07478                   ast_hangup(chan);
07479                }
07480                chan = NULL;
07481             }
07482          }
07483       }
07484    } else {
07485       if (!(as = ast_calloc(1, sizeof(*as)))) {
07486          res = -1;
07487          goto outgoing_exten_cleanup;
07488       }
07489       chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
07490       if (channel) {
07491          *channel = chan;
07492          if (chan)
07493             ast_channel_lock(chan);
07494       }
07495       if (!chan) {
07496          ast_free(as);
07497          res = -1;
07498          goto outgoing_exten_cleanup;
07499       }
07500       as->chan = chan;
07501       ast_copy_string(as->context, context, sizeof(as->context));
07502       set_ext_pri(as->chan,  exten, priority);
07503       as->timeout = timeout;
07504       ast_set_variables(chan, vars);
07505       if (account)
07506          ast_cdr_setaccount(chan, account);
07507       if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) {
07508          ast_log(LOG_WARNING, "Failed to start async wait\n");
07509          ast_free(as);
07510          if (channel) {
07511             *channel = NULL;
07512             ast_channel_unlock(chan);
07513          }
07514          ast_hangup(chan);
07515          res = -1;
07516          goto outgoing_exten_cleanup;
07517       }
07518       res = 0;
07519    }
07520 outgoing_exten_cleanup:
07521    ast_variables_destroy(vars);
07522    return res;
07523 }

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

04095 {
04096    return ast_pbx_run_args(c, NULL);
04097 }

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

04080 {
04081    enum ast_pbx_result res = AST_PBX_SUCCESS;
04082 
04083    if (increase_call_count(c)) {
04084       return AST_PBX_CALL_LIMIT;
04085    }
04086 
04087    res = __ast_pbx_run(c, args);
04088 
04089    decrease_call_count();
04090 
04091    return res;
04092 }

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 4057 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(), pri_dchannel(), rpt_call(), sip_new(), skinny_new(), unistim_new(), and usbradio_new().

04058 {
04059    pthread_t t;
04060 
04061    if (!c) {
04062       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
04063       return AST_PBX_FAILED;
04064    }
04065 
04066    if (increase_call_count(c))
04067       return AST_PBX_CALL_LIMIT;
04068 
04069    /* Start a new thread, and get something handling this channel. */
04070    if (ast_pthread_create_detached(&t, NULL, pbx_thread, c)) {
04071       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
04072       decrease_call_count();
04073       return AST_PBX_FAILED;
04074    }
04075 
04076    return AST_PBX_SUCCESS;
04077 }

int ast_processed_calls ( void   ) 

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

Definition at line 4104 of file pbx.c.

Referenced by handle_chanlist(), and handle_showcalls().

04105 {
04106    return totalcalls;
04107 }

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

08789 {
08790    return ast_rwlock_rdlock(&con->lock);
08791 }

int ast_rdlock_contexts ( void   ) 
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 4609 of file pbx.c.

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

Referenced by load_module().

04610 {
04611    struct ast_switch *tmp;
04612 
04613    AST_RWLIST_WRLOCK(&switches);
04614    AST_RWLIST_TRAVERSE(&switches, tmp, list) {
04615       if (!strcasecmp(tmp->name, sw->name)) {
04616          AST_RWLIST_UNLOCK(&switches);
04617          ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
04618          return -1;
04619       }
04620    }
04621    AST_RWLIST_INSERT_TAIL(&switches, sw, list);
04622    AST_RWLIST_UNLOCK(&switches);
04623 
04624    return 0;
04625 }

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

03672 {
03673    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn);
03674 }

int ast_unlock_context ( struct ast_context con  ) 
int ast_unlock_contexts ( void   ) 
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 4627 of file pbx.c.

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

Referenced by __unload_module(), and unload_module().

04628 {
04629    AST_RWLIST_WRLOCK(&switches);
04630    AST_RWLIST_REMOVE(&switches, sw, list);
04631    AST_RWLIST_UNLOCK(&switches);
04632 }

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

Definition at line 8907 of file pbx.c.

References ast_exten::next, 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().

08909 {
08910    if (!exten)
08911       return con ? con->root : NULL;
08912    else
08913       return exten->next;
08914 }

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

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

08942 {
08943    if (!ip)
08944       return con ? con->ignorepats : NULL;
08945    else
08946       return ip->next;
08947 }

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

Definition at line 8916 of file pbx.c.

References AST_LIST_FIRST, and AST_LIST_NEXT.

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

08918 {
08919    if (!sw)
08920       return con ? AST_LIST_FIRST(&con->alts) : NULL;
08921    else
08922       return AST_LIST_NEXT(sw, list);
08923 }

struct ast_context* ast_walk_contexts ( struct ast_context con  )  [read]
struct ast_exten* ast_walk_extension_priorities ( struct ast_exten exten,
struct ast_exten priority 
) [read]
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 8783 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().

08784 {
08785    return ast_rwlock_wrlock(&con->lock);
08786 }

int ast_wrlock_contexts ( void   ) 

Write locks the context list.

Return values:
0 on success
-1 on error

Definition at line 8762 of file pbx.c.

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

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

08763 {
08764    int res = ast_rwlock_wrlock(&conlock);
08765    if (!res)
08766       ast_atomic_fetchadd_int(&conlock_wrlock_version, 1);
08767    return res;
08768 }

int ast_wrlock_contexts_version ( void   ) 

Definition at line 8754 of file pbx.c.

References conlock_wrlock_version.

Referenced by ast_merge_contexts_and_delete().

08755 {
08756    return conlock_wrlock_version;
08757 }

void pbx_builtin_clear_globals ( void   ) 

Definition at line 8599 of file pbx.c.

References AST_LIST_REMOVE_HEAD, ast_rwlock_unlock(), ast_rwlock_wrlock(), and ast_var_delete().

Referenced by handle_cli_dialplan_reload(), and reload().

08600 {
08601    struct ast_var_t *vardata;
08602 
08603    ast_rwlock_wrlock(&globalslock);
08604    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
08605       ast_var_delete(vardata);
08606    ast_rwlock_unlock(&globalslock);
08607 }

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 8369 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(), and ast_channel::varshead.

Referenced by __ast_pbx_run(), _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), array(), ast_bridge_call(), ast_call_forward(), 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(), pbx_builtin_background(), 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(), update_bridge_vars(), and wait_for_answer().

08370 {
08371    struct ast_var_t *variables;
08372    const char *ret = NULL;
08373    int i;
08374    struct varshead *places[2] = { NULL, &globals };
08375 
08376    if (!name)
08377       return NULL;
08378 
08379    if (chan) {
08380       ast_channel_lock(chan);
08381       places[0] = &chan->varshead;
08382    }
08383 
08384    for (i = 0; i < 2; i++) {
08385       if (!places[i])
08386          continue;
08387       if (places[i] == &globals)
08388          ast_rwlock_rdlock(&globalslock);
08389       AST_LIST_TRAVERSE(places[i], variables, entries) {
08390          if (!strcmp(name, ast_var_name(variables))) {
08391             ret = ast_var_value(variables);
08392             break;
08393          }
08394       }
08395       if (places[i] == &globals)
08396          ast_rwlock_unlock(&globalslock);
08397       if (ret)
08398          break;
08399    }
08400 
08401    if (chan)
08402       ast_channel_unlock(chan);
08403 
08404    return ret;
08405 }

void pbx_builtin_pushvar_helper ( struct ast_channel chan,
const char *  name,
const char *  value 
)
Note:
Will lock the channel.

Definition at line 8407 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, LOG_WARNING, and ast_channel::varshead.

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

08408 {
08409    struct ast_var_t *newvariable;
08410    struct varshead *headp;
08411 
08412    if (name[strlen(name)-1] == ')') {
08413       char *function = ast_strdupa(name);
08414 
08415       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
08416       ast_func_write(chan, function, value);
08417       return;
08418    }
08419 
08420    if (chan) {
08421       ast_channel_lock(chan);
08422       headp = &chan->varshead;
08423    } else {
08424       ast_rwlock_wrlock(&globalslock);
08425       headp = &globals;
08426    }
08427 
08428    if (value) {
08429       if (headp == &globals)
08430          ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value);
08431       newvariable = ast_var_assign(name, value);
08432       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
08433    }
08434 
08435    if (chan)
08436       ast_channel_unlock(chan);
08437    else
08438       ast_rwlock_unlock(&globalslock);
08439 }

int pbx_builtin_raise_exception ( struct ast_channel chan,
void *  data 
)

Definition at line 2595 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, ast_channel::context, ast_datastore::data, exception_store_info, ast_channel::exten, ast_channel::priority, pbx_exception::priority, and set_ext_pri().

Referenced by __ast_pbx_run().

02596 {
02597    const char *reason = vreason;
02598    struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL);
02599    struct pbx_exception *exception = NULL;
02600 
02601    if (!ds) {
02602       ds = ast_datastore_alloc(&exception_store_info, NULL);
02603       if (!ds)
02604          return -1;
02605       exception = ast_calloc(1, sizeof(struct pbx_exception));
02606       if (!exception) {
02607          ast_datastore_free(ds);
02608          return -1;
02609       }
02610       if (ast_string_field_init(exception, 128)) {
02611          ast_free(exception);
02612          ast_datastore_free(ds);
02613          return -1;
02614       }
02615       ds->data = exception;
02616       ast_channel_datastore_add(chan, ds);
02617    } else
02618       exception = ds->data;
02619 
02620    ast_string_field_set(exception, reason, reason);
02621    ast_string_field_set(exception, context, chan->context);
02622    ast_string_field_set(exception, exten, chan->exten);
02623    exception->priority = chan->priority;
02624    set_ext_pri(chan, "e", 0);
02625    return 0;
02626 }

int pbx_builtin_serialize_variables ( struct ast_channel chan,
struct ast_str **  buf 
)
Note:
Will lock the channel.

Definition at line 8337 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(), LOG_ERROR, total, var, and ast_channel::varshead.

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

08338 {
08339    struct ast_var_t *variables;
08340    const char *var, *val;
08341    int total = 0;
08342 
08343    if (!chan)
08344       return 0;
08345 
08346    (*buf)->used = 0;
08347    (*buf)->str[0] = '\0';
08348 
08349    ast_channel_lock(chan);
08350 
08351    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
08352       if ((var = ast_var_name(variables)) && (val = ast_var_value(variables))
08353          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
08354          ) {
08355          if (ast_str_append(buf, 0, "%s=%s\n", var, val) < 0) {
08356             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
08357             break;
08358          } else
08359             total++;
08360       } else
08361          break;
08362    }
08363 
08364    ast_channel_unlock(chan);
08365 
08366    return total;
08367 }

int pbx_builtin_setvar ( struct ast_channel chan,
void *  data 
)
Note:
Will lock the channel.

Definition at line 8498 of file pbx.c.

References ast_compat_app_set, ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, pbx_builtin_setvar_helper(), pbx_builtin_setvar_multiple(), and strsep().

Referenced by rpt_exec().

08499 {
08500    char *name, *value, *mydata;
08501 
08502    if (ast_compat_app_set) {
08503       return pbx_builtin_setvar_multiple(chan, data);
08504    }
08505 
08506    if (ast_strlen_zero(data)) {
08507       ast_log(LOG_WARNING, "Set requires one variable name/value pair.\n");
08508       return 0;
08509    }
08510 
08511    mydata = ast_strdupa(data);
08512    name = strsep(&mydata, "=");
08513    value = mydata;
08514    if (strchr(name, ' '))
08515       ast_log(LOG_WARNING, "Please avoid unnecessary spaces on variables as it may lead to unexpected results ('%s' set to '%s').\n", name, mydata);
08516 
08517    pbx_builtin_setvar_helper(chan, name, value);
08518    return(0);
08519 }

void pbx_builtin_setvar_helper ( struct ast_channel chan,
const char *  name,
const char *  value 
)
Note:
Will lock the channel.

Definition at line 8441 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, EVENT_FLAG_DIALPLAN, manager_event, and ast_channel::varshead.

Referenced by __ast_pbx_run(), __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(), disa_exec(), 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(), pri_dchannel(), privacy_exec(), 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(), sip_read(), skinny_new(), sla_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), ss7_start_call(), 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().

08442 {
08443    struct ast_var_t *newvariable;
08444    struct varshead *headp;
08445    const char *nametail = name;
08446 
08447    if (name[strlen(name) - 1] == ')') {
08448       char *function = ast_strdupa(name);
08449 
08450       ast_func_write(chan, function, value);
08451       return;
08452    }
08453 
08454    if (chan) {
08455       ast_channel_lock(chan);
08456       headp = &chan->varshead;
08457    } else {
08458       ast_rwlock_wrlock(&globalslock);
08459       headp = &globals;
08460    }
08461 
08462    /* For comparison purposes, we have to strip leading underscores */
08463    if (*nametail == '_') {
08464       nametail++;
08465       if (*nametail == '_')
08466          nametail++;
08467    }
08468 
08469    AST_LIST_TRAVERSE (headp, newvariable, entries) {
08470       if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
08471          /* there is already such a variable, delete it */
08472          AST_LIST_REMOVE(headp, newvariable, entries);
08473          ast_var_delete(newvariable);
08474          break;
08475       }
08476    }
08477 
08478    if (value) {
08479       if (headp == &globals)
08480          ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value);
08481       newvariable = ast_var_assign(name, value);
08482       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
08483       manager_event(EVENT_FLAG_DIALPLAN, "VarSet", 
08484          "Channel: %s\r\n"
08485          "Variable: %s\r\n"
08486          "Value: %s\r\n"
08487          "Uniqueid: %s\r\n", 
08488          chan ? chan->name : "none", name, value, 
08489          chan ? chan->uniqueid : "none");
08490    }
08491 
08492    if (chan)
08493       ast_channel_unlock(chan);
08494    else
08495       ast_rwlock_unlock(&globalslock);
08496 }

int pbx_builtin_setvar_multiple ( struct ast_channel chan,
void *  data 
)

Definition at line 8521 of file pbx.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_channel::context, ast_channel::exten, LOG_WARNING, pbx_builtin_setvar_helper(), and ast_channel::priority.

Referenced by pbx_builtin_setvar(), queue_function_var(), set_queue_variables(), and try_calling().

08522 {
08523    char *data;
08524    int x;
08525    AST_DECLARE_APP_ARGS(args,
08526       AST_APP_ARG(pair)[24];
08527    );
08528    AST_DECLARE_APP_ARGS(pair,
08529       AST_APP_ARG(name);
08530       AST_APP_ARG(value);
08531    );
08532 
08533    if (ast_strlen_zero(vdata)) {
08534       ast_log(LOG_WARNING, "MSet requires at least one variable name/value pair.\n");
08535       return 0;
08536    }
08537 
08538    data = ast_strdupa(vdata);
08539    AST_STANDARD_APP_ARGS(args, data);
08540 
08541    for (x = 0; x < args.argc; x++) {
08542       AST_NONSTANDARD_APP_ARGS(pair, args.pair[x], '=');
08543       if (pair.argc == 2) {
08544          pbx_builtin_setvar_helper(chan, pair.name, pair.value);
08545          if (strchr(pair.name, ' '))
08546             ast_log(LOG_WARNING, "Please avoid unnecessary spaces on variables as it may lead to unexpected results ('%s' set to '%s').\n", pair.name, pair.value);
08547       } else if (!chan) {
08548          ast_log(LOG_WARNING, "MSet: ignoring entry '%s' with no '='\n", pair.name);
08549       } else {
08550          ast_log(LOG_WARNING, "MSet: ignoring entry '%s' with no '=' (in %s@%s:%d\n", pair.name, chan->exten, chan->context, chan->priority);
08551       }
08552    }
08553 
08554    return 0;
08555 }

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

08610 {
08611    int res;
08612    if (ast_strlen_zero(condition)) {                /* NULL or empty strings are false */
08613       return 0;
08614    } else if (sscanf(condition, "%30d", &res) == 1) { /* Numbers are evaluated for truth */
08615       return res;
08616    } else {                                         /* Strings are true */
08617       return 1;
08618    }
08619 }

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

References __ast_module_user_add(), __ast_module_user_remove(), ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_log(), ast_opt_dont_warn, ast_strlen_zero(), ast_channel::cdr, ast_channel::data, ast_app::execute, LOG_WARNING, 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(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().

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

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 
) [read]

Definition at line 2068 of file pbx.c.

References 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, 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, 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, new_find_extension(), ast_include::next, scoreboard::node, 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(), 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().

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

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

Look up an application.

Parameters:
app name of the app

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

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

Definition at line 975 of file pbx.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, and AST_RWLIST_UNLOCK.

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

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

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:
Will lock the channel.
See also

Definition at line 2467 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, ast_channel::hangupcause, parse_variable_name(), ast_channel::priority, s, substring(), and ast_channel::varshead.

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

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

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

Referenced by pbx_load_module().

04110 {
04111    int oldval = autofallthrough;
04112    autofallthrough = newval;
04113    return oldval;
04114 }

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

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

04117 {
04118    int oldval = extenpatternmatchnew;
04119    extenpatternmatchnew = newval;
04120    return oldval;
04121 }

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

References ast_free, ast_strdup, and ast_strlen_zero().

Referenced by pbx_load_module().

04124 {
04125    if (overrideswitch) {
04126       ast_free(overrideswitch);
04127    }
04128    if (!ast_strlen_zero(newval)) {
04129       overrideswitch = ast_strdup(newval);
04130    } else {
04131       overrideswitch = NULL;
04132    }
04133 }

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 
)

Generated on 2 Mar 2010 for Asterisk - the Open Source PBX by  doxygen 1.6.1