#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 2693 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02694 { 02695 return countcalls; 02696 }
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 4614 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().
04617 { 04618 int ret = -1; 04619 struct ast_context *c = find_context_locked(context); 04620 04621 if (c) { 04622 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04623 application, data, datad, registrar); 04624 ast_unlock_contexts(); 04625 } 04626 return ret; 04627 }
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 4829 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().
04833 { 04834 /* 04835 * Sort extensions (or patterns) according to the rules indicated above. 04836 * These are implemented by the function ext_cmp()). 04837 * All priorities for the same ext/pattern/cid are kept in a list, 04838 * using the 'peer' field as a link field.. 04839 */ 04840 struct ast_exten *tmp, *e, *el = NULL; 04841 int res; 04842 int length; 04843 char *p; 04844 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04845 04846 /* if we are adding a hint, and there are global variables, and the hint 04847 contains variable references, then expand them 04848 */ 04849 ast_mutex_lock(&globalslock); 04850 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04851 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04852 application = expand_buf; 04853 } 04854 ast_mutex_unlock(&globalslock); 04855 04856 length = sizeof(struct ast_exten); 04857 length += strlen(extension) + 1; 04858 length += strlen(application) + 1; 04859 if (label) 04860 length += strlen(label) + 1; 04861 if (callerid) 04862 length += strlen(callerid) + 1; 04863 else 04864 length ++; /* just the '\0' */ 04865 04866 /* Be optimistic: Build the extension structure first */ 04867 if (!(tmp = ast_calloc(1, length))) 04868 return -1; 04869 04870 /* use p as dst in assignments, as the fields are const char * */ 04871 p = tmp->stuff; 04872 if (label) { 04873 tmp->label = p; 04874 strcpy(p, label); 04875 p += strlen(label) + 1; 04876 } 04877 tmp->exten = p; 04878 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04879 tmp->priority = priority; 04880 tmp->cidmatch = p; /* but use p for assignments below */ 04881 if (callerid) { 04882 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04883 tmp->matchcid = 1; 04884 } else { 04885 *p++ = '\0'; 04886 tmp->matchcid = 0; 04887 } 04888 tmp->app = p; 04889 strcpy(p, application); 04890 tmp->parent = con; 04891 tmp->data = data; 04892 tmp->datad = datad; 04893 tmp->registrar = registrar; 04894 04895 ast_mutex_lock(&con->lock); 04896 res = 0; /* some compilers will think it is uninitialized otherwise */ 04897 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04898 res = ext_cmp(e->exten, tmp->exten); 04899 if (res == 0) { /* extension match, now look at cidmatch */ 04900 if (!e->matchcid && !tmp->matchcid) 04901 res = 0; 04902 else if (tmp->matchcid && !e->matchcid) 04903 res = 1; 04904 else if (e->matchcid && !tmp->matchcid) 04905 res = -1; 04906 else 04907 res = ext_cmp(e->cidmatch, tmp->cidmatch); 04908 } 04909 if (res >= 0) 04910 break; 04911 } 04912 if (e && res == 0) { /* exact match, insert in the pri chain */ 04913 res = add_pri(con, tmp, el, e, replace); 04914 ast_mutex_unlock(&con->lock); 04915 if (res < 0) { 04916 errno = EEXIST; /* XXX do we care ? */ 04917 return 0; /* XXX should we return -1 maybe ? */ 04918 } 04919 } else { 04920 /* 04921 * not an exact match, this is the first entry with this pattern, 04922 * so insert in the main list right before 'e' (if any) 04923 */ 04924 tmp->next = e; 04925 if (el) 04926 el->next = tmp; 04927 else 04928 con->root = tmp; 04929 ast_mutex_unlock(&con->lock); 04930 if (tmp->priority == PRIORITY_HINT) 04931 ast_add_hint(tmp); 04932 } 04933 if (option_debug) { 04934 if (tmp->matchcid) { 04935 if (option_debug) 04936 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04937 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04938 } else { 04939 if (option_debug) 04940 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04941 tmp->exten, tmp->priority, con->name); 04942 } 04943 } 04944 if (option_verbose > 2) { 04945 if (tmp->matchcid) { 04946 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04947 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04948 } else { 04949 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04950 tmp->exten, tmp->priority, con->name); 04951 } 04952 } 04953 return 0; 04954 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4652 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().
04653 { 04654 int res = 0; 04655 04656 ast_channel_lock(chan); 04657 04658 if (chan->pbx) { /* This channel is currently in the PBX */ 04659 ast_explicit_goto(chan, context, exten, priority); 04660 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04661 } else { 04662 /* In order to do it when the channel doesn't really exist within 04663 the PBX, we have to make a new channel, masquerade, and start the PBX 04664 at the new location */ 04665 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04666 if (!tmpchan) { 04667 res = -1; 04668 } else { 04669 if (chan->cdr) { 04670 ast_cdr_discard(tmpchan->cdr); 04671 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 04672 } 04673 /* Make formats okay */ 04674 tmpchan->readformat = chan->readformat; 04675 tmpchan->writeformat = chan->writeformat; 04676 /* Setup proper location */ 04677 ast_explicit_goto(tmpchan, 04678 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04679 04680 /* Masquerade into temp channel */ 04681 if (ast_channel_masquerade(tmpchan, chan)) { 04682 /* Failed to set up the masquerade. It's probably chan_local 04683 * in the middle of optimizing itself out. Sad. :( */ 04684 ast_hangup(tmpchan); 04685 tmpchan = NULL; 04686 res = -1; 04687 } else { 04688 /* Grab the locks and get going */ 04689 ast_channel_lock(tmpchan); 04690 ast_do_masquerade(tmpchan); 04691 ast_channel_unlock(tmpchan); 04692 /* Start the PBX going on our stolen channel */ 04693 if (ast_pbx_start(tmpchan)) { 04694 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04695 ast_hangup(tmpchan); 04696 res = -1; 04697 } 04698 } 04699 } 04700 } 04701 ast_channel_unlock(chan); 04702 return res; 04703 }
int ast_async_goto_by_name | ( | const char * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4705 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04706 { 04707 struct ast_channel *chan; 04708 int res = -1; 04709 04710 chan = ast_get_channel_by_name_locked(channame); 04711 if (chan) { 04712 res = ast_async_goto(chan, context, exten, priority); 04713 ast_channel_unlock(chan); 04714 } 04715 return res; 04716 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6538 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06539 { 06540 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06541 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info | |||
) |
Definition at line 4292 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().
04293 { 04294 char info_save[256]; 04295 char *info; 04296 04297 /* Check for empty just in case */ 04298 if (ast_strlen_zero(info_in)) 04299 return 0; 04300 /* make a copy just in case we were passed a static string */ 04301 ast_copy_string(info_save, info_in, sizeof(info_save)); 04302 info = info_save; 04303 /* Assume everything except time */ 04304 i->monthmask = 0xfff; /* 12 bits */ 04305 i->daymask = 0x7fffffffU; /* 31 bits */ 04306 i->dowmask = 0x7f; /* 7 bits */ 04307 /* on each call, use strsep() to move info to the next argument */ 04308 get_timerange(i, strsep(&info, "|")); 04309 if (info) 04310 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04311 if (info) 04312 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04313 if (info) 04314 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04315 return 1; 04316 }
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 2314 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(), pbx_builtin_background(), phone_check_exception(), skinny_ss(), ss_thread(), and valid_exit().
02315 { 02316 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH); 02317 }
int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 4318 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().
04319 { 04320 struct tm tm; 04321 time_t t = time(NULL); 04322 04323 ast_localtime(&t, &tm, NULL); 04324 04325 /* If it's not the right month, return */ 04326 if (!(i->monthmask & (1 << tm.tm_mon))) 04327 return 0; 04328 04329 /* If it's not that time of the month.... */ 04330 /* Warning, tm_mday has range 1..31! */ 04331 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04332 return 0; 04333 04334 /* If it's not the right day of the week */ 04335 if (!(i->dowmask & (1 << tm.tm_wday))) 04336 return 0; 04337 04338 /* Sanity check the hour just to be safe */ 04339 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04340 ast_log(LOG_WARNING, "Insane time...\n"); 04341 return 0; 04342 } 04343 04344 /* Now the tough part, we calculate if it fits 04345 in the right time based on min/hour */ 04346 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04347 return 0; 04348 04349 /* If we got this far, then we're good */ 04350 return 1; 04351 }
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 4545 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().
04546 { 04547 int ret = -1; 04548 struct ast_context *c = find_context_locked(context); 04549 04550 if (c) { 04551 ret = ast_context_add_ignorepat2(c, value, registrar); 04552 ast_unlock_contexts(); 04553 } 04554 return ret; 04555 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4557 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().
04558 { 04559 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04560 int length; 04561 char *pattern; 04562 length = sizeof(struct ast_ignorepat); 04563 length += strlen(value) + 1; 04564 if (!(ignorepat = ast_calloc(1, length))) 04565 return -1; 04566 /* The cast to char * is because we need to write the initial value. 04567 * The field is not supposed to be modified otherwise. Also, gcc 4.2 04568 * sees the cast as dereferencing a type-punned pointer and warns about 04569 * it. This is the workaround (we're telling gcc, yes, that's really 04570 * what we wanted to do). 04571 */ 04572 pattern = (char *) ignorepat->pattern; 04573 strcpy(pattern, value); 04574 ignorepat->next = NULL; 04575 ignorepat->registrar = registrar; 04576 ast_mutex_lock(&con->lock); 04577 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04578 ignorepatl = ignorepatc; 04579 if (!strcasecmp(ignorepatc->pattern, value)) { 04580 /* Already there */ 04581 ast_mutex_unlock(&con->lock); 04582 errno = EEXIST; 04583 return -1; 04584 } 04585 } 04586 if (ignorepatl) 04587 ignorepatl->next = ignorepat; 04588 else 04589 con->ignorepats = ignorepat; 04590 ast_mutex_unlock(&con->lock); 04591 return 0; 04592 04593 }
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 4098 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().
04099 { 04100 int ret = -1; 04101 struct ast_context *c = find_context_locked(context); 04102 04103 if (c) { 04104 ret = ast_context_add_include2(c, include, registrar); 04105 ast_unlock_contexts(); 04106 } 04107 return ret; 04108 }
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 4360 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().
04362 { 04363 struct ast_include *new_include; 04364 char *c; 04365 struct ast_include *i, *il = NULL; /* include, include_last */ 04366 int length; 04367 char *p; 04368 04369 length = sizeof(struct ast_include); 04370 length += 2 * (strlen(value) + 1); 04371 04372 /* allocate new include structure ... */ 04373 if (!(new_include = ast_calloc(1, length))) 04374 return -1; 04375 /* Fill in this structure. Use 'p' for assignments, as the fields 04376 * in the structure are 'const char *' 04377 */ 04378 p = new_include->stuff; 04379 new_include->name = p; 04380 strcpy(p, value); 04381 p += strlen(value) + 1; 04382 new_include->rname = p; 04383 strcpy(p, value); 04384 /* Strip off timing info, and process if it is there */ 04385 if ( (c = strchr(p, '|')) ) { 04386 *c++ = '\0'; 04387 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04388 } 04389 new_include->next = NULL; 04390 new_include->registrar = registrar; 04391 04392 ast_mutex_lock(&con->lock); 04393 04394 /* ... go to last include and check if context is already included too... */ 04395 for (i = con->includes; i; i = i->next) { 04396 if (!strcasecmp(i->name, new_include->name)) { 04397 free(new_include); 04398 ast_mutex_unlock(&con->lock); 04399 errno = EEXIST; 04400 return -1; 04401 } 04402 il = i; 04403 } 04404 04405 /* ... include new context into context list, unlock, return */ 04406 if (il) 04407 il->next = new_include; 04408 else 04409 con->includes = new_include; 04410 if (option_verbose > 2) 04411 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04412 ast_mutex_unlock(&con->lock); 04413 04414 return 0; 04415 }
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 4422 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04423 { 04424 int ret = -1; 04425 struct ast_context *c = find_context_locked(context); 04426 04427 if (c) { /* found, add switch to this context */ 04428 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04429 ast_unlock_contexts(); 04430 } 04431 return ret; 04432 }
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 4441 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().
04443 { 04444 struct ast_sw *new_sw; 04445 struct ast_sw *i; 04446 int length; 04447 char *p; 04448 04449 length = sizeof(struct ast_sw); 04450 length += strlen(value) + 1; 04451 if (data) 04452 length += strlen(data); 04453 length++; 04454 04455 /* allocate new sw structure ... */ 04456 if (!(new_sw = ast_calloc(1, length))) 04457 return -1; 04458 /* ... fill in this structure ... */ 04459 p = new_sw->stuff; 04460 new_sw->name = p; 04461 strcpy(new_sw->name, value); 04462 p += strlen(value) + 1; 04463 new_sw->data = p; 04464 if (data) { 04465 strcpy(new_sw->data, data); 04466 p += strlen(data) + 1; 04467 } else { 04468 strcpy(new_sw->data, ""); 04469 p++; 04470 } 04471 new_sw->eval = eval; 04472 new_sw->registrar = registrar; 04473 04474 /* ... try to lock this context ... */ 04475 ast_mutex_lock(&con->lock); 04476 04477 /* ... go to last sw and check if context is already swd too... */ 04478 AST_LIST_TRAVERSE(&con->alts, i, list) { 04479 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04480 free(new_sw); 04481 ast_mutex_unlock(&con->lock); 04482 errno = EEXIST; 04483 return -1; 04484 } 04485 } 04486 04487 /* ... sw new context into context list, unlock, return */ 04488 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04489 04490 if (option_verbose > 2) 04491 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04492 04493 ast_mutex_unlock(&con->lock); 04494 04495 return 0; 04496 }
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 3968 of file pbx.c.
References __ast_context_create().
Referenced by do_parking_thread(), park_call_full(), and set_config().
03969 { 03970 return __ast_context_create(extcontexts, name, registrar, 0); 03971 }
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 5410 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().
05411 { 05412 ast_wrlock_contexts(); 05413 __ast_context_destroy(con,registrar); 05414 ast_unlock_contexts(); 05415 }
struct ast_context* ast_context_find | ( | const char * | name | ) |
Find a context.
name | name of the context to find |
Definition at line 934 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().
00935 { 00936 struct ast_context *tmp = NULL; 00937 00938 ast_rdlock_contexts(); 00939 00940 while ( (tmp = ast_walk_contexts(tmp)) ) { 00941 if (!name || !strcasecmp(name, tmp->name)) 00942 break; 00943 } 00944 00945 ast_unlock_contexts(); 00946 00947 return tmp; 00948 }
struct ast_context* ast_context_find_or_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar | |||
) |
Definition at line 3973 of file pbx.c.
References __ast_context_create().
Referenced by pbx_load_config(), and pbx_load_users().
03974 { 03975 return __ast_context_create(extcontexts, name, registrar, 1); 03976 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 2935 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().
02936 { 02937 struct ast_context *c = NULL; 02938 int ret = -1; 02939 02940 ast_rdlock_contexts(); 02941 02942 while ((c = ast_walk_contexts(c))) { 02943 if (!strcmp(ast_get_context_name(c), context)) { 02944 ret = 0; 02945 break; 02946 } 02947 } 02948 02949 ast_unlock_contexts(); 02950 02951 /* if we found context, lock macrolock */ 02952 if (ret == 0) 02953 ret = ast_mutex_lock(&c->macrolock); 02954 02955 return ret; 02956 }
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 2836 of file pbx.c.
References ast_context_remove_extension_callerid().
Referenced by destroy_station(), destroy_trunk(), and register_peer_exten().
02837 { 02838 return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar); 02839 }
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 2863 of file pbx.c.
References ast_context_remove_extension_callerid2().
Referenced by do_parking_thread(), and park_exec().
02864 { 02865 return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar); 02866 }
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 2841 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().
02842 { 02843 int ret = -1; /* default error return */ 02844 struct ast_context *c = find_context_locked(context); 02845 02846 if (c) { /* ... remove extension ... */ 02847 ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar); 02848 ast_unlock_contexts(); 02849 } 02850 return ret; 02851 }
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 2868 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().
02869 { 02870 struct ast_exten *exten, *prev_exten = NULL; 02871 struct ast_exten *peer; 02872 struct ast_exten *previous_peer = NULL; 02873 struct ast_exten *next_peer = NULL; 02874 int found = 0; 02875 02876 ast_mutex_lock(&con->lock); 02877 02878 /* scan the extension list to find first matching extension-registrar */ 02879 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02880 if (!strcmp(exten->exten, extension) && 02881 (!registrar || !strcmp(exten->registrar, registrar))) 02882 break; 02883 } 02884 if (!exten) { 02885 /* we can't find right extension */ 02886 ast_mutex_unlock(&con->lock); 02887 return -1; 02888 } 02889 02890 /* scan the priority list to remove extension with exten->priority == priority */ 02891 for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next; 02892 peer && !strcmp(peer->exten, extension); 02893 peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) { 02894 if ((priority == 0 || peer->priority == priority) && 02895 (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) && 02896 (!registrar || !strcmp(peer->registrar, registrar) )) { 02897 found = 1; 02898 02899 /* we are first priority extension? */ 02900 if (!previous_peer) { 02901 /* 02902 * We are first in the priority chain, so must update the extension chain. 02903 * The next node is either the next priority or the next extension 02904 */ 02905 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02906 02907 if (!prev_exten) { /* change the root... */ 02908 con->root = next_node; 02909 } else { 02910 prev_exten->next = next_node; /* unlink */ 02911 } 02912 if (peer->peer) { /* update the new head of the pri list */ 02913 peer->peer->next = peer->next; 02914 } 02915 } else { /* easy, we are not first priority in extension */ 02916 previous_peer->peer = peer->peer; 02917 } 02918 02919 /* now, free whole priority extension */ 02920 destroy_exten(peer); 02921 } else { 02922 previous_peer = peer; 02923 } 02924 } 02925 ast_mutex_unlock(&con->lock); 02926 return found ? 0 : -1; 02927 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4502 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().
04503 { 04504 int ret = -1; 04505 struct ast_context *c = find_context_locked(context); 04506 04507 if (c) { 04508 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04509 ast_unlock_contexts(); 04510 } 04511 return ret; 04512 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4514 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().
04515 { 04516 struct ast_ignorepat *ip, *ipl = NULL; 04517 04518 ast_mutex_lock(&con->lock); 04519 04520 for (ip = con->ignorepats; ip; ip = ip->next) { 04521 if (!strcmp(ip->pattern, ignorepat) && 04522 (!registrar || (registrar == ip->registrar))) { 04523 if (ipl) { 04524 ipl->next = ip->next; 04525 free(ip); 04526 } else { 04527 con->ignorepats = ip->next; 04528 free(ip); 04529 } 04530 ast_mutex_unlock(&con->lock); 04531 return 0; 04532 } 04533 ipl = ip; 04534 } 04535 04536 ast_mutex_unlock(&con->lock); 04537 errno = EINVAL; 04538 return -1; 04539 }
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 2732 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().
02733 { 02734 int ret = -1; 02735 struct ast_context *c = find_context_locked(context); 02736 02737 if (c) { 02738 /* found, remove include from this context ... */ 02739 ret = ast_context_remove_include2(c, include, registrar); 02740 ast_unlock_contexts(); 02741 } 02742 return ret; 02743 }
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 2753 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().
02754 { 02755 struct ast_include *i, *pi = NULL; 02756 int ret = -1; 02757 02758 ast_mutex_lock(&con->lock); 02759 02760 /* find our include */ 02761 for (i = con->includes; i; pi = i, i = i->next) { 02762 if (!strcmp(i->name, include) && 02763 (!registrar || !strcmp(i->registrar, registrar))) { 02764 /* remove from list */ 02765 if (pi) 02766 pi->next = i->next; 02767 else 02768 con->includes = i->next; 02769 /* free include and return */ 02770 free(i); 02771 ret = 0; 02772 break; 02773 } 02774 } 02775 02776 ast_mutex_unlock(&con->lock); 02777 return ret; 02778 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 2785 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
02786 { 02787 int ret = -1; /* default error return */ 02788 struct ast_context *c = find_context_locked(context); 02789 02790 if (c) { 02791 /* remove switch from this context ... */ 02792 ret = ast_context_remove_switch2(c, sw, data, registrar); 02793 ast_unlock_contexts(); 02794 } 02795 return ret; 02796 }
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 2806 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().
02807 { 02808 struct ast_sw *i; 02809 int ret = -1; 02810 02811 ast_mutex_lock(&con->lock); 02812 02813 /* walk switches */ 02814 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02815 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02816 (!registrar || !strcmp(i->registrar, registrar))) { 02817 /* found, remove from list */ 02818 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02819 free(i); /* free switch and return */ 02820 ret = 0; 02821 break; 02822 } 02823 } 02824 AST_LIST_TRAVERSE_SAFE_END 02825 02826 ast_mutex_unlock(&con->lock); 02827 02828 return ret; 02829 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 2963 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().
02964 { 02965 struct ast_context *c = NULL; 02966 int ret = -1; 02967 02968 ast_rdlock_contexts(); 02969 02970 while ((c = ast_walk_contexts(c))) { 02971 if (!strcmp(ast_get_context_name(c), context)) { 02972 ret = 0; 02973 break; 02974 } 02975 } 02976 02977 ast_unlock_contexts(); 02978 02979 /* if we found context, unlock macrolock */ 02980 if (ret == 0) 02981 ret = ast_mutex_unlock(&c->macrolock); 02982 02983 return ret; 02984 }
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 6495 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().
06496 { 06497 struct ast_include *inc = NULL; 06498 int res = 0; 06499 06500 while ( (inc = ast_walk_context_includes(con, inc)) ) { 06501 if (ast_context_find(inc->rname)) 06502 continue; 06503 06504 res = -1; 06505 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 06506 ast_get_context_name(con), inc->rname); 06507 break; 06508 } 06509 06510 return res; 06511 }
struct ast_custom_function* ast_custom_function_find | ( | const char * | name | ) |
Definition at line 1496 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().
01497 { 01498 struct ast_custom_function *acf = NULL; 01499 01500 AST_LIST_LOCK(&acf_root); 01501 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01502 if (!strcmp(name, acf->name)) 01503 break; 01504 } 01505 AST_LIST_UNLOCK(&acf_root); 01506 01507 return acf; 01508 }
int ast_custom_function_register | ( | struct ast_custom_function * | acf | ) |
Reigster a custom function.
Definition at line 1532 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().
01533 { 01534 struct ast_custom_function *cur; 01535 01536 if (!acf) 01537 return -1; 01538 01539 AST_LIST_LOCK(&acf_root); 01540 01541 if (ast_custom_function_find(acf->name)) { 01542 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01543 AST_LIST_UNLOCK(&acf_root); 01544 return -1; 01545 } 01546 01547 /* Store in alphabetical order */ 01548 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01549 if (strcasecmp(acf->name, cur->name) < 0) { 01550 AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist); 01551 break; 01552 } 01553 } 01554 AST_LIST_TRAVERSE_SAFE_END 01555 if (!cur) 01556 AST_LIST_INSERT_TAIL(&acf_root, acf, acflist); 01557 01558 AST_LIST_UNLOCK(&acf_root); 01559 01560 if (option_verbose > 1) 01561 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01562 01563 return 0; 01564 }
int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Unregister a custom function.
Definition at line 1510 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().
01511 { 01512 struct ast_custom_function *cur; 01513 01514 if (!acf) 01515 return -1; 01516 01517 AST_LIST_LOCK(&acf_root); 01518 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01519 if (cur == acf) { 01520 AST_LIST_REMOVE_CURRENT(&acf_root, acflist); 01521 if (option_verbose > 1) 01522 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01523 break; 01524 } 01525 } 01526 AST_LIST_TRAVERSE_SAFE_END 01527 AST_LIST_UNLOCK(&acf_root); 01528 01529 return acf ? 0 : -1; 01530 }
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 1960 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().
01961 { 01962 switch (devstate) { 01963 case AST_DEVICE_ONHOLD: 01964 return AST_EXTENSION_ONHOLD; 01965 case AST_DEVICE_BUSY: 01966 return AST_EXTENSION_BUSY; 01967 case AST_DEVICE_UNAVAILABLE: 01968 case AST_DEVICE_UNKNOWN: 01969 case AST_DEVICE_INVALID: 01970 return AST_EXTENSION_UNAVAILABLE; 01971 case AST_DEVICE_RINGINUSE: 01972 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING); 01973 case AST_DEVICE_RINGING: 01974 return AST_EXTENSION_RINGING; 01975 case AST_DEVICE_INUSE: 01976 return AST_EXTENSION_INUSE; 01977 case AST_DEVICE_NOT_INUSE: 01978 return AST_EXTENSION_NOT_INUSE; 01979 case AST_DEVICE_TOTAL: /* not a device state, included for completeness */ 01980 break; 01981 } 01982 01983 return AST_EXTENSION_NOT_INUSE; 01984 }
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 2299 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(), dahdi_r2_on_call_offered(), dahdi_r2_on_dnis_digit_received(), 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().
02300 { 02301 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH); 02302 }
int ast_explicit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4629 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().
04630 { 04631 if (!chan) 04632 return -1; 04633 04634 ast_channel_lock(chan); 04635 04636 if (!ast_strlen_zero(context)) 04637 ast_copy_string(chan->context, context, sizeof(chan->context)); 04638 if (!ast_strlen_zero(exten)) 04639 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04640 if (priority > -1) { 04641 chan->priority = priority; 04642 /* see flag description in channel.h for explanation */ 04643 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04644 chan->priority--; 04645 } 04646 04647 ast_channel_unlock(chan); 04648 04649 return 0; 04650 }
int ast_extension_close | ( | const char * | pattern, | |
const char * | data, | |||
int | needmore | |||
) |
Definition at line 927 of file pbx.c.
References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.
Referenced by realtime_switch_common().
00928 { 00929 if (needmore != E_MATCHMORE && needmore != E_CANMATCH) 00930 ast_log(LOG_WARNING, "invalid argument %d\n", needmore); 00931 return extension_match_core(pattern, data, needmore); 00932 }
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 922 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().
00923 { 00924 return extension_match_core(pattern, data, E_MATCH); 00925 }
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 2021 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), and handle_request_subscribe().
02022 { 02023 struct ast_exten *e; 02024 02025 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 02026 if (!e) 02027 return -1; /* No hint, return -1 */ 02028 02029 return ast_extension_state2(e); /* Check all devices in the hint */ 02030 }
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 2009 of file pbx.c.
References extension_states.
Referenced by cb_extensionstate(), handle_request_subscribe(), and handle_show_hints().
02010 { 02011 int i; 02012 02013 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 02014 if (extension_states[i].extension_state == extension_state) 02015 return extension_states[i].text; 02016 } 02017 return "Unknown"; 02018 }
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 2078 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().
02080 { 02081 struct ast_hint *hint; 02082 struct ast_state_cb *cblist; 02083 struct ast_exten *e; 02084 02085 /* If there's no context and extension: add callback to statecbs list */ 02086 if (!context && !exten) { 02087 AST_LIST_LOCK(&hints); 02088 02089 for (cblist = statecbs; cblist; cblist = cblist->next) { 02090 if (cblist->callback == callback) { 02091 cblist->data = data; 02092 AST_LIST_UNLOCK(&hints); 02093 return 0; 02094 } 02095 } 02096 02097 /* Now insert the callback */ 02098 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02099 AST_LIST_UNLOCK(&hints); 02100 return -1; 02101 } 02102 cblist->id = 0; 02103 cblist->callback = callback; 02104 cblist->data = data; 02105 02106 cblist->next = statecbs; 02107 statecbs = cblist; 02108 02109 AST_LIST_UNLOCK(&hints); 02110 return 0; 02111 } 02112 02113 if (!context || !exten) 02114 return -1; 02115 02116 /* This callback type is for only one hint, so get the hint */ 02117 e = ast_hint_extension(NULL, context, exten); 02118 if (!e) { 02119 return -1; 02120 } 02121 02122 /* Find the hint in the list of hints */ 02123 AST_LIST_LOCK(&hints); 02124 02125 AST_LIST_TRAVERSE(&hints, hint, list) { 02126 if (hint->exten == e) 02127 break; 02128 } 02129 02130 if (!hint) { 02131 /* We have no hint, sorry */ 02132 AST_LIST_UNLOCK(&hints); 02133 return -1; 02134 } 02135 02136 /* Now insert the callback in the callback list */ 02137 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02138 AST_LIST_UNLOCK(&hints); 02139 return -1; 02140 } 02141 cblist->id = stateid++; /* Unique ID for this callback */ 02142 cblist->callback = callback; /* Pointer to callback routine */ 02143 cblist->data = data; /* Data for the callback */ 02144 02145 cblist->next = hint->callbacks; 02146 hint->callbacks = cblist; 02147 02148 AST_LIST_UNLOCK(&hints); 02149 return cblist->id; 02150 }
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 2153 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().
02154 { 02155 struct ast_state_cb **p_cur = NULL; /* address of pointer to us */ 02156 int ret = -1; 02157 02158 if (!id && !callback) 02159 return -1; 02160 02161 AST_LIST_LOCK(&hints); 02162 02163 if (!id) { /* id == 0 is a callback without extension */ 02164 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) { 02165 if ((*p_cur)->callback == callback) 02166 break; 02167 } 02168 } else { /* callback with extension, find the callback based on ID */ 02169 struct ast_hint *hint; 02170 AST_LIST_TRAVERSE(&hints, hint, list) { 02171 for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) { 02172 if ((*p_cur)->id == id) 02173 break; 02174 } 02175 if (*p_cur) /* found in the inner loop */ 02176 break; 02177 } 02178 } 02179 if (p_cur && *p_cur) { 02180 struct ast_state_cb *cur = *p_cur; 02181 *p_cur = cur->next; 02182 free(cur); 02183 ret = 0; 02184 } 02185 AST_LIST_UNLOCK(&hints); 02186 return ret; 02187 }
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 2304 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().
02305 { 02306 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL); 02307 }
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 2309 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
02310 { 02311 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL); 02312 }
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 1586 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().
01587 { 01588 char *args = func_args(function); 01589 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01590 01591 if (acfptr == NULL) 01592 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01593 else if (!acfptr->read) 01594 ast_log(LOG_ERROR, "Function %s cannot be read\n", function); 01595 else 01596 return acfptr->read(chan, function, args, workspace, len); 01597 return -1; 01598 }
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 1600 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().
01601 { 01602 char *args = func_args(function); 01603 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01604 01605 if (acfptr == NULL) 01606 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01607 else if (!acfptr->write) 01608 ast_log(LOG_ERROR, "Function %s cannot be written to\n", function); 01609 else 01610 return acfptr->write(chan, function, args, value); 01611 01612 return -1; 01613 }
const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 6352 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().
06353 { 06354 return con ? con->name : NULL; 06355 }
const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 6390 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06391 { 06392 return c ? c->registrar : NULL; 06393 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6420 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().
06421 { 06422 return e ? e->app : NULL; 06423 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6425 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06426 { 06427 return e ? e->data : NULL; 06428 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6415 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().
06416 { 06417 return e ? e->cidmatch : NULL; 06418 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
const char* ast_get_extension_label | ( | struct ast_exten * | e | ) |
Definition at line 6367 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 6410 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().
06411 { 06412 return e ? e->matchcid : 0; 06413 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6362 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 6382 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 6395 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06396 { 06397 return e ? e->registrar : NULL; 06398 }
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 2282 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().
02283 { 02284 struct ast_exten *e = ast_hint_extension(c, context, exten); 02285 02286 if (e) { 02287 if (hint) 02288 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02289 if (name) { 02290 const char *tmp = ast_get_extension_app_data(e); 02291 if (tmp) 02292 ast_copy_string(name, tmp, namesize); 02293 } 02294 return -1; 02295 } 02296 return 0; 02297 }
const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6377 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().
06378 { 06379 return ip ? ip->pattern : NULL; 06380 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6405 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06406 { 06407 return ip ? ip->registrar : NULL; 06408 }
const char* ast_get_include_name | ( | struct ast_include * | include | ) |
Definition at line 6372 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 6400 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06401 { 06402 return i ? i->registrar : NULL; 06403 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6435 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06436 { 06437 return sw ? sw->data : NULL; 06438 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6430 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06431 { 06432 return sw ? sw->name : NULL; 06433 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6440 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06441 { 06442 return sw ? sw->registrar : NULL; 06443 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6533 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().
06534 { 06535 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06536 }
void ast_hint_state_changed | ( | const char * | device | ) |
Definition at line 2032 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().
02033 { 02034 struct ast_hint *hint; 02035 02036 ast_rdlock_contexts(); 02037 AST_LIST_LOCK(&hints); 02038 02039 AST_LIST_TRAVERSE(&hints, hint, list) { 02040 struct ast_state_cb *cblist; 02041 char buf[AST_MAX_EXTENSION]; 02042 char *parse = buf; 02043 char *cur; 02044 int state; 02045 02046 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 02047 while ( (cur = strsep(&parse, "&")) ) { 02048 if (!strcasecmp(cur, device)) 02049 break; 02050 } 02051 if (!cur) 02052 continue; 02053 02054 /* Get device state for this hint */ 02055 state = ast_extension_state2(hint->exten); 02056 02057 if ((state == -1) || (state == hint->laststate)) 02058 continue; 02059 02060 /* Device state changed since last check - notify the watchers */ 02061 02062 /* For general callbacks */ 02063 for (cblist = statecbs; cblist; cblist = cblist->next) 02064 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02065 02066 /* For extension callbacks */ 02067 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 02068 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02069 02070 hint->laststate = state; /* record we saw the change */ 02071 } 02072 02073 AST_LIST_UNLOCK(&hints); 02074 ast_unlock_contexts(); 02075 }
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 4595 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().
04596 { 04597 struct ast_context *con = ast_context_find(context); 04598 if (con) { 04599 struct ast_ignorepat *pat; 04600 for (pat = con->ignorepats; pat; pat = pat->next) { 04601 if (ast_extension_match(pat->pattern, pattern)) 04602 return 1; 04603 } 04604 } 04605 04606 return 0; 04607 }
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 6339 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().
06340 { 06341 return ast_mutex_lock(&con->lock); 06342 }
int ast_lock_contexts | ( | void | ) |
Locks the context list.
0 | on success | |
-1 | on error |
Definition at line 6316 of file pbx.c.
References ast_rwlock_wrlock, and conlock.
Referenced by find_matching_endwhile().
06317 { 06318 return ast_rwlock_wrlock(&conlock); 06319 }
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 2319 of file pbx.c.
References E_MATCHMORE, and pbx_extension_helper().
Referenced by ast_app_dtget(), collect_digits(), dahdi_r2_on_dnis_digit_received(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_stimulus_message(), loopback_matchmore(), mgcp_ss(), pbx_builtin_background(), skinny_ss(), and ss_thread().
02320 { 02321 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE); 02322 }
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 3991 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().
03992 { 03993 struct ast_context *tmp, *lasttmp = NULL; 03994 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 03995 struct store_hint *this; 03996 struct ast_hint *hint; 03997 struct ast_exten *exten; 03998 int length; 03999 struct ast_state_cb *thiscb, *prevcb; 04000 04001 /* it is very important that this function hold the hint list lock _and_ the conlock 04002 during its operation; not only do we need to ensure that the list of contexts 04003 and extensions does not change, but also that no hint callbacks (watchers) are 04004 added or removed during the merge/delete process 04005 04006 in addition, the locks _must_ be taken in this order, because there are already 04007 other code paths that use this order 04008 */ 04009 ast_wrlock_contexts(); 04010 AST_LIST_LOCK(&hints); 04011 04012 /* preserve all watchers for hints associated with this registrar */ 04013 AST_LIST_TRAVERSE(&hints, hint, list) { 04014 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 04015 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 04016 if (!(this = ast_calloc(1, length))) 04017 continue; 04018 this->callbacks = hint->callbacks; 04019 hint->callbacks = NULL; 04020 this->laststate = hint->laststate; 04021 this->context = this->data; 04022 strcpy(this->data, hint->exten->parent->name); 04023 this->exten = this->data + strlen(this->context) + 1; 04024 strcpy(this->exten, hint->exten->exten); 04025 AST_LIST_INSERT_HEAD(&store, this, list); 04026 } 04027 } 04028 04029 tmp = *extcontexts; 04030 if (registrar) { 04031 /* XXX remove previous contexts from same registrar */ 04032 if (option_debug) 04033 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 04034 __ast_context_destroy(NULL,registrar); 04035 while (tmp) { 04036 lasttmp = tmp; 04037 tmp = tmp->next; 04038 } 04039 } else { 04040 /* XXX remove contexts with the same name */ 04041 while (tmp) { 04042 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 04043 __ast_context_destroy(tmp,tmp->registrar); 04044 lasttmp = tmp; 04045 tmp = tmp->next; 04046 } 04047 } 04048 if (lasttmp) { 04049 lasttmp->next = contexts; 04050 contexts = *extcontexts; 04051 *extcontexts = NULL; 04052 } else 04053 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 04054 04055 /* restore the watchers for hints that can be found; notify those that 04056 cannot be restored 04057 */ 04058 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 04059 struct pbx_find_info q = { .stacklen = 0 }; 04060 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 04061 /* Find the hint in the list of hints */ 04062 AST_LIST_TRAVERSE(&hints, hint, list) { 04063 if (hint->exten == exten) 04064 break; 04065 } 04066 if (!exten || !hint) { 04067 /* this hint has been removed, notify the watchers */ 04068 prevcb = NULL; 04069 thiscb = this->callbacks; 04070 while (thiscb) { 04071 prevcb = thiscb; 04072 thiscb = thiscb->next; 04073 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 04074 free(prevcb); 04075 } 04076 } else { 04077 thiscb = this->callbacks; 04078 while (thiscb->next) 04079 thiscb = thiscb->next; 04080 thiscb->next = hint->callbacks; 04081 hint->callbacks = this->callbacks; 04082 hint->laststate = this->laststate; 04083 } 04084 free(this); 04085 } 04086 04087 AST_LIST_UNLOCK(&hints); 04088 ast_unlock_contexts(); 04089 04090 return; 04091 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
This function will handle locking the channel as needed.
Definition at line 6543 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().
06544 { 06545 char *exten, *pri, *context; 06546 char *stringp; 06547 int ipri; 06548 int mode = 0; 06549 06550 if (ast_strlen_zero(goto_string)) { 06551 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06552 return -1; 06553 } 06554 stringp = ast_strdupa(goto_string); 06555 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06556 exten = strsep(&stringp, "|"); 06557 pri = strsep(&stringp, "|"); 06558 if (!exten) { /* Only a priority in this one */ 06559 pri = context; 06560 exten = NULL; 06561 context = NULL; 06562 } else if (!pri) { /* Only an extension and priority in this one */ 06563 pri = exten; 06564 exten = context; 06565 context = NULL; 06566 } 06567 if (*pri == '+') { 06568 mode = 1; 06569 pri++; 06570 } else if (*pri == '-') { 06571 mode = -1; 06572 pri++; 06573 } 06574 if (sscanf(pri, "%30d", &ipri) != 1) { 06575 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06576 pri, chan->cid.cid_num)) < 1) { 06577 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06578 return -1; 06579 } else 06580 mode = 0; 06581 } 06582 /* At this point we have a priority and maybe an extension and a context */ 06583 06584 if (mode) 06585 ipri = chan->priority + (ipri * mode); 06586 06587 ast_explicit_goto(chan, context, exten, ipri); 06588 return 0; 06589 06590 }
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 5222 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().
05223 { 05224 struct ast_channel *chan; 05225 struct app_tmp *tmp; 05226 int res = -1, cdr_res = -1; 05227 struct outgoing_helper oh; 05228 pthread_attr_t attr; 05229 05230 memset(&oh, 0, sizeof(oh)); 05231 oh.vars = vars; 05232 oh.account = account; 05233 05234 if (locked_channel) 05235 *locked_channel = NULL; 05236 if (ast_strlen_zero(app)) { 05237 res = -1; 05238 goto outgoing_app_cleanup; 05239 } 05240 if (sync) { 05241 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05242 if (chan) { 05243 ast_set_variables(chan, vars); 05244 if (account) 05245 ast_cdr_setaccount(chan, account); 05246 if (chan->_state == AST_STATE_UP) { 05247 res = 0; 05248 if (option_verbose > 3) 05249 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05250 tmp = ast_calloc(1, sizeof(*tmp)); 05251 if (!tmp) 05252 res = -1; 05253 else { 05254 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05255 if (appdata) 05256 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05257 tmp->chan = chan; 05258 if (sync > 1) { 05259 if (locked_channel) 05260 ast_channel_unlock(chan); 05261 ast_pbx_run_app(tmp); 05262 } else { 05263 pthread_attr_init(&attr); 05264 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05265 if (locked_channel) 05266 ast_channel_lock(chan); 05267 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05268 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05269 free(tmp); 05270 if (locked_channel) 05271 ast_channel_unlock(chan); 05272 ast_hangup(chan); 05273 res = -1; 05274 } else { 05275 if (locked_channel) 05276 *locked_channel = chan; 05277 } 05278 pthread_attr_destroy(&attr); 05279 } 05280 } 05281 } else { 05282 if (option_verbose > 3) 05283 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05284 if (chan->cdr) { /* update the cdr */ 05285 /* here we update the status of the call, which sould be busy. 05286 * if that fails then we set the status to failed */ 05287 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05288 ast_cdr_failed(chan->cdr); 05289 } 05290 ast_hangup(chan); 05291 } 05292 } 05293 05294 if (res < 0) { /* the call failed for some reason */ 05295 if (*reason == 0) { /* if the call failed (not busy or no answer) 05296 * update the cdr with the failed message */ 05297 cdr_res = ast_pbx_outgoing_cdr_failed(); 05298 if (cdr_res != 0) { 05299 res = cdr_res; 05300 goto outgoing_app_cleanup; 05301 } 05302 } 05303 } 05304 05305 } else { 05306 struct async_stat *as; 05307 if (!(as = ast_calloc(1, sizeof(*as)))) { 05308 res = -1; 05309 goto outgoing_app_cleanup; 05310 } 05311 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05312 if (!chan) { 05313 free(as); 05314 res = -1; 05315 goto outgoing_app_cleanup; 05316 } 05317 as->chan = chan; 05318 ast_copy_string(as->app, app, sizeof(as->app)); 05319 if (appdata) 05320 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05321 as->timeout = timeout; 05322 ast_set_variables(chan, vars); 05323 if (account) 05324 ast_cdr_setaccount(chan, account); 05325 /* Start a new thread, and get something handling this channel. */ 05326 pthread_attr_init(&attr); 05327 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05328 if (locked_channel) 05329 ast_channel_lock(chan); 05330 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05331 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05332 free(as); 05333 if (locked_channel) 05334 ast_channel_unlock(chan); 05335 ast_hangup(chan); 05336 res = -1; 05337 pthread_attr_destroy(&attr); 05338 goto outgoing_app_cleanup; 05339 } else { 05340 if (locked_channel) 05341 *locked_channel = chan; 05342 } 05343 pthread_attr_destroy(&attr); 05344 res = 0; 05345 } 05346 outgoing_app_cleanup: 05347 ast_variables_destroy(vars); 05348 return res; 05349 }
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 5056 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().
05057 { 05058 struct ast_channel *chan; 05059 struct async_stat *as; 05060 int res = -1, cdr_res = -1; 05061 struct outgoing_helper oh; 05062 pthread_attr_t attr; 05063 05064 if (sync) { 05065 LOAD_OH(oh); 05066 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05067 if (channel) { 05068 *channel = chan; 05069 if (chan) 05070 ast_channel_lock(chan); 05071 } 05072 if (chan) { 05073 if (chan->_state == AST_STATE_UP) { 05074 res = 0; 05075 if (option_verbose > 3) 05076 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05077 05078 if (sync > 1) { 05079 if (channel) 05080 ast_channel_unlock(chan); 05081 if (ast_pbx_run(chan)) { 05082 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05083 if (channel) 05084 *channel = NULL; 05085 ast_hangup(chan); 05086 chan = NULL; 05087 res = -1; 05088 } 05089 } else { 05090 if (ast_pbx_start(chan)) { 05091 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05092 if (channel) { 05093 *channel = NULL; 05094 ast_channel_unlock(chan); 05095 } 05096 ast_hangup(chan); 05097 res = -1; 05098 } 05099 chan = NULL; 05100 } 05101 } else { 05102 if (option_verbose > 3) 05103 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05104 05105 if (chan->cdr) { /* update the cdr */ 05106 /* here we update the status of the call, which sould be busy. 05107 * if that fails then we set the status to failed */ 05108 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05109 ast_cdr_failed(chan->cdr); 05110 } 05111 05112 if (channel) { 05113 *channel = NULL; 05114 ast_channel_unlock(chan); 05115 } 05116 ast_hangup(chan); 05117 chan = NULL; 05118 } 05119 } 05120 05121 if (res < 0) { /* the call failed for some reason */ 05122 if (*reason == 0) { /* if the call failed (not busy or no answer) 05123 * update the cdr with the failed message */ 05124 cdr_res = ast_pbx_outgoing_cdr_failed(); 05125 if (cdr_res != 0) { 05126 res = cdr_res; 05127 goto outgoing_exten_cleanup; 05128 } 05129 } 05130 05131 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05132 /* check if "failed" exists */ 05133 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05134 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05135 if (chan) { 05136 char failed_reason[4] = ""; 05137 if (!ast_strlen_zero(context)) 05138 ast_copy_string(chan->context, context, sizeof(chan->context)); 05139 set_ext_pri(chan, "failed", 1); 05140 ast_set_variables(chan, vars); 05141 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 05142 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 05143 if (account) 05144 ast_cdr_setaccount(chan, account); 05145 if (ast_pbx_run(chan)) { 05146 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05147 ast_hangup(chan); 05148 } 05149 chan = NULL; 05150 } 05151 } 05152 } 05153 } else { 05154 if (!(as = ast_calloc(1, sizeof(*as)))) { 05155 res = -1; 05156 goto outgoing_exten_cleanup; 05157 } 05158 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05159 if (channel) { 05160 *channel = chan; 05161 if (chan) 05162 ast_channel_lock(chan); 05163 } 05164 if (!chan) { 05165 free(as); 05166 res = -1; 05167 goto outgoing_exten_cleanup; 05168 } 05169 as->chan = chan; 05170 ast_copy_string(as->context, context, sizeof(as->context)); 05171 set_ext_pri(as->chan, exten, priority); 05172 as->timeout = timeout; 05173 ast_set_variables(chan, vars); 05174 if (account) 05175 ast_cdr_setaccount(chan, account); 05176 pthread_attr_init(&attr); 05177 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05178 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05179 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05180 free(as); 05181 if (channel) { 05182 *channel = NULL; 05183 ast_channel_unlock(chan); 05184 } 05185 ast_hangup(chan); 05186 res = -1; 05187 pthread_attr_destroy(&attr); 05188 goto outgoing_exten_cleanup; 05189 } 05190 pthread_attr_destroy(&attr); 05191 res = 0; 05192 } 05193 outgoing_exten_cleanup: 05194 ast_variables_destroy(vars); 05195 return res; 05196 }
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 2680 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().
02681 { 02682 enum ast_pbx_result res = AST_PBX_SUCCESS; 02683 02684 if (increase_call_count(c)) 02685 return AST_PBX_CALL_LIMIT; 02686 02687 res = __ast_pbx_run(c); 02688 decrease_call_count(); 02689 02690 return res; 02691 }
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 2653 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().
02654 { 02655 pthread_t t; 02656 pthread_attr_t attr; 02657 02658 if (!c) { 02659 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02660 return AST_PBX_FAILED; 02661 } 02662 02663 if (increase_call_count(c)) 02664 return AST_PBX_CALL_LIMIT; 02665 02666 /* Start a new thread, and get something handling this channel. */ 02667 pthread_attr_init(&attr); 02668 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02669 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02670 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02671 pthread_attr_destroy(&attr); 02672 decrease_call_count(); 02673 return AST_PBX_FAILED; 02674 } 02675 pthread_attr_destroy(&attr); 02676 02677 return AST_PBX_SUCCESS; 02678 }
int ast_processed_calls | ( | void | ) |
Retrieve the total number of calls processed through the PBX since last restart.
Definition at line 2698 of file pbx.c.
References totalcalls.
02699 { 02700 return totalcalls; 02701 }
int ast_rdlock_contexts | ( | void | ) |
Definition at line 6321 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().
06322 { 06323 return ast_rwlock_rdlock(&conlock); 06324 }
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 2987 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().
02988 { 02989 struct ast_app *tmp, *cur = NULL; 02990 char tmps[80]; 02991 int length; 02992 02993 AST_LIST_LOCK(&apps); 02994 AST_LIST_TRAVERSE(&apps, tmp, list) { 02995 if (!strcasecmp(app, tmp->name)) { 02996 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02997 AST_LIST_UNLOCK(&apps); 02998 return -1; 02999 } 03000 } 03001 03002 length = sizeof(*tmp) + strlen(app) + 1; 03003 03004 if (!(tmp = ast_calloc(1, length))) { 03005 AST_LIST_UNLOCK(&apps); 03006 return -1; 03007 } 03008 03009 strcpy(tmp->name, app); 03010 tmp->execute = execute; 03011 tmp->synopsis = synopsis; 03012 tmp->description = description; 03013 03014 /* Store in alphabetical order */ 03015 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 03016 if (strcasecmp(tmp->name, cur->name) < 0) { 03017 AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 03018 break; 03019 } 03020 } 03021 AST_LIST_TRAVERSE_SAFE_END 03022 if (!cur) 03023 AST_LIST_INSERT_TAIL(&apps, tmp, list); 03024 03025 if (option_verbose > 1) 03026 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 03027 03028 AST_LIST_UNLOCK(&apps); 03029 03030 return 0; 03031 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 3037 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().
03038 { 03039 struct ast_switch *tmp; 03040 03041 AST_LIST_LOCK(&switches); 03042 AST_LIST_TRAVERSE(&switches, tmp, list) { 03043 if (!strcasecmp(tmp->name, sw->name)) { 03044 AST_LIST_UNLOCK(&switches); 03045 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 03046 return -1; 03047 } 03048 } 03049 AST_LIST_INSERT_TAIL(&switches, sw, list); 03050 AST_LIST_UNLOCK(&switches); 03051 03052 return 0; 03053 }
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 2324 of file pbx.c.
References E_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), _macro_exec(), ast_bridge_call(), and loopback_exec().
02325 { 02326 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN); 02327 }
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 6344 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().
06345 { 06346 return ast_mutex_unlock(&con->lock); 06347 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 6331 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().
06332 { 06333 return ast_rwlock_unlock(&conlock); 06334 }
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 3902 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().
03903 { 03904 struct ast_app *tmp; 03905 03906 AST_LIST_LOCK(&apps); 03907 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03908 if (!strcasecmp(app, tmp->name)) { 03909 AST_LIST_REMOVE_CURRENT(&apps, list); 03910 if (option_verbose > 1) 03911 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03912 free(tmp); 03913 break; 03914 } 03915 } 03916 AST_LIST_TRAVERSE_SAFE_END 03917 AST_LIST_UNLOCK(&apps); 03918 03919 return tmp ? 0 : -1; 03920 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 3055 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().
03056 { 03057 AST_LIST_LOCK(&switches); 03058 AST_LIST_REMOVE(&switches, sw, list); 03059 AST_LIST_UNLOCK(&switches); 03060 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | priority | |||
) |
Definition at line 6453 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().
06455 { 06456 if (!exten) 06457 return con ? con->root : NULL; 06458 else 06459 return exten->next; 06460 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 6486 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().
06488 { 06489 if (!ip) 06490 return con ? con->ignorepats : NULL; 06491 else 06492 return ip->next; 06493 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 6477 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().
06479 { 06480 if (!inc) 06481 return con ? con->includes : NULL; 06482 else 06483 return inc->next; 06484 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 6462 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().
06464 { 06465 if (!sw) 06466 return con ? AST_LIST_FIRST(&con->alts) : NULL; 06467 else 06468 return AST_LIST_NEXT(sw, list); 06469 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 6448 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 6471 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 6326 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().
06327 { 06328 return ast_rwlock_wrlock(&conlock); 06329 }
void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 6092 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().
06093 { 06094 struct ast_var_t *vardata; 06095 06096 ast_mutex_lock(&globalslock); 06097 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06098 ast_var_delete(vardata); 06099 ast_mutex_unlock(&globalslock); 06100 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5869 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(), dahdi_r2_answer(), dahdi_r2_get_channel_category(), 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(), pbx_builtin_background(), 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().
05870 { 05871 struct ast_var_t *variables; 05872 const char *ret = NULL; 05873 int i; 05874 struct varshead *places[2] = { NULL, &globals }; 05875 05876 if (!name) 05877 return NULL; 05878 05879 if (chan) { 05880 ast_channel_lock(chan); 05881 places[0] = &chan->varshead; 05882 } 05883 05884 for (i = 0; i < 2; i++) { 05885 if (!places[i]) 05886 continue; 05887 if (places[i] == &globals) 05888 ast_mutex_lock(&globalslock); 05889 AST_LIST_TRAVERSE(places[i], variables, entries) { 05890 if (!strcmp(name, ast_var_name(variables))) { 05891 ret = ast_var_value(variables); 05892 break; 05893 } 05894 } 05895 if (places[i] == &globals) 05896 ast_mutex_unlock(&globalslock); 05897 if (ret) 05898 break; 05899 } 05900 05901 if (chan) 05902 ast_channel_unlock(chan); 05903 05904 return ret; 05905 }
void pbx_builtin_pushvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5907 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().
05908 { 05909 struct ast_var_t *newvariable; 05910 struct varshead *headp; 05911 05912 if (name[strlen(name)-1] == ')') { 05913 char *function = ast_strdupa(name); 05914 05915 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05916 ast_func_write(chan, function, value); 05917 return; 05918 } 05919 05920 if (chan) { 05921 ast_channel_lock(chan); 05922 headp = &chan->varshead; 05923 } else { 05924 ast_mutex_lock(&globalslock); 05925 headp = &globals; 05926 } 05927 05928 if (value) { 05929 if ((option_verbose > 1) && (headp == &globals)) 05930 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05931 newvariable = ast_var_assign(name, value); 05932 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05933 } 05934 05935 if (chan) 05936 ast_channel_unlock(chan); 05937 else 05938 ast_mutex_unlock(&globalslock); 05939 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5838 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().
05839 { 05840 struct ast_var_t *variables; 05841 const char *var, *val; 05842 int total = 0; 05843 05844 if (!chan) 05845 return 0; 05846 05847 memset(buf, 0, size); 05848 05849 ast_channel_lock(chan); 05850 05851 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05852 if ((var=ast_var_name(variables)) && (val=ast_var_value(variables)) 05853 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 05854 ) { 05855 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05856 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05857 break; 05858 } else 05859 total++; 05860 } else 05861 break; 05862 } 05863 05864 ast_channel_unlock(chan); 05865 05866 return total; 05867 }
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 5941 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().
05942 { 05943 struct ast_var_t *newvariable; 05944 struct varshead *headp; 05945 const char *nametail = name; 05946 05947 if (name[strlen(name)-1] == ')') { 05948 char *function = ast_strdupa(name); 05949 05950 ast_func_write(chan, function, value); 05951 return; 05952 } 05953 05954 if (chan) { 05955 ast_channel_lock(chan); 05956 headp = &chan->varshead; 05957 } else { 05958 ast_mutex_lock(&globalslock); 05959 headp = &globals; 05960 } 05961 05962 /* For comparison purposes, we have to strip leading underscores */ 05963 if (*nametail == '_') { 05964 nametail++; 05965 if (*nametail == '_') 05966 nametail++; 05967 } 05968 05969 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05970 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 05971 /* there is already such a variable, delete it */ 05972 AST_LIST_REMOVE(headp, newvariable, entries); 05973 ast_var_delete(newvariable); 05974 break; 05975 } 05976 } 05977 05978 if (value) { 05979 if ((option_verbose > 1) && (headp == &globals)) 05980 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05981 newvariable = ast_var_assign(name, value); 05982 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05983 } 05984 05985 if (chan) 05986 ast_channel_unlock(chan); 05987 else 05988 ast_mutex_unlock(&globalslock); 05989 }
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 6102 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().
06103 { 06104 if (ast_strlen_zero(condition)) /* NULL or empty strings are false */ 06105 return 0; 06106 else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */ 06107 return atoi(condition); 06108 else /* Strings are true */ 06109 return 1; 06110 }
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(), 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(), 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 1190 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().
01191 { 01192 const char not_found = '\0'; 01193 char *tmpvar; 01194 const char *s; /* the result */ 01195 int offset, length; 01196 int i, need_substring; 01197 struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */ 01198 01199 if (c) { 01200 ast_channel_lock(c); 01201 places[0] = &c->varshead; 01202 } 01203 /* 01204 * Make a copy of var because parse_variable_name() modifies the string. 01205 * Then if called directly, we might need to run substring() on the result; 01206 * remember this for later in 'need_substring', 'offset' and 'length' 01207 */ 01208 tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */ 01209 need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */); 01210 01211 /* 01212 * Look first into predefined variables, then into variable lists. 01213 * Variable 's' points to the result, according to the following rules: 01214 * s == ¬_found (set at the beginning) means that we did not find a 01215 * matching variable and need to look into more places. 01216 * If s != ¬_found, s is a valid result string as follows: 01217 * s = NULL if the variable does not have a value; 01218 * you typically do this when looking for an unset predefined variable. 01219 * s = workspace if the result has been assembled there; 01220 * typically done when the result is built e.g. with an snprintf(), 01221 * so we don't need to do an additional copy. 01222 * s != workspace in case we have a string, that needs to be copied 01223 * (the ast_copy_string is done once for all at the end). 01224 * Typically done when the result is already available in some string. 01225 */ 01226 s = ¬_found; /* default value */ 01227 if (c) { /* This group requires a valid channel */ 01228 /* Names with common parts are looked up a piece at a time using strncmp. */ 01229 if (!strncmp(var, "CALL", 4)) { 01230 if (!strncmp(var + 4, "ING", 3)) { 01231 if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */ 01232 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 01233 s = workspace; 01234 } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */ 01235 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 01236 s = workspace; 01237 } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */ 01238 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 01239 s = workspace; 01240 } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */ 01241 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 01242 s = workspace; 01243 } 01244 } 01245 } else if (!strcmp(var, "HINT")) { 01246 s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL; 01247 } else if (!strcmp(var, "HINTNAME")) { 01248 s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL; 01249 } else if (!strcmp(var, "EXTEN")) { 01250 s = c->exten; 01251 } else if (!strcmp(var, "CONTEXT")) { 01252 s = c->context; 01253 } else if (!strcmp(var, "PRIORITY")) { 01254 snprintf(workspace, workspacelen, "%d", c->priority); 01255 s = workspace; 01256 } else if (!strcmp(var, "CHANNEL")) { 01257 s = c->name; 01258 } else if (!strcmp(var, "UNIQUEID")) { 01259 s = c->uniqueid; 01260 } else if (!strcmp(var, "HANGUPCAUSE")) { 01261 snprintf(workspace, workspacelen, "%d", c->hangupcause); 01262 s = workspace; 01263 } else if (c && !strcmp(var, "HANGUPCAUSESTR")) { 01264 ast_copy_string(workspace, ast_cause2str(c->hangupcause), workspacelen); 01265 *ret = workspace; 01266 } 01267 } 01268 if (s == ¬_found) { /* look for more */ 01269 if (!strcmp(var, "EPOCH")) { 01270 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 01271 s = workspace; 01272 } else if (!strcmp(var, "SYSTEMNAME")) { 01273 s = ast_config_AST_SYSTEM_NAME; 01274 } 01275 } 01276 /* if not found, look into chanvars or global vars */ 01277 for (i = 0; s == ¬_found && i < (sizeof(places) / sizeof(places[0])); i++) { 01278 struct ast_var_t *variables; 01279 if (!places[i]) 01280 continue; 01281 if (places[i] == &globals) 01282 ast_mutex_lock(&globalslock); 01283 AST_LIST_TRAVERSE(places[i], variables, entries) { 01284 if (strcasecmp(ast_var_name(variables), var)==0) { 01285 s = ast_var_value(variables); 01286 break; 01287 } 01288 } 01289 if (places[i] == &globals) 01290 ast_mutex_unlock(&globalslock); 01291 } 01292 if (s == ¬_found || s == NULL) 01293 *ret = NULL; 01294 else { 01295 if (s != workspace) 01296 ast_copy_string(workspace, s, workspacelen); 01297 *ret = workspace; 01298 if (need_substring) 01299 *ret = substring(*ret, offset, length, workspace, workspacelen); 01300 } 01301 01302 if (c) 01303 ast_channel_unlock(c); 01304 }
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 2703 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
02704 { 02705 int oldval = autofallthrough; 02706 autofallthrough = newval; 02707 return oldval; 02708 }
void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1810 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().
01811 { 01812 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 01813 }
void pbx_substitute_variables_varshead | ( | struct varshead * | headp, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1815 of file pbx.c.
References pbx_substitute_variables_helper_full().
Referenced by ast_add_extension2(), dundi_lookup_local(), and loopback_subst().
01816 { 01817 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 01818 }