Wed Oct 28 11:46:15 2009

Asterisk developer's documentation


pbx.h File Reference

Core PBX routines and definitions. More...

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

Include dependency graph for pbx.h:

Go to the source code of this file.

Data Structures

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

Defines

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

Typedefs

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

Enumerations

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

Functions

int __ast_custom_function_register (struct ast_custom_function *acf, struct ast_module *mod)
 Register a custom function.
int ast_active_calls (void)
 Retrieve the number of active calls.
int ast_add_extension (const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 Add and extension to an extension context.
int ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 Add an extension to an extension context, this time with an ast_context *.
int ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_async_goto_by_name (const char *chan, const char *context, const char *exten, int priority)
int ast_async_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_async_parseable_goto (struct ast_channel *chan, const char *goto_string)
int ast_build_timing (struct ast_timing *i, const char *info)
int ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Looks for a valid matching extension.
int ast_check_timing (const struct ast_timing *i)
int ast_context_add_ignorepat (const char *context, const char *ignorepat, const char *registrar)
 Add an ignorepat.
int ast_context_add_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar)
int ast_context_add_include (const char *context, const char *include, const char *registrar)
 Add a context include.
int ast_context_add_include2 (struct ast_context *con, const char *include, const char *registrar)
 Add a context include.
int ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar)
 Add a switch.
int ast_context_add_switch2 (struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar)
 Adds a switch (first param is a ast_context).
void ast_context_destroy (struct ast_context *con, const char *registrar)
 Destroy a context (matches the specified context (or ANY context if NULL).
struct ast_contextast_context_find (const char *name)
 Find a context.
struct ast_contextast_context_find_or_create (struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
 Register a new context or find an existing one.
int ast_context_lockmacro (const char *macrocontext)
 locks the macrolock in the given given context
int ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar)
 Simply remove extension from context.
int ast_context_remove_extension2 (struct ast_context *con, const char *extension, int priority, const char *registrar, int already_locked)
 This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return.
int ast_context_remove_extension_callerid (const char *context, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar)
int ast_context_remove_extension_callerid2 (struct ast_context *con, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar, int already_locked)
int ast_context_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar)
int ast_context_remove_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar)
int ast_context_remove_include (const char *context, const char *include, const char *registrar)
 Remove a context include.
int ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar)
 Removes an include by an ast_context structure.
int ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar)
 Remove a switch.
int ast_context_remove_switch2 (struct ast_context *con, const char *sw, const char *data, const char *registrar)
 This function locks given context, removes switch, unlock context and return.
int ast_context_unlockmacro (const char *macrocontext)
 Unlocks the macrolock in the given context.
int ast_context_verify_includes (struct ast_context *con)
 Verifies includes in an ast_contect structure.
struct ast_custom_functionast_custom_function_find (const char *name)
int ast_custom_function_unregister (struct ast_custom_function *acf)
 Unregister a custom function.
enum ast_extension_states ast_devstate_to_extenstate (enum ast_device_state devstate)
 Map devstate to an extension state.
int ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Determine whether an extension exists.
int ast_explicit_goto (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_extension_close (const char *pattern, const char *data, int needmore)
int ast_extension_cmp (const char *a, const char *b)
 Determine if one extension should match before another.
int ast_extension_match (const char *pattern, const char *extension)
 Determine if a given extension matches a given pattern (in NXX format).
int ast_extension_patmatch (const char *pattern, const char *data)
int ast_extension_state (struct ast_channel *c, const char *context, const char *exten)
 Uses hint and devicestate callback to get the state of an extension.
const char * ast_extension_state2str (int extension_state)
 Return string representation of the state of an extension.
int ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data)
 Registers a state change callback.
int ast_extension_state_del (int id, ast_state_cb_type callback)
 Deletes a registered state change callback by ID.
int ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
 Find the priority of an extension that has the specified label.
int ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
 Find the priority of an extension that has the specified label.
int ast_func_read (struct ast_channel *chan, const char *function, char *workspace, size_t len)
 executes a read operation on a function
int ast_func_write (struct ast_channel *chan, const char *function, const char *value)
 executes a write operation on a function
int ast_get_hint (char *hint, int maxlen, char *name, int maxnamelen, struct ast_channel *c, const char *context, const char *exten)
 If an extension hint exists, return non-zero.
int ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_hashtab_compare_contexts (const void *ah_a, const void *ah_b)
unsigned int ast_hashtab_hash_contexts (const void *obj)
int ast_ignore_pattern (const char *context, const char *pattern)
 Checks to see if a number should be ignored.
int ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Looks to see if adding anything to this extension might match something. (exists ^ canmatch).
void ast_merge_contexts_and_delete (struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *registrar)
 Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added.
int ast_parseable_goto (struct ast_channel *chan, const char *goto_string)
int ast_pbx_outgoing_app (const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
int ast_pbx_outgoing_exten (const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
enum ast_pbx_result ast_pbx_run (struct ast_channel *c)
 Execute the PBX in the current thread.
enum ast_pbx_result ast_pbx_run_args (struct ast_channel *c, struct ast_pbx_args *args)
 Execute the PBX in the current thread.
enum ast_pbx_result ast_pbx_start (struct ast_channel *c)
 Create a new thread and start the PBX.
int ast_processed_calls (void)
 Retrieve the total number of calls processed through the PBX since last restart.
int ast_rdlock_context (struct ast_context *con)
 Read locks a given context.
int ast_rdlock_contexts (void)
 Read locks the context list.
int ast_register_switch (struct ast_switch *sw)
 Register an alternative dialplan switch.
int ast_spawn_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid, int *found, int combined_find_spawn)
 Launch a new extension (i.e. new stack).
int ast_unlock_context (struct ast_context *con)
int ast_unlock_contexts (void)
 Unlocks contexts.
void ast_unregister_switch (struct ast_switch *sw)
 Unregister an alternative switch.
struct ast_extenast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority)
struct ast_ignorepatast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip)
struct ast_includeast_walk_context_includes (struct ast_context *con, struct ast_include *inc)
struct ast_swast_walk_context_switches (struct ast_context *con, struct ast_sw *sw)
struct ast_contextast_walk_contexts (struct ast_context *con)
struct ast_extenast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority)
int ast_wrlock_context (struct ast_context *con)
 Write locks a given context.
int ast_wrlock_contexts (void)
 Write locks the context list.
int ast_wrlock_contexts_version (void)
void pbx_builtin_clear_globals (void)
const char * pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name)
void pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value)
int pbx_builtin_raise_exception (struct ast_channel *chan, void *data)
int pbx_builtin_serialize_variables (struct ast_channel *chan, struct ast_str **buf)
int pbx_builtin_setvar (struct ast_channel *chan, void *data)
void pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value)
int pbx_builtin_setvar_multiple (struct ast_channel *chan, void *data)
int pbx_checkcondition (const char *condition)
 Evaluate a condition.
int pbx_exec (struct ast_channel *c, struct ast_app *app, void *data)
 Execute an application.
struct ast_extenpbx_find_extension (struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
struct ast_apppbx_findapp (const char *app)
 Look up an application.
void pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
 Support for Asterisk built-in variables in the dialplan.
int pbx_set_autofallthrough (int newval)
int pbx_set_extenpatternmatchnew (int newval)
void pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count)
void pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count)
Functions for returning values from structures

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


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


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


Detailed Description

Core PBX routines and definitions.

Definition in file pbx.h.


Define Documentation

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

Register a custom function.

Definition at line 969 of file pbx.h.

Referenced by load_module(), and reload().

#define AST_MAX_APP   32

Max length of an application

Definition at line 35 of file pbx.h.

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

#define AST_PBX_ERROR   1

Jump to the 'e' exten

Definition at line 43 of file pbx.h.

Referenced by __ast_pbx_run().

#define AST_PBX_HANGUP   -1

Special return values from applications to the PBX {.

Jump to the 'h' exten

Definition at line 41 of file pbx.h.

#define AST_PBX_KEEP   0

Definition at line 37 of file pbx.h.

#define AST_PBX_MAX_STACK   128

Definition at line 1034 of file pbx.h.

#define AST_PBX_OK   0

No errors

Definition at line 42 of file pbx.h.

#define AST_PBX_REPLACE   1

Definition at line 38 of file pbx.h.

#define PRIORITY_HINT   -1

#define STATUS_NO_CONTEXT   1

Definition at line 1029 of file pbx.h.

#define STATUS_NO_EXTENSION   2

Definition at line 1030 of file pbx.h.

#define STATUS_NO_LABEL   4

Definition at line 1032 of file pbx.h.

#define STATUS_NO_PRIORITY   3

Definition at line 1031 of file pbx.h.

#define STATUS_SUCCESS   5

Definition at line 1033 of file pbx.h.


Typedef Documentation

typedef int(* ast_state_cb_type)(char *context, char *id, enum ast_extension_states state, void *data)

Typedef for devicestate and hint callbacks.

Definition at line 71 of file pbx.h.

typedef int( ast_switch_f)(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)

All switch functions have the same interface, so define a type for them.

Data structure associated with an Asterisk switch

Definition at line 86 of file pbx.h.


Enumeration Type Documentation

Extension states.

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

Definition at line 52 of file pbx.h.

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

The result codes when starting the PBX on a channelwith.

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

Definition at line 228 of file pbx.h.

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

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

Enumerator:
E_MATCHMORE 
E_CANMATCH 
E_MATCH 
E_MATCH_MASK 
E_SPAWN 
E_FINDLABEL 
E_MATCHMORE 
E_CANMATCH 
E_MATCH 
E_MATCH_MASK 
E_SPAWN 
E_FINDLABEL 

Definition at line 1020 of file pbx.h.

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


Function Documentation

int __ast_custom_function_register ( struct ast_custom_function acf,
struct ast_module mod 
)

Register a custom function.

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

02715 {
02716    struct ast_custom_function *cur;
02717    char tmps[80];
02718 
02719    if (!acf)
02720       return -1;
02721 
02722    acf->mod = mod;
02723 
02724    AST_RWLIST_WRLOCK(&acf_root);
02725 
02726    AST_RWLIST_TRAVERSE(&acf_root, cur, acflist) {
02727       if (!strcmp(acf->name, cur->name)) {
02728          ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
02729          AST_RWLIST_UNLOCK(&acf_root);
02730          return -1;
02731       }
02732    }
02733 
02734    /* Store in alphabetical order */
02735    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
02736       if (strcasecmp(acf->name, cur->name) < 0) {
02737          AST_RWLIST_INSERT_BEFORE_CURRENT(acf, acflist);
02738          break;
02739       }
02740    }
02741    AST_RWLIST_TRAVERSE_SAFE_END;
02742    if (!cur)
02743       AST_RWLIST_INSERT_TAIL(&acf_root, acf, acflist);
02744 
02745    AST_RWLIST_UNLOCK(&acf_root);
02746 
02747    ast_verb(2, "Registered custom function '%s'\n", term_color(tmps, acf->name, COLOR_BRCYAN, 0, sizeof(tmps)));
02748 
02749    return 0;
02750 }

int ast_active_calls ( void   ) 

Retrieve the number of active calls.

Definition at line 3996 of file pbx.c.

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

03997 {
03998    return countcalls;
03999 }

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

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

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

06437 {
06438    int ret = -1;
06439    struct ast_context *c = find_context_locked(context);
06440 
06441    if (c) {
06442       ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
06443          application, data, datad, registrar);
06444       ast_unlock_contexts();
06445    }
06446    
06447    return ret;
06448 }

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

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

Note:
For details about the arguments, check ast_add_extension()
Add an extension to an extension context, this time with an ast_context *.

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

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

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

Definition at line 6752 of file pbx.c.

References ast_add_extension2_lockopt().

Referenced by ast_add_extension(), context_merge(), do_parking_thread(), load_config(), load_module(), park_call_full(), pbx_load_config(), pbx_load_users(), sla_build_station(), and sla_build_trunk().

06756 {
06757    return ast_add_extension2_lockopt(con, replace, extension, priority, label, callerid, application, data, datad, registrar, 1, 1);
06758 }

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

Definition at line 6473 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, ast_channel::context, ast_channel::exten, LOG_WARNING, ast_channel::name, ast_channel::pbx, ast_channel::readformat, S_OR, and ast_channel::writeformat.

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

06474 {
06475    int res = 0;
06476 
06477    ast_channel_lock(chan);
06478 
06479    if (chan->pbx) { /* This channel is currently in the PBX */
06480       ast_explicit_goto(chan, context, exten, priority + 1);
06481       ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
06482    } else {
06483       /* In order to do it when the channel doesn't really exist within
06484          the PBX, we have to make a new channel, masquerade, and start the PBX
06485          at the new location */
06486       struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name);
06487       if (!tmpchan) {
06488          res = -1;
06489       } else {
06490          if (chan->cdr) {
06491             ast_cdr_discard(tmpchan->cdr);
06492             tmpchan->cdr = ast_cdr_dup(chan->cdr);  /* share the love */
06493          }
06494          /* Make formats okay */
06495          tmpchan->readformat = chan->readformat;
06496          tmpchan->writeformat = chan->writeformat;
06497          /* Setup proper location */
06498          ast_explicit_goto(tmpchan,
06499             S_OR(context, chan->context), S_OR(exten, chan->exten), priority);
06500 
06501          /* Masquerade into temp channel */
06502          if (ast_channel_masquerade(tmpchan, chan)) {
06503             /* Failed to set up the masquerade.  It's probably chan_local
06504              * in the middle of optimizing itself out.  Sad. :( */
06505             ast_hangup(tmpchan);
06506             tmpchan = NULL;
06507             res = -1;
06508          } else {
06509             /* Grab the locks and get going */
06510             ast_channel_lock(tmpchan);
06511             ast_do_masquerade(tmpchan);
06512             ast_channel_unlock(tmpchan);
06513             /* Start the PBX going on our stolen channel */
06514             if (ast_pbx_start(tmpchan)) {
06515                ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
06516                ast_hangup(tmpchan);
06517                res = -1;
06518             }
06519          }
06520       }
06521    }
06522    ast_channel_unlock(chan);
06523    return res;
06524 }

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

Definition at line 6526 of file pbx.c.

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

06527 {
06528    struct ast_channel *chan;
06529    int res = -1;
06530 
06531    chan = ast_get_channel_by_name_locked(channame);
06532    if (chan) {
06533       res = ast_async_goto(chan, context, exten, priority);
06534       ast_channel_unlock(chan);
06535    }
06536    return res;
06537 }

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

References __ast_goto_if_exists().

08634 {
08635    return __ast_goto_if_exists(chan, context, exten, priority, 1);
08636 }

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

References pbx_parseable_goto().

Referenced by asyncgoto_exec().

08697 {
08698    return pbx_parseable_goto(chan, goto_string, 1);
08699 }

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

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

06114 {
06115    char info_save[256];
06116    char *info;
06117 
06118    /* Check for empty just in case */
06119    if (ast_strlen_zero(info_in))
06120       return 0;
06121    /* make a copy just in case we were passed a static string */
06122    ast_copy_string(info_save, info_in, sizeof(info_save));
06123    info = info_save;
06124    /* Assume everything except time */
06125    i->monthmask = 0xfff;   /* 12 bits */
06126    i->daymask = 0x7fffffffU; /* 31 bits */
06127    i->dowmask = 0x7f; /* 7 bits */
06128    /* on each call, use strsep() to move info to the next argument */
06129    get_timerange(i, strsep(&info, "|,"));
06130    if (info)
06131       i->dowmask = get_range(strsep(&info, "|,"), 7, days, "day of week");
06132    if (info)
06133       i->daymask = get_range(strsep(&info, "|,"), 31, NULL, "day");
06134    if (info)
06135       i->monthmask = get_range(strsep(&info, "|,"), 12, months, "month");
06136    return 1;
06137 }

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

References E_CANMATCH, and pbx_extension_helper().

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

03575 {
03576    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0, 0);
03577 }

int ast_check_timing ( const struct ast_timing i  ) 

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

06140 {
06141    struct ast_tm tm;
06142    struct timeval tv = ast_tvnow();
06143 
06144    ast_localtime(&tv, &tm, NULL);
06145 
06146    /* If it's not the right month, return */
06147    if (!(i->monthmask & (1 << tm.tm_mon)))
06148       return 0;
06149 
06150    /* If it's not that time of the month.... */
06151    /* Warning, tm_mday has range 1..31! */
06152    if (!(i->daymask & (1 << (tm.tm_mday-1))))
06153       return 0;
06154 
06155    /* If it's not the right day of the week */
06156    if (!(i->dowmask & (1 << tm.tm_wday)))
06157       return 0;
06158 
06159    /* Sanity check the hour just to be safe */
06160    if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
06161       ast_log(LOG_WARNING, "Insane time...\n");
06162       return 0;
06163    }
06164 
06165    /* Now the tough part, we calculate if it fits
06166       in the right time based on min/hour */
06167    if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
06168       return 0;
06169 
06170    /* If we got this far, then we're good */
06171    return 1;
06172 }

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

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

Referenced by handle_cli_dialplan_add_ignorepat().

06366 {
06367    int ret = -1;
06368    struct ast_context *c = find_context_locked(context);
06369 
06370    if (c) {
06371       ret = ast_context_add_ignorepat2(c, value, registrar);
06372       ast_unlock_contexts();
06373    }
06374    return ret;
06375 }

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

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

06378 {
06379    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
06380    int length;
06381    char *pattern;
06382    length = sizeof(struct ast_ignorepat);
06383    length += strlen(value) + 1;
06384    if (!(ignorepat = ast_calloc(1, length)))
06385       return -1;
06386    /* The cast to char * is because we need to write the initial value.
06387     * The field is not supposed to be modified otherwise.  Also, gcc 4.2
06388     * sees the cast as dereferencing a type-punned pointer and warns about
06389     * it.  This is the workaround (we're telling gcc, yes, that's really
06390     * what we wanted to do).
06391     */
06392    pattern = (char *) ignorepat->pattern;
06393    strcpy(pattern, value);
06394    ignorepat->next = NULL;
06395    ignorepat->registrar = registrar;
06396    ast_wrlock_context(con);
06397    for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
06398       ignorepatl = ignorepatc;
06399       if (!strcasecmp(ignorepatc->pattern, value)) {
06400          /* Already there */
06401          ast_unlock_context(con);
06402          errno = EEXIST;
06403          return -1;
06404       }
06405    }
06406    if (ignorepatl)
06407       ignorepatl->next = ignorepat;
06408    else
06409       con->ignorepats = ignorepat;
06410    ast_unlock_context(con);
06411    return 0;
06412 
06413 }

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

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

Referenced by handle_cli_dialplan_add_include().

05920 {
05921    int ret = -1;
05922    struct ast_context *c = find_context_locked(context);
05923 
05924    if (c) {
05925       ret = ast_context_add_include2(c, include, registrar);
05926       ast_unlock_contexts();
05927    }
05928    return ret;
05929 }

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

06183 {
06184    struct ast_include *new_include;
06185    char *c;
06186    struct ast_include *i, *il = NULL; /* include, include_last */
06187    int length;
06188    char *p;
06189 
06190    length = sizeof(struct ast_include);
06191    length += 2 * (strlen(value) + 1);
06192 
06193    /* allocate new include structure ... */
06194    if (!(new_include = ast_calloc(1, length)))
06195       return -1;
06196    /* Fill in this structure. Use 'p' for assignments, as the fields
06197     * in the structure are 'const char *'
06198     */
06199    p = new_include->stuff;
06200    new_include->name = p;
06201    strcpy(p, value);
06202    p += strlen(value) + 1;
06203    new_include->rname = p;
06204    strcpy(p, value);
06205    /* Strip off timing info, and process if it is there */
06206    if ( (c = strchr(p, ',')) ) {
06207       *c++ = '\0';
06208       new_include->hastime = ast_build_timing(&(new_include->timing), c);
06209    }
06210    new_include->next      = NULL;
06211    new_include->registrar = registrar;
06212 
06213    ast_wrlock_context(con);
06214 
06215    /* ... go to last include and check if context is already included too... */
06216    for (i = con->includes; i; i = i->next) {
06217       if (!strcasecmp(i->name, new_include->name)) {
06218          ast_free(new_include);
06219          ast_unlock_context(con);
06220          errno = EEXIST;
06221          return -1;
06222       }
06223       il = i;
06224    }
06225 
06226    /* ... include new context into context list, unlock, return */
06227    if (il)
06228       il->next = new_include;
06229    else
06230       con->includes = new_include;
06231    ast_verb(3, "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
06232 
06233    ast_unlock_context(con);
06234 
06235    return 0;
06236 }

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

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

06244 {
06245    int ret = -1;
06246    struct ast_context *c = find_context_locked(context);
06247 
06248    if (c) { /* found, add switch to this context */
06249       ret = ast_context_add_switch2(c, sw, data, eval, registrar);
06250       ast_unlock_contexts();
06251    }
06252    return ret;
06253 }

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 6262 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, ast_sw::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().

06264 {
06265    struct ast_sw *new_sw;
06266    struct ast_sw *i;
06267    int length;
06268    char *p;
06269 
06270    length = sizeof(struct ast_sw);
06271    length += strlen(value) + 1;
06272    if (data)
06273       length += strlen(data);
06274    length++;
06275 
06276    /* allocate new sw structure ... */
06277    if (!(new_sw = ast_calloc(1, length)))
06278       return -1;
06279    /* ... fill in this structure ... */
06280    p = new_sw->stuff;
06281    new_sw->name = p;
06282    strcpy(new_sw->name, value);
06283    p += strlen(value) + 1;
06284    new_sw->data = p;
06285    if (data) {
06286       strcpy(new_sw->data, data);
06287       p += strlen(data) + 1;
06288    } else {
06289       strcpy(new_sw->data, "");
06290       p++;
06291    }
06292    new_sw->eval     = eval;
06293    new_sw->registrar = registrar;
06294 
06295    /* ... try to lock this context ... */
06296    ast_wrlock_context(con);
06297 
06298    /* ... go to last sw and check if context is already swd too... */
06299    AST_LIST_TRAVERSE(&con->alts, i, list) {
06300       if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
06301          ast_free(new_sw);
06302          ast_unlock_context(con);
06303          errno = EEXIST;
06304          return -1;
06305       }
06306    }
06307 
06308    /* ... sw new context into context list, unlock, return */
06309    AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
06310 
06311    ast_verb(3, "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
06312 
06313    ast_unlock_context(con);
06314 
06315    return 0;
06316 }

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

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

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

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

Find a context.

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

Returns:
the ast_context on success, NULL on failure.

Definition at line 2001 of file pbx.c.

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

Referenced by __unload_module(), _macro_exec(), ast_context_verify_includes(), ast_ignore_pattern(), cleanup_stale_contexts(), do_parking_thread(), isexten_function_read(), load_config(), park_exec(), register_exten(), register_peer_exten(), unload_module(), and unregister_exten().

02002 {
02003    struct ast_context *tmp = NULL;
02004    struct fake_context item;
02005    strncpy(item.name,name,256);
02006    ast_rdlock_contexts();
02007    if( contexts_table ) {
02008       tmp = ast_hashtab_lookup(contexts_table,&item);
02009    } else {
02010       while ( (tmp = ast_walk_contexts(tmp)) ) {
02011          if (!name || !strcasecmp(name, tmp->name))
02012             break;
02013       }
02014    }
02015    ast_unlock_contexts();
02016    return tmp;
02017 }

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

Register a new context or find an existing one.

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

This will first search for a context with your name. If it exists already, it will not create a new one. If it does not exist, it will create a new one with the given name and registrar.

Returns:
NULL on failure, and an ast_context structure on success

Definition at line 5578 of file pbx.c.

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

Referenced by context_merge(), do_parking_thread(), load_config(), load_module(), lua_register_switches(), park_call_full(), pbx_load_config(), pbx_load_users(), reload_config(), set_config(), sla_build_station(), and sla_build_trunk().

05579 {
05580    struct ast_context *tmp, **local_contexts;
05581    struct fake_context search;
05582    int length = sizeof(struct ast_context) + strlen(name) + 1;
05583 
05584    if (!contexts_table) {
05585       contexts_table = ast_hashtab_create(17,
05586                                  ast_hashtab_compare_contexts, 
05587                                  ast_hashtab_resize_java,
05588                                  ast_hashtab_newsize_java,
05589                                  ast_hashtab_hash_contexts,
05590                                  0);
05591    }
05592    
05593    strncpy(search.name,name,sizeof(search.name));
05594    if (!extcontexts) {
05595       ast_rdlock_contexts();
05596       local_contexts = &contexts;
05597       tmp = ast_hashtab_lookup(contexts_table, &search);
05598       ast_unlock_contexts();
05599       if (tmp) {
05600          tmp->refcount++;
05601          return tmp;
05602       }
05603    } else { /* local contexts just in a linked list; search there for the new context; slow, linear search, but not frequent */
05604       local_contexts = extcontexts;
05605       tmp = ast_hashtab_lookup(exttable, &search);
05606       if (tmp) {
05607          tmp->refcount++;
05608          return tmp;
05609       }
05610    }
05611    
05612    if ((tmp = ast_calloc(1, length))) {
05613       ast_rwlock_init(&tmp->lock);
05614       ast_mutex_init(&tmp->macrolock);
05615       strcpy(tmp->name, name);
05616       tmp->root = NULL;
05617       tmp->root_table = NULL;
05618       tmp->registrar = ast_strdup(registrar);
05619       tmp->includes = NULL;
05620       tmp->ignorepats = NULL;
05621       tmp->refcount = 1;
05622    } else {
05623       ast_log(LOG_ERROR, "Danger! We failed to allocate a context for %s!\n", name);
05624       return NULL;
05625    }
05626    
05627    if (!extcontexts) {
05628       ast_wrlock_contexts();
05629       tmp->next = *local_contexts;
05630       *local_contexts = tmp;
05631       ast_hashtab_insert_safe(contexts_table, tmp); /*put this context into the tree */
05632       ast_unlock_contexts();
05633       ast_debug(1, "Registered context '%s'(%p) in table %p registrar: %s\n", tmp->name, tmp, contexts_table, registrar);
05634       ast_verb(3, "Registered extension context '%s' (%p) in table %p; registrar: %s\n", tmp->name, tmp, contexts_table, registrar);
05635    } else {
05636       tmp->next = *local_contexts;
05637       if (exttable)
05638          ast_hashtab_insert_immediate(exttable, tmp); /*put this context into the tree */
05639       
05640       *local_contexts = tmp;
05641       ast_debug(1, "Registered context '%s'(%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar);
05642       ast_verb(3, "Registered extension context '%s' (%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar);
05643    }
05644    return tmp;
05645 }

int ast_context_lockmacro ( const char *  context  ) 

locks the macrolock in the given given context

Parameters:
macrocontext name of the macro-context to lock
Locks the given macro-context to ensure only one thread (call) can execute it at a time

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

Definition at line 4355 of file pbx.c.

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

Referenced by _macro_exec().

04356 {
04357    struct ast_context *c = NULL;
04358    int ret = -1;
04359    struct fake_context item;
04360 
04361    ast_rdlock_contexts();
04362 
04363    strncpy(item.name,context,256);
04364    c = ast_hashtab_lookup(contexts_table,&item);
04365    if (c)
04366       ret = 0;
04367 
04368 
04369 #ifdef NOTNOW
04370 
04371    while ((c = ast_walk_contexts(c))) {
04372       if (!strcmp(ast_get_context_name(c), context)) {
04373          ret = 0;
04374          break;
04375       }
04376    }
04377 
04378 #endif
04379    ast_unlock_contexts();
04380 
04381    /* if we found context, lock macrolock */
04382    if (ret == 0) 
04383       ret = ast_mutex_lock(&c->macrolock);
04384 
04385    return ret;
04386 }

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

References ast_context_remove_extension_callerid().

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

04163 {
04164    return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar);
04165 }

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

References ast_context_remove_extension_callerid2().

Referenced by do_parking_thread(), load_config(), park_exec(), and unload_module().

04190 {
04191    return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar, already_locked);
04192 }

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

04168 {
04169    int ret = -1; /* default error return */
04170    struct ast_context *c = find_context_locked(context);
04171 
04172    if (c) { /* ... remove extension ... */
04173       ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar, 1);
04174       ast_unlock_contexts();
04175    }
04176    return ret;
04177 }

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

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

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

04195 {
04196    struct ast_exten *exten, *prev_exten = NULL;
04197    struct ast_exten *peer;
04198    struct ast_exten ex, *exten2, *exten3;
04199    char dummy_name[1024];
04200    struct ast_exten *previous_peer = NULL;
04201    struct ast_exten *next_peer = NULL;
04202    int found = 0;
04203 
04204    if (!already_locked)
04205       ast_wrlock_context(con);
04206 
04207    /* Handle this is in the new world */
04208 
04209    /* FIXME For backwards compatibility, if callerid==NULL, then remove ALL
04210     * peers, not just those matching the callerid. */
04211 #ifdef NEED_DEBUG
04212    ast_verb(3,"Removing %s/%s/%d%s%s from trees, registrar=%s\n", con->name, extension, priority, matchcid ? "/" : "", matchcid ? callerid : "", registrar);
04213 #endif
04214 #ifdef CONTEXT_DEBUG
04215    check_contexts(__FILE__, __LINE__);
04216 #endif
04217    /* find this particular extension */
04218    ex.exten = dummy_name;
04219    ex.matchcid = matchcid && !ast_strlen_zero(callerid); /* don't say match if there's no callerid */
04220    ex.cidmatch = callerid;
04221    ast_copy_string(dummy_name, extension, sizeof(dummy_name));
04222    exten = ast_hashtab_lookup(con->root_table, &ex);
04223    if (exten) {
04224       if (priority == 0) {
04225          exten2 = ast_hashtab_remove_this_object(con->root_table, exten);
04226          if (!exten2)
04227             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);
04228          if (con->pattern_tree) {
04229             
04230             struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
04231             
04232             if (x->exten) { /* this test for safety purposes */
04233                x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
04234                x->exten = 0; /* get rid of what will become a bad pointer */
04235             } else {
04236                ast_log(LOG_WARNING,"Trying to delete an exten from a context, but the pattern tree node returned isn't a full extension\n");
04237             }
04238          }
04239       } else {
04240          ex.priority = priority;
04241          exten2 = ast_hashtab_lookup(exten->peer_table, &ex);
04242          if (exten2) {
04243             
04244             if (exten2->label) { /* if this exten has a label, remove that, too */
04245                exten3 = ast_hashtab_remove_this_object(exten->peer_label_table,exten2);
04246                if (!exten3)
04247                   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);
04248             }
04249          
04250             exten3 = ast_hashtab_remove_this_object(exten->peer_table, exten2);
04251             if (!exten3)
04252                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);
04253             if (exten2 == exten && exten2->peer) {
04254                exten2 = ast_hashtab_remove_this_object(con->root_table, exten);
04255                ast_hashtab_insert_immediate(con->root_table, exten2->peer);
04256             }
04257             if (ast_hashtab_size(exten->peer_table) == 0) {
04258                /* well, if the last priority of an exten is to be removed,
04259                   then, the extension is removed, too! */
04260                exten3 = ast_hashtab_remove_this_object(con->root_table, exten);
04261                if (!exten3)
04262                   ast_log(LOG_ERROR,"Did not remove this exten (%s) from the context root_table (%s) (priority %d)\n", exten->exten, con->name, priority);
04263                if (con->pattern_tree) {
04264                   struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
04265                   if (x->exten) { /* this test for safety purposes */
04266                      x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
04267                      x->exten = 0; /* get rid of what will become a bad pointer */
04268                   }
04269                }
04270             }
04271          } else {
04272             ast_log(LOG_ERROR,"Could not find priority %d of exten %s in context %s!\n",
04273                   priority, exten->exten, con->name);
04274          }
04275       }
04276    } else {
04277       /* hmmm? this exten is not in this pattern tree? */
04278       ast_log(LOG_WARNING,"Cannot find extension %s in root_table in context %s\n",
04279             extension, con->name);
04280    }
04281 #ifdef NEED_DEBUG
04282    if (con->pattern_tree) {
04283       ast_log(LOG_NOTICE,"match char tree after exten removal:\n");
04284       log_match_char_tree(con->pattern_tree, " ");
04285    }
04286 #endif
04287 
04288    /* scan the extension list to find first matching extension-registrar */
04289    for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
04290       if (!strcmp(exten->exten, extension) &&
04291          (!registrar || !strcmp(exten->registrar, registrar)) &&
04292          (!matchcid || (!ast_strlen_zero(callerid) && !ast_strlen_zero(exten->cidmatch) && !strcmp(exten->cidmatch, callerid)) || (ast_strlen_zero(callerid) && ast_strlen_zero(exten->cidmatch))))
04293          break;
04294    }
04295    if (!exten) {
04296       /* we can't find right extension */
04297       if (!already_locked)
04298          ast_unlock_context(con);
04299       return -1;
04300    }
04301 
04302    /* scan the priority list to remove extension with exten->priority == priority */
04303    for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next;
04304        peer && !strcmp(peer->exten, extension) && (!matchcid || (!ast_strlen_zero(callerid) && !ast_strlen_zero(peer->cidmatch) && !strcmp(peer->cidmatch,callerid)) || (ast_strlen_zero(callerid) && ast_strlen_zero(peer->cidmatch)));
04305          peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) {
04306       if ((priority == 0 || peer->priority == priority) &&
04307             (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) &&
04308             (!registrar || !strcmp(peer->registrar, registrar) )) {
04309          found = 1;
04310 
04311          /* we are first priority extension? */
04312          if (!previous_peer) {
04313             /*
04314              * We are first in the priority chain, so must update the extension chain.
04315              * The next node is either the next priority or the next extension
04316              */
04317             struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
04318             if (peer->peer) {
04319                /* move the peer_table and peer_label_table down to the next peer, if
04320                   it is there */
04321                peer->peer->peer_table = peer->peer_table;
04322                peer->peer->peer_label_table = peer->peer_label_table;
04323                peer->peer_table = NULL;
04324                peer->peer_label_table = NULL;
04325             }
04326             if (!prev_exten) {   /* change the root... */
04327                con->root = next_node;
04328             } else {
04329                prev_exten->next = next_node; /* unlink */
04330             }
04331             if (peer->peer)   { /* update the new head of the pri list */
04332                peer->peer->next = peer->next;
04333             }
04334          } else { /* easy, we are not first priority in extension */
04335             previous_peer->peer = peer->peer;
04336          }
04337 
04338          /* now, free whole priority extension */
04339          destroy_exten(peer);
04340       } else {
04341          previous_peer = peer;
04342       }
04343    }
04344    if (!already_locked)
04345       ast_unlock_context(con);
04346    return found ? 0 : -1;
04347 }

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

Definition at line 6322 of file pbx.c.

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

Referenced by handle_cli_dialplan_remove_ignorepat().

06323 {
06324    int ret = -1;
06325    struct ast_context *c = find_context_locked(context);
06326 
06327    if (c) {
06328       ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
06329       ast_unlock_contexts();
06330    }
06331    return ret;
06332 }

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

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

06335 {
06336    struct ast_ignorepat *ip, *ipl = NULL;
06337 
06338    ast_wrlock_context(con);
06339 
06340    for (ip = con->ignorepats; ip; ip = ip->next) {
06341       if (!strcmp(ip->pattern, ignorepat) &&
06342          (!registrar || (registrar == ip->registrar))) {
06343          if (ipl) {
06344             ipl->next = ip->next;
06345             ast_free(ip);
06346          } else {
06347             con->ignorepats = ip->next;
06348             ast_free(ip);
06349          }
06350          ast_unlock_context(con);
06351          return 0;
06352       }
06353       ipl = ip;
06354    }
06355 
06356    ast_unlock_context(con);
06357    errno = EINVAL;
06358    return -1;
06359 }

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

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

Referenced by handle_cli_dialplan_remove_include().

04055 {
04056    int ret = -1;
04057    struct ast_context *c = find_context_locked(context);
04058 
04059    if (c) {
04060       /* found, remove include from this context ... */
04061       ret = ast_context_remove_include2(c, include, registrar);
04062       ast_unlock_contexts();
04063    }
04064    return ret;
04065 }

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

Removes an include by an ast_context structure.

Note:
See ast_context_add_include2 for information on arguments
Return values:
0 on success
-1 on success
Removes an include by an ast_context structure.

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

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

04077 {
04078    struct ast_include *i, *pi = NULL;
04079    int ret = -1;
04080 
04081    ast_wrlock_context(con);
04082 
04083    /* find our include */
04084    for (i = con->includes; i; pi = i, i = i->next) {
04085       if (!strcmp(i->name, include) &&
04086             (!registrar || !strcmp(i->registrar, registrar))) {
04087          /* remove from list */
04088          ast_verb(3, "Removing inclusion of context '%s' in context '%s; registrar=%s'\n", include, ast_get_context_name(con), registrar);
04089          if (pi)
04090             pi->next = i->next;
04091          else
04092             con->includes = i->next;
04093          /* free include and return */
04094          ast_free(i);
04095          ret = 0;
04096          break;
04097       }
04098    }
04099 
04100    ast_unlock_context(con);
04101 
04102    return ret;
04103 }

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

Remove a switch.

Removes a switch with the given parameters

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

Definition at line 4110 of file pbx.c.

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

04111 {
04112    int ret = -1; /* default error return */
04113    struct ast_context *c = find_context_locked(context);
04114 
04115    if (c) {
04116       /* remove switch from this context ... */
04117       ret = ast_context_remove_switch2(c, sw, data, registrar);
04118       ast_unlock_contexts();
04119    }
04120    return ret;
04121 }

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

04132 {
04133    struct ast_sw *i;
04134    int ret = -1;
04135 
04136    ast_wrlock_context(con);
04137 
04138    /* walk switches */
04139    AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
04140       if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
04141          (!registrar || !strcmp(i->registrar, registrar))) {
04142          /* found, remove from list */
04143          ast_verb(3, "Removing switch '%s' from context '%s; registrar=%s'\n", sw, ast_get_context_name(con), registrar);
04144          AST_LIST_REMOVE_CURRENT(list);
04145          ast_free(i); /* free switch and return */
04146          ret = 0;
04147          break;
04148       }
04149    }
04150    AST_LIST_TRAVERSE_SAFE_END;
04151 
04152    ast_unlock_context(con);
04153 
04154    return ret;
04155 }

int ast_context_unlockmacro ( const char *  context  ) 

Unlocks the macrolock in the given context.

Parameters:
macrocontext name of the macro-context to unlock
Unlocks the given macro-context so that another thread (call) can execute it

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

Definition at line 4393 of file pbx.c.

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

Referenced by _macro_exec().

04394 {
04395    struct ast_context *c = NULL;
04396    int ret = -1;
04397    struct fake_context item;
04398 
04399    ast_rdlock_contexts();
04400 
04401    strncpy(item.name, context, 256);
04402    c = ast_hashtab_lookup(contexts_table,&item);
04403    if (c)
04404       ret = 0;
04405 #ifdef NOTNOW
04406 
04407    while ((c = ast_walk_contexts(c))) {
04408       if (!strcmp(ast_get_context_name(c), context)) {
04409          ret = 0;
04410          break;
04411       }
04412    }
04413 
04414 #endif
04415    ast_unlock_contexts();
04416 
04417    /* if we found context, unlock macrolock */
04418    if (ret == 0) 
04419       ret = ast_mutex_unlock(&c->macrolock);
04420 
04421    return ret;
04422 }

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

08591 {
08592    struct ast_include *inc = NULL;
08593    int res = 0;
08594 
08595    while ( (inc = ast_walk_context_includes(con, inc)) ) {
08596       if (ast_context_find(inc->rname))
08597          continue;
08598 
08599       res = -1;
08600       ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n",
08601          ast_get_context_name(con), inc->rname);
08602       break;
08603    }
08604 
08605    return res;
08606 }

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

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

02686 {
02687    struct ast_custom_function *acf = NULL;
02688 
02689    AST_RWLIST_RDLOCK(&acf_root);
02690    AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) {
02691       if (!strcmp(name, acf->name))
02692          break;
02693    }
02694    AST_RWLIST_UNLOCK(&acf_root);
02695 
02696    return acf;
02697 }

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

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

02700 {
02701    struct ast_custom_function *cur;
02702 
02703    if (!acf)
02704       return -1;
02705 
02706    AST_RWLIST_WRLOCK(&acf_root);
02707    if ((cur = AST_RWLIST_REMOVE(&acf_root, acf, acflist)))
02708       ast_verb(2, "Unregistered custom function %s\n", cur->name);
02709    AST_RWLIST_UNLOCK(&acf_root);
02710 
02711    return cur ? 0 : -1;
02712 }

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

03176 {
03177    switch (devstate) {
03178    case AST_DEVICE_ONHOLD:
03179       return AST_EXTENSION_ONHOLD;
03180    case AST_DEVICE_BUSY:
03181       return AST_EXTENSION_BUSY;
03182    case AST_DEVICE_UNAVAILABLE:
03183    case AST_DEVICE_UNKNOWN:
03184    case AST_DEVICE_INVALID:
03185       return AST_EXTENSION_UNAVAILABLE;
03186    case AST_DEVICE_RINGINUSE:
03187       return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING);
03188    case AST_DEVICE_RINGING:
03189       return AST_EXTENSION_RINGING;
03190    case AST_DEVICE_INUSE:
03191       return AST_EXTENSION_INUSE;
03192    case AST_DEVICE_NOT_INUSE:
03193       return AST_EXTENSION_NOT_INUSE;
03194    case AST_DEVICE_TOTAL: /* not a device state, included for completeness */
03195       break;
03196    }
03197 
03198    return AST_EXTENSION_NOT_INUSE;
03199 }

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 3559 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_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(), process_ast_dsp(), readexten_exec(), register_peer_exten(), skinny_ss(), socket_process(), ss_thread(), and waitstream_core().

03560 {
03561    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0, 0);
03562 }

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

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

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

06451 {
06452    if (!chan)
06453       return -1;
06454 
06455    ast_channel_lock(chan);
06456 
06457    if (!ast_strlen_zero(context))
06458       ast_copy_string(chan->context, context, sizeof(chan->context));
06459    if (!ast_strlen_zero(exten))
06460       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
06461    if (priority > -1) {
06462       chan->priority = priority;
06463       /* see flag description in channel.h for explanation */
06464       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
06465          chan->priority--;
06466    }
06467 
06468    ast_channel_unlock(chan);
06469 
06470    return 0;
06471 }

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

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

01979 {
01980    if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
01981       ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
01982    return extension_match_core(pattern, data, needmore);
01983 }

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

References ext_cmp().

Referenced by lua_extension_cmp().

01781 {
01782    return ext_cmp(a, b);
01783 }

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

01974 {
01975    return extension_match_core(pattern, data, E_MATCH);
01976 }

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

References ast_extension_state2(), and ast_hint_extension().

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

03237 {
03238    struct ast_exten *e;
03239 
03240    e = ast_hint_extension(c, context, exten);   /* Do we have a hint for this extension ? */
03241    if (!e)
03242       return -1;           /* No hint, return -1 */
03243 
03244    return ast_extension_state2(e);        /* Check all devices in the hint */
03245 }

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

03225 {
03226    int i;
03227 
03228    for (i = 0; (i < ARRAY_LEN(extension_states)); i++) {
03229       if (extension_states[i].extension_state == extension_state)
03230          return extension_states[i].text;
03231    }
03232    return "Unknown";
03233 }

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

References ast_calloc, ast_hint_extension(), AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_hint::exten, ast_state_cb::id, ast_sw::list, and ast_state_cb::next.

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

03336 {
03337    struct ast_hint *hint;
03338    struct ast_state_cb *cblist;
03339    struct ast_exten *e;
03340 
03341    /* If there's no context and extension:  add callback to statecbs list */
03342    if (!context && !exten) {
03343       AST_RWLIST_WRLOCK(&hints);
03344 
03345       for (cblist = statecbs; cblist; cblist = cblist->next) {
03346          if (cblist->callback == callback) {
03347             cblist->data = data;
03348             AST_RWLIST_UNLOCK(&hints);
03349             return 0;
03350          }
03351       }
03352 
03353       /* Now insert the callback */
03354       if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
03355          AST_RWLIST_UNLOCK(&hints);
03356          return -1;
03357       }
03358       cblist->id = 0;
03359       cblist->callback = callback;
03360       cblist->data = data;
03361 
03362       cblist->next = statecbs;
03363       statecbs = cblist;
03364 
03365       AST_RWLIST_UNLOCK(&hints);
03366       return 0;
03367    }
03368 
03369    if (!context || !exten)
03370       return -1;
03371 
03372    /* This callback type is for only one hint, so get the hint */
03373    e = ast_hint_extension(NULL, context, exten);
03374    if (!e) {
03375       return -1;
03376    }
03377 
03378    /* Find the hint in the list of hints */
03379    AST_RWLIST_WRLOCK(&hints);
03380 
03381    AST_RWLIST_TRAVERSE(&hints, hint, list) {
03382       if (hint->exten == e)
03383          break;
03384    }
03385 
03386    if (!hint) {
03387       /* We have no hint, sorry */
03388       AST_RWLIST_UNLOCK(&hints);
03389       return -1;
03390    }
03391 
03392    /* Now insert the callback in the callback list  */
03393    if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
03394       AST_RWLIST_UNLOCK(&hints);
03395       return -1;
03396    }
03397    cblist->id = stateid++;    /* Unique ID for this callback */
03398    cblist->callback = callback;  /* Pointer to callback routine */
03399    cblist->data = data;    /* Data for the callback */
03400 
03401    cblist->next = hint->callbacks;
03402    hint->callbacks = cblist;
03403 
03404    AST_RWLIST_UNLOCK(&hints);
03405    return cblist->id;
03406 }

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

References ast_free, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_hint::callbacks, ast_sw::list, and ast_state_cb::next.

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

03410 {
03411    struct ast_state_cb **p_cur = NULL; /* address of pointer to us */
03412    int ret = -1;
03413 
03414    if (!id && !callback)
03415       return -1;
03416 
03417    AST_RWLIST_WRLOCK(&hints);
03418 
03419    if (!id) {  /* id == 0 is a callback without extension */
03420       for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) {
03421          if ((*p_cur)->callback == callback)
03422             break;
03423       }
03424    } else { /* callback with extension, find the callback based on ID */
03425       struct ast_hint *hint;
03426       AST_RWLIST_TRAVERSE(&hints, hint, list) {
03427          for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) {
03428             if ((*p_cur)->id == id)
03429                break;
03430          }
03431          if (*p_cur) /* found in the inner loop */
03432             break;
03433       }
03434    }
03435    if (p_cur && *p_cur) {
03436       struct ast_state_cb *cur = *p_cur;
03437       *p_cur = cur->next;
03438       ast_free(cur);
03439       ret = 0;
03440    }
03441    AST_RWLIST_UNLOCK(&hints);
03442    return ret;
03443 }

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

03565 {
03566    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
03567 }

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

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

03570 {
03571    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
03572 }

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

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

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

02773 {
02774    char *copy = ast_strdupa(function);
02775    char *args = func_args(copy);
02776    struct ast_custom_function *acfptr = ast_custom_function_find(copy);
02777 
02778    if (acfptr == NULL)
02779       ast_log(LOG_ERROR, "Function %s not registered\n", copy);
02780    else if (!acfptr->read)
02781       ast_log(LOG_ERROR, "Function %s cannot be read\n", copy);
02782    else {
02783       int res;
02784       struct ast_module_user *u = NULL;
02785       if (acfptr->mod)
02786          u = __ast_module_user_add(acfptr->mod, chan);
02787       res = acfptr->read(chan, copy, args, workspace, len);
02788       if (acfptr->mod && u)
02789          __ast_module_user_remove(acfptr->mod, u);
02790       return res;
02791    }
02792    return -1;
02793 }

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

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

Referenced by pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().

02796 {
02797    char *copy = ast_strdupa(function);
02798    char *args = func_args(copy);
02799    struct ast_custom_function *acfptr = ast_custom_function_find(copy);
02800 
02801    if (acfptr == NULL)
02802       ast_log(LOG_ERROR, "Function %s not registered\n", copy);
02803    else if (!acfptr->write)
02804       ast_log(LOG_ERROR, "Function %s cannot be written to\n", copy);
02805    else {
02806       int res;
02807       struct ast_module_user *u = NULL;
02808       if (acfptr->mod)
02809          u = __ast_module_user_add(acfptr->mod, chan);
02810       res = acfptr->write(chan, copy, args, value);
02811       if (acfptr->mod && u)
02812          __ast_module_user_remove(acfptr->mod, u);
02813       return res;
02814    }
02815 
02816    return -1;
02817 }

const char* ast_get_context_name ( struct ast_context con  ) 

const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 8480 of file pbx.c.

References ast_context::registrar.

Referenced by handle_cli_dialplan_save(), and show_dialplan_helper().

08481 {
08482    return c ? c->registrar : NULL;
08483 }

const char* ast_get_extension_app ( struct ast_exten e  ) 

void* ast_get_extension_app_data ( struct ast_exten e  ) 

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

08516 {
08517    return e ? e->data : NULL;
08518 }

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 8505 of file pbx.c.

References ast_exten::cidmatch.

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

08506 {
08507    return e ? e->cidmatch : NULL;
08508 }

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

Definition at line 8447 of file pbx.c.

References ast_exten::parent.

Referenced by handle_show_hint(), and handle_show_hints().

08448 {
08449    return exten ? exten->parent : NULL;
08450 }

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 8457 of file pbx.c.

References ast_exten::label.

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

08458 {
08459    return exten ? exten->label : NULL;
08460 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 8500 of file pbx.c.

References ast_exten::matchcid.

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

08501 {
08502    return e ? e->matchcid : 0;
08503 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 

int ast_get_extension_priority ( struct ast_exten exten  ) 

Definition at line 8472 of file pbx.c.

References ast_exten::priority.

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

08473 {
08474    return exten ? exten->priority : -1;
08475 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 8485 of file pbx.c.

References ast_exten::registrar.

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

08486 {
08487    return e ? e->registrar : NULL;
08488 }

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

If an extension hint exists, return non-zero.

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

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

03543 {
03544    struct ast_exten *e = ast_hint_extension(c, context, exten);
03545 
03546    if (e) {
03547       if (hint)
03548          ast_copy_string(hint, ast_get_extension_app(e), hintsize);
03549       if (name) {
03550          const char *tmp = ast_get_extension_app_data(e);
03551          if (tmp)
03552             ast_copy_string(name, tmp, namesize);
03553       }
03554       return -1;
03555    }
03556    return 0;
03557 }

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 

const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

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

08496 {
08497    return ip ? ip->registrar : NULL;
08498 }

const char* ast_get_include_name ( struct ast_include include  ) 

const char* ast_get_include_registrar ( struct ast_include i  ) 

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

08491 {
08492    return i ? i->registrar : NULL;
08493 }

const char* ast_get_switch_data ( struct ast_sw sw  ) 

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

08526 {
08527    return sw ? sw->data : NULL;
08528 }

int ast_get_switch_eval ( struct ast_sw sw  ) 

Definition at line 8530 of file pbx.c.

References ast_sw::eval.

Referenced by context_merge_incls_swits_igps_other_registrars().

08531 {
08532    return sw->eval;
08533 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

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

08521 {
08522    return sw ? sw->name : NULL;
08523 }

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

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

08536 {
08537    return sw ? sw->registrar : NULL;
08538 }

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

References __ast_goto_if_exists().

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

08629 {
08630    return __ast_goto_if_exists(chan, context, exten, priority, 0);
08631 }

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

06416 {
06417    struct ast_context *con = ast_context_find(context);
06418    if (con) {
06419       struct ast_ignorepat *pat;
06420       for (pat = con->ignorepats; pat; pat = pat->next) {
06421          if (ast_extension_match(pat->pattern, pattern))
06422             return 1;
06423       }
06424    }
06425 
06426    return 0;
06427 }

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 3579 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(), loopback_matchmore(), mgcp_ss(), pbx_builtin_background(), readexten_exec(), skinny_ss(), and ss_thread().

03580 {
03581    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0);
03582 }

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

References __ast_internal_context_destroy(), ast_calloc, AST_EXTENSION_REMOVED, ast_free, ast_hashtab_destroy(), ast_hashtab_end_traversal(), ast_hashtab_next(), ast_hashtab_start_traversal(), 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_tvdiff_us(), ast_tvnow(), ast_unlock_contexts(), ast_verb, ast_wrlock_contexts(), ast_wrlock_contexts_version(), ast_state_cb::callback, ast_hint::callbacks, context, context_merge(), ast_state_cb::data, E_MATCH, ast_exten::exten, ast_hint::exten, ast_hint::laststate, ast_sw::list, LOG_WARNING, ast_context::name, ast_context::next, ast_sw::next, ast_state_cb::next, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_context::registrar, and pbx_find_info::stacklen.

Referenced by lua_reload_extensions(), and pbx_load_module().

05778 {
05779    double ft;
05780    struct ast_context *tmp, *oldcontextslist;
05781    struct ast_hashtab *oldtable;
05782    struct store_hints store = AST_LIST_HEAD_INIT_VALUE;
05783    struct store_hint *this;
05784    struct ast_hint *hint;
05785    struct ast_exten *exten;
05786    int length;
05787    struct ast_state_cb *thiscb, *prevcb;
05788    struct ast_hashtab_iter *iter;
05789    
05790    /* it is very important that this function hold the hint list lock _and_ the conlock
05791       during its operation; not only do we need to ensure that the list of contexts
05792       and extensions does not change, but also that no hint callbacks (watchers) are
05793       added or removed during the merge/delete process
05794 
05795       in addition, the locks _must_ be taken in this order, because there are already
05796       other code paths that use this order
05797    */
05798    
05799    struct timeval begintime, writelocktime, endlocktime, enddeltime;
05800    int wrlock_ver;
05801    
05802    begintime = ast_tvnow();
05803    ast_rdlock_contexts();
05804    iter = ast_hashtab_start_traversal(contexts_table);
05805    while ((tmp=ast_hashtab_next(iter))) {
05806       context_merge(extcontexts, exttable, tmp, registrar);
05807    }
05808    ast_hashtab_end_traversal(iter);
05809    wrlock_ver = ast_wrlock_contexts_version();
05810    
05811    ast_unlock_contexts(); /* this feels real retarded, but you must do
05812                        what you must do If this isn't done, the following 
05813                         wrlock is a guraranteed deadlock */
05814    ast_wrlock_contexts();
05815    if (ast_wrlock_contexts_version() > wrlock_ver+1) {
05816       ast_log(LOG_WARNING,"==================!!!!!!!!!!!!!!!Something changed the contexts in the middle of merging contexts!\n");
05817    }
05818    
05819    AST_RWLIST_WRLOCK(&hints);
05820    writelocktime = ast_tvnow();
05821 
05822    /* preserve all watchers for hints associated with this registrar */
05823    AST_RWLIST_TRAVERSE(&hints, hint, list) {
05824       if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) {
05825          length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this);
05826          if (!(this = ast_calloc(1, length)))
05827             continue;
05828          this->callbacks = hint->callbacks;
05829          hint->callbacks = NULL;
05830          this->laststate = hint->laststate;
05831          this->context = this->data;
05832          strcpy(this->data, hint->exten->parent->name);
05833          this->exten = this->data + strlen(this->context) + 1;
05834          strcpy(this->exten, hint->exten->exten);
05835          AST_LIST_INSERT_HEAD(&store, this, list);
05836       }
05837    }
05838 
05839    /* save the old table and list */
05840    oldtable = contexts_table;
05841    oldcontextslist = contexts;
05842 
05843    /* move in the new table and list */
05844    contexts_table = exttable;
05845    contexts = *extcontexts;
05846    
05847    /* restore the watchers for hints that can be found; notify those that
05848       cannot be restored
05849    */
05850    while ((this = AST_LIST_REMOVE_HEAD(&store, list))) {
05851       struct pbx_find_info q = { .stacklen = 0 };
05852       exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH);
05853       /* Find the hint in the list of hints */
05854       AST_RWLIST_TRAVERSE(&hints, hint, list) {
05855          if (hint->exten == exten)
05856             break;
05857       }
05858       if (!exten || !hint) {
05859          /* this hint has been removed, notify the watchers */
05860          prevcb = NULL;
05861          thiscb = this->callbacks;
05862          while (thiscb) {
05863             prevcb = thiscb;
05864             thiscb = thiscb->next;
05865             prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data);
05866             ast_free(prevcb);
05867             }
05868       } else {
05869          thiscb = this->callbacks;
05870          while (thiscb->next)
05871             thiscb = thiscb->next;
05872          thiscb->next = hint->callbacks;
05873          hint->callbacks = this->callbacks;
05874          hint->laststate = this->laststate;
05875       }
05876       ast_free(this);
05877    }
05878 
05879    AST_RWLIST_UNLOCK(&hints);
05880    ast_unlock_contexts();
05881    endlocktime = ast_tvnow();
05882    
05883    /* the old list and hashtab no longer are relevant, delete them while the rest of asterisk
05884       is now freely using the new stuff instead */
05885    
05886    ast_hashtab_destroy(oldtable, NULL);
05887    
05888    for (tmp = oldcontextslist; tmp; ) {
05889       struct ast_context *next;  /* next starting point */
05890       next = tmp->next;
05891       __ast_internal_context_destroy(tmp);
05892       tmp = next;
05893    }
05894    enddeltime = ast_tvnow();
05895    
05896    ft = ast_tvdiff_us(writelocktime, begintime);
05897    ft /= 1000000.0;
05898    ast_verb(3,"Time to scan old dialplan and merge leftovers back into the new: %8.6f sec\n", ft);
05899    
05900    ft = ast_tvdiff_us(endlocktime, writelocktime);
05901    ft /= 1000000.0;
05902    ast_verb(3,"Time to restore hints and swap in new dialplan: %8.6f sec\n", ft);
05903 
05904    ft = ast_tvdiff_us(enddeltime, endlocktime);
05905    ft /= 1000000.0;
05906    ast_verb(3,"Time to delete the old dialplan: %8.6f sec\n", ft);
05907 
05908    ft = ast_tvdiff_us(enddeltime, begintime);
05909    ft /= 1000000.0;
05910    ast_verb(3,"Total time merge_contexts_delete: %8.6f sec\n", ft);
05911    return;
05912 }

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

References pbx_parseable_goto().

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

08692 {
08693    return pbx_parseable_goto(chan, goto_string, 0);
08694 }

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

References __ast_request_and_dial(), ast_channel::_state, outgoing_helper::account, async_stat::app, app_tmp::app, async_stat::appdata, ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_free, ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create_detached, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verb, async_wait(), ast_channel::cdr, async_stat::chan, app_tmp::chan, app_tmp::data, errno, ast_channel::hangupcause, LOG_WARNING, ast_channel::name, async_stat::p, app_tmp::t, async_stat::timeout, and outgoing_helper::vars.

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

07232 {
07233    struct ast_channel *chan;
07234    struct app_tmp *tmp;
07235    int res = -1, cdr_res = -1;
07236    struct outgoing_helper oh;
07237 
07238    memset(&oh, 0, sizeof(oh));
07239    oh.vars = vars;
07240    oh.account = account;
07241 
07242    if (locked_channel)
07243       *locked_channel = NULL;
07244    if (ast_strlen_zero(app)) {
07245       res = -1;
07246       goto outgoing_app_cleanup;
07247    }
07248    if (sync) {
07249       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
07250       if (chan) {
07251          ast_set_variables(chan, vars);
07252          if (account)
07253             ast_cdr_setaccount(chan, account);
07254          if (chan->_state == AST_STATE_UP) {
07255             res = 0;
07256             ast_verb(4, "Channel %s was answered.\n", chan->name);
07257             tmp = ast_calloc(1, sizeof(*tmp));
07258             if (!tmp)
07259                res = -1;
07260             else {
07261                ast_copy_string(tmp->app, app, sizeof(tmp->app));
07262                if (appdata)
07263                   ast_copy_string(tmp->data, appdata, sizeof(tmp->data));
07264                tmp->chan = chan;
07265                if (sync > 1) {
07266                   if (locked_channel)
07267                      ast_channel_unlock(chan);
07268                   ast_pbx_run_app(tmp);
07269                } else {
07270                   if (locked_channel)
07271                      ast_channel_lock(chan);
07272                   if (ast_pthread_create_detached(&tmp->t, NULL, ast_pbx_run_app, tmp)) {
07273                      ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
07274                      ast_free(tmp);
07275                      if (locked_channel)
07276                         ast_channel_unlock(chan);
07277                      ast_hangup(chan);
07278                      res = -1;
07279                   } else {
07280                      if (locked_channel)
07281                         *locked_channel = chan;
07282                   }
07283                }
07284             }
07285          } else {
07286             ast_verb(4, "Channel %s was never answered.\n", chan->name);
07287             if (chan->cdr) { /* update the cdr */
07288                /* here we update the status of the call, which sould be busy.
07289                 * if that fails then we set the status to failed */
07290                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
07291                   ast_cdr_failed(chan->cdr);
07292             }
07293             ast_hangup(chan);
07294          }
07295       }
07296 
07297       if (res < 0) { /* the call failed for some reason */
07298          if (*reason == 0) { /* if the call failed (not busy or no answer)
07299                         * update the cdr with the failed message */
07300             cdr_res = ast_pbx_outgoing_cdr_failed();
07301             if (cdr_res != 0) {
07302                res = cdr_res;
07303                goto outgoing_app_cleanup;
07304             }
07305          }
07306       }
07307 
07308    } else {
07309       struct async_stat *as;
07310       if (!(as = ast_calloc(1, sizeof(*as)))) {
07311          res = -1;
07312          goto outgoing_app_cleanup;
07313       }
07314       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
07315       if (!chan) {
07316          ast_free(as);
07317          res = -1;
07318          goto outgoing_app_cleanup;
07319       }
07320       as->chan = chan;
07321       ast_copy_string(as->app, app, sizeof(as->app));
07322       if (appdata)
07323          ast_copy_string(as->appdata,  appdata, sizeof(as->appdata));
07324       as->timeout = timeout;
07325       ast_set_variables(chan, vars);
07326       if (account)
07327          ast_cdr_setaccount(chan, account);
07328       /* Start a new thread, and get something handling this channel. */
07329       if (locked_channel)
07330          ast_channel_lock(chan);
07331       if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) {
07332          ast_log(LOG_WARNING, "Failed to start async wait\n");
07333          ast_free(as);
07334          if (locked_channel)
07335             ast_channel_unlock(chan);
07336          ast_hangup(chan);
07337          res = -1;
07338          goto outgoing_app_cleanup;
07339       } else {
07340          if (locked_channel)
07341             *locked_channel = chan;
07342       }
07343       res = 0;
07344    }
07345 outgoing_app_cleanup:
07346    ast_variables_destroy(vars);
07347    return res;
07348 }

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

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

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

07066 {
07067    struct ast_channel *chan;
07068    struct async_stat *as;
07069    int res = -1, cdr_res = -1;
07070    struct outgoing_helper oh;
07071 
07072    if (sync) {
07073       oh.context = context;
07074       oh.exten = exten;
07075       oh.priority = priority;
07076       oh.cid_num = cid_num;
07077       oh.cid_name = cid_name;
07078       oh.account = account;
07079       oh.vars = vars;
07080       oh.parent_channel = NULL;
07081 
07082       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
07083       if (channel) {
07084          *channel = chan;
07085          if (chan)
07086             ast_channel_lock(chan);
07087       }
07088       if (chan) {
07089          if (chan->_state == AST_STATE_UP) {
07090                res = 0;
07091             ast_verb(4, "Channel %s was answered.\n", chan->name);
07092 
07093             if (sync > 1) {
07094                if (channel)
07095                   ast_channel_unlock(chan);
07096                if (ast_pbx_run(chan)) {
07097                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
07098                   if (channel)
07099                      *channel = NULL;
07100                   ast_hangup(chan);
07101                   chan = NULL;
07102                   res = -1;
07103                }
07104             } else {
07105                if (ast_pbx_start(chan)) {
07106                   ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name);
07107                   if (channel) {
07108                      *channel = NULL;
07109                      ast_channel_unlock(chan);
07110                   }
07111                   ast_hangup(chan);
07112                   res = -1;
07113                }
07114                chan = NULL;
07115             }
07116          } else {
07117             ast_verb(4, "Channel %s was never answered.\n", chan->name);
07118 
07119             if (chan->cdr) { /* update the cdr */
07120                /* here we update the status of the call, which sould be busy.
07121                 * if that fails then we set the status to failed */
07122                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
07123                   ast_cdr_failed(chan->cdr);
07124             }
07125 
07126             if (channel) {
07127                *channel = NULL;
07128                ast_channel_unlock(chan);
07129             }
07130             ast_hangup(chan);
07131             chan = NULL;
07132          }
07133       }
07134 
07135       if (res < 0) { /* the call failed for some reason */
07136          if (*reason == 0) { /* if the call failed (not busy or no answer)
07137                         * update the cdr with the failed message */
07138             cdr_res = ast_pbx_outgoing_cdr_failed();
07139             if (cdr_res != 0) {
07140                res = cdr_res;
07141                goto outgoing_exten_cleanup;
07142             }
07143          }
07144 
07145          /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */
07146          /* check if "failed" exists */
07147          if (ast_exists_extension(chan, context, "failed", 1, NULL)) {
07148             chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed");
07149             if (chan) {
07150                char failed_reason[4] = "";
07151                if (!ast_strlen_zero(context))
07152                   ast_copy_string(chan->context, context, sizeof(chan->context));
07153                set_ext_pri(chan, "failed", 1);
07154                ast_set_variables(chan, vars);
07155                snprintf(failed_reason, sizeof(failed_reason), "%d", *reason);
07156                pbx_builtin_setvar_helper(chan, "REASON", failed_reason);
07157                if (account)
07158                   ast_cdr_setaccount(chan, account);
07159                if (ast_pbx_run(chan)) {
07160                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
07161                   ast_hangup(chan);
07162                }
07163                chan = NULL;
07164             }
07165          }
07166       }
07167    } else {
07168       if (!(as = ast_calloc(1, sizeof(*as)))) {
07169          res = -1;
07170          goto outgoing_exten_cleanup;
07171       }
07172       chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
07173       if (channel) {
07174          *channel = chan;
07175          if (chan)
07176             ast_channel_lock(chan);
07177       }
07178       if (!chan) {
07179          ast_free(as);
07180          res = -1;
07181          goto outgoing_exten_cleanup;
07182       }
07183       as->chan = chan;
07184       ast_copy_string(as->context, context, sizeof(as->context));
07185       set_ext_pri(as->chan,  exten, priority);
07186       as->timeout = timeout;
07187       ast_set_variables(chan, vars);
07188       if (account)
07189          ast_cdr_setaccount(chan, account);
07190       if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) {
07191          ast_log(LOG_WARNING, "Failed to start async wait\n");
07192          ast_free(as);
07193          if (channel) {
07194             *channel = NULL;
07195             ast_channel_unlock(chan);
07196          }
07197          ast_hangup(chan);
07198          res = -1;
07199          goto outgoing_exten_cleanup;
07200       }
07201       res = 0;
07202    }
07203 outgoing_exten_cleanup:
07204    ast_variables_destroy(vars);
07205    return res;
07206 }

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

References ast_pbx_run_args().

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

03992 {
03993    return ast_pbx_run_args(c, NULL);
03994 }

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

References __ast_pbx_run(), AST_PBX_CALL_LIMIT, AST_PBX_SUCCESS, decrease_call_count(), and increase_call_count().

Referenced by ast_pbx_run(), dial_exec_full(), handle_gosub(), and try_calling().

03977 {
03978    enum ast_pbx_result res = AST_PBX_SUCCESS;
03979 
03980    if (increase_call_count(c)) {
03981       return AST_PBX_CALL_LIMIT;
03982    }
03983 
03984    res = __ast_pbx_run(c, args);
03985 
03986    decrease_call_count();
03987 
03988    return res;
03989 }

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

03955 {
03956    pthread_t t;
03957 
03958    if (!c) {
03959       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
03960       return AST_PBX_FAILED;
03961    }
03962 
03963    if (increase_call_count(c))
03964       return AST_PBX_CALL_LIMIT;
03965 
03966    /* Start a new thread, and get something handling this channel. */
03967    if (ast_pthread_create_detached(&t, NULL, pbx_thread, c)) {
03968       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
03969       decrease_call_count();
03970       return AST_PBX_FAILED;
03971    }
03972 
03973    return AST_PBX_SUCCESS;
03974 }

int ast_processed_calls ( void   ) 

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

Definition at line 4001 of file pbx.c.

Referenced by handle_chanlist(), and handle_showcalls().

04002 {
04003    return totalcalls;
04004 }

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 8429 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(), and show_dialplan_helper().

08430 {
08431    return ast_rwlock_rdlock(&con->lock);
08432 }

int ast_rdlock_contexts ( void   ) 

int ast_register_switch ( struct ast_switch sw  ) 

Register an alternative dialplan switch.

Parameters:
sw switch to register
This function registers a populated ast_switch structure with the asterisk switching architecture.

Returns:
0 on success, and other than 0 on failure

Definition at line 4476 of file pbx.c.

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

Referenced by load_module().

04477 {
04478    struct ast_switch *tmp;
04479 
04480    AST_RWLIST_WRLOCK(&switches);
04481    AST_RWLIST_TRAVERSE(&switches, tmp, list) {
04482       if (!strcasecmp(tmp->name, sw->name)) {
04483          AST_RWLIST_UNLOCK(&switches);
04484          ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
04485          return -1;
04486       }
04487    }
04488    AST_RWLIST_INSERT_TAIL(&switches, sw, list);
04489    AST_RWLIST_UNLOCK(&switches);
04490 
04491    return 0;
04492 }

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

03585 {
03586    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn);
03587 }

int ast_unlock_context ( struct ast_context con  ) 

int ast_unlock_contexts ( void   ) 

void ast_unregister_switch ( struct ast_switch sw  ) 

Unregister an alternative switch.

Parameters:
sw switch to unregister
Unregisters a switch from asterisk.

Returns:
nothing

Definition at line 4494 of file pbx.c.

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

Referenced by __unload_module(), and unload_module().

04495 {
04496    AST_RWLIST_WRLOCK(&switches);
04497    AST_RWLIST_REMOVE(&switches, sw, list);
04498    AST_RWLIST_UNLOCK(&switches);
04499 }

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

Definition at line 8548 of file pbx.c.

References ast_exten::next, and ast_context::root.

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

08550 {
08551    if (!exten)
08552       return con ? con->root : NULL;
08553    else
08554       return exten->next;
08555 }

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

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

08583 {
08584    if (!ip)
08585       return con ? con->ignorepats : NULL;
08586    else
08587       return ip->next;
08588 }

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

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

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

08559 {
08560    if (!sw)
08561       return con ? AST_LIST_FIRST(&con->alts) : NULL;
08562    else
08563       return AST_LIST_NEXT(sw, list);
08564 }

struct ast_context* ast_walk_contexts ( struct ast_context con  )  [read]

struct ast_exten* ast_walk_extension_priorities ( struct ast_exten exten,
struct ast_exten priority 
) [read]

int ast_wrlock_context ( struct ast_context con  ) 

Write locks a given context.

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

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

08425 {
08426    return ast_rwlock_wrlock(&con->lock);
08427 }

int ast_wrlock_contexts ( void   ) 

Write locks the context list.

Return values:
0 on success
-1 on error

Definition at line 8403 of file pbx.c.

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

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

08404 {
08405    int res = ast_rwlock_wrlock(&conlock);
08406    if (!res)
08407       ast_atomic_fetchadd_int(&conlock_wrlock_version, 1);
08408    return res;
08409 }

int ast_wrlock_contexts_version ( void   ) 

Definition at line 8395 of file pbx.c.

References conlock_wrlock_version.

Referenced by ast_merge_contexts_and_delete().

08396 {
08397    return conlock_wrlock_version;
08398 }

void pbx_builtin_clear_globals ( void   ) 

Definition at line 8247 of file pbx.c.

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

Referenced by handle_cli_dialplan_reload(), and reload().

08248 {
08249    struct ast_var_t *vardata;
08250 
08251    ast_rwlock_wrlock(&globalslock);
08252    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
08253       ast_var_delete(vardata);
08254    ast_rwlock_unlock(&globalslock);
08255 }

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

Referenced by __ast_pbx_run(), _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), array(), ast_bridge_call(), ast_call_forward(), ast_eivr_getvariable(), ast_feature_interpret(), ast_monitor_stop(), 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(), get_also_info(), get_index(), get_refer_info(), global_read(), hash_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), local_read(), login_exec(), macro_fixup(), minivm_delete_exec(), minivm_notify_exec(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_call_full(), park_space_reserve(), pickup_by_mark(), queue_exec(), real_ctx(), retrydial_exec(), ring_entry(), run_agi(), set_config_flags(), set_local_info(), sip_addheader(), sla_trunk_exec(), speech_background(), try_calling(), try_suggested_sip_codec(), update_bridge_vars(), and wait_for_answer().

08018 {
08019    struct ast_var_t *variables;
08020    const char *ret = NULL;
08021    int i;
08022    struct varshead *places[2] = { NULL, &globals };
08023 
08024    if (!name)
08025       return NULL;
08026 
08027    if (chan) {
08028       ast_channel_lock(chan);
08029       places[0] = &chan->varshead;
08030    }
08031 
08032    for (i = 0; i < 2; i++) {
08033       if (!places[i])
08034          continue;
08035       if (places[i] == &globals)
08036          ast_rwlock_rdlock(&globalslock);
08037       AST_LIST_TRAVERSE(places[i], variables, entries) {
08038          if (!strcmp(name, ast_var_name(variables))) {
08039             ret = ast_var_value(variables);
08040             break;
08041          }
08042       }
08043       if (places[i] == &globals)
08044          ast_rwlock_unlock(&globalslock);
08045       if (ret)
08046          break;
08047    }
08048 
08049    if (chan)
08050       ast_channel_unlock(chan);
08051 
08052    return ret;
08053 }

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

Note:
Will lock the channel.

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

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

08056 {
08057    struct ast_var_t *newvariable;
08058    struct varshead *headp;
08059 
08060    if (name[strlen(name)-1] == ')') {
08061       char *function = ast_strdupa(name);
08062 
08063       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
08064       ast_func_write(chan, function, value);
08065       return;
08066    }
08067 
08068    if (chan) {
08069       ast_channel_lock(chan);
08070       headp = &chan->varshead;
08071    } else {
08072       ast_rwlock_wrlock(&globalslock);
08073       headp = &globals;
08074    }
08075 
08076    if (value) {
08077       if (headp == &globals)
08078          ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value);
08079       newvariable = ast_var_assign(name, value);
08080       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
08081    }
08082 
08083    if (chan)
08084       ast_channel_unlock(chan);
08085    else
08086       ast_rwlock_unlock(&globalslock);
08087 }

int pbx_builtin_raise_exception ( struct ast_channel chan,
void *  data 
)

Definition at line 2498 of file pbx.c.

References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_alloc(), ast_channel_datastore_find(), ast_channel_datastore_free(), ast_free, ast_string_field_init, ast_string_field_set, ast_channel::context, 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().

02499 {
02500    const char *reason = vreason;
02501    struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL);
02502    struct pbx_exception *exception = NULL;
02503 
02504    if (!ds) {
02505       ds = ast_channel_datastore_alloc(&exception_store_info, NULL);
02506       if (!ds)
02507          return -1;
02508       exception = ast_calloc(1, sizeof(struct pbx_exception));
02509       if (!exception) {
02510          ast_channel_datastore_free(ds);
02511          return -1;
02512       }
02513       if (ast_string_field_init(exception, 128)) {
02514          ast_free(exception);
02515          ast_channel_datastore_free(ds);
02516          return -1;
02517       }
02518       ds->data = exception;
02519       ast_channel_datastore_add(chan, ds);
02520    } else
02521       exception = ds->data;
02522 
02523    ast_string_field_set(exception, reason, reason);
02524    ast_string_field_set(exception, context, chan->context);
02525    ast_string_field_set(exception, exten, chan->exten);
02526    exception->priority = chan->priority;
02527    set_ext_pri(chan, "e", 0);
02528    return 0;
02529 }

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

Note:
Will lock the channel.

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

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

07986 {
07987    struct ast_var_t *variables;
07988    const char *var, *val;
07989    int total = 0;
07990 
07991    if (!chan)
07992       return 0;
07993 
07994    (*buf)->used = 0;
07995    (*buf)->str[0] = '\0';
07996 
07997    ast_channel_lock(chan);
07998 
07999    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
08000       if ((var = ast_var_name(variables)) && (val = ast_var_value(variables))
08001          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
08002          ) {
08003          if (ast_str_append(buf, 0, "%s=%s\n", var, val) < 0) {
08004             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
08005             break;
08006          } else
08007             total++;
08008       } else
08009          break;
08010    }
08011 
08012    ast_channel_unlock(chan);
08013 
08014    return total;
08015 }

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

References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE, AST_LIST_TRAVERSE, ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verb, EVENT_FLAG_DIALPLAN, globalslock, manager_event, ast_channel::name, ast_channel::uniqueid, and ast_channel::varshead.

Referenced by __ast_pbx_run(), __oh323_new(), _macro_exec(), _while_exec(), acf_fetch(), acf_odbc_read(), acf_odbc_write(), action_setvar(), agi_exec_full(), aji_status_exec(), aqm_exec(), array(), ast_bridge_call(), ast_eivr_setvariable(), ast_feature_request_and_dial(), ast_iax2_new(), ast_monitor_start(), ast_pbx_outgoing_exten(), ast_set_variables(), asyncgoto_exec(), background_detect_exec(), bridge_exec(), builtin_automixmonitor(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), channel_spy(), conf_run(), controlplayback_exec(), count_exec(), dahdi_handle_dtmfup(), dahdi_new(), dial_exec_full(), disa_exec(), do_parking_thread(), 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(), 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(), 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(), privacy_exec(), process_ast_dsp(), read_exec(), readexten_exec(), readfile_exec(), record_exec(), return_exec(), rotate_file(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_hangup(), sip_new(), skinny_new(), sla_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), ss_thread(), start_monitor_exec(), system_exec_helper(), transfer_exec(), transmit(), tryexec_exec(), update_bridge_vars(), update_qe_rule(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), waituntil_exec(), and zapateller_exec().

08090 {
08091    struct ast_var_t *newvariable;
08092    struct varshead *headp;
08093    const char *nametail = name;
08094 
08095    if (name[strlen(name) - 1] == ')') {
08096       char *function = ast_strdupa(name);
08097 
08098       ast_func_write(chan, function, value);
08099       return;
08100    }
08101 
08102    if (chan) {
08103       ast_channel_lock(chan);
08104       headp = &chan->varshead;
08105    } else {
08106       ast_rwlock_wrlock(&globalslock);
08107       headp = &globals;
08108    }
08109 
08110    /* For comparison purposes, we have to strip leading underscores */
08111    if (*nametail == '_') {
08112       nametail++;
08113       if (*nametail == '_')
08114          nametail++;
08115    }
08116 
08117    AST_LIST_TRAVERSE (headp, newvariable, entries) {
08118       if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
08119          /* there is already such a variable, delete it */
08120          AST_LIST_REMOVE(headp, newvariable, entries);
08121          ast_var_delete(newvariable);
08122          break;
08123       }
08124    }
08125 
08126    if (value) {
08127       if (headp == &globals)
08128          ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value);
08129       newvariable = ast_var_assign(name, value);
08130       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
08131       manager_event(EVENT_FLAG_DIALPLAN, "VarSet", 
08132          "Channel: %s\r\n"
08133          "Variable: %s\r\n"
08134          "Value: %s\r\n"
08135          "Uniqueid: %s\r\n", 
08136          chan ? chan->name : "none", name, value, 
08137          chan ? chan->uniqueid : "none");
08138    }
08139 
08140    if (chan)
08141       ast_channel_unlock(chan);
08142    else
08143       ast_rwlock_unlock(&globalslock);
08144 }

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

08258 {
08259    if (ast_strlen_zero(condition))  /* NULL or empty strings are false */
08260       return 0;
08261    else if (*condition >= '0' && *condition <= '9')   /* Numbers are evaluated for truth */
08262       return atoi(condition);
08263    else  /* Strings are true */
08264       return 1;
08265 }

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

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

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

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

Definition at line 2036 of file pbx.c.

References ast_context::alts, ast_autoservice_start(), ast_autoservice_stop(), ast_hashtab_lookup(), AST_LIST_TRAVERSE, ast_log(), AST_PBX_MAX_STACK, ast_str_thread_get(), ast_walk_context_extensions(), ast_walk_contexts(), ast_walk_extension_priorities(), ast_switch::canmatch, scoreboard::canmatch_exten, create_match_char_tree(), ast_sw::data, pbx_find_info::data, E_CANMATCH, E_FINDLABEL, E_MATCHMORE, ast_sw::eval, ast_switch::exists, ast_exten::exten, scoreboard::exten, extension_match_core(), pbx_find_info::foundcontext, include_valid(), ast_context::includes, pbx_find_info::incstack, ast_exten::label, scoreboard::last_char, ast_str::len, ast_sw::list, 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, 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, switch_data, pbx_find_info::swo, scoreboard::total_length, scoreboard::total_specificity, and trie_find_next_match().

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

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

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

Look up an application.

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

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

Definition at line 966 of file pbx.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_sw::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(), realtime_exec(), try_calling(), and tryexec_exec().

00967 {
00968    struct ast_app *tmp;
00969 
00970    AST_RWLIST_RDLOCK(&apps);
00971    AST_RWLIST_TRAVERSE(&apps, tmp, list) {
00972       if (!strcasecmp(tmp->name, app))
00973          break;
00974    }
00975    AST_RWLIST_UNLOCK(&apps);
00976 
00977    return tmp;
00978 }

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

Support for Asterisk built-in variables in the dialplan.

Note:
Will lock the channel.

See also

Definition at line 2373 of file pbx.c.

References ARRAY_LEN, ast_channel_lock, ast_channel_unlock, ast_config_AST_SYSTEM_NAME, ast_copy_string(), 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_var_t::entries, ast_channel::exten, globalslock, ast_channel::hangupcause, ast_channel::name, parse_variable_name(), ast_channel::priority, s, substring(), ast_channel::uniqueid, and ast_channel::varshead.

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

02374 {
02375    const char not_found = '\0';
02376    char *tmpvar;
02377    const char *s; /* the result */
02378    int offset, length;
02379    int i, need_substring;
02380    struct varshead *places[2] = { headp, &globals };  /* list of places where we may look */
02381 
02382    if (c) {
02383       ast_channel_lock(c);
02384       places[0] = &c->varshead;
02385    }
02386    /*
02387     * Make a copy of var because parse_variable_name() modifies the string.
02388     * Then if called directly, we might need to run substring() on the result;
02389     * remember this for later in 'need_substring', 'offset' and 'length'
02390     */
02391    tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */
02392    need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
02393 
02394    /*
02395     * Look first into predefined variables, then into variable lists.
02396     * Variable 's' points to the result, according to the following rules:
02397     * s == &not_found (set at the beginning) means that we did not find a
02398     * matching variable and need to look into more places.
02399     * If s != &not_found, s is a valid result string as follows:
02400     * s = NULL if the variable does not have a value;
02401     * you typically do this when looking for an unset predefined variable.
02402     * s = workspace if the result has been assembled there;
02403     * typically done when the result is built e.g. with an snprintf(),
02404     * so we don't need to do an additional copy.
02405     * s != workspace in case we have a string, that needs to be copied
02406     * (the ast_copy_string is done once for all at the end).
02407     * Typically done when the result is already available in some string.
02408     */
02409    s = &not_found;   /* default value */
02410    if (c) { /* This group requires a valid channel */
02411       /* Names with common parts are looked up a piece at a time using strncmp. */
02412       if (!strncmp(var, "CALL", 4)) {
02413          if (!strncmp(var + 4, "ING", 3)) {
02414             if (!strcmp(var + 7, "PRES")) {        /* CALLINGPRES */
02415                snprintf(workspace, workspacelen, "%d", c->cid.cid_pres);
02416                s = workspace;
02417             } else if (!strcmp(var + 7, "ANI2")) {    /* CALLINGANI2 */
02418                snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2);
02419                s = workspace;
02420             } else if (!strcmp(var + 7, "TON")) {     /* CALLINGTON */
02421                snprintf(workspace, workspacelen, "%d", c->cid.cid_ton);
02422                s = workspace;
02423             } else if (!strcmp(var + 7, "TNS")) {     /* CALLINGTNS */
02424                snprintf(workspace, workspacelen, "%d", c->cid.cid_tns);
02425                s = workspace;
02426             }
02427          }
02428       } else if (!strcmp(var, "HINT")) {
02429          s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL;
02430       } else if (!strcmp(var, "HINTNAME")) {
02431          s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL;
02432       } else if (!strcmp(var, "EXTEN")) {
02433          s = c->exten;
02434       } else if (!strcmp(var, "CONTEXT")) {
02435          s = c->context;
02436       } else if (!strcmp(var, "PRIORITY")) {
02437          snprintf(workspace, workspacelen, "%d", c->priority);
02438          s = workspace;
02439       } else if (!strcmp(var, "CHANNEL")) {
02440          s = c->name;
02441       } else if (!strcmp(var, "UNIQUEID")) {
02442          s = c->uniqueid;
02443       } else if (!strcmp(var, "HANGUPCAUSE")) {
02444          snprintf(workspace, workspacelen, "%d", c->hangupcause);
02445          s = workspace;
02446       }
02447    }
02448    if (s == &not_found) { /* look for more */
02449       if (!strcmp(var, "EPOCH")) {
02450          snprintf(workspace, workspacelen, "%u",(int)time(NULL));
02451          s = workspace;
02452       } else if (!strcmp(var, "SYSTEMNAME")) {
02453          s = ast_config_AST_SYSTEM_NAME;
02454       }
02455    }
02456    /* if not found, look into chanvars or global vars */
02457    for (i = 0; s == &not_found && i < ARRAY_LEN(places); i++) {
02458       struct ast_var_t *variables;
02459       if (!places[i])
02460          continue;
02461       if (places[i] == &globals)
02462          ast_rwlock_rdlock(&globalslock);
02463       AST_LIST_TRAVERSE(places[i], variables, entries) {
02464          if (!strcasecmp(ast_var_name(variables), var)) {
02465             s = ast_var_value(variables);
02466             break;
02467          }
02468       }
02469       if (places[i] == &globals)
02470          ast_rwlock_unlock(&globalslock);
02471    }
02472    if (s == &not_found || s == NULL)
02473       *ret = NULL;
02474    else {
02475       if (s != workspace)
02476          ast_copy_string(workspace, s, workspacelen);
02477       *ret = workspace;
02478       if (need_substring)
02479          *ret = substring(*ret, offset, length, workspace, workspacelen);
02480    }
02481 
02482    if (c)
02483       ast_channel_unlock(c);
02484 }

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

Referenced by pbx_load_module().

04007 {
04008    int oldval = autofallthrough;
04009    autofallthrough = newval;
04010    return oldval;
04011 }

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

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

04014 {
04015    int oldval = extenpatternmatchnew;
04016    extenpatternmatchnew = newval;
04017    return oldval;
04018 }

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

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


Generated on Wed Oct 28 11:46:16 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6