#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/linkedlists.h"
#include "asterisk/devicestate.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_switch |
struct | ast_timing |
Defines | |
#define | AST_MAX_APP 32 |
#define | AST_PBX_KEEP 0 |
#define | AST_PBX_KEEPALIVE 10 |
Special return values from applications to the PBX {. | |
#define | AST_PBX_REPLACE 1 |
#define | PRIORITY_HINT -1 |
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 } |
Functions | |
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_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). | |
ast_context * | ast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar) |
Register a new context. | |
void | ast_context_destroy (struct ast_context *con, const char *registrar) |
Destroy a context (matches the specified context (or ANY context if NULL). | |
ast_context * | ast_context_find (const char *name) |
Find a context. | |
ast_context * | ast_context_find_or_create (struct ast_context **extcontexts, const char *name, const char *registrar) |
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) |
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 | ast_context_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
int | ast_context_remove_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar) |
int | ast_context_remove_include (const char *context, const char *include, const char *registrar) |
Remove a context include. | |
int | ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar) |
Removes an include by an ast_context structure. | |
int | ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar) |
Remove a switch. | |
int | ast_context_remove_switch2 (struct ast_context *con, const char *sw, const char *data, const char *registrar) |
This function locks given context, removes switch, unlock context and return. | |
int | ast_context_unlockmacro (const char *macrocontext) |
Unlocks the macrolock in the given context. | |
int | ast_context_verify_includes (struct ast_context *con) |
Verifies includes in an ast_contect structure. | |
ast_custom_function * | ast_custom_function_find (const char *name) |
int | ast_custom_function_register (struct ast_custom_function *acf) |
Reigster a custom function. | |
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_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, char *function, char *workspace, size_t len) |
executes a read operation on a function | |
int | ast_func_write (struct ast_channel *chan, char *function, const char *value) |
executes a write operation on a function | |
const char * | ast_get_context_name (struct ast_context *con) |
const char * | ast_get_context_registrar (struct ast_context *c) |
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) |
ast_context * | ast_get_extension_context (struct ast_exten *exten) |
const char * | ast_get_extension_label (struct ast_exten *e) |
int | ast_get_extension_matchcid (struct ast_exten *e) |
const char * | ast_get_extension_name (struct ast_exten *exten) |
int | ast_get_extension_priority (struct ast_exten *exten) |
const char * | ast_get_extension_registrar (struct ast_exten *e) |
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 exists, return non-zero. | |
const char * | ast_get_ignorepat_name (struct ast_ignorepat *ip) |
const char * | ast_get_ignorepat_registrar (struct ast_ignorepat *ip) |
const char * | ast_get_include_name (struct ast_include *include) |
const char * | ast_get_include_registrar (struct ast_include *i) |
const char * | ast_get_switch_data (struct ast_sw *sw) |
const char * | ast_get_switch_name (struct ast_sw *sw) |
const char * | ast_get_switch_registrar (struct ast_sw *sw) |
int | ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
void | ast_hint_state_changed (const char *device) |
int | ast_ignore_pattern (const char *context, const char *pattern) |
Checks to see if a number should be ignored. | |
int | ast_lock_context (struct ast_context *con) |
Locks a given context. | |
int | ast_lock_contexts (void) |
Locks the context list. | |
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, 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_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_contexts (void) |
int | ast_register_application (const char *app, int(*execute)(struct ast_channel *, void *), const char *synopsis, const char *description) |
Register an application. | |
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) |
Launch a new extension (i.e. new stack). | |
int | ast_unlock_context (struct ast_context *con) |
int | ast_unlock_contexts (void) |
Unlocks contexts. | |
int | ast_unregister_application (const char *app) |
Unregister an application. | |
void | ast_unregister_switch (struct ast_switch *sw) |
Unregister an alternative switch. | |
ast_exten * | ast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority) |
ast_ignorepat * | ast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip) |
ast_include * | ast_walk_context_includes (struct ast_context *con, struct ast_include *inc) |
ast_sw * | ast_walk_context_switches (struct ast_context *con, struct ast_sw *sw) |
ast_context * | ast_walk_contexts (struct ast_context *con) |
ast_exten * | ast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority) |
int | ast_wrlock_contexts (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_serialize_variables (struct ast_channel *chan, char *buf, size_t size) |
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_checkcondition (const char *condition) |
Evaluate a condition. | |
int | pbx_exec (struct ast_channel *c, struct ast_app *app, void *data) |
Execute an application. | |
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) |
pbx_retrieve_variable: Support for Asterisk built-in variables --- | |
int | pbx_set_autofallthrough (int newval) |
void | pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count) |
void | pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count) |
Definition in file pbx.h.
#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_application_deprecated(), handle_show_function(), and handle_show_function_deprecated().
#define AST_PBX_KEEPALIVE 10 |
Special return values from applications to the PBX {.
Destroy the thread, but don't hang up the channel
Definition at line 41 of file pbx.h.
Referenced by __ast_pbx_run(), _macro_exec(), agi_handle_command(), and run_agi().
#define PRIORITY_HINT -1 |
} Special Priority for a hint
Definition at line 44 of file pbx.h.
Referenced by add_extensions(), add_pri(), ast_add_extension2(), ast_hint_extension(), ast_merge_contexts_and_delete(), destroy_exten(), destroy_station(), handle_context_add_extension(), handle_context_add_extension_deprecated(), handle_context_remove_extension(), handle_context_remove_extension_deprecated(), handle_save_dialplan(), park_add_hints(), pbx_load_config(), and print_ext().
typedef int(*) ast_state_cb_type(char *context, char *id, enum ast_extension_states state, void *data) |
typedef int( ast_switch_f)(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
enum ast_extension_states |
Extension states.
Definition at line 47 of file pbx.h.
00047 { 00048 AST_EXTENSION_REMOVED = -2, /*!< Extension removed */ 00049 AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */ 00050 AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */ 00051 AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */ 00052 AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */ 00053 AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */ 00054 AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */ 00055 AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */ 00056 };
enum ast_pbx_result |
Definition at line 214 of file pbx.h.
00214 { 00215 AST_PBX_SUCCESS = 0, 00216 AST_PBX_FAILED = -1, 00217 AST_PBX_CALL_LIMIT = -2, 00218 };
int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 2675 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02676 { 02677 return countcalls; 02678 }
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 4596 of file pbx.c.
References ast_add_extension2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_context_add_extension(), handle_context_add_extension_deprecated(), park_add_hints(), and register_peer_exten().
04599 { 04600 int ret = -1; 04601 struct ast_context *c = find_context_locked(context); 04602 04603 if (c) { 04604 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04605 application, data, datad, registrar); 04606 ast_unlock_contexts(); 04607 } 04608 return ret; 04609 }
int ast_add_extension2 | ( | struct ast_context * | con, | |
int | replace, | |||
const char * | extension, | |||
int | priority, | |||
const char * | label, | |||
const char * | callerid, | |||
const char * | application, | |||
void * | data, | |||
void(*)(void *) | datad, | |||
const char * | registrar | |||
) |
Add an extension to an extension context, this time with an ast_context *.
We sort extensions in order of matching preference, so that we can stop the search as soon as we find a suitable match. This ordering also takes care of wildcards such as '.' (meaning "one or more of any character") and '!' (which is 'earlymatch', meaning "zero or more of any character" but also impacts the return value from CANMATCH and EARLYMATCH.
The extension match rules defined in the devmeeting 2006.05.05 are quite simple: WE SELECT THE LONGEST MATCH. In detail, "longest" means the number of matched characters in the extension. In case of ties (e.g. _XXX and 333) in the length of a pattern, we give priority to entries with the smallest cardinality (e.g, [5-9] comes before [2-8] before the former has only 5 elements, while the latter has 7, etc. In case of same cardinality, the first element in the range counts. If we still have a tie, any final '!' will make this as a possibly less specific pattern.
EBUSY - can't lock EEXIST - extension with the same priority exist and no replace is set
Definition at line 4811 of file pbx.c.
References add_pri(), ast_exten::app, ast_add_hint(), ast_calloc, AST_LIST_FIRST, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_exten::cidmatch, ast_exten::data, ast_exten::datad, el, errno, ext_cmp(), ext_strncpy(), ast_exten::exten, globals, globalslock, ast_exten::label, ast_context::lock, ast_exten::matchcid, ast_context::name, ast_exten::next, option_verbose, ast_exten::parent, pbx_substitute_variables_varshead(), ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, ast_context::root, ast_exten::stuff, VAR_BUF_SIZE, and VERBOSE_PREFIX_3.
Referenced by add_extensions(), ast_add_extension(), do_parking_thread(), park_call_full(), pbx_load_config(), and pbx_load_users().
04815 { 04816 /* 04817 * Sort extensions (or patterns) according to the rules indicated above. 04818 * These are implemented by the function ext_cmp()). 04819 * All priorities for the same ext/pattern/cid are kept in a list, 04820 * using the 'peer' field as a link field.. 04821 */ 04822 struct ast_exten *tmp, *e, *el = NULL; 04823 int res; 04824 int length; 04825 char *p; 04826 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04827 04828 /* if we are adding a hint, and there are global variables, and the hint 04829 contains variable references, then expand them 04830 */ 04831 ast_mutex_lock(&globalslock); 04832 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04833 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04834 application = expand_buf; 04835 } 04836 ast_mutex_unlock(&globalslock); 04837 04838 length = sizeof(struct ast_exten); 04839 length += strlen(extension) + 1; 04840 length += strlen(application) + 1; 04841 if (label) 04842 length += strlen(label) + 1; 04843 if (callerid) 04844 length += strlen(callerid) + 1; 04845 else 04846 length ++; /* just the '\0' */ 04847 04848 /* Be optimistic: Build the extension structure first */ 04849 if (!(tmp = ast_calloc(1, length))) 04850 return -1; 04851 04852 /* use p as dst in assignments, as the fields are const char * */ 04853 p = tmp->stuff; 04854 if (label) { 04855 tmp->label = p; 04856 strcpy(p, label); 04857 p += strlen(label) + 1; 04858 } 04859 tmp->exten = p; 04860 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04861 tmp->priority = priority; 04862 tmp->cidmatch = p; /* but use p for assignments below */ 04863 if (callerid) { 04864 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04865 tmp->matchcid = 1; 04866 } else { 04867 *p++ = '\0'; 04868 tmp->matchcid = 0; 04869 } 04870 tmp->app = p; 04871 strcpy(p, application); 04872 tmp->parent = con; 04873 tmp->data = data; 04874 tmp->datad = datad; 04875 tmp->registrar = registrar; 04876 04877 ast_mutex_lock(&con->lock); 04878 res = 0; /* some compilers will think it is uninitialized otherwise */ 04879 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04880 res = ext_cmp(e->exten, tmp->exten); 04881 if (res == 0) { /* extension match, now look at cidmatch */ 04882 if (!e->matchcid && !tmp->matchcid) 04883 res = 0; 04884 else if (tmp->matchcid && !e->matchcid) 04885 res = 1; 04886 else if (e->matchcid && !tmp->matchcid) 04887 res = -1; 04888 else 04889 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04890 } 04891 if (res >= 0) 04892 break; 04893 } 04894 if (e && res == 0) { /* exact match, insert in the pri chain */ 04895 res = add_pri(con, tmp, el, e, replace); 04896 ast_mutex_unlock(&con->lock); 04897 if (res < 0) { 04898 errno = EEXIST; /* XXX do we care ? */ 04899 return 0; /* XXX should we return -1 maybe ? */ 04900 } 04901 } else { 04902 /* 04903 * not an exact match, this is the first entry with this pattern, 04904 * so insert in the main list right before 'e' (if any) 04905 */ 04906 tmp->next = e; 04907 if (el) 04908 el->next = tmp; 04909 else 04910 con->root = tmp; 04911 ast_mutex_unlock(&con->lock); 04912 if (tmp->priority == PRIORITY_HINT) 04913 ast_add_hint(tmp); 04914 } 04915 if (option_debug) { 04916 if (tmp->matchcid) { 04917 if (option_debug) 04918 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04919 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04920 } else { 04921 if (option_debug) 04922 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04923 tmp->exten, tmp->priority, con->name); 04924 } 04925 } 04926 if (option_verbose > 2) { 04927 if (tmp->matchcid) { 04928 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04929 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04930 } else { 04931 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04932 tmp->exten, tmp->priority, con->name); 04933 } 04934 } 04935 return 0; 04936 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4634 of file pbx.c.
References ast_channel::_state, ast_channel::accountcode, ast_channel::amaflags, ast_cdr_discard(), ast_cdr_dup(), ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_unlock, ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_pbx_start(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_channel::cdr, ast_channel::context, ast_channel::exten, LOG_WARNING, ast_channel::name, ast_channel::pbx, ast_channel::readformat, S_OR, and ast_channel::writeformat.
Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), console_transfer_deprecated(), dahdi_handle_dtmfup(), handle_request_bye(), handle_request_refer(), process_ast_dsp(), and socket_process().
04635 { 04636 int res = 0; 04637 04638 ast_channel_lock(chan); 04639 04640 if (chan->pbx) { /* This channel is currently in the PBX */ 04641 ast_explicit_goto(chan, context, exten, priority); 04642 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04643 } else { 04644 /* In order to do it when the channel doesn't really exist within 04645 the PBX, we have to make a new channel, masquerade, and start the PBX 04646 at the new location */ 04647 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04648 if (!tmpchan) { 04649 res = -1; 04650 } else { 04651 if (chan->cdr) { 04652 ast_cdr_discard(tmpchan->cdr); 04653 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 04654 } 04655 /* Make formats okay */ 04656 tmpchan->readformat = chan->readformat; 04657 tmpchan->writeformat = chan->writeformat; 04658 /* Setup proper location */ 04659 ast_explicit_goto(tmpchan, 04660 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04661 04662 /* Masquerade into temp channel */ 04663 if (ast_channel_masquerade(tmpchan, chan)) { 04664 /* Failed to set up the masquerade. It's probably chan_local 04665 * in the middle of optimizing itself out. Sad. :( */ 04666 ast_hangup(tmpchan); 04667 tmpchan = NULL; 04668 res = -1; 04669 } else { 04670 /* Grab the locks and get going */ 04671 ast_channel_lock(tmpchan); 04672 ast_do_masquerade(tmpchan); 04673 ast_channel_unlock(tmpchan); 04674 /* Start the PBX going on our stolen channel */ 04675 if (ast_pbx_start(tmpchan)) { 04676 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04677 ast_hangup(tmpchan); 04678 res = -1; 04679 } 04680 } 04681 } 04682 } 04683 ast_channel_unlock(chan); 04684 return res; 04685 }
int ast_async_goto_by_name | ( | const char * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4687 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04688 { 04689 struct ast_channel *chan; 04690 int res = -1; 04691 04692 chan = ast_get_channel_by_name_locked(channame); 04693 if (chan) { 04694 res = ast_async_goto(chan, context, exten, priority); 04695 ast_channel_unlock(chan); 04696 } 04697 return res; 04698 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6505 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06506 { 06507 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06508 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info | |||
) |
Definition at line 4274 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, and months.
Referenced by ast_context_add_include2(), iftime(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
04275 { 04276 char info_save[256]; 04277 char *info; 04278 04279 /* Check for empty just in case */ 04280 if (ast_strlen_zero(info_in)) 04281 return 0; 04282 /* make a copy just in case we were passed a static string */ 04283 ast_copy_string(info_save, info_in, sizeof(info_save)); 04284 info = info_save; 04285 /* Assume everything except time */ 04286 i->monthmask = 0xfff; /* 12 bits */ 04287 i->daymask = 0x7fffffffU; /* 31 bits */ 04288 i->dowmask = 0x7f; /* 7 bits */ 04289 /* on each call, use strsep() to move info to the next argument */ 04290 get_timerange(i, strsep(&info, "|")); 04291 if (info) 04292 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04293 if (info) 04294 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04295 if (info) 04296 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04297 return 1; 04298 }
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 2297 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(), local_dtmf_helper(), loopback_canmatch(), mgcp_ss(), phone_check_exception(), skinny_ss(), ss_thread(), and valid_exit().
02298 { 02299 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH); 02300 }
int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 4300 of file pbx.c.
References ast_localtime(), ast_log(), ast_timing::daymask, ast_timing::dowmask, LOG_WARNING, ast_timing::minmask, ast_timing::monthmask, and t.
Referenced by iftime(), include_valid(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
04301 { 04302 struct tm tm; 04303 time_t t = time(NULL); 04304 04305 ast_localtime(&t, &tm, NULL); 04306 04307 /* If it's not the right month, return */ 04308 if (!(i->monthmask & (1 << tm.tm_mon))) 04309 return 0; 04310 04311 /* If it's not that time of the month.... */ 04312 /* Warning, tm_mday has range 1..31! */ 04313 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04314 return 0; 04315 04316 /* If it's not the right day of the week */ 04317 if (!(i->dowmask & (1 << tm.tm_wday))) 04318 return 0; 04319 04320 /* Sanity check the hour just to be safe */ 04321 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04322 ast_log(LOG_WARNING, "Insane time...\n"); 04323 return 0; 04324 } 04325 04326 /* Now the tough part, we calculate if it fits 04327 in the right time based on min/hour */ 04328 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04329 return 0; 04330 04331 /* If we got this far, then we're good */ 04332 return 1; 04333 }
int ast_context_add_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Add an ignorepat.
context | which context to add the ignorpattern to | |
ignorepat | ignorepattern to set up for the extension | |
registrar | registrar of the ignore pattern |
0 | on success | |
-1 | on failure |
Definition at line 4527 of file pbx.c.
References ast_context_add_ignorepat2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_context_add_ignorepat(), and handle_context_add_ignorepat_deprecated().
04528 { 04529 int ret = -1; 04530 struct ast_context *c = find_context_locked(context); 04531 04532 if (c) { 04533 ret = ast_context_add_ignorepat2(c, value, registrar); 04534 ast_unlock_contexts(); 04535 } 04536 return ret; 04537 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4539 of file pbx.c.
References ast_calloc, ast_mutex_lock(), ast_mutex_unlock(), errno, ast_context::ignorepats, ast_context::lock, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.
Referenced by ast_context_add_ignorepat(), and pbx_load_config().
04540 { 04541 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04542 int length; 04543 char *pattern; 04544 length = sizeof(struct ast_ignorepat); 04545 length += strlen(value) + 1; 04546 if (!(ignorepat = ast_calloc(1, length))) 04547 return -1; 04548 /* The cast to char * is because we need to write the initial value. 04549 * The field is not supposed to be modified otherwise. Also, gcc 4.2 04550 * sees the cast as dereferencing a type-punned pointer and warns about 04551 * it. This is the workaround (we're telling gcc, yes, that's really 04552 * what we wanted to do). 04553 */ 04554 pattern = (char *) ignorepat->pattern; 04555 strcpy(pattern, value); 04556 ignorepat->next = NULL; 04557 ignorepat->registrar = registrar; 04558 ast_mutex_lock(&con->lock); 04559 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04560 ignorepatl = ignorepatc; 04561 if (!strcasecmp(ignorepatc->pattern, value)) { 04562 /* Already there */ 04563 ast_mutex_unlock(&con->lock); 04564 errno = EEXIST; 04565 return -1; 04566 } 04567 } 04568 if (ignorepatl) 04569 ignorepatl->next = ignorepat; 04570 else 04571 con->ignorepats = ignorepat; 04572 ast_mutex_unlock(&con->lock); 04573 return 0; 04574 04575 }
int ast_context_add_include | ( | const char * | context, | |
const char * | include, | |||
const char * | registrar | |||
) |
Add a context include.
context | context to add include to | |
include | new include to add | |
registrar | who's registering it |
0 | on success | |
-1 | on error |
Definition at line 4080 of file pbx.c.
References ast_context_add_include2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_context_add_include(), and handle_context_add_include_deprecated().
04081 { 04082 int ret = -1; 04083 struct ast_context *c = find_context_locked(context); 04084 04085 if (c) { 04086 ret = ast_context_add_include2(c, include, registrar); 04087 ast_unlock_contexts(); 04088 } 04089 return ret; 04090 }
int ast_context_add_include2 | ( | struct ast_context * | con, | |
const char * | include, | |||
const char * | registrar | |||
) |
Add a context include.
con | context to add the include to | |
include | include to add | |
registrar | who registered the context |
0 | on success | |
-1 | on failure |
Definition at line 4342 of file pbx.c.
References ast_build_timing(), ast_calloc, ast_get_context_name(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), errno, free, ast_include::hastime, ast_context::includes, ast_context::lock, ast_include::name, ast_include::next, option_verbose, ast_include::registrar, ast_include::rname, ast_include::stuff, ast_include::timing, and VERBOSE_PREFIX_3.
Referenced by ast_context_add_include(), and pbx_load_config().
04344 { 04345 struct ast_include *new_include; 04346 char *c; 04347 struct ast_include *i, *il = NULL; /* include, include_last */ 04348 int length; 04349 char *p; 04350 04351 length = sizeof(struct ast_include); 04352 length += 2 * (strlen(value) + 1); 04353 04354 /* allocate new include structure ... */ 04355 if (!(new_include = ast_calloc(1, length))) 04356 return -1; 04357 /* Fill in this structure. Use 'p' for assignments, as the fields 04358 * in the structure are 'const char *' 04359 */ 04360 p = new_include->stuff; 04361 new_include->name = p; 04362 strcpy(p, value); 04363 p += strlen(value) + 1; 04364 new_include->rname = p; 04365 strcpy(p, value); 04366 /* Strip off timing info, and process if it is there */ 04367 if ( (c = strchr(p, '|')) ) { 04368 *c++ = '\0'; 04369 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04370 } 04371 new_include->next = NULL; 04372 new_include->registrar = registrar; 04373 04374 ast_mutex_lock(&con->lock); 04375 04376 /* ... go to last include and check if context is already included too... */ 04377 for (i = con->includes; i; i = i->next) { 04378 if (!strcasecmp(i->name, new_include->name)) { 04379 free(new_include); 04380 ast_mutex_unlock(&con->lock); 04381 errno = EEXIST; 04382 return -1; 04383 } 04384 il = i; 04385 } 04386 04387 /* ... include new context into context list, unlock, return */ 04388 if (il) 04389 il->next = new_include; 04390 else 04391 con->includes = new_include; 04392 if (option_verbose > 2) 04393 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04394 ast_mutex_unlock(&con->lock); 04395 04396 return 0; 04397 }
int ast_context_add_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
int | eval, | |||
const char * | registrar | |||
) |
Add a switch.
context | context to which to add the switch | |
sw | switch to add | |
data | data to pass to switch | |
eval | whether to evaluate variables when running switch | |
registrar | whoever registered the switch |
0 | on success | |
-1 | on failure |
Definition at line 4404 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04405 { 04406 int ret = -1; 04407 struct ast_context *c = find_context_locked(context); 04408 04409 if (c) { /* found, add switch to this context */ 04410 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04411 ast_unlock_contexts(); 04412 } 04413 return ret; 04414 }
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 4423 of file pbx.c.
References ast_context::alts, ast_calloc, ast_get_context_name(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_sw::data, errno, ast_sw::eval, free, store_hint::list, ast_context::lock, ast_sw::name, option_verbose, ast_sw::registrar, ast_sw::stuff, and VERBOSE_PREFIX_3.
Referenced by ast_context_add_switch(), and pbx_load_config().
04425 { 04426 struct ast_sw *new_sw; 04427 struct ast_sw *i; 04428 int length; 04429 char *p; 04430 04431 length = sizeof(struct ast_sw); 04432 length += strlen(value) + 1; 04433 if (data) 04434 length += strlen(data); 04435 length++; 04436 04437 /* allocate new sw structure ... */ 04438 if (!(new_sw = ast_calloc(1, length))) 04439 return -1; 04440 /* ... fill in this structure ... */ 04441 p = new_sw->stuff; 04442 new_sw->name = p; 04443 strcpy(new_sw->name, value); 04444 p += strlen(value) + 1; 04445 new_sw->data = p; 04446 if (data) { 04447 strcpy(new_sw->data, data); 04448 p += strlen(data) + 1; 04449 } else { 04450 strcpy(new_sw->data, ""); 04451 p++; 04452 } 04453 new_sw->eval = eval; 04454 new_sw->registrar = registrar; 04455 04456 /* ... try to lock this context ... */ 04457 ast_mutex_lock(&con->lock); 04458 04459 /* ... go to last sw and check if context is already swd too... */ 04460 AST_LIST_TRAVERSE(&con->alts, i, list) { 04461 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04462 free(new_sw); 04463 ast_mutex_unlock(&con->lock); 04464 errno = EEXIST; 04465 return -1; 04466 } 04467 } 04468 04469 /* ... sw new context into context list, unlock, return */ 04470 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04471 04472 if (option_verbose > 2) 04473 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04474 04475 ast_mutex_unlock(&con->lock); 04476 04477 return 0; 04478 }
struct ast_context* ast_context_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar | |||
) |
Register a new context.
extcontexts | pointer to the ast_context structure pointer | |
name | name of the new context | |
registrar | registrar of the context |
Definition at line 3950 of file pbx.c.
References __ast_context_create().
Referenced by do_parking_thread(), park_call_full(), and set_config().
03951 { 03952 return __ast_context_create(extcontexts, name, registrar, 0); 03953 }
void ast_context_destroy | ( | struct ast_context * | con, | |
const char * | registrar | |||
) |
Destroy a context (matches the specified context (or ANY context if NULL).
con | context to destroy | |
registrar | who registered it |
Definition at line 5392 of file pbx.c.
References __ast_context_destroy(), ast_unlock_contexts(), and ast_wrlock_contexts().
Referenced by cleanup_stale_contexts(), sla_destroy(), and unload_module().
05393 { 05394 ast_wrlock_contexts(); 05395 __ast_context_destroy(con,registrar); 05396 ast_unlock_contexts(); 05397 }
struct ast_context* ast_context_find | ( | const char * | name | ) |
Find a context.
name | name of the context to find |
Definition at line 918 of file pbx.c.
References ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::name.
Referenced by _macro_exec(), ast_context_verify_includes(), ast_ignore_pattern(), cleanup_stale_contexts(), do_parking_thread(), park_call_full(), park_exec(), register_peer_exten(), and set_config().
00919 { 00920 struct ast_context *tmp = NULL; 00921 00922 ast_rdlock_contexts(); 00923 00924 while ( (tmp = ast_walk_contexts(tmp)) ) { 00925 if (!name || !strcasecmp(name, tmp->name)) 00926 break; 00927 } 00928 00929 ast_unlock_contexts(); 00930 00931 return tmp; 00932 }
struct ast_context* ast_context_find_or_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar | |||
) |
Definition at line 3955 of file pbx.c.
References __ast_context_create().
Referenced by pbx_load_config(), and pbx_load_users().
03956 { 03957 return __ast_context_create(extcontexts, name, registrar, 1); 03958 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 2917 of file pbx.c.
References ast_get_context_name(), ast_mutex_lock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::macrolock.
Referenced by _macro_exec().
02918 { 02919 struct ast_context *c = NULL; 02920 int ret = -1; 02921 02922 ast_rdlock_contexts(); 02923 02924 while ((c = ast_walk_contexts(c))) { 02925 if (!strcmp(ast_get_context_name(c), context)) { 02926 ret = 0; 02927 break; 02928 } 02929 } 02930 02931 ast_unlock_contexts(); 02932 02933 /* if we found context, lock macrolock */ 02934 if (ret == 0) 02935 ret = ast_mutex_lock(&c->macrolock); 02936 02937 return ret; 02938 }
int ast_context_remove_extension | ( | const char * | context, | |
const char * | extension, | |||
int | priority, | |||
const char * | registrar | |||
) |
Simply remove extension from context.
context | context to remove extension from | |
extension | which extension to remove | |
priority | priority of extension to remove (0 to remove all) | |
callerid | NULL to remove all; non-NULL to match a single record per priority | |
matchcid | non-zero to match callerid element (if non-NULL); 0 to match default case | |
registrar | registrar of the extension |
0 | on success | |
-1 | on failure |
Definition at line 2818 of file pbx.c.
References ast_context_remove_extension_callerid().
Referenced by destroy_station(), destroy_trunk(), and register_peer_exten().
02819 { 02820 return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar); 02821 }
int ast_context_remove_extension2 | ( | struct ast_context * | con, | |
const char * | extension, | |||
int | priority, | |||
const char * | registrar | |||
) |
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 2845 of file pbx.c.
References ast_context_remove_extension_callerid2().
Referenced by do_parking_thread(), and park_exec().
02846 { 02847 return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar); 02848 }
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 2823 of file pbx.c.
References ast_context_remove_extension_callerid2(), ast_unlock_contexts(), and find_context_locked().
Referenced by ast_context_remove_extension(), handle_context_remove_extension(), and handle_context_remove_extension_deprecated().
02824 { 02825 int ret = -1; /* default error return */ 02826 struct ast_context *c = find_context_locked(context); 02827 02828 if (c) { /* ... remove extension ... */ 02829 ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar); 02830 ast_unlock_contexts(); 02831 } 02832 return ret; 02833 }
int ast_context_remove_extension_callerid2 | ( | struct ast_context * | con, | |
const char * | extension, | |||
int | priority, | |||
const char * | callerid, | |||
int | matchcid, | |||
const char * | registrar | |||
) |
Definition at line 2850 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_exten::cidmatch, destroy_exten(), ast_exten::exten, exten, ast_context::lock, ast_exten::next, ast_exten::peer, ast_exten::priority, ast_exten::registrar, and ast_context::root.
Referenced by ast_context_remove_extension2(), and ast_context_remove_extension_callerid().
02851 { 02852 struct ast_exten *exten, *prev_exten = NULL; 02853 struct ast_exten *peer; 02854 struct ast_exten *previous_peer = NULL; 02855 struct ast_exten *next_peer = NULL; 02856 int found = 0; 02857 02858 ast_mutex_lock(&con->lock); 02859 02860 /* scan the extension list to find first matching extension-registrar */ 02861 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02862 if (!strcmp(exten->exten, extension) && 02863 (!registrar || !strcmp(exten->registrar, registrar))) 02864 break; 02865 } 02866 if (!exten) { 02867 /* we can't find right extension */ 02868 ast_mutex_unlock(&con->lock); 02869 return -1; 02870 } 02871 02872 /* scan the priority list to remove extension with exten->priority == priority */ 02873 for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next; 02874 peer && !strcmp(peer->exten, extension); 02875 peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) { 02876 if ((priority == 0 || peer->priority == priority) && 02877 (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) && 02878 (!registrar || !strcmp(peer->registrar, registrar) )) { 02879 found = 1; 02880 02881 /* we are first priority extension? */ 02882 if (!previous_peer) { 02883 /* 02884 * We are first in the priority chain, so must update the extension chain. 02885 * The next node is either the next priority or the next extension 02886 */ 02887 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02888 02889 if (!prev_exten) { /* change the root... */ 02890 con->root = next_node; 02891 } else { 02892 prev_exten->next = next_node; /* unlink */ 02893 } 02894 if (peer->peer) { /* update the new head of the pri list */ 02895 peer->peer->next = peer->next; 02896 } 02897 } else { /* easy, we are not first priority in extension */ 02898 previous_peer->peer = peer->peer; 02899 } 02900 02901 /* now, free whole priority extension */ 02902 destroy_exten(peer); 02903 } else { 02904 previous_peer = peer; 02905 } 02906 } 02907 ast_mutex_unlock(&con->lock); 02908 return found ? 0 : -1; 02909 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4484 of file pbx.c.
References ast_context_remove_ignorepat2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_context_remove_ignorepat(), and handle_context_remove_ignorepat_deprecated().
04485 { 04486 int ret = -1; 04487 struct ast_context *c = find_context_locked(context); 04488 04489 if (c) { 04490 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04491 ast_unlock_contexts(); 04492 } 04493 return ret; 04494 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4496 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), errno, free, ast_context::ignorepats, ast_context::lock, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.
Referenced by ast_context_remove_ignorepat().
04497 { 04498 struct ast_ignorepat *ip, *ipl = NULL; 04499 04500 ast_mutex_lock(&con->lock); 04501 04502 for (ip = con->ignorepats; ip; ip = ip->next) { 04503 if (!strcmp(ip->pattern, ignorepat) && 04504 (!registrar || (registrar == ip->registrar))) { 04505 if (ipl) { 04506 ipl->next = ip->next; 04507 free(ip); 04508 } else { 04509 con->ignorepats = ip->next; 04510 free(ip); 04511 } 04512 ast_mutex_unlock(&con->lock); 04513 return 0; 04514 } 04515 ipl = ip; 04516 } 04517 04518 ast_mutex_unlock(&con->lock); 04519 errno = EINVAL; 04520 return -1; 04521 }
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 2714 of file pbx.c.
References ast_context_remove_include2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_context_dont_include_deprecated(), and handle_context_remove_include().
02715 { 02716 int ret = -1; 02717 struct ast_context *c = find_context_locked(context); 02718 02719 if (c) { 02720 /* found, remove include from this context ... */ 02721 ret = ast_context_remove_include2(c, include, registrar); 02722 ast_unlock_contexts(); 02723 } 02724 return ret; 02725 }
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 |
Definition at line 2735 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), free, ast_context::includes, ast_context::lock, ast_include::name, ast_include::next, and ast_include::registrar.
Referenced by ast_context_remove_include().
02736 { 02737 struct ast_include *i, *pi = NULL; 02738 int ret = -1; 02739 02740 ast_mutex_lock(&con->lock); 02741 02742 /* find our include */ 02743 for (i = con->includes; i; pi = i, i = i->next) { 02744 if (!strcmp(i->name, include) && 02745 (!registrar || !strcmp(i->registrar, registrar))) { 02746 /* remove from list */ 02747 if (pi) 02748 pi->next = i->next; 02749 else 02750 con->includes = i->next; 02751 /* free include and return */ 02752 free(i); 02753 ret = 0; 02754 break; 02755 } 02756 } 02757 02758 ast_mutex_unlock(&con->lock); 02759 return ret; 02760 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 2767 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
02768 { 02769 int ret = -1; /* default error return */ 02770 struct ast_context *c = find_context_locked(context); 02771 02772 if (c) { 02773 /* remove switch from this context ... */ 02774 ret = ast_context_remove_switch2(c, sw, data, registrar); 02775 ast_unlock_contexts(); 02776 } 02777 return ret; 02778 }
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 2788 of file pbx.c.
References ast_context::alts, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), ast_sw::data, free, ast_sw::list, ast_context::lock, ast_sw::name, and ast_sw::registrar.
Referenced by ast_context_remove_switch().
02789 { 02790 struct ast_sw *i; 02791 int ret = -1; 02792 02793 ast_mutex_lock(&con->lock); 02794 02795 /* walk switches */ 02796 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02797 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02798 (!registrar || !strcmp(i->registrar, registrar))) { 02799 /* found, remove from list */ 02800 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02801 free(i); /* free switch and return */ 02802 ret = 0; 02803 break; 02804 } 02805 } 02806 AST_LIST_TRAVERSE_SAFE_END 02807 02808 ast_mutex_unlock(&con->lock); 02809 02810 return ret; 02811 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 2945 of file pbx.c.
References ast_get_context_name(), ast_mutex_unlock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::macrolock.
Referenced by _macro_exec().
02946 { 02947 struct ast_context *c = NULL; 02948 int ret = -1; 02949 02950 ast_rdlock_contexts(); 02951 02952 while ((c = ast_walk_contexts(c))) { 02953 if (!strcmp(ast_get_context_name(c), context)) { 02954 ret = 0; 02955 break; 02956 } 02957 } 02958 02959 ast_unlock_contexts(); 02960 02961 /* if we found context, unlock macrolock */ 02962 if (ret == 0) 02963 ret = ast_mutex_unlock(&c->macrolock); 02964 02965 return ret; 02966 }
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 6462 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().
06463 { 06464 struct ast_include *inc = NULL; 06465 int res = 0; 06466 06467 while ( (inc = ast_walk_context_includes(con, inc)) ) { 06468 if (ast_context_find(inc->rname)) 06469 continue; 06470 06471 res = -1; 06472 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 06473 ast_get_context_name(con), inc->rname); 06474 break; 06475 } 06476 06477 return res; 06478 }
struct ast_custom_function* ast_custom_function_find | ( | const char * | name | ) |
Definition at line 1480 of file pbx.c.
References ast_custom_function::acflist, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_custom_function::name.
Referenced by ast_custom_function_register(), ast_func_read(), ast_func_write(), handle_show_function(), and handle_show_function_deprecated().
01481 { 01482 struct ast_custom_function *acf = NULL; 01483 01484 AST_LIST_LOCK(&acf_root); 01485 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01486 if (!strcmp(name, acf->name)) 01487 break; 01488 } 01489 AST_LIST_UNLOCK(&acf_root); 01490 01491 return acf; 01492 }
int ast_custom_function_register | ( | struct ast_custom_function * | acf | ) |
Reigster a custom function.
Definition at line 1516 of file pbx.c.
References ast_custom_function::acflist, ast_custom_function_find(), AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), LOG_ERROR, ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by load_module(), odbc_load_module(), and reload().
01517 { 01518 struct ast_custom_function *cur; 01519 01520 if (!acf) 01521 return -1; 01522 01523 AST_LIST_LOCK(&acf_root); 01524 01525 if (ast_custom_function_find(acf->name)) { 01526 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01527 AST_LIST_UNLOCK(&acf_root); 01528 return -1; 01529 } 01530 01531 /* Store in alphabetical order */ 01532 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01533 if (strcasecmp(acf->name, cur->name) < 0) { 01534 AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist); 01535 break; 01536 } 01537 } 01538 AST_LIST_TRAVERSE_SAFE_END 01539 if (!cur) 01540 AST_LIST_INSERT_TAIL(&acf_root, acf, acflist); 01541 01542 AST_LIST_UNLOCK(&acf_root); 01543 01544 if (option_verbose > 1) 01545 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01546 01547 return 0; 01548 }
int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Unregister a custom function.
Definition at line 1494 of file pbx.c.
References ast_custom_function::acflist, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by odbc_unload_module(), reload(), and unload_module().
01495 { 01496 struct ast_custom_function *cur; 01497 01498 if (!acf) 01499 return -1; 01500 01501 AST_LIST_LOCK(&acf_root); 01502 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01503 if (cur == acf) { 01504 AST_LIST_REMOVE_CURRENT(&acf_root, acflist); 01505 if (option_verbose > 1) 01506 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01507 break; 01508 } 01509 } 01510 AST_LIST_TRAVERSE_SAFE_END 01511 AST_LIST_UNLOCK(&acf_root); 01512 01513 return acf ? 0 : -1; 01514 }
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 1943 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().
01944 { 01945 switch (devstate) { 01946 case AST_DEVICE_ONHOLD: 01947 return AST_EXTENSION_ONHOLD; 01948 case AST_DEVICE_BUSY: 01949 return AST_EXTENSION_BUSY; 01950 case AST_DEVICE_UNAVAILABLE: 01951 case AST_DEVICE_UNKNOWN: 01952 case AST_DEVICE_INVALID: 01953 return AST_EXTENSION_UNAVAILABLE; 01954 case AST_DEVICE_RINGINUSE: 01955 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING); 01956 case AST_DEVICE_RINGING: 01957 return AST_EXTENSION_RINGING; 01958 case AST_DEVICE_INUSE: 01959 return AST_EXTENSION_INUSE; 01960 case AST_DEVICE_NOT_INUSE: 01961 return AST_EXTENSION_NOT_INUSE; 01962 case AST_DEVICE_TOTAL: /* not a device state, included for completeness */ 01963 break; 01964 } 01965 01966 return AST_EXTENSION_NOT_INUSE; 01967 }
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 2282 of file pbx.c.
References E_MATCH, and pbx_extension_helper().
Referenced by __ast_goto_if_exists(), __ast_pbx_run(), __login_exec(), _macro_exec(), agentmonitoroutgoing_exec(), answer_call(), ast_app_dtget(), ast_bridge_call(), ast_pbx_outgoing_exten(), builtin_blindtransfer(), cb_events(), conf_run(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), dahdi_handle_dtmfup(), disa_exec(), do_atxfer(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), handle_stimulus_message(), leave_voicemail(), local_alloc(), local_call(), local_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), misdn_overlap_dial_task(), park_space_reserve(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), pri_dchannel(), process_ast_dsp(), register_peer_exten(), skinny_ss(), socket_process(), ss_thread(), and waitstream_core().
02283 { 02284 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH); 02285 }
int ast_explicit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4611 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(), ast_parseable_goto(), disa_exec(), do_atxfer(), and handle_setpriority().
04612 { 04613 if (!chan) 04614 return -1; 04615 04616 ast_channel_lock(chan); 04617 04618 if (!ast_strlen_zero(context)) 04619 ast_copy_string(chan->context, context, sizeof(chan->context)); 04620 if (!ast_strlen_zero(exten)) 04621 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04622 if (priority > -1) { 04623 chan->priority = priority; 04624 /* see flag description in channel.h for explanation */ 04625 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04626 chan->priority--; 04627 } 04628 04629 ast_channel_unlock(chan); 04630 04631 return 0; 04632 }
int ast_extension_close | ( | const char * | pattern, | |
const char * | data, | |||
int | needmore | |||
) |
Definition at line 911 of file pbx.c.
References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.
Referenced by realtime_switch_common().
00912 { 00913 if (needmore != E_MATCHMORE && needmore != E_CANMATCH) 00914 ast_log(LOG_WARNING, "invalid argument %d\n", needmore); 00915 return extension_match_core(pattern, data, needmore); 00916 }
int ast_extension_match | ( | const char * | pattern, | |
const char * | extension | |||
) |
Determine if a given extension matches a given pattern (in NXX format).
pattern | pattern to match | |
extension | extension to check against the pattern. |
1 | on match | |
0 | on failure |
Definition at line 906 of file pbx.c.
References E_MATCH, and extension_match_core().
Referenced by ast_ignore_pattern(), do_say(), find_matching_priority(), loopback_canmatch(), loopback_exists(), loopback_matchmore(), matchcid(), misdn_cfg_is_msn_valid(), realtime_switch_common(), and show_dialplan_helper().
00907 { 00908 return extension_match_core(pattern, data, E_MATCH); 00909 }
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 2004 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), and handle_request_subscribe().
02005 { 02006 struct ast_exten *e; 02007 02008 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 02009 if (!e) 02010 return -1; /* No hint, return -1 */ 02011 02012 return ast_extension_state2(e); /* Check all devices in the hint */ 02013 }
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 1992 of file pbx.c.
References extension_states.
Referenced by cb_extensionstate(), handle_request_subscribe(), and handle_show_hints().
01993 { 01994 int i; 01995 01996 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 01997 if (extension_states[i].extension_state == extension_state) 01998 return extension_states[i].text; 01999 } 02000 return "Unknown"; 02001 }
int ast_extension_state_add | ( | const char * | context, | |
const char * | exten, | |||
ast_state_cb_type | callback, | |||
void * | data | |||
) |
Registers a state change callback.
context | which context to look in | |
exten | which extension to get state | |
callback | callback to call if state changed | |
data | to pass to callback |
-1 | on failure | |
ID | on success |
Definition at line 2061 of file pbx.c.
References ast_calloc, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_state_cb::callback, ast_state_cb::data, ast_state_cb::next, and statecbs.
Referenced by handle_request_subscribe(), and init_manager().
02063 { 02064 struct ast_hint *hint; 02065 struct ast_state_cb *cblist; 02066 struct ast_exten *e; 02067 02068 /* If there's no context and extension: add callback to statecbs list */ 02069 if (!context && !exten) { 02070 AST_LIST_LOCK(&hints); 02071 02072 for (cblist = statecbs; cblist; cblist = cblist->next) { 02073 if (cblist->callback == callback) { 02074 cblist->data = data; 02075 AST_LIST_UNLOCK(&hints); 02076 return 0; 02077 } 02078 } 02079 02080 /* Now insert the callback */ 02081 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02082 AST_LIST_UNLOCK(&hints); 02083 return -1; 02084 } 02085 cblist->id = 0; 02086 cblist->callback = callback; 02087 cblist->data = data; 02088 02089 cblist->next = statecbs; 02090 statecbs = cblist; 02091 02092 AST_LIST_UNLOCK(&hints); 02093 return 0; 02094 } 02095 02096 if (!context || !exten) 02097 return -1; 02098 02099 /* This callback type is for only one hint, so get the hint */ 02100 e = ast_hint_extension(NULL, context, exten); 02101 if (!e) { 02102 return -1; 02103 } 02104 02105 /* Find the hint in the list of hints */ 02106 AST_LIST_LOCK(&hints); 02107 02108 AST_LIST_TRAVERSE(&hints, hint, list) { 02109 if (hint->exten == e) 02110 break; 02111 } 02112 02113 if (!hint) { 02114 /* We have no hint, sorry */ 02115 AST_LIST_UNLOCK(&hints); 02116 return -1; 02117 } 02118 02119 /* Now insert the callback in the callback list */ 02120 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02121 AST_LIST_UNLOCK(&hints); 02122 return -1; 02123 } 02124 cblist->id = stateid++; /* Unique ID for this callback */ 02125 cblist->callback = callback; /* Pointer to callback routine */ 02126 cblist->data = data; /* Data for the callback */ 02127 02128 cblist->next = hint->callbacks; 02129 hint->callbacks = cblist; 02130 02131 AST_LIST_UNLOCK(&hints); 02132 return cblist->id; 02133 }
int ast_extension_state_del | ( | int | id, | |
ast_state_cb_type | callback | |||
) |
Deletes a registered state change callback by ID.
id | of the callback to delete | |
callback | callback |
0 | success | |
-1 | failure |
Definition at line 2136 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_hint::callbacks, free, ast_sw::list, ast_state_cb::next, and statecbs.
Referenced by __sip_destroy(), and handle_request_subscribe().
02137 { 02138 struct ast_state_cb **p_cur = NULL; /* address of pointer to us */ 02139 int ret = -1; 02140 02141 if (!id && !callback) 02142 return -1; 02143 02144 AST_LIST_LOCK(&hints); 02145 02146 if (!id) { /* id == 0 is a callback without extension */ 02147 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) { 02148 if ((*p_cur)->callback == callback) 02149 break; 02150 } 02151 } else { /* callback with extension, find the callback based on ID */ 02152 struct ast_hint *hint; 02153 AST_LIST_TRAVERSE(&hints, hint, list) { 02154 for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) { 02155 if ((*p_cur)->id == id) 02156 break; 02157 } 02158 if (*p_cur) /* found in the inner loop */ 02159 break; 02160 } 02161 } 02162 if (p_cur && *p_cur) { 02163 struct ast_state_cb *cur = *p_cur; 02164 *p_cur = cur->next; 02165 free(cur); 02166 ret = 0; 02167 } 02168 AST_LIST_UNLOCK(&hints); 02169 return ret; 02170 }
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 |
Definition at line 2287 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by action_originate(), action_redirect(), ast_parseable_goto(), asyncgoto_exec(), and handle_setpriority().
02288 { 02289 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL); 02290 }
int ast_findlabel_extension2 | ( | struct ast_channel * | c, | |
struct ast_context * | con, | |||
const char * | exten, | |||
const char * | label, | |||
const char * | callerid | |||
) |
Find the priority of an extension that has the specified label.
This function is the same as ast_findlabel_extension, except that it accepts a pointer to an ast_context structure to specify the context instead of the name of the context. Otherwise, the functions behave the same.
Definition at line 2292 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
02293 { 02294 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL); 02295 }
int ast_func_read | ( | struct ast_channel * | chan, | |
char * | function, | |||
char * | workspace, | |||
size_t | len | |||
) |
executes a read operation on a function
chan | Channel to execute on | |
function | Data containing the function call string (will be modified) | |
workspace | A pointer to safe memory to use for a return value | |
len | the number of bytes in workspace |
Definition at line 1570 of file pbx.c.
References ast_custom_function_find(), ast_log(), func_args(), LOG_ERROR, and ast_custom_function::read.
Referenced by action_getvar(), handle_getvariable(), and pbx_substitute_variables_helper_full().
01571 { 01572 char *args = func_args(function); 01573 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01574 01575 if (acfptr == NULL) 01576 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01577 else if (!acfptr->read) 01578 ast_log(LOG_ERROR, "Function %s cannot be read\n", function); 01579 else 01580 return acfptr->read(chan, function, args, workspace, len); 01581 return -1; 01582 }
int ast_func_write | ( | struct ast_channel * | chan, | |
char * | function, | |||
const char * | value | |||
) |
executes a write operation on a function
chan | Channel to execute on | |
function | Data containing the function call string (will be modified) | |
value | A value parameter to pass for writing |
Definition at line 1584 of file pbx.c.
References ast_custom_function_find(), ast_log(), func_args(), LOG_ERROR, and ast_custom_function::write.
Referenced by pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().
01585 { 01586 char *args = func_args(function); 01587 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01588 01589 if (acfptr == NULL) 01590 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01591 else if (!acfptr->write) 01592 ast_log(LOG_ERROR, "Function %s cannot be written to\n", function); 01593 else 01594 return acfptr->write(chan, function, args, value); 01595 01596 return -1; 01597 }
const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 6319 of file pbx.c.
References ast_context::name.
Referenced by _macro_exec(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_context_verify_includes(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper().
06320 { 06321 return con ? con->name : NULL; 06322 }
const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 6357 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06358 { 06359 return c ? c->registrar : NULL; 06360 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6387 of file pbx.c.
References ast_exten::app.
Referenced by _macro_exec(), ast_add_hint(), ast_extension_state2(), ast_get_hint(), ast_hint_state_changed(), find_matching_endwhile(), handle_save_dialplan(), handle_show_hints(), and print_ext().
06388 { 06389 return e ? e->app : NULL; 06390 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6392 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06393 { 06394 return e ? e->data : NULL; 06395 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6382 of file pbx.c.
References ast_exten::cidmatch.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), and handle_save_dialplan().
06383 { 06384 return e ? e->cidmatch : NULL; 06385 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
const char* ast_get_extension_label | ( | struct ast_exten * | e | ) |
Definition at line 6334 of file pbx.c.
References exten.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
int ast_get_extension_matchcid | ( | struct ast_exten * | e | ) |
Definition at line 6377 of file pbx.c.
References ast_exten::matchcid.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), and handle_save_dialplan().
06378 { 06379 return e ? e->matchcid : 0; 06380 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6329 of file pbx.c.
References exten.
Referenced by ast_add_hint(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), dundi_precache_full(), find_matching_priority(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper().
int ast_get_extension_priority | ( | struct ast_exten * | exten | ) |
Definition at line 6349 of file pbx.c.
References exten.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), handle_save_dialplan(), and print_ext().
const char* ast_get_extension_registrar | ( | struct ast_exten * | e | ) |
Definition at line 6362 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06363 { 06364 return e ? e->registrar : NULL; 06365 }
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 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 2265 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(), pbx_retrieve_variable(), and transmit_state_notify().
02266 { 02267 struct ast_exten *e = ast_hint_extension(c, context, exten); 02268 02269 if (e) { 02270 if (hint) 02271 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02272 if (name) { 02273 const char *tmp = ast_get_extension_app_data(e); 02274 if (tmp) 02275 ast_copy_string(name, tmp, namesize); 02276 } 02277 return -1; 02278 } 02279 return 0; 02280 }
const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6344 of file pbx.c.
References ast_ignorepat::pattern.
Referenced by complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), handle_save_dialplan(), lookup_c_ip(), and show_dialplan_helper().
06345 { 06346 return ip ? ip->pattern : NULL; 06347 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6372 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06373 { 06374 return ip ? ip->registrar : NULL; 06375 }
const char* ast_get_include_name | ( | struct ast_include * | include | ) |
Definition at line 6339 of file pbx.c.
References ast_include::name.
Referenced by complete_context_dont_include_deprecated(), complete_context_remove_include(), find_matching_priority(), handle_save_dialplan(), lookup_ci(), and show_dialplan_helper().
const char* ast_get_include_registrar | ( | struct ast_include * | i | ) |
Definition at line 6367 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06368 { 06369 return i ? i->registrar : NULL; 06370 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6402 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06403 { 06404 return sw ? sw->data : NULL; 06405 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6397 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06398 { 06399 return sw ? sw->name : NULL; 06400 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6407 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06408 { 06409 return sw ? sw->registrar : NULL; 06410 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6500 of file pbx.c.
References __ast_goto_if_exists().
Referenced by aqm_exec(), background_detect_exec(), chanavail_exec(), conf_run(), controlplayback_exec(), do_directory(), hasvoicemail_exec(), leave_voicemail(), lookupblacklist_exec(), onedigit_goto(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), play_mailbox_owner(), playback_exec(), pqm_exec(), privacy_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), system_exec_helper(), transfer_exec(), upqm_exec(), valid_exit(), vm_box_exists(), vm_exec(), and wait_for_answer().
06501 { 06502 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06503 }
void ast_hint_state_changed | ( | const char * | device | ) |
Definition at line 2015 of file pbx.c.
References ast_copy_string(), ast_extension_state2(), ast_get_extension_app(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, AST_MAX_EXTENSION, ast_rdlock_contexts(), ast_unlock_contexts(), ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_exten::exten, ast_hint::exten, ast_hint::laststate, ast_sw::list, ast_context::name, ast_state_cb::next, ast_exten::parent, parse(), and statecbs.
Referenced by do_state_change().
02016 { 02017 struct ast_hint *hint; 02018 02019 ast_rdlock_contexts(); 02020 AST_LIST_LOCK(&hints); 02021 02022 AST_LIST_TRAVERSE(&hints, hint, list) { 02023 struct ast_state_cb *cblist; 02024 char buf[AST_MAX_EXTENSION]; 02025 char *parse = buf; 02026 char *cur; 02027 int state; 02028 02029 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 02030 while ( (cur = strsep(&parse, "&")) ) { 02031 if (!strcasecmp(cur, device)) 02032 break; 02033 } 02034 if (!cur) 02035 continue; 02036 02037 /* Get device state for this hint */ 02038 state = ast_extension_state2(hint->exten); 02039 02040 if ((state == -1) || (state == hint->laststate)) 02041 continue; 02042 02043 /* Device state changed since last check - notify the watchers */ 02044 02045 /* For general callbacks */ 02046 for (cblist = statecbs; cblist; cblist = cblist->next) 02047 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02048 02049 /* For extension callbacks */ 02050 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 02051 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02052 02053 hint->laststate = state; /* record we saw the change */ 02054 } 02055 02056 AST_LIST_UNLOCK(&hints); 02057 ast_unlock_contexts(); 02058 }
int ast_ignore_pattern | ( | const char * | context, | |
const char * | pattern | |||
) |
Checks to see if a number should be ignored.
context | context to search within | |
pattern | to check whether it should be ignored or not |
0 | if the pattern should not be ignored | |
non-zero | if the pattern should be ignored |
Definition at line 4577 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().
04578 { 04579 struct ast_context *con = ast_context_find(context); 04580 if (con) { 04581 struct ast_ignorepat *pat; 04582 for (pat = con->ignorepats; pat; pat = pat->next) { 04583 if (ast_extension_match(pat->pattern, pattern)) 04584 return 1; 04585 } 04586 } 04587 04588 return 0; 04589 }
int ast_lock_context | ( | struct ast_context * | con | ) |
Locks a given context.
con | context to lock |
0 | on success | |
-1 | on failure |
Definition at line 6306 of file pbx.c.
References ast_mutex_lock(), and ast_context::lock.
Referenced by _macro_exec(), complete_context_dont_include_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), lookup_c_ip(), lookup_ci(), and show_dialplan_helper().
06307 { 06308 return ast_mutex_lock(&con->lock); 06309 }
int ast_lock_contexts | ( | void | ) |
Locks the context list.
0 | on success | |
-1 | on error |
Definition at line 6283 of file pbx.c.
References ast_rwlock_wrlock(), and conlock.
Referenced by find_matching_endwhile().
06284 { 06285 return ast_rwlock_wrlock(&conlock); 06286 }
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 2302 of file pbx.c.
References E_MATCHMORE, and pbx_extension_helper().
Referenced by ast_app_dtget(), collect_digits(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_stimulus_message(), loopback_matchmore(), mgcp_ss(), pbx_builtin_background(), skinny_ss(), and ss_thread().
02303 { 02304 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE); 02305 }
void ast_merge_contexts_and_delete | ( | struct ast_context ** | extcontexts, | |
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 pointer | |
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 3973 of file pbx.c.
References __ast_context_destroy(), ast_calloc, AST_EXTENSION_REMOVED, AST_LIST_HEAD_INIT_VALUE, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_unlock_contexts(), ast_wrlock_contexts(), ast_state_cb::callback, store_hint::callbacks, ast_hint::callbacks, store_hint::context, contexts, ast_state_cb::data, E_MATCH, store_hint::exten, ast_exten::exten, ast_hint::exten, free, ast_hint::laststate, store_hint::laststate, store_hint::list, LOG_WARNING, ast_context::name, ast_state_cb::next, ast_context::next, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_context::registrar, and pbx_find_info::stacklen.
Referenced by pbx_load_module().
03974 { 03975 struct ast_context *tmp, *lasttmp = NULL; 03976 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 03977 struct store_hint *this; 03978 struct ast_hint *hint; 03979 struct ast_exten *exten; 03980 int length; 03981 struct ast_state_cb *thiscb, *prevcb; 03982 03983 /* it is very important that this function hold the hint list lock _and_ the conlock 03984 during its operation; not only do we need to ensure that the list of contexts 03985 and extensions does not change, but also that no hint callbacks (watchers) are 03986 added or removed during the merge/delete process 03987 03988 in addition, the locks _must_ be taken in this order, because there are already 03989 other code paths that use this order 03990 */ 03991 ast_wrlock_contexts(); 03992 AST_LIST_LOCK(&hints); 03993 03994 /* preserve all watchers for hints associated with this registrar */ 03995 AST_LIST_TRAVERSE(&hints, hint, list) { 03996 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03997 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03998 if (!(this = ast_calloc(1, length))) 03999 continue; 04000 this->callbacks = hint->callbacks; 04001 hint->callbacks = NULL; 04002 this->laststate = hint->laststate; 04003 this->context = this->data; 04004 strcpy(this->data, hint->exten->parent->name); 04005 this->exten = this->data + strlen(this->context) + 1; 04006 strcpy(this->exten, hint->exten->exten); 04007 AST_LIST_INSERT_HEAD(&store, this, list); 04008 } 04009 } 04010 04011 tmp = *extcontexts; 04012 if (registrar) { 04013 /* XXX remove previous contexts from same registrar */ 04014 if (option_debug) 04015 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 04016 __ast_context_destroy(NULL,registrar); 04017 while (tmp) { 04018 lasttmp = tmp; 04019 tmp = tmp->next; 04020 } 04021 } else { 04022 /* XXX remove contexts with the same name */ 04023 while (tmp) { 04024 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 04025 __ast_context_destroy(tmp,tmp->registrar); 04026 lasttmp = tmp; 04027 tmp = tmp->next; 04028 } 04029 } 04030 if (lasttmp) { 04031 lasttmp->next = contexts; 04032 contexts = *extcontexts; 04033 *extcontexts = NULL; 04034 } else 04035 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 04036 04037 /* restore the watchers for hints that can be found; notify those that 04038 cannot be restored 04039 */ 04040 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 04041 struct pbx_find_info q = { .stacklen = 0 }; 04042 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 04043 /* Find the hint in the list of hints */ 04044 AST_LIST_TRAVERSE(&hints, hint, list) { 04045 if (hint->exten == exten) 04046 break; 04047 } 04048 if (!exten || !hint) { 04049 /* this hint has been removed, notify the watchers */ 04050 prevcb = NULL; 04051 thiscb = this->callbacks; 04052 while (thiscb) { 04053 prevcb = thiscb; 04054 thiscb = thiscb->next; 04055 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 04056 free(prevcb); 04057 } 04058 } else { 04059 thiscb = this->callbacks; 04060 while (thiscb->next) 04061 thiscb = thiscb->next; 04062 thiscb->next = hint->callbacks; 04063 hint->callbacks = this->callbacks; 04064 hint->laststate = this->laststate; 04065 } 04066 free(this); 04067 } 04068 04069 AST_LIST_UNLOCK(&hints); 04070 ast_unlock_contexts(); 04071 04072 return; 04073 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
This function will handle locking the channel as needed.
Definition at line 6510 of file pbx.c.
References ast_explicit_goto(), ast_findlabel_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, LOG_WARNING, and ast_channel::priority.
Referenced by _while_exec(), check_goto_on_transfer(), gosub_exec(), ivr_dispatch(), pbx_builtin_goto(), random_exec(), return_exec(), and while_continue_exec().
06511 { 06512 char *exten, *pri, *context; 06513 char *stringp; 06514 int ipri; 06515 int mode = 0; 06516 06517 if (ast_strlen_zero(goto_string)) { 06518 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06519 return -1; 06520 } 06521 stringp = ast_strdupa(goto_string); 06522 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06523 exten = strsep(&stringp, "|"); 06524 pri = strsep(&stringp, "|"); 06525 if (!exten) { /* Only a priority in this one */ 06526 pri = context; 06527 exten = NULL; 06528 context = NULL; 06529 } else if (!pri) { /* Only an extension and priority in this one */ 06530 pri = exten; 06531 exten = context; 06532 context = NULL; 06533 } 06534 if (*pri == '+') { 06535 mode = 1; 06536 pri++; 06537 } else if (*pri == '-') { 06538 mode = -1; 06539 pri++; 06540 } 06541 if (sscanf(pri, "%30d", &ipri) != 1) { 06542 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06543 pri, chan->cid.cid_num)) < 1) { 06544 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06545 return -1; 06546 } else 06547 mode = 0; 06548 } 06549 /* At this point we have a priority and maybe an extension and a context */ 06550 06551 if (mode) 06552 ipri = chan->priority + (ipri * mode); 06553 06554 ast_explicit_goto(chan, context, exten, ipri); 06555 return 0; 06556 06557 }
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 5204 of file pbx.c.
References __ast_request_and_dial(), ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), async_stat::chan, errno, free, LOG_WARNING, option_verbose, outgoing_helper::vars, and VERBOSE_PREFIX_4.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_app().
05205 { 05206 struct ast_channel *chan; 05207 struct app_tmp *tmp; 05208 int res = -1, cdr_res = -1; 05209 struct outgoing_helper oh; 05210 pthread_attr_t attr; 05211 05212 memset(&oh, 0, sizeof(oh)); 05213 oh.vars = vars; 05214 oh.account = account; 05215 05216 if (locked_channel) 05217 *locked_channel = NULL; 05218 if (ast_strlen_zero(app)) { 05219 res = -1; 05220 goto outgoing_app_cleanup; 05221 } 05222 if (sync) { 05223 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05224 if (chan) { 05225 ast_set_variables(chan, vars); 05226 if (account) 05227 ast_cdr_setaccount(chan, account); 05228 if (chan->_state == AST_STATE_UP) { 05229 res = 0; 05230 if (option_verbose > 3) 05231 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05232 tmp = ast_calloc(1, sizeof(*tmp)); 05233 if (!tmp) 05234 res = -1; 05235 else { 05236 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05237 if (appdata) 05238 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05239 tmp->chan = chan; 05240 if (sync > 1) { 05241 if (locked_channel) 05242 ast_channel_unlock(chan); 05243 ast_pbx_run_app(tmp); 05244 } else { 05245 pthread_attr_init(&attr); 05246 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05247 if (locked_channel) 05248 ast_channel_lock(chan); 05249 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05250 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05251 free(tmp); 05252 if (locked_channel) 05253 ast_channel_unlock(chan); 05254 ast_hangup(chan); 05255 res = -1; 05256 } else { 05257 if (locked_channel) 05258 *locked_channel = chan; 05259 } 05260 pthread_attr_destroy(&attr); 05261 } 05262 } 05263 } else { 05264 if (option_verbose > 3) 05265 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05266 if (chan->cdr) { /* update the cdr */ 05267 /* here we update the status of the call, which sould be busy. 05268 * if that fails then we set the status to failed */ 05269 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05270 ast_cdr_failed(chan->cdr); 05271 } 05272 ast_hangup(chan); 05273 } 05274 } 05275 05276 if (res < 0) { /* the call failed for some reason */ 05277 if (*reason == 0) { /* if the call failed (not busy or no answer) 05278 * update the cdr with the failed message */ 05279 cdr_res = ast_pbx_outgoing_cdr_failed(); 05280 if (cdr_res != 0) { 05281 res = cdr_res; 05282 goto outgoing_app_cleanup; 05283 } 05284 } 05285 } 05286 05287 } else { 05288 struct async_stat *as; 05289 if (!(as = ast_calloc(1, sizeof(*as)))) { 05290 res = -1; 05291 goto outgoing_app_cleanup; 05292 } 05293 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05294 if (!chan) { 05295 free(as); 05296 res = -1; 05297 goto outgoing_app_cleanup; 05298 } 05299 as->chan = chan; 05300 ast_copy_string(as->app, app, sizeof(as->app)); 05301 if (appdata) 05302 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05303 as->timeout = timeout; 05304 ast_set_variables(chan, vars); 05305 if (account) 05306 ast_cdr_setaccount(chan, account); 05307 /* Start a new thread, and get something handling this channel. */ 05308 pthread_attr_init(&attr); 05309 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05310 if (locked_channel) 05311 ast_channel_lock(chan); 05312 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05313 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05314 free(as); 05315 if (locked_channel) 05316 ast_channel_unlock(chan); 05317 ast_hangup(chan); 05318 res = -1; 05319 pthread_attr_destroy(&attr); 05320 goto outgoing_app_cleanup; 05321 } else { 05322 if (locked_channel) 05323 *locked_channel = chan; 05324 } 05325 pthread_attr_destroy(&attr); 05326 res = 0; 05327 } 05328 outgoing_app_cleanup: 05329 ast_variables_destroy(vars); 05330 return res; 05331 }
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 5038 of file pbx.c.
References __ast_request_and_dial(), ast_channel::_state, 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_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create, ast_request_and_dial(), ast_set_variables(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, ast_channel::context, free, ast_channel::hangupcause, LOAD_OH, LOG_ERROR, LOG_WARNING, ast_channel::name, option_verbose, pbx_builtin_setvar_helper(), set_ext_pri(), outgoing_helper::vars, and VERBOSE_PREFIX_4.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_exten().
05039 { 05040 struct ast_channel *chan; 05041 struct async_stat *as; 05042 int res = -1, cdr_res = -1; 05043 struct outgoing_helper oh; 05044 pthread_attr_t attr; 05045 05046 if (sync) { 05047 LOAD_OH(oh); 05048 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05049 if (channel) { 05050 *channel = chan; 05051 if (chan) 05052 ast_channel_lock(chan); 05053 } 05054 if (chan) { 05055 if (chan->_state == AST_STATE_UP) { 05056 res = 0; 05057 if (option_verbose > 3) 05058 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05059 05060 if (sync > 1) { 05061 if (channel) 05062 ast_channel_unlock(chan); 05063 if (ast_pbx_run(chan)) { 05064 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05065 if (channel) 05066 *channel = NULL; 05067 ast_hangup(chan); 05068 chan = NULL; 05069 res = -1; 05070 } 05071 } else { 05072 if (ast_pbx_start(chan)) { 05073 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05074 if (channel) { 05075 *channel = NULL; 05076 ast_channel_unlock(chan); 05077 } 05078 ast_hangup(chan); 05079 res = -1; 05080 } 05081 chan = NULL; 05082 } 05083 } else { 05084 if (option_verbose > 3) 05085 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05086 05087 if (chan->cdr) { /* update the cdr */ 05088 /* here we update the status of the call, which sould be busy. 05089 * if that fails then we set the status to failed */ 05090 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05091 ast_cdr_failed(chan->cdr); 05092 } 05093 05094 if (channel) { 05095 *channel = NULL; 05096 ast_channel_unlock(chan); 05097 } 05098 ast_hangup(chan); 05099 chan = NULL; 05100 } 05101 } 05102 05103 if (res < 0) { /* the call failed for some reason */ 05104 if (*reason == 0) { /* if the call failed (not busy or no answer) 05105 * update the cdr with the failed message */ 05106 cdr_res = ast_pbx_outgoing_cdr_failed(); 05107 if (cdr_res != 0) { 05108 res = cdr_res; 05109 goto outgoing_exten_cleanup; 05110 } 05111 } 05112 05113 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05114 /* check if "failed" exists */ 05115 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05116 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05117 if (chan) { 05118 char failed_reason[4] = ""; 05119 if (!ast_strlen_zero(context)) 05120 ast_copy_string(chan->context, context, sizeof(chan->context)); 05121 set_ext_pri(chan, "failed", 1); 05122 ast_set_variables(chan, vars); 05123 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 05124 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 05125 if (account) 05126 ast_cdr_setaccount(chan, account); 05127 if (ast_pbx_run(chan)) { 05128 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05129 ast_hangup(chan); 05130 } 05131 chan = NULL; 05132 } 05133 } 05134 } 05135 } else { 05136 if (!(as = ast_calloc(1, sizeof(*as)))) { 05137 res = -1; 05138 goto outgoing_exten_cleanup; 05139 } 05140 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05141 if (channel) { 05142 *channel = chan; 05143 if (chan) 05144 ast_channel_lock(chan); 05145 } 05146 if (!chan) { 05147 free(as); 05148 res = -1; 05149 goto outgoing_exten_cleanup; 05150 } 05151 as->chan = chan; 05152 ast_copy_string(as->context, context, sizeof(as->context)); 05153 set_ext_pri(as->chan, exten, priority); 05154 as->timeout = timeout; 05155 ast_set_variables(chan, vars); 05156 if (account) 05157 ast_cdr_setaccount(chan, account); 05158 pthread_attr_init(&attr); 05159 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05160 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05161 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05162 free(as); 05163 if (channel) { 05164 *channel = NULL; 05165 ast_channel_unlock(chan); 05166 } 05167 ast_hangup(chan); 05168 res = -1; 05169 pthread_attr_destroy(&attr); 05170 goto outgoing_exten_cleanup; 05171 } 05172 pthread_attr_destroy(&attr); 05173 res = 0; 05174 } 05175 outgoing_exten_cleanup: 05176 ast_variables_destroy(vars); 05177 return res; 05178 }
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 |
Definition at line 2662 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_outgoing_exten(), async_wait(), do_idle_thread(), mgcp_ss(), skinny_newcall(), and ss_thread().
02663 { 02664 enum ast_pbx_result res = AST_PBX_SUCCESS; 02665 02666 if (increase_call_count(c)) 02667 return AST_PBX_CALL_LIMIT; 02668 02669 res = __ast_pbx_run(c); 02670 decrease_call_count(); 02671 02672 return res; 02673 }
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 |
Definition at line 2635 of file pbx.c.
References ast_log(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_pthread_create, decrease_call_count(), increase_call_count(), LOG_WARNING, pbx_thread(), and t.
Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_exten(), check_goto_on_transfer(), dahdi_new(), do_parking_thread(), gtalk_new(), gtalk_newcall(), handle_request_invite(), local_call(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), and skinny_new().
02636 { 02637 pthread_t t; 02638 pthread_attr_t attr; 02639 02640 if (!c) { 02641 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02642 return AST_PBX_FAILED; 02643 } 02644 02645 if (increase_call_count(c)) 02646 return AST_PBX_CALL_LIMIT; 02647 02648 /* Start a new thread, and get something handling this channel. */ 02649 pthread_attr_init(&attr); 02650 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02651 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02652 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02653 pthread_attr_destroy(&attr); 02654 decrease_call_count(); 02655 return AST_PBX_FAILED; 02656 } 02657 pthread_attr_destroy(&attr); 02658 02659 return AST_PBX_SUCCESS; 02660 }
int ast_processed_calls | ( | void | ) |
Retrieve the total number of calls processed through the PBX since last restart.
Definition at line 2680 of file pbx.c.
References totalcalls.
02681 { 02682 return totalcalls; 02683 }
int ast_rdlock_contexts | ( | void | ) |
Definition at line 6288 of file pbx.c.
References ast_rwlock_rdlock(), and conlock.
Referenced by __ast_context_create(), _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_hint_extension(), ast_hint_state_changed(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), handle_save_dialplan(), pbx_extension_helper(), and show_dialplan_helper().
06289 { 06290 return ast_rwlock_rdlock(&conlock); 06291 }
int ast_register_application | ( | const char * | app, | |
int(*)(struct ast_channel *, void *) | execute, | |||
const char * | synopsis, | |||
const char * | description | |||
) |
Register an application.
app | Short name of the application | |
execute | a function callback to execute the application. It should return non-zero if the channel needs to be hung up. | |
synopsis | a short description (one line synopsis) of the application | |
description | long description with all of the details about the use of the application |
0 | success | |
-1 | failure. |
Definition at line 2969 of file pbx.c.
References ast_calloc, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), COLOR_BRCYAN, ast_app::description, ast_app::execute, ast_app::list, LOG_WARNING, ast_app::name, option_verbose, ast_app::synopsis, term_color(), and VERBOSE_PREFIX_2.
Referenced by load_module(), and load_pbx().
02970 { 02971 struct ast_app *tmp, *cur = NULL; 02972 char tmps[80]; 02973 int length; 02974 02975 AST_LIST_LOCK(&apps); 02976 AST_LIST_TRAVERSE(&apps, tmp, list) { 02977 if (!strcasecmp(app, tmp->name)) { 02978 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02979 AST_LIST_UNLOCK(&apps); 02980 return -1; 02981 } 02982 } 02983 02984 length = sizeof(*tmp) + strlen(app) + 1; 02985 02986 if (!(tmp = ast_calloc(1, length))) { 02987 AST_LIST_UNLOCK(&apps); 02988 return -1; 02989 } 02990 02991 strcpy(tmp->name, app); 02992 tmp->execute = execute; 02993 tmp->synopsis = synopsis; 02994 tmp->description = description; 02995 02996 /* Store in alphabetical order */ 02997 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 02998 if (strcasecmp(tmp->name, cur->name) < 0) { 02999 AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 03000 break; 03001 } 03002 } 03003 AST_LIST_TRAVERSE_SAFE_END 03004 if (!cur) 03005 AST_LIST_INSERT_TAIL(&apps, tmp, list); 03006 03007 if (option_verbose > 1) 03008 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 03009 03010 AST_LIST_UNLOCK(&apps); 03011 03012 return 0; 03013 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 3019 of file pbx.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_switch::list, LOG_WARNING, and ast_switch::name.
Referenced by load_module().
03020 { 03021 struct ast_switch *tmp; 03022 03023 AST_LIST_LOCK(&switches); 03024 AST_LIST_TRAVERSE(&switches, tmp, list) { 03025 if (!strcasecmp(tmp->name, sw->name)) { 03026 AST_LIST_UNLOCK(&switches); 03027 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 03028 return -1; 03029 } 03030 } 03031 AST_LIST_INSERT_TAIL(&switches, sw, list); 03032 AST_LIST_UNLOCK(&switches); 03033 03034 return 0; 03035 }
int ast_spawn_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) |
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 |
0 | on success | |
-1 | on failure. |
Definition at line 2307 of file pbx.c.
References E_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), _macro_exec(), ast_bridge_call(), and loopback_exec().
02308 { 02309 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN); 02310 }
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 6311 of file pbx.c.
References ast_mutex_unlock(), and ast_context::lock.
Referenced by _macro_exec(), complete_context_dont_include_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), lookup_c_ip(), lookup_ci(), and show_dialplan_helper().
06312 { 06313 return ast_mutex_unlock(&con->lock); 06314 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 6298 of file pbx.c.
References ast_rwlock_unlock(), and conlock.
Referenced by __ast_context_create(), _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_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_hint_state_changed(), ast_merge_contexts_and_delete(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_save_dialplan(), pbx_extension_helper(), and show_dialplan_helper().
06299 { 06300 return ast_rwlock_unlock(&conlock); 06301 }
int ast_unregister_application | ( | const char * | app | ) |
Unregister an application.
app | name of the application (does not have to be the same string as the one that was registered) |
0 | success | |
-1 | failure |
Definition at line 3884 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), free, ast_app::list, ast_app::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by __unload_module(), and unload_module().
03885 { 03886 struct ast_app *tmp; 03887 03888 AST_LIST_LOCK(&apps); 03889 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03890 if (!strcasecmp(app, tmp->name)) { 03891 AST_LIST_REMOVE_CURRENT(&apps, list); 03892 if (option_verbose > 1) 03893 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03894 free(tmp); 03895 break; 03896 } 03897 } 03898 AST_LIST_TRAVERSE_SAFE_END 03899 AST_LIST_UNLOCK(&apps); 03900 03901 return tmp ? 0 : -1; 03902 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 3037 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, and ast_switch::list.
Referenced by __unload_module(), and unload_module().
03038 { 03039 AST_LIST_LOCK(&switches); 03040 AST_LIST_REMOVE(&switches, sw, list); 03041 AST_LIST_UNLOCK(&switches); 03042 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | priority | |||
) |
Definition at line 6420 of file pbx.c.
References exten, and ast_context::root.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), dundi_precache_full(), find_matching_priority(), handle_save_dialplan(), pbx_find_extension(), and show_dialplan_helper().
06422 { 06423 if (!exten) 06424 return con ? con->root : NULL; 06425 else 06426 return exten->next; 06427 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 6453 of file pbx.c.
References ast_context::ignorepats, and ast_ignorepat::next.
Referenced by complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), handle_save_dialplan(), lookup_c_ip(), and show_dialplan_helper().
06455 { 06456 if (!ip) 06457 return con ? con->ignorepats : NULL; 06458 else 06459 return ip->next; 06460 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 6444 of file pbx.c.
References ast_context::includes, and ast_include::next.
Referenced by ast_context_verify_includes(), complete_context_dont_include_deprecated(), complete_context_remove_include(), find_matching_priority(), handle_save_dialplan(), lookup_ci(), and show_dialplan_helper().
06446 { 06447 if (!inc) 06448 return con ? con->includes : NULL; 06449 else 06450 return inc->next; 06451 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 6429 of file pbx.c.
References ast_context::alts, AST_LIST_FIRST, AST_LIST_NEXT, and ast_sw::list.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06431 { 06432 if (!sw) 06433 return con ? AST_LIST_FIRST(&con->alts) : NULL; 06434 else 06435 return AST_LIST_NEXT(sw, list); 06436 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 6415 of file pbx.c.
References contexts, and ast_context::next.
Referenced by _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), pbx_find_extension(), pbx_load_module(), and show_dialplan_helper().
struct ast_exten* ast_walk_extension_priorities | ( | struct ast_exten * | exten, | |
struct ast_exten * | priority | |||
) |
Definition at line 6438 of file pbx.c.
References exten, and ast_exten::priority.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), handle_save_dialplan(), pbx_find_extension(), and show_dialplan_helper().
int ast_wrlock_contexts | ( | void | ) |
Definition at line 6293 of file pbx.c.
References ast_rwlock_wrlock(), and conlock.
Referenced by ast_context_destroy(), ast_merge_contexts_and_delete(), and complete_context_dont_include_deprecated().
06294 { 06295 return ast_rwlock_wrlock(&conlock); 06296 }
void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 6059 of file pbx.c.
References AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), ast_var_delete(), ast_var_t::entries, globals, and globalslock.
Referenced by handle_reload_extensions(), and reload().
06060 { 06061 struct ast_var_t *vardata; 06062 06063 ast_mutex_lock(&globalslock); 06064 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06065 ast_var_delete(vardata); 06066 ast_mutex_unlock(&globalslock); 06067 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5836 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), globals, and globalslock.
Referenced by __login_exec(), _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), ast_bridge_call(), ast_call_forward(), ast_monitor_stop(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dahdi_call(), dahdi_hangup(), dundi_exec(), dundi_helper(), feature_interpret(), get_also_info(), get_index(), get_refer_info(), global_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), macro_fixup(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_call_full(), park_space_reserve(), pickup_by_mark(), queue_exec(), real_ctx(), retrydial_exec(), return_exec(), ring_entry(), run_agi(), set_config_flags(), sip_addheader(), sla_trunk_exec(), speech_background(), try_suggested_sip_codec(), update_bridgepeer(), and wait_for_answer().
05837 { 05838 struct ast_var_t *variables; 05839 const char *ret = NULL; 05840 int i; 05841 struct varshead *places[2] = { NULL, &globals }; 05842 05843 if (!name) 05844 return NULL; 05845 05846 if (chan) { 05847 ast_channel_lock(chan); 05848 places[0] = &chan->varshead; 05849 } 05850 05851 for (i = 0; i < 2; i++) { 05852 if (!places[i]) 05853 continue; 05854 if (places[i] == &globals) 05855 ast_mutex_lock(&globalslock); 05856 AST_LIST_TRAVERSE(places[i], variables, entries) { 05857 if (!strcmp(name, ast_var_name(variables))) { 05858 ret = ast_var_value(variables); 05859 break; 05860 } 05861 } 05862 if (places[i] == &globals) 05863 ast_mutex_unlock(&globalslock); 05864 if (ret) 05865 break; 05866 } 05867 05868 if (chan) 05869 ast_channel_unlock(chan); 05870 05871 return ret; 05872 }
void pbx_builtin_pushvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5874 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_verbose(), globals, globalslock, LOG_WARNING, option_verbose, and VERBOSE_PREFIX_2.
Referenced by acf_odbc_read(), acf_odbc_write(), and gosub_exec().
05875 { 05876 struct ast_var_t *newvariable; 05877 struct varshead *headp; 05878 05879 if (name[strlen(name)-1] == ')') { 05880 char *function = ast_strdupa(name); 05881 05882 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05883 ast_func_write(chan, function, value); 05884 return; 05885 } 05886 05887 if (chan) { 05888 ast_channel_lock(chan); 05889 headp = &chan->varshead; 05890 } else { 05891 ast_mutex_lock(&globalslock); 05892 headp = &globals; 05893 } 05894 05895 if (value) { 05896 if ((option_verbose > 1) && (headp == &globals)) 05897 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05898 newvariable = ast_var_assign(name, value); 05899 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05900 } 05901 05902 if (chan) 05903 ast_channel_unlock(chan); 05904 else 05905 ast_mutex_unlock(&globalslock); 05906 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5805 of file pbx.c.
References ast_build_string(), ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_var_name(), ast_var_value(), ast_var_t::entries, LOG_ERROR, total, var, and ast_channel::varshead.
Referenced by dumpchan_exec(), handle_showchan(), handle_showchan_deprecated(), and vars2manager().
05806 { 05807 struct ast_var_t *variables; 05808 const char *var, *val; 05809 int total = 0; 05810 05811 if (!chan) 05812 return 0; 05813 05814 memset(buf, 0, size); 05815 05816 ast_channel_lock(chan); 05817 05818 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05819 if ((var=ast_var_name(variables)) && (val=ast_var_value(variables)) 05820 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 05821 ) { 05822 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05823 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05824 break; 05825 } else 05826 total++; 05827 } else 05828 break; 05829 } 05830 05831 ast_channel_unlock(chan); 05832 05833 return total; 05834 }
int pbx_builtin_setvar | ( | struct ast_channel * | chan, | |
void * | data | |||
) |
void pbx_builtin_setvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5908 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_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verbose(), globals, globalslock, option_verbose, and VERBOSE_PREFIX_2.
Referenced by __oh323_new(), _macro_exec(), _while_exec(), acf_odbc_read(), acf_odbc_write(), action_setvar(), agi_exec_full(), aji_status_exec(), aqm_exec(), array(), ast_bridge_call(), ast_feature_request_and_dial(), ast_iax2_new(), ast_monitor_start(), ast_pbx_outgoing_exten(), ast_set_variables(), background_detect_exec(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), controlplayback_exec(), count_exec(), dahdi_handle_dtmfup(), dahdi_new(), disa_exec(), do_waiting(), end_bridge_callback(), export_aoc_vars(), export_ch(), function_db_delete(), function_db_exists(), function_db_read(), global_write(), handle_request_bye(), handle_request_refer(), handle_set_global(), handle_set_global_deprecated(), handle_setvariable(), hasvoicemail_exec(), isAnsweringMachine(), leave_voicemail(), local_hangup(), lookupblacklist_exec(), macro_fixup(), misdn_call(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_exec(), parse_moved_contact(), pbx_builtin_importvar(), pbx_builtin_saydate(), pbx_builtin_saytime(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_load_config(), play_message_datetime(), playback_exec(), pop_exec(), pqm_exec(), prep_email_sub_vars(), privacy_exec(), process_ast_dsp(), read_exec(), readfile_exec(), realtime_exec(), realtime_update_exec(), record_exec(), return_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_hangup(), sip_new(), sla_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), ss_thread(), start_monitor_exec(), system_exec_helper(), transfer_exec(), tryexec_exec(), update_bridgepeer(), upqm_exec(), vm_box_exists(), vm_exec(), and vmauthenticate().
05909 { 05910 struct ast_var_t *newvariable; 05911 struct varshead *headp; 05912 const char *nametail = name; 05913 05914 if (name[strlen(name)-1] == ')') { 05915 char *function = ast_strdupa(name); 05916 05917 ast_func_write(chan, function, value); 05918 return; 05919 } 05920 05921 if (chan) { 05922 ast_channel_lock(chan); 05923 headp = &chan->varshead; 05924 } else { 05925 ast_mutex_lock(&globalslock); 05926 headp = &globals; 05927 } 05928 05929 /* For comparison purposes, we have to strip leading underscores */ 05930 if (*nametail == '_') { 05931 nametail++; 05932 if (*nametail == '_') 05933 nametail++; 05934 } 05935 05936 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05937 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 05938 /* there is already such a variable, delete it */ 05939 AST_LIST_REMOVE(headp, newvariable, entries); 05940 ast_var_delete(newvariable); 05941 break; 05942 } 05943 } 05944 05945 if (value) { 05946 if ((option_verbose > 1) && (headp == &globals)) 05947 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05948 newvariable = ast_var_assign(name, value); 05949 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05950 } 05951 05952 if (chan) 05953 ast_channel_unlock(chan); 05954 else 05955 ast_mutex_unlock(&globalslock); 05956 }
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 6069 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().
06070 { 06071 if (ast_strlen_zero(condition)) /* NULL or empty strings are false */ 06072 return 0; 06073 else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */ 06074 return atoi(condition); 06075 else /* Strings are true */ 06076 return 1; 06077 }
int pbx_exec | ( | struct ast_channel * | c, | |
struct ast_app * | app, | |||
void * | data | |||
) |
Execute an application.
c | channel to execute on | |
app | which app to execute | |
data | the data passed into the app |
c | Channel |
app | Application |
data | Data for execution |
Definition at line 537 of file pbx.c.
References app, ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_channel::cdr, ast_channel::data, and S_OR.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), milliwatt_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), and tryexec_exec().
00540 { 00541 int res; 00542 00543 const char *saved_c_appl; 00544 const char *saved_c_data; 00545 00546 if (c->cdr && !ast_check_hangup(c)) 00547 ast_cdr_setapp(c->cdr, app->name, data); 00548 00549 /* save channel values */ 00550 saved_c_appl= c->appl; 00551 saved_c_data= c->data; 00552 00553 c->appl = app->name; 00554 c->data = data; 00555 /* XXX remember what to to when we have linked apps to modules */ 00556 if (app->module) { 00557 /* XXX LOCAL_USER_ADD(app->module) */ 00558 } 00559 res = app->execute(c, S_OR(data, "")); 00560 if (app->module) { 00561 /* XXX LOCAL_USER_REMOVE(app->module) */ 00562 } 00563 /* restore channel values */ 00564 c->appl = saved_c_appl; 00565 c->data = saved_c_data; 00566 return res; 00567 }
struct ast_app* pbx_findapp | ( | const char * | app | ) |
Look up an application.
app | name of the app |
Definition at line 575 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sw::list, and ast_app::name.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), milliwatt_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), and tryexec_exec().
00576 { 00577 struct ast_app *tmp; 00578 00579 AST_LIST_LOCK(&apps); 00580 AST_LIST_TRAVERSE(&apps, tmp, list) { 00581 if (!strcasecmp(tmp->name, app)) 00582 break; 00583 } 00584 AST_LIST_UNLOCK(&apps); 00585 00586 return tmp; 00587 }
void pbx_retrieve_variable | ( | struct ast_channel * | c, | |
const char * | var, | |||
char ** | ret, | |||
char * | workspace, | |||
int | workspacelen, | |||
struct varshead * | headp | |||
) |
pbx_retrieve_variable: Support for Asterisk built-in variables ---
Definition at line 1174 of file pbx.c.
References ast_cause2str(), ast_channel_lock, ast_channel_unlock, ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_get_hint(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_name(), ast_var_value(), ast_channel::cid, ast_callerid::cid_ani2, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, globals, globalslock, ast_channel::hangupcause, ast_channel::name, offset, parse_variable_name(), ast_channel::priority, s, substring(), and ast_channel::uniqueid.
Referenced by action_getvar(), handle_getvariable(), and pbx_substitute_variables_helper_full().
01175 { 01176 const char not_found = '\0'; 01177 char *tmpvar; 01178 const char *s; /* the result */ 01179 int offset, length; 01180 int i, need_substring; 01181 struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */ 01182 01183 if (c) { 01184 ast_channel_lock(c); 01185 places[0] = &c->varshead; 01186 } 01187 /* 01188 * Make a copy of var because parse_variable_name() modifies the string. 01189 * Then if called directly, we might need to run substring() on the result; 01190 * remember this for later in 'need_substring', 'offset' and 'length' 01191 */ 01192 tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */ 01193 need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */); 01194 01195 /* 01196 * Look first into predefined variables, then into variable lists. 01197 * Variable 's' points to the result, according to the following rules: 01198 * s == ¬_found (set at the beginning) means that we did not find a 01199 * matching variable and need to look into more places. 01200 * If s != ¬_found, s is a valid result string as follows: 01201 * s = NULL if the variable does not have a value; 01202 * you typically do this when looking for an unset predefined variable. 01203 * s = workspace if the result has been assembled there; 01204 * typically done when the result is built e.g. with an snprintf(), 01205 * so we don't need to do an additional copy. 01206 * s != workspace in case we have a string, that needs to be copied 01207 * (the ast_copy_string is done once for all at the end). 01208 * Typically done when the result is already available in some string. 01209 */ 01210 s = ¬_found; /* default value */ 01211 if (c) { /* This group requires a valid channel */ 01212 /* Names with common parts are looked up a piece at a time using strncmp. */ 01213 if (!strncmp(var, "CALL", 4)) { 01214 if (!strncmp(var + 4, "ING", 3)) { 01215 if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */ 01216 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 01217 s = workspace; 01218 } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */ 01219 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 01220 s = workspace; 01221 } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */ 01222 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 01223 s = workspace; 01224 } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */ 01225 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 01226 s = workspace; 01227 } 01228 } 01229 } else if (!strcmp(var, "HINT")) { 01230 s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL; 01231 } else if (!strcmp(var, "HINTNAME")) { 01232 s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL; 01233 } else if (!strcmp(var, "EXTEN")) { 01234 s = c->exten; 01235 } else if (!strcmp(var, "CONTEXT")) { 01236 s = c->context; 01237 } else if (!strcmp(var, "PRIORITY")) { 01238 snprintf(workspace, workspacelen, "%d", c->priority); 01239 s = workspace; 01240 } else if (!strcmp(var, "CHANNEL")) { 01241 s = c->name; 01242 } else if (!strcmp(var, "UNIQUEID")) { 01243 s = c->uniqueid; 01244 } else if (!strcmp(var, "HANGUPCAUSE")) { 01245 snprintf(workspace, workspacelen, "%d", c->hangupcause); 01246 s = workspace; 01247 } else if (c && !strcmp(var, "HANGUPCAUSESTR")) { 01248 ast_copy_string(workspace, ast_cause2str(c->hangupcause), workspacelen); 01249 *ret = workspace; 01250 } 01251 } 01252 if (s == ¬_found) { /* look for more */ 01253 if (!strcmp(var, "EPOCH")) { 01254 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 01255 s = workspace; 01256 } else if (!strcmp(var, "SYSTEMNAME")) { 01257 s = ast_config_AST_SYSTEM_NAME; 01258 } 01259 } 01260 /* if not found, look into chanvars or global vars */ 01261 for (i = 0; s == ¬_found && i < (sizeof(places) / sizeof(places[0])); i++) { 01262 struct ast_var_t *variables; 01263 if (!places[i]) 01264 continue; 01265 if (places[i] == &globals) 01266 ast_mutex_lock(&globalslock); 01267 AST_LIST_TRAVERSE(places[i], variables, entries) { 01268 if (strcasecmp(ast_var_name(variables), var)==0) { 01269 s = ast_var_value(variables); 01270 break; 01271 } 01272 } 01273 if (places[i] == &globals) 01274 ast_mutex_unlock(&globalslock); 01275 } 01276 if (s == ¬_found || s == NULL) 01277 *ret = NULL; 01278 else { 01279 if (s != workspace) 01280 ast_copy_string(workspace, s, workspacelen); 01281 *ret = workspace; 01282 if (need_substring) 01283 *ret = substring(*ret, offset, length, workspace, workspacelen); 01284 } 01285 01286 if (c) 01287 ast_channel_unlock(c); 01288 }
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 2685 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
02686 { 02687 int oldval = autofallthrough; 02688 autofallthrough = newval; 02689 return oldval; 02690 }
void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1794 of file pbx.c.
References pbx_substitute_variables_helper_full(), and ast_channel::varshead.
Referenced by _macro_exec(), acf_odbc_read(), acf_odbc_write(), add_extensions(), custom_log(), cut_internal(), exec_exec(), function_eval(), function_fieldqty(), handle_getvariablefull(), launch_monitor_thread(), make_email_file(), pbx_builtin_importvar(), pbx_load_config(), pbx_substitute_variables(), realtime_exec(), rpt_do_lstats(), sendpage(), and tryexec_exec().
01795 { 01796 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 01797 }
void pbx_substitute_variables_varshead | ( | struct varshead * | headp, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1799 of file pbx.c.
References pbx_substitute_variables_helper_full().
Referenced by ast_add_extension2(), dundi_lookup_local(), and loopback_subst().
01800 { 01801 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 01802 }