Wed Aug 18 22:34:28 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"

Go to the source code of this file.

Data Structures

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

const char * ast_get_context_name (struct ast_context *con)
ast_contextast_get_extension_context (struct ast_exten *exten)
const char * ast_get_extension_name (struct ast_exten *exten)
const char * ast_get_ignorepat_name (struct ast_ignorepat *ip)
const char * ast_get_include_name (struct ast_include *include)
const char * ast_get_switch_data (struct ast_sw *sw)
int ast_get_switch_eval (struct ast_sw *sw)
const char * ast_get_switch_name (struct ast_sw *sw)

Registrar info functions ...

const char * ast_get_context_registrar (struct ast_context *c)
const char * ast_get_extension_registrar (struct ast_exten *e)
const char * ast_get_ignorepat_registrar (struct ast_ignorepat *ip)
const char * ast_get_include_registrar (struct ast_include *i)
const char * ast_get_switch_registrar (struct ast_sw *sw)

Other Extension stuff

const char * ast_get_extension_app (struct ast_exten *e)
void * ast_get_extension_app_data (struct ast_exten *e)
const char * ast_get_extension_cidmatch (struct ast_exten *e)
const char * ast_get_extension_label (struct ast_exten *e)
int ast_get_extension_matchcid (struct ast_exten *e)
int ast_get_extension_priority (struct ast_exten *exten)

Defines

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

Typedefs

typedef int(*) ast_state_cb_type (char *context, char *id, enum ast_extension_states state, void *data)
 Typedef for devicestate and hint callbacks.
typedef int( ast_switch_f )(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 All switch functions have the same interface, so define a type for them.

Enumerations

enum  ast_extension_states {
  AST_EXTENSION_REMOVED = -2, AST_EXTENSION_DEACTIVATED = -1, AST_EXTENSION_NOT_INUSE = 0, AST_EXTENSION_INUSE = 1 << 0,
  AST_EXTENSION_BUSY = 1 << 1, AST_EXTENSION_UNAVAILABLE = 1 << 2, AST_EXTENSION_RINGING = 1 << 3, AST_EXTENSION_ONHOLD = 1 << 4
}
 Extension states. More...
enum  ast_pbx_result { AST_PBX_SUCCESS = 0, AST_PBX_FAILED = -1, AST_PBX_CALL_LIMIT = -2 }
 The result codes when starting the PBX on a channelwith. More...
enum  ext_match_t {
  E_MATCHMORE = 0x00, E_CANMATCH = 0x01, E_MATCH = 0x02, E_MATCH_MASK = 0x03,
  E_SPAWN = 0x12, E_FINDLABEL = 0x22
}

Functions

int __ast_custom_function_register (struct ast_custom_function *acf, struct ast_module *mod)
 Register a custom function.
int ast_active_calls (void)
 Retrieve the number of active calls.
int ast_add_extension (const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 Add and extension to an extension context.
int ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 Add an extension to an extension context, this time with an ast_context *.
int ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_async_goto_by_name (const char *chan, const char *context, const char *exten, int priority)
int ast_async_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_async_parseable_goto (struct ast_channel *chan, const char *goto_string)
int ast_build_timing (struct ast_timing *i, const char *info)
int ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Looks for a valid matching extension.
int ast_check_timing (const struct ast_timing *i)
int ast_context_add_ignorepat (const char *context, const char *ignorepat, const char *registrar)
 Add an ignorepat.
int ast_context_add_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar)
int ast_context_add_include (const char *context, const char *include, const char *registrar)
 Add a context include.
int ast_context_add_include2 (struct ast_context *con, const char *include, const char *registrar)
 Add a context include.
int ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar)
 Add a switch.
int ast_context_add_switch2 (struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar)
 Adds a switch (first param is a ast_context).
void ast_context_destroy (struct ast_context *con, const char *registrar)
 Destroy a context (matches the specified context (or ANY context if NULL).
ast_contextast_context_find (const char *name)
 Find a context.
ast_contextast_context_find_or_create (struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
 Register a new context or find an existing one.
int ast_context_lockmacro (const char *macrocontext)
 locks the macrolock in the given given context
int ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar)
 Simply remove extension from context.
int ast_context_remove_extension2 (struct ast_context *con, const char *extension, int priority, const char *registrar, int already_locked)
 This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return.
int ast_context_remove_extension_callerid (const char *context, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar)
int ast_context_remove_extension_callerid2 (struct ast_context *con, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar, int already_locked)
int ast_context_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar)
int ast_context_remove_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar)
int ast_context_remove_include (const char *context, const char *include, const char *registrar)
 Remove a context include.
int ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar)
 Removes an include by an ast_context structure.
int ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar)
 Remove a switch.
int ast_context_remove_switch2 (struct ast_context *con, const char *sw, const char *data, const char *registrar)
 This function locks given context, removes switch, unlock context and return.
int ast_context_unlockmacro (const char *macrocontext)
 Unlocks the macrolock in the given context.
int ast_context_verify_includes (struct ast_context *con)
 Verifies includes in an ast_contect structure.
ast_custom_functionast_custom_function_find (const char *name)
int ast_custom_function_unregister (struct ast_custom_function *acf)
 Unregister a custom function.
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.
ast_extenast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority)
ast_ignorepatast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip)
ast_includeast_walk_context_includes (struct ast_context *con, struct ast_include *inc)
ast_swast_walk_context_switches (struct ast_context *con, struct ast_sw *sw)
ast_contextast_walk_contexts (struct ast_context *con)
ast_extenast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority)
int ast_wrlock_context (struct ast_context *con)
 Write locks a given context.
int ast_wrlock_contexts (void)
 Write locks the context list.
int ast_wrlock_contexts_version (void)
void pbx_builtin_clear_globals (void)
const char * pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name)
void pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value)
int pbx_builtin_raise_exception (struct ast_channel *chan, void *data)
int pbx_builtin_serialize_variables (struct ast_channel *chan, struct ast_str **buf)
int pbx_builtin_setvar (struct ast_channel *chan, void *data)
void pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value)
int pbx_builtin_setvar_multiple (struct ast_channel *chan, void *data)
int pbx_checkcondition (const char *condition)
 Evaluate a condition.
int pbx_exec (struct ast_channel *c, struct ast_app *app, void *data)
 Execute an application.
ast_extenpbx_find_extension (struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
ast_apppbx_findapp (const char *app)
 Look up an application.
void pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
 Support for Asterisk built-in variables in the dialplan.
int pbx_set_autofallthrough (int newval)
int pbx_set_extenpatternmatchnew (int newval)
void pbx_set_overrideswitch (const char *newval)
void pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count)
void pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count)


Detailed Description

Core PBX routines and definitions.

Definition in file pbx.h.


Define Documentation

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

Register a custom function.

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

#define AST_PBX_ERROR   1

Jump to the 'e' exten

Definition at line 43 of file pbx.h.

#define AST_PBX_HANGUP   -1

Special return values from applications to the PBX {.

Jump to the 'h' exten

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

} Special Priority for a hint

Definition at line 47 of file pbx.h.

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

#define STATUS_NO_CONTEXT   1

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

enum ast_extension_states

Extension states.

Note:
States can be combined
Enumerator:
AST_EXTENSION_REMOVED  Extension removed
AST_EXTENSION_DEACTIVATED  Extension hint removed
AST_EXTENSION_NOT_INUSE  No device INUSE or BUSY
AST_EXTENSION_INUSE  One or more devices INUSE
AST_EXTENSION_BUSY  All devices BUSY
AST_EXTENSION_UNAVAILABLE  All devices UNAVAILABLE/UNREGISTERED
AST_EXTENSION_RINGING  All devices RINGING
AST_EXTENSION_ONHOLD  All devices ONHOLD

Definition at line 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 };

enum ast_pbx_result

The result codes when starting the PBX on a channelwith.

See also:
ast_pbx_start. AST_PBX_CALL_LIMIT refers to the maxcalls call limit in asterisk.conf
Enumerator:
AST_PBX_SUCCESS 
AST_PBX_FAILED 
AST_PBX_CALL_LIMIT 

Definition at line 229 of file pbx.h.

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

enum ext_match_t

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

Enumerator:
E_MATCHMORE 
E_CANMATCH 
E_MATCH 
E_MATCH_MASK 
E_SPAWN 
E_FINDLABEL 

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

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

int ast_active_calls ( void   ) 

Retrieve the number of active calls.

Definition at line 4108 of file pbx.c.

References countcalls.

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

04109 {
04110    return countcalls;
04111 }

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

06762 {
06763    int ret = -1;
06764    struct ast_context *c = find_context_locked(context);
06765 
06766    if (c) {
06767       ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
06768          application, data, datad, registrar);
06769       ast_unlock_contexts();
06770    }
06771    
06772    return ret;
06773 }

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

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

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

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

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

Definition at line 7077 of file pbx.c.

References ast_add_extension2_lockopt().

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

07081 {
07082    return ast_add_extension2_lockopt(con, replace, extension, priority, label, callerid, application, data, datad, registrar, 1, 1);
07083 }

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

Definition at line 6798 of file pbx.c.

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

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

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

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

Definition at line 6851 of file pbx.c.

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

06852 {
06853    struct ast_channel *chan;
06854    int res = -1;
06855 
06856    chan = ast_get_channel_by_name_locked(channame);
06857    if (chan) {
06858       res = ast_async_goto(chan, context, exten, priority);
06859       ast_channel_unlock(chan);
06860    }
06861    return res;
06862 }

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

References __ast_goto_if_exists(), and chan.

09005 {
09006    return __ast_goto_if_exists(chan, context, exten, priority, 1);
09007 }

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

References chan, and pbx_parseable_goto().

Referenced by asyncgoto_exec().

09068 {
09069    return pbx_parseable_goto(chan, goto_string, 1);
09070 }

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

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

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

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

References E_CANMATCH, and pbx_extension_helper().

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

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

int ast_check_timing ( const struct ast_timing i  ) 

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

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

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

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

Referenced by handle_cli_dialplan_add_ignorepat().

06672 {
06673    int ret = -1;
06674    struct ast_context *c = find_context_locked(context);
06675 
06676    if (c) {
06677       ret = ast_context_add_ignorepat2(c, value, registrar);
06678       ast_unlock_contexts();
06679    }
06680    return ret;
06681 }

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

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

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

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

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

Referenced by handle_cli_dialplan_add_include().

06226 {
06227    int ret = -1;
06228    struct ast_context *c = find_context_locked(context);
06229 
06230    if (c) {
06231       ret = ast_context_add_include2(c, include, registrar);
06232       ast_unlock_contexts();
06233    }
06234    return ret;
06235 }

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

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

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

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

06550 {
06551    int ret = -1;
06552    struct ast_context *c = find_context_locked(context);
06553 
06554    if (c) { /* found, add switch to this context */
06555       ret = ast_context_add_switch2(c, sw, data, eval, registrar);
06556       ast_unlock_contexts();
06557    }
06558    return ret;
06559 }

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

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

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

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

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

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

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

struct ast_context* ast_context_find ( const char *  name  ) 

Find a context.

Parameters:
name name of the context to find
Will search for the context with the given name.

Returns:
the ast_context on success, NULL on failure.

Definition at line 2031 of file pbx.c.

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

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

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

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

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

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

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

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

int ast_context_lockmacro ( const char *  context  ) 

locks the macrolock in the given given context

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

Definition at line 4495 of file pbx.c.

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

Referenced by _macro_exec().

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

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

References ast_context_remove_extension_callerid().

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

04303 {
04304    return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar);
04305 }

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

References ast_context_remove_extension_callerid2().

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

04330 {
04331    return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar, already_locked);
04332 }

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

04308 {
04309    int ret = -1; /* default error return */
04310    struct ast_context *c = find_context_locked(context);
04311 
04312    if (c) { /* ... remove extension ... */
04313       ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcallerid, registrar, 1);
04314       ast_unlock_contexts();
04315    }
04316    return ret;
04317 }

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

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

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

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

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

Definition at line 6628 of file pbx.c.

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

Referenced by handle_cli_dialplan_remove_ignorepat().

06629 {
06630    int ret = -1;
06631    struct ast_context *c = find_context_locked(context);
06632 
06633    if (c) {
06634       ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
06635       ast_unlock_contexts();
06636    }
06637    return ret;
06638 }

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

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

06641 {
06642    struct ast_ignorepat *ip, *ipl = NULL;
06643 
06644    ast_wrlock_context(con);
06645 
06646    for (ip = con->ignorepats; ip; ip = ip->next) {
06647       if (!strcmp(ip->pattern, ignorepat) &&
06648          (!registrar || (registrar == ip->registrar))) {
06649          if (ipl) {
06650             ipl->next = ip->next;
06651             ast_free(ip);
06652          } else {
06653             con->ignorepats = ip->next;
06654             ast_free(ip);
06655          }
06656          ast_unlock_context(con);
06657          return 0;
06658       }
06659       ipl = ip;
06660    }
06661 
06662    ast_unlock_context(con);
06663    errno = EINVAL;
06664    return -1;
06665 }

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

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

Referenced by handle_cli_dialplan_remove_include().

04195 {
04196    int ret = -1;
04197    struct ast_context *c = find_context_locked(context);
04198 
04199    if (c) {
04200       /* found, remove include from this context ... */
04201       ret = ast_context_remove_include2(c, include, registrar);
04202       ast_unlock_contexts();
04203    }
04204    return ret;
04205 }

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

Removes an include by an ast_context structure.

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

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

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

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

Remove a switch.

Note:
This function locks contexts list by &conlist, search for the rigt context structure, leave context list locked and call ast_context_remove_switch2 which removes switch, unlock contexts list and return ...

Definition at line 4250 of file pbx.c.

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

04251 {
04252    int ret = -1; /* default error return */
04253    struct ast_context *c = find_context_locked(context);
04254 
04255    if (c) {
04256       /* remove switch from this context ... */
04257       ret = ast_context_remove_switch2(c, sw, data, registrar);
04258       ast_unlock_contexts();
04259    }
04260    return ret;
04261 }

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

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

Referenced by ast_context_remove_switch().

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

int ast_context_unlockmacro ( const char *  context  ) 

Unlocks the macrolock in the given context.

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

Definition at line 4534 of file pbx.c.

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

Referenced by _macro_exec().

04535 {
04536    struct ast_context *c = NULL;
04537    int ret = -1;
04538    struct fake_context item;
04539 
04540    ast_rdlock_contexts();
04541 
04542    ast_copy_string(item.name, context, sizeof(item.name));
04543 
04544    c = ast_hashtab_lookup(contexts_table,&item);
04545    if (c)
04546       ret = 0;
04547 #ifdef NOTNOW
04548 
04549    while ((c = ast_walk_contexts(c))) {
04550       if (!strcmp(ast_get_context_name(c), context)) {
04551          ret = 0;
04552          break;
04553       }
04554    }
04555 
04556 #endif
04557    ast_unlock_contexts();
04558 
04559    /* if we found context, unlock macrolock */
04560    if (ret == 0) 
04561       ret = ast_mutex_unlock(&c->macrolock);
04562 
04563    return ret;
04564 }

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

08962 {
08963    struct ast_include *inc = NULL;
08964    int res = 0;
08965 
08966    while ( (inc = ast_walk_context_includes(con, inc)) ) {
08967       if (ast_context_find(inc->rname))
08968          continue;
08969 
08970       res = -1;
08971       ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n",
08972          ast_get_context_name(con), inc->rname);
08973       break;
08974    }
08975 
08976    return res;
08977 }

struct ast_custom_function* ast_custom_function_find ( const char *  name  ) 

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

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

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

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

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

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

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

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

References E_MATCH, and pbx_extension_helper().

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

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

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

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

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

06776 {
06777    if (!chan)
06778       return -1;
06779 
06780    ast_channel_lock(chan);
06781 
06782    if (!ast_strlen_zero(context))
06783       ast_copy_string(chan->context, context, sizeof(chan->context));
06784    if (!ast_strlen_zero(exten))
06785       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
06786    if (priority > -1) {
06787       chan->priority = priority;
06788       /* see flag description in channel.h for explanation */
06789       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
06790          chan->priority--;
06791    }
06792 
06793    ast_channel_unlock(chan);
06794 
06795    return 0;
06796 }

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

Definition at line 2008 of file pbx.c.

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

Referenced by lua_find_extension(), and realtime_switch_common().

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

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

Determine if one extension should match before another.

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

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

Definition at line 1810 of file pbx.c.

References ext_cmp().

Referenced by lua_extension_cmp().

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

int ast_extension_match ( const char *  pattern,
const char *  extension 
)

Determine if a given extension matches a given pattern (in NXX format).

Parameters:
pattern pattern to match
extension extension to check against the pattern.
Checks whether or not the given extension matches the given pattern.

Return values:
1 on match
0 on failure

Definition at line 2003 of file pbx.c.

References E_MATCH, and extension_match_core().

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

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

int ast_extension_patmatch ( const char *  pattern,
const char *  data 
)

int ast_extension_state ( struct ast_channel c,
const char *  context,
const char *  exten 
)

Uses hint and devicestate callback to get the state of an extension.

Parameters:
c this is not important
context which context to look in
exten which extension to get state
Returns:
extension state as defined in the ast_extension_states enum

Definition at line 3343 of file pbx.c.

References ast_extension_state2(), and ast_hint_extension().

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

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

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

03332 {
03333    int i;
03334 
03335    for (i = 0; (i < ARRAY_LEN(extension_states)); i++) {
03336       if (extension_states[i].extension_state == extension_state)
03337          return extension_states[i].text;
03338    }
03339    return "Unknown";
03340 }

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

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

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

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

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

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

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

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

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

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

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

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

03662 {
03663    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
03664 }

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

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

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

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

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

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

Referenced by action_setvar(), pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().

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

const char* ast_get_context_name ( struct ast_context con  ) 

Definition at line 8813 of file pbx.c.

References ast_context::name.

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

08814 {
08815    return con ? con->name : NULL;
08816 }

const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 8851 of file pbx.c.

References ast_context::registrar.

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

08852 {
08853    return c ? c->registrar : NULL;
08854 }

const char* ast_get_extension_app ( struct ast_exten e  ) 

Definition at line 8881 of file pbx.c.

References ast_exten::app.

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

08882 {
08883    return e ? e->app : NULL;
08884 }

void* ast_get_extension_app_data ( struct ast_exten e  ) 

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

08887 {
08888    return e ? e->data : NULL;
08889 }

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 8876 of file pbx.c.

References ast_exten::cidmatch.

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

08877 {
08878    return e ? e->cidmatch : NULL;
08879 }

struct ast_context* ast_get_extension_context ( struct ast_exten exten  ) 

Definition at line 8818 of file pbx.c.

References exten.

Referenced by handle_show_hint(), and handle_show_hints().

08819 {
08820    return exten ? exten->parent : NULL;
08821 }

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 8828 of file pbx.c.

References exten.

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

08829 {
08830    return exten ? exten->label : NULL;
08831 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 8871 of file pbx.c.

References ast_exten::matchcid.

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

08872 {
08873    return e ? e->matchcid : 0;
08874 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 

Definition at line 8823 of file pbx.c.

References exten.

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

08824 {
08825    return exten ? exten->exten : NULL;
08826 }

int ast_get_extension_priority ( struct ast_exten exten  ) 

Definition at line 8843 of file pbx.c.

References exten.

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

08844 {
08845    return exten ? exten->priority : -1;
08846 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 8856 of file pbx.c.

References ast_exten::registrar.

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

08857 {
08858    return e ? e->registrar : NULL;
08859 }

int ast_get_hint ( char *  hint,
int  maxlen,
char *  name,
int  maxnamelen,
struct ast_channel c,
const char *  context,
const char *  exten 
)

If an extension hint exists, return non-zero.

Parameters:
hint buffer for hint
maxlen size of hint buffer
name buffer for name portion of hint
maxnamelen size of name buffer
c this is not important
context which context to look in
exten which extension to search for
Returns:
If an extension within the given context with the priority PRIORITY_HINT is found a non zero value will be returned. Otherwise, 0 is returned.

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

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

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 

Definition at line 8838 of file pbx.c.

References ast_ignorepat::pattern.

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

08839 {
08840    return ip ? ip->pattern : NULL;
08841 }

const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

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

08867 {
08868    return ip ? ip->registrar : NULL;
08869 }

const char* ast_get_include_name ( struct ast_include include  ) 

Definition at line 8833 of file pbx.c.

References ast_include::name.

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

08834 {
08835    return inc ? inc->name : NULL;
08836 }

const char* ast_get_include_registrar ( struct ast_include i  ) 

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

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

const char* ast_get_switch_data ( struct ast_sw sw  ) 

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

08897 {
08898    return sw ? sw->data : NULL;
08899 }

int ast_get_switch_eval ( struct ast_sw sw  ) 

Definition at line 8901 of file pbx.c.

References ast_sw::eval.

Referenced by context_merge_incls_swits_igps_other_registrars().

08902 {
08903    return sw->eval;
08904 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

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

08892 {
08893    return sw ? sw->name : NULL;
08894 }

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

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

08907 {
08908    return sw ? sw->registrar : NULL;
08909 }

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

References __ast_goto_if_exists(), and chan.

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

09000 {
09001    return __ast_goto_if_exists(chan, context, exten, priority, 0);
09002 }

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

unsigned int ast_hashtab_hash_contexts ( const void *  obj  ) 

int ast_ignore_pattern ( const char *  context,
const char *  pattern 
)

Checks to see if a number should be ignored.

Parameters:
context context to search within
pattern to check whether it should be ignored or not
Check if a number should be ignored with respect to dialtone cancellation.

Return values:
0 if the pattern should not be ignored
non-zero if the pattern should be ignored

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

06722 {
06723    struct ast_context *con = ast_context_find(context);
06724    if (con) {
06725       struct ast_ignorepat *pat;
06726       for (pat = con->ignorepats; pat; pat = pat->next) {
06727          if (ast_extension_match(pat->pattern, pattern))
06728             return 1;
06729       }
06730    }
06731 
06732    return 0;
06733 }

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

References E_MATCHMORE, and pbx_extension_helper().

Referenced by ast_app_dtget(), collect_digits(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_link_data(), handle_link_phone_dtmf(), local_dtmf_helper(), loopback_matchmore(), mgcp_ss(), pbx_builtin_background(), readexten_exec(), skinny_ss(), and ss_thread().

03672 {
03673    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0);
03674 }

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

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

Referenced by lua_reload_extensions(), and pbx_load_module().

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

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

References chan, and pbx_parseable_goto().

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

09063 {
09064    return pbx_parseable_goto(chan, goto_string, 0);
09065 }

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

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

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

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

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

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

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

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

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

04104 {
04105    return ast_pbx_run_args(c, NULL);
04106 }

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 4088 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(), and handle_gosub().

04089 {
04090    enum ast_pbx_result res = AST_PBX_SUCCESS;
04091 
04092    if (increase_call_count(c)) {
04093       return AST_PBX_CALL_LIMIT;
04094    }
04095 
04096    res = __ast_pbx_run(c, args);
04097 
04098    decrease_call_count();
04099 
04100    return res;
04101 }

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

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

Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_bridge_call_thread(), ast_iax2_new(), ast_pbx_outgoing_exten(), bridge_exec(), check_goto_on_transfer(), console_new(), dahdi_new(), dial_exec_full(), gtalk_new(), gtalk_newcall(), handle_request_invite(), jingle_new(), jingle_newcall(), local_call(), manage_parkinglot(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), skinny_new(), unistim_new(), and usbradio_new().

04067 {
04068    pthread_t t;
04069 
04070    if (!c) {
04071       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
04072       return AST_PBX_FAILED;
04073    }
04074 
04075    if (increase_call_count(c))
04076       return AST_PBX_CALL_LIMIT;
04077 
04078    /* Start a new thread, and get something handling this channel. */
04079    if (ast_pthread_create_detached(&t, NULL, pbx_thread, c)) {
04080       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
04081       decrease_call_count();
04082       return AST_PBX_FAILED;
04083    }
04084 
04085    return AST_PBX_SUCCESS;
04086 }

int ast_processed_calls ( void   ) 

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

Definition at line 4113 of file pbx.c.

References totalcalls.

Referenced by handle_chanlist(), and handle_showcalls().

04114 {
04115    return totalcalls;
04116 }

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

08801 {
08802    return ast_rwlock_rdlock(&con->lock);
08803 }

int ast_rdlock_contexts ( void   ) 

Read locks the context list.

Return values:
0 on success
-1 on error

Definition at line 8782 of file pbx.c.

References ast_rwlock_rdlock(), and conlock.

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

08783 {
08784    return ast_rwlock_rdlock(&conlock);
08785 }

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

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

Referenced by load_module().

04619 {
04620    struct ast_switch *tmp;
04621 
04622    AST_RWLIST_WRLOCK(&switches);
04623    AST_RWLIST_TRAVERSE(&switches, tmp, list) {
04624       if (!strcasecmp(tmp->name, sw->name)) {
04625          AST_RWLIST_UNLOCK(&switches);
04626          ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
04627          return -1;
04628       }
04629    }
04630    AST_RWLIST_INSERT_TAIL(&switches, sw, list);
04631    AST_RWLIST_UNLOCK(&switches);
04632 
04633    return 0;
04634 }

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

03677 {
03678    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn);
03679 }

int ast_unlock_context ( struct ast_context con  ) 

Return values:
Unlocks the given context
Parameters:
con context to unlock
Return values:
0 on success
-1 on failure

Definition at line 8805 of file pbx.c.

References ast_rwlock_unlock(), and ast_context::lock.

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

08806 {
08807    return ast_rwlock_unlock(&con->lock);
08808 }

int ast_unlock_contexts ( void   ) 

Unlocks contexts.

Return values:
0 on success
-1 on failure

Definition at line 8787 of file pbx.c.

References ast_rwlock_unlock(), and conlock.

Referenced by _macro_exec(), ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_destroy(), ast_context_find(), ast_context_find_or_create(), ast_context_lockmacro(), ast_context_remove_extension_callerid(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_unlockmacro(), ast_hint_extension(), ast_merge_contexts_and_delete(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_cli_dialplan_save(), handle_statechange(), manager_show_dialplan_helper(), pbx_extension_helper(), show_debug_helper(), show_dialplan_helper(), and unreference_cached_app().

08788 {
08789    return ast_rwlock_unlock(&conlock);
08790 }

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

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

Referenced by __unload_module(), and unload_module().

04637 {
04638    AST_RWLIST_WRLOCK(&switches);
04639    AST_RWLIST_REMOVE(&switches, sw, list);
04640    AST_RWLIST_UNLOCK(&switches);
04641 }

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

Definition at line 8919 of file pbx.c.

References exten, and ast_context::root.

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

08921 {
08922    if (!exten)
08923       return con ? con->root : NULL;
08924    else
08925       return exten->next;
08926 }

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

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

08954 {
08955    if (!ip)
08956       return con ? con->ignorepats : NULL;
08957    else
08958       return ip->next;
08959 }

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

Definition at line 8943 of file pbx.c.

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

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

08945 {
08946    if (!inc)
08947       return con ? con->includes : NULL;
08948    else
08949       return inc->next;
08950 }

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

Definition at line 8928 of file pbx.c.

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

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

08930 {
08931    if (!sw)
08932       return con ? AST_LIST_FIRST(&con->alts) : NULL;
08933    else
08934       return AST_LIST_NEXT(sw, list);
08935 }

struct ast_context* ast_walk_contexts ( struct ast_context con  ) 

Definition at line 8914 of file pbx.c.

References contexts, and ast_context::next.

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

08915 {
08916    return con ? con->next : contexts;
08917 }

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

Definition at line 8937 of file pbx.c.

References exten, and ast_exten::priority.

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

08939 {
08940    return priority ? priority->peer : exten;
08941 }

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

08796 {
08797    return ast_rwlock_wrlock(&con->lock);
08798 }

int ast_wrlock_contexts ( void   ) 

Write locks the context list.

Return values:
0 on success
-1 on error

Definition at line 8774 of file pbx.c.

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

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

08775 {
08776    int res = ast_rwlock_wrlock(&conlock);
08777    if (!res)
08778       ast_atomic_fetchadd_int(&conlock_wrlock_version, 1);
08779    return res;
08780 }

int ast_wrlock_contexts_version ( void   ) 

Definition at line 8766 of file pbx.c.

Referenced by ast_merge_contexts_and_delete().

08767 {
08768    return conlock_wrlock_version;
08769 }

void pbx_builtin_clear_globals ( void   ) 

Definition at line 8611 of file pbx.c.

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

Referenced by handle_cli_dialplan_reload(), and reload().

08612 {
08613    struct ast_var_t *vardata;
08614 
08615    ast_rwlock_wrlock(&globalslock);
08616    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
08617       ast_var_delete(vardata);
08618    ast_rwlock_unlock(&globalslock);
08619 }

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

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

Referenced by _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), array(), ast_bridge_call(), ast_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_call(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), local_read(), login_exec(), macro_fixup(), minivm_delete_exec(), minivm_notify_exec(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_space_reserve(), pbx_builtin_background(), pickup_by_mark(), queue_exec(), real_ctx(), retrydial_exec(), ring_entry(), run_agi(), set_config_flags(), set_local_info(), sip_addheader(), sla_trunk_exec(), speech_background(), try_suggested_sip_codec(), and update_bridge_vars().

08381 {
08382    struct ast_var_t *variables;
08383    const char *ret = NULL;
08384    int i;
08385    struct varshead *places[2] = { NULL, &globals };
08386 
08387    if (!name)
08388       return NULL;
08389 
08390    if (chan) {
08391       ast_channel_lock(chan);
08392       places[0] = &chan->varshead;
08393    }
08394 
08395    for (i = 0; i < 2; i++) {
08396       if (!places[i])
08397          continue;
08398       if (places[i] == &globals)
08399          ast_rwlock_rdlock(&globalslock);
08400       AST_LIST_TRAVERSE(places[i], variables, entries) {
08401          if (!strcmp(name, ast_var_name(variables))) {
08402             ret = ast_var_value(variables);
08403             break;
08404          }
08405       }
08406       if (places[i] == &globals)
08407          ast_rwlock_unlock(&globalslock);
08408       if (ret)
08409          break;
08410    }
08411 
08412    if (chan)
08413       ast_channel_unlock(chan);
08414 
08415    return ret;
08416 }

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

Note:
Will lock the channel.

Definition at line 8418 of file pbx.c.

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

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

08419 {
08420    struct ast_var_t *newvariable;
08421    struct varshead *headp;
08422 
08423    if (name[strlen(name)-1] == ')') {
08424       char *function = ast_strdupa(name);
08425 
08426       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
08427       ast_func_write(chan, function, value);
08428       return;
08429    }
08430 
08431    if (chan) {
08432       ast_channel_lock(chan);
08433       headp = &chan->varshead;
08434    } else {
08435       ast_rwlock_wrlock(&globalslock);
08436       headp = &globals;
08437    }
08438 
08439    if (value) {
08440       if (headp == &globals)
08441          ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value);
08442       newvariable = ast_var_assign(name, value);
08443       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
08444    }
08445 
08446    if (chan)
08447       ast_channel_unlock(chan);
08448    else
08449       ast_rwlock_unlock(&globalslock);
08450 }

int pbx_builtin_raise_exception ( struct ast_channel chan,
void *  data 
)

Definition at line 2595 of file pbx.c.

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

Referenced by __ast_pbx_run().

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

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

Note:
Will lock the channel.

Definition at line 8348 of file pbx.c.

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

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

08349 {
08350    struct ast_var_t *variables;
08351    const char *var, *val;
08352    int total = 0;
08353 
08354    if (!chan)
08355       return 0;
08356 
08357    (*buf)->used = 0;
08358    (*buf)->str[0] = '\0';
08359 
08360    ast_channel_lock(chan);
08361 
08362    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
08363       if ((var = ast_var_name(variables)) && (val = ast_var_value(variables))
08364          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
08365          ) {
08366          if (ast_str_append(buf, 0, "%s=%s\n", var, val) < 0) {
08367             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
08368             break;
08369          } else
08370             total++;
08371       } else
08372          break;
08373    }
08374 
08375    ast_channel_unlock(chan);
08376 
08377    return total;
08378 }

int pbx_builtin_setvar ( struct ast_channel chan,
void *  data 
)

Note:
Will lock the channel.

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

Note:
Will lock the channel.

Definition at line 8452 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verb, chan, EVENT_FLAG_DIALPLAN, globals, globalslock, manager_event, ast_channel::name, and ast_channel::uniqueid.

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

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

int pbx_builtin_setvar_multiple ( struct ast_channel chan,
void *  data 
)

int pbx_checkcondition ( const char *  condition  ) 

Evaluate a condition.

Return values:
0 if the condition is NULL or of zero length
int If the string is an integer, the integer representation of the integer is returned
1 Any other non-empty string

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

08622 {
08623    int res;
08624    if (ast_strlen_zero(condition)) {                /* NULL or empty strings are false */
08625       return 0;
08626    } else if (sscanf(condition, "%30d", &res) == 1) { /* Numbers are evaluated for truth */
08627       return res;
08628    } else {                                         /* Strings are true */
08629       return 1;
08630    }
08631 }

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(), app, ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_log(), ast_opt_dont_warn, ast_strlen_zero(), ast_channel::cdr, ast_channel::data, LOG_WARNING, ast_channel::name, and S_OR.

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

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

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

Definition at line 2068 of file pbx.c.

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

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

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

struct ast_app* pbx_findapp ( const char *  app  ) 

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, AST_RWLIST_UNLOCK, ast_app::list, and ast_app::name.

Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automixmonitor(), builtin_automonitor(), conf_run(), dial_exec_full(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), handle_gosub(), iax2_exec(), lua_pbx_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), 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:
See also

Definition at line 2467 of file pbx.c.

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

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

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

int pbx_set_autofallthrough ( int  newval  ) 

Set "autofallthrough" flag, if newval is <0, does not acutally set. If set to 1, sets to auto fall through. If newval set to 0, sets to no auto fall through (reads extension instead). Returns previous value.

Definition at line 4118 of file pbx.c.

References autofallthrough.

Referenced by pbx_load_module().

04119 {
04120    int oldval = autofallthrough;
04121    autofallthrough = newval;
04122    return oldval;
04123 }

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

References extenpatternmatchnew.

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

04126 {
04127    int oldval = extenpatternmatchnew;
04128    extenpatternmatchnew = newval;
04129    return oldval;
04130 }

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

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

Referenced by pbx_load_module().

04133 {
04134    if (overrideswitch) {
04135       ast_free(overrideswitch);
04136    }
04137    if (!ast_strlen_zero(newval)) {
04138       overrideswitch = ast_strdup(newval);
04139    } else {
04140       overrideswitch = NULL;
04141    }
04142 }

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

Definition at line 3111 of file pbx.c.

References pbx_substitute_variables_helper_full(), and ast_channel::varshead.

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

03112 {
03113    pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
03114 }

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

Definition at line 3116 of file pbx.c.

References pbx_substitute_variables_helper_full().

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

03117 {
03118    pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
03119 }


Generated on Wed Aug 18 22:34:29 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7