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