#include "asterisk/sched.h"
#include "asterisk/devicestate.h"
#include "asterisk/chanvars.h"
#include "asterisk/hashtab.h"
Go to the source code of this file.
Data Structures | |
struct | ast_custom_function |
Data structure associated with a custom dialplan function. More... | |
struct | ast_pbx |
struct | ast_pbx_args |
Options for ast_pbx_run(). More... | |
struct | ast_switch |
struct | ast_timing |
struct | pbx_find_info |
Functions for returning values from structures | |
const char * | ast_get_context_name (struct ast_context *con) |
ast_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. | |
enum ast_extension_states | ast_devstate_to_extenstate (enum ast_device_state devstate) |
Map devstate to an extension state. | |
int | ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
Determine whether an extension exists. | |
int | ast_explicit_goto (struct ast_channel *chan, const char *context, const char *exten, int priority) |
int | ast_extension_close (const char *pattern, const char *data, int needmore) |
int | ast_extension_cmp (const char *a, const char *b) |
Determine if one extension should match before another. | |
int | ast_extension_match (const char *pattern, const char *extension) |
Determine if a given extension matches a given pattern (in NXX format). | |
int | ast_extension_patmatch (const char *pattern, const char *data) |
int | ast_extension_state (struct ast_channel *c, const char *context, const char *exten) |
Uses hint and devicestate callback to get the state of an extension. | |
const char * | ast_extension_state2str (int extension_state) |
Return string representation of the state of an extension. | |
int | ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data) |
Registers a state change callback. | |
int | ast_extension_state_del (int id, ast_state_cb_type callback) |
Deletes a registered state change callback by ID. | |
int | ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid) |
Find the priority of an extension that has the specified label. | |
int | ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid) |
Find the priority of an extension that has the specified label. | |
int | ast_func_read (struct ast_channel *chan, const char *function, char *workspace, size_t len) |
executes a read operation on a function | |
int | ast_func_write (struct ast_channel *chan, const char *function, const char *value) |
executes a write operation on a function | |
int | ast_get_hint (char *hint, int maxlen, char *name, int maxnamelen, struct ast_channel *c, const char *context, const char *exten) |
If an extension hint exists, return non-zero. | |
int | ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
int | ast_hashtab_compare_contexts (const void *ah_a, const void *ah_b) |
unsigned int | ast_hashtab_hash_contexts (const void *obj) |
int | ast_ignore_pattern (const char *context, const char *pattern) |
Checks to see if a number should be ignored. | |
int | ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
Looks to see if adding anything to this extension might match something. (exists ^ canmatch). | |
void | ast_merge_contexts_and_delete (struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *registrar) |
Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added. | |
int | ast_parseable_goto (struct ast_channel *chan, const char *goto_string) |
int | ast_pbx_outgoing_app (const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) |
int | ast_pbx_outgoing_exten (const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) |
enum ast_pbx_result | ast_pbx_run (struct ast_channel *c) |
Execute the PBX in the current thread. | |
enum ast_pbx_result | ast_pbx_run_args (struct ast_channel *c, struct ast_pbx_args *args) |
Execute the PBX in the current thread. | |
enum ast_pbx_result | ast_pbx_start (struct ast_channel *c) |
Create a new thread and start the PBX. | |
int | ast_processed_calls (void) |
Retrieve the total number of calls processed through the PBX since last restart. | |
int | ast_rdlock_context (struct ast_context *con) |
Read locks a given context. | |
int | ast_rdlock_contexts (void) |
Read locks the context list. | |
int | ast_register_switch (struct ast_switch *sw) |
Register an alternative dialplan switch. | |
int | ast_spawn_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid, int *found, int combined_find_spawn) |
Launch a new extension (i.e. new stack). | |
int | ast_unlock_context (struct ast_context *con) |
int | ast_unlock_contexts (void) |
Unlocks contexts. | |
void | ast_unregister_switch (struct ast_switch *sw) |
Unregister an alternative switch. | |
ast_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 977 of file pbx.h.
Referenced by load_module(), and reload().
#define AST_MAX_APP 32 |
Max length of an application
Definition at line 35 of file pbx.h.
Referenced by destroy_station(), handle_show_application(), and handle_show_function().
#define AST_PBX_HANGUP -1 |
#define AST_PBX_INCOMPLETE 12 |
Return to PBX matching, allowing more digits for the extension
Definition at line 44 of file pbx.h.
Referenced by dial_exec_full(), pbx_builtin_incomplete(), and retrydial_exec().
#define PRIORITY_HINT -1 |
} Special Priority for a hint
Definition at line 47 of file pbx.h.
Referenced by ast_add_extension2_lockopt(), ast_hint_extension_nolock(), ast_merge_contexts_and_delete(), destroy_exten(), destroy_station(), handle_cli_dialplan_add_extension(), handle_cli_dialplan_remove_extension(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), park_add_hints(), pbx_load_config(), and print_ext().
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 53 of file pbx.h.
00053 { 00054 AST_EXTENSION_REMOVED = -2, /*!< Extension removed */ 00055 AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */ 00056 AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */ 00057 AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */ 00058 AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */ 00059 AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */ 00060 AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */ 00061 AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */ 00062 };
enum ast_pbx_result |
The result codes when starting the PBX on a channelwith.
Definition at line 229 of file pbx.h.
00229 { 00230 AST_PBX_SUCCESS = 0, 00231 AST_PBX_FAILED = -1, 00232 AST_PBX_CALL_LIMIT = -2, 00233 };
enum ext_match_t |
When looking up extensions, we can have different requests identified by the 'action' argument, as follows. Note that the coding is such that the low 4 bits are the third argument to extension_match_core.
Definition at line 1028 of file pbx.h.
01028 { 01029 E_MATCHMORE = 0x00, /* extension can match but only with more 'digits' */ 01030 E_CANMATCH = 0x01, /* extension can match with or without more 'digits' */ 01031 E_MATCH = 0x02, /* extension is an exact match */ 01032 E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */ 01033 E_SPAWN = 0x12, /* want to spawn an extension. Requires exact match */ 01034 E_FINDLABEL = 0x22 /* returns the priority for a given label. Requires exact match */ 01035 };
int __ast_custom_function_register | ( | struct ast_custom_function * | acf, | |
struct ast_module * | mod | |||
) |
Register a custom function.
Definition at line 2814 of file pbx.c.
References ast_custom_function::acflist, ast_log(), AST_RWLIST_INSERT_BEFORE_CURRENT, AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, COLOR_BRCYAN, LOG_ERROR, ast_custom_function::mod, ast_custom_function::name, and term_color().
Referenced by load_pbx().
02815 { 02816 struct ast_custom_function *cur; 02817 char tmps[80]; 02818 02819 if (!acf) 02820 return -1; 02821 02822 acf->mod = mod; 02823 02824 AST_RWLIST_WRLOCK(&acf_root); 02825 02826 AST_RWLIST_TRAVERSE(&acf_root, cur, acflist) { 02827 if (!strcmp(acf->name, cur->name)) { 02828 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 02829 AST_RWLIST_UNLOCK(&acf_root); 02830 return -1; 02831 } 02832 } 02833 02834 /* Store in alphabetical order */ 02835 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 02836 if (strcasecmp(acf->name, cur->name) < 0) { 02837 AST_RWLIST_INSERT_BEFORE_CURRENT(acf, acflist); 02838 break; 02839 } 02840 } 02841 AST_RWLIST_TRAVERSE_SAFE_END; 02842 if (!cur) 02843 AST_RWLIST_INSERT_TAIL(&acf_root, acf, acflist); 02844 02845 AST_RWLIST_UNLOCK(&acf_root); 02846 02847 ast_verb(2, "Registered custom function '%s'\n", term_color(tmps, acf->name, COLOR_BRCYAN, 0, sizeof(tmps))); 02848 02849 return 0; 02850 }
int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 4108 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), handle_showcalls(), and sysinfo_helper().
04109 { 04110 return countcalls; 04111 }
int ast_add_extension | ( | const char * | context, | |
int | replace, | |||
const char * | extension, | |||
int | priority, | |||
const char * | label, | |||
const char * | callerid, | |||
const char * | application, | |||
void * | data, | |||
void(*)(void *) | datad, | |||
const char * | registrar | |||
) |
Add and extension to an extension context.
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 6759 of file pbx.c.
References ast_add_extension2(), ast_unlock_contexts(), and find_context_locked().
Referenced by ast_extension_state_add(), handle_cli_dialplan_add_extension(), park_add_hints(), register_exten(), register_peer_exten(), and RegisterExtension().
06762 { 06763 int ret = -1; 06764 struct ast_context *c = find_context_locked(context); 06765 06766 if (c) { 06767 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 06768 application, data, datad, registrar); 06769 ast_unlock_contexts(); 06770 } 06771 06772 return ret; 06773 }
int ast_add_extension2 | ( | struct ast_context * | con, | |
int | replace, | |||
const char * | extension, | |||
int | priority, | |||
const char * | label, | |||
const char * | callerid, | |||
const char * | application, | |||
void * | data, | |||
void(*)(void *) | datad, | |||
const char * | registrar | |||
) |
Add an extension to an extension context, this time with an ast_context *.
We sort extensions in order of matching preference, so that we can stop the search as soon as we find a suitable match. This ordering also takes care of wildcards such as '.' (meaning "one or more of any character") and '!' (which is 'earlymatch', meaning "zero or more of any character" but also impacts the return value from CANMATCH and EARLYMATCH.
The extension match rules defined in the devmeeting 2006.05.05 are quite simple: WE SELECT THE LONGEST MATCH. In detail, "longest" means the number of matched characters in the extension. In case of ties (e.g. _XXX and 333) in the length of a pattern, we give priority to entries with the smallest cardinality (e.g, [5-9] comes before [2-8] before the former has only 5 elements, while the latter has 7, etc. In case of same cardinality, the first element in the range counts. If we still have a tie, any final '!' will make this as a possibly less specific pattern.
EBUSY - can't lock EEXIST - extension with the same priority exist and no replace is set
Definition at line 7077 of file pbx.c.
References ast_add_extension2_lockopt().
Referenced by ast_add_extension(), ast_park_call_full(), build_parkinglot(), context_merge(), load_module(), manage_parkinglot(), pbx_load_config(), and pbx_load_users().
07081 { 07082 return ast_add_extension2_lockopt(con, replace, extension, priority, label, callerid, application, data, datad, registrar, 1, 1); 07083 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6798 of file pbx.c.
References ast_channel::_state, ast_channel::accountcode, ast_channel::amaflags, ast_cdr_discard(), ast_cdr_dup(), ast_channel_alloc, ast_channel_lock, ast_channel_masquerade(), ast_channel_unlock, ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_pbx_start(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_channel::cdr, chan, ast_channel::context, ast_channel::exten, LOG_WARNING, ast_channel::name, ast_channel::pbx, ast_channel::readformat, S_OR, and ast_channel::writeformat.
Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), dahdi_handle_dtmfup(), handle_request_bye(), handle_request_refer(), pbx_parseable_goto(), process_ast_dsp(), sip_read(), and socket_process().
06799 { 06800 int res = 0; 06801 06802 ast_channel_lock(chan); 06803 06804 if (chan->pbx) { /* This channel is currently in the PBX */ 06805 ast_explicit_goto(chan, context, exten, priority + 1); 06806 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 06807 } else { 06808 /* In order to do it when the channel doesn't really exist within 06809 the PBX, we have to make a new channel, masquerade, and start the PBX 06810 at the new location */ 06811 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 06812 if (!tmpchan) { 06813 res = -1; 06814 } else { 06815 if (chan->cdr) { 06816 ast_cdr_discard(tmpchan->cdr); 06817 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 06818 } 06819 /* Make formats okay */ 06820 tmpchan->readformat = chan->readformat; 06821 tmpchan->writeformat = chan->writeformat; 06822 /* Setup proper location */ 06823 ast_explicit_goto(tmpchan, 06824 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 06825 06826 /* Masquerade into temp channel */ 06827 if (ast_channel_masquerade(tmpchan, chan)) { 06828 /* Failed to set up the masquerade. It's probably chan_local 06829 * in the middle of optimizing itself out. Sad. :( */ 06830 ast_hangup(tmpchan); 06831 tmpchan = NULL; 06832 res = -1; 06833 } else { 06834 /* Grab the locks and get going */ 06835 ast_channel_lock(tmpchan); 06836 ast_do_masquerade(tmpchan); 06837 ast_channel_unlock(tmpchan); 06838 /* Start the PBX going on our stolen channel */ 06839 if (ast_pbx_start(tmpchan)) { 06840 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 06841 ast_hangup(tmpchan); 06842 res = -1; 06843 } 06844 } 06845 } 06846 } 06847 ast_channel_unlock(chan); 06848 return res; 06849 }
int ast_async_goto_by_name | ( | const char * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6851 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, ast_get_channel_by_name_locked(), and chan.
06852 { 06853 struct ast_channel *chan; 06854 int res = -1; 06855 06856 chan = ast_get_channel_by_name_locked(channame); 06857 if (chan) { 06858 res = ast_async_goto(chan, context, exten, priority); 06859 ast_channel_unlock(chan); 06860 } 06861 return res; 06862 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 9004 of file pbx.c.
References __ast_goto_if_exists(), and chan.
09005 { 09006 return __ast_goto_if_exists(chan, context, exten, priority, 1); 09007 }
int ast_async_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
Definition at line 9067 of file pbx.c.
References chan, and pbx_parseable_goto().
Referenced by asyncgoto_exec().
09068 { 09069 return pbx_parseable_goto(chan, goto_string, 1); 09070 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info | |||
) |
Definition at line 6419 of file pbx.c.
References ast_copy_string(), ast_strlen_zero(), ast_timing::daymask, days, ast_timing::dowmask, get_range(), get_timerange(), ast_timing::monthmask, months, and strsep().
Referenced by ast_context_add_include2(), iftime(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
06420 { 06421 char info_save[256]; 06422 char *info; 06423 06424 /* Check for empty just in case */ 06425 if (ast_strlen_zero(info_in)) 06426 return 0; 06427 /* make a copy just in case we were passed a static string */ 06428 ast_copy_string(info_save, info_in, sizeof(info_save)); 06429 info = info_save; 06430 /* Assume everything except time */ 06431 i->monthmask = 0xfff; /* 12 bits */ 06432 i->daymask = 0x7fffffffU; /* 31 bits */ 06433 i->dowmask = 0x7f; /* 7 bits */ 06434 /* on each call, use strsep() to move info to the next argument */ 06435 get_timerange(i, strsep(&info, "|,")); 06436 if (info) 06437 i->dowmask = get_range(strsep(&info, "|,"), 7, days, "day of week"); 06438 if (info) 06439 i->daymask = get_range(strsep(&info, "|,"), 31, NULL, "day"); 06440 if (info) 06441 i->monthmask = get_range(strsep(&info, "|,"), 12, months, "month"); 06442 return 1; 06443 }
int ast_canmatch_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) |
Looks for a valid matching extension.
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 3666 of file pbx.c.
References E_CANMATCH, and pbx_extension_helper().
Referenced by background_detect_exec(), cb_events(), do_immediate_setup(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), handle_link_data(), handle_link_phone_dtmf(), leave_voicemail(), local_dtmf_helper(), loopback_canmatch(), mgcp_ss(), pbx_builtin_background(), phone_check_exception(), skinny_ss(), ss_thread(), and valid_exit().
03667 { 03668 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0, 0); 03669 }
int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 6445 of file pbx.c.
References ast_localtime(), ast_log(), ast_tvnow(), ast_timing::daymask, ast_timing::dowmask, LOG_WARNING, ast_timing::minmask, ast_timing::monthmask, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, and ast_tm::tm_wday.
Referenced by iftime(), include_valid(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
06446 { 06447 struct ast_tm tm; 06448 struct timeval now = ast_tvnow(); 06449 06450 ast_localtime(&now, &tm, NULL); 06451 06452 /* If it's not the right month, return */ 06453 if (!(i->monthmask & (1 << tm.tm_mon))) 06454 return 0; 06455 06456 /* If it's not that time of the month.... */ 06457 /* Warning, tm_mday has range 1..31! */ 06458 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 06459 return 0; 06460 06461 /* If it's not the right day of the week */ 06462 if (!(i->dowmask & (1 << tm.tm_wday))) 06463 return 0; 06464 06465 /* Sanity check the hour just to be safe */ 06466 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 06467 ast_log(LOG_WARNING, "Insane time...\n"); 06468 return 0; 06469 } 06470 06471 /* Now the tough part, we calculate if it fits 06472 in the right time based on min/hour */ 06473 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 06474 return 0; 06475 06476 /* If we got this far, then we're good */ 06477 return 1; 06478 }
int ast_context_add_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Add an ignorepat.
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 6671 of file pbx.c.
References ast_context_add_ignorepat2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_cli_dialplan_add_ignorepat().
06672 { 06673 int ret = -1; 06674 struct ast_context *c = find_context_locked(context); 06675 06676 if (c) { 06677 ret = ast_context_add_ignorepat2(c, value, registrar); 06678 ast_unlock_contexts(); 06679 } 06680 return ret; 06681 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 6683 of file pbx.c.
References ast_calloc, ast_unlock_context(), ast_wrlock_context(), errno, ast_context::ignorepats, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.
Referenced by ast_context_add_ignorepat(), context_merge_incls_swits_igps_other_registrars(), and pbx_load_config().
06684 { 06685 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 06686 int length; 06687 char *pattern; 06688 length = sizeof(struct ast_ignorepat); 06689 length += strlen(value) + 1; 06690 if (!(ignorepat = ast_calloc(1, length))) 06691 return -1; 06692 /* The cast to char * is because we need to write the initial value. 06693 * The field is not supposed to be modified otherwise. Also, gcc 4.2 06694 * sees the cast as dereferencing a type-punned pointer and warns about 06695 * it. This is the workaround (we're telling gcc, yes, that's really 06696 * what we wanted to do). 06697 */ 06698 pattern = (char *) ignorepat->pattern; 06699 strcpy(pattern, value); 06700 ignorepat->next = NULL; 06701 ignorepat->registrar = registrar; 06702 ast_wrlock_context(con); 06703 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 06704 ignorepatl = ignorepatc; 06705 if (!strcasecmp(ignorepatc->pattern, value)) { 06706 /* Already there */ 06707 ast_unlock_context(con); 06708 errno = EEXIST; 06709 return -1; 06710 } 06711 } 06712 if (ignorepatl) 06713 ignorepatl->next = ignorepat; 06714 else 06715 con->ignorepats = ignorepat; 06716 ast_unlock_context(con); 06717 return 0; 06718 06719 }
int ast_context_add_include | ( | const char * | context, | |
const char * | include, | |||
const char * | registrar | |||
) |
Add a context include.
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 6225 of file pbx.c.
References ast_context_add_include2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_cli_dialplan_add_include().
06226 { 06227 int ret = -1; 06228 struct ast_context *c = find_context_locked(context); 06229 06230 if (c) { 06231 ret = ast_context_add_include2(c, include, registrar); 06232 ast_unlock_contexts(); 06233 } 06234 return ret; 06235 }
int ast_context_add_include2 | ( | struct ast_context * | con, | |
const char * | include, | |||
const char * | registrar | |||
) |
Add a context include.
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 6487 of file pbx.c.
References ast_build_timing(), ast_calloc, ast_free, ast_get_context_name(), ast_unlock_context(), ast_verb, ast_wrlock_context(), errno, ast_include::hastime, ast_context::includes, ast_include::name, ast_include::next, ast_include::registrar, ast_include::rname, ast_include::stuff, and ast_include::timing.
Referenced by ast_context_add_include(), context_merge_incls_swits_igps_other_registrars(), and pbx_load_config().
06489 { 06490 struct ast_include *new_include; 06491 char *c; 06492 struct ast_include *i, *il = NULL; /* include, include_last */ 06493 int length; 06494 char *p; 06495 06496 length = sizeof(struct ast_include); 06497 length += 2 * (strlen(value) + 1); 06498 06499 /* allocate new include structure ... */ 06500 if (!(new_include = ast_calloc(1, length))) 06501 return -1; 06502 /* Fill in this structure. Use 'p' for assignments, as the fields 06503 * in the structure are 'const char *' 06504 */ 06505 p = new_include->stuff; 06506 new_include->name = p; 06507 strcpy(p, value); 06508 p += strlen(value) + 1; 06509 new_include->rname = p; 06510 strcpy(p, value); 06511 /* Strip off timing info, and process if it is there */ 06512 if ( (c = strchr(p, ',')) ) { 06513 *c++ = '\0'; 06514 new_include->hastime = ast_build_timing(&(new_include->timing), c); 06515 } 06516 new_include->next = NULL; 06517 new_include->registrar = registrar; 06518 06519 ast_wrlock_context(con); 06520 06521 /* ... go to last include and check if context is already included too... */ 06522 for (i = con->includes; i; i = i->next) { 06523 if (!strcasecmp(i->name, new_include->name)) { 06524 ast_free(new_include); 06525 ast_unlock_context(con); 06526 errno = EEXIST; 06527 return -1; 06528 } 06529 il = i; 06530 } 06531 06532 /* ... include new context into context list, unlock, return */ 06533 if (il) 06534 il->next = new_include; 06535 else 06536 con->includes = new_include; 06537 ast_verb(3, "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 06538 06539 ast_unlock_context(con); 06540 06541 return 0; 06542 }
int ast_context_add_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
int | eval, | |||
const char * | registrar | |||
) |
Add a switch.
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 6549 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
06550 { 06551 int ret = -1; 06552 struct ast_context *c = find_context_locked(context); 06553 06554 if (c) { /* found, add switch to this context */ 06555 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 06556 ast_unlock_contexts(); 06557 } 06558 return ret; 06559 }
int ast_context_add_switch2 | ( | struct ast_context * | con, | |
const char * | sw, | |||
const char * | data, | |||
int | eval, | |||
const char * | registrar | |||
) |
Adds a switch (first param is a ast_context).
Definition at line 6568 of file pbx.c.
References ast_context::alts, ast_calloc, ast_free, ast_get_context_name(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_sw::data, errno, ast_sw::eval, store_hint::list, ast_sw::name, ast_sw::registrar, and ast_sw::stuff.
Referenced by ast_context_add_switch(), context_merge_incls_swits_igps_other_registrars(), lua_register_switches(), and pbx_load_config().
06570 { 06571 struct ast_sw *new_sw; 06572 struct ast_sw *i; 06573 int length; 06574 char *p; 06575 06576 length = sizeof(struct ast_sw); 06577 length += strlen(value) + 1; 06578 if (data) 06579 length += strlen(data); 06580 length++; 06581 06582 /* allocate new sw structure ... */ 06583 if (!(new_sw = ast_calloc(1, length))) 06584 return -1; 06585 /* ... fill in this structure ... */ 06586 p = new_sw->stuff; 06587 new_sw->name = p; 06588 strcpy(new_sw->name, value); 06589 p += strlen(value) + 1; 06590 new_sw->data = p; 06591 if (data) { 06592 strcpy(new_sw->data, data); 06593 p += strlen(data) + 1; 06594 } else { 06595 strcpy(new_sw->data, ""); 06596 p++; 06597 } 06598 new_sw->eval = eval; 06599 new_sw->registrar = registrar; 06600 06601 /* ... try to lock this context ... */ 06602 ast_wrlock_context(con); 06603 06604 /* ... go to last sw and check if context is already swd too... */ 06605 AST_LIST_TRAVERSE(&con->alts, i, list) { 06606 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 06607 ast_free(new_sw); 06608 ast_unlock_context(con); 06609 errno = EEXIST; 06610 return -1; 06611 } 06612 } 06613 06614 /* ... sw new context into context list, unlock, return */ 06615 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 06616 06617 ast_verb(3, "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 06618 06619 ast_unlock_context(con); 06620 06621 return 0; 06622 }
void ast_context_destroy | ( | struct ast_context * | con, | |
const char * | registrar | |||
) |
Destroy a context (matches the specified context (or ANY context if NULL).
con | context to destroy | |
registrar | who registered it |
Definition at line 7868 of file pbx.c.
References __ast_context_destroy(), ast_unlock_contexts(), ast_wrlock_contexts(), contexts, and contexts_table.
Referenced by __unload_module(), cleanup_stale_contexts(), parkinglot_destroy(), sla_destroy(), and unload_module().
07869 { 07870 ast_wrlock_contexts(); 07871 __ast_context_destroy(contexts, contexts_table, con,registrar); 07872 ast_unlock_contexts(); 07873 }
struct ast_context* ast_context_find | ( | const char * | name | ) |
Find a context.
name | name of the context to find |
Definition at line 2031 of file pbx.c.
References ast_copy_string(), ast_hashtab_lookup(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), contexts_table, ast_context::name, and fake_context::name.
Referenced by __unload_module(), _macro_exec(), ast_context_verify_includes(), ast_ignore_pattern(), cleanup_stale_contexts(), isexten_function_read(), manage_parkinglot(), park_exec_full(), parkinglot_destroy(), register_exten(), register_peer_exten(), unload_module(), and unregister_exten().
02032 { 02033 struct ast_context *tmp = NULL; 02034 struct fake_context item; 02035 02036 ast_copy_string(item.name, name, sizeof(item.name)); 02037 02038 ast_rdlock_contexts(); 02039 if( contexts_table ) { 02040 tmp = ast_hashtab_lookup(contexts_table,&item); 02041 } else { 02042 while ( (tmp = ast_walk_contexts(tmp)) ) { 02043 if (!name || !strcasecmp(name, tmp->name)) 02044 break; 02045 } 02046 } 02047 ast_unlock_contexts(); 02048 return tmp; 02049 }
struct ast_context* ast_context_find_or_create | ( | struct ast_context ** | extcontexts, | |
struct ast_hashtab * | exttable, | |||
const char * | name, | |||
const char * | registrar | |||
) |
Register a new context or find an existing one.
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 5881 of file pbx.c.
References ast_calloc, ast_copy_string(), ast_debug, ast_hashtab_compare_contexts(), ast_hashtab_create(), ast_hashtab_hash_contexts(), ast_hashtab_insert_immediate(), ast_hashtab_insert_safe(), ast_hashtab_lookup(), ast_hashtab_newsize_java(), ast_hashtab_resize_java(), ast_log(), ast_mutex_init(), ast_rdlock_contexts(), ast_rwlock_init(), ast_strdup, ast_unlock_contexts(), ast_verb, ast_wrlock_contexts(), contexts, contexts_table, ast_context::ignorepats, ast_context::includes, local_contexts, ast_context::lock, LOG_ERROR, ast_context::macrolock, ast_context::name, fake_context::name, name, ast_context::next, ast_context::refcount, ast_context::registrar, ast_context::root, and ast_context::root_table.
Referenced by ast_park_call_full(), build_parkinglot(), context_merge(), load_module(), lua_register_switches(), manage_parkinglot(), pbx_load_config(), pbx_load_users(), reload_config(), and set_config().
05882 { 05883 struct ast_context *tmp, **local_contexts; 05884 struct fake_context search; 05885 int length = sizeof(struct ast_context) + strlen(name) + 1; 05886 05887 if (!contexts_table) { 05888 contexts_table = ast_hashtab_create(17, 05889 ast_hashtab_compare_contexts, 05890 ast_hashtab_resize_java, 05891 ast_hashtab_newsize_java, 05892 ast_hashtab_hash_contexts, 05893 0); 05894 } 05895 05896 ast_copy_string(search.name, name, sizeof(search.name)); 05897 if (!extcontexts) { 05898 ast_rdlock_contexts(); 05899 local_contexts = &contexts; 05900 tmp = ast_hashtab_lookup(contexts_table, &search); 05901 ast_unlock_contexts(); 05902 if (tmp) { 05903 tmp->refcount++; 05904 return tmp; 05905 } 05906 } else { /* local contexts just in a linked list; search there for the new context; slow, linear search, but not frequent */ 05907 local_contexts = extcontexts; 05908 tmp = ast_hashtab_lookup(exttable, &search); 05909 if (tmp) { 05910 tmp->refcount++; 05911 return tmp; 05912 } 05913 } 05914 05915 if ((tmp = ast_calloc(1, length))) { 05916 ast_rwlock_init(&tmp->lock); 05917 ast_mutex_init(&tmp->macrolock); 05918 strcpy(tmp->name, name); 05919 tmp->root = NULL; 05920 tmp->root_table = NULL; 05921 tmp->registrar = ast_strdup(registrar); 05922 tmp->includes = NULL; 05923 tmp->ignorepats = NULL; 05924 tmp->refcount = 1; 05925 } else { 05926 ast_log(LOG_ERROR, "Danger! We failed to allocate a context for %s!\n", name); 05927 return NULL; 05928 } 05929 05930 if (!extcontexts) { 05931 ast_wrlock_contexts(); 05932 tmp->next = *local_contexts; 05933 *local_contexts = tmp; 05934 ast_hashtab_insert_safe(contexts_table, tmp); /*put this context into the tree */ 05935 ast_unlock_contexts(); 05936 ast_debug(1, "Registered context '%s'(%p) in table %p registrar: %s\n", tmp->name, tmp, contexts_table, registrar); 05937 ast_verb(3, "Registered extension context '%s' (%p) in table %p; registrar: %s\n", tmp->name, tmp, contexts_table, registrar); 05938 } else { 05939 tmp->next = *local_contexts; 05940 if (exttable) 05941 ast_hashtab_insert_immediate(exttable, tmp); /*put this context into the tree */ 05942 05943 *local_contexts = tmp; 05944 ast_debug(1, "Registered context '%s'(%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar); 05945 ast_verb(3, "Registered extension context '%s' (%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar); 05946 } 05947 return tmp; 05948 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 4495 of file pbx.c.
References ast_copy_string(), ast_get_context_name(), ast_hashtab_lookup(), ast_mutex_lock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), contexts_table, ast_context::macrolock, and fake_context::name.
Referenced by _macro_exec().
04496 { 04497 struct ast_context *c = NULL; 04498 int ret = -1; 04499 struct fake_context item; 04500 04501 ast_rdlock_contexts(); 04502 04503 ast_copy_string(item.name, context, sizeof(item.name)); 04504 04505 c = ast_hashtab_lookup(contexts_table,&item); 04506 if (c) 04507 ret = 0; 04508 04509 04510 #ifdef NOTNOW 04511 04512 while ((c = ast_walk_contexts(c))) { 04513 if (!strcmp(ast_get_context_name(c), context)) { 04514 ret = 0; 04515 break; 04516 } 04517 } 04518 04519 #endif 04520 ast_unlock_contexts(); 04521 04522 /* if we found context, lock macrolock */ 04523 if (ret == 0) 04524 ret = ast_mutex_lock(&c->macrolock); 04525 04526 return ret; 04527 }
int ast_context_remove_extension | ( | const char * | context, | |
const char * | extension, | |||
int | priority, | |||
const char * | registrar | |||
) |
Simply remove extension from context.
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 4302 of file pbx.c.
References ast_context_remove_extension_callerid().
Referenced by destroy_station(), destroy_trunk(), register_peer_exten(), unregister_exten(), and UnregisterExtension().
04303 { 04304 return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar); 04305 }
int ast_context_remove_extension2 | ( | struct ast_context * | con, | |
const char * | extension, | |||
int | priority, | |||
const char * | registrar, | |||
int | already_locked | |||
) |
This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return.
Definition at line 4329 of file pbx.c.
References ast_context_remove_extension_callerid2().
Referenced by manage_parkinglot(), park_exec_full(), and unload_module().
04330 { 04331 return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar, already_locked); 04332 }
int ast_context_remove_extension_callerid | ( | const char * | context, | |
const char * | extension, | |||
int | priority, | |||
const char * | callerid, | |||
int | matchcid, | |||
const char * | registrar | |||
) |
Definition at line 4307 of file pbx.c.
References ast_context_remove_extension_callerid2(), ast_unlock_contexts(), and find_context_locked().
Referenced by ast_context_remove_extension(), and handle_cli_dialplan_remove_extension().
04308 { 04309 int ret = -1; /* default error return */ 04310 struct ast_context *c = find_context_locked(context); 04311 04312 if (c) { /* ... remove extension ... */ 04313 ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcallerid, registrar, 1); 04314 ast_unlock_contexts(); 04315 } 04316 return ret; 04317 }
int ast_context_remove_extension_callerid2 | ( | struct ast_context * | con, | |
const char * | extension, | |||
int | priority, | |||
const char * | callerid, | |||
int | matchcid, | |||
const char * | registrar, | |||
int | already_locked | |||
) |
Definition at line 4334 of file pbx.c.
References add_exten_to_pattern_tree(), ast_copy_string(), ast_hashtab_insert_immediate(), ast_hashtab_lookup(), ast_hashtab_remove_this_object(), ast_hashtab_size(), ast_log(), ast_strlen_zero(), ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_exten::cidmatch, destroy_exten(), ast_exten::exten, exten, ast_exten::label, LOG_ERROR, log_match_char_tree(), LOG_NOTICE, LOG_WARNING, ast_exten::matchcid, ast_exten::next, ast_exten::peer, ast_exten::peer_label_table, ast_exten::peer_table, ast_exten::priority, ast_exten::registrar, and match_char::x.
Referenced by __ast_context_destroy(), ast_context_remove_extension2(), and ast_context_remove_extension_callerid().
04335 { 04336 struct ast_exten *exten, *prev_exten = NULL; 04337 struct ast_exten *peer; 04338 struct ast_exten ex, *exten2, *exten3; 04339 char dummy_name[1024]; 04340 struct ast_exten *previous_peer = NULL; 04341 struct ast_exten *next_peer = NULL; 04342 int found = 0; 04343 04344 if (!already_locked) 04345 ast_wrlock_context(con); 04346 04347 /* Handle this is in the new world */ 04348 04349 /* FIXME For backwards compatibility, if callerid==NULL, then remove ALL 04350 * peers, not just those matching the callerid. */ 04351 #ifdef NEED_DEBUG 04352 ast_verb(3,"Removing %s/%s/%d%s%s from trees, registrar=%s\n", con->name, extension, priority, matchcallerid ? "/" : "", matchcallerid ? callerid : "", registrar); 04353 #endif 04354 #ifdef CONTEXT_DEBUG 04355 check_contexts(__FILE__, __LINE__); 04356 #endif 04357 /* find this particular extension */ 04358 ex.exten = dummy_name; 04359 ex.matchcid = matchcallerid && !ast_strlen_zero(callerid); /* don't say match if there's no callerid */ 04360 ex.cidmatch = callerid; 04361 ast_copy_string(dummy_name, extension, sizeof(dummy_name)); 04362 exten = ast_hashtab_lookup(con->root_table, &ex); 04363 if (exten) { 04364 if (priority == 0) { 04365 exten2 = ast_hashtab_remove_this_object(con->root_table, exten); 04366 if (!exten2) 04367 ast_log(LOG_ERROR,"Trying to delete the exten %s from context %s, but could not remove from the root_table\n", extension, con->name); 04368 if (con->pattern_tree) { 04369 04370 struct match_char *x = add_exten_to_pattern_tree(con, exten, 1); 04371 04372 if (x->exten) { /* this test for safety purposes */ 04373 x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */ 04374 x->exten = 0; /* get rid of what will become a bad pointer */ 04375 } else { 04376 ast_log(LOG_WARNING,"Trying to delete an exten from a context, but the pattern tree node returned isn't a full extension\n"); 04377 } 04378 } 04379 } else { 04380 ex.priority = priority; 04381 exten2 = ast_hashtab_lookup(exten->peer_table, &ex); 04382 if (exten2) { 04383 04384 if (exten2->label) { /* if this exten has a label, remove that, too */ 04385 exten3 = ast_hashtab_remove_this_object(exten->peer_label_table,exten2); 04386 if (!exten3) 04387 ast_log(LOG_ERROR,"Did not remove this priority label (%d/%s) from the peer_label_table of context %s, extension %s!\n", priority, exten2->label, con->name, exten2->exten); 04388 } 04389 04390 exten3 = ast_hashtab_remove_this_object(exten->peer_table, exten2); 04391 if (!exten3) 04392 ast_log(LOG_ERROR,"Did not remove this priority (%d) from the peer_table of context %s, extension %s!\n", priority, con->name, exten2->exten); 04393 if (exten2 == exten && exten2->peer) { 04394 exten2 = ast_hashtab_remove_this_object(con->root_table, exten); 04395 ast_hashtab_insert_immediate(con->root_table, exten2->peer); 04396 } 04397 if (ast_hashtab_size(exten->peer_table) == 0) { 04398 /* well, if the last priority of an exten is to be removed, 04399 then, the extension is removed, too! */ 04400 exten3 = ast_hashtab_remove_this_object(con->root_table, exten); 04401 if (!exten3) 04402 ast_log(LOG_ERROR,"Did not remove this exten (%s) from the context root_table (%s) (priority %d)\n", exten->exten, con->name, priority); 04403 if (con->pattern_tree) { 04404 struct match_char *x = add_exten_to_pattern_tree(con, exten, 1); 04405 if (x->exten) { /* this test for safety purposes */ 04406 x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */ 04407 x->exten = 0; /* get rid of what will become a bad pointer */ 04408 } 04409 } 04410 } 04411 } else { 04412 ast_log(LOG_ERROR,"Could not find priority %d of exten %s in context %s!\n", 04413 priority, exten->exten, con->name); 04414 } 04415 } 04416 } else { 04417 /* hmmm? this exten is not in this pattern tree? */ 04418 ast_log(LOG_WARNING,"Cannot find extension %s in root_table in context %s\n", 04419 extension, con->name); 04420 } 04421 #ifdef NEED_DEBUG 04422 if (con->pattern_tree) { 04423 ast_log(LOG_NOTICE,"match char tree after exten removal:\n"); 04424 log_match_char_tree(con->pattern_tree, " "); 04425 } 04426 #endif 04427 04428 /* scan the extension list to find first matching extension-registrar */ 04429 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 04430 if (!strcmp(exten->exten, extension) && 04431 (!registrar || !strcmp(exten->registrar, registrar)) && 04432 (!matchcallerid || (!ast_strlen_zero(callerid) && !ast_strlen_zero(exten->cidmatch) && !strcmp(exten->cidmatch, callerid)) || (ast_strlen_zero(callerid) && ast_strlen_zero(exten->cidmatch)))) 04433 break; 04434 } 04435 if (!exten) { 04436 /* we can't find right extension */ 04437 if (!already_locked) 04438 ast_unlock_context(con); 04439 return -1; 04440 } 04441 04442 /* scan the priority list to remove extension with exten->priority == priority */ 04443 for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next; 04444 peer && !strcmp(peer->exten, extension) && (!matchcallerid || (!ast_strlen_zero(callerid) && !ast_strlen_zero(peer->cidmatch) && !strcmp(peer->cidmatch,callerid)) || (ast_strlen_zero(callerid) && ast_strlen_zero(peer->cidmatch))); 04445 peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) { 04446 if ((priority == 0 || peer->priority == priority) && 04447 (!callerid || !matchcallerid || (matchcallerid && !strcmp(peer->cidmatch, callerid))) && 04448 (!registrar || !strcmp(peer->registrar, registrar) )) { 04449 found = 1; 04450 04451 /* we are first priority extension? */ 04452 if (!previous_peer) { 04453 /* 04454 * We are first in the priority chain, so must update the extension chain. 04455 * The next node is either the next priority or the next extension 04456 */ 04457 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 04458 if (peer->peer) { 04459 /* move the peer_table and peer_label_table down to the next peer, if 04460 it is there */ 04461 peer->peer->peer_table = peer->peer_table; 04462 peer->peer->peer_label_table = peer->peer_label_table; 04463 peer->peer_table = NULL; 04464 peer->peer_label_table = NULL; 04465 } 04466 if (!prev_exten) { /* change the root... */ 04467 con->root = next_node; 04468 } else { 04469 prev_exten->next = next_node; /* unlink */ 04470 } 04471 if (peer->peer) { /* update the new head of the pri list */ 04472 peer->peer->next = peer->next; 04473 } 04474 } else { /* easy, we are not first priority in extension */ 04475 previous_peer->peer = peer->peer; 04476 } 04477 04478 /* now, free whole priority extension */ 04479 destroy_exten(peer); 04480 } else { 04481 previous_peer = peer; 04482 } 04483 } 04484 if (!already_locked) 04485 ast_unlock_context(con); 04486 return found ? 0 : -1; 04487 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 6628 of file pbx.c.
References ast_context_remove_ignorepat2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_cli_dialplan_remove_ignorepat().
06629 { 06630 int ret = -1; 06631 struct ast_context *c = find_context_locked(context); 06632 06633 if (c) { 06634 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 06635 ast_unlock_contexts(); 06636 } 06637 return ret; 06638 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 6640 of file pbx.c.
References ast_free, ast_unlock_context(), ast_wrlock_context(), errno, ast_context::ignorepats, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.
Referenced by ast_context_remove_ignorepat().
06641 { 06642 struct ast_ignorepat *ip, *ipl = NULL; 06643 06644 ast_wrlock_context(con); 06645 06646 for (ip = con->ignorepats; ip; ip = ip->next) { 06647 if (!strcmp(ip->pattern, ignorepat) && 06648 (!registrar || (registrar == ip->registrar))) { 06649 if (ipl) { 06650 ipl->next = ip->next; 06651 ast_free(ip); 06652 } else { 06653 con->ignorepats = ip->next; 06654 ast_free(ip); 06655 } 06656 ast_unlock_context(con); 06657 return 0; 06658 } 06659 ipl = ip; 06660 } 06661 06662 ast_unlock_context(con); 06663 errno = EINVAL; 06664 return -1; 06665 }
int ast_context_remove_include | ( | const char * | context, | |
const char * | include, | |||
const char * | registrar | |||
) |
Remove a context include.
0 | on success | |
-1 | on failure |
Definition at line 4194 of file pbx.c.
References ast_context_remove_include2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_cli_dialplan_remove_include().
04195 { 04196 int ret = -1; 04197 struct ast_context *c = find_context_locked(context); 04198 04199 if (c) { 04200 /* found, remove include from this context ... */ 04201 ret = ast_context_remove_include2(c, include, registrar); 04202 ast_unlock_contexts(); 04203 } 04204 return ret; 04205 }
int ast_context_remove_include2 | ( | struct ast_context * | con, | |
const char * | include, | |||
const char * | registrar | |||
) |
Removes an include by an ast_context structure.
0 | on success. | |
-1 | on failure. |
Definition at line 4216 of file pbx.c.
References ast_free, ast_get_context_name(), ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_context::includes, ast_include::name, ast_include::next, and ast_include::registrar.
Referenced by ast_context_remove_include().
04217 { 04218 struct ast_include *i, *pi = NULL; 04219 int ret = -1; 04220 04221 ast_wrlock_context(con); 04222 04223 /* find our include */ 04224 for (i = con->includes; i; pi = i, i = i->next) { 04225 if (!strcmp(i->name, include) && 04226 (!registrar || !strcmp(i->registrar, registrar))) { 04227 /* remove from list */ 04228 ast_verb(3, "Removing inclusion of context '%s' in context '%s; registrar=%s'\n", include, ast_get_context_name(con), registrar); 04229 if (pi) 04230 pi->next = i->next; 04231 else 04232 con->includes = i->next; 04233 /* free include and return */ 04234 ast_free(i); 04235 ret = 0; 04236 break; 04237 } 04238 } 04239 04240 ast_unlock_context(con); 04241 04242 return ret; 04243 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 4250 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
04251 { 04252 int ret = -1; /* default error return */ 04253 struct ast_context *c = find_context_locked(context); 04254 04255 if (c) { 04256 /* remove switch from this context ... */ 04257 ret = ast_context_remove_switch2(c, sw, data, registrar); 04258 ast_unlock_contexts(); 04259 } 04260 return ret; 04261 }
int ast_context_remove_switch2 | ( | struct ast_context * | con, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
This function locks given context, removes switch, unlock context and return.
Definition at line 4271 of file pbx.c.
References ast_context::alts, ast_free, ast_get_context_name(), AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_sw::data, ast_sw::list, ast_sw::name, and ast_sw::registrar.
Referenced by ast_context_remove_switch().
04272 { 04273 struct ast_sw *i; 04274 int ret = -1; 04275 04276 ast_wrlock_context(con); 04277 04278 /* walk switches */ 04279 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 04280 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 04281 (!registrar || !strcmp(i->registrar, registrar))) { 04282 /* found, remove from list */ 04283 ast_verb(3, "Removing switch '%s' from context '%s; registrar=%s'\n", sw, ast_get_context_name(con), registrar); 04284 AST_LIST_REMOVE_CURRENT(list); 04285 ast_free(i); /* free switch and return */ 04286 ret = 0; 04287 break; 04288 } 04289 } 04290 AST_LIST_TRAVERSE_SAFE_END; 04291 04292 ast_unlock_context(con); 04293 04294 return ret; 04295 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 4534 of file pbx.c.
References ast_copy_string(), ast_get_context_name(), ast_hashtab_lookup(), ast_mutex_unlock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), contexts_table, ast_context::macrolock, and fake_context::name.
Referenced by _macro_exec().
04535 { 04536 struct ast_context *c = NULL; 04537 int ret = -1; 04538 struct fake_context item; 04539 04540 ast_rdlock_contexts(); 04541 04542 ast_copy_string(item.name, context, sizeof(item.name)); 04543 04544 c = ast_hashtab_lookup(contexts_table,&item); 04545 if (c) 04546 ret = 0; 04547 #ifdef NOTNOW 04548 04549 while ((c = ast_walk_contexts(c))) { 04550 if (!strcmp(ast_get_context_name(c), context)) { 04551 ret = 0; 04552 break; 04553 } 04554 } 04555 04556 #endif 04557 ast_unlock_contexts(); 04558 04559 /* if we found context, unlock macrolock */ 04560 if (ret == 0) 04561 ret = ast_mutex_unlock(&c->macrolock); 04562 04563 return ret; 04564 }
int ast_context_verify_includes | ( | struct ast_context * | con | ) |
Verifies includes in an ast_contect structure.
con | context in which to verify the includes |
0 | if no problems found | |
-1 | if there were any missing context |
Definition at line 8961 of file pbx.c.
References ast_context_find(), ast_get_context_name(), ast_log(), ast_walk_context_includes(), LOG_WARNING, and ast_include::rname.
Referenced by pbx_load_module().
08962 { 08963 struct ast_include *inc = NULL; 08964 int res = 0; 08965 08966 while ( (inc = ast_walk_context_includes(con, inc)) ) { 08967 if (ast_context_find(inc->rname)) 08968 continue; 08969 08970 res = -1; 08971 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 08972 ast_get_context_name(con), inc->rname); 08973 break; 08974 } 08975 08976 return res; 08977 }
struct ast_custom_function* ast_custom_function_find | ( | const char * | name | ) |
Definition at line 2785 of file pbx.c.
References ast_custom_function::acflist, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, and ast_custom_function::name.
Referenced by ast_func_read(), ast_func_write(), config_curl(), destroy_curl(), handle_show_function(), op_func(), realtime_curl(), realtime_multi_curl(), require_curl(), store_curl(), and update_curl().
02786 { 02787 struct ast_custom_function *acf = NULL; 02788 02789 AST_RWLIST_RDLOCK(&acf_root); 02790 AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) { 02791 if (!strcmp(name, acf->name)) 02792 break; 02793 } 02794 AST_RWLIST_UNLOCK(&acf_root); 02795 02796 return acf; 02797 }
int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Unregister a custom function.
Definition at line 2799 of file pbx.c.
References ast_custom_function::acflist, AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, and ast_custom_function::name.
Referenced by load_module(), reload(), and unload_module().
02800 { 02801 struct ast_custom_function *cur; 02802 02803 if (!acf) 02804 return -1; 02805 02806 AST_RWLIST_WRLOCK(&acf_root); 02807 if ((cur = AST_RWLIST_REMOVE(&acf_root, acf, acflist))) 02808 ast_verb(2, "Unregistered custom function %s\n", cur->name); 02809 AST_RWLIST_UNLOCK(&acf_root); 02810 02811 return cur ? 0 : -1; 02812 }
enum ast_extension_states ast_devstate_to_extenstate | ( | enum ast_device_state | devstate | ) |
Map devstate to an extension state.
[in] | device | state |
Definition at line 3281 of file pbx.c.
References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_TOTAL, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, AST_EXTENSION_BUSY, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_RINGING, and AST_EXTENSION_UNAVAILABLE.
Referenced by ast_extension_state2().
03282 { 03283 switch (devstate) { 03284 case AST_DEVICE_ONHOLD: 03285 return AST_EXTENSION_ONHOLD; 03286 case AST_DEVICE_BUSY: 03287 return AST_EXTENSION_BUSY; 03288 case AST_DEVICE_UNAVAILABLE: 03289 case AST_DEVICE_UNKNOWN: 03290 case AST_DEVICE_INVALID: 03291 return AST_EXTENSION_UNAVAILABLE; 03292 case AST_DEVICE_RINGINUSE: 03293 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING); 03294 case AST_DEVICE_RINGING: 03295 return AST_EXTENSION_RINGING; 03296 case AST_DEVICE_INUSE: 03297 return AST_EXTENSION_INUSE; 03298 case AST_DEVICE_NOT_INUSE: 03299 return AST_EXTENSION_NOT_INUSE; 03300 case AST_DEVICE_TOTAL: /* not a device state, included for completeness */ 03301 break; 03302 } 03303 03304 return AST_EXTENSION_NOT_INUSE; 03305 }
int ast_exists_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) |
Determine whether an extension exists.
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 3651 of file pbx.c.
References E_MATCH, and pbx_extension_helper().
Referenced by __ast_goto_if_exists(), __ast_pbx_run(), _macro_exec(), acf_isexten_exec(), answer_call(), ast_app_dtget(), ast_bridge_call(), ast_pbx_outgoing_exten(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), cli_console_dial(), conf_run(), console_dial(), console_transfer(), dahdi_handle_dtmfup(), dial_exec_full(), disa_exec(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), gosub_exec(), handle_gosub(), handle_link_data(), handle_link_phone_dtmf(), handle_stimulus_message(), isexten_function_read(), leave_voicemail(), local_alloc(), local_call(), local_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), minivm_greet_exec(), misdn_overlap_dial_task(), park_space_reserve(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), pri_dchannel(), privacy_exec(), process_ast_dsp(), readexten_exec(), register_peer_exten(), rpt_exec(), show_debug_helper(), sip_read(), skinny_ss(), socket_process(), ss_thread(), and waitstream_core().
03652 { 03653 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0, 0); 03654 }
int ast_explicit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6775 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_FLAG_IN_AUTOLOOP, ast_strlen_zero(), ast_test_flag, chan, ast_channel::context, ast_channel::exten, and ast_channel::priority.
Referenced by __ast_goto_if_exists(), ast_async_goto(), builtin_atxfer(), do_bridge_masquerade(), handle_setpriority(), pbx_parseable_goto(), and return_exec().
06776 { 06777 if (!chan) 06778 return -1; 06779 06780 ast_channel_lock(chan); 06781 06782 if (!ast_strlen_zero(context)) 06783 ast_copy_string(chan->context, context, sizeof(chan->context)); 06784 if (!ast_strlen_zero(exten)) 06785 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 06786 if (priority > -1) { 06787 chan->priority = priority; 06788 /* see flag description in channel.h for explanation */ 06789 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 06790 chan->priority--; 06791 } 06792 06793 ast_channel_unlock(chan); 06794 06795 return 0; 06796 }
int ast_extension_close | ( | const char * | pattern, | |
const char * | data, | |||
int | needmore | |||
) |
Definition at line 2008 of file pbx.c.
References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.
Referenced by lua_find_extension(), and realtime_switch_common().
02009 { 02010 if (needmore != E_MATCHMORE && needmore != E_CANMATCH) 02011 ast_log(LOG_WARNING, "invalid argument %d\n", needmore); 02012 return extension_match_core(pattern, data, needmore); 02013 }
int ast_extension_cmp | ( | const char * | a, | |
const char * | b | |||
) |
Determine if one extension should match before another.
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 1810 of file pbx.c.
References ext_cmp().
Referenced by lua_extension_cmp().
01811 { 01812 return ext_cmp(a, b); 01813 }
int ast_extension_match | ( | const char * | pattern, | |
const char * | extension | |||
) |
Determine if a given extension matches a given pattern (in NXX format).
pattern | pattern to match | |
extension | extension to check against the pattern. |
1 | on match | |
0 | on failure |
Definition at line 2003 of file pbx.c.
References E_MATCH, and extension_match_core().
Referenced by ast_ignore_pattern(), do_say(), find_matching_priority(), load_module(), loopback_canmatch(), loopback_exists(), loopback_matchmore(), lua_find_extension(), manager_show_dialplan_helper(), matchcid(), misdn_cfg_is_msn_valid(), realtime_switch_common(), reload(), and show_dialplan_helper().
02004 { 02005 return extension_match_core(pattern, data, E_MATCH); 02006 }
int ast_extension_patmatch | ( | const char * | pattern, | |
const char * | data | |||
) |
int ast_extension_state | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten | |||
) |
Uses hint and devicestate callback to get the state of an extension.
c | this is not important | |
context | which context to look in | |
exten | which extension to get state |
Definition at line 3343 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), extstate_read(), and handle_request_subscribe().
03344 { 03345 struct ast_exten *e; 03346 03347 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 03348 if (!e) 03349 return -1; /* No hint, return -1 */ 03350 03351 return ast_extension_state2(e); /* Check all devices in the hint */ 03352 }
const char* ast_extension_state2str | ( | int | extension_state | ) |
Return string representation of the state of an extension.
extension_state | is the numerical state delivered by ast_extension_state |
Definition at line 3331 of file pbx.c.
References ARRAY_LEN, extension_states, and cfextension_states::text.
Referenced by cb_extensionstate(), handle_request_subscribe(), handle_show_hint(), handle_show_hints(), and show_channels_cb().
03332 { 03333 int i; 03334 03335 for (i = 0; (i < ARRAY_LEN(extension_states)); i++) { 03336 if (extension_states[i].extension_state == extension_state) 03337 return extension_states[i].text; 03338 } 03339 return "Unknown"; 03340 }
int ast_extension_state_add | ( | const char * | context, | |
const char * | exten, | |||
ast_state_cb_type | callback, | |||
void * | data | |||
) |
Registers a state change callback.
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 3404 of file pbx.c.
References ast_exten::app, ast_add_extension(), ast_calloc, ast_free_ptr, ast_hint_extension(), AST_LIST_INSERT_HEAD, AST_LIST_TRAVERSE, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_state_cb::callback, ast_hint::callbacks, ast_exten::cidmatch, ast_exten::data, ast_state_cb::data, ast_hint::exten, ast_exten::exten, ast_exten::label, ast_exten::matchcid, ast_context::name, ast_exten::parent, ast_exten::priority, ast_exten::registrar, and stateid.
Referenced by __init_manager(), handle_request_subscribe(), and skinny_register().
03406 { 03407 struct ast_hint *hint; 03408 struct ast_state_cb *cblist; 03409 struct ast_exten *e; 03410 03411 /* If there's no context and extension: add callback to statecbs list */ 03412 if (!context && !exten) { 03413 AST_RWLIST_WRLOCK(&hints); 03414 03415 AST_LIST_TRAVERSE(&statecbs, cblist, entry) { 03416 if (cblist->callback == callback) { 03417 cblist->data = data; 03418 AST_RWLIST_UNLOCK(&hints); 03419 return 0; 03420 } 03421 } 03422 03423 /* Now insert the callback */ 03424 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 03425 AST_RWLIST_UNLOCK(&hints); 03426 return -1; 03427 } 03428 cblist->id = 0; 03429 cblist->callback = callback; 03430 cblist->data = data; 03431 03432 AST_LIST_INSERT_HEAD(&statecbs, cblist, entry); 03433 03434 AST_RWLIST_UNLOCK(&hints); 03435 03436 return 0; 03437 } 03438 03439 if (!context || !exten) 03440 return -1; 03441 03442 /* This callback type is for only one hint, so get the hint */ 03443 e = ast_hint_extension(NULL, context, exten); 03444 if (!e) { 03445 return -1; 03446 } 03447 03448 /* If this is a pattern, dynamically create a new extension for this 03449 * particular match. Note that this will only happen once for each 03450 * individual extension, because the pattern will no longer match first. 03451 */ 03452 if (e->exten[0] == '_') { 03453 ast_add_extension(e->parent->name, 0, exten, e->priority, e->label, 03454 e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr, 03455 e->registrar); 03456 e = ast_hint_extension(NULL, context, exten); 03457 if (!e || e->exten[0] == '_') { 03458 return -1; 03459 } 03460 } 03461 03462 /* Find the hint in the list of hints */ 03463 AST_RWLIST_WRLOCK(&hints); 03464 03465 AST_RWLIST_TRAVERSE(&hints, hint, list) { 03466 if (hint->exten == e) 03467 break; 03468 } 03469 03470 if (!hint) { 03471 /* We have no hint, sorry */ 03472 AST_RWLIST_UNLOCK(&hints); 03473 return -1; 03474 } 03475 03476 /* Now insert the callback in the callback list */ 03477 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 03478 AST_RWLIST_UNLOCK(&hints); 03479 return -1; 03480 } 03481 03482 cblist->id = stateid++; /* Unique ID for this callback */ 03483 cblist->callback = callback; /* Pointer to callback routine */ 03484 cblist->data = data; /* Data for the callback */ 03485 03486 AST_LIST_INSERT_HEAD(&hint->callbacks, cblist, entry); 03487 03488 AST_RWLIST_UNLOCK(&hints); 03489 03490 return cblist->id; 03491 }
int ast_extension_state_del | ( | int | id, | |
ast_state_cb_type | callback | |||
) |
Deletes a registered state change callback by ID.
id | of the callback to delete | |
callback | callback |
0 | success | |
-1 | failure |
Definition at line 3494 of file pbx.c.
References ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::entry, ast_state_cb::id, and ast_hint::list.
Referenced by dialog_unlink_all(), handle_request_subscribe(), and skinny_unregister().
03495 { 03496 struct ast_state_cb *p_cur = NULL; 03497 int ret = -1; 03498 03499 if (!id && !callback) 03500 return -1; 03501 03502 AST_RWLIST_WRLOCK(&hints); 03503 03504 if (!id) { /* id == 0 is a callback without extension */ 03505 AST_LIST_TRAVERSE_SAFE_BEGIN(&statecbs, p_cur, entry) { 03506 if (p_cur->callback == callback) { 03507 AST_LIST_REMOVE_CURRENT(entry); 03508 break; 03509 } 03510 } 03511 AST_LIST_TRAVERSE_SAFE_END; 03512 } else { /* callback with extension, find the callback based on ID */ 03513 struct ast_hint *hint; 03514 AST_RWLIST_TRAVERSE(&hints, hint, list) { 03515 AST_LIST_TRAVERSE_SAFE_BEGIN(&hint->callbacks, p_cur, entry) { 03516 if (p_cur->id == id) { 03517 AST_LIST_REMOVE_CURRENT(entry); 03518 break; 03519 } 03520 } 03521 AST_LIST_TRAVERSE_SAFE_END; 03522 03523 if (p_cur) 03524 break; 03525 } 03526 } 03527 03528 if (p_cur) { 03529 ast_free(p_cur); 03530 } 03531 03532 AST_RWLIST_UNLOCK(&hints); 03533 03534 return ret; 03535 }
int ast_findlabel_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
const char * | label, | |||
const char * | callerid | |||
) |
Find the priority of an extension that has the specified label.
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 3656 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by action_originate(), action_redirect(), handle_gosub(), handle_setpriority(), isexten_function_read(), and pbx_parseable_goto().
03657 { 03658 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0, 0); 03659 }
int ast_findlabel_extension2 | ( | struct ast_channel * | c, | |
struct ast_context * | con, | |||
const char * | exten, | |||
const char * | label, | |||
const char * | callerid | |||
) |
Find the priority of an extension that has the specified label.
This function is the same as ast_findlabel_extension, except that it accepts a pointer to an ast_context structure to specify the context instead of the name of the context. Otherwise, the functions behave the same.
Definition at line 3661 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
03662 { 03663 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0, 0); 03664 }
int ast_func_read | ( | struct ast_channel * | chan, | |
const char * | function, | |||
char * | workspace, | |||
size_t | len | |||
) |
executes a read operation on a function
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 2872 of file pbx.c.
References __ast_module_user_add(), __ast_module_user_remove(), ast_custom_function_find(), ast_log(), ast_strdupa, chan, copy(), func_args(), LOG_ERROR, ast_custom_function::mod, and ast_custom_function::read.
Referenced by action_getvar(), action_status(), handle_getvariable(), lua_get_variable_value(), and pbx_substitute_variables_helper_full().
02873 { 02874 char *copy = ast_strdupa(function); 02875 char *args = func_args(copy); 02876 struct ast_custom_function *acfptr = ast_custom_function_find(copy); 02877 02878 if (acfptr == NULL) 02879 ast_log(LOG_ERROR, "Function %s not registered\n", copy); 02880 else if (!acfptr->read) 02881 ast_log(LOG_ERROR, "Function %s cannot be read\n", copy); 02882 else { 02883 int res; 02884 struct ast_module_user *u = NULL; 02885 if (acfptr->mod) 02886 u = __ast_module_user_add(acfptr->mod, chan); 02887 res = acfptr->read(chan, copy, args, workspace, len); 02888 if (acfptr->mod && u) 02889 __ast_module_user_remove(acfptr->mod, u); 02890 return res; 02891 } 02892 return -1; 02893 }
int ast_func_write | ( | struct ast_channel * | chan, | |
const char * | function, | |||
const char * | value | |||
) |
executes a write operation on a function
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 2895 of file pbx.c.
References __ast_module_user_add(), __ast_module_user_remove(), ast_custom_function_find(), ast_log(), ast_strdupa, chan, copy(), func_args(), LOG_ERROR, ast_custom_function::mod, and ast_custom_function::write.
Referenced by action_setvar(), pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().
02896 { 02897 char *copy = ast_strdupa(function); 02898 char *args = func_args(copy); 02899 struct ast_custom_function *acfptr = ast_custom_function_find(copy); 02900 02901 if (acfptr == NULL) 02902 ast_log(LOG_ERROR, "Function %s not registered\n", copy); 02903 else if (!acfptr->write) 02904 ast_log(LOG_ERROR, "Function %s cannot be written to\n", copy); 02905 else { 02906 int res; 02907 struct ast_module_user *u = NULL; 02908 if (acfptr->mod) 02909 u = __ast_module_user_add(acfptr->mod, chan); 02910 res = acfptr->write(chan, copy, args, value); 02911 if (acfptr->mod && u) 02912 __ast_module_user_remove(acfptr->mod, u); 02913 return res; 02914 } 02915 02916 return -1; 02917 }
const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 8813 of file pbx.c.
References ast_context::name.
Referenced by _macro_exec(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_lockmacro(), ast_context_remove_include2(), ast_context_remove_switch2(), ast_context_unlockmacro(), ast_context_verify_includes(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), context_merge_incls_swits_igps_other_registrars(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_cli_dialplan_save(), handle_show_hint(), handle_show_hints(), manager_show_dialplan_helper(), show_debug_helper(), and show_dialplan_helper().
08814 { 08815 return con ? con->name : NULL; 08816 }
const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 8851 of file pbx.c.
References ast_context::registrar.
Referenced by handle_cli_dialplan_save(), show_debug_helper(), and show_dialplan_helper().
08852 { 08853 return c ? c->registrar : NULL; 08854 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 8881 of file pbx.c.
References ast_exten::app.
Referenced by _macro_exec(), ast_add_hint_nolock(), ast_extension_state2(), ast_get_hint(), find_matching_endwhile(), handle_cli_dialplan_save(), handle_show_hint(), handle_show_hints(), handle_statechange(), manager_show_dialplan_helper(), and print_ext().
08882 { 08883 return e ? e->app : NULL; 08884 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 8886 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and print_ext().
08887 { 08888 return e ? e->data : NULL; 08889 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 8876 of file pbx.c.
References ast_exten::cidmatch.
Referenced by complete_dialplan_remove_extension(), find_matching_priority(), and handle_cli_dialplan_save().
08877 { 08878 return e ? e->cidmatch : NULL; 08879 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
Definition at line 8818 of file pbx.c.
References exten.
Referenced by handle_show_hint(), and handle_show_hints().
const char* ast_get_extension_label | ( | struct ast_exten * | e | ) |
Definition at line 8828 of file pbx.c.
References exten.
Referenced by handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
int ast_get_extension_matchcid | ( | struct ast_exten * | e | ) |
Definition at line 8871 of file pbx.c.
References ast_exten::matchcid.
Referenced by complete_dialplan_remove_extension(), find_matching_priority(), and handle_cli_dialplan_save().
08872 { 08873 return e ? e->matchcid : 0; 08874 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 8823 of file pbx.c.
References exten.
Referenced by ast_add_hint_nolock(), complete_core_show_hint(), complete_dialplan_remove_extension(), dundi_precache_full(), find_matching_priority(), handle_cli_dialplan_save(), handle_show_hint(), handle_show_hints(), manager_show_dialplan_helper(), and show_dialplan_helper().
int ast_get_extension_priority | ( | struct ast_exten * | exten | ) |
Definition at line 8843 of file pbx.c.
References exten.
Referenced by complete_dialplan_remove_extension(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and print_ext().
const char* ast_get_extension_registrar | ( | struct ast_exten * | e | ) |
Definition at line 8856 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08857 { 08858 return e ? e->registrar : NULL; 08859 }
int ast_get_hint | ( | char * | hint, | |
int | maxlen, | |||
char * | name, | |||
int | maxnamelen, | |||
struct ast_channel * | c, | |||
const char * | context, | |||
const char * | exten | |||
) |
If an extension hint exists, return non-zero.
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 3634 of file pbx.c.
References ast_copy_string(), ast_get_extension_app(), ast_get_extension_app_data(), and ast_hint_extension().
Referenced by action_extensionstate(), get_cid_name(), get_destination(), hint_read(), manager_state_cb(), pbx_retrieve_variable(), skinny_extensionstate_cb(), and transmit_state_notify().
03635 { 03636 struct ast_exten *e = ast_hint_extension(c, context, exten); 03637 03638 if (e) { 03639 if (hint) 03640 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 03641 if (name) { 03642 const char *tmp = ast_get_extension_app_data(e); 03643 if (tmp) 03644 ast_copy_string(name, tmp, namesize); 03645 } 03646 return -1; 03647 } 03648 return 0; 03649 }
const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 8838 of file pbx.c.
References ast_ignorepat::pattern.
Referenced by complete_dialplan_remove_ignorepat(), context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), lookup_c_ip(), manager_show_dialplan_helper(), and show_dialplan_helper().
08839 { 08840 return ip ? ip->pattern : NULL; 08841 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 8866 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08867 { 08868 return ip ? ip->registrar : NULL; 08869 }
const char* ast_get_include_name | ( | struct ast_include * | include | ) |
Definition at line 8833 of file pbx.c.
References ast_include::name.
Referenced by complete_dialplan_remove_include(), context_merge_incls_swits_igps_other_registrars(), find_matching_priority(), handle_cli_dialplan_save(), lookup_ci(), manager_show_dialplan_helper(), and show_dialplan_helper().
const char* ast_get_include_registrar | ( | struct ast_include * | i | ) |
Definition at line 8861 of file pbx.c.
References ast_include::registrar.
Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08862 { 08863 return i ? i->registrar : NULL; 08864 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 8896 of file pbx.c.
References ast_sw::data.
Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08897 { 08898 return sw ? sw->data : NULL; 08899 }
int ast_get_switch_eval | ( | struct ast_sw * | sw | ) |
Definition at line 8901 of file pbx.c.
References ast_sw::eval.
Referenced by context_merge_incls_swits_igps_other_registrars().
08902 { 08903 return sw->eval; 08904 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 8891 of file pbx.c.
References ast_sw::name.
Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08892 { 08893 return sw ? sw->name : NULL; 08894 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 8906 of file pbx.c.
References ast_sw::registrar.
Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08907 { 08908 return sw ? sw->registrar : NULL; 08909 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 8999 of file pbx.c.
References __ast_goto_if_exists(), and chan.
Referenced by background_detect_exec(), channel_spy(), common_exec(), conf_run(), goto_exten(), onedigit_goto(), priority_jump(), select_entry(), and valid_exit().
09000 { 09001 return __ast_goto_if_exists(chan, context, exten, priority, 0); 09002 }
int ast_hashtab_compare_contexts | ( | const void * | ah_a, | |
const void * | ah_b | |||
) |
unsigned int ast_hashtab_hash_contexts | ( | const void * | obj | ) |
int ast_ignore_pattern | ( | const char * | context, | |
const char * | pattern | |||
) |
Checks to see if a number should be ignored.
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 6721 of file pbx.c.
References ast_context_find(), ast_extension_match(), ast_context::ignorepats, ast_ignorepat::next, and ast_ignorepat::pattern.
Referenced by ast_app_dtget(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_enbloc_call_message(), handle_soft_key_event_message(), handle_stimulus_message(), mgcp_ss(), skinny_ss(), and ss_thread().
06722 { 06723 struct ast_context *con = ast_context_find(context); 06724 if (con) { 06725 struct ast_ignorepat *pat; 06726 for (pat = con->ignorepats; pat; pat = pat->next) { 06727 if (ast_extension_match(pat->pattern, pattern)) 06728 return 1; 06729 } 06730 } 06731 06732 return 0; 06733 }
int ast_matchmore_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) |
Looks to see if adding anything to this extension might match something. (exists ^ canmatch).
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 3671 of file pbx.c.
References E_MATCHMORE, and pbx_extension_helper().
Referenced by ast_app_dtget(), collect_digits(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_link_data(), handle_link_phone_dtmf(), local_dtmf_helper(), loopback_matchmore(), mgcp_ss(), pbx_builtin_background(), readexten_exec(), skinny_ss(), and ss_thread().
03672 { 03673 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0); 03674 }
void ast_merge_contexts_and_delete | ( | struct ast_context ** | extcontexts, | |
struct ast_hashtab * | exttable, | |||
const char * | registrar | |||
) |
Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added.
extcontexts | pointer to the ast_context structure | |
exttable | pointer to the ast_hashtab structure that contains all the elements in extcontexts | |
registrar | of the context; if it's set the routine will delete all contexts that belong to that registrar; if NULL only the contexts that are specified in extcontexts |
Definition at line 6080 of file pbx.c.
References __ast_internal_context_destroy(), ast_add_extension_nolock(), ast_calloc, AST_EXTENSION_REMOVED, ast_free, ast_free_ptr, ast_hashtab_destroy(), ast_hashtab_end_traversal(), ast_hashtab_next(), ast_hashtab_start_traversal(), ast_hint_extension_nolock(), AST_LIST_APPEND_LIST, AST_LIST_EMPTY, AST_LIST_HEAD_INIT_VALUE, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_rdlock_contexts(), AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_tvdiff_us(), ast_tvnow(), ast_unlock_contexts(), ast_verb, ast_wrlock_contexts(), ast_wrlock_contexts_version(), ast_state_cb::callback, ast_hint::callbacks, context_merge(), contexts, contexts_table, ast_state_cb::data, E_MATCH, store_hint::exten, ast_exten::exten, ast_hint::exten, ast_hint::laststate, store_hint::list, LOG_WARNING, ast_context::name, ast_context::next, store_hint::next, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, and pbx_find_info::stacklen.
Referenced by lua_reload_extensions(), and pbx_load_module().
06081 { 06082 double ft; 06083 struct ast_context *tmp, *oldcontextslist; 06084 struct ast_hashtab *oldtable; 06085 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 06086 struct store_hint *this; 06087 struct ast_hint *hint; 06088 struct ast_exten *exten; 06089 int length; 06090 struct ast_state_cb *thiscb; 06091 struct ast_hashtab_iter *iter; 06092 06093 /* it is very important that this function hold the hint list lock _and_ the conlock 06094 during its operation; not only do we need to ensure that the list of contexts 06095 and extensions does not change, but also that no hint callbacks (watchers) are 06096 added or removed during the merge/delete process 06097 06098 in addition, the locks _must_ be taken in this order, because there are already 06099 other code paths that use this order 06100 */ 06101 06102 struct timeval begintime, writelocktime, endlocktime, enddeltime; 06103 int wrlock_ver; 06104 06105 begintime = ast_tvnow(); 06106 ast_rdlock_contexts(); 06107 iter = ast_hashtab_start_traversal(contexts_table); 06108 while ((tmp = ast_hashtab_next(iter))) { 06109 context_merge(extcontexts, exttable, tmp, registrar); 06110 } 06111 ast_hashtab_end_traversal(iter); 06112 wrlock_ver = ast_wrlock_contexts_version(); 06113 06114 ast_unlock_contexts(); /* this feels real retarded, but you must do 06115 what you must do If this isn't done, the following 06116 wrlock is a guraranteed deadlock */ 06117 ast_wrlock_contexts(); 06118 if (ast_wrlock_contexts_version() > wrlock_ver+1) { 06119 ast_log(LOG_WARNING,"==================!!!!!!!!!!!!!!!Something changed the contexts in the middle of merging contexts!\n"); 06120 } 06121 06122 AST_RWLIST_WRLOCK(&hints); 06123 writelocktime = ast_tvnow(); 06124 06125 /* preserve all watchers for hints */ 06126 AST_RWLIST_TRAVERSE(&hints, hint, list) { 06127 if (!AST_LIST_EMPTY(&hint->callbacks)) { 06128 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 06129 if (!(this = ast_calloc(1, length))) 06130 continue; 06131 /* this removes all the callbacks from the hint into this. */ 06132 AST_LIST_APPEND_LIST(&this->callbacks, &hint->callbacks, entry); 06133 this->laststate = hint->laststate; 06134 this->context = this->data; 06135 strcpy(this->data, hint->exten->parent->name); 06136 this->exten = this->data + strlen(this->context) + 1; 06137 strcpy(this->exten, hint->exten->exten); 06138 AST_LIST_INSERT_HEAD(&store, this, list); 06139 } 06140 } 06141 06142 /* save the old table and list */ 06143 oldtable = contexts_table; 06144 oldcontextslist = contexts; 06145 06146 /* move in the new table and list */ 06147 contexts_table = exttable; 06148 contexts = *extcontexts; 06149 06150 /* restore the watchers for hints that can be found; notify those that 06151 cannot be restored 06152 */ 06153 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 06154 struct pbx_find_info q = { .stacklen = 0 }; 06155 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 06156 /* If this is a pattern, dynamically create a new extension for this 06157 * particular match. Note that this will only happen once for each 06158 * individual extension, because the pattern will no longer match first. 06159 */ 06160 if (exten && exten->exten[0] == '_') { 06161 ast_add_extension_nolock(exten->parent->name, 0, this->exten, PRIORITY_HINT, NULL, 06162 0, exten->app, ast_strdup(exten->data), ast_free_ptr, exten->registrar); 06163 /* rwlocks are not recursive locks */ 06164 exten = ast_hint_extension_nolock(NULL, this->context, this->exten); 06165 } 06166 06167 /* Find the hint in the list of hints */ 06168 AST_RWLIST_TRAVERSE(&hints, hint, list) { 06169 if (hint->exten == exten) 06170 break; 06171 } 06172 if (!exten || !hint) { 06173 /* this hint has been removed, notify the watchers */ 06174 while ((thiscb = AST_LIST_REMOVE_HEAD(&this->callbacks, entry))) { 06175 thiscb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, thiscb->data); 06176 ast_free(thiscb); 06177 } 06178 } else { 06179 AST_LIST_APPEND_LIST(&hint->callbacks, &this->callbacks, entry); 06180 hint->laststate = this->laststate; 06181 } 06182 ast_free(this); 06183 } 06184 06185 AST_RWLIST_UNLOCK(&hints); 06186 ast_unlock_contexts(); 06187 endlocktime = ast_tvnow(); 06188 06189 /* the old list and hashtab no longer are relevant, delete them while the rest of asterisk 06190 is now freely using the new stuff instead */ 06191 06192 ast_hashtab_destroy(oldtable, NULL); 06193 06194 for (tmp = oldcontextslist; tmp; ) { 06195 struct ast_context *next; /* next starting point */ 06196 next = tmp->next; 06197 __ast_internal_context_destroy(tmp); 06198 tmp = next; 06199 } 06200 enddeltime = ast_tvnow(); 06201 06202 ft = ast_tvdiff_us(writelocktime, begintime); 06203 ft /= 1000000.0; 06204 ast_verb(3,"Time to scan old dialplan and merge leftovers back into the new: %8.6f sec\n", ft); 06205 06206 ft = ast_tvdiff_us(endlocktime, writelocktime); 06207 ft /= 1000000.0; 06208 ast_verb(3,"Time to restore hints and swap in new dialplan: %8.6f sec\n", ft); 06209 06210 ft = ast_tvdiff_us(enddeltime, endlocktime); 06211 ft /= 1000000.0; 06212 ast_verb(3,"Time to delete the old dialplan: %8.6f sec\n", ft); 06213 06214 ft = ast_tvdiff_us(enddeltime, begintime); 06215 ft /= 1000000.0; 06216 ast_verb(3,"Total time merge_contexts_delete: %8.6f sec\n", ft); 06217 return; 06218 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
This function will handle locking the channel as needed.
Definition at line 9062 of file pbx.c.
References chan, and pbx_parseable_goto().
Referenced by _while_exec(), check_goto_on_transfer(), dial_exec_full(), gosub_exec(), ivr_dispatch(), parkandannounce_exec(), pbx_builtin_goto(), and while_continue_exec().
09063 { 09064 return pbx_parseable_goto(chan, goto_string, 0); 09065 }
int ast_pbx_outgoing_app | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int | timeout, | |||
const char * | app, | |||
const char * | appdata, | |||
int * | reason, | |||
int | sync, | |||
const char * | cid_num, | |||
const char * | cid_name, | |||
struct ast_variable * | vars, | |||
const char * | account, | |||
struct ast_channel ** | locked_channel | |||
) |
Synchronously or asynchronously make an outbound call and send it to a particular application with given extension
Definition at line 7559 of file pbx.c.
References __ast_request_and_dial(), ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_free, ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create_detached, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verb, async_wait(), chan, errno, LOG_WARNING, and outgoing_helper::vars.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_app().
07560 { 07561 struct ast_channel *chan; 07562 struct app_tmp *tmp; 07563 int res = -1, cdr_res = -1; 07564 struct outgoing_helper oh; 07565 07566 memset(&oh, 0, sizeof(oh)); 07567 oh.vars = vars; 07568 oh.account = account; 07569 07570 if (locked_channel) 07571 *locked_channel = NULL; 07572 if (ast_strlen_zero(app)) { 07573 res = -1; 07574 goto outgoing_app_cleanup; 07575 } 07576 if (synchronous) { 07577 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 07578 if (chan) { 07579 ast_set_variables(chan, vars); 07580 if (account) 07581 ast_cdr_setaccount(chan, account); 07582 if (chan->_state == AST_STATE_UP) { 07583 res = 0; 07584 ast_verb(4, "Channel %s was answered.\n", chan->name); 07585 tmp = ast_calloc(1, sizeof(*tmp)); 07586 if (!tmp) 07587 res = -1; 07588 else { 07589 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 07590 if (appdata) 07591 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 07592 tmp->chan = chan; 07593 if (synchronous > 1) { 07594 if (locked_channel) 07595 ast_channel_unlock(chan); 07596 ast_pbx_run_app(tmp); 07597 } else { 07598 if (locked_channel) 07599 ast_channel_lock(chan); 07600 if (ast_pthread_create_detached(&tmp->t, NULL, ast_pbx_run_app, tmp)) { 07601 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 07602 ast_free(tmp); 07603 if (locked_channel) 07604 ast_channel_unlock(chan); 07605 ast_hangup(chan); 07606 res = -1; 07607 } else { 07608 if (locked_channel) 07609 *locked_channel = chan; 07610 } 07611 } 07612 } 07613 } else { 07614 ast_verb(4, "Channel %s was never answered.\n", chan->name); 07615 if (chan->cdr) { /* update the cdr */ 07616 /* here we update the status of the call, which sould be busy. 07617 * if that fails then we set the status to failed */ 07618 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 07619 ast_cdr_failed(chan->cdr); 07620 } 07621 ast_hangup(chan); 07622 } 07623 } 07624 07625 if (res < 0) { /* the call failed for some reason */ 07626 if (*reason == 0) { /* if the call failed (not busy or no answer) 07627 * update the cdr with the failed message */ 07628 cdr_res = ast_pbx_outgoing_cdr_failed(); 07629 if (cdr_res != 0) { 07630 res = cdr_res; 07631 goto outgoing_app_cleanup; 07632 } 07633 } 07634 } 07635 07636 } else { 07637 struct async_stat *as; 07638 if (!(as = ast_calloc(1, sizeof(*as)))) { 07639 res = -1; 07640 goto outgoing_app_cleanup; 07641 } 07642 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 07643 if (!chan) { 07644 ast_free(as); 07645 res = -1; 07646 goto outgoing_app_cleanup; 07647 } 07648 as->chan = chan; 07649 ast_copy_string(as->app, app, sizeof(as->app)); 07650 if (appdata) 07651 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 07652 as->timeout = timeout; 07653 ast_set_variables(chan, vars); 07654 if (account) 07655 ast_cdr_setaccount(chan, account); 07656 /* Start a new thread, and get something handling this channel. */ 07657 if (locked_channel) 07658 ast_channel_lock(chan); 07659 if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) { 07660 ast_log(LOG_WARNING, "Failed to start async wait\n"); 07661 ast_free(as); 07662 if (locked_channel) 07663 ast_channel_unlock(chan); 07664 ast_hangup(chan); 07665 res = -1; 07666 goto outgoing_app_cleanup; 07667 } else { 07668 if (locked_channel) 07669 *locked_channel = chan; 07670 } 07671 res = 0; 07672 } 07673 outgoing_app_cleanup: 07674 ast_variables_destroy(vars); 07675 return res; 07676 }
int ast_pbx_outgoing_exten | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int | timeout, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
int * | reason, | |||
int | sync, | |||
const char * | cid_num, | |||
const char * | cid_name, | |||
struct ast_variable * | vars, | |||
const char * | account, | |||
struct ast_channel ** | locked_channel | |||
) |
Synchronously or asynchronously make an outbound call and send it to a particular extension
Definition at line 7393 of file pbx.c.
References __ast_request_and_dial(), ast_channel::_state, outgoing_helper::account, ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_alloc, ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_exists_extension(), ast_free, ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create_detached, ast_request_and_dial(), ast_set_variables(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verb, async_wait(), ast_channel::cdr, chan, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::context, outgoing_helper::context, outgoing_helper::exten, ast_channel::hangupcause, LOG_ERROR, LOG_WARNING, ast_channel::name, outgoing_helper::parent_channel, pbx_builtin_setvar_helper(), outgoing_helper::priority, set_ext_pri(), and outgoing_helper::vars.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_exten().
07394 { 07395 struct ast_channel *chan; 07396 struct async_stat *as; 07397 int res = -1, cdr_res = -1; 07398 struct outgoing_helper oh; 07399 07400 if (synchronous) { 07401 oh.context = context; 07402 oh.exten = exten; 07403 oh.priority = priority; 07404 oh.cid_num = cid_num; 07405 oh.cid_name = cid_name; 07406 oh.account = account; 07407 oh.vars = vars; 07408 oh.parent_channel = NULL; 07409 07410 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 07411 if (channel) { 07412 *channel = chan; 07413 if (chan) 07414 ast_channel_lock(chan); 07415 } 07416 if (chan) { 07417 if (chan->_state == AST_STATE_UP) { 07418 res = 0; 07419 ast_verb(4, "Channel %s was answered.\n", chan->name); 07420 07421 if (synchronous > 1) { 07422 if (channel) 07423 ast_channel_unlock(chan); 07424 if (ast_pbx_run(chan)) { 07425 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 07426 if (channel) 07427 *channel = NULL; 07428 ast_hangup(chan); 07429 chan = NULL; 07430 res = -1; 07431 } 07432 } else { 07433 if (ast_pbx_start(chan)) { 07434 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 07435 if (channel) { 07436 *channel = NULL; 07437 ast_channel_unlock(chan); 07438 } 07439 ast_hangup(chan); 07440 res = -1; 07441 } 07442 chan = NULL; 07443 } 07444 } else { 07445 ast_verb(4, "Channel %s was never answered.\n", chan->name); 07446 07447 if (chan->cdr) { /* update the cdr */ 07448 /* here we update the status of the call, which sould be busy. 07449 * if that fails then we set the status to failed */ 07450 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 07451 ast_cdr_failed(chan->cdr); 07452 } 07453 07454 if (channel) { 07455 *channel = NULL; 07456 ast_channel_unlock(chan); 07457 } 07458 ast_hangup(chan); 07459 chan = NULL; 07460 } 07461 } 07462 07463 if (res < 0) { /* the call failed for some reason */ 07464 if (*reason == 0) { /* if the call failed (not busy or no answer) 07465 * update the cdr with the failed message */ 07466 cdr_res = ast_pbx_outgoing_cdr_failed(); 07467 if (cdr_res != 0) { 07468 res = cdr_res; 07469 goto outgoing_exten_cleanup; 07470 } 07471 } 07472 07473 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 07474 /* check if "failed" exists */ 07475 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 07476 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 07477 if (chan) { 07478 char failed_reason[4] = ""; 07479 if (!ast_strlen_zero(context)) 07480 ast_copy_string(chan->context, context, sizeof(chan->context)); 07481 set_ext_pri(chan, "failed", 1); 07482 ast_set_variables(chan, vars); 07483 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 07484 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 07485 if (account) 07486 ast_cdr_setaccount(chan, account); 07487 if (ast_pbx_run(chan)) { 07488 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 07489 ast_hangup(chan); 07490 } 07491 chan = NULL; 07492 } 07493 } 07494 } 07495 } else { 07496 if (!(as = ast_calloc(1, sizeof(*as)))) { 07497 res = -1; 07498 goto outgoing_exten_cleanup; 07499 } 07500 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 07501 if (channel) { 07502 *channel = chan; 07503 if (chan) 07504 ast_channel_lock(chan); 07505 } 07506 if (!chan) { 07507 ast_free(as); 07508 res = -1; 07509 goto outgoing_exten_cleanup; 07510 } 07511 as->chan = chan; 07512 ast_copy_string(as->context, context, sizeof(as->context)); 07513 set_ext_pri(as->chan, exten, priority); 07514 as->timeout = timeout; 07515 ast_set_variables(chan, vars); 07516 if (account) 07517 ast_cdr_setaccount(chan, account); 07518 if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) { 07519 ast_log(LOG_WARNING, "Failed to start async wait\n"); 07520 ast_free(as); 07521 if (channel) { 07522 *channel = NULL; 07523 ast_channel_unlock(chan); 07524 } 07525 ast_hangup(chan); 07526 res = -1; 07527 goto outgoing_exten_cleanup; 07528 } 07529 res = 0; 07530 } 07531 outgoing_exten_cleanup: 07532 ast_variables_destroy(vars); 07533 return res; 07534 }
enum ast_pbx_result ast_pbx_run | ( | struct ast_channel * | c | ) |
Execute the PBX in the current thread.
c | channel to run the pbx on |
Zero | on success | |
non-zero | on failure |
Definition at line 4103 of file pbx.c.
References ast_pbx_run_args().
Referenced by ast_pbx_outgoing_exten(), async_wait(), do_idle_thread(), mgcp_ss(), skinny_newcall(), ss_thread(), and unistim_ss().
04104 { 04105 return ast_pbx_run_args(c, NULL); 04106 }
enum ast_pbx_result ast_pbx_run_args | ( | struct ast_channel * | c, | |
struct ast_pbx_args * | args | |||
) |
Execute the PBX in the current thread.
c | channel to run the pbx on | |
args | options for the pbx |
Zero | on success | |
non-zero | on failure |
Definition at line 4088 of file pbx.c.
References __ast_pbx_run(), AST_PBX_CALL_LIMIT, AST_PBX_SUCCESS, decrease_call_count(), and increase_call_count().
Referenced by ast_pbx_run(), dial_exec_full(), and handle_gosub().
04089 { 04090 enum ast_pbx_result res = AST_PBX_SUCCESS; 04091 04092 if (increase_call_count(c)) { 04093 return AST_PBX_CALL_LIMIT; 04094 } 04095 04096 res = __ast_pbx_run(c, args); 04097 04098 decrease_call_count(); 04099 04100 return res; 04101 }
enum ast_pbx_result ast_pbx_start | ( | struct ast_channel * | c | ) |
Create a new thread and start the PBX.
c | channel to start the pbx on |
Zero | on success | |
non-zero | on failure |
Definition at line 4066 of file pbx.c.
References ast_log(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_pthread_create_detached, decrease_call_count(), increase_call_count(), LOG_WARNING, and pbx_thread().
Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_bridge_call_thread(), ast_iax2_new(), ast_pbx_outgoing_exten(), bridge_exec(), check_goto_on_transfer(), console_new(), dahdi_new(), dial_exec_full(), gtalk_new(), gtalk_newcall(), handle_request_invite(), jingle_new(), jingle_newcall(), local_call(), manage_parkinglot(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), skinny_new(), unistim_new(), and usbradio_new().
04067 { 04068 pthread_t t; 04069 04070 if (!c) { 04071 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 04072 return AST_PBX_FAILED; 04073 } 04074 04075 if (increase_call_count(c)) 04076 return AST_PBX_CALL_LIMIT; 04077 04078 /* Start a new thread, and get something handling this channel. */ 04079 if (ast_pthread_create_detached(&t, NULL, pbx_thread, c)) { 04080 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 04081 decrease_call_count(); 04082 return AST_PBX_FAILED; 04083 } 04084 04085 return AST_PBX_SUCCESS; 04086 }
int ast_processed_calls | ( | void | ) |
Retrieve the total number of calls processed through the PBX since last restart.
Definition at line 4113 of file pbx.c.
References totalcalls.
Referenced by handle_chanlist(), and handle_showcalls().
04114 { 04115 return totalcalls; 04116 }
int ast_rdlock_context | ( | struct ast_context * | con | ) |
Read locks a given context.
con | context to lock |
0 | on success | |
-1 | on failure |
Definition at line 8800 of file pbx.c.
References ast_rwlock_rdlock(), and ast_context::lock.
Referenced by _macro_exec(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_cli_dialplan_save(), lookup_c_ip(), lookup_ci(), manager_show_dialplan_helper(), show_debug_helper(), and show_dialplan_helper().
08801 { 08802 return ast_rwlock_rdlock(&con->lock); 08803 }
int ast_rdlock_contexts | ( | void | ) |
Read locks the context list.
0 | on success | |
-1 | on error |
Definition at line 8782 of file pbx.c.
References ast_rwlock_rdlock(), and conlock.
Referenced by _macro_exec(), ast_context_find(), ast_context_find_or_create(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_hint_extension(), ast_merge_contexts_and_delete(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_cli_dialplan_save(), handle_statechange(), manager_show_dialplan_helper(), pbx_extension_helper(), show_debug_helper(), show_dialplan_helper(), and unreference_cached_app().
08783 { 08784 return ast_rwlock_rdlock(&conlock); 08785 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 4618 of file pbx.c.
References ast_log(), AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_switch::list, LOG_WARNING, and ast_switch::name.
Referenced by load_module().
04619 { 04620 struct ast_switch *tmp; 04621 04622 AST_RWLIST_WRLOCK(&switches); 04623 AST_RWLIST_TRAVERSE(&switches, tmp, list) { 04624 if (!strcasecmp(tmp->name, sw->name)) { 04625 AST_RWLIST_UNLOCK(&switches); 04626 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 04627 return -1; 04628 } 04629 } 04630 AST_RWLIST_INSERT_TAIL(&switches, sw, list); 04631 AST_RWLIST_UNLOCK(&switches); 04632 04633 return 0; 04634 }
int ast_spawn_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
int * | found, | |||
int | combined_find_spawn | |||
) |
Launch a new extension (i.e. new stack).
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 3676 of file pbx.c.
References E_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), _macro_exec(), ast_bridge_call(), dial_exec_full(), and loopback_exec().
03677 { 03678 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn); 03679 }
int ast_unlock_context | ( | struct ast_context * | con | ) |
Unlocks | the given context |
con | context to unlock |
0 | on success | |
-1 | on failure |
Definition at line 8805 of file pbx.c.
References ast_rwlock_unlock(), and ast_context::lock.
Referenced by __ast_context_destroy(), _macro_exec(), ast_add_extension2_lockopt(), ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_remove_extension_callerid2(), ast_context_remove_ignorepat2(), ast_context_remove_include2(), ast_context_remove_switch2(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_cli_dialplan_save(), lookup_c_ip(), lookup_ci(), manager_show_dialplan_helper(), show_debug_helper(), and show_dialplan_helper().
08806 { 08807 return ast_rwlock_unlock(&con->lock); 08808 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 8787 of file pbx.c.
References ast_rwlock_unlock(), and conlock.
Referenced by _macro_exec(), ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_destroy(), ast_context_find(), ast_context_find_or_create(), ast_context_lockmacro(), ast_context_remove_extension_callerid(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_unlockmacro(), ast_hint_extension(), ast_merge_contexts_and_delete(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_cli_dialplan_save(), handle_statechange(), manager_show_dialplan_helper(), pbx_extension_helper(), show_debug_helper(), show_dialplan_helper(), and unreference_cached_app().
08788 { 08789 return ast_rwlock_unlock(&conlock); 08790 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 4636 of file pbx.c.
References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and ast_switch::list.
Referenced by __unload_module(), and unload_module().
04637 { 04638 AST_RWLIST_WRLOCK(&switches); 04639 AST_RWLIST_REMOVE(&switches, sw, list); 04640 AST_RWLIST_UNLOCK(&switches); 04641 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | priority | |||
) |
Definition at line 8919 of file pbx.c.
References exten, and ast_context::root.
Referenced by complete_dialplan_remove_extension(), dundi_precache_full(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), pbx_find_extension(), show_dialplan_helper(), and unreference_cached_app().
08921 { 08922 if (!exten) 08923 return con ? con->root : NULL; 08924 else 08925 return exten->next; 08926 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 8952 of file pbx.c.
References ast_context::ignorepats, and ast_ignorepat::next.
Referenced by complete_dialplan_remove_ignorepat(), context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), lookup_c_ip(), manager_show_dialplan_helper(), and show_dialplan_helper().
08954 { 08955 if (!ip) 08956 return con ? con->ignorepats : NULL; 08957 else 08958 return ip->next; 08959 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 8943 of file pbx.c.
References ast_context::includes, and ast_include::next.
Referenced by ast_context_verify_includes(), complete_dialplan_remove_include(), context_merge_incls_swits_igps_other_registrars(), find_matching_priority(), handle_cli_dialplan_save(), lookup_ci(), manager_show_dialplan_helper(), and show_dialplan_helper().
08945 { 08946 if (!inc) 08947 return con ? con->includes : NULL; 08948 else 08949 return inc->next; 08950 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 8928 of file pbx.c.
References ast_context::alts, AST_LIST_FIRST, AST_LIST_NEXT, and ast_sw::list.
Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08930 { 08931 if (!sw) 08932 return con ? AST_LIST_FIRST(&con->alts) : NULL; 08933 else 08934 return AST_LIST_NEXT(sw, list); 08935 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 8914 of file pbx.c.
References contexts, and ast_context::next.
Referenced by _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), pbx_find_extension(), pbx_load_module(), show_debug_helper(), show_dialplan_helper(), and unreference_cached_app().
struct ast_exten* ast_walk_extension_priorities | ( | struct ast_exten * | exten, | |
struct ast_exten * | priority | |||
) |
Definition at line 8937 of file pbx.c.
References exten, and ast_exten::priority.
Referenced by complete_dialplan_remove_extension(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), pbx_find_extension(), show_dialplan_helper(), and unreference_cached_app().
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 8795 of file pbx.c.
References ast_rwlock_wrlock(), and ast_context::lock.
Referenced by __ast_context_destroy(), ast_add_extension2_lockopt(), ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_remove_extension_callerid2(), ast_context_remove_ignorepat2(), ast_context_remove_include2(), and ast_context_remove_switch2().
08796 { 08797 return ast_rwlock_wrlock(&con->lock); 08798 }
int ast_wrlock_contexts | ( | void | ) |
Write locks the context list.
0 | on success | |
-1 | on error |
Definition at line 8774 of file pbx.c.
References ast_atomic_fetchadd_int(), ast_rwlock_wrlock(), and conlock.
Referenced by ast_context_destroy(), ast_context_find_or_create(), ast_merge_contexts_and_delete(), and complete_dialplan_remove_include().
08775 { 08776 int res = ast_rwlock_wrlock(&conlock); 08777 if (!res) 08778 ast_atomic_fetchadd_int(&conlock_wrlock_version, 1); 08779 return res; 08780 }
int ast_wrlock_contexts_version | ( | void | ) |
Definition at line 8766 of file pbx.c.
Referenced by ast_merge_contexts_and_delete().
08767 { 08768 return conlock_wrlock_version; 08769 }
void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 8611 of file pbx.c.
References AST_LIST_REMOVE_HEAD, ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_var_delete(), ast_var_t::entries, globals, and globalslock.
Referenced by handle_cli_dialplan_reload(), and reload().
08612 { 08613 struct ast_var_t *vardata; 08614 08615 ast_rwlock_wrlock(&globalslock); 08616 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 08617 ast_var_delete(vardata); 08618 ast_rwlock_unlock(&globalslock); 08619 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
This function will return a pointer to the buffer inside the channel variable. This value should only be accessed with the channel locked. If the value needs to be kept around, it should be done by using the following thread-safe code:
const char *var; ast_channel_lock(chan); if ((var = pbx_builtin_getvar_helper(chan, "MYVAR"))) { var = ast_strdupa(var); } ast_channel_unlock(chan);
Definition at line 8380 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_var_name(), ast_var_value(), chan, globals, and globalslock.
Referenced by _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), array(), ast_bridge_call(), ast_call_forward(), ast_eivr_getvariable(), ast_feature_interpret(), ast_monitor_stop(), ast_park_call_full(), bridge_play_sounds(), builtin_atxfer(), builtin_automixmonitor(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dahdi_call(), dahdi_hangup(), dial_exec_full(), do_forward(), do_timelimit(), dundi_exec(), dundi_helper(), findparkinglotname(), get_also_info(), get_index(), get_refer_info(), global_read(), hash_read(), iax2_call(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), local_read(), login_exec(), macro_fixup(), minivm_delete_exec(), minivm_notify_exec(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_space_reserve(), pbx_builtin_background(), pickup_by_mark(), queue_exec(), real_ctx(), retrydial_exec(), ring_entry(), run_agi(), set_config_flags(), set_local_info(), sip_addheader(), sla_trunk_exec(), speech_background(), try_suggested_sip_codec(), and update_bridge_vars().
08381 { 08382 struct ast_var_t *variables; 08383 const char *ret = NULL; 08384 int i; 08385 struct varshead *places[2] = { NULL, &globals }; 08386 08387 if (!name) 08388 return NULL; 08389 08390 if (chan) { 08391 ast_channel_lock(chan); 08392 places[0] = &chan->varshead; 08393 } 08394 08395 for (i = 0; i < 2; i++) { 08396 if (!places[i]) 08397 continue; 08398 if (places[i] == &globals) 08399 ast_rwlock_rdlock(&globalslock); 08400 AST_LIST_TRAVERSE(places[i], variables, entries) { 08401 if (!strcmp(name, ast_var_name(variables))) { 08402 ret = ast_var_value(variables); 08403 break; 08404 } 08405 } 08406 if (places[i] == &globals) 08407 ast_rwlock_unlock(&globalslock); 08408 if (ret) 08409 break; 08410 } 08411 08412 if (chan) 08413 ast_channel_unlock(chan); 08414 08415 return ret; 08416 }
void pbx_builtin_pushvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 8418 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_strdupa, ast_var_assign(), ast_verb, chan, globals, globalslock, and LOG_WARNING.
Referenced by acf_odbc_read(), acf_odbc_write(), and frame_set_var().
08419 { 08420 struct ast_var_t *newvariable; 08421 struct varshead *headp; 08422 08423 if (name[strlen(name)-1] == ')') { 08424 char *function = ast_strdupa(name); 08425 08426 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 08427 ast_func_write(chan, function, value); 08428 return; 08429 } 08430 08431 if (chan) { 08432 ast_channel_lock(chan); 08433 headp = &chan->varshead; 08434 } else { 08435 ast_rwlock_wrlock(&globalslock); 08436 headp = &globals; 08437 } 08438 08439 if (value) { 08440 if (headp == &globals) 08441 ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value); 08442 newvariable = ast_var_assign(name, value); 08443 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 08444 } 08445 08446 if (chan) 08447 ast_channel_unlock(chan); 08448 else 08449 ast_rwlock_unlock(&globalslock); 08450 }
int pbx_builtin_raise_exception | ( | struct ast_channel * | chan, | |
void * | data | |||
) |
Definition at line 2595 of file pbx.c.
References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc, ast_datastore_free(), ast_free, ast_string_field_init, ast_string_field_set, chan, ast_channel::context, ast_datastore::data, exception_store_info, ast_channel::exten, exten, ast_channel::priority, pbx_exception::priority, and set_ext_pri().
Referenced by __ast_pbx_run().
02596 { 02597 const char *reason = vreason; 02598 struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL); 02599 struct pbx_exception *exception = NULL; 02600 02601 if (!ds) { 02602 ds = ast_datastore_alloc(&exception_store_info, NULL); 02603 if (!ds) 02604 return -1; 02605 exception = ast_calloc(1, sizeof(struct pbx_exception)); 02606 if (!exception) { 02607 ast_datastore_free(ds); 02608 return -1; 02609 } 02610 if (ast_string_field_init(exception, 128)) { 02611 ast_free(exception); 02612 ast_datastore_free(ds); 02613 return -1; 02614 } 02615 ds->data = exception; 02616 ast_channel_datastore_add(chan, ds); 02617 } else 02618 exception = ds->data; 02619 02620 ast_string_field_set(exception, reason, reason); 02621 ast_string_field_set(exception, context, chan->context); 02622 ast_string_field_set(exception, exten, chan->exten); 02623 exception->priority = chan->priority; 02624 set_ext_pri(chan, "e", 0); 02625 return 0; 02626 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
struct ast_str ** | buf | |||
) |
Definition at line 8348 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_str_append(), ast_var_name(), ast_var_value(), buf, chan, ast_var_t::entries, LOG_ERROR, total, var, and ast_channel::varshead.
Referenced by dumpchan_exec(), handle_show_chanvar(), handle_showchan(), and vars2manager().
08349 { 08350 struct ast_var_t *variables; 08351 const char *var, *val; 08352 int total = 0; 08353 08354 if (!chan) 08355 return 0; 08356 08357 (*buf)->used = 0; 08358 (*buf)->str[0] = '\0'; 08359 08360 ast_channel_lock(chan); 08361 08362 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 08363 if ((var = ast_var_name(variables)) && (val = ast_var_value(variables)) 08364 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 08365 ) { 08366 if (ast_str_append(buf, 0, "%s=%s\n", var, val) < 0) { 08367 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 08368 break; 08369 } else 08370 total++; 08371 } else 08372 break; 08373 } 08374 08375 ast_channel_unlock(chan); 08376 08377 return total; 08378 }
int pbx_builtin_setvar | ( | struct ast_channel * | chan, | |
void * | data | |||
) |
void pbx_builtin_setvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 8452 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verb, chan, EVENT_FLAG_DIALPLAN, globals, globalslock, manager_event, ast_channel::name, and ast_channel::uniqueid.
Referenced by __oh323_new(), _macro_exec(), _while_exec(), acf_fetch(), acf_odbc_read(), acf_odbc_write(), action_atxfer(), action_setvar(), agi_exec_full(), aji_status_exec(), aqm_exec(), array(), ast_bridge_call(), ast_eivr_setvariable(), ast_feature_request_and_dial(), ast_iax2_new(), ast_monitor_start(), ast_monitor_stop(), ast_pbx_outgoing_exten(), ast_rtp_set_vars(), ast_set_variables(), asyncgoto_exec(), background_detect_exec(), bridge_exec(), bridge_play_sounds(), builtin_atxfer(), builtin_automixmonitor(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), channel_spy(), conf_run(), controlplayback_exec(), count_exec(), dahdi_handle_dtmfup(), dahdi_new(), dial_exec_full(), do_waiting(), end_bridge_callback(), export_aoc_vars(), export_ch(), frame_set_var(), function_db_delete(), function_db_exists(), function_db_read(), function_realtime_store(), get_rdnis(), get_refer_info(), global_write(), gosub_release_frame(), handle_request_bye(), handle_request_refer(), handle_set_chanvar(), handle_set_global(), handle_setvariable(), hash_read(), hash_write(), isAnsweringMachine(), leave_voicemail(), local_hangup(), lua_set_variable(), lua_set_variable_value(), macro_fixup(), manage_parkinglot(), minivm_accmess_exec(), minivm_delete_exec(), minivm_greet_exec(), minivm_notify_exec(), minivm_record_exec(), misdn_call(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_exec_full(), parse_moved_contact(), pbx_builtin_background(), pbx_builtin_importvar(), pbx_builtin_setvar(), pbx_builtin_setvar_multiple(), pbx_load_config(), phase_e_handler(), play_message_datetime(), playback_exec(), pqm_exec(), prep_email_sub_vars(), process_ast_dsp(), read_exec(), readexten_exec(), readfile_exec(), record_exec(), return_exec(), rotate_file(), rpt_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_hangup(), sip_new(), sip_read(), skinny_new(), sla_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), ss_thread(), start_monitor_exec(), system_exec_helper(), transfer_exec(), transmit(), tryexec_exec(), update_bridge_vars(), update_qe_rule(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), waituntil_exec(), and zapateller_exec().
08453 { 08454 struct ast_var_t *newvariable; 08455 struct varshead *headp; 08456 const char *nametail = name; 08457 08458 if (name[strlen(name) - 1] == ')') { 08459 char *function = ast_strdupa(name); 08460 08461 ast_func_write(chan, function, value); 08462 return; 08463 } 08464 08465 if (chan) { 08466 ast_channel_lock(chan); 08467 headp = &chan->varshead; 08468 } else { 08469 ast_rwlock_wrlock(&globalslock); 08470 headp = &globals; 08471 } 08472 08473 /* For comparison purposes, we have to strip leading underscores */ 08474 if (*nametail == '_') { 08475 nametail++; 08476 if (*nametail == '_') 08477 nametail++; 08478 } 08479 08480 AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) { 08481 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 08482 /* there is already such a variable, delete it */ 08483 AST_LIST_REMOVE_CURRENT(entries); 08484 ast_var_delete(newvariable); 08485 break; 08486 } 08487 } 08488 AST_LIST_TRAVERSE_SAFE_END; 08489 08490 if (value) { 08491 if (headp == &globals) 08492 ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value); 08493 newvariable = ast_var_assign(name, value); 08494 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 08495 manager_event(EVENT_FLAG_DIALPLAN, "VarSet", 08496 "Channel: %s\r\n" 08497 "Variable: %s\r\n" 08498 "Value: %s\r\n" 08499 "Uniqueid: %s\r\n", 08500 chan ? chan->name : "none", name, value, 08501 chan ? chan->uniqueid : "none"); 08502 } 08503 08504 if (chan) 08505 ast_channel_unlock(chan); 08506 else 08507 ast_rwlock_unlock(&globalslock); 08508 }
int pbx_builtin_setvar_multiple | ( | struct ast_channel * | chan, | |
void * | data | |||
) |
int pbx_checkcondition | ( | const char * | condition | ) |
Evaluate a condition.
0 | if the condition is NULL or of zero length | |
int | If the string is an integer, the integer representation of the integer is returned | |
1 | Any other non-empty string |
Definition at line 8621 of file pbx.c.
References ast_strlen_zero().
Referenced by _macro_exec(), _while_exec(), acf_if(), execif_exec(), gosubif_exec(), macroif_exec(), and pbx_builtin_gotoif().
08622 { 08623 int res; 08624 if (ast_strlen_zero(condition)) { /* NULL or empty strings are false */ 08625 return 0; 08626 } else if (sscanf(condition, "%30d", &res) == 1) { /* Numbers are evaluated for truth */ 08627 return res; 08628 } else { /* Strings are true */ 08629 return 1; 08630 } 08631 }
int pbx_exec | ( | struct ast_channel * | c, | |
struct ast_app * | app, | |||
void * | data | |||
) |
Execute an application.
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 934 of file pbx.c.
References __ast_module_user_add(), __ast_module_user_remove(), app, ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_log(), ast_opt_dont_warn, ast_strlen_zero(), ast_channel::cdr, ast_channel::data, LOG_WARNING, ast_channel::name, and S_OR.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automixmonitor(), builtin_automonitor(), conf_run(), dial_exec_full(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), handle_gosub(), iax2_exec(), lua_pbx_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), and tryexec_exec().
00937 { 00938 int res; 00939 struct ast_module_user *u = NULL; 00940 const char *saved_c_appl; 00941 const char *saved_c_data; 00942 00943 if (c->cdr && !ast_check_hangup(c)) 00944 ast_cdr_setapp(c->cdr, app->name, data); 00945 00946 /* save channel values */ 00947 saved_c_appl= c->appl; 00948 saved_c_data= c->data; 00949 00950 c->appl = app->name; 00951 c->data = data; 00952 if (app->module) 00953 u = __ast_module_user_add(app->module, c); 00954 if (strcasecmp(app->name, "system") && !ast_strlen_zero(data) && 00955 strchr(data, '|') && !strchr(data, ',') && !ast_opt_dont_warn) { 00956 ast_log(LOG_WARNING, "The application delimiter is now the comma, not " 00957 "the pipe. Did you forget to convert your dialplan? (%s(%s))\n", 00958 app->name, (char *) data); 00959 } 00960 res = app->execute(c, S_OR(data, "")); 00961 if (app->module && u) 00962 __ast_module_user_remove(app->module, u); 00963 /* restore channel values */ 00964 c->appl = saved_c_appl; 00965 c->data = saved_c_data; 00966 return res; 00967 }
struct ast_exten* pbx_find_extension | ( | struct ast_channel * | chan, | |
struct ast_context * | bypass, | |||
struct pbx_find_info * | q, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | label, | |||
const char * | callerid, | |||
enum ext_match_t | action | |||
) |
Definition at line 2068 of file pbx.c.
References ast_context::alts, ast_autoservice_start(), ast_autoservice_stop(), ast_copy_string(), ast_hashtab_lookup(), AST_LIST_TRAVERSE, ast_log(), AST_PBX_MAX_STACK, ast_str_thread_get(), ast_strdupa, ast_strlen_zero(), ast_walk_context_extensions(), ast_walk_contexts(), ast_walk_extension_priorities(), ast_switch::canmatch, scoreboard::canmatch_exten, chan, contexts_table, create_match_char_tree(), ast_sw::data, pbx_find_info::data, E_CANMATCH, E_FINDLABEL, E_MATCHMORE, ast_sw::eval, ast_switch::exists, ast_exten::exten, scoreboard::exten, extenpatternmatchnew, extension_match_core(), pbx_find_info::foundcontext, include_valid(), ast_context::includes, pbx_find_info::incstack, ast_exten::label, scoreboard::last_char, ast_str::len, LOG_DEBUG, log_match_char_tree(), LOG_NOTICE, LOG_WARNING, match(), matchcid(), ast_switch::matchmore, ast_sw::name, ast_context::name, fake_context::name, new_find_extension(), ast_include::next, scoreboard::node, overrideswitch, ast_context::pattern_tree, pbx_find_extension(), pbx_findswitch(), pbx_substitute_variables_helper(), ast_exten::priority, ast_include::rname, ast_context::root_table, pbx_find_info::stacklen, pbx_find_info::status, STATUS_NO_CONTEXT, STATUS_NO_EXTENSION, STATUS_NO_LABEL, STATUS_NO_PRIORITY, STATUS_SUCCESS, ast_str::str, strsep(), switch_data, pbx_find_info::swo, scoreboard::total_length, scoreboard::total_specificity, and trie_find_next_match().
Referenced by ast_hint_extension_nolock(), ast_merge_contexts_and_delete(), pbx_extension_helper(), pbx_find_extension(), and register_peer_exten().
02072 { 02073 int x, res; 02074 struct ast_context *tmp = NULL; 02075 struct ast_exten *e = NULL, *eroot = NULL; 02076 struct ast_include *i = NULL; 02077 struct ast_sw *sw = NULL; 02078 struct ast_exten pattern = {NULL, }; 02079 struct scoreboard score = {0, }; 02080 struct ast_str *tmpdata = NULL; 02081 02082 pattern.label = label; 02083 pattern.priority = priority; 02084 #ifdef NEED_DEBUG_HERE 02085 ast_log(LOG_NOTICE,"Looking for cont/ext/prio/label/action = %s/%s/%d/%s/%d\n", context, exten, priority, label, (int)action); 02086 #endif 02087 02088 /* Initialize status if appropriate */ 02089 if (q->stacklen == 0) { 02090 q->status = STATUS_NO_CONTEXT; 02091 q->swo = NULL; 02092 q->data = NULL; 02093 q->foundcontext = NULL; 02094 } else if (q->stacklen >= AST_PBX_MAX_STACK) { 02095 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n"); 02096 return NULL; 02097 } 02098 02099 /* Check first to see if we've already been checked */ 02100 for (x = 0; x < q->stacklen; x++) { 02101 if (!strcasecmp(q->incstack[x], context)) 02102 return NULL; 02103 } 02104 02105 if (bypass) /* bypass means we only look there */ 02106 tmp = bypass; 02107 else { /* look in contexts */ 02108 struct fake_context item; 02109 02110 ast_copy_string(item.name, context, sizeof(item.name)); 02111 02112 tmp = ast_hashtab_lookup(contexts_table, &item); 02113 #ifdef NOTNOW 02114 tmp = NULL; 02115 while ((tmp = ast_walk_contexts(tmp)) ) { 02116 if (!strcmp(tmp->name, context)) 02117 break; 02118 } 02119 #endif 02120 if (!tmp) 02121 return NULL; 02122 02123 } 02124 02125 if (q->status < STATUS_NO_EXTENSION) 02126 q->status = STATUS_NO_EXTENSION; 02127 02128 /* Do a search for matching extension */ 02129 02130 eroot = NULL; 02131 score.total_specificity = 0; 02132 score.exten = 0; 02133 score.total_length = 0; 02134 if (!tmp->pattern_tree && tmp->root_table) 02135 { 02136 create_match_char_tree(tmp); 02137 #ifdef NEED_DEBUG 02138 ast_log(LOG_DEBUG,"Tree Created in context %s:\n", context); 02139 log_match_char_tree(tmp->pattern_tree," "); 02140 #endif 02141 } 02142 #ifdef NEED_DEBUG 02143 ast_log(LOG_NOTICE,"The Trie we are searching in:\n"); 02144 log_match_char_tree(tmp->pattern_tree, ":: "); 02145 #endif 02146 02147 do { 02148 if (!ast_strlen_zero(overrideswitch)) { 02149 char *osw = ast_strdupa(overrideswitch), *name; 02150 struct ast_switch *asw; 02151 ast_switch_f *aswf = NULL; 02152 char *datap; 02153 int eval = 0; 02154 02155 name = strsep(&osw, "/"); 02156 asw = pbx_findswitch(name); 02157 02158 if (!asw) { 02159 ast_log(LOG_WARNING, "No such switch '%s'\n", name); 02160 break; 02161 } 02162 02163 if (osw && strchr(osw, '$')) { 02164 eval = 1; 02165 } 02166 02167 if (eval && !(tmpdata = ast_str_thread_get(&switch_data, 512))) { 02168 ast_log(LOG_WARNING, "Can't evaluate overrideswitch?!"); 02169 break; 02170 } else if (eval) { 02171 /* Substitute variables now */ 02172 pbx_substitute_variables_helper(chan, osw, tmpdata->str, tmpdata->len); 02173 datap = tmpdata->str; 02174 } else { 02175 datap = osw; 02176 } 02177 02178 /* equivalent of extension_match_core() at the switch level */ 02179 if (action == E_CANMATCH) 02180 aswf = asw->canmatch; 02181 else if (action == E_MATCHMORE) 02182 aswf = asw->matchmore; 02183 else /* action == E_MATCH */ 02184 aswf = asw->exists; 02185 if (!aswf) { 02186 res = 0; 02187 } else { 02188 if (chan) { 02189 ast_autoservice_start(chan); 02190 } 02191 res = aswf(chan, context, exten, priority, callerid, datap); 02192 if (chan) { 02193 ast_autoservice_stop(chan); 02194 } 02195 } 02196 if (res) { /* Got a match */ 02197 q->swo = asw; 02198 q->data = datap; 02199 q->foundcontext = context; 02200 /* XXX keep status = STATUS_NO_CONTEXT ? */ 02201 return NULL; 02202 } 02203 } 02204 } while (0); 02205 02206 if (extenpatternmatchnew) { 02207 new_find_extension(exten, &score, tmp->pattern_tree, 0, 0, callerid, label, action); 02208 eroot = score.exten; 02209 02210 if (score.last_char == '!' && action == E_MATCHMORE) { 02211 /* We match an extension ending in '!'. 02212 * The decision in this case is final and is NULL (no match). 02213 */ 02214 #ifdef NEED_DEBUG_HERE 02215 ast_log(LOG_NOTICE,"Returning MATCHMORE NULL with exclamation point.\n"); 02216 #endif 02217 return NULL; 02218 } 02219 02220 if (!eroot && (action == E_CANMATCH || action == E_MATCHMORE) && score.canmatch_exten) { 02221 q->status = STATUS_SUCCESS; 02222 #ifdef NEED_DEBUG_HERE 02223 ast_log(LOG_NOTICE,"Returning CANMATCH exten %s\n", score.canmatch_exten->exten); 02224 #endif 02225 return score.canmatch_exten; 02226 } 02227 02228 if ((action == E_MATCHMORE || action == E_CANMATCH) && eroot) { 02229 if (score.node) { 02230 struct ast_exten *z = trie_find_next_match(score.node); 02231 if (z) { 02232 #ifdef NEED_DEBUG_HERE 02233 ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten %s\n", z->exten); 02234 #endif 02235 } else { 02236 if (score.canmatch_exten) { 02237 #ifdef NEED_DEBUG_HERE 02238 ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE canmatchmatch exten %s(%p)\n", score.canmatch_exten->exten, score.canmatch_exten); 02239 #endif 02240 return score.canmatch_exten; 02241 } else { 02242 #ifdef NEED_DEBUG_HERE 02243 ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten NULL\n"); 02244 #endif 02245 } 02246 } 02247 return z; 02248 } 02249 #ifdef NEED_DEBUG_HERE 02250 ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE NULL (no next_match)\n"); 02251 #endif 02252 return NULL; /* according to the code, complete matches are null matches in MATCHMORE mode */ 02253 } 02254 02255 if (eroot) { 02256 /* found entry, now look for the right priority */ 02257 if (q->status < STATUS_NO_PRIORITY) 02258 q->status = STATUS_NO_PRIORITY; 02259 e = NULL; 02260 if (action == E_FINDLABEL && label ) { 02261 if (q->status < STATUS_NO_LABEL) 02262 q->status = STATUS_NO_LABEL; 02263 e = ast_hashtab_lookup(eroot->peer_label_table, &pattern); 02264 } else { 02265 e = ast_hashtab_lookup(eroot->peer_table, &pattern); 02266 } 02267 if (e) { /* found a valid match */ 02268 q->status = STATUS_SUCCESS; 02269 q->foundcontext = context; 02270 #ifdef NEED_DEBUG_HERE 02271 ast_log(LOG_NOTICE,"Returning complete match of exten %s\n", e->exten); 02272 #endif 02273 return e; 02274 } 02275 } 02276 } else { /* the old/current default exten pattern match algorithm */ 02277 02278 /* scan the list trying to match extension and CID */ 02279 eroot = NULL; 02280 while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) { 02281 int match = extension_match_core(eroot->exten, exten, action); 02282 /* 0 on fail, 1 on match, 2 on earlymatch */ 02283 02284 if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid))) 02285 continue; /* keep trying */ 02286 if (match == 2 && action == E_MATCHMORE) { 02287 /* We match an extension ending in '!'. 02288 * The decision in this case is final and is NULL (no match). 02289 */ 02290 return NULL; 02291 } 02292 /* found entry, now look for the right priority */ 02293 if (q->status < STATUS_NO_PRIORITY) 02294 q->status = STATUS_NO_PRIORITY; 02295 e = NULL; 02296 if (action == E_FINDLABEL && label ) { 02297 if (q->status < STATUS_NO_LABEL) 02298 q->status = STATUS_NO_LABEL; 02299 e = ast_hashtab_lookup(eroot->peer_label_table, &pattern); 02300 } else { 02301 e = ast_hashtab_lookup(eroot->peer_table, &pattern); 02302 } 02303 #ifdef NOTNOW 02304 while ( (e = ast_walk_extension_priorities(eroot, e)) ) { 02305 /* Match label or priority */ 02306 if (action == E_FINDLABEL) { 02307 if (q->status < STATUS_NO_LABEL) 02308 q->status = STATUS_NO_LABEL; 02309 if (label && e->label && !strcmp(label, e->label)) 02310 break; /* found it */ 02311 } else if (e->priority == priority) { 02312 break; /* found it */ 02313 } /* else keep searching */ 02314 } 02315 #endif 02316 if (e) { /* found a valid match */ 02317 q->status = STATUS_SUCCESS; 02318 q->foundcontext = context; 02319 return e; 02320 } 02321 } 02322 } 02323 02324 02325 /* Check alternative switches */ 02326 AST_LIST_TRAVERSE(&tmp->alts, sw, list) { 02327 struct ast_switch *asw = pbx_findswitch(sw->name); 02328 ast_switch_f *aswf = NULL; 02329 char *datap; 02330 02331 if (!asw) { 02332 ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name); 02333 continue; 02334 } 02335 /* Substitute variables now */ 02336 02337 if (sw->eval) { 02338 if (!(tmpdata = ast_str_thread_get(&switch_data, 512))) { 02339 ast_log(LOG_WARNING, "Can't evaluate switch?!"); 02340 continue; 02341 } 02342 pbx_substitute_variables_helper(chan, sw->data, tmpdata->str, tmpdata->len); 02343 } 02344 02345 /* equivalent of extension_match_core() at the switch level */ 02346 if (action == E_CANMATCH) 02347 aswf = asw->canmatch; 02348 else if (action == E_MATCHMORE) 02349 aswf = asw->matchmore; 02350 else /* action == E_MATCH */ 02351 aswf = asw->exists; 02352 datap = sw->eval ? tmpdata->str : sw->data; 02353 if (!aswf) 02354 res = 0; 02355 else { 02356 if (chan) 02357 ast_autoservice_start(chan); 02358 res = aswf(chan, context, exten, priority, callerid, datap); 02359 if (chan) 02360 ast_autoservice_stop(chan); 02361 } 02362 if (res) { /* Got a match */ 02363 q->swo = asw; 02364 q->data = datap; 02365 q->foundcontext = context; 02366 /* XXX keep status = STATUS_NO_CONTEXT ? */ 02367 return NULL; 02368 } 02369 } 02370 q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */ 02371 /* Now try any includes we have in this context */ 02372 for (i = tmp->includes; i; i = i->next) { 02373 if (include_valid(i)) { 02374 if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action))) { 02375 #ifdef NEED_DEBUG_HERE 02376 ast_log(LOG_NOTICE,"Returning recursive match of %s\n", e->exten); 02377 #endif 02378 return e; 02379 } 02380 if (q->swo) 02381 return NULL; 02382 } 02383 } 02384 return NULL; 02385 }
struct ast_app* pbx_findapp | ( | const char * | app | ) |
Look up an application.
app | name of the app |
Definition at line 975 of file pbx.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_app::list, and ast_app::name.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automixmonitor(), builtin_automonitor(), conf_run(), dial_exec_full(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), handle_gosub(), iax2_exec(), lua_pbx_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), and tryexec_exec().
00976 { 00977 struct ast_app *tmp; 00978 00979 AST_RWLIST_RDLOCK(&apps); 00980 AST_RWLIST_TRAVERSE(&apps, tmp, list) { 00981 if (!strcasecmp(tmp->name, app)) 00982 break; 00983 } 00984 AST_RWLIST_UNLOCK(&apps); 00985 00986 return tmp; 00987 }
void pbx_retrieve_variable | ( | struct ast_channel * | c, | |
const char * | var, | |||
char ** | ret, | |||
char * | workspace, | |||
int | workspacelen, | |||
struct varshead * | headp | |||
) |
Support for Asterisk built-in variables in the dialplan.
Definition at line 2467 of file pbx.c.
References ARRAY_LEN, ast_channel_lock, ast_channel_unlock, ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_eid_default, ast_eid_to_str(), ast_get_hint(), AST_LIST_TRAVERSE, ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_strdupa, ast_var_name(), ast_var_value(), ast_channel::cid, ast_callerid::cid_ani2, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, globals, globalslock, ast_channel::hangupcause, ast_channel::name, parse_variable_name(), ast_channel::priority, s, substring(), and ast_channel::uniqueid.
Referenced by action_getvar(), action_status(), handle_getvariable(), lua_get_variable(), lua_get_variable_value(), and pbx_substitute_variables_helper_full().
02468 { 02469 const char not_found = '\0'; 02470 char *tmpvar; 02471 const char *s; /* the result */ 02472 int offset, length; 02473 int i, need_substring; 02474 struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */ 02475 02476 if (c) { 02477 ast_channel_lock(c); 02478 places[0] = &c->varshead; 02479 } 02480 /* 02481 * Make a copy of var because parse_variable_name() modifies the string. 02482 * Then if called directly, we might need to run substring() on the result; 02483 * remember this for later in 'need_substring', 'offset' and 'length' 02484 */ 02485 tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */ 02486 need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */); 02487 02488 /* 02489 * Look first into predefined variables, then into variable lists. 02490 * Variable 's' points to the result, according to the following rules: 02491 * s == ¬_found (set at the beginning) means that we did not find a 02492 * matching variable and need to look into more places. 02493 * If s != ¬_found, s is a valid result string as follows: 02494 * s = NULL if the variable does not have a value; 02495 * you typically do this when looking for an unset predefined variable. 02496 * s = workspace if the result has been assembled there; 02497 * typically done when the result is built e.g. with an snprintf(), 02498 * so we don't need to do an additional copy. 02499 * s != workspace in case we have a string, that needs to be copied 02500 * (the ast_copy_string is done once for all at the end). 02501 * Typically done when the result is already available in some string. 02502 */ 02503 s = ¬_found; /* default value */ 02504 if (c) { /* This group requires a valid channel */ 02505 /* Names with common parts are looked up a piece at a time using strncmp. */ 02506 if (!strncmp(var, "CALL", 4)) { 02507 if (!strncmp(var + 4, "ING", 3)) { 02508 if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */ 02509 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 02510 s = workspace; 02511 } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */ 02512 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 02513 s = workspace; 02514 } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */ 02515 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 02516 s = workspace; 02517 } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */ 02518 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 02519 s = workspace; 02520 } 02521 } 02522 } else if (!strcmp(var, "HINT")) { 02523 s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL; 02524 } else if (!strcmp(var, "HINTNAME")) { 02525 s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL; 02526 } else if (!strcmp(var, "EXTEN")) { 02527 s = c->exten; 02528 } else if (!strcmp(var, "CONTEXT")) { 02529 s = c->context; 02530 } else if (!strcmp(var, "PRIORITY")) { 02531 snprintf(workspace, workspacelen, "%d", c->priority); 02532 s = workspace; 02533 } else if (!strcmp(var, "CHANNEL")) { 02534 s = c->name; 02535 } else if (!strcmp(var, "UNIQUEID")) { 02536 s = c->uniqueid; 02537 } else if (!strcmp(var, "HANGUPCAUSE")) { 02538 snprintf(workspace, workspacelen, "%d", c->hangupcause); 02539 s = workspace; 02540 } 02541 } 02542 if (s == ¬_found) { /* look for more */ 02543 if (!strcmp(var, "EPOCH")) { 02544 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 02545 s = workspace; 02546 } else if (!strcmp(var, "SYSTEMNAME")) { 02547 s = ast_config_AST_SYSTEM_NAME; 02548 } else if (!strcmp(var, "ENTITYID")) { 02549 ast_eid_to_str(workspace, workspacelen, &ast_eid_default); 02550 s = workspace; 02551 } 02552 } 02553 /* if not found, look into chanvars or global vars */ 02554 for (i = 0; s == ¬_found && i < ARRAY_LEN(places); i++) { 02555 struct ast_var_t *variables; 02556 if (!places[i]) 02557 continue; 02558 if (places[i] == &globals) 02559 ast_rwlock_rdlock(&globalslock); 02560 AST_LIST_TRAVERSE(places[i], variables, entries) { 02561 if (!strcasecmp(ast_var_name(variables), var)) { 02562 s = ast_var_value(variables); 02563 break; 02564 } 02565 } 02566 if (places[i] == &globals) 02567 ast_rwlock_unlock(&globalslock); 02568 } 02569 if (s == ¬_found || s == NULL) 02570 *ret = NULL; 02571 else { 02572 if (s != workspace) 02573 ast_copy_string(workspace, s, workspacelen); 02574 *ret = workspace; 02575 if (need_substring) 02576 *ret = substring(*ret, offset, length, workspace, workspacelen); 02577 } 02578 02579 if (c) 02580 ast_channel_unlock(c); 02581 }
int pbx_set_autofallthrough | ( | int | newval | ) |
Set "autofallthrough" flag, if newval is <0, does not acutally set. If set to 1, sets to auto fall through. If newval set to 0, sets to no auto fall through (reads extension instead). Returns previous value.
Definition at line 4118 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
04119 { 04120 int oldval = autofallthrough; 04121 autofallthrough = newval; 04122 return oldval; 04123 }
int pbx_set_extenpatternmatchnew | ( | int | newval | ) |
Set "extenpatternmatchnew" flag, if newval is <0, does not acutally set. If set to 1, sets to use the new Trie-based pattern matcher. If newval set to 0, sets to use the old linear-search algorithm. Returns previous value.
Definition at line 4125 of file pbx.c.
References extenpatternmatchnew.
Referenced by handle_set_extenpatternmatchnew(), handle_unset_extenpatternmatchnew(), and pbx_load_module().
04126 { 04127 int oldval = extenpatternmatchnew; 04128 extenpatternmatchnew = newval; 04129 return oldval; 04130 }
void pbx_set_overrideswitch | ( | const char * | newval | ) |
Set "overrideswitch" field. If set and of nonzero length, all contexts will be tried directly through the named switch prior to any other matching within that context.
Definition at line 4132 of file pbx.c.
References ast_free, ast_strdup, ast_strlen_zero(), and overrideswitch.
Referenced by pbx_load_module().
04133 { 04134 if (overrideswitch) { 04135 ast_free(overrideswitch); 04136 } 04137 if (!ast_strlen_zero(newval)) { 04138 overrideswitch = ast_strdup(newval); 04139 } else { 04140 overrideswitch = NULL; 04141 } 04142 }
void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 3111 of file pbx.c.
References pbx_substitute_variables_helper_full(), and ast_channel::varshead.
Referenced by _macro_exec(), acf_import(), acf_odbc_read(), acf_odbc_write(), ast_add_extension2_lockopt(), config_curl(), custom_log(), cut_internal(), destroy_curl(), exec_exec(), function_eval(), function_fieldqty(), get_mapping_weight(), handle_getvariablefull(), launch_monitor_thread(), make_email_file(), manager_log(), pbx_builtin_importvar(), pbx_find_extension(), pbx_load_config(), pbx_substitute_variables(), realtime_curl(), realtime_multi_curl(), require_curl(), rotate_file(), rpt_do_lstats(), rpt_exec(), sendmail(), sendpage(), store_curl(), substituted(), tryexec_exec(), update_curl(), and write_cdr().
03112 { 03113 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 03114 }
void pbx_substitute_variables_varshead | ( | struct varshead * | headp, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 3116 of file pbx.c.
References pbx_substitute_variables_helper_full().
Referenced by add_user_extension(), build_user_routes(), dundi_lookup_local(), loopback_subst(), phoneprov_callback(), pp_each_extension_exec(), and pp_each_user_exec().
03117 { 03118 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 03119 }