#include "asterisk/sched.h"
#include "asterisk/chanvars.h"
#include "asterisk/hashtab.h"
Go to the source code of this file.
Data Structures | |
struct | ast_custom_function |
Data structure associated with a custom dialplan function. More... | |
struct | ast_pbx |
struct | ast_pbx_args |
Options for ast_pbx_run(). More... | |
struct | ast_switch |
struct | ast_timing |
struct | pbx_find_info |
Functions for returning values from structures | |
const char * | ast_get_context_name (struct ast_context *con) |
ast_context * | ast_get_extension_context (struct ast_exten *exten) |
const char * | ast_get_extension_name (struct ast_exten *exten) |
const char * | ast_get_ignorepat_name (struct ast_ignorepat *ip) |
const char * | ast_get_include_name (struct ast_include *include) |
const char * | ast_get_switch_data (struct ast_sw *sw) |
int | ast_get_switch_eval (struct ast_sw *sw) |
const char * | ast_get_switch_name (struct ast_sw *sw) |
Registrar info functions ... | |
const char * | ast_get_context_registrar (struct ast_context *c) |
const char * | ast_get_extension_registrar (struct ast_exten *e) |
const char * | ast_get_ignorepat_registrar (struct ast_ignorepat *ip) |
const char * | ast_get_include_registrar (struct ast_include *i) |
const char * | ast_get_switch_registrar (struct ast_sw *sw) |
Other Extension stuff | |
const char * | ast_get_extension_app (struct ast_exten *e) |
void * | ast_get_extension_app_data (struct ast_exten *e) |
const char * | ast_get_extension_cidmatch (struct ast_exten *e) |
const char * | ast_get_extension_label (struct ast_exten *e) |
int | ast_get_extension_matchcid (struct ast_exten *e) |
int | ast_get_extension_priority (struct ast_exten *exten) |
Defines | |
#define | ast_custom_function_register(acf) __ast_custom_function_register(acf, ast_module_info->self) |
Register a custom function. | |
#define | AST_MAX_APP 32 |
#define | AST_PBX_ERROR 1 |
#define | AST_PBX_HANGUP -1 |
Special return values from applications to the PBX {. | |
#define | AST_PBX_INCOMPLETE 12 |
#define | AST_PBX_KEEP 0 |
#define | AST_PBX_MAX_STACK 128 |
#define | AST_PBX_OK 0 |
#define | AST_PBX_REPLACE 1 |
#define | PRIORITY_HINT -1 |
#define | STATUS_NO_CONTEXT 1 |
#define | STATUS_NO_EXTENSION 2 |
#define | STATUS_NO_LABEL 4 |
#define | STATUS_NO_PRIORITY 3 |
#define | STATUS_SUCCESS 5 |
Typedefs | |
typedef int(*) | ast_state_cb_type (char *context, char *id, enum ast_extension_states state, void *data) |
Typedef for devicestate and hint callbacks. | |
typedef int( | ast_switch_f )(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
All switch functions have the same interface, so define a type for them. | |
Enumerations | |
enum | ast_extension_states { AST_EXTENSION_REMOVED = -2, AST_EXTENSION_DEACTIVATED = -1, AST_EXTENSION_NOT_INUSE = 0, AST_EXTENSION_INUSE = 1 << 0, AST_EXTENSION_BUSY = 1 << 1, AST_EXTENSION_UNAVAILABLE = 1 << 2, AST_EXTENSION_RINGING = 1 << 3, AST_EXTENSION_ONHOLD = 1 << 4 } |
Extension states. More... | |
enum | ast_pbx_result { AST_PBX_SUCCESS = 0, AST_PBX_FAILED = -1, AST_PBX_CALL_LIMIT = -2 } |
The result codes when starting the PBX on a channelwith. More... | |
enum | ext_match_t { E_MATCHMORE = 0x00, E_CANMATCH = 0x01, E_MATCH = 0x02, E_MATCH_MASK = 0x03, E_SPAWN = 0x12, E_FINDLABEL = 0x22 } |
Functions | |
int | __ast_custom_function_register (struct ast_custom_function *acf, struct ast_module *mod) |
Register a custom function. | |
int | ast_active_calls (void) |
Retrieve the number of active calls. | |
int | ast_add_extension (const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar) |
Add and extension to an extension context. | |
int | ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar) |
Add an extension to an extension context, this time with an ast_context *. | |
int | ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority) |
int | ast_async_goto_by_name (const char *chan, const char *context, const char *exten, int priority) |
int | ast_async_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
int | ast_async_parseable_goto (struct ast_channel *chan, const char *goto_string) |
int | ast_build_timing (struct ast_timing *i, const char *info) |
int | ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
Looks for a valid matching extension. | |
int | ast_check_timing (const struct ast_timing *i) |
int | ast_context_add_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
Add an ignorepat. | |
int | ast_context_add_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar) |
int | ast_context_add_include (const char *context, const char *include, const char *registrar) |
Add a context include. | |
int | ast_context_add_include2 (struct ast_context *con, const char *include, const char *registrar) |
Add a context include. | |
int | ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar) |
Add a switch. | |
int | ast_context_add_switch2 (struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar) |
Adds a switch (first param is a ast_context). | |
void | ast_context_destroy (struct ast_context *con, const char *registrar) |
Destroy a context (matches the specified context (or ANY context if NULL). | |
ast_context * | ast_context_find (const char *name) |
Find a context. | |
ast_context * | ast_context_find_or_create (struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar) |
Register a new context or find an existing one. | |
int | ast_context_lockmacro (const char *macrocontext) |
locks the macrolock in the given given context | |
int | ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar) |
Simply remove extension from context. | |
int | ast_context_remove_extension2 (struct ast_context *con, const char *extension, int priority, const char *registrar, int already_locked) |
This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return. | |
int | ast_context_remove_extension_callerid (const char *context, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar) |
int | ast_context_remove_extension_callerid2 (struct ast_context *con, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar, int already_locked) |
int | ast_context_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
int | ast_context_remove_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar) |
int | ast_context_remove_include (const char *context, const char *include, const char *registrar) |
Remove a context include. | |
int | ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar) |
Removes an include by an ast_context structure. | |
int | ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar) |
Remove a switch. | |
int | ast_context_remove_switch2 (struct ast_context *con, const char *sw, const char *data, const char *registrar) |
This function locks given context, removes switch, unlock context and return. | |
int | ast_context_unlockmacro (const char *macrocontext) |
Unlocks the macrolock in the given context. | |
int | ast_context_verify_includes (struct ast_context *con) |
Verifies includes in an ast_contect structure. | |
ast_custom_function * | ast_custom_function_find (const char *name) |
int | ast_custom_function_unregister (struct ast_custom_function *acf) |
Unregister a custom function. | |
int | ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
Determine whether an extension exists. | |
int | ast_explicit_goto (struct ast_channel *chan, const char *context, const char *exten, int priority) |
int | ast_extension_close (const char *pattern, const char *data, int needmore) |
int | ast_extension_cmp (const char *a, const char *b) |
Determine if one extension should match before another. | |
int | ast_extension_match (const char *pattern, const char *extension) |
Determine if a given extension matches a given pattern (in NXX format). | |
int | ast_extension_patmatch (const char *pattern, const char *data) |
int | ast_extension_state (struct ast_channel *c, const char *context, const char *exten) |
Uses hint and devicestate callback to get the state of an extension. | |
const char * | ast_extension_state2str (int extension_state) |
Return string representation of the state of an extension. | |
int | ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data) |
Registers a state change callback. | |
int | ast_extension_state_del (int id, ast_state_cb_type callback) |
Deletes a registered state change callback by ID. | |
int | ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid) |
Find the priority of an extension that has the specified label. | |
int | ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid) |
Find the priority of an extension that has the specified label. | |
int | ast_func_read (struct ast_channel *chan, const char *function, char *workspace, size_t len) |
executes a read operation on a function | |
int | ast_func_write (struct ast_channel *chan, const char *function, const char *value) |
executes a write operation on a function | |
int | ast_get_hint (char *hint, int maxlen, char *name, int maxnamelen, struct ast_channel *c, const char *context, const char *exten) |
If an extension hint exists, return non-zero. | |
int | ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
int | ast_hashtab_compare_contexts (const void *ah_a, const void *ah_b) |
unsigned int | ast_hashtab_hash_contexts (const void *obj) |
int | ast_ignore_pattern (const char *context, const char *pattern) |
Checks to see if a number should be ignored. | |
int | ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
Looks to see if adding anything to this extension might match something. (exists ^ canmatch). | |
void | ast_merge_contexts_and_delete (struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *registrar) |
Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added. | |
int | ast_parseable_goto (struct ast_channel *chan, const char *goto_string) |
int | ast_pbx_outgoing_app (const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) |
int | ast_pbx_outgoing_exten (const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) |
enum ast_pbx_result | ast_pbx_run (struct ast_channel *c) |
Execute the PBX in the current thread. | |
enum ast_pbx_result | ast_pbx_run_args (struct ast_channel *c, struct ast_pbx_args *args) |
Execute the PBX in the current thread. | |
enum ast_pbx_result | ast_pbx_start (struct ast_channel *c) |
Create a new thread and start the PBX. | |
int | ast_processed_calls (void) |
Retrieve the total number of calls processed through the PBX since last restart. | |
int | ast_rdlock_context (struct ast_context *con) |
Read locks a given context. | |
int | ast_rdlock_contexts (void) |
Read locks the context list. | |
int | ast_register_switch (struct ast_switch *sw) |
Register an alternative dialplan switch. | |
int | ast_spawn_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid, int *found, int combined_find_spawn) |
Launch a new extension (i.e. new stack). | |
int | ast_unlock_context (struct ast_context *con) |
int | ast_unlock_contexts (void) |
Unlocks contexts. | |
void | ast_unregister_switch (struct ast_switch *sw) |
Unregister an alternative switch. | |
ast_exten * | ast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority) |
ast_ignorepat * | ast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip) |
ast_include * | ast_walk_context_includes (struct ast_context *con, struct ast_include *inc) |
ast_sw * | ast_walk_context_switches (struct ast_context *con, struct ast_sw *sw) |
ast_context * | ast_walk_contexts (struct ast_context *con) |
ast_exten * | ast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority) |
int | ast_wrlock_context (struct ast_context *con) |
Write locks a given context. | |
int | ast_wrlock_contexts (void) |
Write locks the context list. | |
int | ast_wrlock_contexts_version (void) |
void | pbx_builtin_clear_globals (void) |
const char * | pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name) |
void | pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value) |
int | pbx_builtin_raise_exception (struct ast_channel *chan, void *data) |
int | pbx_builtin_serialize_variables (struct ast_channel *chan, struct ast_str **buf) |
int | pbx_builtin_setvar (struct ast_channel *chan, void *data) |
void | pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value) |
int | pbx_builtin_setvar_multiple (struct ast_channel *chan, void *data) |
int | pbx_checkcondition (const char *condition) |
Evaluate a condition. | |
int | pbx_exec (struct ast_channel *c, struct ast_app *app, void *data) |
Execute an application. | |
ast_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) |
ast_app * | pbx_findapp (const char *app) |
Look up an application. | |
void | pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp) |
Support for Asterisk built-in variables in the dialplan. | |
int | pbx_set_autofallthrough (int newval) |
int | pbx_set_extenpatternmatchnew (int newval) |
void | pbx_set_overrideswitch (const char *newval) |
void | pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count) |
void | pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count) |
Definition in file pbx.h.
#define ast_custom_function_register | ( | acf | ) | __ast_custom_function_register(acf, ast_module_info->self) |
Register a custom function.
Definition at line 968 of file pbx.h.
Referenced by load_module(), and reload().
#define AST_MAX_APP 32 |
Max length of an application
Definition at line 34 of file pbx.h.
Referenced by destroy_station(), handle_show_application(), and handle_show_function().
#define AST_PBX_HANGUP -1 |
#define AST_PBX_INCOMPLETE 12 |
Return to PBX matching, allowing more digits for the extension
Definition at line 43 of file pbx.h.
Referenced by dial_exec_full(), pbx_builtin_incomplete(), and retrydial_exec().
#define PRIORITY_HINT -1 |
} Special Priority for a hint
Definition at line 46 of file pbx.h.
Referenced by ast_add_extension2_lockopt(), ast_hint_extension_nolock(), ast_merge_contexts_and_delete(), destroy_exten(), destroy_station(), handle_cli_dialplan_add_extension(), handle_cli_dialplan_remove_extension(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), park_add_hints(), pbx_load_config(), and print_ext().
typedef int(*) ast_state_cb_type(char *context, char *id, enum ast_extension_states state, void *data) |
typedef int( ast_switch_f)(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
enum ast_extension_states |
Extension states.
Definition at line 52 of file pbx.h.
00052 { 00053 AST_EXTENSION_REMOVED = -2, /*!< Extension removed */ 00054 AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */ 00055 AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */ 00056 AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */ 00057 AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */ 00058 AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */ 00059 AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */ 00060 AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */ 00061 };
enum ast_pbx_result |
The result codes when starting the PBX on a channelwith.
Definition at line 228 of file pbx.h.
00228 { 00229 AST_PBX_SUCCESS = 0, 00230 AST_PBX_FAILED = -1, 00231 AST_PBX_CALL_LIMIT = -2, 00232 };
enum ext_match_t |
When looking up extensions, we can have different requests identified by the 'action' argument, as follows. Note that the coding is such that the low 4 bits are the third argument to extension_match_core.
Definition at line 1019 of file pbx.h.
01019 { 01020 E_MATCHMORE = 0x00, /* extension can match but only with more 'digits' */ 01021 E_CANMATCH = 0x01, /* extension can match with or without more 'digits' */ 01022 E_MATCH = 0x02, /* extension is an exact match */ 01023 E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */ 01024 E_SPAWN = 0x12, /* want to spawn an extension. Requires exact match */ 01025 E_FINDLABEL = 0x22 /* returns the priority for a given label. Requires exact match */ 01026 };
int __ast_custom_function_register | ( | struct ast_custom_function * | acf, | |
struct ast_module * | mod | |||
) |
Register a custom function.
Definition at line 2792 of file pbx.c.
References ast_custom_function::acflist, ast_log(), AST_RWLIST_INSERT_BEFORE_CURRENT, AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, COLOR_BRCYAN, LOG_ERROR, ast_custom_function::mod, ast_custom_function::name, and term_color().
Referenced by load_pbx().
02793 { 02794 struct ast_custom_function *cur; 02795 char tmps[80]; 02796 02797 if (!acf) 02798 return -1; 02799 02800 acf->mod = mod; 02801 02802 AST_RWLIST_WRLOCK(&acf_root); 02803 02804 AST_RWLIST_TRAVERSE(&acf_root, cur, acflist) { 02805 if (!strcmp(acf->name, cur->name)) { 02806 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 02807 AST_RWLIST_UNLOCK(&acf_root); 02808 return -1; 02809 } 02810 } 02811 02812 /* Store in alphabetical order */ 02813 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 02814 if (strcasecmp(acf->name, cur->name) < 0) { 02815 AST_RWLIST_INSERT_BEFORE_CURRENT(acf, acflist); 02816 break; 02817 } 02818 } 02819 AST_RWLIST_TRAVERSE_SAFE_END; 02820 if (!cur) 02821 AST_RWLIST_INSERT_TAIL(&acf_root, acf, acflist); 02822 02823 AST_RWLIST_UNLOCK(&acf_root); 02824 02825 ast_verb(2, "Registered custom function '%s'\n", term_color(tmps, acf->name, COLOR_BRCYAN, 0, sizeof(tmps))); 02826 02827 return 0; 02828 }
int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 4074 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), handle_showcalls(), and sysinfo_helper().
04075 { 04076 return countcalls; 04077 }
int ast_add_extension | ( | const char * | context, | |
int | replace, | |||
const char * | extension, | |||
int | priority, | |||
const char * | label, | |||
const char * | callerid, | |||
const char * | application, | |||
void * | data, | |||
void(*)(void *) | datad, | |||
const char * | registrar | |||
) |
Add and extension to an extension context.
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 |
0 | success | |
-1 | failure |
Definition at line 6691 of file pbx.c.
References ast_add_extension2(), ast_unlock_contexts(), and find_context_locked().
Referenced by ast_extension_state_add(), handle_cli_dialplan_add_extension(), park_add_hints(), register_exten(), register_peer_exten(), and RegisterExtension().
06694 { 06695 int ret = -1; 06696 struct ast_context *c = find_context_locked(context); 06697 06698 if (c) { 06699 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 06700 application, data, datad, registrar); 06701 ast_unlock_contexts(); 06702 } 06703 06704 return ret; 06705 }
int ast_add_extension2 | ( | struct ast_context * | con, | |
int | replace, | |||
const char * | extension, | |||
int | priority, | |||
const char * | label, | |||
const char * | callerid, | |||
const char * | application, | |||
void * | data, | |||
void(*)(void *) | datad, | |||
const char * | registrar | |||
) |
Add an extension to an extension context, this time with an ast_context *.
We sort extensions in order of matching preference, so that we can stop the search as soon as we find a suitable match. This ordering also takes care of wildcards such as '.' (meaning "one or more of any character") and '!' (which is 'earlymatch', meaning "zero or more of any character" but also impacts the return value from CANMATCH and EARLYMATCH.
The extension match rules defined in the devmeeting 2006.05.05 are quite simple: WE SELECT THE LONGEST MATCH. In detail, "longest" means the number of matched characters in the extension. In case of ties (e.g. _XXX and 333) in the length of a pattern, we give priority to entries with the smallest cardinality (e.g, [5-9] comes before [2-8] before the former has only 5 elements, while the latter has 7, etc. In case of same cardinality, the first element in the range counts. If we still have a tie, any final '!' will make this as a possibly less specific pattern.
EBUSY - can't lock EEXIST - extension with the same priority exist and no replace is set
Definition at line 7009 of file pbx.c.
References ast_add_extension2_lockopt().
Referenced by ast_add_extension(), ast_park_call_full(), build_parkinglot(), context_merge(), load_module(), manage_parkinglot(), pbx_load_config(), and pbx_load_users().
07013 { 07014 return ast_add_extension2_lockopt(con, replace, extension, priority, label, callerid, application, data, datad, registrar, 1, 1); 07015 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6730 of file pbx.c.
References ast_channel::_state, ast_channel::accountcode, ast_channel::amaflags, ast_cdr_discard(), ast_cdr_dup(), ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_unlock, ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_pbx_start(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_channel::cdr, chan, ast_channel::context, ast_channel::exten, LOG_WARNING, ast_channel::name, ast_channel::pbx, ast_channel::readformat, S_OR, and ast_channel::writeformat.
Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), dahdi_handle_dtmfup(), handle_request_bye(), handle_request_refer(), pbx_parseable_goto(), process_ast_dsp(), and socket_process().
06731 { 06732 int res = 0; 06733 06734 ast_channel_lock(chan); 06735 06736 if (chan->pbx) { /* This channel is currently in the PBX */ 06737 ast_explicit_goto(chan, context, exten, priority + 1); 06738 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 06739 } else { 06740 /* In order to do it when the channel doesn't really exist within 06741 the PBX, we have to make a new channel, masquerade, and start the PBX 06742 at the new location */ 06743 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 06744 if (!tmpchan) { 06745 res = -1; 06746 } else { 06747 if (chan->cdr) { 06748 ast_cdr_discard(tmpchan->cdr); 06749 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 06750 } 06751 /* Make formats okay */ 06752 tmpchan->readformat = chan->readformat; 06753 tmpchan->writeformat = chan->writeformat; 06754 /* Setup proper location */ 06755 ast_explicit_goto(tmpchan, 06756 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 06757 06758 /* Masquerade into temp channel */ 06759 if (ast_channel_masquerade(tmpchan, chan)) { 06760 /* Failed to set up the masquerade. It's probably chan_local 06761 * in the middle of optimizing itself out. Sad. :( */ 06762 ast_hangup(tmpchan); 06763 tmpchan = NULL; 06764 res = -1; 06765 } else { 06766 /* Grab the locks and get going */ 06767 ast_channel_lock(tmpchan); 06768 ast_do_masquerade(tmpchan); 06769 ast_channel_unlock(tmpchan); 06770 /* Start the PBX going on our stolen channel */ 06771 if (ast_pbx_start(tmpchan)) { 06772 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 06773 ast_hangup(tmpchan); 06774 res = -1; 06775 } 06776 } 06777 } 06778 } 06779 ast_channel_unlock(chan); 06780 return res; 06781 }
int ast_async_goto_by_name | ( | const char * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6783 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, ast_get_channel_by_name_locked(), and chan.
06784 { 06785 struct ast_channel *chan; 06786 int res = -1; 06787 06788 chan = ast_get_channel_by_name_locked(channame); 06789 if (chan) { 06790 res = ast_async_goto(chan, context, exten, priority); 06791 ast_channel_unlock(chan); 06792 } 06793 return res; 06794 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 8903 of file pbx.c.
References __ast_goto_if_exists(), and chan.
08904 { 08905 return __ast_goto_if_exists(chan, context, exten, priority, 1); 08906 }
int ast_async_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
Definition at line 8966 of file pbx.c.
References chan, and pbx_parseable_goto().
Referenced by asyncgoto_exec().
08967 { 08968 return pbx_parseable_goto(chan, goto_string, 1); 08969 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info | |||
) |
Definition at line 6351 of file pbx.c.
References ast_copy_string(), ast_strlen_zero(), ast_timing::daymask, days, ast_timing::dowmask, get_range(), get_timerange(), ast_timing::monthmask, months, and strsep().
Referenced by ast_context_add_include2(), iftime(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
06352 { 06353 char info_save[256]; 06354 char *info; 06355 06356 /* Check for empty just in case */ 06357 if (ast_strlen_zero(info_in)) 06358 return 0; 06359 /* make a copy just in case we were passed a static string */ 06360 ast_copy_string(info_save, info_in, sizeof(info_save)); 06361 info = info_save; 06362 /* Assume everything except time */ 06363 i->monthmask = 0xfff; /* 12 bits */ 06364 i->daymask = 0x7fffffffU; /* 31 bits */ 06365 i->dowmask = 0x7f; /* 7 bits */ 06366 /* on each call, use strsep() to move info to the next argument */ 06367 get_timerange(i, strsep(&info, "|,")); 06368 if (info) 06369 i->dowmask = get_range(strsep(&info, "|,"), 7, days, "day of week"); 06370 if (info) 06371 i->daymask = get_range(strsep(&info, "|,"), 31, NULL, "day"); 06372 if (info) 06373 i->monthmask = get_range(strsep(&info, "|,"), 12, months, "month"); 06374 return 1; 06375 }
int ast_canmatch_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) |
Looks for a valid matching extension.
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 |
Definition at line 3636 of file pbx.c.
References E_CANMATCH, and pbx_extension_helper().
Referenced by background_detect_exec(), cb_events(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), handle_link_data(), handle_link_phone_dtmf(), leave_voicemail(), local_dtmf_helper(), loopback_canmatch(), mgcp_ss(), phone_check_exception(), skinny_ss(), ss_thread(), and valid_exit().
03637 { 03638 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0, 0); 03639 }
int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 6377 of file pbx.c.
References ast_localtime(), ast_log(), ast_tvnow(), ast_timing::daymask, ast_timing::dowmask, LOG_WARNING, ast_timing::minmask, ast_timing::monthmask, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, and ast_tm::tm_wday.
Referenced by iftime(), include_valid(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
06378 { 06379 struct ast_tm tm; 06380 struct timeval now = ast_tvnow(); 06381 06382 ast_localtime(&now, &tm, NULL); 06383 06384 /* If it's not the right month, return */ 06385 if (!(i->monthmask & (1 << tm.tm_mon))) 06386 return 0; 06387 06388 /* If it's not that time of the month.... */ 06389 /* Warning, tm_mday has range 1..31! */ 06390 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 06391 return 0; 06392 06393 /* If it's not the right day of the week */ 06394 if (!(i->dowmask & (1 << tm.tm_wday))) 06395 return 0; 06396 06397 /* Sanity check the hour just to be safe */ 06398 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 06399 ast_log(LOG_WARNING, "Insane time...\n"); 06400 return 0; 06401 } 06402 06403 /* Now the tough part, we calculate if it fits 06404 in the right time based on min/hour */ 06405 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 06406 return 0; 06407 06408 /* If we got this far, then we're good */ 06409 return 1; 06410 }
int ast_context_add_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Add an ignorepat.
context | which context to add the ignorpattern to | |
ignorepat | ignorepattern to set up for the extension | |
registrar | registrar of the ignore pattern |
0 | on success | |
-1 | on failure |
Definition at line 6603 of file pbx.c.
References ast_context_add_ignorepat2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_cli_dialplan_add_ignorepat().
06604 { 06605 int ret = -1; 06606 struct ast_context *c = find_context_locked(context); 06607 06608 if (c) { 06609 ret = ast_context_add_ignorepat2(c, value, registrar); 06610 ast_unlock_contexts(); 06611 } 06612 return ret; 06613 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 6615 of file pbx.c.
References ast_calloc, ast_unlock_context(), ast_wrlock_context(), errno, ast_context::ignorepats, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.
Referenced by ast_context_add_ignorepat(), context_merge_incls_swits_igps_other_registrars(), and pbx_load_config().
06616 { 06617 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 06618 int length; 06619 char *pattern; 06620 length = sizeof(struct ast_ignorepat); 06621 length += strlen(value) + 1; 06622 if (!(ignorepat = ast_calloc(1, length))) 06623 return -1; 06624 /* The cast to char * is because we need to write the initial value. 06625 * The field is not supposed to be modified otherwise. Also, gcc 4.2 06626 * sees the cast as dereferencing a type-punned pointer and warns about 06627 * it. This is the workaround (we're telling gcc, yes, that's really 06628 * what we wanted to do). 06629 */ 06630 pattern = (char *) ignorepat->pattern; 06631 strcpy(pattern, value); 06632 ignorepat->next = NULL; 06633 ignorepat->registrar = registrar; 06634 ast_wrlock_context(con); 06635 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 06636 ignorepatl = ignorepatc; 06637 if (!strcasecmp(ignorepatc->pattern, value)) { 06638 /* Already there */ 06639 ast_unlock_context(con); 06640 errno = EEXIST; 06641 return -1; 06642 } 06643 } 06644 if (ignorepatl) 06645 ignorepatl->next = ignorepat; 06646 else 06647 con->ignorepats = ignorepat; 06648 ast_unlock_context(con); 06649 return 0; 06650 06651 }
int ast_context_add_include | ( | const char * | context, | |
const char * | include, | |||
const char * | registrar | |||
) |
Add a context include.
context | context to add include to | |
include | new include to add | |
registrar | who's registering it |
0 | on success | |
-1 | on error |
Definition at line 6157 of file pbx.c.
References ast_context_add_include2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_cli_dialplan_add_include().
06158 { 06159 int ret = -1; 06160 struct ast_context *c = find_context_locked(context); 06161 06162 if (c) { 06163 ret = ast_context_add_include2(c, include, registrar); 06164 ast_unlock_contexts(); 06165 } 06166 return ret; 06167 }
int ast_context_add_include2 | ( | struct ast_context * | con, | |
const char * | include, | |||
const char * | registrar | |||
) |
Add a context include.
con | context to add the include to | |
include | include to add | |
registrar | who registered the context |
0 | on success | |
-1 | on failure |
Definition at line 6419 of file pbx.c.
References ast_build_timing(), ast_calloc, ast_free, ast_get_context_name(), ast_unlock_context(), ast_verb, ast_wrlock_context(), errno, ast_include::hastime, ast_context::includes, ast_include::name, ast_include::next, ast_include::registrar, ast_include::rname, ast_include::stuff, and ast_include::timing.
Referenced by ast_context_add_include(), context_merge_incls_swits_igps_other_registrars(), and pbx_load_config().
06421 { 06422 struct ast_include *new_include; 06423 char *c; 06424 struct ast_include *i, *il = NULL; /* include, include_last */ 06425 int length; 06426 char *p; 06427 06428 length = sizeof(struct ast_include); 06429 length += 2 * (strlen(value) + 1); 06430 06431 /* allocate new include structure ... */ 06432 if (!(new_include = ast_calloc(1, length))) 06433 return -1; 06434 /* Fill in this structure. Use 'p' for assignments, as the fields 06435 * in the structure are 'const char *' 06436 */ 06437 p = new_include->stuff; 06438 new_include->name = p; 06439 strcpy(p, value); 06440 p += strlen(value) + 1; 06441 new_include->rname = p; 06442 strcpy(p, value); 06443 /* Strip off timing info, and process if it is there */ 06444 if ( (c = strchr(p, ',')) ) { 06445 *c++ = '\0'; 06446 new_include->hastime = ast_build_timing(&(new_include->timing), c); 06447 } 06448 new_include->next = NULL; 06449 new_include->registrar = registrar; 06450 06451 ast_wrlock_context(con); 06452 06453 /* ... go to last include and check if context is already included too... */ 06454 for (i = con->includes; i; i = i->next) { 06455 if (!strcasecmp(i->name, new_include->name)) { 06456 ast_free(new_include); 06457 ast_unlock_context(con); 06458 errno = EEXIST; 06459 return -1; 06460 } 06461 il = i; 06462 } 06463 06464 /* ... include new context into context list, unlock, return */ 06465 if (il) 06466 il->next = new_include; 06467 else 06468 con->includes = new_include; 06469 ast_verb(3, "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 06470 06471 ast_unlock_context(con); 06472 06473 return 0; 06474 }
int ast_context_add_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
int | eval, | |||
const char * | registrar | |||
) |
Add a switch.
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 |
0 | on success | |
-1 | on failure |
Definition at line 6481 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
06482 { 06483 int ret = -1; 06484 struct ast_context *c = find_context_locked(context); 06485 06486 if (c) { /* found, add switch to this context */ 06487 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 06488 ast_unlock_contexts(); 06489 } 06490 return ret; 06491 }
int ast_context_add_switch2 | ( | struct ast_context * | con, | |
const char * | sw, | |||
const char * | data, | |||
int | eval, | |||
const char * | registrar | |||
) |
Adds a switch (first param is a ast_context).
Definition at line 6500 of file pbx.c.
References ast_context::alts, ast_calloc, ast_free, ast_get_context_name(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_sw::data, errno, ast_sw::eval, store_hint::list, ast_sw::name, ast_sw::registrar, and ast_sw::stuff.
Referenced by ast_context_add_switch(), context_merge_incls_swits_igps_other_registrars(), lua_register_switches(), and pbx_load_config().
06502 { 06503 struct ast_sw *new_sw; 06504 struct ast_sw *i; 06505 int length; 06506 char *p; 06507 06508 length = sizeof(struct ast_sw); 06509 length += strlen(value) + 1; 06510 if (data) 06511 length += strlen(data); 06512 length++; 06513 06514 /* allocate new sw structure ... */ 06515 if (!(new_sw = ast_calloc(1, length))) 06516 return -1; 06517 /* ... fill in this structure ... */ 06518 p = new_sw->stuff; 06519 new_sw->name = p; 06520 strcpy(new_sw->name, value); 06521 p += strlen(value) + 1; 06522 new_sw->data = p; 06523 if (data) { 06524 strcpy(new_sw->data, data); 06525 p += strlen(data) + 1; 06526 } else { 06527 strcpy(new_sw->data, ""); 06528 p++; 06529 } 06530 new_sw->eval = eval; 06531 new_sw->registrar = registrar; 06532 06533 /* ... try to lock this context ... */ 06534 ast_wrlock_context(con); 06535 06536 /* ... go to last sw and check if context is already swd too... */ 06537 AST_LIST_TRAVERSE(&con->alts, i, list) { 06538 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 06539 ast_free(new_sw); 06540 ast_unlock_context(con); 06541 errno = EEXIST; 06542 return -1; 06543 } 06544 } 06545 06546 /* ... sw new context into context list, unlock, return */ 06547 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 06548 06549 ast_verb(3, "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 06550 06551 ast_unlock_context(con); 06552 06553 return 0; 06554 }
void ast_context_destroy | ( | struct ast_context * | con, | |
const char * | registrar | |||
) |
Destroy a context (matches the specified context (or ANY context if NULL).
con | context to destroy | |
registrar | who registered it |
Definition at line 7798 of file pbx.c.
References __ast_context_destroy(), ast_unlock_contexts(), ast_wrlock_contexts(), contexts, and contexts_table.
Referenced by __unload_module(), cleanup_stale_contexts(), parkinglot_destroy(), sla_destroy(), and unload_module().
07799 { 07800 ast_wrlock_contexts(); 07801 __ast_context_destroy(contexts, contexts_table, con,registrar); 07802 ast_unlock_contexts(); 07803 }
struct ast_context* ast_context_find | ( | const char * | name | ) |
Find a context.
name | name of the context to find |
Definition at line 2012 of file pbx.c.
References ast_copy_string(), ast_hashtab_lookup(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), contexts_table, ast_context::name, and fake_context::name.
Referenced by __unload_module(), _macro_exec(), ast_context_verify_includes(), ast_ignore_pattern(), cleanup_stale_contexts(), isexten_function_read(), manage_parkinglot(), park_exec_full(), parkinglot_destroy(), register_exten(), register_peer_exten(), unload_module(), and unregister_exten().
02013 { 02014 struct ast_context *tmp = NULL; 02015 struct fake_context item; 02016 02017 ast_copy_string(item.name, name, sizeof(item.name)); 02018 02019 ast_rdlock_contexts(); 02020 if( contexts_table ) { 02021 tmp = ast_hashtab_lookup(contexts_table,&item); 02022 } else { 02023 while ( (tmp = ast_walk_contexts(tmp)) ) { 02024 if (!name || !strcasecmp(name, tmp->name)) 02025 break; 02026 } 02027 } 02028 ast_unlock_contexts(); 02029 return tmp; 02030 }
struct ast_context* ast_context_find_or_create | ( | struct ast_context ** | extcontexts, | |
struct ast_hashtab * | exttable, | |||
const char * | name, | |||
const char * | registrar | |||
) |
Register a new context or find an existing one.
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 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.
Definition at line 5814 of file pbx.c.
References ast_calloc, ast_copy_string(), ast_debug, ast_hashtab_compare_contexts(), ast_hashtab_create(), ast_hashtab_hash_contexts(), ast_hashtab_insert_immediate(), ast_hashtab_insert_safe(), ast_hashtab_lookup(), ast_hashtab_newsize_java(), ast_hashtab_resize_java(), ast_log(), ast_mutex_init(), ast_rdlock_contexts(), ast_rwlock_init(), ast_strdup, ast_unlock_contexts(), ast_verb, ast_wrlock_contexts(), contexts, contexts_table, ast_context::ignorepats, ast_context::includes, local_contexts, ast_context::lock, LOG_ERROR, ast_context::macrolock, ast_context::name, fake_context::name, name, ast_context::next, ast_context::refcount, ast_context::registrar, ast_context::root, and ast_context::root_table.
Referenced by ast_park_call_full(), build_parkinglot(), context_merge(), load_module(), lua_register_switches(), manage_parkinglot(), pbx_load_config(), pbx_load_users(), reload_config(), and set_config().
05815 { 05816 struct ast_context *tmp, **local_contexts; 05817 struct fake_context search; 05818 int length = sizeof(struct ast_context) + strlen(name) + 1; 05819 05820 if (!contexts_table) { 05821 contexts_table = ast_hashtab_create(17, 05822 ast_hashtab_compare_contexts, 05823 ast_hashtab_resize_java, 05824 ast_hashtab_newsize_java, 05825 ast_hashtab_hash_contexts, 05826 0); 05827 } 05828 05829 ast_copy_string(search.name, name, sizeof(search.name)); 05830 if (!extcontexts) { 05831 ast_rdlock_contexts(); 05832 local_contexts = &contexts; 05833 tmp = ast_hashtab_lookup(contexts_table, &search); 05834 ast_unlock_contexts(); 05835 if (tmp) { 05836 tmp->refcount++; 05837 return tmp; 05838 } 05839 } else { /* local contexts just in a linked list; search there for the new context; slow, linear search, but not frequent */ 05840 local_contexts = extcontexts; 05841 tmp = ast_hashtab_lookup(exttable, &search); 05842 if (tmp) { 05843 tmp->refcount++; 05844 return tmp; 05845 } 05846 } 05847 05848 if ((tmp = ast_calloc(1, length))) { 05849 ast_rwlock_init(&tmp->lock); 05850 ast_mutex_init(&tmp->macrolock); 05851 strcpy(tmp->name, name); 05852 tmp->root = NULL; 05853 tmp->root_table = NULL; 05854 tmp->registrar = ast_strdup(registrar); 05855 tmp->includes = NULL; 05856 tmp->ignorepats = NULL; 05857 tmp->refcount = 1; 05858 } else { 05859 ast_log(LOG_ERROR, "Danger! We failed to allocate a context for %s!\n", name); 05860 return NULL; 05861 } 05862 05863 if (!extcontexts) { 05864 ast_wrlock_contexts(); 05865 tmp->next = *local_contexts; 05866 *local_contexts = tmp; 05867 ast_hashtab_insert_safe(contexts_table, tmp); /*put this context into the tree */ 05868 ast_unlock_contexts(); 05869 ast_debug(1, "Registered context '%s'(%p) in table %p registrar: %s\n", tmp->name, tmp, contexts_table, registrar); 05870 ast_verb(3, "Registered extension context '%s' (%p) in table %p; registrar: %s\n", tmp->name, tmp, contexts_table, registrar); 05871 } else { 05872 tmp->next = *local_contexts; 05873 if (exttable) 05874 ast_hashtab_insert_immediate(exttable, tmp); /*put this context into the tree */ 05875 05876 *local_contexts = tmp; 05877 ast_debug(1, "Registered context '%s'(%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar); 05878 ast_verb(3, "Registered extension context '%s' (%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar); 05879 } 05880 return tmp; 05881 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 4461 of file pbx.c.
References ast_copy_string(), ast_get_context_name(), ast_hashtab_lookup(), ast_mutex_lock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), contexts_table, ast_context::macrolock, and fake_context::name.
Referenced by _macro_exec().
04462 { 04463 struct ast_context *c = NULL; 04464 int ret = -1; 04465 struct fake_context item; 04466 04467 ast_rdlock_contexts(); 04468 04469 ast_copy_string(item.name, context, sizeof(item.name)); 04470 04471 c = ast_hashtab_lookup(contexts_table,&item); 04472 if (c) 04473 ret = 0; 04474 04475 04476 #ifdef NOTNOW 04477 04478 while ((c = ast_walk_contexts(c))) { 04479 if (!strcmp(ast_get_context_name(c), context)) { 04480 ret = 0; 04481 break; 04482 } 04483 } 04484 04485 #endif 04486 ast_unlock_contexts(); 04487 04488 /* if we found context, lock macrolock */ 04489 if (ret == 0) 04490 ret = ast_mutex_lock(&c->macrolock); 04491 04492 return ret; 04493 }
int ast_context_remove_extension | ( | const char * | context, | |
const char * | extension, | |||
int | priority, | |||
const char * | registrar | |||
) |
Simply remove extension from context.
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 |
0 | on success | |
-1 | on failure |
Definition at line 4268 of file pbx.c.
References ast_context_remove_extension_callerid().
Referenced by destroy_station(), destroy_trunk(), register_peer_exten(), unregister_exten(), and UnregisterExtension().
04269 { 04270 return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar); 04271 }
int ast_context_remove_extension2 | ( | struct ast_context * | con, | |
const char * | extension, | |||
int | priority, | |||
const char * | registrar, | |||
int | already_locked | |||
) |
This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return.
Definition at line 4295 of file pbx.c.
References ast_context_remove_extension_callerid2().
Referenced by manage_parkinglot(), park_exec_full(), and unload_module().
04296 { 04297 return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar, already_locked); 04298 }
int ast_context_remove_extension_callerid | ( | const char * | context, | |
const char * | extension, | |||
int | priority, | |||
const char * | callerid, | |||
int | matchcid, | |||
const char * | registrar | |||
) |
Definition at line 4273 of file pbx.c.
References ast_context_remove_extension_callerid2(), ast_unlock_contexts(), and find_context_locked().
Referenced by ast_context_remove_extension(), and handle_cli_dialplan_remove_extension().
04274 { 04275 int ret = -1; /* default error return */ 04276 struct ast_context *c = find_context_locked(context); 04277 04278 if (c) { /* ... remove extension ... */ 04279 ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcallerid, registrar, 1); 04280 ast_unlock_contexts(); 04281 } 04282 return ret; 04283 }
int ast_context_remove_extension_callerid2 | ( | struct ast_context * | con, | |
const char * | extension, | |||
int | priority, | |||
const char * | callerid, | |||
int | matchcid, | |||
const char * | registrar, | |||
int | already_locked | |||
) |
Definition at line 4300 of file pbx.c.
References add_exten_to_pattern_tree(), ast_copy_string(), ast_hashtab_insert_immediate(), ast_hashtab_lookup(), ast_hashtab_remove_this_object(), ast_hashtab_size(), ast_log(), ast_strlen_zero(), ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_exten::cidmatch, destroy_exten(), ast_exten::exten, exten, ast_exten::label, LOG_ERROR, log_match_char_tree(), LOG_NOTICE, LOG_WARNING, ast_exten::matchcid, ast_exten::next, ast_exten::peer, ast_exten::peer_label_table, ast_exten::peer_table, ast_exten::priority, ast_exten::registrar, and match_char::x.
Referenced by __ast_context_destroy(), ast_context_remove_extension2(), and ast_context_remove_extension_callerid().
04301 { 04302 struct ast_exten *exten, *prev_exten = NULL; 04303 struct ast_exten *peer; 04304 struct ast_exten ex, *exten2, *exten3; 04305 char dummy_name[1024]; 04306 struct ast_exten *previous_peer = NULL; 04307 struct ast_exten *next_peer = NULL; 04308 int found = 0; 04309 04310 if (!already_locked) 04311 ast_wrlock_context(con); 04312 04313 /* Handle this is in the new world */ 04314 04315 /* FIXME For backwards compatibility, if callerid==NULL, then remove ALL 04316 * peers, not just those matching the callerid. */ 04317 #ifdef NEED_DEBUG 04318 ast_verb(3,"Removing %s/%s/%d%s%s from trees, registrar=%s\n", con->name, extension, priority, matchcallerid ? "/" : "", matchcallerid ? callerid : "", registrar); 04319 #endif 04320 #ifdef CONTEXT_DEBUG 04321 check_contexts(__FILE__, __LINE__); 04322 #endif 04323 /* find this particular extension */ 04324 ex.exten = dummy_name; 04325 ex.matchcid = matchcallerid && !ast_strlen_zero(callerid); /* don't say match if there's no callerid */ 04326 ex.cidmatch = callerid; 04327 ast_copy_string(dummy_name, extension, sizeof(dummy_name)); 04328 exten = ast_hashtab_lookup(con->root_table, &ex); 04329 if (exten) { 04330 if (priority == 0) { 04331 exten2 = ast_hashtab_remove_this_object(con->root_table, exten); 04332 if (!exten2) 04333 ast_log(LOG_ERROR,"Trying to delete the exten %s from context %s, but could not remove from the root_table\n", extension, con->name); 04334 if (con->pattern_tree) { 04335 04336 struct match_char *x = add_exten_to_pattern_tree(con, exten, 1); 04337 04338 if (x->exten) { /* this test for safety purposes */ 04339 x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */ 04340 x->exten = 0; /* get rid of what will become a bad pointer */ 04341 } else { 04342 ast_log(LOG_WARNING,"Trying to delete an exten from a context, but the pattern tree node returned isn't a full extension\n"); 04343 } 04344 } 04345 } else { 04346 ex.priority = priority; 04347 exten2 = ast_hashtab_lookup(exten->peer_table, &ex); 04348 if (exten2) { 04349 04350 if (exten2->label) { /* if this exten has a label, remove that, too */ 04351 exten3 = ast_hashtab_remove_this_object(exten->peer_label_table,exten2); 04352 if (!exten3) 04353 ast_log(LOG_ERROR,"Did not remove this priority label (%d/%s) from the peer_label_table of context %s, extension %s!\n", priority, exten2->label, con->name, exten2->exten); 04354 } 04355 04356 exten3 = ast_hashtab_remove_this_object(exten->peer_table, exten2); 04357 if (!exten3) 04358 ast_log(LOG_ERROR,"Did not remove this priority (%d) from the peer_table of context %s, extension %s!\n", priority, con->name, exten2->exten); 04359 if (exten2 == exten && exten2->peer) { 04360 exten2 = ast_hashtab_remove_this_object(con->root_table, exten); 04361 ast_hashtab_insert_immediate(con->root_table, exten2->peer); 04362 } 04363 if (ast_hashtab_size(exten->peer_table) == 0) { 04364 /* well, if the last priority of an exten is to be removed, 04365 then, the extension is removed, too! */ 04366 exten3 = ast_hashtab_remove_this_object(con->root_table, exten); 04367 if (!exten3) 04368 ast_log(LOG_ERROR,"Did not remove this exten (%s) from the context root_table (%s) (priority %d)\n", exten->exten, con->name, priority); 04369 if (con->pattern_tree) { 04370 struct match_char *x = add_exten_to_pattern_tree(con, exten, 1); 04371 if (x->exten) { /* this test for safety purposes */ 04372 x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */ 04373 x->exten = 0; /* get rid of what will become a bad pointer */ 04374 } 04375 } 04376 } 04377 } else { 04378 ast_log(LOG_ERROR,"Could not find priority %d of exten %s in context %s!\n", 04379 priority, exten->exten, con->name); 04380 } 04381 } 04382 } else { 04383 /* hmmm? this exten is not in this pattern tree? */ 04384 ast_log(LOG_WARNING,"Cannot find extension %s in root_table in context %s\n", 04385 extension, con->name); 04386 } 04387 #ifdef NEED_DEBUG 04388 if (con->pattern_tree) { 04389 ast_log(LOG_NOTICE,"match char tree after exten removal:\n"); 04390 log_match_char_tree(con->pattern_tree, " "); 04391 } 04392 #endif 04393 04394 /* scan the extension list to find first matching extension-registrar */ 04395 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 04396 if (!strcmp(exten->exten, extension) && 04397 (!registrar || !strcmp(exten->registrar, registrar)) && 04398 (!matchcallerid || (!ast_strlen_zero(callerid) && !ast_strlen_zero(exten->cidmatch) && !strcmp(exten->cidmatch, callerid)) || (ast_strlen_zero(callerid) && ast_strlen_zero(exten->cidmatch)))) 04399 break; 04400 } 04401 if (!exten) { 04402 /* we can't find right extension */ 04403 if (!already_locked) 04404 ast_unlock_context(con); 04405 return -1; 04406 } 04407 04408 /* scan the priority list to remove extension with exten->priority == priority */ 04409 for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next; 04410 peer && !strcmp(peer->exten, extension) && (!matchcallerid || (!ast_strlen_zero(callerid) && !ast_strlen_zero(peer->cidmatch) && !strcmp(peer->cidmatch,callerid)) || (ast_strlen_zero(callerid) && ast_strlen_zero(peer->cidmatch))); 04411 peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) { 04412 if ((priority == 0 || peer->priority == priority) && 04413 (!callerid || !matchcallerid || (matchcallerid && !strcmp(peer->cidmatch, callerid))) && 04414 (!registrar || !strcmp(peer->registrar, registrar) )) { 04415 found = 1; 04416 04417 /* we are first priority extension? */ 04418 if (!previous_peer) { 04419 /* 04420 * We are first in the priority chain, so must update the extension chain. 04421 * The next node is either the next priority or the next extension 04422 */ 04423 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 04424 if (peer->peer) { 04425 /* move the peer_table and peer_label_table down to the next peer, if 04426 it is there */ 04427 peer->peer->peer_table = peer->peer_table; 04428 peer->peer->peer_label_table = peer->peer_label_table; 04429 peer->peer_table = NULL; 04430 peer->peer_label_table = NULL; 04431 } 04432 if (!prev_exten) { /* change the root... */ 04433 con->root = next_node; 04434 } else { 04435 prev_exten->next = next_node; /* unlink */ 04436 } 04437 if (peer->peer) { /* update the new head of the pri list */ 04438 peer->peer->next = peer->next; 04439 } 04440 } else { /* easy, we are not first priority in extension */ 04441 previous_peer->peer = peer->peer; 04442 } 04443 04444 /* now, free whole priority extension */ 04445 destroy_exten(peer); 04446 } else { 04447 previous_peer = peer; 04448 } 04449 } 04450 if (!already_locked) 04451 ast_unlock_context(con); 04452 return found ? 0 : -1; 04453 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 6560 of file pbx.c.
References ast_context_remove_ignorepat2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_cli_dialplan_remove_ignorepat().
06561 { 06562 int ret = -1; 06563 struct ast_context *c = find_context_locked(context); 06564 06565 if (c) { 06566 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 06567 ast_unlock_contexts(); 06568 } 06569 return ret; 06570 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 6572 of file pbx.c.
References ast_free, ast_unlock_context(), ast_wrlock_context(), errno, ast_context::ignorepats, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.
Referenced by ast_context_remove_ignorepat().
06573 { 06574 struct ast_ignorepat *ip, *ipl = NULL; 06575 06576 ast_wrlock_context(con); 06577 06578 for (ip = con->ignorepats; ip; ip = ip->next) { 06579 if (!strcmp(ip->pattern, ignorepat) && 06580 (!registrar || (registrar == ip->registrar))) { 06581 if (ipl) { 06582 ipl->next = ip->next; 06583 ast_free(ip); 06584 } else { 06585 con->ignorepats = ip->next; 06586 ast_free(ip); 06587 } 06588 ast_unlock_context(con); 06589 return 0; 06590 } 06591 ipl = ip; 06592 } 06593 06594 ast_unlock_context(con); 06595 errno = EINVAL; 06596 return -1; 06597 }
int ast_context_remove_include | ( | const char * | context, | |
const char * | include, | |||
const char * | registrar | |||
) |
Remove a context include.
0 | on success | |
-1 | on failure |
Definition at line 4160 of file pbx.c.
References ast_context_remove_include2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_cli_dialplan_remove_include().
04161 { 04162 int ret = -1; 04163 struct ast_context *c = find_context_locked(context); 04164 04165 if (c) { 04166 /* found, remove include from this context ... */ 04167 ret = ast_context_remove_include2(c, include, registrar); 04168 ast_unlock_contexts(); 04169 } 04170 return ret; 04171 }
int ast_context_remove_include2 | ( | struct ast_context * | con, | |
const char * | include, | |||
const char * | registrar | |||
) |
Removes an include by an ast_context structure.
0 | on success. | |
-1 | on failure. |
Definition at line 4182 of file pbx.c.
References ast_free, ast_get_context_name(), ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_context::includes, ast_include::name, ast_include::next, and ast_include::registrar.
Referenced by ast_context_remove_include().
04183 { 04184 struct ast_include *i, *pi = NULL; 04185 int ret = -1; 04186 04187 ast_wrlock_context(con); 04188 04189 /* find our include */ 04190 for (i = con->includes; i; pi = i, i = i->next) { 04191 if (!strcmp(i->name, include) && 04192 (!registrar || !strcmp(i->registrar, registrar))) { 04193 /* remove from list */ 04194 ast_verb(3, "Removing inclusion of context '%s' in context '%s; registrar=%s'\n", include, ast_get_context_name(con), registrar); 04195 if (pi) 04196 pi->next = i->next; 04197 else 04198 con->includes = i->next; 04199 /* free include and return */ 04200 ast_free(i); 04201 ret = 0; 04202 break; 04203 } 04204 } 04205 04206 ast_unlock_context(con); 04207 04208 return ret; 04209 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 4216 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
04217 { 04218 int ret = -1; /* default error return */ 04219 struct ast_context *c = find_context_locked(context); 04220 04221 if (c) { 04222 /* remove switch from this context ... */ 04223 ret = ast_context_remove_switch2(c, sw, data, registrar); 04224 ast_unlock_contexts(); 04225 } 04226 return ret; 04227 }
int ast_context_remove_switch2 | ( | struct ast_context * | con, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
This function locks given context, removes switch, unlock context and return.
Definition at line 4237 of file pbx.c.
References ast_context::alts, ast_free, ast_get_context_name(), AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_sw::data, ast_sw::list, ast_sw::name, and ast_sw::registrar.
Referenced by ast_context_remove_switch().
04238 { 04239 struct ast_sw *i; 04240 int ret = -1; 04241 04242 ast_wrlock_context(con); 04243 04244 /* walk switches */ 04245 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 04246 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 04247 (!registrar || !strcmp(i->registrar, registrar))) { 04248 /* found, remove from list */ 04249 ast_verb(3, "Removing switch '%s' from context '%s; registrar=%s'\n", sw, ast_get_context_name(con), registrar); 04250 AST_LIST_REMOVE_CURRENT(list); 04251 ast_free(i); /* free switch and return */ 04252 ret = 0; 04253 break; 04254 } 04255 } 04256 AST_LIST_TRAVERSE_SAFE_END; 04257 04258 ast_unlock_context(con); 04259 04260 return ret; 04261 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 4500 of file pbx.c.
References ast_copy_string(), ast_get_context_name(), ast_hashtab_lookup(), ast_mutex_unlock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), contexts_table, ast_context::macrolock, and fake_context::name.
Referenced by _macro_exec().
04501 { 04502 struct ast_context *c = NULL; 04503 int ret = -1; 04504 struct fake_context item; 04505 04506 ast_rdlock_contexts(); 04507 04508 ast_copy_string(item.name, context, sizeof(item.name)); 04509 04510 c = ast_hashtab_lookup(contexts_table,&item); 04511 if (c) 04512 ret = 0; 04513 #ifdef NOTNOW 04514 04515 while ((c = ast_walk_contexts(c))) { 04516 if (!strcmp(ast_get_context_name(c), context)) { 04517 ret = 0; 04518 break; 04519 } 04520 } 04521 04522 #endif 04523 ast_unlock_contexts(); 04524 04525 /* if we found context, unlock macrolock */ 04526 if (ret == 0) 04527 ret = ast_mutex_unlock(&c->macrolock); 04528 04529 return ret; 04530 }
int ast_context_verify_includes | ( | struct ast_context * | con | ) |
Verifies includes in an ast_contect structure.
con | context in which to verify the includes |
0 | if no problems found | |
-1 | if there were any missing context |
Definition at line 8860 of file pbx.c.
References ast_context_find(), ast_get_context_name(), ast_log(), ast_walk_context_includes(), LOG_WARNING, and ast_include::rname.
Referenced by pbx_load_module().
08861 { 08862 struct ast_include *inc = NULL; 08863 int res = 0; 08864 08865 while ( (inc = ast_walk_context_includes(con, inc)) ) { 08866 if (ast_context_find(inc->rname)) 08867 continue; 08868 08869 res = -1; 08870 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 08871 ast_get_context_name(con), inc->rname); 08872 break; 08873 } 08874 08875 return res; 08876 }
struct ast_custom_function* ast_custom_function_find | ( | const char * | name | ) |
Definition at line 2763 of file pbx.c.
References ast_custom_function::acflist, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, and ast_custom_function::name.
Referenced by ast_func_read(), ast_func_write(), config_curl(), destroy_curl(), handle_show_function(), op_func(), realtime_curl(), realtime_multi_curl(), require_curl(), store_curl(), and update_curl().
02764 { 02765 struct ast_custom_function *acf = NULL; 02766 02767 AST_RWLIST_RDLOCK(&acf_root); 02768 AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) { 02769 if (!strcmp(name, acf->name)) 02770 break; 02771 } 02772 AST_RWLIST_UNLOCK(&acf_root); 02773 02774 return acf; 02775 }
int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Unregister a custom function.
Definition at line 2777 of file pbx.c.
References ast_custom_function::acflist, AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, and ast_custom_function::name.
Referenced by load_module(), reload(), and unload_module().
02778 { 02779 struct ast_custom_function *cur; 02780 02781 if (!acf) 02782 return -1; 02783 02784 AST_RWLIST_WRLOCK(&acf_root); 02785 if ((cur = AST_RWLIST_REMOVE(&acf_root, acf, acflist))) 02786 ast_verb(2, "Unregistered custom function %s\n", cur->name); 02787 AST_RWLIST_UNLOCK(&acf_root); 02788 02789 return cur ? 0 : -1; 02790 }
int ast_exists_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) |
Determine whether an extension exists.
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 |
Definition at line 3621 of file pbx.c.
References E_MATCH, and pbx_extension_helper().
Referenced by __ast_goto_if_exists(), __ast_pbx_run(), _macro_exec(), acf_isexten_exec(), answer_call(), ast_app_dtget(), ast_bridge_call(), ast_pbx_outgoing_exten(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), cli_console_dial(), conf_run(), console_dial(), console_transfer(), dahdi_handle_dtmfup(), dial_exec_full(), disa_exec(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), gosub_exec(), handle_gosub(), handle_link_data(), handle_link_phone_dtmf(), handle_stimulus_message(), isexten_function_read(), leave_voicemail(), local_alloc(), local_call(), local_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), minivm_greet_exec(), misdn_overlap_dial_task(), park_space_reserve(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), pri_dchannel(), privacy_exec(), process_ast_dsp(), readexten_exec(), register_peer_exten(), rpt_exec(), show_debug_helper(), skinny_ss(), socket_process(), ss_thread(), and waitstream_core().
03622 { 03623 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0, 0); 03624 }
int ast_explicit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6707 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_FLAG_IN_AUTOLOOP, ast_strlen_zero(), ast_test_flag, chan, ast_channel::context, ast_channel::exten, and ast_channel::priority.
Referenced by __ast_goto_if_exists(), ast_async_goto(), builtin_atxfer(), do_bridge_masquerade(), handle_setpriority(), pbx_parseable_goto(), and return_exec().
06708 { 06709 if (!chan) 06710 return -1; 06711 06712 ast_channel_lock(chan); 06713 06714 if (!ast_strlen_zero(context)) 06715 ast_copy_string(chan->context, context, sizeof(chan->context)); 06716 if (!ast_strlen_zero(exten)) 06717 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 06718 if (priority > -1) { 06719 chan->priority = priority; 06720 /* see flag description in channel.h for explanation */ 06721 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 06722 chan->priority--; 06723 } 06724 06725 ast_channel_unlock(chan); 06726 06727 return 0; 06728 }
int ast_extension_close | ( | const char * | pattern, | |
const char * | data, | |||
int | needmore | |||
) |
Definition at line 1989 of file pbx.c.
References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.
Referenced by lua_find_extension(), and realtime_switch_common().
01990 { 01991 if (needmore != E_MATCHMORE && needmore != E_CANMATCH) 01992 ast_log(LOG_WARNING, "invalid argument %d\n", needmore); 01993 return extension_match_core(pattern, data, needmore); 01994 }
int ast_extension_cmp | ( | const char * | a, | |
const char * | b | |||
) |
Determine if one extension should match before another.
a | extension to compare with b | |
b | extension to compare with a |
0 | if the two extensions have equal matching priority | |
1 | on a > b | |
-1 | on a < b |
Definition at line 1791 of file pbx.c.
References ext_cmp().
Referenced by lua_extension_cmp().
01792 { 01793 return ext_cmp(a, b); 01794 }
int ast_extension_match | ( | const char * | pattern, | |
const char * | extension | |||
) |
Determine if a given extension matches a given pattern (in NXX format).
pattern | pattern to match | |
extension | extension to check against the pattern. |
1 | on match | |
0 | on failure |
Definition at line 1984 of file pbx.c.
References E_MATCH, and extension_match_core().
Referenced by ast_ignore_pattern(), do_say(), find_matching_priority(), load_module(), loopback_canmatch(), loopback_exists(), loopback_matchmore(), lua_find_extension(), manager_show_dialplan_helper(), matchcid(), misdn_cfg_is_msn_valid(), realtime_switch_common(), reload(), and show_dialplan_helper().
01985 { 01986 return extension_match_core(pattern, data, E_MATCH); 01987 }
int ast_extension_patmatch | ( | const char * | pattern, | |
const char * | data | |||
) |
int ast_extension_state | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten | |||
) |
Uses hint and devicestate callback to get the state of an extension.
c | this is not important | |
context | which context to look in | |
exten | which extension to get state |
Definition at line 3313 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), extstate_read(), and handle_request_subscribe().
03314 { 03315 struct ast_exten *e; 03316 03317 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 03318 if (!e) 03319 return -1; /* No hint, return -1 */ 03320 03321 return ast_extension_state2(e); /* Check all devices in the hint */ 03322 }
const char* ast_extension_state2str | ( | int | extension_state | ) |
Return string representation of the state of an extension.
extension_state | is the numerical state delivered by ast_extension_state |
Definition at line 3301 of file pbx.c.
References ARRAY_LEN, extension_states, and cfextension_states::text.
Referenced by cb_extensionstate(), handle_request_subscribe(), handle_show_hint(), handle_show_hints(), and show_channels_cb().
03302 { 03303 int i; 03304 03305 for (i = 0; (i < ARRAY_LEN(extension_states)); i++) { 03306 if (extension_states[i].extension_state == extension_state) 03307 return extension_states[i].text; 03308 } 03309 return "Unknown"; 03310 }
int ast_extension_state_add | ( | const char * | context, | |
const char * | exten, | |||
ast_state_cb_type | callback, | |||
void * | data | |||
) |
Registers a state change callback.
context | which context to look in | |
exten | which extension to get state | |
callback | callback to call if state changed | |
data | to pass to callback |
-1 | on failure | |
ID | on success |
Definition at line 3374 of file pbx.c.
References ast_exten::app, ast_add_extension(), ast_calloc, ast_free_ptr, ast_hint_extension(), AST_LIST_INSERT_HEAD, AST_LIST_TRAVERSE, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_state_cb::callback, ast_hint::callbacks, ast_exten::cidmatch, ast_exten::data, ast_state_cb::data, ast_hint::exten, ast_exten::exten, ast_exten::label, ast_context::name, ast_exten::parent, ast_exten::priority, ast_exten::registrar, and stateid.
Referenced by __init_manager(), handle_request_subscribe(), and skinny_register().
03376 { 03377 struct ast_hint *hint; 03378 struct ast_state_cb *cblist; 03379 struct ast_exten *e; 03380 03381 /* If there's no context and extension: add callback to statecbs list */ 03382 if (!context && !exten) { 03383 AST_RWLIST_WRLOCK(&hints); 03384 03385 AST_LIST_TRAVERSE(&statecbs, cblist, entry) { 03386 if (cblist->callback == callback) { 03387 cblist->data = data; 03388 AST_RWLIST_UNLOCK(&hints); 03389 return 0; 03390 } 03391 } 03392 03393 /* Now insert the callback */ 03394 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 03395 AST_RWLIST_UNLOCK(&hints); 03396 return -1; 03397 } 03398 cblist->id = 0; 03399 cblist->callback = callback; 03400 cblist->data = data; 03401 03402 AST_LIST_INSERT_HEAD(&statecbs, cblist, entry); 03403 03404 AST_RWLIST_UNLOCK(&hints); 03405 03406 return 0; 03407 } 03408 03409 if (!context || !exten) 03410 return -1; 03411 03412 /* This callback type is for only one hint, so get the hint */ 03413 e = ast_hint_extension(NULL, context, exten); 03414 if (!e) { 03415 return -1; 03416 } 03417 03418 /* If this is a pattern, dynamically create a new extension for this 03419 * particular match. Note that this will only happen once for each 03420 * individual extension, because the pattern will no longer match first. 03421 */ 03422 if (e->exten[0] == '_') { 03423 ast_add_extension(e->parent->name, 0, exten, e->priority, e->label, 03424 e->cidmatch, e->app, ast_strdup(e->data), ast_free_ptr, 03425 e->registrar); 03426 e = ast_hint_extension(NULL, context, exten); 03427 if (!e || e->exten[0] == '_') { 03428 return -1; 03429 } 03430 } 03431 03432 /* Find the hint in the list of hints */ 03433 AST_RWLIST_WRLOCK(&hints); 03434 03435 AST_RWLIST_TRAVERSE(&hints, hint, list) { 03436 if (hint->exten == e) 03437 break; 03438 } 03439 03440 if (!hint) { 03441 /* We have no hint, sorry */ 03442 AST_RWLIST_UNLOCK(&hints); 03443 return -1; 03444 } 03445 03446 /* Now insert the callback in the callback list */ 03447 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 03448 AST_RWLIST_UNLOCK(&hints); 03449 return -1; 03450 } 03451 03452 cblist->id = stateid++; /* Unique ID for this callback */ 03453 cblist->callback = callback; /* Pointer to callback routine */ 03454 cblist->data = data; /* Data for the callback */ 03455 03456 AST_LIST_INSERT_HEAD(&hint->callbacks, cblist, entry); 03457 03458 AST_RWLIST_UNLOCK(&hints); 03459 03460 return cblist->id; 03461 }
int ast_extension_state_del | ( | int | id, | |
ast_state_cb_type | callback | |||
) |
Deletes a registered state change callback by ID.
id | of the callback to delete | |
callback | callback |
0 | success | |
-1 | failure |
Definition at line 3464 of file pbx.c.
References ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::entry, ast_state_cb::id, and ast_hint::list.
Referenced by dialog_unlink_all(), handle_request_subscribe(), and skinny_unregister().
03465 { 03466 struct ast_state_cb *p_cur = NULL; 03467 int ret = -1; 03468 03469 if (!id && !callback) 03470 return -1; 03471 03472 AST_RWLIST_WRLOCK(&hints); 03473 03474 if (!id) { /* id == 0 is a callback without extension */ 03475 AST_LIST_TRAVERSE_SAFE_BEGIN(&statecbs, p_cur, entry) { 03476 if (p_cur->callback == callback) { 03477 AST_LIST_REMOVE_CURRENT(entry); 03478 break; 03479 } 03480 } 03481 AST_LIST_TRAVERSE_SAFE_END; 03482 } else { /* callback with extension, find the callback based on ID */ 03483 struct ast_hint *hint; 03484 AST_RWLIST_TRAVERSE(&hints, hint, list) { 03485 AST_LIST_TRAVERSE_SAFE_BEGIN(&hint->callbacks, p_cur, entry) { 03486 if (p_cur->id == id) { 03487 AST_LIST_REMOVE_CURRENT(entry); 03488 break; 03489 } 03490 } 03491 AST_LIST_TRAVERSE_SAFE_END; 03492 03493 if (p_cur) 03494 break; 03495 } 03496 } 03497 03498 if (p_cur) { 03499 ast_free(p_cur); 03500 } 03501 03502 AST_RWLIST_UNLOCK(&hints); 03503 03504 return ret; 03505 }
int ast_findlabel_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
const char * | label, | |||
const char * | callerid | |||
) |
Find the priority of an extension that has the specified label.
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 |
the | priority which matches the given label in the extension | |
-1 | if not found. |
Definition at line 3626 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by action_originate(), action_redirect(), handle_gosub(), handle_setpriority(), isexten_function_read(), and pbx_parseable_goto().
03627 { 03628 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0, 0); 03629 }
int ast_findlabel_extension2 | ( | struct ast_channel * | c, | |
struct ast_context * | con, | |||
const char * | exten, | |||
const char * | label, | |||
const char * | callerid | |||
) |
Find the priority of an extension that has the specified label.
This function is the same as ast_findlabel_extension, except that it accepts a pointer to an ast_context structure to specify the context instead of the name of the context. Otherwise, the functions behave the same.
Definition at line 3631 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
03632 { 03633 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0, 0); 03634 }
int ast_func_read | ( | struct ast_channel * | chan, | |
const char * | function, | |||
char * | workspace, | |||
size_t | len | |||
) |
executes a read operation on a function
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 |
Definition at line 2850 of file pbx.c.
References __ast_module_user_add(), __ast_module_user_remove(), ast_custom_function_find(), ast_log(), ast_strdupa, chan, copy(), func_args(), LOG_ERROR, ast_custom_function::mod, and ast_custom_function::read.
Referenced by action_getvar(), action_status(), handle_getvariable(), lua_get_variable_value(), and pbx_substitute_variables_helper_full().
02851 { 02852 char *copy = ast_strdupa(function); 02853 char *args = func_args(copy); 02854 struct ast_custom_function *acfptr = ast_custom_function_find(copy); 02855 02856 if (acfptr == NULL) 02857 ast_log(LOG_ERROR, "Function %s not registered\n", copy); 02858 else if (!acfptr->read) 02859 ast_log(LOG_ERROR, "Function %s cannot be read\n", copy); 02860 else { 02861 int res; 02862 struct ast_module_user *u = NULL; 02863 if (acfptr->mod) 02864 u = __ast_module_user_add(acfptr->mod, chan); 02865 res = acfptr->read(chan, copy, args, workspace, len); 02866 if (acfptr->mod && u) 02867 __ast_module_user_remove(acfptr->mod, u); 02868 return res; 02869 } 02870 return -1; 02871 }
int ast_func_write | ( | struct ast_channel * | chan, | |
const char * | function, | |||
const char * | value | |||
) |
executes a write operation on a function
chan | Channel to execute on | |
function | Data containing the function call string (will be modified) | |
value | A value parameter to pass for writing |
Definition at line 2873 of file pbx.c.
References __ast_module_user_add(), __ast_module_user_remove(), ast_custom_function_find(), ast_log(), ast_strdupa, chan, copy(), func_args(), LOG_ERROR, ast_custom_function::mod, and ast_custom_function::write.
Referenced by pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().
02874 { 02875 char *copy = ast_strdupa(function); 02876 char *args = func_args(copy); 02877 struct ast_custom_function *acfptr = ast_custom_function_find(copy); 02878 02879 if (acfptr == NULL) 02880 ast_log(LOG_ERROR, "Function %s not registered\n", copy); 02881 else if (!acfptr->write) 02882 ast_log(LOG_ERROR, "Function %s cannot be written to\n", copy); 02883 else { 02884 int res; 02885 struct ast_module_user *u = NULL; 02886 if (acfptr->mod) 02887 u = __ast_module_user_add(acfptr->mod, chan); 02888 res = acfptr->write(chan, copy, args, value); 02889 if (acfptr->mod && u) 02890 __ast_module_user_remove(acfptr->mod, u); 02891 return res; 02892 } 02893 02894 return -1; 02895 }
const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 8712 of file pbx.c.
References ast_context::name.
Referenced by _macro_exec(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_lockmacro(), ast_context_remove_include2(), ast_context_remove_switch2(), ast_context_unlockmacro(), ast_context_verify_includes(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), context_merge_incls_swits_igps_other_registrars(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_cli_dialplan_save(), handle_show_hint(), handle_show_hints(), manager_show_dialplan_helper(), show_debug_helper(), and show_dialplan_helper().
08713 { 08714 return con ? con->name : NULL; 08715 }
const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 8750 of file pbx.c.
References ast_context::registrar.
Referenced by handle_cli_dialplan_save(), show_debug_helper(), and show_dialplan_helper().
08751 { 08752 return c ? c->registrar : NULL; 08753 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 8780 of file pbx.c.
References ast_exten::app.
Referenced by _macro_exec(), ast_add_hint_nolock(), ast_extension_state2(), ast_get_hint(), find_matching_endwhile(), handle_cli_dialplan_save(), handle_show_hint(), handle_show_hints(), handle_statechange(), manager_show_dialplan_helper(), and print_ext().
08781 { 08782 return e ? e->app : NULL; 08783 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 8785 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and print_ext().
08786 { 08787 return e ? e->data : NULL; 08788 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 8775 of file pbx.c.
References ast_exten::cidmatch.
Referenced by complete_dialplan_remove_extension(), find_matching_priority(), and handle_cli_dialplan_save().
08776 { 08777 return e ? e->cidmatch : NULL; 08778 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
Definition at line 8717 of file pbx.c.
References exten.
Referenced by handle_show_hint(), and handle_show_hints().
const char* ast_get_extension_label | ( | struct ast_exten * | e | ) |
Definition at line 8727 of file pbx.c.
References exten.
Referenced by handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
int ast_get_extension_matchcid | ( | struct ast_exten * | e | ) |
Definition at line 8770 of file pbx.c.
References ast_exten::matchcid.
Referenced by complete_dialplan_remove_extension(), find_matching_priority(), and handle_cli_dialplan_save().
08771 { 08772 return e ? e->matchcid : 0; 08773 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 8722 of file pbx.c.
References exten.
Referenced by ast_add_hint_nolock(), complete_core_show_hint(), complete_dialplan_remove_extension(), dundi_precache_full(), find_matching_priority(), handle_cli_dialplan_save(), handle_show_hint(), handle_show_hints(), manager_show_dialplan_helper(), and show_dialplan_helper().
int ast_get_extension_priority | ( | struct ast_exten * | exten | ) |
Definition at line 8742 of file pbx.c.
References exten.
Referenced by complete_dialplan_remove_extension(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and print_ext().
const char* ast_get_extension_registrar | ( | struct ast_exten * | e | ) |
Definition at line 8755 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08756 { 08757 return e ? e->registrar : NULL; 08758 }
int ast_get_hint | ( | char * | hint, | |
int | maxlen, | |||
char * | name, | |||
int | maxnamelen, | |||
struct ast_channel * | c, | |||
const char * | context, | |||
const char * | exten | |||
) |
If an extension hint exists, return non-zero.
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 |
Definition at line 3604 of file pbx.c.
References ast_copy_string(), ast_get_extension_app(), ast_get_extension_app_data(), and ast_hint_extension().
Referenced by action_extensionstate(), get_cid_name(), get_destination(), hint_read(), manager_state_cb(), pbx_retrieve_variable(), skinny_extensionstate_cb(), and transmit_state_notify().
03605 { 03606 struct ast_exten *e = ast_hint_extension(c, context, exten); 03607 03608 if (e) { 03609 if (hint) 03610 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 03611 if (name) { 03612 const char *tmp = ast_get_extension_app_data(e); 03613 if (tmp) 03614 ast_copy_string(name, tmp, namesize); 03615 } 03616 return -1; 03617 } 03618 return 0; 03619 }
const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 8737 of file pbx.c.
References ast_ignorepat::pattern.
Referenced by complete_dialplan_remove_ignorepat(), context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), lookup_c_ip(), manager_show_dialplan_helper(), and show_dialplan_helper().
08738 { 08739 return ip ? ip->pattern : NULL; 08740 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 8765 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08766 { 08767 return ip ? ip->registrar : NULL; 08768 }
const char* ast_get_include_name | ( | struct ast_include * | include | ) |
Definition at line 8732 of file pbx.c.
References ast_include::name.
Referenced by complete_dialplan_remove_include(), context_merge_incls_swits_igps_other_registrars(), find_matching_priority(), handle_cli_dialplan_save(), lookup_ci(), manager_show_dialplan_helper(), and show_dialplan_helper().
const char* ast_get_include_registrar | ( | struct ast_include * | i | ) |
Definition at line 8760 of file pbx.c.
References ast_include::registrar.
Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08761 { 08762 return i ? i->registrar : NULL; 08763 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 8795 of file pbx.c.
References ast_sw::data.
Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08796 { 08797 return sw ? sw->data : NULL; 08798 }
int ast_get_switch_eval | ( | struct ast_sw * | sw | ) |
Definition at line 8800 of file pbx.c.
References ast_sw::eval.
Referenced by context_merge_incls_swits_igps_other_registrars().
08801 { 08802 return sw->eval; 08803 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 8790 of file pbx.c.
References ast_sw::name.
Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08791 { 08792 return sw ? sw->name : NULL; 08793 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 8805 of file pbx.c.
References ast_sw::registrar.
Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08806 { 08807 return sw ? sw->registrar : NULL; 08808 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 8898 of file pbx.c.
References __ast_goto_if_exists(), and chan.
Referenced by background_detect_exec(), channel_spy(), common_exec(), conf_run(), goto_exten(), onedigit_goto(), priority_jump(), select_entry(), and valid_exit().
08899 { 08900 return __ast_goto_if_exists(chan, context, exten, priority, 0); 08901 }
int ast_hashtab_compare_contexts | ( | const void * | ah_a, | |
const void * | ah_b | |||
) |
unsigned int ast_hashtab_hash_contexts | ( | const void * | obj | ) |
int ast_ignore_pattern | ( | const char * | context, | |
const char * | pattern | |||
) |
Checks to see if a number should be ignored.
context | context to search within | |
pattern | to check whether it should be ignored or not |
0 | if the pattern should not be ignored | |
non-zero | if the pattern should be ignored |
Definition at line 6653 of file pbx.c.
References ast_context_find(), ast_extension_match(), ast_context::ignorepats, ast_ignorepat::next, and ast_ignorepat::pattern.
Referenced by ast_app_dtget(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_enbloc_call_message(), handle_soft_key_event_message(), handle_stimulus_message(), mgcp_ss(), skinny_ss(), and ss_thread().
06654 { 06655 struct ast_context *con = ast_context_find(context); 06656 if (con) { 06657 struct ast_ignorepat *pat; 06658 for (pat = con->ignorepats; pat; pat = pat->next) { 06659 if (ast_extension_match(pat->pattern, pattern)) 06660 return 1; 06661 } 06662 } 06663 06664 return 0; 06665 }
int ast_matchmore_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) |
Looks to see if adding anything to this extension might match something. (exists ^ canmatch).
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 |
Definition at line 3641 of file pbx.c.
References E_MATCHMORE, and pbx_extension_helper().
Referenced by ast_app_dtget(), collect_digits(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_link_data(), handle_link_phone_dtmf(), local_dtmf_helper(), loopback_matchmore(), mgcp_ss(), readexten_exec(), skinny_ss(), and ss_thread().
03642 { 03643 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0); 03644 }
void ast_merge_contexts_and_delete | ( | struct ast_context ** | extcontexts, | |
struct ast_hashtab * | exttable, | |||
const char * | registrar | |||
) |
Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added.
extcontexts | pointer to the ast_context structure | |
exttable | pointer to the ast_hashtab structure that contains all the elements in extcontexts | |
registrar | of the context; if it's set the routine will delete all contexts that belong to that registrar; if NULL only the contexts that are specified in extcontexts |
Definition at line 6013 of file pbx.c.
References __ast_internal_context_destroy(), ast_add_extension_nolock(), ast_calloc, AST_EXTENSION_REMOVED, ast_free, ast_free_ptr, ast_hashtab_destroy(), ast_hashtab_end_traversal(), ast_hashtab_next(), ast_hashtab_start_traversal(), ast_hint_extension_nolock(), AST_LIST_APPEND_LIST, AST_LIST_EMPTY, AST_LIST_HEAD_INIT_VALUE, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_rdlock_contexts(), AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_tvdiff_us(), ast_tvnow(), ast_unlock_contexts(), ast_verb, ast_wrlock_contexts(), ast_wrlock_contexts_version(), ast_state_cb::callback, ast_hint::callbacks, context_merge(), contexts, contexts_table, ast_state_cb::data, E_MATCH, ast_exten::exten, ast_hint::exten, store_hint::exten, ast_hint::laststate, store_hint::list, LOG_WARNING, ast_context::name, ast_context::next, store_hint::next, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_context::registrar, and pbx_find_info::stacklen.
Referenced by lua_reload_extensions(), and pbx_load_module().
06014 { 06015 double ft; 06016 struct ast_context *tmp, *oldcontextslist; 06017 struct ast_hashtab *oldtable; 06018 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 06019 struct store_hint *this; 06020 struct ast_hint *hint; 06021 struct ast_exten *exten; 06022 int length; 06023 struct ast_state_cb *thiscb; 06024 struct ast_hashtab_iter *iter; 06025 06026 /* it is very important that this function hold the hint list lock _and_ the conlock 06027 during its operation; not only do we need to ensure that the list of contexts 06028 and extensions does not change, but also that no hint callbacks (watchers) are 06029 added or removed during the merge/delete process 06030 06031 in addition, the locks _must_ be taken in this order, because there are already 06032 other code paths that use this order 06033 */ 06034 06035 struct timeval begintime, writelocktime, endlocktime, enddeltime; 06036 int wrlock_ver; 06037 06038 begintime = ast_tvnow(); 06039 ast_rdlock_contexts(); 06040 iter = ast_hashtab_start_traversal(contexts_table); 06041 while ((tmp = ast_hashtab_next(iter))) { 06042 context_merge(extcontexts, exttable, tmp, registrar); 06043 } 06044 ast_hashtab_end_traversal(iter); 06045 wrlock_ver = ast_wrlock_contexts_version(); 06046 06047 ast_unlock_contexts(); /* this feels real retarded, but you must do 06048 what you must do If this isn't done, the following 06049 wrlock is a guraranteed deadlock */ 06050 ast_wrlock_contexts(); 06051 if (ast_wrlock_contexts_version() > wrlock_ver+1) { 06052 ast_log(LOG_WARNING,"==================!!!!!!!!!!!!!!!Something changed the contexts in the middle of merging contexts!\n"); 06053 } 06054 06055 AST_RWLIST_WRLOCK(&hints); 06056 writelocktime = ast_tvnow(); 06057 06058 /* preserve all watchers for hints associated with this registrar */ 06059 AST_RWLIST_TRAVERSE(&hints, hint, list) { 06060 if (!AST_LIST_EMPTY(&hint->callbacks) && !strcmp(registrar, hint->exten->parent->registrar)) { 06061 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 06062 if (!(this = ast_calloc(1, length))) 06063 continue; 06064 AST_LIST_APPEND_LIST(&this->callbacks, &hint->callbacks, entry); 06065 this->laststate = hint->laststate; 06066 this->context = this->data; 06067 strcpy(this->data, hint->exten->parent->name); 06068 this->exten = this->data + strlen(this->context) + 1; 06069 strcpy(this->exten, hint->exten->exten); 06070 AST_LIST_INSERT_HEAD(&store, this, list); 06071 } 06072 } 06073 06074 /* save the old table and list */ 06075 oldtable = contexts_table; 06076 oldcontextslist = contexts; 06077 06078 /* move in the new table and list */ 06079 contexts_table = exttable; 06080 contexts = *extcontexts; 06081 06082 /* restore the watchers for hints that can be found; notify those that 06083 cannot be restored 06084 */ 06085 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 06086 struct pbx_find_info q = { .stacklen = 0 }; 06087 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 06088 /* If this is a pattern, dynamically create a new extension for this 06089 * particular match. Note that this will only happen once for each 06090 * individual extension, because the pattern will no longer match first. 06091 */ 06092 if (exten && exten->exten[0] == '_') { 06093 ast_add_extension_nolock(exten->parent->name, 0, this->exten, PRIORITY_HINT, NULL, 06094 0, exten->app, ast_strdup(exten->data), ast_free_ptr, registrar); 06095 /* rwlocks are not recursive locks */ 06096 exten = ast_hint_extension_nolock(NULL, this->context, this->exten); 06097 } 06098 06099 /* Find the hint in the list of hints */ 06100 AST_RWLIST_TRAVERSE(&hints, hint, list) { 06101 if (hint->exten == exten) 06102 break; 06103 } 06104 if (!exten || !hint) { 06105 /* this hint has been removed, notify the watchers */ 06106 while ((thiscb = AST_LIST_REMOVE_HEAD(&this->callbacks, entry))) { 06107 thiscb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, thiscb->data); 06108 ast_free(thiscb); 06109 } 06110 } else { 06111 AST_LIST_APPEND_LIST(&hint->callbacks, &this->callbacks, entry); 06112 hint->laststate = this->laststate; 06113 } 06114 ast_free(this); 06115 } 06116 06117 AST_RWLIST_UNLOCK(&hints); 06118 ast_unlock_contexts(); 06119 endlocktime = ast_tvnow(); 06120 06121 /* the old list and hashtab no longer are relevant, delete them while the rest of asterisk 06122 is now freely using the new stuff instead */ 06123 06124 ast_hashtab_destroy(oldtable, NULL); 06125 06126 for (tmp = oldcontextslist; tmp; ) { 06127 struct ast_context *next; /* next starting point */ 06128 next = tmp->next; 06129 __ast_internal_context_destroy(tmp); 06130 tmp = next; 06131 } 06132 enddeltime = ast_tvnow(); 06133 06134 ft = ast_tvdiff_us(writelocktime, begintime); 06135 ft /= 1000000.0; 06136 ast_verb(3,"Time to scan old dialplan and merge leftovers back into the new: %8.6f sec\n", ft); 06137 06138 ft = ast_tvdiff_us(endlocktime, writelocktime); 06139 ft /= 1000000.0; 06140 ast_verb(3,"Time to restore hints and swap in new dialplan: %8.6f sec\n", ft); 06141 06142 ft = ast_tvdiff_us(enddeltime, endlocktime); 06143 ft /= 1000000.0; 06144 ast_verb(3,"Time to delete the old dialplan: %8.6f sec\n", ft); 06145 06146 ft = ast_tvdiff_us(enddeltime, begintime); 06147 ft /= 1000000.0; 06148 ast_verb(3,"Total time merge_contexts_delete: %8.6f sec\n", ft); 06149 return; 06150 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
This function will handle locking the channel as needed.
Definition at line 8961 of file pbx.c.
References chan, and pbx_parseable_goto().
Referenced by _while_exec(), check_goto_on_transfer(), dial_exec_full(), gosub_exec(), ivr_dispatch(), parkandannounce_exec(), pbx_builtin_goto(), and while_continue_exec().
08962 { 08963 return pbx_parseable_goto(chan, goto_string, 0); 08964 }
int ast_pbx_outgoing_app | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int | timeout, | |||
const char * | app, | |||
const char * | appdata, | |||
int * | reason, | |||
int | sync, | |||
const char * | cid_num, | |||
const char * | cid_name, | |||
struct ast_variable * | vars, | |||
const char * | account, | |||
struct ast_channel ** | locked_channel | |||
) |
Synchronously or asynchronously make an outbound call and send it to a particular application with given extension
Definition at line 7489 of file pbx.c.
References __ast_request_and_dial(), ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_free, ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create_detached, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verb, async_wait(), chan, errno, LOG_WARNING, and outgoing_helper::vars.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_app().
07490 { 07491 struct ast_channel *chan; 07492 struct app_tmp *tmp; 07493 int res = -1, cdr_res = -1; 07494 struct outgoing_helper oh; 07495 07496 memset(&oh, 0, sizeof(oh)); 07497 oh.vars = vars; 07498 oh.account = account; 07499 07500 if (locked_channel) 07501 *locked_channel = NULL; 07502 if (ast_strlen_zero(app)) { 07503 res = -1; 07504 goto outgoing_app_cleanup; 07505 } 07506 if (synchronous) { 07507 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 07508 if (chan) { 07509 ast_set_variables(chan, vars); 07510 if (account) 07511 ast_cdr_setaccount(chan, account); 07512 if (chan->_state == AST_STATE_UP) { 07513 res = 0; 07514 ast_verb(4, "Channel %s was answered.\n", chan->name); 07515 tmp = ast_calloc(1, sizeof(*tmp)); 07516 if (!tmp) 07517 res = -1; 07518 else { 07519 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 07520 if (appdata) 07521 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 07522 tmp->chan = chan; 07523 if (synchronous > 1) { 07524 if (locked_channel) 07525 ast_channel_unlock(chan); 07526 ast_pbx_run_app(tmp); 07527 } else { 07528 if (locked_channel) 07529 ast_channel_lock(chan); 07530 if (ast_pthread_create_detached(&tmp->t, NULL, ast_pbx_run_app, tmp)) { 07531 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 07532 ast_free(tmp); 07533 if (locked_channel) 07534 ast_channel_unlock(chan); 07535 ast_hangup(chan); 07536 res = -1; 07537 } else { 07538 if (locked_channel) 07539 *locked_channel = chan; 07540 } 07541 } 07542 } 07543 } else { 07544 ast_verb(4, "Channel %s was never answered.\n", chan->name); 07545 if (chan->cdr) { /* update the cdr */ 07546 /* here we update the status of the call, which sould be busy. 07547 * if that fails then we set the status to failed */ 07548 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 07549 ast_cdr_failed(chan->cdr); 07550 } 07551 ast_hangup(chan); 07552 } 07553 } 07554 07555 if (res < 0) { /* the call failed for some reason */ 07556 if (*reason == 0) { /* if the call failed (not busy or no answer) 07557 * update the cdr with the failed message */ 07558 cdr_res = ast_pbx_outgoing_cdr_failed(); 07559 if (cdr_res != 0) { 07560 res = cdr_res; 07561 goto outgoing_app_cleanup; 07562 } 07563 } 07564 } 07565 07566 } else { 07567 struct async_stat *as; 07568 if (!(as = ast_calloc(1, sizeof(*as)))) { 07569 res = -1; 07570 goto outgoing_app_cleanup; 07571 } 07572 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 07573 if (!chan) { 07574 ast_free(as); 07575 res = -1; 07576 goto outgoing_app_cleanup; 07577 } 07578 as->chan = chan; 07579 ast_copy_string(as->app, app, sizeof(as->app)); 07580 if (appdata) 07581 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 07582 as->timeout = timeout; 07583 ast_set_variables(chan, vars); 07584 if (account) 07585 ast_cdr_setaccount(chan, account); 07586 /* Start a new thread, and get something handling this channel. */ 07587 if (locked_channel) 07588 ast_channel_lock(chan); 07589 if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) { 07590 ast_log(LOG_WARNING, "Failed to start async wait\n"); 07591 ast_free(as); 07592 if (locked_channel) 07593 ast_channel_unlock(chan); 07594 ast_hangup(chan); 07595 res = -1; 07596 goto outgoing_app_cleanup; 07597 } else { 07598 if (locked_channel) 07599 *locked_channel = chan; 07600 } 07601 res = 0; 07602 } 07603 outgoing_app_cleanup: 07604 ast_variables_destroy(vars); 07605 return res; 07606 }
int ast_pbx_outgoing_exten | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int | timeout, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
int * | reason, | |||
int | sync, | |||
const char * | cid_num, | |||
const char * | cid_name, | |||
struct ast_variable * | vars, | |||
const char * | account, | |||
struct ast_channel ** | locked_channel | |||
) |
Synchronously or asynchronously make an outbound call and send it to a particular extension
Definition at line 7323 of file pbx.c.
References __ast_request_and_dial(), ast_channel::_state, outgoing_helper::account, ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_alloc(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_exists_extension(), ast_free, ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create_detached, ast_request_and_dial(), ast_set_variables(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verb, async_wait(), ast_channel::cdr, chan, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::context, outgoing_helper::context, outgoing_helper::exten, ast_channel::hangupcause, LOG_ERROR, LOG_WARNING, ast_channel::name, outgoing_helper::parent_channel, pbx_builtin_setvar_helper(), outgoing_helper::priority, set_ext_pri(), and outgoing_helper::vars.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_exten().
07324 { 07325 struct ast_channel *chan; 07326 struct async_stat *as; 07327 int res = -1, cdr_res = -1; 07328 struct outgoing_helper oh; 07329 07330 if (synchronous) { 07331 oh.context = context; 07332 oh.exten = exten; 07333 oh.priority = priority; 07334 oh.cid_num = cid_num; 07335 oh.cid_name = cid_name; 07336 oh.account = account; 07337 oh.vars = vars; 07338 oh.parent_channel = NULL; 07339 07340 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 07341 if (channel) { 07342 *channel = chan; 07343 if (chan) 07344 ast_channel_lock(chan); 07345 } 07346 if (chan) { 07347 if (chan->_state == AST_STATE_UP) { 07348 res = 0; 07349 ast_verb(4, "Channel %s was answered.\n", chan->name); 07350 07351 if (synchronous > 1) { 07352 if (channel) 07353 ast_channel_unlock(chan); 07354 if (ast_pbx_run(chan)) { 07355 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 07356 if (channel) 07357 *channel = NULL; 07358 ast_hangup(chan); 07359 chan = NULL; 07360 res = -1; 07361 } 07362 } else { 07363 if (ast_pbx_start(chan)) { 07364 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 07365 if (channel) { 07366 *channel = NULL; 07367 ast_channel_unlock(chan); 07368 } 07369 ast_hangup(chan); 07370 res = -1; 07371 } 07372 chan = NULL; 07373 } 07374 } else { 07375 ast_verb(4, "Channel %s was never answered.\n", chan->name); 07376 07377 if (chan->cdr) { /* update the cdr */ 07378 /* here we update the status of the call, which sould be busy. 07379 * if that fails then we set the status to failed */ 07380 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 07381 ast_cdr_failed(chan->cdr); 07382 } 07383 07384 if (channel) { 07385 *channel = NULL; 07386 ast_channel_unlock(chan); 07387 } 07388 ast_hangup(chan); 07389 chan = NULL; 07390 } 07391 } 07392 07393 if (res < 0) { /* the call failed for some reason */ 07394 if (*reason == 0) { /* if the call failed (not busy or no answer) 07395 * update the cdr with the failed message */ 07396 cdr_res = ast_pbx_outgoing_cdr_failed(); 07397 if (cdr_res != 0) { 07398 res = cdr_res; 07399 goto outgoing_exten_cleanup; 07400 } 07401 } 07402 07403 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 07404 /* check if "failed" exists */ 07405 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 07406 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 07407 if (chan) { 07408 char failed_reason[4] = ""; 07409 if (!ast_strlen_zero(context)) 07410 ast_copy_string(chan->context, context, sizeof(chan->context)); 07411 set_ext_pri(chan, "failed", 1); 07412 ast_set_variables(chan, vars); 07413 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 07414 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 07415 if (account) 07416 ast_cdr_setaccount(chan, account); 07417 if (ast_pbx_run(chan)) { 07418 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 07419 ast_hangup(chan); 07420 } 07421 chan = NULL; 07422 } 07423 } 07424 } 07425 } else { 07426 if (!(as = ast_calloc(1, sizeof(*as)))) { 07427 res = -1; 07428 goto outgoing_exten_cleanup; 07429 } 07430 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 07431 if (channel) { 07432 *channel = chan; 07433 if (chan) 07434 ast_channel_lock(chan); 07435 } 07436 if (!chan) { 07437 ast_free(as); 07438 res = -1; 07439 goto outgoing_exten_cleanup; 07440 } 07441 as->chan = chan; 07442 ast_copy_string(as->context, context, sizeof(as->context)); 07443 set_ext_pri(as->chan, exten, priority); 07444 as->timeout = timeout; 07445 ast_set_variables(chan, vars); 07446 if (account) 07447 ast_cdr_setaccount(chan, account); 07448 if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) { 07449 ast_log(LOG_WARNING, "Failed to start async wait\n"); 07450 ast_free(as); 07451 if (channel) { 07452 *channel = NULL; 07453 ast_channel_unlock(chan); 07454 } 07455 ast_hangup(chan); 07456 res = -1; 07457 goto outgoing_exten_cleanup; 07458 } 07459 res = 0; 07460 } 07461 outgoing_exten_cleanup: 07462 ast_variables_destroy(vars); 07463 return res; 07464 }
enum ast_pbx_result ast_pbx_run | ( | struct ast_channel * | c | ) |
Execute the PBX in the current thread.
c | channel to run the pbx on |
Zero | on success | |
non-zero | on failure |
Definition at line 4069 of file pbx.c.
References ast_pbx_run_args().
Referenced by ast_pbx_outgoing_exten(), async_wait(), do_idle_thread(), mgcp_ss(), skinny_newcall(), ss_thread(), and unistim_ss().
04070 { 04071 return ast_pbx_run_args(c, NULL); 04072 }
enum ast_pbx_result ast_pbx_run_args | ( | struct ast_channel * | c, | |
struct ast_pbx_args * | args | |||
) |
Execute the PBX in the current thread.
c | channel to run the pbx on | |
args | options for the pbx |
Zero | on success | |
non-zero | on failure |
Definition at line 4054 of file pbx.c.
References __ast_pbx_run(), AST_PBX_CALL_LIMIT, AST_PBX_SUCCESS, decrease_call_count(), and increase_call_count().
Referenced by ast_pbx_run(), dial_exec_full(), handle_gosub(), and try_calling().
04055 { 04056 enum ast_pbx_result res = AST_PBX_SUCCESS; 04057 04058 if (increase_call_count(c)) { 04059 return AST_PBX_CALL_LIMIT; 04060 } 04061 04062 res = __ast_pbx_run(c, args); 04063 04064 decrease_call_count(); 04065 04066 return res; 04067 }
enum ast_pbx_result ast_pbx_start | ( | struct ast_channel * | c | ) |
Create a new thread and start the PBX.
c | channel to start the pbx on |
Zero | on success | |
non-zero | on failure |
Definition at line 4032 of file pbx.c.
References ast_log(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_pthread_create_detached, decrease_call_count(), increase_call_count(), LOG_WARNING, and pbx_thread().
Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_bridge_call_thread(), ast_iax2_new(), ast_pbx_outgoing_exten(), bridge_exec(), check_goto_on_transfer(), console_new(), dahdi_new(), dial_exec_full(), gtalk_new(), gtalk_newcall(), handle_request_invite(), jingle_new(), jingle_newcall(), local_call(), manage_parkinglot(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), skinny_new(), unistim_new(), and usbradio_new().
04033 { 04034 pthread_t t; 04035 04036 if (!c) { 04037 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 04038 return AST_PBX_FAILED; 04039 } 04040 04041 if (increase_call_count(c)) 04042 return AST_PBX_CALL_LIMIT; 04043 04044 /* Start a new thread, and get something handling this channel. */ 04045 if (ast_pthread_create_detached(&t, NULL, pbx_thread, c)) { 04046 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 04047 decrease_call_count(); 04048 return AST_PBX_FAILED; 04049 } 04050 04051 return AST_PBX_SUCCESS; 04052 }
int ast_processed_calls | ( | void | ) |
Retrieve the total number of calls processed through the PBX since last restart.
Definition at line 4079 of file pbx.c.
References totalcalls.
Referenced by handle_chanlist(), and handle_showcalls().
04080 { 04081 return totalcalls; 04082 }
int ast_rdlock_context | ( | struct ast_context * | con | ) |
Read locks a given context.
con | context to lock |
0 | on success | |
-1 | on failure |
Definition at line 8699 of file pbx.c.
References ast_rwlock_rdlock(), and ast_context::lock.
Referenced by _macro_exec(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_cli_dialplan_save(), lookup_c_ip(), lookup_ci(), manager_show_dialplan_helper(), show_debug_helper(), and show_dialplan_helper().
08700 { 08701 return ast_rwlock_rdlock(&con->lock); 08702 }
int ast_rdlock_contexts | ( | void | ) |
Read locks the context list.
0 | on success | |
-1 | on error |
Definition at line 8681 of file pbx.c.
References ast_rwlock_rdlock(), and conlock.
Referenced by _macro_exec(), ast_context_find(), ast_context_find_or_create(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_hint_extension(), ast_merge_contexts_and_delete(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_cli_dialplan_save(), handle_statechange(), manager_show_dialplan_helper(), pbx_extension_helper(), show_debug_helper(), show_dialplan_helper(), and unreference_cached_app().
08682 { 08683 return ast_rwlock_rdlock(&conlock); 08684 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 4584 of file pbx.c.
References ast_log(), AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_switch::list, LOG_WARNING, and ast_switch::name.
Referenced by load_module().
04585 { 04586 struct ast_switch *tmp; 04587 04588 AST_RWLIST_WRLOCK(&switches); 04589 AST_RWLIST_TRAVERSE(&switches, tmp, list) { 04590 if (!strcasecmp(tmp->name, sw->name)) { 04591 AST_RWLIST_UNLOCK(&switches); 04592 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 04593 return -1; 04594 } 04595 } 04596 AST_RWLIST_INSERT_TAIL(&switches, sw, list); 04597 AST_RWLIST_UNLOCK(&switches); 04598 04599 return 0; 04600 }
int ast_spawn_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
int * | found, | |||
int | combined_find_spawn | |||
) |
Launch a new extension (i.e. new stack).
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 |
0 | on success | |
-1 | on failure. |
Definition at line 3646 of file pbx.c.
References E_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), _macro_exec(), ast_bridge_call(), dial_exec_full(), and loopback_exec().
03647 { 03648 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn); 03649 }
int ast_unlock_context | ( | struct ast_context * | con | ) |
Unlocks | the given context |
con | context to unlock |
0 | on success | |
-1 | on failure |
Definition at line 8704 of file pbx.c.
References ast_rwlock_unlock(), and ast_context::lock.
Referenced by __ast_context_destroy(), _macro_exec(), ast_add_extension2_lockopt(), ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_remove_extension_callerid2(), ast_context_remove_ignorepat2(), ast_context_remove_include2(), ast_context_remove_switch2(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_cli_dialplan_save(), lookup_c_ip(), lookup_ci(), manager_show_dialplan_helper(), show_debug_helper(), and show_dialplan_helper().
08705 { 08706 return ast_rwlock_unlock(&con->lock); 08707 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 8686 of file pbx.c.
References ast_rwlock_unlock(), and conlock.
Referenced by _macro_exec(), ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_destroy(), ast_context_find(), ast_context_find_or_create(), ast_context_lockmacro(), ast_context_remove_extension_callerid(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_unlockmacro(), ast_hint_extension(), ast_merge_contexts_and_delete(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_cli_dialplan_save(), handle_statechange(), manager_show_dialplan_helper(), pbx_extension_helper(), show_debug_helper(), show_dialplan_helper(), and unreference_cached_app().
08687 { 08688 return ast_rwlock_unlock(&conlock); 08689 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 4602 of file pbx.c.
References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and ast_switch::list.
Referenced by __unload_module(), and unload_module().
04603 { 04604 AST_RWLIST_WRLOCK(&switches); 04605 AST_RWLIST_REMOVE(&switches, sw, list); 04606 AST_RWLIST_UNLOCK(&switches); 04607 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | priority | |||
) |
Definition at line 8818 of file pbx.c.
References exten, and ast_context::root.
Referenced by complete_dialplan_remove_extension(), dundi_precache_full(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), pbx_find_extension(), show_dialplan_helper(), and unreference_cached_app().
08820 { 08821 if (!exten) 08822 return con ? con->root : NULL; 08823 else 08824 return exten->next; 08825 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 8851 of file pbx.c.
References ast_context::ignorepats, and ast_ignorepat::next.
Referenced by complete_dialplan_remove_ignorepat(), context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), lookup_c_ip(), manager_show_dialplan_helper(), and show_dialplan_helper().
08853 { 08854 if (!ip) 08855 return con ? con->ignorepats : NULL; 08856 else 08857 return ip->next; 08858 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 8842 of file pbx.c.
References ast_context::includes, and ast_include::next.
Referenced by ast_context_verify_includes(), complete_dialplan_remove_include(), context_merge_incls_swits_igps_other_registrars(), find_matching_priority(), handle_cli_dialplan_save(), lookup_ci(), manager_show_dialplan_helper(), and show_dialplan_helper().
08844 { 08845 if (!inc) 08846 return con ? con->includes : NULL; 08847 else 08848 return inc->next; 08849 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 8827 of file pbx.c.
References ast_context::alts, AST_LIST_FIRST, AST_LIST_NEXT, and ast_sw::list.
Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08829 { 08830 if (!sw) 08831 return con ? AST_LIST_FIRST(&con->alts) : NULL; 08832 else 08833 return AST_LIST_NEXT(sw, list); 08834 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 8813 of file pbx.c.
References contexts, and ast_context::next.
Referenced by _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), pbx_find_extension(), pbx_load_module(), show_debug_helper(), show_dialplan_helper(), and unreference_cached_app().
struct ast_exten* ast_walk_extension_priorities | ( | struct ast_exten * | exten, | |
struct ast_exten * | priority | |||
) |
Definition at line 8836 of file pbx.c.
References exten, and ast_exten::priority.
Referenced by complete_dialplan_remove_extension(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), pbx_find_extension(), show_dialplan_helper(), and unreference_cached_app().
int ast_wrlock_context | ( | struct ast_context * | con | ) |
Write locks a given context.
con | context to lock |
0 | on success | |
-1 | on failure |
Definition at line 8694 of file pbx.c.
References ast_rwlock_wrlock(), and ast_context::lock.
Referenced by __ast_context_destroy(), ast_add_extension2_lockopt(), ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_remove_extension_callerid2(), ast_context_remove_ignorepat2(), ast_context_remove_include2(), and ast_context_remove_switch2().
08695 { 08696 return ast_rwlock_wrlock(&con->lock); 08697 }
int ast_wrlock_contexts | ( | void | ) |
Write locks the context list.
0 | on success | |
-1 | on error |
Definition at line 8673 of file pbx.c.
References ast_atomic_fetchadd_int(), ast_rwlock_wrlock(), and conlock.
Referenced by ast_context_destroy(), ast_context_find_or_create(), ast_merge_contexts_and_delete(), and complete_dialplan_remove_include().
08674 { 08675 int res = ast_rwlock_wrlock(&conlock); 08676 if (!res) 08677 ast_atomic_fetchadd_int(&conlock_wrlock_version, 1); 08678 return res; 08679 }
int ast_wrlock_contexts_version | ( | void | ) |
Definition at line 8665 of file pbx.c.
Referenced by ast_merge_contexts_and_delete().
08666 { 08667 return conlock_wrlock_version; 08668 }
void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 8510 of file pbx.c.
References AST_LIST_REMOVE_HEAD, ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_var_delete(), ast_var_t::entries, globals, and globalslock.
Referenced by handle_cli_dialplan_reload(), and reload().
08511 { 08512 struct ast_var_t *vardata; 08513 08514 ast_rwlock_wrlock(&globalslock); 08515 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 08516 ast_var_delete(vardata); 08517 ast_rwlock_unlock(&globalslock); 08518 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
This function will return a pointer to the buffer inside the channel variable. This value should only be accessed with the channel locked. If the value needs to be kept around, it should be done by using the following thread-safe code:
const char *var; ast_channel_lock(chan); if ((var = pbx_builtin_getvar_helper(chan, "MYVAR"))) { var = ast_strdupa(var); } ast_channel_unlock(chan);
Definition at line 8280 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_var_name(), ast_var_value(), chan, globals, and globalslock.
Referenced by _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), array(), ast_bridge_call(), ast_eivr_getvariable(), ast_feature_interpret(), ast_monitor_stop(), ast_park_call_full(), bridge_play_sounds(), builtin_atxfer(), builtin_automixmonitor(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dahdi_call(), dahdi_hangup(), dial_exec_full(), do_forward(), do_timelimit(), dundi_exec(), dundi_helper(), findparkinglotname(), get_also_info(), get_index(), get_refer_info(), global_read(), hash_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), local_read(), login_exec(), macro_fixup(), minivm_delete_exec(), minivm_notify_exec(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_space_reserve(), pickup_by_mark(), queue_exec(), real_ctx(), retrydial_exec(), ring_entry(), run_agi(), set_config_flags(), set_local_info(), sip_addheader(), sla_trunk_exec(), speech_background(), try_calling(), try_suggested_sip_codec(), and update_bridge_vars().
08281 { 08282 struct ast_var_t *variables; 08283 const char *ret = NULL; 08284 int i; 08285 struct varshead *places[2] = { NULL, &globals }; 08286 08287 if (!name) 08288 return NULL; 08289 08290 if (chan) { 08291 ast_channel_lock(chan); 08292 places[0] = &chan->varshead; 08293 } 08294 08295 for (i = 0; i < 2; i++) { 08296 if (!places[i]) 08297 continue; 08298 if (places[i] == &globals) 08299 ast_rwlock_rdlock(&globalslock); 08300 AST_LIST_TRAVERSE(places[i], variables, entries) { 08301 if (!strcmp(name, ast_var_name(variables))) { 08302 ret = ast_var_value(variables); 08303 break; 08304 } 08305 } 08306 if (places[i] == &globals) 08307 ast_rwlock_unlock(&globalslock); 08308 if (ret) 08309 break; 08310 } 08311 08312 if (chan) 08313 ast_channel_unlock(chan); 08314 08315 return ret; 08316 }
void pbx_builtin_pushvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 8318 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_strdupa, ast_var_assign(), ast_verb, chan, globals, globalslock, and LOG_WARNING.
Referenced by acf_odbc_read(), acf_odbc_write(), and frame_set_var().
08319 { 08320 struct ast_var_t *newvariable; 08321 struct varshead *headp; 08322 08323 if (name[strlen(name)-1] == ')') { 08324 char *function = ast_strdupa(name); 08325 08326 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 08327 ast_func_write(chan, function, value); 08328 return; 08329 } 08330 08331 if (chan) { 08332 ast_channel_lock(chan); 08333 headp = &chan->varshead; 08334 } else { 08335 ast_rwlock_wrlock(&globalslock); 08336 headp = &globals; 08337 } 08338 08339 if (value) { 08340 if (headp == &globals) 08341 ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value); 08342 newvariable = ast_var_assign(name, value); 08343 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 08344 } 08345 08346 if (chan) 08347 ast_channel_unlock(chan); 08348 else 08349 ast_rwlock_unlock(&globalslock); 08350 }
int pbx_builtin_raise_exception | ( | struct ast_channel * | chan, | |
void * | data | |||
) |
Definition at line 2576 of file pbx.c.
References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc(), ast_datastore_free(), ast_free, ast_string_field_init, ast_string_field_set, chan, ast_channel::context, ast_datastore::data, exception_store_info, ast_channel::exten, exten, ast_channel::priority, pbx_exception::priority, and set_ext_pri().
Referenced by __ast_pbx_run().
02577 { 02578 const char *reason = vreason; 02579 struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL); 02580 struct pbx_exception *exception = NULL; 02581 02582 if (!ds) { 02583 ds = ast_datastore_alloc(&exception_store_info, NULL); 02584 if (!ds) 02585 return -1; 02586 exception = ast_calloc(1, sizeof(struct pbx_exception)); 02587 if (!exception) { 02588 ast_datastore_free(ds); 02589 return -1; 02590 } 02591 if (ast_string_field_init(exception, 128)) { 02592 ast_free(exception); 02593 ast_datastore_free(ds); 02594 return -1; 02595 } 02596 ds->data = exception; 02597 ast_channel_datastore_add(chan, ds); 02598 } else 02599 exception = ds->data; 02600 02601 ast_string_field_set(exception, reason, reason); 02602 ast_string_field_set(exception, context, chan->context); 02603 ast_string_field_set(exception, exten, chan->exten); 02604 exception->priority = chan->priority; 02605 set_ext_pri(chan, "e", 0); 02606 return 0; 02607 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
struct ast_str ** | buf | |||
) |
Definition at line 8248 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_str_append(), ast_var_name(), ast_var_value(), buf, chan, ast_var_t::entries, LOG_ERROR, total, var, and ast_channel::varshead.
Referenced by dumpchan_exec(), handle_show_chanvar(), handle_showchan(), and vars2manager().
08249 { 08250 struct ast_var_t *variables; 08251 const char *var, *val; 08252 int total = 0; 08253 08254 if (!chan) 08255 return 0; 08256 08257 (*buf)->used = 0; 08258 (*buf)->str[0] = '\0'; 08259 08260 ast_channel_lock(chan); 08261 08262 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 08263 if ((var = ast_var_name(variables)) && (val = ast_var_value(variables)) 08264 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 08265 ) { 08266 if (ast_str_append(buf, 0, "%s=%s\n", var, val) < 0) { 08267 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 08268 break; 08269 } else 08270 total++; 08271 } else 08272 break; 08273 } 08274 08275 ast_channel_unlock(chan); 08276 08277 return total; 08278 }
int pbx_builtin_setvar | ( | struct ast_channel * | chan, | |
void * | data | |||
) |
void pbx_builtin_setvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 8352 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE, AST_LIST_TRAVERSE, ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verb, chan, EVENT_FLAG_DIALPLAN, globals, globalslock, manager_event, ast_channel::name, and ast_channel::uniqueid.
Referenced by __oh323_new(), _macro_exec(), _while_exec(), acf_fetch(), acf_odbc_read(), acf_odbc_write(), action_atxfer(), action_setvar(), agi_exec_full(), aji_status_exec(), aqm_exec(), array(), ast_bridge_call(), ast_eivr_setvariable(), ast_feature_request_and_dial(), ast_iax2_new(), ast_monitor_start(), ast_pbx_outgoing_exten(), ast_rtp_set_vars(), ast_set_variables(), asyncgoto_exec(), background_detect_exec(), bridge_exec(), bridge_play_sounds(), builtin_atxfer(), builtin_automixmonitor(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), channel_spy(), conf_run(), controlplayback_exec(), count_exec(), dahdi_handle_dtmfup(), dahdi_new(), dial_exec_full(), do_waiting(), end_bridge_callback(), export_aoc_vars(), export_ch(), frame_set_var(), function_db_delete(), function_db_exists(), function_db_read(), function_realtime_store(), get_rdnis(), get_refer_info(), global_write(), gosub_release_frame(), handle_request_bye(), handle_request_refer(), handle_set_chanvar(), handle_set_global(), handle_setvariable(), hash_read(), hash_write(), isAnsweringMachine(), leave_voicemail(), local_hangup(), lua_set_variable(), lua_set_variable_value(), macro_fixup(), manage_parkinglot(), minivm_accmess_exec(), minivm_delete_exec(), minivm_greet_exec(), minivm_notify_exec(), minivm_record_exec(), misdn_call(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_exec_full(), parse_moved_contact(), pbx_builtin_background(), pbx_builtin_importvar(), pbx_builtin_setvar(), pbx_builtin_setvar_multiple(), pbx_load_config(), phase_e_handler(), play_message_datetime(), playback_exec(), pqm_exec(), prep_email_sub_vars(), process_ast_dsp(), read_exec(), readexten_exec(), readfile_exec(), record_exec(), return_exec(), rotate_file(), rpt_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_hangup(), sip_new(), skinny_new(), sla_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), ss_thread(), start_monitor_exec(), system_exec_helper(), transfer_exec(), transmit(), tryexec_exec(), update_bridge_vars(), update_qe_rule(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), waituntil_exec(), and zapateller_exec().
08353 { 08354 struct ast_var_t *newvariable; 08355 struct varshead *headp; 08356 const char *nametail = name; 08357 08358 if (name[strlen(name) - 1] == ')') { 08359 char *function = ast_strdupa(name); 08360 08361 ast_func_write(chan, function, value); 08362 return; 08363 } 08364 08365 if (chan) { 08366 ast_channel_lock(chan); 08367 headp = &chan->varshead; 08368 } else { 08369 ast_rwlock_wrlock(&globalslock); 08370 headp = &globals; 08371 } 08372 08373 /* For comparison purposes, we have to strip leading underscores */ 08374 if (*nametail == '_') { 08375 nametail++; 08376 if (*nametail == '_') 08377 nametail++; 08378 } 08379 08380 AST_LIST_TRAVERSE (headp, newvariable, entries) { 08381 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 08382 /* there is already such a variable, delete it */ 08383 AST_LIST_REMOVE(headp, newvariable, entries); 08384 ast_var_delete(newvariable); 08385 break; 08386 } 08387 } 08388 08389 if (value) { 08390 if (headp == &globals) 08391 ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value); 08392 newvariable = ast_var_assign(name, value); 08393 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 08394 manager_event(EVENT_FLAG_DIALPLAN, "VarSet", 08395 "Channel: %s\r\n" 08396 "Variable: %s\r\n" 08397 "Value: %s\r\n" 08398 "Uniqueid: %s\r\n", 08399 chan ? chan->name : "none", name, value, 08400 chan ? chan->uniqueid : "none"); 08401 } 08402 08403 if (chan) 08404 ast_channel_unlock(chan); 08405 else 08406 ast_rwlock_unlock(&globalslock); 08407 }
int pbx_builtin_setvar_multiple | ( | struct ast_channel * | chan, | |
void * | data | |||
) |
int pbx_checkcondition | ( | const char * | condition | ) |
Evaluate a condition.
0 | if the condition is NULL or of zero length | |
int | If the string is an integer, the integer representation of the integer is returned | |
1 | Any other non-empty string |
Definition at line 8520 of file pbx.c.
References ast_strlen_zero().
Referenced by _macro_exec(), _while_exec(), acf_if(), execif_exec(), gosubif_exec(), macroif_exec(), and pbx_builtin_gotoif().
08521 { 08522 int res; 08523 if (ast_strlen_zero(condition)) { /* NULL or empty strings are false */ 08524 return 0; 08525 } else if (sscanf(condition, "%d", &res) == 1) { /* Numbers are evaluated for truth */ 08526 return res; 08527 } else { /* Strings are true */ 08528 return 1; 08529 } 08530 }
int pbx_exec | ( | struct ast_channel * | c, | |
struct ast_app * | app, | |||
void * | data | |||
) |
Execute an application.
c | channel to execute on | |
app | which app to execute | |
data | the data passed into the app |
c | Channel |
app | Application |
data | Data for execution |
Definition at line 932 of file pbx.c.
References __ast_module_user_add(), __ast_module_user_remove(), app, ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_log(), ast_strlen_zero(), ast_channel::cdr, ast_channel::data, LOG_WARNING, ast_channel::name, and S_OR.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automixmonitor(), builtin_automonitor(), conf_run(), dial_exec_full(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), handle_gosub(), iax2_exec(), lua_pbx_exec(), milliwatt_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), try_calling(), and tryexec_exec().
00935 { 00936 int res; 00937 struct ast_module_user *u = NULL; 00938 const char *saved_c_appl; 00939 const char *saved_c_data; 00940 00941 if (c->cdr && !ast_check_hangup(c)) 00942 ast_cdr_setapp(c->cdr, app->name, data); 00943 00944 /* save channel values */ 00945 saved_c_appl= c->appl; 00946 saved_c_data= c->data; 00947 00948 c->appl = app->name; 00949 c->data = data; 00950 if (app->module) 00951 u = __ast_module_user_add(app->module, c); 00952 if (!ast_strlen_zero(data) && strchr(data, '|') && !strchr(data, ',')) { 00953 ast_log(LOG_WARNING, "The application delimiter is now the comma, not " 00954 "the pipe. Did you forget to convert your dialplan? (%s(%s))\n", 00955 app->name, (char *) data); 00956 } 00957 res = app->execute(c, S_OR(data, "")); 00958 if (app->module && u) 00959 __ast_module_user_remove(app->module, u); 00960 /* restore channel values */ 00961 c->appl = saved_c_appl; 00962 c->data = saved_c_data; 00963 return res; 00964 }
struct ast_exten* pbx_find_extension | ( | struct ast_channel * | chan, | |
struct ast_context * | bypass, | |||
struct pbx_find_info * | q, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | label, | |||
const char * | callerid, | |||
enum ext_match_t | action | |||
) |
Definition at line 2049 of file pbx.c.
References ast_context::alts, ast_autoservice_start(), ast_autoservice_stop(), ast_copy_string(), ast_hashtab_lookup(), AST_LIST_TRAVERSE, ast_log(), AST_PBX_MAX_STACK, ast_str_thread_get(), ast_strdupa, ast_strlen_zero(), ast_walk_context_extensions(), ast_walk_contexts(), ast_walk_extension_priorities(), ast_switch::canmatch, scoreboard::canmatch_exten, chan, contexts_table, create_match_char_tree(), ast_sw::data, pbx_find_info::data, E_CANMATCH, E_FINDLABEL, E_MATCHMORE, ast_sw::eval, ast_switch::exists, ast_exten::exten, scoreboard::exten, extenpatternmatchnew, extension_match_core(), pbx_find_info::foundcontext, include_valid(), ast_context::includes, pbx_find_info::incstack, ast_exten::label, scoreboard::last_char, ast_str::len, LOG_DEBUG, log_match_char_tree(), LOG_NOTICE, LOG_WARNING, match(), matchcid(), ast_switch::matchmore, ast_sw::name, ast_context::name, fake_context::name, new_find_extension(), ast_include::next, scoreboard::node, overrideswitch, ast_context::pattern_tree, pbx_find_extension(), pbx_findswitch(), pbx_substitute_variables_helper(), ast_exten::priority, ast_include::rname, ast_context::root_table, pbx_find_info::stacklen, pbx_find_info::status, STATUS_NO_CONTEXT, STATUS_NO_EXTENSION, STATUS_NO_LABEL, STATUS_NO_PRIORITY, STATUS_SUCCESS, ast_str::str, strsep(), switch_data, pbx_find_info::swo, scoreboard::total_length, scoreboard::total_specificity, and trie_find_next_match().
Referenced by ast_hint_extension_nolock(), ast_merge_contexts_and_delete(), pbx_extension_helper(), pbx_find_extension(), and register_peer_exten().
02053 { 02054 int x, res; 02055 struct ast_context *tmp = NULL; 02056 struct ast_exten *e = NULL, *eroot = NULL; 02057 struct ast_include *i = NULL; 02058 struct ast_sw *sw = NULL; 02059 struct ast_exten pattern = {NULL, }; 02060 struct scoreboard score = {0, }; 02061 struct ast_str *tmpdata = NULL; 02062 02063 pattern.label = label; 02064 pattern.priority = priority; 02065 #ifdef NEED_DEBUG_HERE 02066 ast_log(LOG_NOTICE,"Looking for cont/ext/prio/label/action = %s/%s/%d/%s/%d\n", context, exten, priority, label, (int)action); 02067 #endif 02068 02069 /* Initialize status if appropriate */ 02070 if (q->stacklen == 0) { 02071 q->status = STATUS_NO_CONTEXT; 02072 q->swo = NULL; 02073 q->data = NULL; 02074 q->foundcontext = NULL; 02075 } else if (q->stacklen >= AST_PBX_MAX_STACK) { 02076 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n"); 02077 return NULL; 02078 } 02079 02080 /* Check first to see if we've already been checked */ 02081 for (x = 0; x < q->stacklen; x++) { 02082 if (!strcasecmp(q->incstack[x], context)) 02083 return NULL; 02084 } 02085 02086 if (bypass) /* bypass means we only look there */ 02087 tmp = bypass; 02088 else { /* look in contexts */ 02089 struct fake_context item; 02090 02091 ast_copy_string(item.name, context, sizeof(item.name)); 02092 02093 tmp = ast_hashtab_lookup(contexts_table, &item); 02094 #ifdef NOTNOW 02095 tmp = NULL; 02096 while ((tmp = ast_walk_contexts(tmp)) ) { 02097 if (!strcmp(tmp->name, context)) 02098 break; 02099 } 02100 #endif 02101 if (!tmp) 02102 return NULL; 02103 02104 } 02105 02106 if (q->status < STATUS_NO_EXTENSION) 02107 q->status = STATUS_NO_EXTENSION; 02108 02109 /* Do a search for matching extension */ 02110 02111 eroot = NULL; 02112 score.total_specificity = 0; 02113 score.exten = 0; 02114 score.total_length = 0; 02115 if (!tmp->pattern_tree && tmp->root_table) 02116 { 02117 create_match_char_tree(tmp); 02118 #ifdef NEED_DEBUG 02119 ast_log(LOG_DEBUG,"Tree Created in context %s:\n", context); 02120 log_match_char_tree(tmp->pattern_tree," "); 02121 #endif 02122 } 02123 #ifdef NEED_DEBUG 02124 ast_log(LOG_NOTICE,"The Trie we are searching in:\n"); 02125 log_match_char_tree(tmp->pattern_tree, ":: "); 02126 #endif 02127 02128 do { 02129 if (!ast_strlen_zero(overrideswitch)) { 02130 char *osw = ast_strdupa(overrideswitch), *name; 02131 struct ast_switch *asw; 02132 ast_switch_f *aswf = NULL; 02133 char *datap; 02134 int eval = 0; 02135 02136 name = strsep(&osw, "/"); 02137 asw = pbx_findswitch(name); 02138 02139 if (!asw) { 02140 ast_log(LOG_WARNING, "No such switch '%s'\n", name); 02141 break; 02142 } 02143 02144 if (osw && strchr(osw, '$')) { 02145 eval = 1; 02146 } 02147 02148 if (eval && !(tmpdata = ast_str_thread_get(&switch_data, 512))) { 02149 ast_log(LOG_WARNING, "Can't evaluate overrideswitch?!"); 02150 break; 02151 } else if (eval) { 02152 /* Substitute variables now */ 02153 pbx_substitute_variables_helper(chan, osw, tmpdata->str, tmpdata->len); 02154 datap = tmpdata->str; 02155 } else { 02156 datap = osw; 02157 } 02158 02159 /* equivalent of extension_match_core() at the switch level */ 02160 if (action == E_CANMATCH) 02161 aswf = asw->canmatch; 02162 else if (action == E_MATCHMORE) 02163 aswf = asw->matchmore; 02164 else /* action == E_MATCH */ 02165 aswf = asw->exists; 02166 if (!aswf) { 02167 res = 0; 02168 } else { 02169 if (chan) { 02170 ast_autoservice_start(chan); 02171 } 02172 res = aswf(chan, context, exten, priority, callerid, datap); 02173 if (chan) { 02174 ast_autoservice_stop(chan); 02175 } 02176 } 02177 if (res) { /* Got a match */ 02178 q->swo = asw; 02179 q->data = datap; 02180 q->foundcontext = context; 02181 /* XXX keep status = STATUS_NO_CONTEXT ? */ 02182 return NULL; 02183 } 02184 } 02185 } while (0); 02186 02187 if (extenpatternmatchnew) { 02188 new_find_extension(exten, &score, tmp->pattern_tree, 0, 0, callerid, label, action); 02189 eroot = score.exten; 02190 02191 if (score.last_char == '!' && action == E_MATCHMORE) { 02192 /* We match an extension ending in '!'. 02193 * The decision in this case is final and is NULL (no match). 02194 */ 02195 #ifdef NEED_DEBUG_HERE 02196 ast_log(LOG_NOTICE,"Returning MATCHMORE NULL with exclamation point.\n"); 02197 #endif 02198 return NULL; 02199 } 02200 02201 if (!eroot && (action == E_CANMATCH || action == E_MATCHMORE) && score.canmatch_exten) { 02202 q->status = STATUS_SUCCESS; 02203 #ifdef NEED_DEBUG_HERE 02204 ast_log(LOG_NOTICE,"Returning CANMATCH exten %s\n", score.canmatch_exten->exten); 02205 #endif 02206 return score.canmatch_exten; 02207 } 02208 02209 if ((action == E_MATCHMORE || action == E_CANMATCH) && eroot) { 02210 if (score.node) { 02211 struct ast_exten *z = trie_find_next_match(score.node); 02212 if (z) { 02213 #ifdef NEED_DEBUG_HERE 02214 ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten %s\n", z->exten); 02215 #endif 02216 } else { 02217 if (score.canmatch_exten) { 02218 #ifdef NEED_DEBUG_HERE 02219 ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE canmatchmatch exten %s(%p)\n", score.canmatch_exten->exten, score.canmatch_exten); 02220 #endif 02221 return score.canmatch_exten; 02222 } else { 02223 #ifdef NEED_DEBUG_HERE 02224 ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten NULL\n"); 02225 #endif 02226 } 02227 } 02228 return z; 02229 } 02230 #ifdef NEED_DEBUG_HERE 02231 ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE NULL (no next_match)\n"); 02232 #endif 02233 return NULL; /* according to the code, complete matches are null matches in MATCHMORE mode */ 02234 } 02235 02236 if (eroot) { 02237 /* found entry, now look for the right priority */ 02238 if (q->status < STATUS_NO_PRIORITY) 02239 q->status = STATUS_NO_PRIORITY; 02240 e = NULL; 02241 if (action == E_FINDLABEL && label ) { 02242 if (q->status < STATUS_NO_LABEL) 02243 q->status = STATUS_NO_LABEL; 02244 e = ast_hashtab_lookup(eroot->peer_label_table, &pattern); 02245 } else { 02246 e = ast_hashtab_lookup(eroot->peer_table, &pattern); 02247 } 02248 if (e) { /* found a valid match */ 02249 q->status = STATUS_SUCCESS; 02250 q->foundcontext = context; 02251 #ifdef NEED_DEBUG_HERE 02252 ast_log(LOG_NOTICE,"Returning complete match of exten %s\n", e->exten); 02253 #endif 02254 return e; 02255 } 02256 } 02257 } else { /* the old/current default exten pattern match algorithm */ 02258 02259 /* scan the list trying to match extension and CID */ 02260 eroot = NULL; 02261 while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) { 02262 int match = extension_match_core(eroot->exten, exten, action); 02263 /* 0 on fail, 1 on match, 2 on earlymatch */ 02264 02265 if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid))) 02266 continue; /* keep trying */ 02267 if (match == 2 && action == E_MATCHMORE) { 02268 /* We match an extension ending in '!'. 02269 * The decision in this case is final and is NULL (no match). 02270 */ 02271 return NULL; 02272 } 02273 /* found entry, now look for the right priority */ 02274 if (q->status < STATUS_NO_PRIORITY) 02275 q->status = STATUS_NO_PRIORITY; 02276 e = NULL; 02277 if (action == E_FINDLABEL && label ) { 02278 if (q->status < STATUS_NO_LABEL) 02279 q->status = STATUS_NO_LABEL; 02280 e = ast_hashtab_lookup(eroot->peer_label_table, &pattern); 02281 } else { 02282 e = ast_hashtab_lookup(eroot->peer_table, &pattern); 02283 } 02284 #ifdef NOTNOW 02285 while ( (e = ast_walk_extension_priorities(eroot, e)) ) { 02286 /* Match label or priority */ 02287 if (action == E_FINDLABEL) { 02288 if (q->status < STATUS_NO_LABEL) 02289 q->status = STATUS_NO_LABEL; 02290 if (label && e->label && !strcmp(label, e->label)) 02291 break; /* found it */ 02292 } else if (e->priority == priority) { 02293 break; /* found it */ 02294 } /* else keep searching */ 02295 } 02296 #endif 02297 if (e) { /* found a valid match */ 02298 q->status = STATUS_SUCCESS; 02299 q->foundcontext = context; 02300 return e; 02301 } 02302 } 02303 } 02304 02305 02306 /* Check alternative switches */ 02307 AST_LIST_TRAVERSE(&tmp->alts, sw, list) { 02308 struct ast_switch *asw = pbx_findswitch(sw->name); 02309 ast_switch_f *aswf = NULL; 02310 char *datap; 02311 02312 if (!asw) { 02313 ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name); 02314 continue; 02315 } 02316 /* Substitute variables now */ 02317 02318 if (sw->eval) { 02319 if (!(tmpdata = ast_str_thread_get(&switch_data, 512))) { 02320 ast_log(LOG_WARNING, "Can't evaluate switch?!"); 02321 continue; 02322 } 02323 pbx_substitute_variables_helper(chan, sw->data, tmpdata->str, tmpdata->len); 02324 } 02325 02326 /* equivalent of extension_match_core() at the switch level */ 02327 if (action == E_CANMATCH) 02328 aswf = asw->canmatch; 02329 else if (action == E_MATCHMORE) 02330 aswf = asw->matchmore; 02331 else /* action == E_MATCH */ 02332 aswf = asw->exists; 02333 datap = sw->eval ? tmpdata->str : sw->data; 02334 if (!aswf) 02335 res = 0; 02336 else { 02337 if (chan) 02338 ast_autoservice_start(chan); 02339 res = aswf(chan, context, exten, priority, callerid, datap); 02340 if (chan) 02341 ast_autoservice_stop(chan); 02342 } 02343 if (res) { /* Got a match */ 02344 q->swo = asw; 02345 q->data = datap; 02346 q->foundcontext = context; 02347 /* XXX keep status = STATUS_NO_CONTEXT ? */ 02348 return NULL; 02349 } 02350 } 02351 q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */ 02352 /* Now try any includes we have in this context */ 02353 for (i = tmp->includes; i; i = i->next) { 02354 if (include_valid(i)) { 02355 if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action))) { 02356 #ifdef NEED_DEBUG_HERE 02357 ast_log(LOG_NOTICE,"Returning recursive match of %s\n", e->exten); 02358 #endif 02359 return e; 02360 } 02361 if (q->swo) 02362 return NULL; 02363 } 02364 } 02365 return NULL; 02366 }
struct ast_app* pbx_findapp | ( | const char * | app | ) |
Look up an application.
app | name of the app |
Definition at line 972 of file pbx.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_app::list, and ast_app::name.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automixmonitor(), builtin_automonitor(), conf_run(), dial_exec_full(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), handle_gosub(), iax2_exec(), lua_pbx_exec(), milliwatt_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), try_calling(), and tryexec_exec().
00973 { 00974 struct ast_app *tmp; 00975 00976 AST_RWLIST_RDLOCK(&apps); 00977 AST_RWLIST_TRAVERSE(&apps, tmp, list) { 00978 if (!strcasecmp(tmp->name, app)) 00979 break; 00980 } 00981 AST_RWLIST_UNLOCK(&apps); 00982 00983 return tmp; 00984 }
void pbx_retrieve_variable | ( | struct ast_channel * | c, | |
const char * | var, | |||
char ** | ret, | |||
char * | workspace, | |||
int | workspacelen, | |||
struct varshead * | headp | |||
) |
Support for Asterisk built-in variables in the dialplan.
Definition at line 2448 of file pbx.c.
References ARRAY_LEN, ast_channel_lock, ast_channel_unlock, ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_eid_default, ast_eid_to_str(), ast_get_hint(), AST_LIST_TRAVERSE, ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_strdupa, ast_var_name(), ast_var_value(), ast_channel::cid, ast_callerid::cid_ani2, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, globals, globalslock, ast_channel::hangupcause, ast_channel::name, parse_variable_name(), ast_channel::priority, s, substring(), and ast_channel::uniqueid.
Referenced by action_getvar(), action_status(), handle_getvariable(), lua_get_variable(), lua_get_variable_value(), and pbx_substitute_variables_helper_full().
02449 { 02450 const char not_found = '\0'; 02451 char *tmpvar; 02452 const char *s; /* the result */ 02453 int offset, length; 02454 int i, need_substring; 02455 struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */ 02456 02457 if (c) { 02458 ast_channel_lock(c); 02459 places[0] = &c->varshead; 02460 } 02461 /* 02462 * Make a copy of var because parse_variable_name() modifies the string. 02463 * Then if called directly, we might need to run substring() on the result; 02464 * remember this for later in 'need_substring', 'offset' and 'length' 02465 */ 02466 tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */ 02467 need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */); 02468 02469 /* 02470 * Look first into predefined variables, then into variable lists. 02471 * Variable 's' points to the result, according to the following rules: 02472 * s == ¬_found (set at the beginning) means that we did not find a 02473 * matching variable and need to look into more places. 02474 * If s != ¬_found, s is a valid result string as follows: 02475 * s = NULL if the variable does not have a value; 02476 * you typically do this when looking for an unset predefined variable. 02477 * s = workspace if the result has been assembled there; 02478 * typically done when the result is built e.g. with an snprintf(), 02479 * so we don't need to do an additional copy. 02480 * s != workspace in case we have a string, that needs to be copied 02481 * (the ast_copy_string is done once for all at the end). 02482 * Typically done when the result is already available in some string. 02483 */ 02484 s = ¬_found; /* default value */ 02485 if (c) { /* This group requires a valid channel */ 02486 /* Names with common parts are looked up a piece at a time using strncmp. */ 02487 if (!strncmp(var, "CALL", 4)) { 02488 if (!strncmp(var + 4, "ING", 3)) { 02489 if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */ 02490 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 02491 s = workspace; 02492 } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */ 02493 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 02494 s = workspace; 02495 } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */ 02496 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 02497 s = workspace; 02498 } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */ 02499 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 02500 s = workspace; 02501 } 02502 } 02503 } else if (!strcmp(var, "HINT")) { 02504 s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL; 02505 } else if (!strcmp(var, "HINTNAME")) { 02506 s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL; 02507 } else if (!strcmp(var, "EXTEN")) { 02508 s = c->exten; 02509 } else if (!strcmp(var, "CONTEXT")) { 02510 s = c->context; 02511 } else if (!strcmp(var, "PRIORITY")) { 02512 snprintf(workspace, workspacelen, "%d", c->priority); 02513 s = workspace; 02514 } else if (!strcmp(var, "CHANNEL")) { 02515 s = c->name; 02516 } else if (!strcmp(var, "UNIQUEID")) { 02517 s = c->uniqueid; 02518 } else if (!strcmp(var, "HANGUPCAUSE")) { 02519 snprintf(workspace, workspacelen, "%d", c->hangupcause); 02520 s = workspace; 02521 } 02522 } 02523 if (s == ¬_found) { /* look for more */ 02524 if (!strcmp(var, "EPOCH")) { 02525 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 02526 s = workspace; 02527 } else if (!strcmp(var, "SYSTEMNAME")) { 02528 s = ast_config_AST_SYSTEM_NAME; 02529 } else if (!strcmp(var, "ENTITYID")) { 02530 ast_eid_to_str(workspace, workspacelen, &ast_eid_default); 02531 s = workspace; 02532 } 02533 } 02534 /* if not found, look into chanvars or global vars */ 02535 for (i = 0; s == ¬_found && i < ARRAY_LEN(places); i++) { 02536 struct ast_var_t *variables; 02537 if (!places[i]) 02538 continue; 02539 if (places[i] == &globals) 02540 ast_rwlock_rdlock(&globalslock); 02541 AST_LIST_TRAVERSE(places[i], variables, entries) { 02542 if (!strcasecmp(ast_var_name(variables), var)) { 02543 s = ast_var_value(variables); 02544 break; 02545 } 02546 } 02547 if (places[i] == &globals) 02548 ast_rwlock_unlock(&globalslock); 02549 } 02550 if (s == ¬_found || s == NULL) 02551 *ret = NULL; 02552 else { 02553 if (s != workspace) 02554 ast_copy_string(workspace, s, workspacelen); 02555 *ret = workspace; 02556 if (need_substring) 02557 *ret = substring(*ret, offset, length, workspace, workspacelen); 02558 } 02559 02560 if (c) 02561 ast_channel_unlock(c); 02562 }
int pbx_set_autofallthrough | ( | int | newval | ) |
Set "autofallthrough" flag, if newval is <0, does not acutally set. If set to 1, sets to auto fall through. If newval set to 0, sets to no auto fall through (reads extension instead). Returns previous value.
Definition at line 4084 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
04085 { 04086 int oldval = autofallthrough; 04087 autofallthrough = newval; 04088 return oldval; 04089 }
int pbx_set_extenpatternmatchnew | ( | int | newval | ) |
Set "extenpatternmatchnew" flag, if newval is <0, does not acutally set. If set to 1, sets to use the new Trie-based pattern matcher. If newval set to 0, sets to use the old linear-search algorithm. Returns previous value.
Definition at line 4091 of file pbx.c.
References extenpatternmatchnew.
Referenced by handle_set_extenpatternmatchnew(), handle_unset_extenpatternmatchnew(), and pbx_load_module().
04092 { 04093 int oldval = extenpatternmatchnew; 04094 extenpatternmatchnew = newval; 04095 return oldval; 04096 }
void pbx_set_overrideswitch | ( | const char * | newval | ) |
Set "overrideswitch" field. If set and of nonzero length, all contexts will be tried directly through the named switch prior to any other matching within that context.
Definition at line 4098 of file pbx.c.
References ast_free, ast_strdup, ast_strlen_zero(), and overrideswitch.
Referenced by pbx_load_module().
04099 { 04100 if (overrideswitch) { 04101 ast_free(overrideswitch); 04102 } 04103 if (!ast_strlen_zero(newval)) { 04104 overrideswitch = ast_strdup(newval); 04105 } else { 04106 overrideswitch = NULL; 04107 } 04108 }
void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 3089 of file pbx.c.
References pbx_substitute_variables_helper_full(), and ast_channel::varshead.
Referenced by _macro_exec(), acf_import(), acf_odbc_read(), acf_odbc_write(), ast_add_extension2_lockopt(), config_curl(), custom_log(), cut_internal(), destroy_curl(), exec_exec(), function_eval(), function_fieldqty(), get_mapping_weight(), handle_getvariablefull(), launch_monitor_thread(), make_email_file(), manager_log(), pbx_builtin_importvar(), pbx_find_extension(), pbx_load_config(), pbx_substitute_variables(), realtime_curl(), realtime_multi_curl(), require_curl(), rotate_file(), rpt_do_lstats(), rpt_exec(), sendmail(), sendpage(), sqlite3_log(), store_curl(), substituted(), try_calling(), tryexec_exec(), and update_curl().
03090 { 03091 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 03092 }
void pbx_substitute_variables_varshead | ( | struct varshead * | headp, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 3094 of file pbx.c.
References pbx_substitute_variables_helper_full().
Referenced by add_user_extension(), build_user_routes(), dundi_lookup_local(), loopback_subst(), phoneprov_callback(), pp_each_extension_exec(), and pp_each_user_exec().
03095 { 03096 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 03097 }