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 2795 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().
02796 { 02797 struct ast_custom_function *cur; 02798 char tmps[80]; 02799 02800 if (!acf) 02801 return -1; 02802 02803 acf->mod = mod; 02804 02805 AST_RWLIST_WRLOCK(&acf_root); 02806 02807 AST_RWLIST_TRAVERSE(&acf_root, cur, acflist) { 02808 if (!strcmp(acf->name, cur->name)) { 02809 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 02810 AST_RWLIST_UNLOCK(&acf_root); 02811 return -1; 02812 } 02813 } 02814 02815 /* Store in alphabetical order */ 02816 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 02817 if (strcasecmp(acf->name, cur->name) < 0) { 02818 AST_RWLIST_INSERT_BEFORE_CURRENT(acf, acflist); 02819 break; 02820 } 02821 } 02822 AST_RWLIST_TRAVERSE_SAFE_END; 02823 if (!cur) 02824 AST_RWLIST_INSERT_TAIL(&acf_root, acf, acflist); 02825 02826 AST_RWLIST_UNLOCK(&acf_root); 02827 02828 ast_verb(2, "Registered custom function '%s'\n", term_color(tmps, acf->name, COLOR_BRCYAN, 0, sizeof(tmps))); 02829 02830 return 0; 02831 }
| int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 4082 of file pbx.c.
Referenced by handle_chanlist(), handle_showcalls(), and sysinfo_helper().
04083 { 04084 return countcalls; 04085 }
| 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 6732 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().
06735 { 06736 int ret = -1; 06737 struct ast_context *c = find_context_locked(context); 06738 06739 if (c) { 06740 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 06741 application, data, datad, registrar); 06742 ast_unlock_contexts(); 06743 } 06744 06745 return ret; 06746 }
| 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 7050 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().
07054 { 07055 return ast_add_extension2_lockopt(con, replace, extension, priority, label, callerid, application, data, datad, registrar, 1, 1); 07056 }
| int ast_async_goto | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 6771 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(), and socket_process().
06772 { 06773 int res = 0; 06774 06775 ast_channel_lock(chan); 06776 06777 if (chan->pbx) { /* This channel is currently in the PBX */ 06778 ast_explicit_goto(chan, context, exten, priority + 1); 06779 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 06780 } else { 06781 /* In order to do it when the channel doesn't really exist within 06782 the PBX, we have to make a new channel, masquerade, and start the PBX 06783 at the new location */ 06784 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 06785 if (!tmpchan) { 06786 res = -1; 06787 } else { 06788 if (chan->cdr) { 06789 ast_cdr_discard(tmpchan->cdr); 06790 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 06791 } 06792 /* Make formats okay */ 06793 tmpchan->readformat = chan->readformat; 06794 tmpchan->writeformat = chan->writeformat; 06795 /* Setup proper location */ 06796 ast_explicit_goto(tmpchan, 06797 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 06798 06799 /* Masquerade into temp channel */ 06800 if (ast_channel_masquerade(tmpchan, chan)) { 06801 /* Failed to set up the masquerade. It's probably chan_local 06802 * in the middle of optimizing itself out. Sad. :( */ 06803 ast_hangup(tmpchan); 06804 tmpchan = NULL; 06805 res = -1; 06806 } else { 06807 /* Grab the locks and get going */ 06808 ast_channel_lock(tmpchan); 06809 ast_do_masquerade(tmpchan); 06810 ast_channel_unlock(tmpchan); 06811 /* Start the PBX going on our stolen channel */ 06812 if (ast_pbx_start(tmpchan)) { 06813 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 06814 ast_hangup(tmpchan); 06815 res = -1; 06816 } 06817 } 06818 } 06819 } 06820 ast_channel_unlock(chan); 06821 return res; 06822 }
| int ast_async_goto_by_name | ( | const char * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 6824 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
06825 { 06826 struct ast_channel *chan; 06827 int res = -1; 06828 06829 chan = ast_get_channel_by_name_locked(channame); 06830 if (chan) { 06831 res = ast_async_goto(chan, context, exten, priority); 06832 ast_channel_unlock(chan); 06833 } 06834 return res; 06835 }
| int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 8959 of file pbx.c.
References __ast_goto_if_exists().
08960 { 08961 return __ast_goto_if_exists(chan, context, exten, priority, 1); 08962 }
| int ast_async_parseable_goto | ( | struct ast_channel * | chan, | |
| const char * | goto_string | |||
| ) |
Definition at line 9022 of file pbx.c.
References pbx_parseable_goto().
Referenced by asyncgoto_exec().
09023 { 09024 return pbx_parseable_goto(chan, goto_string, 1); 09025 }
| int ast_build_timing | ( | struct ast_timing * | i, | |
| const char * | info | |||
| ) |
Definition at line 6392 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().
06393 { 06394 char info_save[256]; 06395 char *info; 06396 06397 /* Check for empty just in case */ 06398 if (ast_strlen_zero(info_in)) 06399 return 0; 06400 /* make a copy just in case we were passed a static string */ 06401 ast_copy_string(info_save, info_in, sizeof(info_save)); 06402 info = info_save; 06403 /* Assume everything except time */ 06404 i->monthmask = 0xfff; /* 12 bits */ 06405 i->daymask = 0x7fffffffU; /* 31 bits */ 06406 i->dowmask = 0x7f; /* 7 bits */ 06407 /* on each call, use strsep() to move info to the next argument */ 06408 get_timerange(i, strsep(&info, "|,")); 06409 if (info) 06410 i->dowmask = get_range(strsep(&info, "|,"), 7, days, "day of week"); 06411 if (info) 06412 i->daymask = get_range(strsep(&info, "|,"), 31, NULL, "day"); 06413 if (info) 06414 i->monthmask = get_range(strsep(&info, "|,"), 12, months, "month"); 06415 return 1; 06416 }
| 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 3644 of file pbx.c.
References E_CANMATCH, and pbx_extension_helper().
Referenced by background_detect_exec(), cb_events(), do_immediate_setup(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), handle_link_data(), handle_link_phone_dtmf(), leave_voicemail(), local_dtmf_helper(), loopback_canmatch(), mgcp_ss(), phone_check_exception(), pri_dchannel(), skinny_ss(), ss_thread(), and valid_exit().
03645 { 03646 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0, 0); 03647 }
| int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 6418 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().
06419 { 06420 struct ast_tm tm; 06421 struct timeval now = ast_tvnow(); 06422 06423 ast_localtime(&now, &tm, NULL); 06424 06425 /* If it's not the right month, return */ 06426 if (!(i->monthmask & (1 << tm.tm_mon))) 06427 return 0; 06428 06429 /* If it's not that time of the month.... */ 06430 /* Warning, tm_mday has range 1..31! */ 06431 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 06432 return 0; 06433 06434 /* If it's not the right day of the week */ 06435 if (!(i->dowmask & (1 << tm.tm_wday))) 06436 return 0; 06437 06438 /* Sanity check the hour just to be safe */ 06439 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 06440 ast_log(LOG_WARNING, "Insane time...\n"); 06441 return 0; 06442 } 06443 06444 /* Now the tough part, we calculate if it fits 06445 in the right time based on min/hour */ 06446 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 06447 return 0; 06448 06449 /* If we got this far, then we're good */ 06450 return 1; 06451 }
| 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 6644 of file pbx.c.
References ast_context_add_ignorepat2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_cli_dialplan_add_ignorepat().
06645 { 06646 int ret = -1; 06647 struct ast_context *c = find_context_locked(context); 06648 06649 if (c) { 06650 ret = ast_context_add_ignorepat2(c, value, registrar); 06651 ast_unlock_contexts(); 06652 } 06653 return ret; 06654 }
| int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
| const char * | ignorepat, | |||
| const char * | registrar | |||
| ) |
Definition at line 6656 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().
06657 { 06658 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 06659 int length; 06660 char *pattern; 06661 length = sizeof(struct ast_ignorepat); 06662 length += strlen(value) + 1; 06663 if (!(ignorepat = ast_calloc(1, length))) 06664 return -1; 06665 /* The cast to char * is because we need to write the initial value. 06666 * The field is not supposed to be modified otherwise. Also, gcc 4.2 06667 * sees the cast as dereferencing a type-punned pointer and warns about 06668 * it. This is the workaround (we're telling gcc, yes, that's really 06669 * what we wanted to do). 06670 */ 06671 pattern = (char *) ignorepat->pattern; 06672 strcpy(pattern, value); 06673 ignorepat->next = NULL; 06674 ignorepat->registrar = registrar; 06675 ast_wrlock_context(con); 06676 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 06677 ignorepatl = ignorepatc; 06678 if (!strcasecmp(ignorepatc->pattern, value)) { 06679 /* Already there */ 06680 ast_unlock_context(con); 06681 errno = EEXIST; 06682 return -1; 06683 } 06684 } 06685 if (ignorepatl) 06686 ignorepatl->next = ignorepat; 06687 else 06688 con->ignorepats = ignorepat; 06689 ast_unlock_context(con); 06690 return 0; 06691 06692 }
| 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 6198 of file pbx.c.
References ast_context_add_include2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_cli_dialplan_add_include().
06199 { 06200 int ret = -1; 06201 struct ast_context *c = find_context_locked(context); 06202 06203 if (c) { 06204 ret = ast_context_add_include2(c, include, registrar); 06205 ast_unlock_contexts(); 06206 } 06207 return ret; 06208 }
| 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 6460 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().
06462 { 06463 struct ast_include *new_include; 06464 char *c; 06465 struct ast_include *i, *il = NULL; /* include, include_last */ 06466 int length; 06467 char *p; 06468 06469 length = sizeof(struct ast_include); 06470 length += 2 * (strlen(value) + 1); 06471 06472 /* allocate new include structure ... */ 06473 if (!(new_include = ast_calloc(1, length))) 06474 return -1; 06475 /* Fill in this structure. Use 'p' for assignments, as the fields 06476 * in the structure are 'const char *' 06477 */ 06478 p = new_include->stuff; 06479 new_include->name = p; 06480 strcpy(p, value); 06481 p += strlen(value) + 1; 06482 new_include->rname = p; 06483 strcpy(p, value); 06484 /* Strip off timing info, and process if it is there */ 06485 if ( (c = strchr(p, ',')) ) { 06486 *c++ = '\0'; 06487 new_include->hastime = ast_build_timing(&(new_include->timing), c); 06488 } 06489 new_include->next = NULL; 06490 new_include->registrar = registrar; 06491 06492 ast_wrlock_context(con); 06493 06494 /* ... go to last include and check if context is already included too... */ 06495 for (i = con->includes; i; i = i->next) { 06496 if (!strcasecmp(i->name, new_include->name)) { 06497 ast_free(new_include); 06498 ast_unlock_context(con); 06499 errno = EEXIST; 06500 return -1; 06501 } 06502 il = i; 06503 } 06504 06505 /* ... include new context into context list, unlock, return */ 06506 if (il) 06507 il->next = new_include; 06508 else 06509 con->includes = new_include; 06510 ast_verb(3, "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 06511 06512 ast_unlock_context(con); 06513 06514 return 0; 06515 }
| 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 6522 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
06523 { 06524 int ret = -1; 06525 struct ast_context *c = find_context_locked(context); 06526 06527 if (c) { /* found, add switch to this context */ 06528 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 06529 ast_unlock_contexts(); 06530 } 06531 return ret; 06532 }
| 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 6541 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().
06543 { 06544 struct ast_sw *new_sw; 06545 struct ast_sw *i; 06546 int length; 06547 char *p; 06548 06549 length = sizeof(struct ast_sw); 06550 length += strlen(value) + 1; 06551 if (data) 06552 length += strlen(data); 06553 length++; 06554 06555 /* allocate new sw structure ... */ 06556 if (!(new_sw = ast_calloc(1, length))) 06557 return -1; 06558 /* ... fill in this structure ... */ 06559 p = new_sw->stuff; 06560 new_sw->name = p; 06561 strcpy(new_sw->name, value); 06562 p += strlen(value) + 1; 06563 new_sw->data = p; 06564 if (data) { 06565 strcpy(new_sw->data, data); 06566 p += strlen(data) + 1; 06567 } else { 06568 strcpy(new_sw->data, ""); 06569 p++; 06570 } 06571 new_sw->eval = eval; 06572 new_sw->registrar = registrar; 06573 06574 /* ... try to lock this context ... */ 06575 ast_wrlock_context(con); 06576 06577 /* ... go to last sw and check if context is already swd too... */ 06578 AST_LIST_TRAVERSE(&con->alts, i, list) { 06579 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 06580 ast_free(new_sw); 06581 ast_unlock_context(con); 06582 errno = EEXIST; 06583 return -1; 06584 } 06585 } 06586 06587 /* ... sw new context into context list, unlock, return */ 06588 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 06589 06590 ast_verb(3, "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 06591 06592 ast_unlock_context(con); 06593 06594 return 0; 06595 }
| 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 7839 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().
07840 { 07841 ast_wrlock_contexts(); 07842 __ast_context_destroy(contexts, contexts_table, con,registrar); 07843 ast_unlock_contexts(); 07844 }
| 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 2015 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().
02016 { 02017 struct ast_context *tmp = NULL; 02018 struct fake_context item; 02019 02020 ast_copy_string(item.name, name, sizeof(item.name)); 02021 02022 ast_rdlock_contexts(); 02023 if( contexts_table ) { 02024 tmp = ast_hashtab_lookup(contexts_table,&item); 02025 } else { 02026 while ( (tmp = ast_walk_contexts(tmp)) ) { 02027 if (!name || !strcasecmp(name, tmp->name)) 02028 break; 02029 } 02030 } 02031 ast_unlock_contexts(); 02032 return tmp; 02033 }
| 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 5855 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().
05856 { 05857 struct ast_context *tmp, **local_contexts; 05858 struct fake_context search; 05859 int length = sizeof(struct ast_context) + strlen(name) + 1; 05860 05861 if (!contexts_table) { 05862 contexts_table = ast_hashtab_create(17, 05863 ast_hashtab_compare_contexts, 05864 ast_hashtab_resize_java, 05865 ast_hashtab_newsize_java, 05866 ast_hashtab_hash_contexts, 05867 0); 05868 } 05869 05870 ast_copy_string(search.name, name, sizeof(search.name)); 05871 if (!extcontexts) { 05872 ast_rdlock_contexts(); 05873 local_contexts = &contexts; 05874 tmp = ast_hashtab_lookup(contexts_table, &search); 05875 ast_unlock_contexts(); 05876 if (tmp) { 05877 tmp->refcount++; 05878 return tmp; 05879 } 05880 } else { /* local contexts just in a linked list; search there for the new context; slow, linear search, but not frequent */ 05881 local_contexts = extcontexts; 05882 tmp = ast_hashtab_lookup(exttable, &search); 05883 if (tmp) { 05884 tmp->refcount++; 05885 return tmp; 05886 } 05887 } 05888 05889 if ((tmp = ast_calloc(1, length))) { 05890 ast_rwlock_init(&tmp->lock); 05891 ast_mutex_init(&tmp->macrolock); 05892 strcpy(tmp->name, name); 05893 tmp->root = NULL; 05894 tmp->root_table = NULL; 05895 tmp->registrar = ast_strdup(registrar); 05896 tmp->includes = NULL; 05897 tmp->ignorepats = NULL; 05898 tmp->refcount = 1; 05899 } else { 05900 ast_log(LOG_ERROR, "Danger! We failed to allocate a context for %s!\n", name); 05901 return NULL; 05902 } 05903 05904 if (!extcontexts) { 05905 ast_wrlock_contexts(); 05906 tmp->next = *local_contexts; 05907 *local_contexts = tmp; 05908 ast_hashtab_insert_safe(contexts_table, tmp); /*put this context into the tree */ 05909 ast_unlock_contexts(); 05910 ast_debug(1, "Registered context '%s'(%p) in table %p registrar: %s\n", tmp->name, tmp, contexts_table, registrar); 05911 ast_verb(3, "Registered extension context '%s' (%p) in table %p; registrar: %s\n", tmp->name, tmp, contexts_table, registrar); 05912 } else { 05913 tmp->next = *local_contexts; 05914 if (exttable) 05915 ast_hashtab_insert_immediate(exttable, tmp); /*put this context into the tree */ 05916 05917 *local_contexts = tmp; 05918 ast_debug(1, "Registered context '%s'(%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar); 05919 ast_verb(3, "Registered extension context '%s' (%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar); 05920 } 05921 return tmp; 05922 }
| 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 4469 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().
04470 { 04471 struct ast_context *c = NULL; 04472 int ret = -1; 04473 struct fake_context item; 04474 04475 ast_rdlock_contexts(); 04476 04477 ast_copy_string(item.name, context, sizeof(item.name)); 04478 04479 c = ast_hashtab_lookup(contexts_table,&item); 04480 if (c) 04481 ret = 0; 04482 04483 04484 #ifdef NOTNOW 04485 04486 while ((c = ast_walk_contexts(c))) { 04487 if (!strcmp(ast_get_context_name(c), context)) { 04488 ret = 0; 04489 break; 04490 } 04491 } 04492 04493 #endif 04494 ast_unlock_contexts(); 04495 04496 /* if we found context, lock macrolock */ 04497 if (ret == 0) 04498 ret = ast_mutex_lock(&c->macrolock); 04499 04500 return ret; 04501 }
| 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 4276 of file pbx.c.
References ast_context_remove_extension_callerid().
Referenced by destroy_station(), destroy_trunk(), register_peer_exten(), unregister_exten(), and UnregisterExtension().
04277 { 04278 return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar); 04279 }
| 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 4303 of file pbx.c.
References ast_context_remove_extension_callerid2().
Referenced by load_config(), manage_parkinglot(), park_exec_full(), and unload_module().
04304 { 04305 return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar, already_locked); 04306 }
| 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 4281 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().
04282 { 04283 int ret = -1; /* default error return */ 04284 struct ast_context *c = find_context_locked(context); 04285 04286 if (c) { /* ... remove extension ... */ 04287 ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcallerid, registrar, 1); 04288 ast_unlock_contexts(); 04289 } 04290 return ret; 04291 }
| 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 4308 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().
04309 { 04310 struct ast_exten *exten, *prev_exten = NULL; 04311 struct ast_exten *peer; 04312 struct ast_exten ex, *exten2, *exten3; 04313 char dummy_name[1024]; 04314 struct ast_exten *previous_peer = NULL; 04315 struct ast_exten *next_peer = NULL; 04316 int found = 0; 04317 04318 if (!already_locked) 04319 ast_wrlock_context(con); 04320 04321 /* Handle this is in the new world */ 04322 04323 /* FIXME For backwards compatibility, if callerid==NULL, then remove ALL 04324 * peers, not just those matching the callerid. */ 04325 #ifdef NEED_DEBUG 04326 ast_verb(3,"Removing %s/%s/%d%s%s from trees, registrar=%s\n", con->name, extension, priority, matchcallerid ? "/" : "", matchcallerid ? callerid : "", registrar); 04327 #endif 04328 #ifdef CONTEXT_DEBUG 04329 check_contexts(__FILE__, __LINE__); 04330 #endif 04331 /* find this particular extension */ 04332 ex.exten = dummy_name; 04333 ex.matchcid = matchcallerid && !ast_strlen_zero(callerid); /* don't say match if there's no callerid */ 04334 ex.cidmatch = callerid; 04335 ast_copy_string(dummy_name, extension, sizeof(dummy_name)); 04336 exten = ast_hashtab_lookup(con->root_table, &ex); 04337 if (exten) { 04338 if (priority == 0) { 04339 exten2 = ast_hashtab_remove_this_object(con->root_table, exten); 04340 if (!exten2) 04341 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); 04342 if (con->pattern_tree) { 04343 04344 struct match_char *x = add_exten_to_pattern_tree(con, exten, 1); 04345 04346 if (x->exten) { /* this test for safety purposes */ 04347 x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */ 04348 x->exten = 0; /* get rid of what will become a bad pointer */ 04349 } else { 04350 ast_log(LOG_WARNING,"Trying to delete an exten from a context, but the pattern tree node returned isn't a full extension\n"); 04351 } 04352 } 04353 } else { 04354 ex.priority = priority; 04355 exten2 = ast_hashtab_lookup(exten->peer_table, &ex); 04356 if (exten2) { 04357 04358 if (exten2->label) { /* if this exten has a label, remove that, too */ 04359 exten3 = ast_hashtab_remove_this_object(exten->peer_label_table,exten2); 04360 if (!exten3) 04361 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); 04362 } 04363 04364 exten3 = ast_hashtab_remove_this_object(exten->peer_table, exten2); 04365 if (!exten3) 04366 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); 04367 if (exten2 == exten && exten2->peer) { 04368 exten2 = ast_hashtab_remove_this_object(con->root_table, exten); 04369 ast_hashtab_insert_immediate(con->root_table, exten2->peer); 04370 } 04371 if (ast_hashtab_size(exten->peer_table) == 0) { 04372 /* well, if the last priority of an exten is to be removed, 04373 then, the extension is removed, too! */ 04374 exten3 = ast_hashtab_remove_this_object(con->root_table, exten); 04375 if (!exten3) 04376 ast_log(LOG_ERROR,"Did not remove this exten (%s) from the context root_table (%s) (priority %d)\n", exten->exten, con->name, priority); 04377 if (con->pattern_tree) { 04378 struct match_char *x = add_exten_to_pattern_tree(con, exten, 1); 04379 if (x->exten) { /* this test for safety purposes */ 04380 x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */ 04381 x->exten = 0; /* get rid of what will become a bad pointer */ 04382 } 04383 } 04384 } 04385 } else { 04386 ast_log(LOG_ERROR,"Could not find priority %d of exten %s in context %s!\n", 04387 priority, exten->exten, con->name); 04388 } 04389 } 04390 } else { 04391 /* hmmm? this exten is not in this pattern tree? */ 04392 ast_log(LOG_WARNING,"Cannot find extension %s in root_table in context %s\n", 04393 extension, con->name); 04394 } 04395 #ifdef NEED_DEBUG 04396 if (con->pattern_tree) { 04397 ast_log(LOG_NOTICE,"match char tree after exten removal:\n"); 04398 log_match_char_tree(con->pattern_tree, " "); 04399 } 04400 #endif 04401 04402 /* scan the extension list to find first matching extension-registrar */ 04403 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 04404 if (!strcmp(exten->exten, extension) && 04405 (!registrar || !strcmp(exten->registrar, registrar)) && 04406 (!matchcallerid || (!ast_strlen_zero(callerid) && !ast_strlen_zero(exten->cidmatch) && !strcmp(exten->cidmatch, callerid)) || (ast_strlen_zero(callerid) && ast_strlen_zero(exten->cidmatch)))) 04407 break; 04408 } 04409 if (!exten) { 04410 /* we can't find right extension */ 04411 if (!already_locked) 04412 ast_unlock_context(con); 04413 return -1; 04414 } 04415 04416 /* scan the priority list to remove extension with exten->priority == priority */ 04417 for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next; 04418 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))); 04419 peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) { 04420 if ((priority == 0 || peer->priority == priority) && 04421 (!callerid || !matchcallerid || (matchcallerid && !strcmp(peer->cidmatch, callerid))) && 04422 (!registrar || !strcmp(peer->registrar, registrar) )) { 04423 found = 1; 04424 04425 /* we are first priority extension? */ 04426 if (!previous_peer) { 04427 /* 04428 * We are first in the priority chain, so must update the extension chain. 04429 * The next node is either the next priority or the next extension 04430 */ 04431 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 04432 if (peer->peer) { 04433 /* move the peer_table and peer_label_table down to the next peer, if 04434 it is there */ 04435 peer->peer->peer_table = peer->peer_table; 04436 peer->peer->peer_label_table = peer->peer_label_table; 04437 peer->peer_table = NULL; 04438 peer->peer_label_table = NULL; 04439 } 04440 if (!prev_exten) { /* change the root... */ 04441 con->root = next_node; 04442 } else { 04443 prev_exten->next = next_node; /* unlink */ 04444 } 04445 if (peer->peer) { /* update the new head of the pri list */ 04446 peer->peer->next = peer->next; 04447 } 04448 } else { /* easy, we are not first priority in extension */ 04449 previous_peer->peer = peer->peer; 04450 } 04451 04452 /* now, free whole priority extension */ 04453 destroy_exten(peer); 04454 } else { 04455 previous_peer = peer; 04456 } 04457 } 04458 if (!already_locked) 04459 ast_unlock_context(con); 04460 return found ? 0 : -1; 04461 }
| int ast_context_remove_ignorepat | ( | const char * | context, | |
| const char * | ignorepat, | |||
| const char * | registrar | |||
| ) |
Definition at line 6601 of file pbx.c.
References ast_context_remove_ignorepat2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_cli_dialplan_remove_ignorepat().
06602 { 06603 int ret = -1; 06604 struct ast_context *c = find_context_locked(context); 06605 06606 if (c) { 06607 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 06608 ast_unlock_contexts(); 06609 } 06610 return ret; 06611 }
| int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
| const char * | ignorepat, | |||
| const char * | registrar | |||
| ) |
Definition at line 6613 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().
06614 { 06615 struct ast_ignorepat *ip, *ipl = NULL; 06616 06617 ast_wrlock_context(con); 06618 06619 for (ip = con->ignorepats; ip; ip = ip->next) { 06620 if (!strcmp(ip->pattern, ignorepat) && 06621 (!registrar || (registrar == ip->registrar))) { 06622 if (ipl) { 06623 ipl->next = ip->next; 06624 ast_free(ip); 06625 } else { 06626 con->ignorepats = ip->next; 06627 ast_free(ip); 06628 } 06629 ast_unlock_context(con); 06630 return 0; 06631 } 06632 ipl = ip; 06633 } 06634 06635 ast_unlock_context(con); 06636 errno = EINVAL; 06637 return -1; 06638 }
| 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 4168 of file pbx.c.
References ast_context_remove_include2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_cli_dialplan_remove_include().
04169 { 04170 int ret = -1; 04171 struct ast_context *c = find_context_locked(context); 04172 04173 if (c) { 04174 /* found, remove include from this context ... */ 04175 ret = ast_context_remove_include2(c, include, registrar); 04176 ast_unlock_contexts(); 04177 } 04178 return ret; 04179 }
| 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 4190 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().
04191 { 04192 struct ast_include *i, *pi = NULL; 04193 int ret = -1; 04194 04195 ast_wrlock_context(con); 04196 04197 /* find our include */ 04198 for (i = con->includes; i; pi = i, i = i->next) { 04199 if (!strcmp(i->name, include) && 04200 (!registrar || !strcmp(i->registrar, registrar))) { 04201 /* remove from list */ 04202 ast_verb(3, "Removing inclusion of context '%s' in context '%s; registrar=%s'\n", include, ast_get_context_name(con), registrar); 04203 if (pi) 04204 pi->next = i->next; 04205 else 04206 con->includes = i->next; 04207 /* free include and return */ 04208 ast_free(i); 04209 ret = 0; 04210 break; 04211 } 04212 } 04213 04214 ast_unlock_context(con); 04215 04216 return ret; 04217 }
| 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 4224 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
04225 { 04226 int ret = -1; /* default error return */ 04227 struct ast_context *c = find_context_locked(context); 04228 04229 if (c) { 04230 /* remove switch from this context ... */ 04231 ret = ast_context_remove_switch2(c, sw, data, registrar); 04232 ast_unlock_contexts(); 04233 } 04234 return ret; 04235 }
| 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 4245 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().
04246 { 04247 struct ast_sw *i; 04248 int ret = -1; 04249 04250 ast_wrlock_context(con); 04251 04252 /* walk switches */ 04253 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 04254 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 04255 (!registrar || !strcmp(i->registrar, registrar))) { 04256 /* found, remove from list */ 04257 ast_verb(3, "Removing switch '%s' from context '%s; registrar=%s'\n", sw, ast_get_context_name(con), registrar); 04258 AST_LIST_REMOVE_CURRENT(list); 04259 ast_free(i); /* free switch and return */ 04260 ret = 0; 04261 break; 04262 } 04263 } 04264 AST_LIST_TRAVERSE_SAFE_END; 04265 04266 ast_unlock_context(con); 04267 04268 return ret; 04269 }
| 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 4508 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().
04509 { 04510 struct ast_context *c = NULL; 04511 int ret = -1; 04512 struct fake_context item; 04513 04514 ast_rdlock_contexts(); 04515 04516 ast_copy_string(item.name, context, sizeof(item.name)); 04517 04518 c = ast_hashtab_lookup(contexts_table,&item); 04519 if (c) 04520 ret = 0; 04521 #ifdef NOTNOW 04522 04523 while ((c = ast_walk_contexts(c))) { 04524 if (!strcmp(ast_get_context_name(c), context)) { 04525 ret = 0; 04526 break; 04527 } 04528 } 04529 04530 #endif 04531 ast_unlock_contexts(); 04532 04533 /* if we found context, unlock macrolock */ 04534 if (ret == 0) 04535 ret = ast_mutex_unlock(&c->macrolock); 04536 04537 return ret; 04538 }
| 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 8916 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().
08917 { 08918 struct ast_include *inc = NULL; 08919 int res = 0; 08920 08921 while ( (inc = ast_walk_context_includes(con, inc)) ) { 08922 if (ast_context_find(inc->rname)) 08923 continue; 08924 08925 res = -1; 08926 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 08927 ast_get_context_name(con), inc->rname); 08928 break; 08929 } 08930 08931 return res; 08932 }
| struct ast_custom_function* ast_custom_function_find | ( | const char * | name | ) | [read] |
Definition at line 2766 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().
02767 { 02768 struct ast_custom_function *acf = NULL; 02769 02770 AST_RWLIST_RDLOCK(&acf_root); 02771 AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) { 02772 if (!strcmp(name, acf->name)) 02773 break; 02774 } 02775 AST_RWLIST_UNLOCK(&acf_root); 02776 02777 return acf; 02778 }
| int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Unregister a custom function.
Definition at line 2780 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().
02781 { 02782 struct ast_custom_function *cur; 02783 02784 if (!acf) 02785 return -1; 02786 02787 AST_RWLIST_WRLOCK(&acf_root); 02788 if ((cur = AST_RWLIST_REMOVE(&acf_root, acf, acflist))) 02789 ast_verb(2, "Unregistered custom function %s\n", cur->name); 02790 AST_RWLIST_UNLOCK(&acf_root); 02791 02792 return cur ? 0 : -1; 02793 }
| 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 3259 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().
03260 { 03261 switch (devstate) { 03262 case AST_DEVICE_ONHOLD: 03263 return AST_EXTENSION_ONHOLD; 03264 case AST_DEVICE_BUSY: 03265 return AST_EXTENSION_BUSY; 03266 case AST_DEVICE_UNAVAILABLE: 03267 case AST_DEVICE_UNKNOWN: 03268 case AST_DEVICE_INVALID: 03269 return AST_EXTENSION_UNAVAILABLE; 03270 case AST_DEVICE_RINGINUSE: 03271 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING); 03272 case AST_DEVICE_RINGING: 03273 return AST_EXTENSION_RINGING; 03274 case AST_DEVICE_INUSE: 03275 return AST_EXTENSION_INUSE; 03276 case AST_DEVICE_NOT_INUSE: 03277 return AST_EXTENSION_NOT_INUSE; 03278 case AST_DEVICE_TOTAL: /* not a device state, included for completeness */ 03279 break; 03280 } 03281 03282 return AST_EXTENSION_NOT_INUSE; 03283 }
| 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 3629 of file pbx.c.
References E_MATCH, and pbx_extension_helper().
Referenced by __ast_goto_if_exists(), __ast_pbx_run(), _macro_exec(), acf_isexten_exec(), answer_call(), ast_app_dtget(), ast_bridge_call(), ast_pbx_outgoing_exten(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), cli_console_dial(), conf_run(), console_dial(), console_transfer(), dahdi_handle_dtmfup(), dial_exec_full(), disa_exec(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), gosub_exec(), handle_gosub(), handle_link_data(), handle_link_phone_dtmf(), handle_stimulus_message(), isexten_function_read(), leave_voicemail(), local_alloc(), local_call(), local_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), minivm_greet_exec(), misdn_overlap_dial_task(), park_space_reserve(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), pri_dchannel(), privacy_exec(), process_ast_dsp(), readexten_exec(), register_peer_exten(), rpt_exec(), show_debug_helper(), skinny_ss(), socket_process(), ss7_linkset(), ss_thread(), and waitstream_core().
03630 { 03631 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0, 0); 03632 }
| int ast_explicit_goto | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 6748 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().
06749 { 06750 if (!chan) 06751 return -1; 06752 06753 ast_channel_lock(chan); 06754 06755 if (!ast_strlen_zero(context)) 06756 ast_copy_string(chan->context, context, sizeof(chan->context)); 06757 if (!ast_strlen_zero(exten)) 06758 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 06759 if (priority > -1) { 06760 chan->priority = priority; 06761 /* see flag description in channel.h for explanation */ 06762 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 06763 chan->priority--; 06764 } 06765 06766 ast_channel_unlock(chan); 06767 06768 return 0; 06769 }
| int ast_extension_close | ( | const char * | pattern, | |
| const char * | data, | |||
| int | needmore | |||
| ) |
Definition at line 1992 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().
01993 { 01994 if (needmore != E_MATCHMORE && needmore != E_CANMATCH) 01995 ast_log(LOG_WARNING, "invalid argument %d\n", needmore); 01996 return extension_match_core(pattern, data, needmore); 01997 }
| 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 1794 of file pbx.c.
References ext_cmp().
Referenced by lua_extension_cmp().
01795 { 01796 return ext_cmp(a, b); 01797 }
| 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 1987 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().
01988 { 01989 return extension_match_core(pattern, data, E_MATCH); 01990 }
| 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 3321 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), extstate_read(), and handle_request_subscribe().
03322 { 03323 struct ast_exten *e; 03324 03325 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 03326 if (!e) 03327 return -1; /* No hint, return -1 */ 03328 03329 return ast_extension_state2(e); /* Check all devices in the hint */ 03330 }
| 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 3309 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().
03310 { 03311 int i; 03312 03313 for (i = 0; (i < ARRAY_LEN(extension_states)); i++) { 03314 if (extension_states[i].extension_state == extension_state) 03315 return extension_states[i].text; 03316 } 03317 return "Unknown"; 03318 }
| 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 3382 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().
03384 { 03385 struct ast_hint *hint; 03386 struct ast_state_cb *cblist; 03387 struct ast_exten *e; 03388 03389 /* If there's no context and extension: add callback to statecbs list */ 03390 if (!context && !exten) { 03391 AST_RWLIST_WRLOCK(&hints); 03392 03393 AST_LIST_TRAVERSE(&statecbs, cblist, entry) { 03394 if (cblist->callback == callback) { 03395 cblist->data = data; 03396 AST_RWLIST_UNLOCK(&hints); 03397 return 0; 03398 } 03399 } 03400 03401 /* Now insert the callback */ 03402 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 03403 AST_RWLIST_UNLOCK(&hints); 03404 return -1; 03405 } 03406 cblist->id = 0; 03407 cblist->callback = callback; 03408 cblist->data = data; 03409 03410 AST_LIST_INSERT_HEAD(&statecbs, cblist, entry); 03411 03412 AST_RWLIST_UNLOCK(&hints); 03413 03414 return 0; 03415 } 03416 03417 if (!context || !exten) 03418 return -1; 03419 03420 /* This callback type is for only one hint, so get the hint */ 03421 e = ast_hint_extension(NULL, context, exten); 03422 if (!e) { 03423 return -1; 03424 } 03425 03426 /* If this is a pattern, dynamically create a new extension for this 03427 * particular match. Note that this will only happen once for each 03428 * individual extension, because the pattern will no longer match first. 03429 */ 03430 if (e->exten[0] == '_') { 03431 ast_add_extension(e->parent->name, 0, exten, e->priority, e->label, 03432 e->cidmatch, e->app, ast_strdup(e->data), ast_free_ptr, 03433 e->registrar); 03434 e = ast_hint_extension(NULL, context, exten); 03435 if (!e || e->exten[0] == '_') { 03436 return -1; 03437 } 03438 } 03439 03440 /* Find the hint in the list of hints */ 03441 AST_RWLIST_WRLOCK(&hints); 03442 03443 AST_RWLIST_TRAVERSE(&hints, hint, list) { 03444 if (hint->exten == e) 03445 break; 03446 } 03447 03448 if (!hint) { 03449 /* We have no hint, sorry */ 03450 AST_RWLIST_UNLOCK(&hints); 03451 return -1; 03452 } 03453 03454 /* Now insert the callback in the callback list */ 03455 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 03456 AST_RWLIST_UNLOCK(&hints); 03457 return -1; 03458 } 03459 03460 cblist->id = stateid++; /* Unique ID for this callback */ 03461 cblist->callback = callback; /* Pointer to callback routine */ 03462 cblist->data = data; /* Data for the callback */ 03463 03464 AST_LIST_INSERT_HEAD(&hint->callbacks, cblist, entry); 03465 03466 AST_RWLIST_UNLOCK(&hints); 03467 03468 return cblist->id; 03469 }
| 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 3472 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().
03473 { 03474 struct ast_state_cb *p_cur = NULL; 03475 int ret = -1; 03476 03477 if (!id && !callback) 03478 return -1; 03479 03480 AST_RWLIST_WRLOCK(&hints); 03481 03482 if (!id) { /* id == 0 is a callback without extension */ 03483 AST_LIST_TRAVERSE_SAFE_BEGIN(&statecbs, p_cur, entry) { 03484 if (p_cur->callback == callback) { 03485 AST_LIST_REMOVE_CURRENT(entry); 03486 break; 03487 } 03488 } 03489 AST_LIST_TRAVERSE_SAFE_END; 03490 } else { /* callback with extension, find the callback based on ID */ 03491 struct ast_hint *hint; 03492 AST_RWLIST_TRAVERSE(&hints, hint, list) { 03493 AST_LIST_TRAVERSE_SAFE_BEGIN(&hint->callbacks, p_cur, entry) { 03494 if (p_cur->id == id) { 03495 AST_LIST_REMOVE_CURRENT(entry); 03496 break; 03497 } 03498 } 03499 AST_LIST_TRAVERSE_SAFE_END; 03500 03501 if (p_cur) 03502 break; 03503 } 03504 } 03505 03506 if (p_cur) { 03507 ast_free(p_cur); 03508 } 03509 03510 AST_RWLIST_UNLOCK(&hints); 03511 03512 return ret; 03513 }
| 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 3634 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().
03635 { 03636 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0, 0); 03637 }
| 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 3639 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
03640 { 03641 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0, 0); 03642 }
| 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 2853 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().
02854 { 02855 char *copy = ast_strdupa(function); 02856 char *args = func_args(copy); 02857 struct ast_custom_function *acfptr = ast_custom_function_find(copy); 02858 02859 if (acfptr == NULL) 02860 ast_log(LOG_ERROR, "Function %s not registered\n", copy); 02861 else if (!acfptr->read) 02862 ast_log(LOG_ERROR, "Function %s cannot be read\n", copy); 02863 else { 02864 int res; 02865 struct ast_module_user *u = NULL; 02866 if (acfptr->mod) 02867 u = __ast_module_user_add(acfptr->mod, chan); 02868 res = acfptr->read(chan, copy, args, workspace, len); 02869 if (acfptr->mod && u) 02870 __ast_module_user_remove(acfptr->mod, u); 02871 return res; 02872 } 02873 return -1; 02874 }
| 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 2876 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().
02877 { 02878 char *copy = ast_strdupa(function); 02879 char *args = func_args(copy); 02880 struct ast_custom_function *acfptr = ast_custom_function_find(copy); 02881 02882 if (acfptr == NULL) 02883 ast_log(LOG_ERROR, "Function %s not registered\n", copy); 02884 else if (!acfptr->write) 02885 ast_log(LOG_ERROR, "Function %s cannot be written to\n", copy); 02886 else { 02887 int res; 02888 struct ast_module_user *u = NULL; 02889 if (acfptr->mod) 02890 u = __ast_module_user_add(acfptr->mod, chan); 02891 res = acfptr->write(chan, copy, args, value); 02892 if (acfptr->mod && u) 02893 __ast_module_user_remove(acfptr->mod, u); 02894 return res; 02895 } 02896 02897 return -1; 02898 }
| const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 8768 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 8806 of file pbx.c.
References ast_context::registrar.
Referenced by handle_cli_dialplan_save(), show_debug_helper(), and show_dialplan_helper().
08807 { 08808 return c ? c->registrar : NULL; 08809 }
| const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 8836 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().
08837 { 08838 return e ? e->app : NULL; 08839 }
| void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 8841 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().
08842 { 08843 return e ? e->data : NULL; 08844 }
| const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 8831 of file pbx.c.
References ast_exten::cidmatch.
Referenced by complete_dialplan_remove_extension(), find_matching_priority(), and handle_cli_dialplan_save().
08832 { 08833 return e ? e->cidmatch : NULL; 08834 }
| struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) | [read] |
Definition at line 8773 of file pbx.c.
References ast_exten::parent.
Referenced by handle_show_hint(), and handle_show_hints().
08774 { 08775 return exten ? exten->parent : NULL; 08776 }
| const char* ast_get_extension_label | ( | struct ast_exten * | e | ) |
Definition at line 8783 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 8826 of file pbx.c.
References ast_exten::matchcid.
Referenced by complete_dialplan_remove_extension(), find_matching_priority(), and handle_cli_dialplan_save().
08827 { 08828 return e ? e->matchcid : 0; 08829 }
| const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 8778 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().
08779 { 08780 return exten ? exten->exten : NULL; 08781 }
| int ast_get_extension_priority | ( | struct ast_exten * | exten | ) |
Definition at line 8798 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().
08799 { 08800 return exten ? exten->priority : -1; 08801 }
| const char* ast_get_extension_registrar | ( | struct ast_exten * | e | ) |
Definition at line 8811 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().
08812 { 08813 return e ? e->registrar : NULL; 08814 }
| 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 3612 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().
03613 { 03614 struct ast_exten *e = ast_hint_extension(c, context, exten); 03615 03616 if (e) { 03617 if (hint) 03618 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 03619 if (name) { 03620 const char *tmp = ast_get_extension_app_data(e); 03621 if (tmp) 03622 ast_copy_string(name, tmp, namesize); 03623 } 03624 return -1; 03625 } 03626 return 0; 03627 }
| const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 8793 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().
08794 { 08795 return ip ? ip->pattern : NULL; 08796 }
| const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 8821 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().
08822 { 08823 return ip ? ip->registrar : NULL; 08824 }
| const char* ast_get_include_name | ( | struct ast_include * | include | ) |
Definition at line 8788 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 8816 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().
08817 { 08818 return i ? i->registrar : NULL; 08819 }
| const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 8851 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().
08852 { 08853 return sw ? sw->data : NULL; 08854 }
| int ast_get_switch_eval | ( | struct ast_sw * | sw | ) |
Definition at line 8856 of file pbx.c.
References ast_sw::eval.
Referenced by context_merge_incls_swits_igps_other_registrars().
08857 { 08858 return sw->eval; 08859 }
| const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 8846 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().
08847 { 08848 return sw ? sw->name : NULL; 08849 }
| const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 8861 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().
08862 { 08863 return sw ? sw->registrar : NULL; 08864 }
| int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 8954 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().
08955 { 08956 return __ast_goto_if_exists(chan, context, exten, priority, 0); 08957 }
| 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 6694 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().
06695 { 06696 struct ast_context *con = ast_context_find(context); 06697 if (con) { 06698 struct ast_ignorepat *pat; 06699 for (pat = con->ignorepats; pat; pat = pat->next) { 06700 if (ast_extension_match(pat->pattern, pattern)) 06701 return 1; 06702 } 06703 } 06704 06705 return 0; 06706 }
| 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 3649 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().
03650 { 03651 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0); 03652 }
| 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 6054 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_context::registrar, and pbx_find_info::stacklen.
Referenced by lua_reload_extensions(), and pbx_load_module().
06055 { 06056 double ft; 06057 struct ast_context *tmp, *oldcontextslist; 06058 struct ast_hashtab *oldtable; 06059 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 06060 struct store_hint *this; 06061 struct ast_hint *hint; 06062 struct ast_exten *exten; 06063 int length; 06064 struct ast_state_cb *thiscb; 06065 struct ast_hashtab_iter *iter; 06066 06067 /* it is very important that this function hold the hint list lock _and_ the conlock 06068 during its operation; not only do we need to ensure that the list of contexts 06069 and extensions does not change, but also that no hint callbacks (watchers) are 06070 added or removed during the merge/delete process 06071 06072 in addition, the locks _must_ be taken in this order, because there are already 06073 other code paths that use this order 06074 */ 06075 06076 struct timeval begintime, writelocktime, endlocktime, enddeltime; 06077 int wrlock_ver; 06078 06079 begintime = ast_tvnow(); 06080 ast_rdlock_contexts(); 06081 iter = ast_hashtab_start_traversal(contexts_table); 06082 while ((tmp = ast_hashtab_next(iter))) { 06083 context_merge(extcontexts, exttable, tmp, registrar); 06084 } 06085 ast_hashtab_end_traversal(iter); 06086 wrlock_ver = ast_wrlock_contexts_version(); 06087 06088 ast_unlock_contexts(); /* this feels real retarded, but you must do 06089 what you must do If this isn't done, the following 06090 wrlock is a guraranteed deadlock */ 06091 ast_wrlock_contexts(); 06092 if (ast_wrlock_contexts_version() > wrlock_ver+1) { 06093 ast_log(LOG_WARNING,"==================!!!!!!!!!!!!!!!Something changed the contexts in the middle of merging contexts!\n"); 06094 } 06095 06096 AST_RWLIST_WRLOCK(&hints); 06097 writelocktime = ast_tvnow(); 06098 06099 /* preserve all watchers for hints associated with this registrar */ 06100 AST_RWLIST_TRAVERSE(&hints, hint, list) { 06101 if (!AST_LIST_EMPTY(&hint->callbacks) && !strcmp(registrar, hint->exten->parent->registrar)) { 06102 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 06103 if (!(this = ast_calloc(1, length))) 06104 continue; 06105 AST_LIST_APPEND_LIST(&this->callbacks, &hint->callbacks, entry); 06106 this->laststate = hint->laststate; 06107 this->context = this->data; 06108 strcpy(this->data, hint->exten->parent->name); 06109 this->exten = this->data + strlen(this->context) + 1; 06110 strcpy(this->exten, hint->exten->exten); 06111 AST_LIST_INSERT_HEAD(&store, this, list); 06112 } 06113 } 06114 06115 /* save the old table and list */ 06116 oldtable = contexts_table; 06117 oldcontextslist = contexts; 06118 06119 /* move in the new table and list */ 06120 contexts_table = exttable; 06121 contexts = *extcontexts; 06122 06123 /* restore the watchers for hints that can be found; notify those that 06124 cannot be restored 06125 */ 06126 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 06127 struct pbx_find_info q = { .stacklen = 0 }; 06128 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 06129 /* If this is a pattern, dynamically create a new extension for this 06130 * particular match. Note that this will only happen once for each 06131 * individual extension, because the pattern will no longer match first. 06132 */ 06133 if (exten && exten->exten[0] == '_') { 06134 ast_add_extension_nolock(exten->parent->name, 0, this->exten, PRIORITY_HINT, NULL, 06135 0, exten->app, ast_strdup(exten->data), ast_free_ptr, registrar); 06136 /* rwlocks are not recursive locks */ 06137 exten = ast_hint_extension_nolock(NULL, this->context, this->exten); 06138 } 06139 06140 /* Find the hint in the list of hints */ 06141 AST_RWLIST_TRAVERSE(&hints, hint, list) { 06142 if (hint->exten == exten) 06143 break; 06144 } 06145 if (!exten || !hint) { 06146 /* this hint has been removed, notify the watchers */ 06147 while ((thiscb = AST_LIST_REMOVE_HEAD(&this->callbacks, entry))) { 06148 thiscb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, thiscb->data); 06149 ast_free(thiscb); 06150 } 06151 } else { 06152 AST_LIST_APPEND_LIST(&hint->callbacks, &this->callbacks, entry); 06153 hint->laststate = this->laststate; 06154 } 06155 ast_free(this); 06156 } 06157 06158 AST_RWLIST_UNLOCK(&hints); 06159 ast_unlock_contexts(); 06160 endlocktime = ast_tvnow(); 06161 06162 /* the old list and hashtab no longer are relevant, delete them while the rest of asterisk 06163 is now freely using the new stuff instead */ 06164 06165 ast_hashtab_destroy(oldtable, NULL); 06166 06167 for (tmp = oldcontextslist; tmp; ) { 06168 struct ast_context *next; /* next starting point */ 06169 next = tmp->next; 06170 __ast_internal_context_destroy(tmp); 06171 tmp = next; 06172 } 06173 enddeltime = ast_tvnow(); 06174 06175 ft = ast_tvdiff_us(writelocktime, begintime); 06176 ft /= 1000000.0; 06177 ast_verb(3,"Time to scan old dialplan and merge leftovers back into the new: %8.6f sec\n", ft); 06178 06179 ft = ast_tvdiff_us(endlocktime, writelocktime); 06180 ft /= 1000000.0; 06181 ast_verb(3,"Time to restore hints and swap in new dialplan: %8.6f sec\n", ft); 06182 06183 ft = ast_tvdiff_us(enddeltime, endlocktime); 06184 ft /= 1000000.0; 06185 ast_verb(3,"Time to delete the old dialplan: %8.6f sec\n", ft); 06186 06187 ft = ast_tvdiff_us(enddeltime, begintime); 06188 ft /= 1000000.0; 06189 ast_verb(3,"Total time merge_contexts_delete: %8.6f sec\n", ft); 06190 return; 06191 }
| int ast_parseable_goto | ( | struct ast_channel * | chan, | |
| const char * | goto_string | |||
| ) |
Definition at line 9017 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().
09018 { 09019 return pbx_parseable_goto(chan, goto_string, 0); 09020 }
| 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 7530 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().
07531 { 07532 struct ast_channel *chan; 07533 struct app_tmp *tmp; 07534 int res = -1, cdr_res = -1; 07535 struct outgoing_helper oh; 07536 07537 memset(&oh, 0, sizeof(oh)); 07538 oh.vars = vars; 07539 oh.account = account; 07540 07541 if (locked_channel) 07542 *locked_channel = NULL; 07543 if (ast_strlen_zero(app)) { 07544 res = -1; 07545 goto outgoing_app_cleanup; 07546 } 07547 if (synchronous) { 07548 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 07549 if (chan) { 07550 ast_set_variables(chan, vars); 07551 if (account) 07552 ast_cdr_setaccount(chan, account); 07553 if (chan->_state == AST_STATE_UP) { 07554 res = 0; 07555 ast_verb(4, "Channel %s was answered.\n", chan->name); 07556 tmp = ast_calloc(1, sizeof(*tmp)); 07557 if (!tmp) 07558 res = -1; 07559 else { 07560 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 07561 if (appdata) 07562 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 07563 tmp->chan = chan; 07564 if (synchronous > 1) { 07565 if (locked_channel) 07566 ast_channel_unlock(chan); 07567 ast_pbx_run_app(tmp); 07568 } else { 07569 if (locked_channel) 07570 ast_channel_lock(chan); 07571 if (ast_pthread_create_detached(&tmp->t, NULL, ast_pbx_run_app, tmp)) { 07572 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 07573 ast_free(tmp); 07574 if (locked_channel) 07575 ast_channel_unlock(chan); 07576 ast_hangup(chan); 07577 res = -1; 07578 } else { 07579 if (locked_channel) 07580 *locked_channel = chan; 07581 } 07582 } 07583 } 07584 } else { 07585 ast_verb(4, "Channel %s was never answered.\n", chan->name); 07586 if (chan->cdr) { /* update the cdr */ 07587 /* here we update the status of the call, which sould be busy. 07588 * if that fails then we set the status to failed */ 07589 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 07590 ast_cdr_failed(chan->cdr); 07591 } 07592 ast_hangup(chan); 07593 } 07594 } 07595 07596 if (res < 0) { /* the call failed for some reason */ 07597 if (*reason == 0) { /* if the call failed (not busy or no answer) 07598 * update the cdr with the failed message */ 07599 cdr_res = ast_pbx_outgoing_cdr_failed(); 07600 if (cdr_res != 0) { 07601 res = cdr_res; 07602 goto outgoing_app_cleanup; 07603 } 07604 } 07605 } 07606 07607 } else { 07608 struct async_stat *as; 07609 if (!(as = ast_calloc(1, sizeof(*as)))) { 07610 res = -1; 07611 goto outgoing_app_cleanup; 07612 } 07613 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 07614 if (!chan) { 07615 ast_free(as); 07616 res = -1; 07617 goto outgoing_app_cleanup; 07618 } 07619 as->chan = chan; 07620 ast_copy_string(as->app, app, sizeof(as->app)); 07621 if (appdata) 07622 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 07623 as->timeout = timeout; 07624 ast_set_variables(chan, vars); 07625 if (account) 07626 ast_cdr_setaccount(chan, account); 07627 /* Start a new thread, and get something handling this channel. */ 07628 if (locked_channel) 07629 ast_channel_lock(chan); 07630 if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) { 07631 ast_log(LOG_WARNING, "Failed to start async wait\n"); 07632 ast_free(as); 07633 if (locked_channel) 07634 ast_channel_unlock(chan); 07635 ast_hangup(chan); 07636 res = -1; 07637 goto outgoing_app_cleanup; 07638 } else { 07639 if (locked_channel) 07640 *locked_channel = chan; 07641 } 07642 res = 0; 07643 } 07644 outgoing_app_cleanup: 07645 ast_variables_destroy(vars); 07646 return res; 07647 }
| 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 7364 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().
07365 { 07366 struct ast_channel *chan; 07367 struct async_stat *as; 07368 int res = -1, cdr_res = -1; 07369 struct outgoing_helper oh; 07370 07371 if (synchronous) { 07372 oh.context = context; 07373 oh.exten = exten; 07374 oh.priority = priority; 07375 oh.cid_num = cid_num; 07376 oh.cid_name = cid_name; 07377 oh.account = account; 07378 oh.vars = vars; 07379 oh.parent_channel = NULL; 07380 07381 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 07382 if (channel) { 07383 *channel = chan; 07384 if (chan) 07385 ast_channel_lock(chan); 07386 } 07387 if (chan) { 07388 if (chan->_state == AST_STATE_UP) { 07389 res = 0; 07390 ast_verb(4, "Channel %s was answered.\n", chan->name); 07391 07392 if (synchronous > 1) { 07393 if (channel) 07394 ast_channel_unlock(chan); 07395 if (ast_pbx_run(chan)) { 07396 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 07397 if (channel) 07398 *channel = NULL; 07399 ast_hangup(chan); 07400 chan = NULL; 07401 res = -1; 07402 } 07403 } else { 07404 if (ast_pbx_start(chan)) { 07405 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 07406 if (channel) { 07407 *channel = NULL; 07408 ast_channel_unlock(chan); 07409 } 07410 ast_hangup(chan); 07411 res = -1; 07412 } 07413 chan = NULL; 07414 } 07415 } else { 07416 ast_verb(4, "Channel %s was never answered.\n", chan->name); 07417 07418 if (chan->cdr) { /* update the cdr */ 07419 /* here we update the status of the call, which sould be busy. 07420 * if that fails then we set the status to failed */ 07421 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 07422 ast_cdr_failed(chan->cdr); 07423 } 07424 07425 if (channel) { 07426 *channel = NULL; 07427 ast_channel_unlock(chan); 07428 } 07429 ast_hangup(chan); 07430 chan = NULL; 07431 } 07432 } 07433 07434 if (res < 0) { /* the call failed for some reason */ 07435 if (*reason == 0) { /* if the call failed (not busy or no answer) 07436 * update the cdr with the failed message */ 07437 cdr_res = ast_pbx_outgoing_cdr_failed(); 07438 if (cdr_res != 0) { 07439 res = cdr_res; 07440 goto outgoing_exten_cleanup; 07441 } 07442 } 07443 07444 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 07445 /* check if "failed" exists */ 07446 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 07447 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 07448 if (chan) { 07449 char failed_reason[4] = ""; 07450 if (!ast_strlen_zero(context)) 07451 ast_copy_string(chan->context, context, sizeof(chan->context)); 07452 set_ext_pri(chan, "failed", 1); 07453 ast_set_variables(chan, vars); 07454 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 07455 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 07456 if (account) 07457 ast_cdr_setaccount(chan, account); 07458 if (ast_pbx_run(chan)) { 07459 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 07460 ast_hangup(chan); 07461 } 07462 chan = NULL; 07463 } 07464 } 07465 } 07466 } else { 07467 if (!(as = ast_calloc(1, sizeof(*as)))) { 07468 res = -1; 07469 goto outgoing_exten_cleanup; 07470 } 07471 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 07472 if (channel) { 07473 *channel = chan; 07474 if (chan) 07475 ast_channel_lock(chan); 07476 } 07477 if (!chan) { 07478 ast_free(as); 07479 res = -1; 07480 goto outgoing_exten_cleanup; 07481 } 07482 as->chan = chan; 07483 ast_copy_string(as->context, context, sizeof(as->context)); 07484 set_ext_pri(as->chan, exten, priority); 07485 as->timeout = timeout; 07486 ast_set_variables(chan, vars); 07487 if (account) 07488 ast_cdr_setaccount(chan, account); 07489 if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) { 07490 ast_log(LOG_WARNING, "Failed to start async wait\n"); 07491 ast_free(as); 07492 if (channel) { 07493 *channel = NULL; 07494 ast_channel_unlock(chan); 07495 } 07496 ast_hangup(chan); 07497 res = -1; 07498 goto outgoing_exten_cleanup; 07499 } 07500 res = 0; 07501 } 07502 outgoing_exten_cleanup: 07503 ast_variables_destroy(vars); 07504 return res; 07505 }
| 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 4077 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().
04078 { 04079 return ast_pbx_run_args(c, NULL); 04080 }
| 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 4062 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().
04063 { 04064 enum ast_pbx_result res = AST_PBX_SUCCESS; 04065 04066 if (increase_call_count(c)) { 04067 return AST_PBX_CALL_LIMIT; 04068 } 04069 04070 res = __ast_pbx_run(c, args); 04071 04072 decrease_call_count(); 04073 04074 return res; 04075 }
| 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 4040 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().
04041 { 04042 pthread_t t; 04043 04044 if (!c) { 04045 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 04046 return AST_PBX_FAILED; 04047 } 04048 04049 if (increase_call_count(c)) 04050 return AST_PBX_CALL_LIMIT; 04051 04052 /* Start a new thread, and get something handling this channel. */ 04053 if (ast_pthread_create_detached(&t, NULL, pbx_thread, c)) { 04054 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 04055 decrease_call_count(); 04056 return AST_PBX_FAILED; 04057 } 04058 04059 return AST_PBX_SUCCESS; 04060 }
| int ast_processed_calls | ( | void | ) |
Retrieve the total number of calls processed through the PBX since last restart.
Definition at line 4087 of file pbx.c.
Referenced by handle_chanlist(), and handle_showcalls().
04088 { 04089 return totalcalls; 04090 }
| 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 8755 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().
08756 { 08757 return ast_rwlock_rdlock(&con->lock); 08758 }
| int ast_rdlock_contexts | ( | void | ) |
Read locks the context list.
| 0 | on success | |
| -1 | on error |
Definition at line 8737 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().
08738 { 08739 return ast_rwlock_rdlock(&conlock); 08740 }
| 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 4592 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().
04593 { 04594 struct ast_switch *tmp; 04595 04596 AST_RWLIST_WRLOCK(&switches); 04597 AST_RWLIST_TRAVERSE(&switches, tmp, list) { 04598 if (!strcasecmp(tmp->name, sw->name)) { 04599 AST_RWLIST_UNLOCK(&switches); 04600 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 04601 return -1; 04602 } 04603 } 04604 AST_RWLIST_INSERT_TAIL(&switches, sw, list); 04605 AST_RWLIST_UNLOCK(&switches); 04606 04607 return 0; 04608 }
| 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 3654 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().
03655 { 03656 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn); 03657 }
| 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 8760 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().
08761 { 08762 return ast_rwlock_unlock(&con->lock); 08763 }
| int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
| 0 | on success | |
| -1 | on failure |
Definition at line 8742 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().
08743 { 08744 return ast_rwlock_unlock(&conlock); 08745 }
| void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
| sw | switch to unregister |
Unregisters a switch from asterisk.
Definition at line 4610 of file pbx.c.
References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.
Referenced by __unload_module(), and unload_module().
04611 { 04612 AST_RWLIST_WRLOCK(&switches); 04613 AST_RWLIST_REMOVE(&switches, sw, list); 04614 AST_RWLIST_UNLOCK(&switches); 04615 }
| struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
| struct ast_exten * | priority | |||
| ) | [read] |
Definition at line 8874 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 8907 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().
08909 { 08910 if (!ip) 08911 return con ? con->ignorepats : NULL; 08912 else 08913 return ip->next; 08914 }
| struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
| struct ast_include * | inc | |||
| ) | [read] |
Definition at line 8898 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 8883 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().
08885 { 08886 if (!sw) 08887 return con ? AST_LIST_FIRST(&con->alts) : NULL; 08888 else 08889 return AST_LIST_NEXT(sw, list); 08890 }
| struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) | [read] |
Definition at line 8869 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 8892 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().
08894 { 08895 return priority ? priority->peer : exten; 08896 }
| 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 8750 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().
08751 { 08752 return ast_rwlock_wrlock(&con->lock); 08753 }
| int ast_wrlock_contexts | ( | void | ) |
Write locks the context list.
| 0 | on success | |
| -1 | on error |
Definition at line 8729 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().
08730 { 08731 int res = ast_rwlock_wrlock(&conlock); 08732 if (!res) 08733 ast_atomic_fetchadd_int(&conlock_wrlock_version, 1); 08734 return res; 08735 }
| int ast_wrlock_contexts_version | ( | void | ) |
Definition at line 8721 of file pbx.c.
References conlock_wrlock_version.
Referenced by ast_merge_contexts_and_delete().
08722 { 08723 return conlock_wrlock_version; 08724 }
| void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 8566 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().
08567 { 08568 struct ast_var_t *vardata; 08569 08570 ast_rwlock_wrlock(&globalslock); 08571 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 08572 ast_var_delete(vardata); 08573 ast_rwlock_unlock(&globalslock); 08574 }
| 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 8336 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(), 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().
08337 { 08338 struct ast_var_t *variables; 08339 const char *ret = NULL; 08340 int i; 08341 struct varshead *places[2] = { NULL, &globals }; 08342 08343 if (!name) 08344 return NULL; 08345 08346 if (chan) { 08347 ast_channel_lock(chan); 08348 places[0] = &chan->varshead; 08349 } 08350 08351 for (i = 0; i < 2; i++) { 08352 if (!places[i]) 08353 continue; 08354 if (places[i] == &globals) 08355 ast_rwlock_rdlock(&globalslock); 08356 AST_LIST_TRAVERSE(places[i], variables, entries) { 08357 if (!strcmp(name, ast_var_name(variables))) { 08358 ret = ast_var_value(variables); 08359 break; 08360 } 08361 } 08362 if (places[i] == &globals) 08363 ast_rwlock_unlock(&globalslock); 08364 if (ret) 08365 break; 08366 } 08367 08368 if (chan) 08369 ast_channel_unlock(chan); 08370 08371 return ret; 08372 }
| void pbx_builtin_pushvar_helper | ( | struct ast_channel * | chan, | |
| const char * | name, | |||
| const char * | value | |||
| ) |
Definition at line 8374 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().
08375 { 08376 struct ast_var_t *newvariable; 08377 struct varshead *headp; 08378 08379 if (name[strlen(name)-1] == ')') { 08380 char *function = ast_strdupa(name); 08381 08382 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 08383 ast_func_write(chan, function, value); 08384 return; 08385 } 08386 08387 if (chan) { 08388 ast_channel_lock(chan); 08389 headp = &chan->varshead; 08390 } else { 08391 ast_rwlock_wrlock(&globalslock); 08392 headp = &globals; 08393 } 08394 08395 if (value) { 08396 if (headp == &globals) 08397 ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value); 08398 newvariable = ast_var_assign(name, value); 08399 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 08400 } 08401 08402 if (chan) 08403 ast_channel_unlock(chan); 08404 else 08405 ast_rwlock_unlock(&globalslock); 08406 }
| int pbx_builtin_raise_exception | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) |
Definition at line 2579 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().
02580 { 02581 const char *reason = vreason; 02582 struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL); 02583 struct pbx_exception *exception = NULL; 02584 02585 if (!ds) { 02586 ds = ast_datastore_alloc(&exception_store_info, NULL); 02587 if (!ds) 02588 return -1; 02589 exception = ast_calloc(1, sizeof(struct pbx_exception)); 02590 if (!exception) { 02591 ast_datastore_free(ds); 02592 return -1; 02593 } 02594 if (ast_string_field_init(exception, 128)) { 02595 ast_free(exception); 02596 ast_datastore_free(ds); 02597 return -1; 02598 } 02599 ds->data = exception; 02600 ast_channel_datastore_add(chan, ds); 02601 } else 02602 exception = ds->data; 02603 02604 ast_string_field_set(exception, reason, reason); 02605 ast_string_field_set(exception, context, chan->context); 02606 ast_string_field_set(exception, exten, chan->exten); 02607 exception->priority = chan->priority; 02608 set_ext_pri(chan, "e", 0); 02609 return 0; 02610 }
| int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
| struct ast_str ** | buf | |||
| ) |
Definition at line 8304 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().
08305 { 08306 struct ast_var_t *variables; 08307 const char *var, *val; 08308 int total = 0; 08309 08310 if (!chan) 08311 return 0; 08312 08313 (*buf)->used = 0; 08314 (*buf)->str[0] = '\0'; 08315 08316 ast_channel_lock(chan); 08317 08318 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 08319 if ((var = ast_var_name(variables)) && (val = ast_var_value(variables)) 08320 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 08321 ) { 08322 if (ast_str_append(buf, 0, "%s=%s\n", var, val) < 0) { 08323 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 08324 break; 08325 } else 08326 total++; 08327 } else 08328 break; 08329 } 08330 08331 ast_channel_unlock(chan); 08332 08333 return total; 08334 }
| int pbx_builtin_setvar | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) |
Definition at line 8465 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().
08466 { 08467 char *name, *value, *mydata; 08468 08469 if (ast_compat_app_set) { 08470 return pbx_builtin_setvar_multiple(chan, data); 08471 } 08472 08473 if (ast_strlen_zero(data)) { 08474 ast_log(LOG_WARNING, "Set requires one variable name/value pair.\n"); 08475 return 0; 08476 } 08477 08478 mydata = ast_strdupa(data); 08479 name = strsep(&mydata, "="); 08480 value = mydata; 08481 if (strchr(name, ' ')) 08482 ast_log(LOG_WARNING, "Please avoid unnecessary spaces on variables as it may lead to unexpected results ('%s' set to '%s').\n", name, mydata); 08483 08484 pbx_builtin_setvar_helper(chan, name, value); 08485 return(0); 08486 }
| void pbx_builtin_setvar_helper | ( | struct ast_channel * | chan, | |
| const char * | name, | |||
| const char * | value | |||
| ) |
Definition at line 8408 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(), 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().
08409 { 08410 struct ast_var_t *newvariable; 08411 struct varshead *headp; 08412 const char *nametail = name; 08413 08414 if (name[strlen(name) - 1] == ')') { 08415 char *function = ast_strdupa(name); 08416 08417 ast_func_write(chan, function, value); 08418 return; 08419 } 08420 08421 if (chan) { 08422 ast_channel_lock(chan); 08423 headp = &chan->varshead; 08424 } else { 08425 ast_rwlock_wrlock(&globalslock); 08426 headp = &globals; 08427 } 08428 08429 /* For comparison purposes, we have to strip leading underscores */ 08430 if (*nametail == '_') { 08431 nametail++; 08432 if (*nametail == '_') 08433 nametail++; 08434 } 08435 08436 AST_LIST_TRAVERSE (headp, newvariable, entries) { 08437 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 08438 /* there is already such a variable, delete it */ 08439 AST_LIST_REMOVE(headp, newvariable, entries); 08440 ast_var_delete(newvariable); 08441 break; 08442 } 08443 } 08444 08445 if (value) { 08446 if (headp == &globals) 08447 ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value); 08448 newvariable = ast_var_assign(name, value); 08449 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 08450 manager_event(EVENT_FLAG_DIALPLAN, "VarSet", 08451 "Channel: %s\r\n" 08452 "Variable: %s\r\n" 08453 "Value: %s\r\n" 08454 "Uniqueid: %s\r\n", 08455 chan ? chan->name : "none", name, value, 08456 chan ? chan->uniqueid : "none"); 08457 } 08458 08459 if (chan) 08460 ast_channel_unlock(chan); 08461 else 08462 ast_rwlock_unlock(&globalslock); 08463 }
| int pbx_builtin_setvar_multiple | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) |
Definition at line 8488 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().
08489 { 08490 char *data; 08491 int x; 08492 AST_DECLARE_APP_ARGS(args, 08493 AST_APP_ARG(pair)[24]; 08494 ); 08495 AST_DECLARE_APP_ARGS(pair, 08496 AST_APP_ARG(name); 08497 AST_APP_ARG(value); 08498 ); 08499 08500 if (ast_strlen_zero(vdata)) { 08501 ast_log(LOG_WARNING, "MSet requires at least one variable name/value pair.\n"); 08502 return 0; 08503 } 08504 08505 data = ast_strdupa(vdata); 08506 AST_STANDARD_APP_ARGS(args, data); 08507 08508 for (x = 0; x < args.argc; x++) { 08509 AST_NONSTANDARD_APP_ARGS(pair, args.pair[x], '='); 08510 if (pair.argc == 2) { 08511 pbx_builtin_setvar_helper(chan, pair.name, pair.value); 08512 if (strchr(pair.name, ' ')) 08513 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); 08514 } else if (!chan) { 08515 ast_log(LOG_WARNING, "MSet: ignoring entry '%s' with no '='\n", pair.name); 08516 } else { 08517 ast_log(LOG_WARNING, "MSet: ignoring entry '%s' with no '=' (in %s@%s:%d\n", pair.name, chan->exten, chan->context, chan->priority); 08518 } 08519 } 08520 08521 return 0; 08522 }
| 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 8576 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().
08577 { 08578 int res; 08579 if (ast_strlen_zero(condition)) { /* NULL or empty strings are false */ 08580 return 0; 08581 } else if (sscanf(condition, "%30d", &res) == 1) { /* Numbers are evaluated for truth */ 08582 return res; 08583 } else { /* Strings are true */ 08584 return 1; 08585 } 08586 }
| 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_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, ',')) { 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 2052 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().
02056 { 02057 int x, res; 02058 struct ast_context *tmp = NULL; 02059 struct ast_exten *e = NULL, *eroot = NULL; 02060 struct ast_include *i = NULL; 02061 struct ast_sw *sw = NULL; 02062 struct ast_exten pattern = {NULL, }; 02063 struct scoreboard score = {0, }; 02064 struct ast_str *tmpdata = NULL; 02065 02066 pattern.label = label; 02067 pattern.priority = priority; 02068 #ifdef NEED_DEBUG_HERE 02069 ast_log(LOG_NOTICE,"Looking for cont/ext/prio/label/action = %s/%s/%d/%s/%d\n", context, exten, priority, label, (int)action); 02070 #endif 02071 02072 /* Initialize status if appropriate */ 02073 if (q->stacklen == 0) { 02074 q->status = STATUS_NO_CONTEXT; 02075 q->swo = NULL; 02076 q->data = NULL; 02077 q->foundcontext = NULL; 02078 } else if (q->stacklen >= AST_PBX_MAX_STACK) { 02079 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n"); 02080 return NULL; 02081 } 02082 02083 /* Check first to see if we've already been checked */ 02084 for (x = 0; x < q->stacklen; x++) { 02085 if (!strcasecmp(q->incstack[x], context)) 02086 return NULL; 02087 } 02088 02089 if (bypass) /* bypass means we only look there */ 02090 tmp = bypass; 02091 else { /* look in contexts */ 02092 struct fake_context item; 02093 02094 ast_copy_string(item.name, context, sizeof(item.name)); 02095 02096 tmp = ast_hashtab_lookup(contexts_table, &item); 02097 #ifdef NOTNOW 02098 tmp = NULL; 02099 while ((tmp = ast_walk_contexts(tmp)) ) { 02100 if (!strcmp(tmp->name, context)) 02101 break; 02102 } 02103 #endif 02104 if (!tmp) 02105 return NULL; 02106 02107 } 02108 02109 if (q->status < STATUS_NO_EXTENSION) 02110 q->status = STATUS_NO_EXTENSION; 02111 02112 /* Do a search for matching extension */ 02113 02114 eroot = NULL; 02115 score.total_specificity = 0; 02116 score.exten = 0; 02117 score.total_length = 0; 02118 if (!tmp->pattern_tree && tmp->root_table) 02119 { 02120 create_match_char_tree(tmp); 02121 #ifdef NEED_DEBUG 02122 ast_log(LOG_DEBUG,"Tree Created in context %s:\n", context); 02123 log_match_char_tree(tmp->pattern_tree," "); 02124 #endif 02125 } 02126 #ifdef NEED_DEBUG 02127 ast_log(LOG_NOTICE,"The Trie we are searching in:\n"); 02128 log_match_char_tree(tmp->pattern_tree, ":: "); 02129 #endif 02130 02131 do { 02132 if (!ast_strlen_zero(overrideswitch)) { 02133 char *osw = ast_strdupa(overrideswitch), *name; 02134 struct ast_switch *asw; 02135 ast_switch_f *aswf = NULL; 02136 char *datap; 02137 int eval = 0; 02138 02139 name = strsep(&osw, "/"); 02140 asw = pbx_findswitch(name); 02141 02142 if (!asw) { 02143 ast_log(LOG_WARNING, "No such switch '%s'\n", name); 02144 break; 02145 } 02146 02147 if (osw && strchr(osw, '$')) { 02148 eval = 1; 02149 } 02150 02151 if (eval && !(tmpdata = ast_str_thread_get(&switch_data, 512))) { 02152 ast_log(LOG_WARNING, "Can't evaluate overrideswitch?!"); 02153 break; 02154 } else if (eval) { 02155 /* Substitute variables now */ 02156 pbx_substitute_variables_helper(chan, osw, tmpdata->str, tmpdata->len); 02157 datap = tmpdata->str; 02158 } else { 02159 datap = osw; 02160 } 02161 02162 /* equivalent of extension_match_core() at the switch level */ 02163 if (action == E_CANMATCH) 02164 aswf = asw->canmatch; 02165 else if (action == E_MATCHMORE) 02166 aswf = asw->matchmore; 02167 else /* action == E_MATCH */ 02168 aswf = asw->exists; 02169 if (!aswf) { 02170 res = 0; 02171 } else { 02172 if (chan) { 02173 ast_autoservice_start(chan); 02174 } 02175 res = aswf(chan, context, exten, priority, callerid, datap); 02176 if (chan) { 02177 ast_autoservice_stop(chan); 02178 } 02179 } 02180 if (res) { /* Got a match */ 02181 q->swo = asw; 02182 q->data = datap; 02183 q->foundcontext = context; 02184 /* XXX keep status = STATUS_NO_CONTEXT ? */ 02185 return NULL; 02186 } 02187 } 02188 } while (0); 02189 02190 if (extenpatternmatchnew) { 02191 new_find_extension(exten, &score, tmp->pattern_tree, 0, 0, callerid, label, action); 02192 eroot = score.exten; 02193 02194 if (score.last_char == '!' && action == E_MATCHMORE) { 02195 /* We match an extension ending in '!'. 02196 * The decision in this case is final and is NULL (no match). 02197 */ 02198 #ifdef NEED_DEBUG_HERE 02199 ast_log(LOG_NOTICE,"Returning MATCHMORE NULL with exclamation point.\n"); 02200 #endif 02201 return NULL; 02202 } 02203 02204 if (!eroot && (action == E_CANMATCH || action == E_MATCHMORE) && score.canmatch_exten) { 02205 q->status = STATUS_SUCCESS; 02206 #ifdef NEED_DEBUG_HERE 02207 ast_log(LOG_NOTICE,"Returning CANMATCH exten %s\n", score.canmatch_exten->exten); 02208 #endif 02209 return score.canmatch_exten; 02210 } 02211 02212 if ((action == E_MATCHMORE || action == E_CANMATCH) && eroot) { 02213 if (score.node) { 02214 struct ast_exten *z = trie_find_next_match(score.node); 02215 if (z) { 02216 #ifdef NEED_DEBUG_HERE 02217 ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten %s\n", z->exten); 02218 #endif 02219 } else { 02220 if (score.canmatch_exten) { 02221 #ifdef NEED_DEBUG_HERE 02222 ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE canmatchmatch exten %s(%p)\n", score.canmatch_exten->exten, score.canmatch_exten); 02223 #endif 02224 return score.canmatch_exten; 02225 } else { 02226 #ifdef NEED_DEBUG_HERE 02227 ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten NULL\n"); 02228 #endif 02229 } 02230 } 02231 return z; 02232 } 02233 #ifdef NEED_DEBUG_HERE 02234 ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE NULL (no next_match)\n"); 02235 #endif 02236 return NULL; /* according to the code, complete matches are null matches in MATCHMORE mode */ 02237 } 02238 02239 if (eroot) { 02240 /* found entry, now look for the right priority */ 02241 if (q->status < STATUS_NO_PRIORITY) 02242 q->status = STATUS_NO_PRIORITY; 02243 e = NULL; 02244 if (action == E_FINDLABEL && label ) { 02245 if (q->status < STATUS_NO_LABEL) 02246 q->status = STATUS_NO_LABEL; 02247 e = ast_hashtab_lookup(eroot->peer_label_table, &pattern); 02248 } else { 02249 e = ast_hashtab_lookup(eroot->peer_table, &pattern); 02250 } 02251 if (e) { /* found a valid match */ 02252 q->status = STATUS_SUCCESS; 02253 q->foundcontext = context; 02254 #ifdef NEED_DEBUG_HERE 02255 ast_log(LOG_NOTICE,"Returning complete match of exten %s\n", e->exten); 02256 #endif 02257 return e; 02258 } 02259 } 02260 } else { /* the old/current default exten pattern match algorithm */ 02261 02262 /* scan the list trying to match extension and CID */ 02263 eroot = NULL; 02264 while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) { 02265 int match = extension_match_core(eroot->exten, exten, action); 02266 /* 0 on fail, 1 on match, 2 on earlymatch */ 02267 02268 if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid))) 02269 continue; /* keep trying */ 02270 if (match == 2 && action == E_MATCHMORE) { 02271 /* We match an extension ending in '!'. 02272 * The decision in this case is final and is NULL (no match). 02273 */ 02274 return NULL; 02275 } 02276 /* found entry, now look for the right priority */ 02277 if (q->status < STATUS_NO_PRIORITY) 02278 q->status = STATUS_NO_PRIORITY; 02279 e = NULL; 02280 if (action == E_FINDLABEL && label ) { 02281 if (q->status < STATUS_NO_LABEL) 02282 q->status = STATUS_NO_LABEL; 02283 e = ast_hashtab_lookup(eroot->peer_label_table, &pattern); 02284 } else { 02285 e = ast_hashtab_lookup(eroot->peer_table, &pattern); 02286 } 02287 #ifdef NOTNOW 02288 while ( (e = ast_walk_extension_priorities(eroot, e)) ) { 02289 /* Match label or priority */ 02290 if (action == E_FINDLABEL) { 02291 if (q->status < STATUS_NO_LABEL) 02292 q->status = STATUS_NO_LABEL; 02293 if (label && e->label && !strcmp(label, e->label)) 02294 break; /* found it */ 02295 } else if (e->priority == priority) { 02296 break; /* found it */ 02297 } /* else keep searching */ 02298 } 02299 #endif 02300 if (e) { /* found a valid match */ 02301 q->status = STATUS_SUCCESS; 02302 q->foundcontext = context; 02303 return e; 02304 } 02305 } 02306 } 02307 02308 02309 /* Check alternative switches */ 02310 AST_LIST_TRAVERSE(&tmp->alts, sw, list) { 02311 struct ast_switch *asw = pbx_findswitch(sw->name); 02312 ast_switch_f *aswf = NULL; 02313 char *datap; 02314 02315 if (!asw) { 02316 ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name); 02317 continue; 02318 } 02319 /* Substitute variables now */ 02320 02321 if (sw->eval) { 02322 if (!(tmpdata = ast_str_thread_get(&switch_data, 512))) { 02323 ast_log(LOG_WARNING, "Can't evaluate switch?!"); 02324 continue; 02325 } 02326 pbx_substitute_variables_helper(chan, sw->data, tmpdata->str, tmpdata->len); 02327 } 02328 02329 /* equivalent of extension_match_core() at the switch level */ 02330 if (action == E_CANMATCH) 02331 aswf = asw->canmatch; 02332 else if (action == E_MATCHMORE) 02333 aswf = asw->matchmore; 02334 else /* action == E_MATCH */ 02335 aswf = asw->exists; 02336 datap = sw->eval ? tmpdata->str : sw->data; 02337 if (!aswf) 02338 res = 0; 02339 else { 02340 if (chan) 02341 ast_autoservice_start(chan); 02342 res = aswf(chan, context, exten, priority, callerid, datap); 02343 if (chan) 02344 ast_autoservice_stop(chan); 02345 } 02346 if (res) { /* Got a match */ 02347 q->swo = asw; 02348 q->data = datap; 02349 q->foundcontext = context; 02350 /* XXX keep status = STATUS_NO_CONTEXT ? */ 02351 return NULL; 02352 } 02353 } 02354 q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */ 02355 /* Now try any includes we have in this context */ 02356 for (i = tmp->includes; i; i = i->next) { 02357 if (include_valid(i)) { 02358 if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action))) { 02359 #ifdef NEED_DEBUG_HERE 02360 ast_log(LOG_NOTICE,"Returning recursive match of %s\n", e->exten); 02361 #endif 02362 return e; 02363 } 02364 if (q->swo) 02365 return NULL; 02366 } 02367 } 02368 return NULL; 02369 }
| 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 2451 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().
02452 { 02453 const char not_found = '\0'; 02454 char *tmpvar; 02455 const char *s; /* the result */ 02456 int offset, length; 02457 int i, need_substring; 02458 struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */ 02459 02460 if (c) { 02461 ast_channel_lock(c); 02462 places[0] = &c->varshead; 02463 } 02464 /* 02465 * Make a copy of var because parse_variable_name() modifies the string. 02466 * Then if called directly, we might need to run substring() on the result; 02467 * remember this for later in 'need_substring', 'offset' and 'length' 02468 */ 02469 tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */ 02470 need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */); 02471 02472 /* 02473 * Look first into predefined variables, then into variable lists. 02474 * Variable 's' points to the result, according to the following rules: 02475 * s == ¬_found (set at the beginning) means that we did not find a 02476 * matching variable and need to look into more places. 02477 * If s != ¬_found, s is a valid result string as follows: 02478 * s = NULL if the variable does not have a value; 02479 * you typically do this when looking for an unset predefined variable. 02480 * s = workspace if the result has been assembled there; 02481 * typically done when the result is built e.g. with an snprintf(), 02482 * so we don't need to do an additional copy. 02483 * s != workspace in case we have a string, that needs to be copied 02484 * (the ast_copy_string is done once for all at the end). 02485 * Typically done when the result is already available in some string. 02486 */ 02487 s = ¬_found; /* default value */ 02488 if (c) { /* This group requires a valid channel */ 02489 /* Names with common parts are looked up a piece at a time using strncmp. */ 02490 if (!strncmp(var, "CALL", 4)) { 02491 if (!strncmp(var + 4, "ING", 3)) { 02492 if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */ 02493 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 02494 s = workspace; 02495 } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */ 02496 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 02497 s = workspace; 02498 } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */ 02499 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 02500 s = workspace; 02501 } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */ 02502 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 02503 s = workspace; 02504 } 02505 } 02506 } else if (!strcmp(var, "HINT")) { 02507 s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL; 02508 } else if (!strcmp(var, "HINTNAME")) { 02509 s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL; 02510 } else if (!strcmp(var, "EXTEN")) { 02511 s = c->exten; 02512 } else if (!strcmp(var, "CONTEXT")) { 02513 s = c->context; 02514 } else if (!strcmp(var, "PRIORITY")) { 02515 snprintf(workspace, workspacelen, "%d", c->priority); 02516 s = workspace; 02517 } else if (!strcmp(var, "CHANNEL")) { 02518 s = c->name; 02519 } else if (!strcmp(var, "UNIQUEID")) { 02520 s = c->uniqueid; 02521 } else if (!strcmp(var, "HANGUPCAUSE")) { 02522 snprintf(workspace, workspacelen, "%d", c->hangupcause); 02523 s = workspace; 02524 } 02525 } 02526 if (s == ¬_found) { /* look for more */ 02527 if (!strcmp(var, "EPOCH")) { 02528 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 02529 s = workspace; 02530 } else if (!strcmp(var, "SYSTEMNAME")) { 02531 s = ast_config_AST_SYSTEM_NAME; 02532 } else if (!strcmp(var, "ENTITYID")) { 02533 ast_eid_to_str(workspace, workspacelen, &ast_eid_default); 02534 s = workspace; 02535 } 02536 } 02537 /* if not found, look into chanvars or global vars */ 02538 for (i = 0; s == ¬_found && i < ARRAY_LEN(places); i++) { 02539 struct ast_var_t *variables; 02540 if (!places[i]) 02541 continue; 02542 if (places[i] == &globals) 02543 ast_rwlock_rdlock(&globalslock); 02544 AST_LIST_TRAVERSE(places[i], variables, entries) { 02545 if (!strcasecmp(ast_var_name(variables), var)) { 02546 s = ast_var_value(variables); 02547 break; 02548 } 02549 } 02550 if (places[i] == &globals) 02551 ast_rwlock_unlock(&globalslock); 02552 } 02553 if (s == ¬_found || s == NULL) 02554 *ret = NULL; 02555 else { 02556 if (s != workspace) 02557 ast_copy_string(workspace, s, workspacelen); 02558 *ret = workspace; 02559 if (need_substring) 02560 *ret = substring(*ret, offset, length, workspace, workspacelen); 02561 } 02562 02563 if (c) 02564 ast_channel_unlock(c); 02565 }
| 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 4092 of file pbx.c.
Referenced by pbx_load_module().
04093 { 04094 int oldval = autofallthrough; 04095 autofallthrough = newval; 04096 return oldval; 04097 }
| 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 4099 of file pbx.c.
Referenced by handle_set_extenpatternmatchnew(), handle_unset_extenpatternmatchnew(), and pbx_load_module().
04100 { 04101 int oldval = extenpatternmatchnew; 04102 extenpatternmatchnew = newval; 04103 return oldval; 04104 }
| 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 4106 of file pbx.c.
References ast_free, ast_strdup, and ast_strlen_zero().
Referenced by pbx_load_module().
04107 { 04108 if (overrideswitch) { 04109 ast_free(overrideswitch); 04110 } 04111 if (!ast_strlen_zero(newval)) { 04112 overrideswitch = ast_strdup(newval); 04113 } else { 04114 overrideswitch = NULL; 04115 } 04116 }
| void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
| const char * | cp1, | |||
| char * | cp2, | |||
| int | count | |||
| ) |
Definition at line 3092 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().
03093 { 03094 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 03095 }
| void pbx_substitute_variables_varshead | ( | struct varshead * | headp, | |
| const char * | cp1, | |||
| char * | cp2, | |||
| int | count | |||
| ) |
Definition at line 3097 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().
03098 { 03099 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 03100 }
1.6.1