Wed Mar 3 23:02:57 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 2795 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().

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

int ast_active_calls ( void   ) 

Retrieve the number of active calls.

Definition at line 4082 of file pbx.c.

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

04083 {
04084    return countcalls;
04085 }

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

06735 {
06736    int ret = -1;
06737    struct ast_context *c = find_context_locked(context);
06738 
06739    if (c) {
06740       ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
06741          application, data, datad, registrar);
06742       ast_unlock_contexts();
06743    }
06744    
06745    return ret;
06746 }

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

07054 {
07055    return ast_add_extension2_lockopt(con, replace, extension, priority, label, callerid, application, data, datad, registrar, 1, 1);
07056 }

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

Definition at line 6771 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(), and socket_process().

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

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

Definition at line 6824 of file pbx.c.

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

06825 {
06826    struct ast_channel *chan;
06827    int res = -1;
06828 
06829    chan = ast_get_channel_by_name_locked(channame);
06830    if (chan) {
06831       res = ast_async_goto(chan, context, exten, priority);
06832       ast_channel_unlock(chan);
06833    }
06834    return res;
06835 }

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

References __ast_goto_if_exists().

08960 {
08961    return __ast_goto_if_exists(chan, context, exten, priority, 1);
08962 }

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

References pbx_parseable_goto().

Referenced by asyncgoto_exec().

09023 {
09024    return pbx_parseable_goto(chan, goto_string, 1);
09025 }

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

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

06393 {
06394    char info_save[256];
06395    char *info;
06396 
06397    /* Check for empty just in case */
06398    if (ast_strlen_zero(info_in))
06399       return 0;
06400    /* make a copy just in case we were passed a static string */
06401    ast_copy_string(info_save, info_in, sizeof(info_save));
06402    info = info_save;
06403    /* Assume everything except time */
06404    i->monthmask = 0xfff;   /* 12 bits */
06405    i->daymask = 0x7fffffffU; /* 31 bits */
06406    i->dowmask = 0x7f; /* 7 bits */
06407    /* on each call, use strsep() to move info to the next argument */
06408    get_timerange(i, strsep(&info, "|,"));
06409    if (info)
06410       i->dowmask = get_range(strsep(&info, "|,"), 7, days, "day of week");
06411    if (info)
06412       i->daymask = get_range(strsep(&info, "|,"), 31, NULL, "day");
06413    if (info)
06414       i->monthmask = get_range(strsep(&info, "|,"), 12, months, "month");
06415    return 1;
06416 }

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 3644 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(), phone_check_exception(), pri_dchannel(), skinny_ss(), ss_thread(), and valid_exit().

03645 {
03646    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0, 0);
03647 }

int ast_check_timing ( const struct ast_timing i  ) 

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

06419 {
06420    struct ast_tm tm;
06421    struct timeval now = ast_tvnow();
06422 
06423    ast_localtime(&now, &tm, NULL);
06424 
06425    /* If it's not the right month, return */
06426    if (!(i->monthmask & (1 << tm.tm_mon)))
06427       return 0;
06428 
06429    /* If it's not that time of the month.... */
06430    /* Warning, tm_mday has range 1..31! */
06431    if (!(i->daymask & (1 << (tm.tm_mday-1))))
06432       return 0;
06433 
06434    /* If it's not the right day of the week */
06435    if (!(i->dowmask & (1 << tm.tm_wday)))
06436       return 0;
06437 
06438    /* Sanity check the hour just to be safe */
06439    if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
06440       ast_log(LOG_WARNING, "Insane time...\n");
06441       return 0;
06442    }
06443 
06444    /* Now the tough part, we calculate if it fits
06445       in the right time based on min/hour */
06446    if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
06447       return 0;
06448 
06449    /* If we got this far, then we're good */
06450    return 1;
06451 }

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

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

Referenced by handle_cli_dialplan_add_ignorepat().

06645 {
06646    int ret = -1;
06647    struct ast_context *c = find_context_locked(context);
06648 
06649    if (c) {
06650       ret = ast_context_add_ignorepat2(c, value, registrar);
06651       ast_unlock_contexts();
06652    }
06653    return ret;
06654 }

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

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

06657 {
06658    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
06659    int length;
06660    char *pattern;
06661    length = sizeof(struct ast_ignorepat);
06662    length += strlen(value) + 1;
06663    if (!(ignorepat = ast_calloc(1, length)))
06664       return -1;
06665    /* The cast to char * is because we need to write the initial value.
06666     * The field is not supposed to be modified otherwise.  Also, gcc 4.2
06667     * sees the cast as dereferencing a type-punned pointer and warns about
06668     * it.  This is the workaround (we're telling gcc, yes, that's really
06669     * what we wanted to do).
06670     */
06671    pattern = (char *) ignorepat->pattern;
06672    strcpy(pattern, value);
06673    ignorepat->next = NULL;
06674    ignorepat->registrar = registrar;
06675    ast_wrlock_context(con);
06676    for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
06677       ignorepatl = ignorepatc;
06678       if (!strcasecmp(ignorepatc->pattern, value)) {
06679          /* Already there */
06680          ast_unlock_context(con);
06681          errno = EEXIST;
06682          return -1;
06683       }
06684    }
06685    if (ignorepatl)
06686       ignorepatl->next = ignorepat;
06687    else
06688       con->ignorepats = ignorepat;
06689    ast_unlock_context(con);
06690    return 0;
06691 
06692 }

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

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

Referenced by handle_cli_dialplan_add_include().

06199 {
06200    int ret = -1;
06201    struct ast_context *c = find_context_locked(context);
06202 
06203    if (c) {
06204       ret = ast_context_add_include2(c, include, registrar);
06205       ast_unlock_contexts();
06206    }
06207    return ret;
06208 }

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

06462 {
06463    struct ast_include *new_include;
06464    char *c;
06465    struct ast_include *i, *il = NULL; /* include, include_last */
06466    int length;
06467    char *p;
06468 
06469    length = sizeof(struct ast_include);
06470    length += 2 * (strlen(value) + 1);
06471 
06472    /* allocate new include structure ... */
06473    if (!(new_include = ast_calloc(1, length)))
06474       return -1;
06475    /* Fill in this structure. Use 'p' for assignments, as the fields
06476     * in the structure are 'const char *'
06477     */
06478    p = new_include->stuff;
06479    new_include->name = p;
06480    strcpy(p, value);
06481    p += strlen(value) + 1;
06482    new_include->rname = p;
06483    strcpy(p, value);
06484    /* Strip off timing info, and process if it is there */
06485    if ( (c = strchr(p, ',')) ) {
06486       *c++ = '\0';
06487            new_include->hastime = ast_build_timing(&(new_include->timing), c);
06488    }
06489    new_include->next      = NULL;
06490    new_include->registrar = registrar;
06491 
06492    ast_wrlock_context(con);
06493 
06494    /* ... go to last include and check if context is already included too... */
06495    for (i = con->includes; i; i = i->next) {
06496       if (!strcasecmp(i->name, new_include->name)) {
06497          ast_free(new_include);
06498          ast_unlock_context(con);
06499          errno = EEXIST;
06500          return -1;
06501       }
06502       il = i;
06503    }
06504 
06505    /* ... include new context into context list, unlock, return */
06506    if (il)
06507       il->next = new_include;
06508    else
06509       con->includes = new_include;
06510    ast_verb(3, "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
06511 
06512    ast_unlock_context(con);
06513 
06514    return 0;
06515 }

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

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

06523 {
06524    int ret = -1;
06525    struct ast_context *c = find_context_locked(context);
06526 
06527    if (c) { /* found, add switch to this context */
06528       ret = ast_context_add_switch2(c, sw, data, eval, registrar);
06529       ast_unlock_contexts();
06530    }
06531    return ret;
06532 }

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

06543 {
06544    struct ast_sw *new_sw;
06545    struct ast_sw *i;
06546    int length;
06547    char *p;
06548 
06549    length = sizeof(struct ast_sw);
06550    length += strlen(value) + 1;
06551    if (data)
06552       length += strlen(data);
06553    length++;
06554 
06555    /* allocate new sw structure ... */
06556    if (!(new_sw = ast_calloc(1, length)))
06557       return -1;
06558    /* ... fill in this structure ... */
06559    p = new_sw->stuff;
06560    new_sw->name = p;
06561    strcpy(new_sw->name, value);
06562    p += strlen(value) + 1;
06563    new_sw->data = p;
06564    if (data) {
06565       strcpy(new_sw->data, data);
06566       p += strlen(data) + 1;
06567    } else {
06568       strcpy(new_sw->data, "");
06569       p++;
06570    }
06571    new_sw->eval     = eval;
06572    new_sw->registrar = registrar;
06573 
06574    /* ... try to lock this context ... */
06575    ast_wrlock_context(con);
06576 
06577    /* ... go to last sw and check if context is already swd too... */
06578    AST_LIST_TRAVERSE(&con->alts, i, list) {
06579       if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
06580          ast_free(new_sw);
06581          ast_unlock_context(con);
06582          errno = EEXIST;
06583          return -1;
06584       }
06585    }
06586 
06587    /* ... sw new context into context list, unlock, return */
06588    AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
06589 
06590    ast_verb(3, "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
06591 
06592    ast_unlock_context(con);
06593 
06594    return 0;
06595 }

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 7839 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 2015 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().

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

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

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

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

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

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

References ast_context_remove_extension_callerid().

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

04277 {
04278    return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar);
04279 }

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

References ast_context_remove_extension_callerid2().

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

04304 {
04305    return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar, already_locked);
04306 }

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

04282 {
04283    int ret = -1; /* default error return */
04284    struct ast_context *c = find_context_locked(context);
04285 
04286    if (c) { /* ... remove extension ... */
04287       ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcallerid, registrar, 1);
04288       ast_unlock_contexts();
04289    }
04290    return ret;
04291 }

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

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

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

Definition at line 6601 of file pbx.c.

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

Referenced by handle_cli_dialplan_remove_ignorepat().

06602 {
06603    int ret = -1;
06604    struct ast_context *c = find_context_locked(context);
06605 
06606    if (c) {
06607       ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
06608       ast_unlock_contexts();
06609    }
06610    return ret;
06611 }

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

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

06614 {
06615    struct ast_ignorepat *ip, *ipl = NULL;
06616 
06617    ast_wrlock_context(con);
06618 
06619    for (ip = con->ignorepats; ip; ip = ip->next) {
06620       if (!strcmp(ip->pattern, ignorepat) &&
06621          (!registrar || (registrar == ip->registrar))) {
06622          if (ipl) {
06623             ipl->next = ip->next;
06624             ast_free(ip);
06625          } else {
06626             con->ignorepats = ip->next;
06627             ast_free(ip);
06628          }
06629          ast_unlock_context(con);
06630          return 0;
06631       }
06632       ipl = ip;
06633    }
06634 
06635    ast_unlock_context(con);
06636    errno = EINVAL;
06637    return -1;
06638 }

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

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

Referenced by handle_cli_dialplan_remove_include().

04169 {
04170    int ret = -1;
04171    struct ast_context *c = find_context_locked(context);
04172 
04173    if (c) {
04174       /* found, remove include from this context ... */
04175       ret = ast_context_remove_include2(c, include, registrar);
04176       ast_unlock_contexts();
04177    }
04178    return ret;
04179 }

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

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

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

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

04225 {
04226    int ret = -1; /* default error return */
04227    struct ast_context *c = find_context_locked(context);
04228 
04229    if (c) {
04230       /* remove switch from this context ... */
04231       ret = ast_context_remove_switch2(c, sw, data, registrar);
04232       ast_unlock_contexts();
04233    }
04234    return ret;
04235 }

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

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

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

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

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

08917 {
08918    struct ast_include *inc = NULL;
08919    int res = 0;
08920 
08921    while ( (inc = ast_walk_context_includes(con, inc)) ) {
08922       if (ast_context_find(inc->rname))
08923          continue;
08924 
08925       res = -1;
08926       ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n",
08927          ast_get_context_name(con), inc->rname);
08928       break;
08929    }
08930 
08931    return res;
08932 }

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

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

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

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

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

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

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

03260 {
03261    switch (devstate) {
03262    case AST_DEVICE_ONHOLD:
03263       return AST_EXTENSION_ONHOLD;
03264    case AST_DEVICE_BUSY:
03265       return AST_EXTENSION_BUSY;
03266    case AST_DEVICE_UNAVAILABLE:
03267    case AST_DEVICE_UNKNOWN:
03268    case AST_DEVICE_INVALID:
03269       return AST_EXTENSION_UNAVAILABLE;
03270    case AST_DEVICE_RINGINUSE:
03271       return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING);
03272    case AST_DEVICE_RINGING:
03273       return AST_EXTENSION_RINGING;
03274    case AST_DEVICE_INUSE:
03275       return AST_EXTENSION_INUSE;
03276    case AST_DEVICE_NOT_INUSE:
03277       return AST_EXTENSION_NOT_INUSE;
03278    case AST_DEVICE_TOTAL: /* not a device state, included for completeness */
03279       break;
03280    }
03281 
03282    return AST_EXTENSION_NOT_INUSE;
03283 }

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

References E_MATCH, and pbx_extension_helper().

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

03630 {
03631    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0, 0);
03632 }

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

06749 {
06750    if (!chan)
06751       return -1;
06752 
06753    ast_channel_lock(chan);
06754 
06755    if (!ast_strlen_zero(context))
06756       ast_copy_string(chan->context, context, sizeof(chan->context));
06757    if (!ast_strlen_zero(exten))
06758       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
06759    if (priority > -1) {
06760       chan->priority = priority;
06761       /* see flag description in channel.h for explanation */
06762       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
06763          chan->priority--;
06764    }
06765 
06766    ast_channel_unlock(chan);
06767 
06768    return 0;
06769 }

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

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

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

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

References ext_cmp().

Referenced by lua_extension_cmp().

01795 {
01796    return ext_cmp(a, b);
01797 }

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

01988 {
01989    return extension_match_core(pattern, data, E_MATCH);
01990 }

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

References ast_extension_state2(), and ast_hint_extension().

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

03322 {
03323    struct ast_exten *e;
03324 
03325    e = ast_hint_extension(c, context, exten);   /* Do we have a hint for this extension ? */
03326    if (!e)
03327       return -1;           /* No hint, return -1 */
03328 
03329    return ast_extension_state2(e);        /* Check all devices in the hint */
03330 }

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

03310 {
03311    int i;
03312 
03313    for (i = 0; (i < ARRAY_LEN(extension_states)); i++) {
03314       if (extension_states[i].extension_state == extension_state)
03315          return extension_states[i].text;
03316    }
03317    return "Unknown";
03318 }

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

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

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

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

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

03635 {
03636    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
03637 }

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

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

03640 {
03641    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
03642 }

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

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

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

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

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

Definition at line 8806 of file pbx.c.

References ast_context::registrar.

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

08807 {
08808    return c ? c->registrar : NULL;
08809 }

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

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

08842 {
08843    return e ? e->data : NULL;
08844 }

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 8831 of file pbx.c.

References ast_exten::cidmatch.

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

08832 {
08833    return e ? e->cidmatch : NULL;
08834 }

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

Definition at line 8773 of file pbx.c.

References ast_exten::parent.

Referenced by handle_show_hint(), and handle_show_hints().

08774 {
08775    return exten ? exten->parent : NULL;
08776 }

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 8783 of file pbx.c.

References ast_exten::label.

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

08784 {
08785    return exten ? exten->label : NULL;
08786 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 8826 of file pbx.c.

References ast_exten::matchcid.

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

08827 {
08828    return e ? e->matchcid : 0;
08829 }

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

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

08799 {
08800    return exten ? exten->priority : -1;
08801 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 8811 of file pbx.c.

References ast_exten::registrar.

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

08812 {
08813    return e ? e->registrar : NULL;
08814 }

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

03613 {
03614    struct ast_exten *e = ast_hint_extension(c, context, exten);
03615 
03616    if (e) {
03617       if (hint)
03618          ast_copy_string(hint, ast_get_extension_app(e), hintsize);
03619       if (name) {
03620          const char *tmp = ast_get_extension_app_data(e);
03621          if (tmp)
03622             ast_copy_string(name, tmp, namesize);
03623       }
03624       return -1;
03625    }
03626    return 0;
03627 }

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

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

08822 {
08823    return ip ? ip->registrar : NULL;
08824 }

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

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

08817 {
08818    return i ? i->registrar : NULL;
08819 }

const char* ast_get_switch_data ( struct ast_sw sw  ) 

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

08852 {
08853    return sw ? sw->data : NULL;
08854 }

int ast_get_switch_eval ( struct ast_sw sw  ) 

Definition at line 8856 of file pbx.c.

References ast_sw::eval.

Referenced by context_merge_incls_swits_igps_other_registrars().

08857 {
08858    return sw->eval;
08859 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

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

08847 {
08848    return sw ? sw->name : NULL;
08849 }

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

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

08862 {
08863    return sw ? sw->registrar : NULL;
08864 }

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

08955 {
08956    return __ast_goto_if_exists(chan, context, exten, priority, 0);
08957 }

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

06695 {
06696    struct ast_context *con = ast_context_find(context);
06697    if (con) {
06698       struct ast_ignorepat *pat;
06699       for (pat = con->ignorepats; pat; pat = pat->next) {
06700          if (ast_extension_match(pat->pattern, pattern))
06701             return 1;
06702       }
06703    }
06704 
06705    return 0;
06706 }

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

03650 {
03651    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0);
03652 }

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 6054 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_context::registrar, and pbx_find_info::stacklen.

Referenced by lua_reload_extensions(), and pbx_load_module().

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

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

09018 {
09019    return pbx_parseable_goto(chan, goto_string, 0);
09020 }

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

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

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

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

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

04078 {
04079    return ast_pbx_run_args(c, NULL);
04080 }

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

04063 {
04064    enum ast_pbx_result res = AST_PBX_SUCCESS;
04065 
04066    if (increase_call_count(c)) {
04067       return AST_PBX_CALL_LIMIT;
04068    }
04069 
04070    res = __ast_pbx_run(c, args);
04071 
04072    decrease_call_count();
04073 
04074    return res;
04075 }

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

04041 {
04042    pthread_t t;
04043 
04044    if (!c) {
04045       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
04046       return AST_PBX_FAILED;
04047    }
04048 
04049    if (increase_call_count(c))
04050       return AST_PBX_CALL_LIMIT;
04051 
04052    /* Start a new thread, and get something handling this channel. */
04053    if (ast_pthread_create_detached(&t, NULL, pbx_thread, c)) {
04054       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
04055       decrease_call_count();
04056       return AST_PBX_FAILED;
04057    }
04058 
04059    return AST_PBX_SUCCESS;
04060 }

int ast_processed_calls ( void   ) 

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

Definition at line 4087 of file pbx.c.

Referenced by handle_chanlist(), and handle_showcalls().

04088 {
04089    return totalcalls;
04090 }

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

08756 {
08757    return ast_rwlock_rdlock(&con->lock);
08758 }

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

04593 {
04594    struct ast_switch *tmp;
04595 
04596    AST_RWLIST_WRLOCK(&switches);
04597    AST_RWLIST_TRAVERSE(&switches, tmp, list) {
04598       if (!strcasecmp(tmp->name, sw->name)) {
04599          AST_RWLIST_UNLOCK(&switches);
04600          ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
04601          return -1;
04602       }
04603    }
04604    AST_RWLIST_INSERT_TAIL(&switches, sw, list);
04605    AST_RWLIST_UNLOCK(&switches);
04606 
04607    return 0;
04608 }

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

03655 {
03656    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn);
03657 }

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

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

Referenced by __unload_module(), and unload_module().

04611 {
04612    AST_RWLIST_WRLOCK(&switches);
04613    AST_RWLIST_REMOVE(&switches, sw, list);
04614    AST_RWLIST_UNLOCK(&switches);
04615 }

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

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

08876 {
08877    if (!exten)
08878       return con ? con->root : NULL;
08879    else
08880       return exten->next;
08881 }

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

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

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

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

08885 {
08886    if (!sw)
08887       return con ? AST_LIST_FIRST(&con->alts) : NULL;
08888    else
08889       return AST_LIST_NEXT(sw, list);
08890 }

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

08751 {
08752    return ast_rwlock_wrlock(&con->lock);
08753 }

int ast_wrlock_contexts ( void   ) 

Write locks the context list.

Return values:
0 on success
-1 on error

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

08730 {
08731    int res = ast_rwlock_wrlock(&conlock);
08732    if (!res)
08733       ast_atomic_fetchadd_int(&conlock_wrlock_version, 1);
08734    return res;
08735 }

int ast_wrlock_contexts_version ( void   ) 

Definition at line 8721 of file pbx.c.

References conlock_wrlock_version.

Referenced by ast_merge_contexts_and_delete().

08722 {
08723    return conlock_wrlock_version;
08724 }

void pbx_builtin_clear_globals ( void   ) 

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

08567 {
08568    struct ast_var_t *vardata;
08569 
08570    ast_rwlock_wrlock(&globalslock);
08571    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
08572       ast_var_delete(vardata);
08573    ast_rwlock_unlock(&globalslock);
08574 }

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

08337 {
08338    struct ast_var_t *variables;
08339    const char *ret = NULL;
08340    int i;
08341    struct varshead *places[2] = { NULL, &globals };
08342 
08343    if (!name)
08344       return NULL;
08345 
08346    if (chan) {
08347       ast_channel_lock(chan);
08348       places[0] = &chan->varshead;
08349    }
08350 
08351    for (i = 0; i < 2; i++) {
08352       if (!places[i])
08353          continue;
08354       if (places[i] == &globals)
08355          ast_rwlock_rdlock(&globalslock);
08356       AST_LIST_TRAVERSE(places[i], variables, entries) {
08357          if (!strcmp(name, ast_var_name(variables))) {
08358             ret = ast_var_value(variables);
08359             break;
08360          }
08361       }
08362       if (places[i] == &globals)
08363          ast_rwlock_unlock(&globalslock);
08364       if (ret)
08365          break;
08366    }
08367 
08368    if (chan)
08369       ast_channel_unlock(chan);
08370 
08371    return ret;
08372 }

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

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

08375 {
08376    struct ast_var_t *newvariable;
08377    struct varshead *headp;
08378 
08379    if (name[strlen(name)-1] == ')') {
08380       char *function = ast_strdupa(name);
08381 
08382       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
08383       ast_func_write(chan, function, value);
08384       return;
08385    }
08386 
08387    if (chan) {
08388       ast_channel_lock(chan);
08389       headp = &chan->varshead;
08390    } else {
08391       ast_rwlock_wrlock(&globalslock);
08392       headp = &globals;
08393    }
08394 
08395    if (value) {
08396       if (headp == &globals)
08397          ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value);
08398       newvariable = ast_var_assign(name, value);
08399       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
08400    }
08401 
08402    if (chan)
08403       ast_channel_unlock(chan);
08404    else
08405       ast_rwlock_unlock(&globalslock);
08406 }

int pbx_builtin_raise_exception ( struct ast_channel chan,
void *  data 
)

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

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

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

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

08305 {
08306    struct ast_var_t *variables;
08307    const char *var, *val;
08308    int total = 0;
08309 
08310    if (!chan)
08311       return 0;
08312 
08313    (*buf)->used = 0;
08314    (*buf)->str[0] = '\0';
08315 
08316    ast_channel_lock(chan);
08317 
08318    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
08319       if ((var = ast_var_name(variables)) && (val = ast_var_value(variables))
08320          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
08321          ) {
08322          if (ast_str_append(buf, 0, "%s=%s\n", var, val) < 0) {
08323             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
08324             break;
08325          } else
08326             total++;
08327       } else
08328          break;
08329    }
08330 
08331    ast_channel_unlock(chan);
08332 
08333    return total;
08334 }

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

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

08466 {
08467    char *name, *value, *mydata;
08468 
08469    if (ast_compat_app_set) {
08470       return pbx_builtin_setvar_multiple(chan, data);
08471    }
08472 
08473    if (ast_strlen_zero(data)) {
08474       ast_log(LOG_WARNING, "Set requires one variable name/value pair.\n");
08475       return 0;
08476    }
08477 
08478    mydata = ast_strdupa(data);
08479    name = strsep(&mydata, "=");
08480    value = mydata;
08481    if (strchr(name, ' '))
08482       ast_log(LOG_WARNING, "Please avoid unnecessary spaces on variables as it may lead to unexpected results ('%s' set to '%s').\n", name, mydata);
08483 
08484    pbx_builtin_setvar_helper(chan, name, value);
08485    return(0);
08486 }

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

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

08409 {
08410    struct ast_var_t *newvariable;
08411    struct varshead *headp;
08412    const char *nametail = name;
08413 
08414    if (name[strlen(name) - 1] == ')') {
08415       char *function = ast_strdupa(name);
08416 
08417       ast_func_write(chan, function, value);
08418       return;
08419    }
08420 
08421    if (chan) {
08422       ast_channel_lock(chan);
08423       headp = &chan->varshead;
08424    } else {
08425       ast_rwlock_wrlock(&globalslock);
08426       headp = &globals;
08427    }
08428 
08429    /* For comparison purposes, we have to strip leading underscores */
08430    if (*nametail == '_') {
08431       nametail++;
08432       if (*nametail == '_')
08433          nametail++;
08434    }
08435 
08436    AST_LIST_TRAVERSE (headp, newvariable, entries) {
08437       if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
08438          /* there is already such a variable, delete it */
08439          AST_LIST_REMOVE(headp, newvariable, entries);
08440          ast_var_delete(newvariable);
08441          break;
08442       }
08443    }
08444 
08445    if (value) {
08446       if (headp == &globals)
08447          ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value);
08448       newvariable = ast_var_assign(name, value);
08449       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
08450       manager_event(EVENT_FLAG_DIALPLAN, "VarSet", 
08451          "Channel: %s\r\n"
08452          "Variable: %s\r\n"
08453          "Value: %s\r\n"
08454          "Uniqueid: %s\r\n", 
08455          chan ? chan->name : "none", name, value, 
08456          chan ? chan->uniqueid : "none");
08457    }
08458 
08459    if (chan)
08460       ast_channel_unlock(chan);
08461    else
08462       ast_rwlock_unlock(&globalslock);
08463 }

int pbx_builtin_setvar_multiple ( struct ast_channel chan,
void *  data 
)

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

08489 {
08490    char *data;
08491    int x;
08492    AST_DECLARE_APP_ARGS(args,
08493       AST_APP_ARG(pair)[24];
08494    );
08495    AST_DECLARE_APP_ARGS(pair,
08496       AST_APP_ARG(name);
08497       AST_APP_ARG(value);
08498    );
08499 
08500    if (ast_strlen_zero(vdata)) {
08501       ast_log(LOG_WARNING, "MSet requires at least one variable name/value pair.\n");
08502       return 0;
08503    }
08504 
08505    data = ast_strdupa(vdata);
08506    AST_STANDARD_APP_ARGS(args, data);
08507 
08508    for (x = 0; x < args.argc; x++) {
08509       AST_NONSTANDARD_APP_ARGS(pair, args.pair[x], '=');
08510       if (pair.argc == 2) {
08511          pbx_builtin_setvar_helper(chan, pair.name, pair.value);
08512          if (strchr(pair.name, ' '))
08513             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);
08514       } else if (!chan) {
08515          ast_log(LOG_WARNING, "MSet: ignoring entry '%s' with no '='\n", pair.name);
08516       } else {
08517          ast_log(LOG_WARNING, "MSet: ignoring entry '%s' with no '=' (in %s@%s:%d\n", pair.name, chan->exten, chan->context, chan->priority);
08518       }
08519    }
08520 
08521    return 0;
08522 }

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

08577 {
08578    int res;
08579    if (ast_strlen_zero(condition)) {                /* NULL or empty strings are false */
08580       return 0;
08581    } else if (sscanf(condition, "%30d", &res) == 1) { /* Numbers are evaluated for truth */
08582       return res;
08583    } else {                                         /* Strings are true */
08584       return 1;
08585    }
08586 }

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_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, ',')) {
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 2052 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().

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

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

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

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

Referenced by pbx_load_module().

04093 {
04094    int oldval = autofallthrough;
04095    autofallthrough = newval;
04096    return oldval;
04097 }

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

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

04100 {
04101    int oldval = extenpatternmatchnew;
04102    extenpatternmatchnew = newval;
04103    return oldval;
04104 }

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

References ast_free, ast_strdup, and ast_strlen_zero().

Referenced by pbx_load_module().

04107 {
04108    if (overrideswitch) {
04109       ast_free(overrideswitch);
04110    }
04111    if (!ast_strlen_zero(newval)) {
04112       overrideswitch = ast_strdup(newval);
04113    } else {
04114       overrideswitch = NULL;
04115    }
04116 }

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 3 Mar 2010 for Asterisk - the Open Source PBX by  doxygen 1.6.1