Core PBX routines and definitions. More...
#include "asterisk/sched.h"#include "asterisk/devicestate.h"#include "asterisk/chanvars.h"#include "asterisk/hashtab.h"
Go to the source code of this file.
Data Structures | |
| struct | ast_custom_function |
| Data structure associated with a custom dialplan function. More... | |
| struct | ast_pbx |
| struct | ast_pbx_args |
| Options for ast_pbx_run(). More... | |
| struct | ast_switch |
| struct | ast_timing |
| struct | pbx_find_info |
Defines | |
| #define | ast_custom_function_register(acf) __ast_custom_function_register(acf, ast_module_info->self) |
| Register a custom function. | |
| #define | AST_MAX_APP 32 |
| #define | AST_PBX_ERROR 1 |
| #define | AST_PBX_HANGUP -1 |
| Special return values from applications to the PBX {. | |
| #define | AST_PBX_INCOMPLETE 12 |
| #define | AST_PBX_KEEP 0 |
| #define | AST_PBX_MAX_STACK 128 |
| #define | AST_PBX_OK 0 |
| #define | AST_PBX_REPLACE 1 |
| #define | PRIORITY_HINT -1 |
| #define | STATUS_NO_CONTEXT 1 |
| #define | STATUS_NO_EXTENSION 2 |
| #define | STATUS_NO_LABEL 4 |
| #define | STATUS_NO_PRIORITY 3 |
| #define | STATUS_SUCCESS 5 |
Typedefs | |
| typedef int(* | ast_state_cb_type )(char *context, char *id, enum ast_extension_states state, void *data) |
| Typedef for devicestate and hint callbacks. | |
| typedef int( | ast_switch_f )(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| All switch functions have the same interface, so define a type for them. | |
Enumerations | |
| enum | ast_extension_states { AST_EXTENSION_REMOVED = -2, AST_EXTENSION_DEACTIVATED = -1, AST_EXTENSION_NOT_INUSE = 0, AST_EXTENSION_INUSE = 1 << 0, AST_EXTENSION_BUSY = 1 << 1, AST_EXTENSION_UNAVAILABLE = 1 << 2, AST_EXTENSION_RINGING = 1 << 3, AST_EXTENSION_ONHOLD = 1 << 4 } |
Extension states. More... | |
| enum | ast_pbx_result { AST_PBX_SUCCESS = 0, AST_PBX_FAILED = -1, AST_PBX_CALL_LIMIT = -2 } |
The result codes when starting the PBX on a channelwith. More... | |
| enum | ext_match_t { E_MATCHMORE = 0x00, E_CANMATCH = 0x01, E_MATCH = 0x02, E_MATCH_MASK = 0x03, E_SPAWN = 0x12, E_FINDLABEL = 0x22, E_MATCHMORE = 0x00, E_CANMATCH = 0x01, E_MATCH = 0x02, E_MATCH_MASK = 0x03, E_SPAWN = 0x12, E_FINDLABEL = 0x22 } |
Functions | |
| int | __ast_custom_function_register (struct ast_custom_function *acf, struct ast_module *mod) |
| Register a custom function. | |
| int | ast_active_calls (void) |
| Retrieve the number of active calls. | |
| int | ast_add_extension (const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar) |
| Add and extension to an extension context. | |
| int | ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar) |
| Add an extension to an extension context, this time with an ast_context *. | |
| int | ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority) |
| int | ast_async_goto_by_name (const char *chan, const char *context, const char *exten, int priority) |
| int | ast_async_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
| int | ast_async_parseable_goto (struct ast_channel *chan, const char *goto_string) |
| int | ast_build_timing (struct ast_timing *i, const char *info) |
| int | ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| Looks for a valid matching extension. | |
| int | ast_check_timing (const struct ast_timing *i) |
| int | ast_context_add_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
| Add an ignorepat. | |
| int | ast_context_add_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar) |
| int | ast_context_add_include (const char *context, const char *include, const char *registrar) |
| Add a context include. | |
| int | ast_context_add_include2 (struct ast_context *con, const char *include, const char *registrar) |
| Add a context include. | |
| int | ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar) |
| Add a switch. | |
| int | ast_context_add_switch2 (struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar) |
| Adds a switch (first param is a ast_context). | |
| void | ast_context_destroy (struct ast_context *con, const char *registrar) |
| Destroy a context (matches the specified context (or ANY context if NULL). | |
| struct ast_context * | ast_context_find (const char *name) |
| Find a context. | |
| 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. | |
| int | ast_context_lockmacro (const char *macrocontext) |
| locks the macrolock in the given given context | |
| int | ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar) |
| Simply remove extension from context. | |
| int | ast_context_remove_extension2 (struct ast_context *con, const char *extension, int priority, const char *registrar, int already_locked) |
| This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return. | |
| int | ast_context_remove_extension_callerid (const char *context, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar) |
| int | ast_context_remove_extension_callerid2 (struct ast_context *con, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar, int already_locked) |
| int | ast_context_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
| int | ast_context_remove_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar) |
| int | ast_context_remove_include (const char *context, const char *include, const char *registrar) |
| Remove a context include. | |
| int | ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar) |
| Removes an include by an ast_context structure. | |
| int | ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar) |
| Remove a switch. | |
| int | ast_context_remove_switch2 (struct ast_context *con, const char *sw, const char *data, const char *registrar) |
| This function locks given context, removes switch, unlock context and return. | |
| int | ast_context_unlockmacro (const char *macrocontext) |
| Unlocks the macrolock in the given context. | |
| int | ast_context_verify_includes (struct ast_context *con) |
| Verifies includes in an ast_contect structure. | |
| struct ast_custom_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. | |
| struct ast_exten * | ast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority) |
| struct ast_ignorepat * | ast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip) |
| struct ast_include * | ast_walk_context_includes (struct ast_context *con, struct ast_include *inc) |
| struct ast_sw * | ast_walk_context_switches (struct ast_context *con, struct ast_sw *sw) |
| struct ast_context * | ast_walk_contexts (struct ast_context *con) |
| struct 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. | |
| 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) |
| struct 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) |
| const char * | ast_get_context_name (struct ast_context *con) |
| struct 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) |
Core PBX routines and definitions.
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(), handle_show_function(), and sla_build_station().
| #define AST_PBX_ERROR 1 |
| #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 __ast_pbx_run(), 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 add_pri_lockopt(), 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(), print_ext(), and sla_build_station().
| 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.
| AST_EXTENSION_REMOVED |
Extension removed |
| AST_EXTENSION_DEACTIVATED |
Extension hint removed |
| AST_EXTENSION_NOT_INUSE |
No device INUSE or BUSY |
| AST_EXTENSION_INUSE |
One or more devices INUSE |
| AST_EXTENSION_BUSY |
All devices BUSY |
| AST_EXTENSION_UNAVAILABLE |
All devices UNAVAILABLE/UNREGISTERED |
| AST_EXTENSION_RINGING |
All devices RINGING |
| AST_EXTENSION_ONHOLD |
All devices ONHOLD |
Definition at line 53 of file pbx.h.
00053 { 00054 AST_EXTENSION_REMOVED = -2, /*!< Extension removed */ 00055 AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */ 00056 AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */ 00057 AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */ 00058 AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */ 00059 AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */ 00060 AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */ 00061 AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */ 00062 };
| enum ast_pbx_result |
The result codes when starting the PBX on a channelwith.
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.
| E_MATCHMORE | |
| E_CANMATCH | |
| E_MATCH | |
| E_MATCH_MASK | |
| E_SPAWN | |
| E_FINDLABEL | |
| E_MATCHMORE | |
| E_CANMATCH | |
| E_MATCH | |
| E_MATCH_MASK | |
| E_SPAWN | |
| E_FINDLABEL |
Definition at line 1028 of file pbx.h.
01028 { 01029 E_MATCHMORE = 0x00, /* extension can match but only with more 'digits' */ 01030 E_CANMATCH = 0x01, /* extension can match with or without more 'digits' */ 01031 E_MATCH = 0x02, /* extension is an exact match */ 01032 E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */ 01033 E_SPAWN = 0x12, /* want to spawn an extension. Requires exact match */ 01034 E_FINDLABEL = 0x22 /* returns the priority for a given label. Requires exact match */ 01035 };
| int __ast_custom_function_register | ( | struct ast_custom_function * | acf, | |
| struct ast_module * | mod | |||
| ) |
Register a custom function.
Definition at line 2811 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().
02812 { 02813 struct ast_custom_function *cur; 02814 char tmps[80]; 02815 02816 if (!acf) 02817 return -1; 02818 02819 acf->mod = mod; 02820 02821 AST_RWLIST_WRLOCK(&acf_root); 02822 02823 AST_RWLIST_TRAVERSE(&acf_root, cur, acflist) { 02824 if (!strcmp(acf->name, cur->name)) { 02825 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 02826 AST_RWLIST_UNLOCK(&acf_root); 02827 return -1; 02828 } 02829 } 02830 02831 /* Store in alphabetical order */ 02832 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 02833 if (strcasecmp(acf->name, cur->name) < 0) { 02834 AST_RWLIST_INSERT_BEFORE_CURRENT(acf, acflist); 02835 break; 02836 } 02837 } 02838 AST_RWLIST_TRAVERSE_SAFE_END; 02839 if (!cur) 02840 AST_RWLIST_INSERT_TAIL(&acf_root, acf, acflist); 02841 02842 AST_RWLIST_UNLOCK(&acf_root); 02843 02844 ast_verb(2, "Registered custom function '%s'\n", term_color(tmps, acf->name, COLOR_BRCYAN, 0, sizeof(tmps))); 02845 02846 return 0; 02847 }
| int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 4099 of file pbx.c.
Referenced by handle_chanlist(), handle_showcalls(), and sysinfo_helper().
04100 { 04101 return countcalls; 04102 }
| 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 6750 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().
06753 { 06754 int ret = -1; 06755 struct ast_context *c = find_context_locked(context); 06756 06757 if (c) { 06758 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 06759 application, data, datad, registrar); 06760 ast_unlock_contexts(); 06761 } 06762 06763 return ret; 06764 }
| 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 *.
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 7068 of file pbx.c.
References ast_add_extension2_lockopt().
Referenced by ast_add_extension(), ast_park_call_full(), build_parkinglot(), context_merge(), load_config(), load_module(), manage_parkinglot(), pbx_load_config(), pbx_load_users(), sla_build_station(), and sla_build_trunk().
07072 { 07073 return ast_add_extension2_lockopt(con, replace, extension, priority, label, callerid, application, data, datad, registrar, 1, 1); 07074 }
| int ast_async_goto | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 6789 of file pbx.c.
References ast_channel::_state, ast_channel::amaflags, ast_cdr_discard(), ast_cdr_dup(), ast_channel_alloc, ast_channel_lock, ast_channel_masquerade(), ast_channel_unlock, ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_pbx_start(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_channel::cdr, ast_channel::context, ast_channel::exten, LOG_WARNING, ast_channel::pbx, ast_channel::readformat, S_OR, and ast_channel::writeformat.
Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), dahdi_handle_dtmfup(), handle_request_bye(), handle_request_refer(), pbx_parseable_goto(), process_ast_dsp(), sip_read(), and socket_process().
06790 { 06791 int res = 0; 06792 06793 ast_channel_lock(chan); 06794 06795 if (chan->pbx) { /* This channel is currently in the PBX */ 06796 ast_explicit_goto(chan, context, exten, priority + 1); 06797 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 06798 } else { 06799 /* In order to do it when the channel doesn't really exist within 06800 the PBX, we have to make a new channel, masquerade, and start the PBX 06801 at the new location */ 06802 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 06803 if (!tmpchan) { 06804 res = -1; 06805 } else { 06806 if (chan->cdr) { 06807 ast_cdr_discard(tmpchan->cdr); 06808 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 06809 } 06810 /* Make formats okay */ 06811 tmpchan->readformat = chan->readformat; 06812 tmpchan->writeformat = chan->writeformat; 06813 /* Setup proper location */ 06814 ast_explicit_goto(tmpchan, 06815 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 06816 06817 /* Masquerade into temp channel */ 06818 if (ast_channel_masquerade(tmpchan, chan)) { 06819 /* Failed to set up the masquerade. It's probably chan_local 06820 * in the middle of optimizing itself out. Sad. :( */ 06821 ast_hangup(tmpchan); 06822 tmpchan = NULL; 06823 res = -1; 06824 } else { 06825 /* Grab the locks and get going */ 06826 ast_channel_lock(tmpchan); 06827 ast_do_masquerade(tmpchan); 06828 ast_channel_unlock(tmpchan); 06829 /* Start the PBX going on our stolen channel */ 06830 if (ast_pbx_start(tmpchan)) { 06831 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 06832 ast_hangup(tmpchan); 06833 res = -1; 06834 } 06835 } 06836 } 06837 } 06838 ast_channel_unlock(chan); 06839 return res; 06840 }
| int ast_async_goto_by_name | ( | const char * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 6842 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
06843 { 06844 struct ast_channel *chan; 06845 int res = -1; 06846 06847 chan = ast_get_channel_by_name_locked(channame); 06848 if (chan) { 06849 res = ast_async_goto(chan, context, exten, priority); 06850 ast_channel_unlock(chan); 06851 } 06852 return res; 06853 }
| int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 8992 of file pbx.c.
References __ast_goto_if_exists().
08993 { 08994 return __ast_goto_if_exists(chan, context, exten, priority, 1); 08995 }
| int ast_async_parseable_goto | ( | struct ast_channel * | chan, | |
| const char * | goto_string | |||
| ) |
Definition at line 9055 of file pbx.c.
References pbx_parseable_goto().
Referenced by asyncgoto_exec().
09056 { 09057 return pbx_parseable_goto(chan, goto_string, 1); 09058 }
| int ast_build_timing | ( | struct ast_timing * | i, | |
| const char * | info | |||
| ) |
Definition at line 6410 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().
06411 { 06412 char info_save[256]; 06413 char *info; 06414 06415 /* Check for empty just in case */ 06416 if (ast_strlen_zero(info_in)) 06417 return 0; 06418 /* make a copy just in case we were passed a static string */ 06419 ast_copy_string(info_save, info_in, sizeof(info_save)); 06420 info = info_save; 06421 /* Assume everything except time */ 06422 i->monthmask = 0xfff; /* 12 bits */ 06423 i->daymask = 0x7fffffffU; /* 31 bits */ 06424 i->dowmask = 0x7f; /* 7 bits */ 06425 /* on each call, use strsep() to move info to the next argument */ 06426 get_timerange(i, strsep(&info, "|,")); 06427 if (info) 06428 i->dowmask = get_range(strsep(&info, "|,"), 7, days, "day of week"); 06429 if (info) 06430 i->daymask = get_range(strsep(&info, "|,"), 31, NULL, "day"); 06431 if (info) 06432 i->monthmask = get_range(strsep(&info, "|,"), 12, months, "month"); 06433 return 1; 06434 }
| 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 3661 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(), pri_dchannel(), skinny_ss(), ss_thread(), and valid_exit().
03662 { 03663 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0, 0); 03664 }
| int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 6436 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().
06437 { 06438 struct ast_tm tm; 06439 struct timeval now = ast_tvnow(); 06440 06441 ast_localtime(&now, &tm, NULL); 06442 06443 /* If it's not the right month, return */ 06444 if (!(i->monthmask & (1 << tm.tm_mon))) 06445 return 0; 06446 06447 /* If it's not that time of the month.... */ 06448 /* Warning, tm_mday has range 1..31! */ 06449 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 06450 return 0; 06451 06452 /* If it's not the right day of the week */ 06453 if (!(i->dowmask & (1 << tm.tm_wday))) 06454 return 0; 06455 06456 /* Sanity check the hour just to be safe */ 06457 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 06458 ast_log(LOG_WARNING, "Insane time...\n"); 06459 return 0; 06460 } 06461 06462 /* Now the tough part, we calculate if it fits 06463 in the right time based on min/hour */ 06464 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 06465 return 0; 06466 06467 /* If we got this far, then we're good */ 06468 return 1; 06469 }
| 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 |
Adds an ignore pattern to a particular context.
| 0 | on success | |
| -1 | on failure |
Definition at line 6662 of file pbx.c.
References ast_context_add_ignorepat2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_cli_dialplan_add_ignorepat().
06663 { 06664 int ret = -1; 06665 struct ast_context *c = find_context_locked(context); 06666 06667 if (c) { 06668 ret = ast_context_add_ignorepat2(c, value, registrar); 06669 ast_unlock_contexts(); 06670 } 06671 return ret; 06672 }
| int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
| const char * | ignorepat, | |||
| const char * | registrar | |||
| ) |
Definition at line 6674 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().
06675 { 06676 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 06677 int length; 06678 char *pattern; 06679 length = sizeof(struct ast_ignorepat); 06680 length += strlen(value) + 1; 06681 if (!(ignorepat = ast_calloc(1, length))) 06682 return -1; 06683 /* The cast to char * is because we need to write the initial value. 06684 * The field is not supposed to be modified otherwise. Also, gcc 4.2 06685 * sees the cast as dereferencing a type-punned pointer and warns about 06686 * it. This is the workaround (we're telling gcc, yes, that's really 06687 * what we wanted to do). 06688 */ 06689 pattern = (char *) ignorepat->pattern; 06690 strcpy(pattern, value); 06691 ignorepat->next = NULL; 06692 ignorepat->registrar = registrar; 06693 ast_wrlock_context(con); 06694 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 06695 ignorepatl = ignorepatc; 06696 if (!strcasecmp(ignorepatc->pattern, value)) { 06697 /* Already there */ 06698 ast_unlock_context(con); 06699 errno = EEXIST; 06700 return -1; 06701 } 06702 } 06703 if (ignorepatl) 06704 ignorepatl->next = ignorepat; 06705 else 06706 con->ignorepats = ignorepat; 06707 ast_unlock_context(con); 06708 return 0; 06709 06710 }
| 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 |
Adds an include taking a char * string as the context parameter
| 0 | on success | |
| -1 | on error |
Definition at line 6216 of file pbx.c.
References ast_context_add_include2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_cli_dialplan_add_include().
06217 { 06218 int ret = -1; 06219 struct ast_context *c = find_context_locked(context); 06220 06221 if (c) { 06222 ret = ast_context_add_include2(c, include, registrar); 06223 ast_unlock_contexts(); 06224 } 06225 return ret; 06226 }
| 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 |
Adds an include taking a struct ast_context as the first parameter
| 0 | on success | |
| -1 | on failure |
Definition at line 6478 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().
06480 { 06481 struct ast_include *new_include; 06482 char *c; 06483 struct ast_include *i, *il = NULL; /* include, include_last */ 06484 int length; 06485 char *p; 06486 06487 length = sizeof(struct ast_include); 06488 length += 2 * (strlen(value) + 1); 06489 06490 /* allocate new include structure ... */ 06491 if (!(new_include = ast_calloc(1, length))) 06492 return -1; 06493 /* Fill in this structure. Use 'p' for assignments, as the fields 06494 * in the structure are 'const char *' 06495 */ 06496 p = new_include->stuff; 06497 new_include->name = p; 06498 strcpy(p, value); 06499 p += strlen(value) + 1; 06500 new_include->rname = p; 06501 strcpy(p, value); 06502 /* Strip off timing info, and process if it is there */ 06503 if ( (c = strchr(p, ',')) ) { 06504 *c++ = '\0'; 06505 new_include->hastime = ast_build_timing(&(new_include->timing), c); 06506 } 06507 new_include->next = NULL; 06508 new_include->registrar = registrar; 06509 06510 ast_wrlock_context(con); 06511 06512 /* ... go to last include and check if context is already included too... */ 06513 for (i = con->includes; i; i = i->next) { 06514 if (!strcasecmp(i->name, new_include->name)) { 06515 ast_free(new_include); 06516 ast_unlock_context(con); 06517 errno = EEXIST; 06518 return -1; 06519 } 06520 il = i; 06521 } 06522 06523 /* ... include new context into context list, unlock, return */ 06524 if (il) 06525 il->next = new_include; 06526 else 06527 con->includes = new_include; 06528 ast_verb(3, "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 06529 06530 ast_unlock_context(con); 06531 06532 return 0; 06533 }
| 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 |
This function registers a switch with the asterisk switch architecture
| 0 | on success | |
| -1 | on failure |
Definition at line 6540 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
06541 { 06542 int ret = -1; 06543 struct ast_context *c = find_context_locked(context); 06544 06545 if (c) { /* found, add switch to this context */ 06546 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 06547 ast_unlock_contexts(); 06548 } 06549 return ret; 06550 }
| 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 6559 of file pbx.c.
References ast_calloc, ast_free, ast_get_context_name(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_sw::data, errno, ast_sw::eval, ast_sw::name, and ast_sw::registrar.
Referenced by ast_context_add_switch(), context_merge_incls_swits_igps_other_registrars(), lua_register_switches(), and pbx_load_config().
06561 { 06562 struct ast_sw *new_sw; 06563 struct ast_sw *i; 06564 int length; 06565 char *p; 06566 06567 length = sizeof(struct ast_sw); 06568 length += strlen(value) + 1; 06569 if (data) 06570 length += strlen(data); 06571 length++; 06572 06573 /* allocate new sw structure ... */ 06574 if (!(new_sw = ast_calloc(1, length))) 06575 return -1; 06576 /* ... fill in this structure ... */ 06577 p = new_sw->stuff; 06578 new_sw->name = p; 06579 strcpy(new_sw->name, value); 06580 p += strlen(value) + 1; 06581 new_sw->data = p; 06582 if (data) { 06583 strcpy(new_sw->data, data); 06584 p += strlen(data) + 1; 06585 } else { 06586 strcpy(new_sw->data, ""); 06587 p++; 06588 } 06589 new_sw->eval = eval; 06590 new_sw->registrar = registrar; 06591 06592 /* ... try to lock this context ... */ 06593 ast_wrlock_context(con); 06594 06595 /* ... go to last sw and check if context is already swd too... */ 06596 AST_LIST_TRAVERSE(&con->alts, i, list) { 06597 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 06598 ast_free(new_sw); 06599 ast_unlock_context(con); 06600 errno = EEXIST; 06601 return -1; 06602 } 06603 } 06604 06605 /* ... sw new context into context list, unlock, return */ 06606 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 06607 06608 ast_verb(3, "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 06609 06610 ast_unlock_context(con); 06611 06612 return 0; 06613 }
| 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 |
You can optionally leave out either parameter. It will find it based on either the ast_context or the registrar name.
Definition at line 7857 of file pbx.c.
References __ast_context_destroy(), ast_unlock_contexts(), and ast_wrlock_contexts().
Referenced by __unload_module(), cleanup_stale_contexts(), parkinglot_destroy(), sla_destroy(), and unload_module().
07858 { 07859 ast_wrlock_contexts(); 07860 __ast_context_destroy(contexts, contexts_table, con,registrar); 07861 ast_unlock_contexts(); 07862 }
| struct ast_context* ast_context_find | ( | const char * | name | ) | [read] |
Find a context.
| name | name of the context to find |
Will search for the context with the given name.
Definition at line 2031 of file pbx.c.
References ast_copy_string(), ast_hashtab_lookup(), ast_rdlock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by __unload_module(), _macro_exec(), ast_context_verify_includes(), ast_ignore_pattern(), cleanup_stale_contexts(), isexten_function_read(), load_config(), manage_parkinglot(), park_exec_full(), parkinglot_destroy(), register_exten(), register_peer_exten(), unload_module(), and unregister_exten().
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 | |||
| ) | [read] |
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 function allows you to play in two environments: the global contexts (active dialplan) or an external context set of your choosing. To act on the external set, make sure extcontexts and exttable are set; for the globals, make sure both extcontexts and exttable are NULL.
This will first search for a context with your name. If it exists already, it will not create a new one. If it does not exist, it will create a new one with the given name and registrar.
Definition at line 5872 of file pbx.c.
References ast_calloc, ast_copy_string(), ast_debug, ast_hashtab_compare_contexts(), ast_hashtab_create(), ast_hashtab_hash_contexts(), ast_hashtab_insert_immediate(), ast_hashtab_insert_safe(), ast_hashtab_lookup(), ast_hashtab_newsize_java(), ast_hashtab_resize_java(), ast_log(), ast_mutex_init(), ast_rdlock_contexts(), ast_rwlock_init(), ast_strdup, ast_unlock_contexts(), ast_verb, ast_wrlock_contexts(), ast_context::ignorepats, ast_context::includes, local_contexts, ast_context::lock, LOG_ERROR, ast_context::next, ast_context::refcount, ast_context::registrar, ast_context::root, and ast_context::root_table.
Referenced by ast_park_call_full(), build_parkinglot(), context_merge(), load_config(), load_module(), lua_register_switches(), manage_parkinglot(), pbx_load_config(), pbx_load_users(), reload_config(), set_config(), sla_build_station(), and sla_build_trunk().
05873 { 05874 struct ast_context *tmp, **local_contexts; 05875 struct fake_context search; 05876 int length = sizeof(struct ast_context) + strlen(name) + 1; 05877 05878 if (!contexts_table) { 05879 contexts_table = ast_hashtab_create(17, 05880 ast_hashtab_compare_contexts, 05881 ast_hashtab_resize_java, 05882 ast_hashtab_newsize_java, 05883 ast_hashtab_hash_contexts, 05884 0); 05885 } 05886 05887 ast_copy_string(search.name, name, sizeof(search.name)); 05888 if (!extcontexts) { 05889 ast_rdlock_contexts(); 05890 local_contexts = &contexts; 05891 tmp = ast_hashtab_lookup(contexts_table, &search); 05892 ast_unlock_contexts(); 05893 if (tmp) { 05894 tmp->refcount++; 05895 return tmp; 05896 } 05897 } else { /* local contexts just in a linked list; search there for the new context; slow, linear search, but not frequent */ 05898 local_contexts = extcontexts; 05899 tmp = ast_hashtab_lookup(exttable, &search); 05900 if (tmp) { 05901 tmp->refcount++; 05902 return tmp; 05903 } 05904 } 05905 05906 if ((tmp = ast_calloc(1, length))) { 05907 ast_rwlock_init(&tmp->lock); 05908 ast_mutex_init(&tmp->macrolock); 05909 strcpy(tmp->name, name); 05910 tmp->root = NULL; 05911 tmp->root_table = NULL; 05912 tmp->registrar = ast_strdup(registrar); 05913 tmp->includes = NULL; 05914 tmp->ignorepats = NULL; 05915 tmp->refcount = 1; 05916 } else { 05917 ast_log(LOG_ERROR, "Danger! We failed to allocate a context for %s!\n", name); 05918 return NULL; 05919 } 05920 05921 if (!extcontexts) { 05922 ast_wrlock_contexts(); 05923 tmp->next = *local_contexts; 05924 *local_contexts = tmp; 05925 ast_hashtab_insert_safe(contexts_table, tmp); /*put this context into the tree */ 05926 ast_unlock_contexts(); 05927 ast_debug(1, "Registered context '%s'(%p) in table %p registrar: %s\n", tmp->name, tmp, contexts_table, registrar); 05928 ast_verb(3, "Registered extension context '%s' (%p) in table %p; registrar: %s\n", tmp->name, tmp, contexts_table, registrar); 05929 } else { 05930 tmp->next = *local_contexts; 05931 if (exttable) 05932 ast_hashtab_insert_immediate(exttable, tmp); /*put this context into the tree */ 05933 05934 *local_contexts = tmp; 05935 ast_debug(1, "Registered context '%s'(%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar); 05936 ast_verb(3, "Registered extension context '%s' (%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar); 05937 } 05938 return tmp; 05939 }
| int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
| macrocontext | name of the macro-context to lock |
Locks the given macro-context to ensure only one thread (call) can execute it at a time
| 0 | on success | |
| -1 | on failure |
Definition at line 4486 of file pbx.c.
References ast_copy_string(), ast_get_context_name(), ast_hashtab_lookup(), ast_mutex_lock(), ast_rdlock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by _macro_exec().
04487 { 04488 struct ast_context *c = NULL; 04489 int ret = -1; 04490 struct fake_context item; 04491 04492 ast_rdlock_contexts(); 04493 04494 ast_copy_string(item.name, context, sizeof(item.name)); 04495 04496 c = ast_hashtab_lookup(contexts_table,&item); 04497 if (c) 04498 ret = 0; 04499 04500 04501 #ifdef NOTNOW 04502 04503 while ((c = ast_walk_contexts(c))) { 04504 if (!strcmp(ast_get_context_name(c), context)) { 04505 ret = 0; 04506 break; 04507 } 04508 } 04509 04510 #endif 04511 ast_unlock_contexts(); 04512 04513 /* if we found context, lock macrolock */ 04514 if (ret == 0) 04515 ret = ast_mutex_lock(&c->macrolock); 04516 04517 return ret; 04518 }
| 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 |
This function removes an extension from a given context.
| 0 | on success | |
| -1 | on failure |
Definition at line 4293 of file pbx.c.
References ast_context_remove_extension_callerid().
Referenced by destroy_station(), destroy_trunk(), register_peer_exten(), unregister_exten(), and UnregisterExtension().
04294 { 04295 return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar); 04296 }
| 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 4320 of file pbx.c.
References ast_context_remove_extension_callerid2().
Referenced by load_config(), manage_parkinglot(), park_exec_full(), and unload_module().
04321 { 04322 return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar, already_locked); 04323 }
| 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 4298 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().
04299 { 04300 int ret = -1; /* default error return */ 04301 struct ast_context *c = find_context_locked(context); 04302 04303 if (c) { /* ... remove extension ... */ 04304 ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcallerid, registrar, 1); 04305 ast_unlock_contexts(); 04306 } 04307 return ret; 04308 }
| 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 4325 of file pbx.c.
References add_exten_to_pattern_tree(), ast_copy_string(), ast_hashtab_insert_immediate(), ast_hashtab_lookup(), ast_hashtab_remove_this_object(), ast_hashtab_size(), ast_log(), ast_strlen_zero(), ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_exten::cidmatch, match_char::deleted, destroy_exten(), match_char::exten, ast_exten::exten, ast_exten::label, LOG_ERROR, log_match_char_tree(), LOG_NOTICE, LOG_WARNING, ast_exten::matchcid, ast_exten::next, ast_context::pattern_tree, ast_exten::peer, ast_exten::peer_label_table, ast_exten::peer_table, ast_exten::priority, ast_exten::registrar, ast_context::root, ast_context::root_table, and match_char::x.
Referenced by __ast_context_destroy(), ast_context_remove_extension2(), and ast_context_remove_extension_callerid().
04326 { 04327 struct ast_exten *exten, *prev_exten = NULL; 04328 struct ast_exten *peer; 04329 struct ast_exten ex, *exten2, *exten3; 04330 char dummy_name[1024]; 04331 struct ast_exten *previous_peer = NULL; 04332 struct ast_exten *next_peer = NULL; 04333 int found = 0; 04334 04335 if (!already_locked) 04336 ast_wrlock_context(con); 04337 04338 /* Handle this is in the new world */ 04339 04340 /* FIXME For backwards compatibility, if callerid==NULL, then remove ALL 04341 * peers, not just those matching the callerid. */ 04342 #ifdef NEED_DEBUG 04343 ast_verb(3,"Removing %s/%s/%d%s%s from trees, registrar=%s\n", con->name, extension, priority, matchcallerid ? "/" : "", matchcallerid ? callerid : "", registrar); 04344 #endif 04345 #ifdef CONTEXT_DEBUG 04346 check_contexts(__FILE__, __LINE__); 04347 #endif 04348 /* find this particular extension */ 04349 ex.exten = dummy_name; 04350 ex.matchcid = matchcallerid && !ast_strlen_zero(callerid); /* don't say match if there's no callerid */ 04351 ex.cidmatch = callerid; 04352 ast_copy_string(dummy_name, extension, sizeof(dummy_name)); 04353 exten = ast_hashtab_lookup(con->root_table, &ex); 04354 if (exten) { 04355 if (priority == 0) { 04356 exten2 = ast_hashtab_remove_this_object(con->root_table, exten); 04357 if (!exten2) 04358 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); 04359 if (con->pattern_tree) { 04360 04361 struct match_char *x = add_exten_to_pattern_tree(con, exten, 1); 04362 04363 if (x->exten) { /* this test for safety purposes */ 04364 x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */ 04365 x->exten = 0; /* get rid of what will become a bad pointer */ 04366 } else { 04367 ast_log(LOG_WARNING,"Trying to delete an exten from a context, but the pattern tree node returned isn't a full extension\n"); 04368 } 04369 } 04370 } else { 04371 ex.priority = priority; 04372 exten2 = ast_hashtab_lookup(exten->peer_table, &ex); 04373 if (exten2) { 04374 04375 if (exten2->label) { /* if this exten has a label, remove that, too */ 04376 exten3 = ast_hashtab_remove_this_object(exten->peer_label_table,exten2); 04377 if (!exten3) 04378 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); 04379 } 04380 04381 exten3 = ast_hashtab_remove_this_object(exten->peer_table, exten2); 04382 if (!exten3) 04383 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); 04384 if (exten2 == exten && exten2->peer) { 04385 exten2 = ast_hashtab_remove_this_object(con->root_table, exten); 04386 ast_hashtab_insert_immediate(con->root_table, exten2->peer); 04387 } 04388 if (ast_hashtab_size(exten->peer_table) == 0) { 04389 /* well, if the last priority of an exten is to be removed, 04390 then, the extension is removed, too! */ 04391 exten3 = ast_hashtab_remove_this_object(con->root_table, exten); 04392 if (!exten3) 04393 ast_log(LOG_ERROR,"Did not remove this exten (%s) from the context root_table (%s) (priority %d)\n", exten->exten, con->name, priority); 04394 if (con->pattern_tree) { 04395 struct match_char *x = add_exten_to_pattern_tree(con, exten, 1); 04396 if (x->exten) { /* this test for safety purposes */ 04397 x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */ 04398 x->exten = 0; /* get rid of what will become a bad pointer */ 04399 } 04400 } 04401 } 04402 } else { 04403 ast_log(LOG_ERROR,"Could not find priority %d of exten %s in context %s!\n", 04404 priority, exten->exten, con->name); 04405 } 04406 } 04407 } else { 04408 /* hmmm? this exten is not in this pattern tree? */ 04409 ast_log(LOG_WARNING,"Cannot find extension %s in root_table in context %s\n", 04410 extension, con->name); 04411 } 04412 #ifdef NEED_DEBUG 04413 if (con->pattern_tree) { 04414 ast_log(LOG_NOTICE,"match char tree after exten removal:\n"); 04415 log_match_char_tree(con->pattern_tree, " "); 04416 } 04417 #endif 04418 04419 /* scan the extension list to find first matching extension-registrar */ 04420 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 04421 if (!strcmp(exten->exten, extension) && 04422 (!registrar || !strcmp(exten->registrar, registrar)) && 04423 (!matchcallerid || (!ast_strlen_zero(callerid) && !ast_strlen_zero(exten->cidmatch) && !strcmp(exten->cidmatch, callerid)) || (ast_strlen_zero(callerid) && ast_strlen_zero(exten->cidmatch)))) 04424 break; 04425 } 04426 if (!exten) { 04427 /* we can't find right extension */ 04428 if (!already_locked) 04429 ast_unlock_context(con); 04430 return -1; 04431 } 04432 04433 /* scan the priority list to remove extension with exten->priority == priority */ 04434 for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next; 04435 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))); 04436 peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) { 04437 if ((priority == 0 || peer->priority == priority) && 04438 (!callerid || !matchcallerid || (matchcallerid && !strcmp(peer->cidmatch, callerid))) && 04439 (!registrar || !strcmp(peer->registrar, registrar) )) { 04440 found = 1; 04441 04442 /* we are first priority extension? */ 04443 if (!previous_peer) { 04444 /* 04445 * We are first in the priority chain, so must update the extension chain. 04446 * The next node is either the next priority or the next extension 04447 */ 04448 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 04449 if (peer->peer) { 04450 /* move the peer_table and peer_label_table down to the next peer, if 04451 it is there */ 04452 peer->peer->peer_table = peer->peer_table; 04453 peer->peer->peer_label_table = peer->peer_label_table; 04454 peer->peer_table = NULL; 04455 peer->peer_label_table = NULL; 04456 } 04457 if (!prev_exten) { /* change the root... */ 04458 con->root = next_node; 04459 } else { 04460 prev_exten->next = next_node; /* unlink */ 04461 } 04462 if (peer->peer) { /* update the new head of the pri list */ 04463 peer->peer->next = peer->next; 04464 } 04465 } else { /* easy, we are not first priority in extension */ 04466 previous_peer->peer = peer->peer; 04467 } 04468 04469 /* now, free whole priority extension */ 04470 destroy_exten(peer); 04471 } else { 04472 previous_peer = peer; 04473 } 04474 } 04475 if (!already_locked) 04476 ast_unlock_context(con); 04477 return found ? 0 : -1; 04478 }
| int ast_context_remove_ignorepat | ( | const char * | context, | |
| const char * | ignorepat, | |||
| const char * | registrar | |||
| ) |
Definition at line 6619 of file pbx.c.
References ast_context_remove_ignorepat2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_cli_dialplan_remove_ignorepat().
06620 { 06621 int ret = -1; 06622 struct ast_context *c = find_context_locked(context); 06623 06624 if (c) { 06625 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 06626 ast_unlock_contexts(); 06627 } 06628 return ret; 06629 }
| int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
| const char * | ignorepat, | |||
| const char * | registrar | |||
| ) |
Definition at line 6631 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().
06632 { 06633 struct ast_ignorepat *ip, *ipl = NULL; 06634 06635 ast_wrlock_context(con); 06636 06637 for (ip = con->ignorepats; ip; ip = ip->next) { 06638 if (!strcmp(ip->pattern, ignorepat) && 06639 (!registrar || (registrar == ip->registrar))) { 06640 if (ipl) { 06641 ipl->next = ip->next; 06642 ast_free(ip); 06643 } else { 06644 con->ignorepats = ip->next; 06645 ast_free(ip); 06646 } 06647 ast_unlock_context(con); 06648 return 0; 06649 } 06650 ipl = ip; 06651 } 06652 06653 ast_unlock_context(con); 06654 errno = EINVAL; 06655 return -1; 06656 }
| 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 4185 of file pbx.c.
References ast_context_remove_include2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_cli_dialplan_remove_include().
04186 { 04187 int ret = -1; 04188 struct ast_context *c = find_context_locked(context); 04189 04190 if (c) { 04191 /* found, remove include from this context ... */ 04192 ret = ast_context_remove_include2(c, include, registrar); 04193 ast_unlock_contexts(); 04194 } 04195 return ret; 04196 }
| 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 success |
Removes an include by an ast_context structure.
| 0 | on success. | |
| -1 | on failure. |
Definition at line 4207 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().
04208 { 04209 struct ast_include *i, *pi = NULL; 04210 int ret = -1; 04211 04212 ast_wrlock_context(con); 04213 04214 /* find our include */ 04215 for (i = con->includes; i; pi = i, i = i->next) { 04216 if (!strcmp(i->name, include) && 04217 (!registrar || !strcmp(i->registrar, registrar))) { 04218 /* remove from list */ 04219 ast_verb(3, "Removing inclusion of context '%s' in context '%s; registrar=%s'\n", include, ast_get_context_name(con), registrar); 04220 if (pi) 04221 pi->next = i->next; 04222 else 04223 con->includes = i->next; 04224 /* free include and return */ 04225 ast_free(i); 04226 ret = 0; 04227 break; 04228 } 04229 } 04230 04231 ast_unlock_context(con); 04232 04233 return ret; 04234 }
| int ast_context_remove_switch | ( | const char * | context, | |
| const char * | sw, | |||
| const char * | data, | |||
| const char * | registrar | |||
| ) |
Remove a switch.
Removes a switch with the given parameters
| 0 | on success | |
| -1 | on failure |
Definition at line 4241 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
04242 { 04243 int ret = -1; /* default error return */ 04244 struct ast_context *c = find_context_locked(context); 04245 04246 if (c) { 04247 /* remove switch from this context ... */ 04248 ret = ast_context_remove_switch2(c, sw, data, registrar); 04249 ast_unlock_contexts(); 04250 } 04251 return ret; 04252 }
| 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 4262 of file pbx.c.
References ast_free, ast_get_context_name(), AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_sw::data, ast_sw::name, and ast_sw::registrar.
Referenced by ast_context_remove_switch().
04263 { 04264 struct ast_sw *i; 04265 int ret = -1; 04266 04267 ast_wrlock_context(con); 04268 04269 /* walk switches */ 04270 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 04271 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 04272 (!registrar || !strcmp(i->registrar, registrar))) { 04273 /* found, remove from list */ 04274 ast_verb(3, "Removing switch '%s' from context '%s; registrar=%s'\n", sw, ast_get_context_name(con), registrar); 04275 AST_LIST_REMOVE_CURRENT(list); 04276 ast_free(i); /* free switch and return */ 04277 ret = 0; 04278 break; 04279 } 04280 } 04281 AST_LIST_TRAVERSE_SAFE_END; 04282 04283 ast_unlock_context(con); 04284 04285 return ret; 04286 }
| int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
| macrocontext | name of the macro-context to unlock |
Unlocks the given macro-context so that another thread (call) can execute it
| 0 | on success | |
| -1 | on failure |
Definition at line 4525 of file pbx.c.
References ast_copy_string(), ast_get_context_name(), ast_hashtab_lookup(), ast_mutex_unlock(), ast_rdlock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by _macro_exec().
04526 { 04527 struct ast_context *c = NULL; 04528 int ret = -1; 04529 struct fake_context item; 04530 04531 ast_rdlock_contexts(); 04532 04533 ast_copy_string(item.name, context, sizeof(item.name)); 04534 04535 c = ast_hashtab_lookup(contexts_table,&item); 04536 if (c) 04537 ret = 0; 04538 #ifdef NOTNOW 04539 04540 while ((c = ast_walk_contexts(c))) { 04541 if (!strcmp(ast_get_context_name(c), context)) { 04542 ret = 0; 04543 break; 04544 } 04545 } 04546 04547 #endif 04548 ast_unlock_contexts(); 04549 04550 /* if we found context, unlock macrolock */ 04551 if (ret == 0) 04552 ret = ast_mutex_unlock(&c->macrolock); 04553 04554 return ret; 04555 }
| 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 8949 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().
08950 { 08951 struct ast_include *inc = NULL; 08952 int res = 0; 08953 08954 while ( (inc = ast_walk_context_includes(con, inc)) ) { 08955 if (ast_context_find(inc->rname)) 08956 continue; 08957 08958 res = -1; 08959 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 08960 ast_get_context_name(con), inc->rname); 08961 break; 08962 } 08963 08964 return res; 08965 }
| struct ast_custom_function* ast_custom_function_find | ( | const char * | name | ) | [read] |
Definition at line 2782 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().
02783 { 02784 struct ast_custom_function *acf = NULL; 02785 02786 AST_RWLIST_RDLOCK(&acf_root); 02787 AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) { 02788 if (!strcmp(name, acf->name)) 02789 break; 02790 } 02791 AST_RWLIST_UNLOCK(&acf_root); 02792 02793 return acf; 02794 }
| int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Unregister a custom function.
Definition at line 2796 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().
02797 { 02798 struct ast_custom_function *cur; 02799 02800 if (!acf) 02801 return -1; 02802 02803 AST_RWLIST_WRLOCK(&acf_root); 02804 if ((cur = AST_RWLIST_REMOVE(&acf_root, acf, acflist))) 02805 ast_verb(2, "Unregistered custom function %s\n", cur->name); 02806 AST_RWLIST_UNLOCK(&acf_root); 02807 02808 return cur ? 0 : -1; 02809 }
| 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 3276 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().
03277 { 03278 switch (devstate) { 03279 case AST_DEVICE_ONHOLD: 03280 return AST_EXTENSION_ONHOLD; 03281 case AST_DEVICE_BUSY: 03282 return AST_EXTENSION_BUSY; 03283 case AST_DEVICE_UNAVAILABLE: 03284 case AST_DEVICE_UNKNOWN: 03285 case AST_DEVICE_INVALID: 03286 return AST_EXTENSION_UNAVAILABLE; 03287 case AST_DEVICE_RINGINUSE: 03288 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING); 03289 case AST_DEVICE_RINGING: 03290 return AST_EXTENSION_RINGING; 03291 case AST_DEVICE_INUSE: 03292 return AST_EXTENSION_INUSE; 03293 case AST_DEVICE_NOT_INUSE: 03294 return AST_EXTENSION_NOT_INUSE; 03295 case AST_DEVICE_TOTAL: /* not a device state, included for completeness */ 03296 break; 03297 } 03298 03299 return AST_EXTENSION_NOT_INUSE; 03300 }
| 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 3646 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(), ss7_linkset(), ss_thread(), and waitstream_core().
03647 { 03648 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0, 0); 03649 }
| int ast_explicit_goto | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 6766 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_FLAG_IN_AUTOLOOP, ast_strlen_zero(), ast_test_flag, ast_channel::context, ast_channel::exten, and ast_channel::priority.
Referenced by __ast_goto_if_exists(), ast_async_goto(), builtin_atxfer(), disa_exec(), do_bridge_masquerade(), handle_setpriority(), pbx_parseable_goto(), and return_exec().
06767 { 06768 if (!chan) 06769 return -1; 06770 06771 ast_channel_lock(chan); 06772 06773 if (!ast_strlen_zero(context)) 06774 ast_copy_string(chan->context, context, sizeof(chan->context)); 06775 if (!ast_strlen_zero(exten)) 06776 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 06777 if (priority > -1) { 06778 chan->priority = priority; 06779 /* see flag description in channel.h for explanation */ 06780 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 06781 chan->priority--; 06782 } 06783 06784 ast_channel_unlock(chan); 06785 06786 return 0; 06787 }
| 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.
Checks whether or extension a should match before extension b
| 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).
Checks whether or not the given extension matches the given 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 3338 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), extstate_read(), and handle_request_subscribe().
03339 { 03340 struct ast_exten *e; 03341 03342 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 03343 if (!e) 03344 return -1; /* No hint, return -1 */ 03345 03346 return ast_extension_state2(e); /* Check all devices in the hint */ 03347 }
| 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 3326 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().
03327 { 03328 int i; 03329 03330 for (i = 0; (i < ARRAY_LEN(extension_states)); i++) { 03331 if (extension_states[i].extension_state == extension_state) 03332 return extension_states[i].text; 03333 } 03334 return "Unknown"; 03335 }
| 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 |
The callback is called if the state of an extension is changed.
| -1 | on failure | |
| ID | on success |
Definition at line 3399 of file pbx.c.
References ast_exten::app, ast_add_extension(), ast_calloc, ast_free_ptr(), ast_hint_extension(), AST_LIST_INSERT_HEAD, AST_LIST_TRAVERSE, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_state_cb::callback, ast_exten::cidmatch, ast_exten::data, ast_state_cb::data, ast_hint::exten, ast_exten::exten, ast_state_cb::id, ast_exten::label, ast_exten::parent, ast_exten::priority, and ast_exten::registrar.
Referenced by __init_manager(), handle_request_subscribe(), and skinny_register().
03401 { 03402 struct ast_hint *hint; 03403 struct ast_state_cb *cblist; 03404 struct ast_exten *e; 03405 03406 /* If there's no context and extension: add callback to statecbs list */ 03407 if (!context && !exten) { 03408 AST_RWLIST_WRLOCK(&hints); 03409 03410 AST_LIST_TRAVERSE(&statecbs, cblist, entry) { 03411 if (cblist->callback == callback) { 03412 cblist->data = data; 03413 AST_RWLIST_UNLOCK(&hints); 03414 return 0; 03415 } 03416 } 03417 03418 /* Now insert the callback */ 03419 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 03420 AST_RWLIST_UNLOCK(&hints); 03421 return -1; 03422 } 03423 cblist->id = 0; 03424 cblist->callback = callback; 03425 cblist->data = data; 03426 03427 AST_LIST_INSERT_HEAD(&statecbs, cblist, entry); 03428 03429 AST_RWLIST_UNLOCK(&hints); 03430 03431 return 0; 03432 } 03433 03434 if (!context || !exten) 03435 return -1; 03436 03437 /* This callback type is for only one hint, so get the hint */ 03438 e = ast_hint_extension(NULL, context, exten); 03439 if (!e) { 03440 return -1; 03441 } 03442 03443 /* If this is a pattern, dynamically create a new extension for this 03444 * particular match. Note that this will only happen once for each 03445 * individual extension, because the pattern will no longer match first. 03446 */ 03447 if (e->exten[0] == '_') { 03448 ast_add_extension(e->parent->name, 0, exten, e->priority, e->label, 03449 e->cidmatch, e->app, ast_strdup(e->data), ast_free_ptr, 03450 e->registrar); 03451 e = ast_hint_extension(NULL, context, exten); 03452 if (!e || e->exten[0] == '_') { 03453 return -1; 03454 } 03455 } 03456 03457 /* Find the hint in the list of hints */ 03458 AST_RWLIST_WRLOCK(&hints); 03459 03460 AST_RWLIST_TRAVERSE(&hints, hint, list) { 03461 if (hint->exten == e) 03462 break; 03463 } 03464 03465 if (!hint) { 03466 /* We have no hint, sorry */ 03467 AST_RWLIST_UNLOCK(&hints); 03468 return -1; 03469 } 03470 03471 /* Now insert the callback in the callback list */ 03472 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 03473 AST_RWLIST_UNLOCK(&hints); 03474 return -1; 03475 } 03476 03477 cblist->id = stateid++; /* Unique ID for this callback */ 03478 cblist->callback = callback; /* Pointer to callback routine */ 03479 cblist->data = data; /* Data for the callback */ 03480 03481 AST_LIST_INSERT_HEAD(&hint->callbacks, cblist, entry); 03482 03483 AST_RWLIST_UNLOCK(&hints); 03484 03485 return cblist->id; 03486 }
| 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 |
Removes the callback from list of callbacks
| 0 | success | |
| -1 | failure |
Definition at line 3489 of file pbx.c.
References ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_state_cb::callback, and ast_state_cb::id.
Referenced by dialog_unlink_all(), handle_request_subscribe(), and skinny_unregister().
03490 { 03491 struct ast_state_cb *p_cur = NULL; 03492 int ret = -1; 03493 03494 if (!id && !callback) 03495 return -1; 03496 03497 AST_RWLIST_WRLOCK(&hints); 03498 03499 if (!id) { /* id == 0 is a callback without extension */ 03500 AST_LIST_TRAVERSE_SAFE_BEGIN(&statecbs, p_cur, entry) { 03501 if (p_cur->callback == callback) { 03502 AST_LIST_REMOVE_CURRENT(entry); 03503 break; 03504 } 03505 } 03506 AST_LIST_TRAVERSE_SAFE_END; 03507 } else { /* callback with extension, find the callback based on ID */ 03508 struct ast_hint *hint; 03509 AST_RWLIST_TRAVERSE(&hints, hint, list) { 03510 AST_LIST_TRAVERSE_SAFE_BEGIN(&hint->callbacks, p_cur, entry) { 03511 if (p_cur->id == id) { 03512 AST_LIST_REMOVE_CURRENT(entry); 03513 break; 03514 } 03515 } 03516 AST_LIST_TRAVERSE_SAFE_END; 03517 03518 if (p_cur) 03519 break; 03520 } 03521 } 03522 03523 if (p_cur) { 03524 ast_free(p_cur); 03525 } 03526 03527 AST_RWLIST_UNLOCK(&hints); 03528 03529 return ret; 03530 }
| 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 3651 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().
03652 { 03653 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0, 0); 03654 }
| 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.
Definition at line 3656 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
03657 { 03658 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0, 0); 03659 }
| 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 |
This application executes a function in read mode on a given channel.
Definition at line 2869 of file pbx.c.
References __ast_module_user_add(), __ast_module_user_remove(), ast_custom_function_find(), ast_log(), ast_strdupa, copy(), func_args(), LOG_ERROR, ast_custom_function::mod, and ast_custom_function::read.
Referenced by action_getvar(), action_status(), handle_getvariable(), lua_get_variable_value(), and pbx_substitute_variables_helper_full().
02870 { 02871 char *copy = ast_strdupa(function); 02872 char *args = func_args(copy); 02873 struct ast_custom_function *acfptr = ast_custom_function_find(copy); 02874 02875 if (acfptr == NULL) 02876 ast_log(LOG_ERROR, "Function %s not registered\n", copy); 02877 else if (!acfptr->read) 02878 ast_log(LOG_ERROR, "Function %s cannot be read\n", copy); 02879 else { 02880 int res; 02881 struct ast_module_user *u = NULL; 02882 if (acfptr->mod) 02883 u = __ast_module_user_add(acfptr->mod, chan); 02884 res = acfptr->read(chan, copy, args, workspace, len); 02885 if (acfptr->mod && u) 02886 __ast_module_user_remove(acfptr->mod, u); 02887 return res; 02888 } 02889 return -1; 02890 }
| 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 |
This application executes a function in write mode on a given channel.
Definition at line 2892 of file pbx.c.
References __ast_module_user_add(), __ast_module_user_remove(), ast_custom_function_find(), ast_log(), ast_strdupa, copy(), func_args(), LOG_ERROR, ast_custom_function::mod, and ast_custom_function::write.
Referenced by pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().
02893 { 02894 char *copy = ast_strdupa(function); 02895 char *args = func_args(copy); 02896 struct ast_custom_function *acfptr = ast_custom_function_find(copy); 02897 02898 if (acfptr == NULL) 02899 ast_log(LOG_ERROR, "Function %s not registered\n", copy); 02900 else if (!acfptr->write) 02901 ast_log(LOG_ERROR, "Function %s cannot be written to\n", copy); 02902 else { 02903 int res; 02904 struct ast_module_user *u = NULL; 02905 if (acfptr->mod) 02906 u = __ast_module_user_add(acfptr->mod, chan); 02907 res = acfptr->write(chan, copy, args, value); 02908 if (acfptr->mod && u) 02909 __ast_module_user_remove(acfptr->mod, u); 02910 return res; 02911 } 02912 02913 return -1; 02914 }
| const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 8801 of file pbx.c.
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().
| const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 8839 of file pbx.c.
References ast_context::registrar.
Referenced by handle_cli_dialplan_save(), show_debug_helper(), and show_dialplan_helper().
08840 { 08841 return c ? c->registrar : NULL; 08842 }
| const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 8869 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().
08870 { 08871 return e ? e->app : NULL; 08872 }
| void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 8874 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().
08875 { 08876 return e ? e->data : NULL; 08877 }
| const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 8864 of file pbx.c.
References ast_exten::cidmatch.
Referenced by complete_dialplan_remove_extension(), find_matching_priority(), and handle_cli_dialplan_save().
08865 { 08866 return e ? e->cidmatch : NULL; 08867 }
| struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) | [read] |
Definition at line 8806 of file pbx.c.
References ast_exten::parent.
Referenced by handle_show_hint(), and handle_show_hints().
08807 { 08808 return exten ? exten->parent : NULL; 08809 }
| const char* ast_get_extension_label | ( | struct ast_exten * | e | ) |
Definition at line 8816 of file pbx.c.
References ast_exten::label.
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 8859 of file pbx.c.
References ast_exten::matchcid.
Referenced by complete_dialplan_remove_extension(), find_matching_priority(), and handle_cli_dialplan_save().
08860 { 08861 return e ? e->matchcid : 0; 08862 }
| const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 8811 of file pbx.c.
References ast_exten::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().
08812 { 08813 return exten ? exten->exten : NULL; 08814 }
| int ast_get_extension_priority | ( | struct ast_exten * | exten | ) |
Definition at line 8831 of file pbx.c.
References ast_exten::priority.
Referenced by complete_dialplan_remove_extension(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and print_ext().
08832 { 08833 return exten ? exten->priority : -1; 08834 }
| const char* ast_get_extension_registrar | ( | struct ast_exten * | e | ) |
Definition at line 8844 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08845 { 08846 return e ? e->registrar : NULL; 08847 }
| int ast_get_hint | ( | char * | hint, | |
| int | hintsize, | |||
| char * | name, | |||
| int | namesize, | |||
| struct ast_channel * | c, | |||
| const char * | context, | |||
| const char * | exten | |||
| ) |
If an extension hint exists, return non-zero.
| 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 3629 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().
03630 { 03631 struct ast_exten *e = ast_hint_extension(c, context, exten); 03632 03633 if (e) { 03634 if (hint) 03635 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 03636 if (name) { 03637 const char *tmp = ast_get_extension_app_data(e); 03638 if (tmp) 03639 ast_copy_string(name, tmp, namesize); 03640 } 03641 return -1; 03642 } 03643 return 0; 03644 }
| const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 8826 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().
08827 { 08828 return ip ? ip->pattern : NULL; 08829 }
| const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 8854 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().
08855 { 08856 return ip ? ip->registrar : NULL; 08857 }
| const char* ast_get_include_name | ( | struct ast_include * | include | ) |
Definition at line 8821 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 8849 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().
08850 { 08851 return i ? i->registrar : NULL; 08852 }
| const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 8884 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().
08885 { 08886 return sw ? sw->data : NULL; 08887 }
| int ast_get_switch_eval | ( | struct ast_sw * | sw | ) |
Definition at line 8889 of file pbx.c.
References ast_sw::eval.
Referenced by context_merge_incls_swits_igps_other_registrars().
08890 { 08891 return sw->eval; 08892 }
| const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 8879 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().
08880 { 08881 return sw ? sw->name : NULL; 08882 }
| const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 8894 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().
08895 { 08896 return sw ? sw->registrar : NULL; 08897 }
| int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 8987 of file pbx.c.
References __ast_goto_if_exists().
Referenced by background_detect_exec(), channel_spy(), common_exec(), conf_run(), goto_exten(), onedigit_goto(), priority_jump(), select_entry(), and valid_exit().
08988 { 08989 return __ast_goto_if_exists(chan, context, exten, priority, 0); 08990 }
| int ast_hashtab_compare_contexts | ( | const void * | ah_a, | |
| const void * | ah_b | |||
| ) |
Definition at line 351 of file pbx.c.
Referenced by ast_context_find_or_create(), lua_register_switches(), and pbx_load_module().
00352 { 00353 const struct ast_context *ac = ah_a; 00354 const struct ast_context *bc = ah_b; 00355 if (!ac || !bc) /* safety valve, but it might prevent a crash you'd rather have happen */ 00356 return 1; 00357 /* assume context names are registered in a string table! */ 00358 return strcmp(ac->name, bc->name); 00359 }
| unsigned int ast_hashtab_hash_contexts | ( | const void * | obj | ) |
Definition at line 394 of file pbx.c.
References ast_hashtab_hash_string().
Referenced by ast_context_find_or_create(), lua_register_switches(), and pbx_load_module().
00395 { 00396 const struct ast_context *ac = obj; 00397 return ast_hashtab_hash_string(ac->name); 00398 }
| int ast_ignore_pattern | ( | const char * | context, | |
| const char * | pattern | |||
| ) |
Checks to see if a number should be ignored.
| context | context to search within | |
| pattern | to check whether it should be ignored or not |
Check if a number should be ignored with respect to dialtone cancellation.
| 0 | if the pattern should not be ignored | |
| non-zero | if the pattern should be ignored |
Definition at line 6712 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().
06713 { 06714 struct ast_context *con = ast_context_find(context); 06715 if (con) { 06716 struct ast_ignorepat *pat; 06717 for (pat = con->ignorepats; pat; pat = pat->next) { 06718 if (ast_extension_match(pat->pattern, pattern)) 06719 return 1; 06720 } 06721 } 06722 06723 return 0; 06724 }
| 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 3666 of file pbx.c.
References E_MATCHMORE, and pbx_extension_helper().
Referenced by __ast_pbx_run(), ast_app_dtget(), collect_digits(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_link_data(), handle_link_phone_dtmf(), local_dtmf_helper(), loopback_matchmore(), mgcp_ss(), pbx_builtin_background(), pri_dchannel(), readexten_exec(), skinny_ss(), and ss_thread().
03667 { 03668 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0); 03669 }
| 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 6071 of file pbx.c.
References __ast_internal_context_destroy(), ast_exten::app, ast_add_extension_nolock(), ast_calloc, AST_EXTENSION_REMOVED, ast_free, ast_free_ptr(), ast_hashtab_destroy(), ast_hashtab_end_traversal(), ast_hashtab_next(), ast_hashtab_start_traversal(), ast_hint_extension_nolock(), AST_LIST_APPEND_LIST, AST_LIST_EMPTY, AST_LIST_HEAD_INIT_VALUE, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_rdlock_contexts(), AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_tvdiff_us(), ast_tvnow(), ast_unlock_contexts(), ast_verb, ast_wrlock_contexts(), ast_wrlock_contexts_version(), ast_state_cb::callback, context_merge(), ast_state_cb::data, ast_exten::data, E_MATCH, ast_exten::exten, ast_hint::exten, ast_hint::laststate, LOG_WARNING, ast_context::next, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_exten::registrar, and pbx_find_info::stacklen.
Referenced by lua_reload_extensions(), and pbx_load_module().
06072 { 06073 double ft; 06074 struct ast_context *tmp, *oldcontextslist; 06075 struct ast_hashtab *oldtable; 06076 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 06077 struct store_hint *this; 06078 struct ast_hint *hint; 06079 struct ast_exten *exten; 06080 int length; 06081 struct ast_state_cb *thiscb; 06082 struct ast_hashtab_iter *iter; 06083 06084 /* it is very important that this function hold the hint list lock _and_ the conlock 06085 during its operation; not only do we need to ensure that the list of contexts 06086 and extensions does not change, but also that no hint callbacks (watchers) are 06087 added or removed during the merge/delete process 06088 06089 in addition, the locks _must_ be taken in this order, because there are already 06090 other code paths that use this order 06091 */ 06092 06093 struct timeval begintime, writelocktime, endlocktime, enddeltime; 06094 int wrlock_ver; 06095 06096 begintime = ast_tvnow(); 06097 ast_rdlock_contexts(); 06098 iter = ast_hashtab_start_traversal(contexts_table); 06099 while ((tmp = ast_hashtab_next(iter))) { 06100 context_merge(extcontexts, exttable, tmp, registrar); 06101 } 06102 ast_hashtab_end_traversal(iter); 06103 wrlock_ver = ast_wrlock_contexts_version(); 06104 06105 ast_unlock_contexts(); /* this feels real retarded, but you must do 06106 what you must do If this isn't done, the following 06107 wrlock is a guraranteed deadlock */ 06108 ast_wrlock_contexts(); 06109 if (ast_wrlock_contexts_version() > wrlock_ver+1) { 06110 ast_log(LOG_WARNING,"==================!!!!!!!!!!!!!!!Something changed the contexts in the middle of merging contexts!\n"); 06111 } 06112 06113 AST_RWLIST_WRLOCK(&hints); 06114 writelocktime = ast_tvnow(); 06115 06116 /* preserve all watchers for hints */ 06117 AST_RWLIST_TRAVERSE(&hints, hint, list) { 06118 if (!AST_LIST_EMPTY(&hint->callbacks)) { 06119 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 06120 if (!(this = ast_calloc(1, length))) 06121 continue; 06122 /* this removes all the callbacks from the hint into this. */ 06123 AST_LIST_APPEND_LIST(&this->callbacks, &hint->callbacks, entry); 06124 this->laststate = hint->laststate; 06125 this->context = this->data; 06126 strcpy(this->data, hint->exten->parent->name); 06127 this->exten = this->data + strlen(this->context) + 1; 06128 strcpy(this->exten, hint->exten->exten); 06129 AST_LIST_INSERT_HEAD(&store, this, list); 06130 } 06131 } 06132 06133 /* save the old table and list */ 06134 oldtable = contexts_table; 06135 oldcontextslist = contexts; 06136 06137 /* move in the new table and list */ 06138 contexts_table = exttable; 06139 contexts = *extcontexts; 06140 06141 /* restore the watchers for hints that can be found; notify those that 06142 cannot be restored 06143 */ 06144 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 06145 struct pbx_find_info q = { .stacklen = 0 }; 06146 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 06147 /* If this is a pattern, dynamically create a new extension for this 06148 * particular match. Note that this will only happen once for each 06149 * individual extension, because the pattern will no longer match first. 06150 */ 06151 if (exten && exten->exten[0] == '_') { 06152 ast_add_extension_nolock(exten->parent->name, 0, this->exten, PRIORITY_HINT, NULL, 06153 0, exten->app, ast_strdup(exten->data), ast_free_ptr, exten->registrar); 06154 /* rwlocks are not recursive locks */ 06155 exten = ast_hint_extension_nolock(NULL, this->context, this->exten); 06156 } 06157 06158 /* Find the hint in the list of hints */ 06159 AST_RWLIST_TRAVERSE(&hints, hint, list) { 06160 if (hint->exten == exten) 06161 break; 06162 } 06163 if (!exten || !hint) { 06164 /* this hint has been removed, notify the watchers */ 06165 while ((thiscb = AST_LIST_REMOVE_HEAD(&this->callbacks, entry))) { 06166 thiscb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, thiscb->data); 06167 ast_free(thiscb); 06168 } 06169 } else { 06170 AST_LIST_APPEND_LIST(&hint->callbacks, &this->callbacks, entry); 06171 hint->laststate = this->laststate; 06172 } 06173 ast_free(this); 06174 } 06175 06176 AST_RWLIST_UNLOCK(&hints); 06177 ast_unlock_contexts(); 06178 endlocktime = ast_tvnow(); 06179 06180 /* the old list and hashtab no longer are relevant, delete them while the rest of asterisk 06181 is now freely using the new stuff instead */ 06182 06183 ast_hashtab_destroy(oldtable, NULL); 06184 06185 for (tmp = oldcontextslist; tmp; ) { 06186 struct ast_context *next; /* next starting point */ 06187 next = tmp->next; 06188 __ast_internal_context_destroy(tmp); 06189 tmp = next; 06190 } 06191 enddeltime = ast_tvnow(); 06192 06193 ft = ast_tvdiff_us(writelocktime, begintime); 06194 ft /= 1000000.0; 06195 ast_verb(3,"Time to scan old dialplan and merge leftovers back into the new: %8.6f sec\n", ft); 06196 06197 ft = ast_tvdiff_us(endlocktime, writelocktime); 06198 ft /= 1000000.0; 06199 ast_verb(3,"Time to restore hints and swap in new dialplan: %8.6f sec\n", ft); 06200 06201 ft = ast_tvdiff_us(enddeltime, endlocktime); 06202 ft /= 1000000.0; 06203 ast_verb(3,"Time to delete the old dialplan: %8.6f sec\n", ft); 06204 06205 ft = ast_tvdiff_us(enddeltime, begintime); 06206 ft /= 1000000.0; 06207 ast_verb(3,"Total time merge_contexts_delete: %8.6f sec\n", ft); 06208 return; 06209 }
| int ast_parseable_goto | ( | struct ast_channel * | chan, | |
| const char * | goto_string | |||
| ) |
Definition at line 9050 of file pbx.c.
References pbx_parseable_goto().
Referenced by _while_exec(), check_goto_on_transfer(), dial_exec_full(), gosub_exec(), ivr_dispatch(), parkandannounce_exec(), pbx_builtin_goto(), and while_continue_exec().
09051 { 09052 return pbx_parseable_goto(chan, goto_string, 0); 09053 }
| 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 7548 of file pbx.c.
References __ast_request_and_dial(), ast_channel::_state, outgoing_helper::account, async_stat::app, app_tmp::app, async_stat::appdata, ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_free, ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create_detached, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verb, async_wait(), ast_channel::cdr, async_stat::chan, app_tmp::chan, app_tmp::data, errno, ast_channel::hangupcause, LOG_WARNING, async_stat::p, app_tmp::t, async_stat::timeout, and outgoing_helper::vars.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_app().
07549 { 07550 struct ast_channel *chan; 07551 struct app_tmp *tmp; 07552 int res = -1, cdr_res = -1; 07553 struct outgoing_helper oh; 07554 07555 memset(&oh, 0, sizeof(oh)); 07556 oh.vars = vars; 07557 oh.account = account; 07558 07559 if (locked_channel) 07560 *locked_channel = NULL; 07561 if (ast_strlen_zero(app)) { 07562 res = -1; 07563 goto outgoing_app_cleanup; 07564 } 07565 if (synchronous) { 07566 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 07567 if (chan) { 07568 ast_set_variables(chan, vars); 07569 if (account) 07570 ast_cdr_setaccount(chan, account); 07571 if (chan->_state == AST_STATE_UP) { 07572 res = 0; 07573 ast_verb(4, "Channel %s was answered.\n", chan->name); 07574 tmp = ast_calloc(1, sizeof(*tmp)); 07575 if (!tmp) 07576 res = -1; 07577 else { 07578 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 07579 if (appdata) 07580 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 07581 tmp->chan = chan; 07582 if (synchronous > 1) { 07583 if (locked_channel) 07584 ast_channel_unlock(chan); 07585 ast_pbx_run_app(tmp); 07586 } else { 07587 if (locked_channel) 07588 ast_channel_lock(chan); 07589 if (ast_pthread_create_detached(&tmp->t, NULL, ast_pbx_run_app, tmp)) { 07590 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 07591 ast_free(tmp); 07592 if (locked_channel) 07593 ast_channel_unlock(chan); 07594 ast_hangup(chan); 07595 res = -1; 07596 } else { 07597 if (locked_channel) 07598 *locked_channel = chan; 07599 } 07600 } 07601 } 07602 } else { 07603 ast_verb(4, "Channel %s was never answered.\n", chan->name); 07604 if (chan->cdr) { /* update the cdr */ 07605 /* here we update the status of the call, which sould be busy. 07606 * if that fails then we set the status to failed */ 07607 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 07608 ast_cdr_failed(chan->cdr); 07609 } 07610 ast_hangup(chan); 07611 } 07612 } 07613 07614 if (res < 0) { /* the call failed for some reason */ 07615 if (*reason == 0) { /* if the call failed (not busy or no answer) 07616 * update the cdr with the failed message */ 07617 cdr_res = ast_pbx_outgoing_cdr_failed(); 07618 if (cdr_res != 0) { 07619 res = cdr_res; 07620 goto outgoing_app_cleanup; 07621 } 07622 } 07623 } 07624 07625 } else { 07626 struct async_stat *as; 07627 if (!(as = ast_calloc(1, sizeof(*as)))) { 07628 res = -1; 07629 goto outgoing_app_cleanup; 07630 } 07631 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 07632 if (!chan) { 07633 ast_free(as); 07634 res = -1; 07635 goto outgoing_app_cleanup; 07636 } 07637 as->chan = chan; 07638 ast_copy_string(as->app, app, sizeof(as->app)); 07639 if (appdata) 07640 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 07641 as->timeout = timeout; 07642 ast_set_variables(chan, vars); 07643 if (account) 07644 ast_cdr_setaccount(chan, account); 07645 /* Start a new thread, and get something handling this channel. */ 07646 if (locked_channel) 07647 ast_channel_lock(chan); 07648 if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) { 07649 ast_log(LOG_WARNING, "Failed to start async wait\n"); 07650 ast_free(as); 07651 if (locked_channel) 07652 ast_channel_unlock(chan); 07653 ast_hangup(chan); 07654 res = -1; 07655 goto outgoing_app_cleanup; 07656 } else { 07657 if (locked_channel) 07658 *locked_channel = chan; 07659 } 07660 res = 0; 07661 } 07662 outgoing_app_cleanup: 07663 ast_variables_destroy(vars); 07664 return res; 07665 }
| 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 7382 of file pbx.c.
References __ast_request_and_dial(), ast_channel::_state, outgoing_helper::account, ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_alloc, ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_exists_extension(), ast_free, ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create_detached, ast_request_and_dial(), ast_set_variables(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verb, async_wait(), ast_channel::cdr, async_stat::chan, outgoing_helper::cid_name, outgoing_helper::cid_num, async_stat::context, ast_channel::context, outgoing_helper::context, outgoing_helper::exten, ast_channel::hangupcause, LOG_ERROR, LOG_WARNING, async_stat::p, outgoing_helper::parent_channel, pbx_builtin_setvar_helper(), outgoing_helper::priority, set_ext_pri(), async_stat::timeout, and outgoing_helper::vars.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_exten().
07383 { 07384 struct ast_channel *chan; 07385 struct async_stat *as; 07386 int res = -1, cdr_res = -1; 07387 struct outgoing_helper oh; 07388 07389 if (synchronous) { 07390 oh.context = context; 07391 oh.exten = exten; 07392 oh.priority = priority; 07393 oh.cid_num = cid_num; 07394 oh.cid_name = cid_name; 07395 oh.account = account; 07396 oh.vars = vars; 07397 oh.parent_channel = NULL; 07398 07399 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 07400 if (channel) { 07401 *channel = chan; 07402 if (chan) 07403 ast_channel_lock(chan); 07404 } 07405 if (chan) { 07406 if (chan->_state == AST_STATE_UP) { 07407 res = 0; 07408 ast_verb(4, "Channel %s was answered.\n", chan->name); 07409 07410 if (synchronous > 1) { 07411 if (channel) 07412 ast_channel_unlock(chan); 07413 if (ast_pbx_run(chan)) { 07414 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 07415 if (channel) 07416 *channel = NULL; 07417 ast_hangup(chan); 07418 chan = NULL; 07419 res = -1; 07420 } 07421 } else { 07422 if (ast_pbx_start(chan)) { 07423 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 07424 if (channel) { 07425 *channel = NULL; 07426 ast_channel_unlock(chan); 07427 } 07428 ast_hangup(chan); 07429 res = -1; 07430 } 07431 chan = NULL; 07432 } 07433 } else { 07434 ast_verb(4, "Channel %s was never answered.\n", chan->name); 07435 07436 if (chan->cdr) { /* update the cdr */ 07437 /* here we update the status of the call, which sould be busy. 07438 * if that fails then we set the status to failed */ 07439 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 07440 ast_cdr_failed(chan->cdr); 07441 } 07442 07443 if (channel) { 07444 *channel = NULL; 07445 ast_channel_unlock(chan); 07446 } 07447 ast_hangup(chan); 07448 chan = NULL; 07449 } 07450 } 07451 07452 if (res < 0) { /* the call failed for some reason */ 07453 if (*reason == 0) { /* if the call failed (not busy or no answer) 07454 * update the cdr with the failed message */ 07455 cdr_res = ast_pbx_outgoing_cdr_failed(); 07456 if (cdr_res != 0) { 07457 res = cdr_res; 07458 goto outgoing_exten_cleanup; 07459 } 07460 } 07461 07462 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 07463 /* check if "failed" exists */ 07464 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 07465 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 07466 if (chan) { 07467 char failed_reason[4] = ""; 07468 if (!ast_strlen_zero(context)) 07469 ast_copy_string(chan->context, context, sizeof(chan->context)); 07470 set_ext_pri(chan, "failed", 1); 07471 ast_set_variables(chan, vars); 07472 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 07473 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 07474 if (account) 07475 ast_cdr_setaccount(chan, account); 07476 if (ast_pbx_run(chan)) { 07477 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 07478 ast_hangup(chan); 07479 } 07480 chan = NULL; 07481 } 07482 } 07483 } 07484 } else { 07485 if (!(as = ast_calloc(1, sizeof(*as)))) { 07486 res = -1; 07487 goto outgoing_exten_cleanup; 07488 } 07489 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 07490 if (channel) { 07491 *channel = chan; 07492 if (chan) 07493 ast_channel_lock(chan); 07494 } 07495 if (!chan) { 07496 ast_free(as); 07497 res = -1; 07498 goto outgoing_exten_cleanup; 07499 } 07500 as->chan = chan; 07501 ast_copy_string(as->context, context, sizeof(as->context)); 07502 set_ext_pri(as->chan, exten, priority); 07503 as->timeout = timeout; 07504 ast_set_variables(chan, vars); 07505 if (account) 07506 ast_cdr_setaccount(chan, account); 07507 if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) { 07508 ast_log(LOG_WARNING, "Failed to start async wait\n"); 07509 ast_free(as); 07510 if (channel) { 07511 *channel = NULL; 07512 ast_channel_unlock(chan); 07513 } 07514 ast_hangup(chan); 07515 res = -1; 07516 goto outgoing_exten_cleanup; 07517 } 07518 res = 0; 07519 } 07520 outgoing_exten_cleanup: 07521 ast_variables_destroy(vars); 07522 return res; 07523 }
| 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 |
This executes the PBX on a given channel. It allocates a new PBX structure for the channel, and provides all PBX functionality. See ast_pbx_start for an asynchronous function to run the PBX in a new thread as opposed to the current one.
| Zero | on success | |
| non-zero | on failure |
Definition at line 4094 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().
04095 { 04096 return ast_pbx_run_args(c, NULL); 04097 }
| 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 |
This executes the PBX on a given channel. It allocates a new PBX structure for the channel, and provides all PBX functionality. See ast_pbx_start for an asynchronous function to run the PBX in a new thread as opposed to the current one.
| Zero | on success | |
| non-zero | on failure |
Definition at line 4079 of file pbx.c.
References __ast_pbx_run(), AST_PBX_CALL_LIMIT, AST_PBX_SUCCESS, decrease_call_count(), and increase_call_count().
Referenced by ast_pbx_run(), dial_exec_full(), handle_gosub(), and try_calling().
04080 { 04081 enum ast_pbx_result res = AST_PBX_SUCCESS; 04082 04083 if (increase_call_count(c)) { 04084 return AST_PBX_CALL_LIMIT; 04085 } 04086 04087 res = __ast_pbx_run(c, args); 04088 04089 decrease_call_count(); 04090 04091 return res; 04092 }
| 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 4057 of file pbx.c.
References ast_log(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_pthread_create_detached, decrease_call_count(), increase_call_count(), LOG_WARNING, and pbx_thread().
Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_bridge_call_thread(), ast_iax2_new(), ast_pbx_outgoing_exten(), bridge_exec(), check_goto_on_transfer(), console_new(), dahdi_new(), dial_exec_full(), gtalk_new(), gtalk_newcall(), handle_request_invite(), jingle_new(), jingle_newcall(), local_call(), manage_parkinglot(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), pri_dchannel(), rpt_call(), sip_new(), skinny_new(), unistim_new(), and usbradio_new().
04058 { 04059 pthread_t t; 04060 04061 if (!c) { 04062 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 04063 return AST_PBX_FAILED; 04064 } 04065 04066 if (increase_call_count(c)) 04067 return AST_PBX_CALL_LIMIT; 04068 04069 /* Start a new thread, and get something handling this channel. */ 04070 if (ast_pthread_create_detached(&t, NULL, pbx_thread, c)) { 04071 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 04072 decrease_call_count(); 04073 return AST_PBX_FAILED; 04074 } 04075 04076 return AST_PBX_SUCCESS; 04077 }
| int ast_processed_calls | ( | void | ) |
Retrieve the total number of calls processed through the PBX since last restart.
Definition at line 4104 of file pbx.c.
Referenced by handle_chanlist(), and handle_showcalls().
04105 { 04106 return totalcalls; 04107 }
| 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 8788 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().
08789 { 08790 return ast_rwlock_rdlock(&con->lock); 08791 }
| int ast_rdlock_contexts | ( | void | ) |
Read locks the context list.
| 0 | on success | |
| -1 | on error |
Definition at line 8770 of file pbx.c.
References ast_rwlock_rdlock().
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().
08771 { 08772 return ast_rwlock_rdlock(&conlock); 08773 }
| int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
| sw | switch to register |
This function registers a populated ast_switch structure with the asterisk switching architecture.
Definition at line 4609 of file pbx.c.
References ast_log(), AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, LOG_WARNING, and ast_switch::name.
Referenced by load_module().
04610 { 04611 struct ast_switch *tmp; 04612 04613 AST_RWLIST_WRLOCK(&switches); 04614 AST_RWLIST_TRAVERSE(&switches, tmp, list) { 04615 if (!strcasecmp(tmp->name, sw->name)) { 04616 AST_RWLIST_UNLOCK(&switches); 04617 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 04618 return -1; 04619 } 04620 } 04621 AST_RWLIST_INSERT_TAIL(&switches, sw, list); 04622 AST_RWLIST_UNLOCK(&switches); 04623 04624 return 0; 04625 }
| 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 |
This adds a new extension to the asterisk extension list.
| 0 | on success | |
| -1 | on failure. |
Definition at line 3671 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().
03672 { 03673 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn); 03674 }
| 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 8793 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().
08794 { 08795 return ast_rwlock_unlock(&con->lock); 08796 }
| int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
| 0 | on success | |
| -1 | on failure |
Definition at line 8775 of file pbx.c.
References ast_rwlock_unlock().
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().
08776 { 08777 return ast_rwlock_unlock(&conlock); 08778 }
| void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
| sw | switch to unregister |
Unregisters a switch from asterisk.
Definition at line 4627 of file pbx.c.
References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.
Referenced by __unload_module(), and unload_module().
04628 { 04629 AST_RWLIST_WRLOCK(&switches); 04630 AST_RWLIST_REMOVE(&switches, sw, list); 04631 AST_RWLIST_UNLOCK(&switches); 04632 }
| struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
| struct ast_exten * | priority | |||
| ) | [read] |
Definition at line 8907 of file pbx.c.
References ast_exten::next, and ast_context::root.
Referenced by complete_dialplan_remove_extension(), dundi_precache_full(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), pbx_find_extension(), show_dialplan_helper(), and unreference_cached_app().
| struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
| struct ast_ignorepat * | ip | |||
| ) | [read] |
Definition at line 8940 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().
08942 { 08943 if (!ip) 08944 return con ? con->ignorepats : NULL; 08945 else 08946 return ip->next; 08947 }
| struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
| struct ast_include * | inc | |||
| ) | [read] |
Definition at line 8931 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().
| struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
| struct ast_sw * | sw | |||
| ) | [read] |
Definition at line 8916 of file pbx.c.
References AST_LIST_FIRST, and AST_LIST_NEXT.
Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08918 { 08919 if (!sw) 08920 return con ? AST_LIST_FIRST(&con->alts) : NULL; 08921 else 08922 return AST_LIST_NEXT(sw, list); 08923 }
| struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) | [read] |
Definition at line 8902 of file pbx.c.
References 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 | |||
| ) | [read] |
Definition at line 8925 of file pbx.c.
References ast_exten::peer.
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().
08927 { 08928 return priority ? priority->peer : exten; 08929 }
| 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 8783 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().
08784 { 08785 return ast_rwlock_wrlock(&con->lock); 08786 }
| int ast_wrlock_contexts | ( | void | ) |
Write locks the context list.
| 0 | on success | |
| -1 | on error |
Definition at line 8762 of file pbx.c.
References ast_atomic_fetchadd_int(), ast_rwlock_wrlock(), and conlock_wrlock_version.
Referenced by ast_context_destroy(), ast_context_find_or_create(), ast_merge_contexts_and_delete(), and complete_dialplan_remove_include().
08763 { 08764 int res = ast_rwlock_wrlock(&conlock); 08765 if (!res) 08766 ast_atomic_fetchadd_int(&conlock_wrlock_version, 1); 08767 return res; 08768 }
| int ast_wrlock_contexts_version | ( | void | ) |
Definition at line 8754 of file pbx.c.
References conlock_wrlock_version.
Referenced by ast_merge_contexts_and_delete().
08755 { 08756 return conlock_wrlock_version; 08757 }
| void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 8599 of file pbx.c.
References AST_LIST_REMOVE_HEAD, ast_rwlock_unlock(), ast_rwlock_wrlock(), and ast_var_delete().
Referenced by handle_cli_dialplan_reload(), and reload().
08600 { 08601 struct ast_var_t *vardata; 08602 08603 ast_rwlock_wrlock(&globalslock); 08604 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 08605 ast_var_delete(vardata); 08606 ast_rwlock_unlock(&globalslock); 08607 }
| const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
| const char * | name | |||
| ) |
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 8369 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_var_name(), ast_var_value(), and ast_channel::varshead.
Referenced by __ast_pbx_run(), _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), array(), ast_bridge_call(), ast_call_forward(), ast_eivr_getvariable(), ast_feature_interpret(), ast_monitor_stop(), ast_park_call_full(), bridge_play_sounds(), builtin_atxfer(), builtin_automixmonitor(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dahdi_call(), dahdi_hangup(), dial_exec_full(), do_forward(), do_timelimit(), dundi_exec(), dundi_helper(), findparkinglotname(), get_also_info(), get_index(), get_refer_info(), global_read(), hash_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), local_read(), login_exec(), macro_fixup(), minivm_delete_exec(), minivm_notify_exec(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_space_reserve(), 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_calling(), try_suggested_sip_codec(), update_bridge_vars(), and wait_for_answer().
08370 { 08371 struct ast_var_t *variables; 08372 const char *ret = NULL; 08373 int i; 08374 struct varshead *places[2] = { NULL, &globals }; 08375 08376 if (!name) 08377 return NULL; 08378 08379 if (chan) { 08380 ast_channel_lock(chan); 08381 places[0] = &chan->varshead; 08382 } 08383 08384 for (i = 0; i < 2; i++) { 08385 if (!places[i]) 08386 continue; 08387 if (places[i] == &globals) 08388 ast_rwlock_rdlock(&globalslock); 08389 AST_LIST_TRAVERSE(places[i], variables, entries) { 08390 if (!strcmp(name, ast_var_name(variables))) { 08391 ret = ast_var_value(variables); 08392 break; 08393 } 08394 } 08395 if (places[i] == &globals) 08396 ast_rwlock_unlock(&globalslock); 08397 if (ret) 08398 break; 08399 } 08400 08401 if (chan) 08402 ast_channel_unlock(chan); 08403 08404 return ret; 08405 }
| void pbx_builtin_pushvar_helper | ( | struct ast_channel * | chan, | |
| const char * | name, | |||
| const char * | value | |||
| ) |
Definition at line 8407 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_strdupa, ast_var_assign(), ast_verb, LOG_WARNING, and ast_channel::varshead.
Referenced by acf_odbc_read(), acf_odbc_write(), and frame_set_var().
08408 { 08409 struct ast_var_t *newvariable; 08410 struct varshead *headp; 08411 08412 if (name[strlen(name)-1] == ')') { 08413 char *function = ast_strdupa(name); 08414 08415 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 08416 ast_func_write(chan, function, value); 08417 return; 08418 } 08419 08420 if (chan) { 08421 ast_channel_lock(chan); 08422 headp = &chan->varshead; 08423 } else { 08424 ast_rwlock_wrlock(&globalslock); 08425 headp = &globals; 08426 } 08427 08428 if (value) { 08429 if (headp == &globals) 08430 ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value); 08431 newvariable = ast_var_assign(name, value); 08432 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 08433 } 08434 08435 if (chan) 08436 ast_channel_unlock(chan); 08437 else 08438 ast_rwlock_unlock(&globalslock); 08439 }
| 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, ast_channel::context, ast_datastore::data, exception_store_info, ast_channel::exten, ast_channel::priority, pbx_exception::priority, and set_ext_pri().
Referenced by __ast_pbx_run().
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 8337 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_str_append(), ast_var_name(), ast_var_value(), LOG_ERROR, total, var, and ast_channel::varshead.
Referenced by dumpchan_exec(), handle_show_chanvar(), handle_showchan(), and vars2manager().
08338 { 08339 struct ast_var_t *variables; 08340 const char *var, *val; 08341 int total = 0; 08342 08343 if (!chan) 08344 return 0; 08345 08346 (*buf)->used = 0; 08347 (*buf)->str[0] = '\0'; 08348 08349 ast_channel_lock(chan); 08350 08351 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 08352 if ((var = ast_var_name(variables)) && (val = ast_var_value(variables)) 08353 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 08354 ) { 08355 if (ast_str_append(buf, 0, "%s=%s\n", var, val) < 0) { 08356 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 08357 break; 08358 } else 08359 total++; 08360 } else 08361 break; 08362 } 08363 08364 ast_channel_unlock(chan); 08365 08366 return total; 08367 }
| int pbx_builtin_setvar | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) |
Definition at line 8498 of file pbx.c.
References ast_compat_app_set, ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, pbx_builtin_setvar_helper(), pbx_builtin_setvar_multiple(), and strsep().
Referenced by rpt_exec().
08499 { 08500 char *name, *value, *mydata; 08501 08502 if (ast_compat_app_set) { 08503 return pbx_builtin_setvar_multiple(chan, data); 08504 } 08505 08506 if (ast_strlen_zero(data)) { 08507 ast_log(LOG_WARNING, "Set requires one variable name/value pair.\n"); 08508 return 0; 08509 } 08510 08511 mydata = ast_strdupa(data); 08512 name = strsep(&mydata, "="); 08513 value = mydata; 08514 if (strchr(name, ' ')) 08515 ast_log(LOG_WARNING, "Please avoid unnecessary spaces on variables as it may lead to unexpected results ('%s' set to '%s').\n", name, mydata); 08516 08517 pbx_builtin_setvar_helper(chan, name, value); 08518 return(0); 08519 }
| void pbx_builtin_setvar_helper | ( | struct ast_channel * | chan, | |
| const char * | name, | |||
| const char * | value | |||
| ) |
Definition at line 8441 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE, AST_LIST_TRAVERSE, ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verb, EVENT_FLAG_DIALPLAN, manager_event, and ast_channel::varshead.
Referenced by __ast_pbx_run(), __oh323_new(), _macro_exec(), _while_exec(), acf_fetch(), acf_odbc_read(), acf_odbc_write(), action_atxfer(), action_setvar(), agi_exec_full(), aji_status_exec(), aqm_exec(), array(), ast_bridge_call(), ast_eivr_setvariable(), ast_feature_request_and_dial(), ast_iax2_new(), ast_monitor_start(), ast_pbx_outgoing_exten(), ast_rtp_set_vars(), ast_set_variables(), asyncgoto_exec(), background_detect_exec(), bridge_exec(), bridge_play_sounds(), builtin_atxfer(), builtin_automixmonitor(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), channel_spy(), conf_run(), controlplayback_exec(), count_exec(), dahdi_handle_dtmfup(), dahdi_new(), dial_exec_full(), disa_exec(), do_waiting(), end_bridge_callback(), export_aoc_vars(), export_ch(), frame_set_var(), function_db_delete(), function_db_exists(), function_db_read(), function_realtime_store(), get_rdnis(), get_refer_info(), global_write(), gosub_release_frame(), handle_request_bye(), handle_request_refer(), handle_set_chanvar(), handle_set_global(), handle_setvariable(), hash_read(), hash_write(), isAnsweringMachine(), leave_voicemail(), local_hangup(), lua_set_variable(), lua_set_variable_value(), macro_fixup(), manage_parkinglot(), minivm_accmess_exec(), minivm_delete_exec(), minivm_greet_exec(), minivm_notify_exec(), minivm_record_exec(), misdn_call(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_exec_full(), parse_moved_contact(), pbx_builtin_background(), pbx_builtin_importvar(), pbx_builtin_setvar(), pbx_builtin_setvar_multiple(), pbx_load_config(), phase_e_handler(), play_message_datetime(), playback_exec(), pqm_exec(), prep_email_sub_vars(), pri_dchannel(), privacy_exec(), process_ast_dsp(), read_exec(), readexten_exec(), readfile_exec(), record_exec(), return_exec(), rotate_file(), rpt_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_hangup(), sip_new(), sip_read(), skinny_new(), sla_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), ss7_start_call(), ss_thread(), start_monitor_exec(), system_exec_helper(), transfer_exec(), transmit(), tryexec_exec(), update_bridge_vars(), update_qe_rule(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), waituntil_exec(), and zapateller_exec().
08442 { 08443 struct ast_var_t *newvariable; 08444 struct varshead *headp; 08445 const char *nametail = name; 08446 08447 if (name[strlen(name) - 1] == ')') { 08448 char *function = ast_strdupa(name); 08449 08450 ast_func_write(chan, function, value); 08451 return; 08452 } 08453 08454 if (chan) { 08455 ast_channel_lock(chan); 08456 headp = &chan->varshead; 08457 } else { 08458 ast_rwlock_wrlock(&globalslock); 08459 headp = &globals; 08460 } 08461 08462 /* For comparison purposes, we have to strip leading underscores */ 08463 if (*nametail == '_') { 08464 nametail++; 08465 if (*nametail == '_') 08466 nametail++; 08467 } 08468 08469 AST_LIST_TRAVERSE (headp, newvariable, entries) { 08470 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 08471 /* there is already such a variable, delete it */ 08472 AST_LIST_REMOVE(headp, newvariable, entries); 08473 ast_var_delete(newvariable); 08474 break; 08475 } 08476 } 08477 08478 if (value) { 08479 if (headp == &globals) 08480 ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value); 08481 newvariable = ast_var_assign(name, value); 08482 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 08483 manager_event(EVENT_FLAG_DIALPLAN, "VarSet", 08484 "Channel: %s\r\n" 08485 "Variable: %s\r\n" 08486 "Value: %s\r\n" 08487 "Uniqueid: %s\r\n", 08488 chan ? chan->name : "none", name, value, 08489 chan ? chan->uniqueid : "none"); 08490 } 08491 08492 if (chan) 08493 ast_channel_unlock(chan); 08494 else 08495 ast_rwlock_unlock(&globalslock); 08496 }
| int pbx_builtin_setvar_multiple | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) |
Definition at line 8521 of file pbx.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_channel::context, ast_channel::exten, LOG_WARNING, pbx_builtin_setvar_helper(), and ast_channel::priority.
Referenced by pbx_builtin_setvar(), queue_function_var(), set_queue_variables(), and try_calling().
08522 { 08523 char *data; 08524 int x; 08525 AST_DECLARE_APP_ARGS(args, 08526 AST_APP_ARG(pair)[24]; 08527 ); 08528 AST_DECLARE_APP_ARGS(pair, 08529 AST_APP_ARG(name); 08530 AST_APP_ARG(value); 08531 ); 08532 08533 if (ast_strlen_zero(vdata)) { 08534 ast_log(LOG_WARNING, "MSet requires at least one variable name/value pair.\n"); 08535 return 0; 08536 } 08537 08538 data = ast_strdupa(vdata); 08539 AST_STANDARD_APP_ARGS(args, data); 08540 08541 for (x = 0; x < args.argc; x++) { 08542 AST_NONSTANDARD_APP_ARGS(pair, args.pair[x], '='); 08543 if (pair.argc == 2) { 08544 pbx_builtin_setvar_helper(chan, pair.name, pair.value); 08545 if (strchr(pair.name, ' ')) 08546 ast_log(LOG_WARNING, "Please avoid unnecessary spaces on variables as it may lead to unexpected results ('%s' set to '%s').\n", pair.name, pair.value); 08547 } else if (!chan) { 08548 ast_log(LOG_WARNING, "MSet: ignoring entry '%s' with no '='\n", pair.name); 08549 } else { 08550 ast_log(LOG_WARNING, "MSet: ignoring entry '%s' with no '=' (in %s@%s:%d\n", pair.name, chan->exten, chan->context, chan->priority); 08551 } 08552 } 08553 08554 return 0; 08555 }
| 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 8609 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().
08610 { 08611 int res; 08612 if (ast_strlen_zero(condition)) { /* NULL or empty strings are false */ 08613 return 0; 08614 } else if (sscanf(condition, "%30d", &res) == 1) { /* Numbers are evaluated for truth */ 08615 return res; 08616 } else { /* Strings are true */ 08617 return 1; 08618 } 08619 }
| 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 |
This application executes an application on a given channel. It saves the stack and executes the given application passing in the given data.
| c | Channel | |
| app | Application | |
| data | Data for execution |
Definition at line 934 of file pbx.c.
References __ast_module_user_add(), __ast_module_user_remove(), ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_log(), ast_opt_dont_warn, ast_strlen_zero(), ast_channel::cdr, ast_channel::data, ast_app::execute, LOG_WARNING, and S_OR.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automixmonitor(), builtin_automonitor(), conf_run(), dial_exec_full(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), handle_gosub(), iax2_exec(), lua_pbx_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().
00937 { 00938 int res; 00939 struct ast_module_user *u = NULL; 00940 const char *saved_c_appl; 00941 const char *saved_c_data; 00942 00943 if (c->cdr && !ast_check_hangup(c)) 00944 ast_cdr_setapp(c->cdr, app->name, data); 00945 00946 /* save channel values */ 00947 saved_c_appl= c->appl; 00948 saved_c_data= c->data; 00949 00950 c->appl = app->name; 00951 c->data = data; 00952 if (app->module) 00953 u = __ast_module_user_add(app->module, c); 00954 if (strcasecmp(app->name, "system") && !ast_strlen_zero(data) && 00955 strchr(data, '|') && !strchr(data, ',') && !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 | |||
| ) | [read] |
Definition at line 2068 of file pbx.c.
References ast_autoservice_start(), ast_autoservice_stop(), ast_copy_string(), ast_hashtab_lookup(), AST_LIST_TRAVERSE, ast_log(), AST_PBX_MAX_STACK, ast_str_thread_get(), ast_strdupa, ast_strlen_zero(), ast_walk_context_extensions(), ast_walk_contexts(), ast_walk_extension_priorities(), ast_switch::canmatch, scoreboard::canmatch_exten, create_match_char_tree(), ast_sw::data, pbx_find_info::data, E_CANMATCH, E_FINDLABEL, E_MATCHMORE, ast_sw::eval, ast_switch::exists, ast_exten::exten, scoreboard::exten, extension_match_core(), pbx_find_info::foundcontext, include_valid(), ast_context::includes, pbx_find_info::incstack, ast_exten::label, scoreboard::last_char, ast_str::len, LOG_DEBUG, log_match_char_tree(), LOG_NOTICE, LOG_WARNING, match(), matchcid(), ast_switch::matchmore, ast_sw::name, new_find_extension(), ast_include::next, scoreboard::node, ast_context::pattern_tree, pbx_find_extension(), pbx_findswitch(), pbx_substitute_variables_helper(), ast_exten::priority, ast_include::rname, ast_context::root_table, pbx_find_info::stacklen, pbx_find_info::status, STATUS_NO_CONTEXT, STATUS_NO_EXTENSION, STATUS_NO_LABEL, STATUS_NO_PRIORITY, STATUS_SUCCESS, ast_str::str, strsep(), pbx_find_info::swo, scoreboard::total_length, scoreboard::total_specificity, and trie_find_next_match().
Referenced by ast_hint_extension_nolock(), ast_merge_contexts_and_delete(), pbx_extension_helper(), pbx_find_extension(), and register_peer_exten().
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 | ) | [read] |
Look up an application.
| app | name of the app |
This function searches for the ast_app structure within the apps that are registered for the one with the name you passed in.
Definition at line 975 of file pbx.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, and AST_RWLIST_UNLOCK.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automixmonitor(), builtin_automonitor(), conf_run(), dial_exec_full(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), handle_gosub(), iax2_exec(), lua_pbx_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().
00976 { 00977 struct ast_app *tmp; 00978 00979 AST_RWLIST_RDLOCK(&apps); 00980 AST_RWLIST_TRAVERSE(&apps, tmp, list) { 00981 if (!strcasecmp(tmp->name, app)) 00982 break; 00983 } 00984 AST_RWLIST_UNLOCK(&apps); 00985 00986 return tmp; 00987 }
| void pbx_retrieve_variable | ( | struct ast_channel * | c, | |
| const char * | var, | |||
| char ** | ret, | |||
| char * | workspace, | |||
| int | workspacelen, | |||
| struct varshead * | headp | |||
| ) |
Support for Asterisk built-in variables in the dialplan.
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, ast_channel::hangupcause, parse_variable_name(), ast_channel::priority, s, substring(), and ast_channel::varshead.
Referenced by action_getvar(), action_status(), handle_getvariable(), lua_get_variable(), lua_get_variable_value(), and pbx_substitute_variables_helper_full().
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 4109 of file pbx.c.
Referenced by pbx_load_module().
04110 { 04111 int oldval = autofallthrough; 04112 autofallthrough = newval; 04113 return oldval; 04114 }
| 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 4116 of file pbx.c.
Referenced by handle_set_extenpatternmatchnew(), handle_unset_extenpatternmatchnew(), and pbx_load_module().
04117 { 04118 int oldval = extenpatternmatchnew; 04119 extenpatternmatchnew = newval; 04120 return oldval; 04121 }
| 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 4123 of file pbx.c.
References ast_free, ast_strdup, and ast_strlen_zero().
Referenced by pbx_load_module().
04124 { 04125 if (overrideswitch) { 04126 ast_free(overrideswitch); 04127 } 04128 if (!ast_strlen_zero(newval)) { 04129 overrideswitch = ast_strdup(newval); 04130 } else { 04131 overrideswitch = NULL; 04132 } 04133 }
| void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
| const char * | cp1, | |||
| char * | cp2, | |||
| int | count | |||
| ) |
Definition at line 3108 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_exec(), realtime_multi_curl(), require_curl(), rotate_file(), rpt_do_lstats(), rpt_exec(), sendmail(), sendpage(), sqlite3_log(), store_curl(), substituted(), try_calling(), tryexec_exec(), and update_curl().
03109 { 03110 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 03111 }
| void pbx_substitute_variables_varshead | ( | struct varshead * | headp, | |
| const char * | cp1, | |||
| char * | cp2, | |||
| int | count | |||
| ) |
Definition at line 3113 of file pbx.c.
References pbx_substitute_variables_helper_full().
Referenced by add_user_extension(), build_user_routes(), do_say(), dundi_lookup_local(), loopback_subst(), phoneprov_callback(), pp_each_extension_exec(), and pp_each_user_exec().
03114 { 03115 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 03116 }
1.6.1