#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/linkedlists.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_NO_HANGUP_PEER 11 |
#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. | |
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_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 34 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 40 of file pbx.h.
Referenced by __ast_pbx_run(), _macro_exec(), agi_handle_command(), builtin_blindtransfer(), builtin_parkcall(), feature_exec_app(), park_call_exec(), queue_exec(), and run_agi().
#define AST_PBX_NO_HANGUP_PEER 11 |
Definition at line 41 of file pbx.h.
Referenced by builtin_blindtransfer(), builtin_parkcall(), feature_exec_app(), park_exec(), and try_calling().
#define PRIORITY_HINT -1 |
} Special Priority for a hint
Definition at line 44 of file pbx.h.
Referenced by add_extensions(), add_pri(), ast_add_extension2(), ast_hint_extension(), ast_merge_contexts_and_delete(), destroy_exten(), destroy_station(), handle_context_add_extension(), handle_context_add_extension_deprecated(), handle_context_remove_extension(), handle_context_remove_extension_deprecated(), handle_save_dialplan(), park_add_hints(), pbx_load_config(), and print_ext().
typedef int(*) ast_state_cb_type(char *context, char *id, enum ast_extension_states state, void *data) |
typedef int( ast_switch_f)(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
enum ast_extension_states |
Extension states.
Definition at line 47 of file pbx.h.
00047 { 00048 AST_EXTENSION_REMOVED = -2, /*!< Extension removed */ 00049 AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */ 00050 AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */ 00051 AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */ 00052 AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */ 00053 AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */ 00054 AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */ 00055 AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */ 00056 };
enum ast_pbx_result |
Definition at line 214 of file pbx.h.
00214 { 00215 AST_PBX_SUCCESS = 0, 00216 AST_PBX_FAILED = -1, 00217 AST_PBX_CALL_LIMIT = -2, 00218 };
int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 2693 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02694 { 02695 return countcalls; 02696 }
int ast_add_extension | ( | const char * | context, | |
int | replace, | |||
const char * | extension, | |||
int | priority, | |||
const char * | label, | |||
const char * | callerid, | |||
const char * | application, | |||
void * | data, | |||
void(*)(void *) | datad, | |||
const char * | registrar | |||
) |
Add and extension to an extension context.
context | context to add the extension to | |
replace | ||
extension | extension to add | |
priority | priority level of extension addition | |
label | extension label | |
callerid | pattern to match CallerID, or NULL to match any CallerID | |
application | application to run on the extension with that priority level | |
data | data to pass to the application | |
datad | ||
registrar | who registered the extension |
0 | success | |
-1 | failure |
Definition at line 4570 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().
04573 { 04574 int ret = -1; 04575 struct ast_context *c = find_context_locked(context); 04576 04577 if (c) { 04578 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04579 application, data, datad, registrar); 04580 ast_unlock_contexts(); 04581 } 04582 return ret; 04583 }
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 4785 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, ast_exten::label, ast_context::lock, ast_exten::matchcid, 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().
04789 { 04790 /* 04791 * Sort extensions (or patterns) according to the rules indicated above. 04792 * These are implemented by the function ext_cmp()). 04793 * All priorities for the same ext/pattern/cid are kept in a list, 04794 * using the 'peer' field as a link field.. 04795 */ 04796 struct ast_exten *tmp, *e, *el = NULL; 04797 int res; 04798 int length; 04799 char *p; 04800 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04801 04802 /* if we are adding a hint, and there are global variables, and the hint 04803 contains variable references, then expand them 04804 */ 04805 ast_mutex_lock(&globalslock); 04806 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04807 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04808 application = expand_buf; 04809 } 04810 ast_mutex_unlock(&globalslock); 04811 04812 length = sizeof(struct ast_exten); 04813 length += strlen(extension) + 1; 04814 length += strlen(application) + 1; 04815 if (label) 04816 length += strlen(label) + 1; 04817 if (callerid) 04818 length += strlen(callerid) + 1; 04819 else 04820 length ++; /* just the '\0' */ 04821 04822 /* Be optimistic: Build the extension structure first */ 04823 if (!(tmp = ast_calloc(1, length))) 04824 return -1; 04825 04826 /* use p as dst in assignments, as the fields are const char * */ 04827 p = tmp->stuff; 04828 if (label) { 04829 tmp->label = p; 04830 strcpy(p, label); 04831 p += strlen(label) + 1; 04832 } 04833 tmp->exten = p; 04834 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04835 tmp->priority = priority; 04836 tmp->cidmatch = p; /* but use p for assignments below */ 04837 if (callerid) { 04838 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04839 tmp->matchcid = 1; 04840 } else { 04841 *p++ = '\0'; 04842 tmp->matchcid = 0; 04843 } 04844 tmp->app = p; 04845 strcpy(p, application); 04846 tmp->parent = con; 04847 tmp->data = data; 04848 tmp->datad = datad; 04849 tmp->registrar = registrar; 04850 04851 ast_mutex_lock(&con->lock); 04852 res = 0; /* some compilers will think it is uninitialized otherwise */ 04853 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04854 res = ext_cmp(e->exten, extension); 04855 if (res == 0) { /* extension match, now look at cidmatch */ 04856 if (!e->matchcid && !tmp->matchcid) 04857 res = 0; 04858 else if (tmp->matchcid && !e->matchcid) 04859 res = 1; 04860 else if (e->matchcid && !tmp->matchcid) 04861 res = -1; 04862 else 04863 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04864 } 04865 if (res >= 0) 04866 break; 04867 } 04868 if (e && res == 0) { /* exact match, insert in the pri chain */ 04869 res = add_pri(con, tmp, el, e, replace); 04870 ast_mutex_unlock(&con->lock); 04871 if (res < 0) { 04872 errno = EEXIST; /* XXX do we care ? */ 04873 return 0; /* XXX should we return -1 maybe ? */ 04874 } 04875 } else { 04876 /* 04877 * not an exact match, this is the first entry with this pattern, 04878 * so insert in the main list right before 'e' (if any) 04879 */ 04880 tmp->next = e; 04881 if (el) 04882 el->next = tmp; 04883 else 04884 con->root = tmp; 04885 ast_mutex_unlock(&con->lock); 04886 if (tmp->priority == PRIORITY_HINT) 04887 ast_add_hint(tmp); 04888 } 04889 if (option_debug) { 04890 if (tmp->matchcid) { 04891 if (option_debug) 04892 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04893 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04894 } else { 04895 if (option_debug) 04896 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04897 tmp->exten, tmp->priority, con->name); 04898 } 04899 } 04900 if (option_verbose > 2) { 04901 if (tmp->matchcid) { 04902 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04903 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04904 } else { 04905 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04906 tmp->exten, tmp->priority, con->name); 04907 } 04908 } 04909 return 0; 04910 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4608 of file pbx.c.
References ast_channel::_state, ast_channel::amaflags, ast_cdr_discard(), ast_cdr_dup(), ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_unlock, ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_pbx_start(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_channel::cdr, ast_channel::context, ast_channel::exten, LOG_WARNING, ast_channel::pbx, ast_channel::readformat, S_OR, and ast_channel::writeformat.
Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), console_transfer_deprecated(), dahdi_handle_dtmfup(), handle_request_bye(), handle_request_refer(), process_ast_dsp(), and socket_process().
04609 { 04610 int res = 0; 04611 04612 ast_channel_lock(chan); 04613 04614 if (chan->pbx) { /* This channel is currently in the PBX */ 04615 ast_explicit_goto(chan, context, exten, priority); 04616 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04617 } else { 04618 /* In order to do it when the channel doesn't really exist within 04619 the PBX, we have to make a new channel, masquerade, and start the PBX 04620 at the new location */ 04621 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04622 if (!tmpchan) { 04623 res = -1; 04624 } else { 04625 if (chan->cdr) { 04626 ast_cdr_discard(tmpchan->cdr); 04627 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 04628 } 04629 /* Make formats okay */ 04630 tmpchan->readformat = chan->readformat; 04631 tmpchan->writeformat = chan->writeformat; 04632 /* Setup proper location */ 04633 ast_explicit_goto(tmpchan, 04634 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04635 04636 /* Masquerade into temp channel */ 04637 if (ast_channel_masquerade(tmpchan, chan)) { 04638 /* Failed to set up the masquerade. It's probably chan_local 04639 * in the middle of optimizing itself out. Sad. :( */ 04640 ast_hangup(tmpchan); 04641 tmpchan = NULL; 04642 res = -1; 04643 } else { 04644 /* Grab the locks and get going */ 04645 ast_channel_lock(tmpchan); 04646 ast_do_masquerade(tmpchan); 04647 ast_channel_unlock(tmpchan); 04648 /* Start the PBX going on our stolen channel */ 04649 if (ast_pbx_start(tmpchan)) { 04650 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04651 ast_hangup(tmpchan); 04652 res = -1; 04653 } 04654 } 04655 } 04656 } 04657 ast_channel_unlock(chan); 04658 return res; 04659 }
int ast_async_goto_by_name | ( | const char * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4661 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04662 { 04663 struct ast_channel *chan; 04664 int res = -1; 04665 04666 chan = ast_get_channel_by_name_locked(channame); 04667 if (chan) { 04668 res = ast_async_goto(chan, context, exten, priority); 04669 ast_channel_unlock(chan); 04670 } 04671 return res; 04672 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6462 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06463 { 06464 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06465 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info | |||
) |
Definition at line 4253 of file pbx.c.
References ast_strlen_zero(), ast_timing::daymask, days, ast_timing::dowmask, get_range(), get_timerange(), ast_timing::monthmask, months, and strsep().
Referenced by ast_context_add_include2(), iftime(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
04254 { 04255 char info_save[256]; 04256 char *info; 04257 04258 /* Check for empty just in case */ 04259 if (ast_strlen_zero(info_in)) 04260 return 0; 04261 /* make a copy just in case we were passed a static string */ 04262 ast_copy_string(info_save, info_in, sizeof(info_save)); 04263 info = info_save; 04264 /* Assume everything except time */ 04265 i->monthmask = 0xfff; /* 12 bits */ 04266 i->daymask = 0x7fffffffU; /* 31 bits */ 04267 i->dowmask = 0x7f; /* 7 bits */ 04268 /* on each call, use strsep() to move info to the next argument */ 04269 get_timerange(i, strsep(&info, "|")); 04270 if (info) 04271 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04272 if (info) 04273 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04274 if (info) 04275 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04276 return 1; 04277 }
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 2330 of file pbx.c.
References E_CANMATCH, and pbx_extension_helper().
Referenced by background_detect_exec(), cb_events(), 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().
02331 { 02332 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH); 02333 }
int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 4279 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().
04280 { 04281 struct tm tm; 04282 time_t t = time(NULL); 04283 04284 ast_localtime(&t, &tm, NULL); 04285 04286 /* If it's not the right month, return */ 04287 if (!(i->monthmask & (1 << tm.tm_mon))) 04288 return 0; 04289 04290 /* If it's not that time of the month.... */ 04291 /* Warning, tm_mday has range 1..31! */ 04292 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04293 return 0; 04294 04295 /* If it's not the right day of the week */ 04296 if (!(i->dowmask & (1 << tm.tm_wday))) 04297 return 0; 04298 04299 /* Sanity check the hour just to be safe */ 04300 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04301 ast_log(LOG_WARNING, "Insane time...\n"); 04302 return 0; 04303 } 04304 04305 /* Now the tough part, we calculate if it fits 04306 in the right time based on min/hour */ 04307 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04308 return 0; 04309 04310 /* If we got this far, then we're good */ 04311 return 1; 04312 }
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 4506 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().
04507 { 04508 int ret = -1; 04509 struct ast_context *c = find_context_locked(context); 04510 04511 if (c) { 04512 ret = ast_context_add_ignorepat2(c, value, registrar); 04513 ast_unlock_contexts(); 04514 } 04515 return ret; 04516 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4518 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().
04519 { 04520 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04521 int length; 04522 length = sizeof(struct ast_ignorepat); 04523 length += strlen(value) + 1; 04524 if (!(ignorepat = ast_calloc(1, length))) 04525 return -1; 04526 /* The cast to char * is because we need to write the initial value. 04527 * The field is not supposed to be modified otherwise 04528 */ 04529 strcpy((char *)ignorepat->pattern, value); 04530 ignorepat->next = NULL; 04531 ignorepat->registrar = registrar; 04532 ast_mutex_lock(&con->lock); 04533 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04534 ignorepatl = ignorepatc; 04535 if (!strcasecmp(ignorepatc->pattern, value)) { 04536 /* Already there */ 04537 ast_mutex_unlock(&con->lock); 04538 errno = EEXIST; 04539 return -1; 04540 } 04541 } 04542 if (ignorepatl) 04543 ignorepatl->next = ignorepat; 04544 else 04545 con->ignorepats = ignorepat; 04546 ast_mutex_unlock(&con->lock); 04547 return 0; 04548 04549 }
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 4059 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().
04060 { 04061 int ret = -1; 04062 struct ast_context *c = find_context_locked(context); 04063 04064 if (c) { 04065 ret = ast_context_add_include2(c, include, registrar); 04066 ast_unlock_contexts(); 04067 } 04068 return ret; 04069 }
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 4321 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().
04323 { 04324 struct ast_include *new_include; 04325 char *c; 04326 struct ast_include *i, *il = NULL; /* include, include_last */ 04327 int length; 04328 char *p; 04329 04330 length = sizeof(struct ast_include); 04331 length += 2 * (strlen(value) + 1); 04332 04333 /* allocate new include structure ... */ 04334 if (!(new_include = ast_calloc(1, length))) 04335 return -1; 04336 /* Fill in this structure. Use 'p' for assignments, as the fields 04337 * in the structure are 'const char *' 04338 */ 04339 p = new_include->stuff; 04340 new_include->name = p; 04341 strcpy(p, value); 04342 p += strlen(value) + 1; 04343 new_include->rname = p; 04344 strcpy(p, value); 04345 /* Strip off timing info, and process if it is there */ 04346 if ( (c = strchr(p, '|')) ) { 04347 *c++ = '\0'; 04348 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04349 } 04350 new_include->next = NULL; 04351 new_include->registrar = registrar; 04352 04353 ast_mutex_lock(&con->lock); 04354 04355 /* ... go to last include and check if context is already included too... */ 04356 for (i = con->includes; i; i = i->next) { 04357 if (!strcasecmp(i->name, new_include->name)) { 04358 free(new_include); 04359 ast_mutex_unlock(&con->lock); 04360 errno = EEXIST; 04361 return -1; 04362 } 04363 il = i; 04364 } 04365 04366 /* ... include new context into context list, unlock, return */ 04367 if (il) 04368 il->next = new_include; 04369 else 04370 con->includes = new_include; 04371 if (option_verbose > 2) 04372 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04373 ast_mutex_unlock(&con->lock); 04374 04375 return 0; 04376 }
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 4383 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04384 { 04385 int ret = -1; 04386 struct ast_context *c = find_context_locked(context); 04387 04388 if (c) { /* found, add switch to this context */ 04389 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04390 ast_unlock_contexts(); 04391 } 04392 return ret; 04393 }
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 4402 of file pbx.c.
References 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, ast_context::lock, ast_sw::name, option_verbose, ast_sw::registrar, and VERBOSE_PREFIX_3.
Referenced by ast_context_add_switch(), and pbx_load_config().
04404 { 04405 struct ast_sw *new_sw; 04406 struct ast_sw *i; 04407 int length; 04408 char *p; 04409 04410 length = sizeof(struct ast_sw); 04411 length += strlen(value) + 1; 04412 if (data) 04413 length += strlen(data); 04414 length++; 04415 04416 /* allocate new sw structure ... */ 04417 if (!(new_sw = ast_calloc(1, length))) 04418 return -1; 04419 /* ... fill in this structure ... */ 04420 p = new_sw->stuff; 04421 new_sw->name = p; 04422 strcpy(new_sw->name, value); 04423 p += strlen(value) + 1; 04424 new_sw->data = p; 04425 if (data) { 04426 strcpy(new_sw->data, data); 04427 p += strlen(data) + 1; 04428 } else { 04429 strcpy(new_sw->data, ""); 04430 p++; 04431 } 04432 new_sw->eval = eval; 04433 new_sw->registrar = registrar; 04434 04435 /* ... try to lock this context ... */ 04436 ast_mutex_lock(&con->lock); 04437 04438 /* ... go to last sw and check if context is already swd too... */ 04439 AST_LIST_TRAVERSE(&con->alts, i, list) { 04440 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04441 free(new_sw); 04442 ast_mutex_unlock(&con->lock); 04443 errno = EEXIST; 04444 return -1; 04445 } 04446 } 04447 04448 /* ... sw new context into context list, unlock, return */ 04449 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04450 04451 if (option_verbose > 2) 04452 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04453 04454 ast_mutex_unlock(&con->lock); 04455 04456 return 0; 04457 }
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 3929 of file pbx.c.
References __ast_context_create().
Referenced by do_parking_thread(), park_call_full(), and set_config().
03930 { 03931 return __ast_context_create(extcontexts, name, registrar, 0); 03932 }
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 5366 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().
05367 { 05368 ast_wrlock_contexts(); 05369 __ast_context_destroy(con,registrar); 05370 ast_unlock_contexts(); 05371 }
struct ast_context* ast_context_find | ( | const char * | name | ) |
Find a context.
name | name of the context to find |
Definition at line 917 of file pbx.c.
References ast_rdlock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
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().
00918 { 00919 struct ast_context *tmp = NULL; 00920 00921 ast_rdlock_contexts(); 00922 00923 while ( (tmp = ast_walk_contexts(tmp)) ) { 00924 if (!name || !strcasecmp(name, tmp->name)) 00925 break; 00926 } 00927 00928 ast_unlock_contexts(); 00929 00930 return tmp; 00931 }
struct ast_context* ast_context_find_or_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar | |||
) |
Definition at line 3934 of file pbx.c.
References __ast_context_create().
Referenced by pbx_load_config(), and pbx_load_users().
03935 { 03936 return __ast_context_create(extcontexts, name, registrar, 1); 03937 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 2930 of file pbx.c.
References ast_get_context_name(), ast_mutex_lock(), ast_rdlock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by _macro_exec().
02931 { 02932 struct ast_context *c = NULL; 02933 int ret = -1; 02934 02935 ast_rdlock_contexts(); 02936 02937 while ((c = ast_walk_contexts(c))) { 02938 if (!strcmp(ast_get_context_name(c), context)) { 02939 ret = 0; 02940 break; 02941 } 02942 } 02943 02944 ast_unlock_contexts(); 02945 02946 /* if we found context, lock macrolock */ 02947 if (ret == 0) 02948 ret = ast_mutex_lock(&c->macrolock); 02949 02950 return ret; 02951 }
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 2831 of file pbx.c.
References ast_context_remove_extension_callerid().
Referenced by destroy_station(), destroy_trunk(), and register_peer_exten().
02832 { 02833 return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar); 02834 }
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 2858 of file pbx.c.
References ast_context_remove_extension_callerid2().
Referenced by do_parking_thread(), and park_exec().
02859 { 02860 return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar); 02861 }
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 2836 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().
02837 { 02838 int ret = -1; /* default error return */ 02839 struct ast_context *c = find_context_locked(context); 02840 02841 if (c) { /* ... remove extension ... */ 02842 ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar); 02843 ast_unlock_contexts(); 02844 } 02845 return ret; 02846 }
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 2863 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().
02864 { 02865 struct ast_exten *exten, *prev_exten = NULL; 02866 struct ast_exten *peer; 02867 struct ast_exten *previous_peer = NULL; 02868 struct ast_exten *next_peer = NULL; 02869 int found = 0; 02870 02871 ast_mutex_lock(&con->lock); 02872 02873 /* scan the extension list to find first matching extension-registrar */ 02874 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02875 if (!strcmp(exten->exten, extension) && 02876 (!registrar || !strcmp(exten->registrar, registrar))) 02877 break; 02878 } 02879 if (!exten) { 02880 /* we can't find right extension */ 02881 ast_mutex_unlock(&con->lock); 02882 return -1; 02883 } 02884 02885 /* scan the priority list to remove extension with exten->priority == priority */ 02886 for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next; 02887 peer && !strcmp(peer->exten, extension); 02888 peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) { 02889 if ((priority == 0 || peer->priority == priority) && 02890 (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) && 02891 (!registrar || !strcmp(peer->registrar, registrar) )) { 02892 found = 1; 02893 02894 /* we are first priority extension? */ 02895 if (!previous_peer) { 02896 /* 02897 * We are first in the priority chain, so must update the extension chain. 02898 * The next node is either the next priority or the next extension 02899 */ 02900 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02901 02902 if (!prev_exten) { /* change the root... */ 02903 con->root = next_node; 02904 } else { 02905 prev_exten->next = next_node; /* unlink */ 02906 } 02907 if (peer->peer) { /* update the new head of the pri list */ 02908 peer->peer->next = peer->next; 02909 } 02910 } else { /* easy, we are not first priority in extension */ 02911 previous_peer->peer = peer->peer; 02912 } 02913 02914 /* now, free whole priority extension */ 02915 destroy_exten(peer); 02916 } else { 02917 previous_peer = peer; 02918 } 02919 } 02920 ast_mutex_unlock(&con->lock); 02921 return found ? 0 : -1; 02922 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4463 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().
04464 { 04465 int ret = -1; 04466 struct ast_context *c = find_context_locked(context); 04467 04468 if (c) { 04469 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04470 ast_unlock_contexts(); 04471 } 04472 return ret; 04473 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4475 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().
04476 { 04477 struct ast_ignorepat *ip, *ipl = NULL; 04478 04479 ast_mutex_lock(&con->lock); 04480 04481 for (ip = con->ignorepats; ip; ip = ip->next) { 04482 if (!strcmp(ip->pattern, ignorepat) && 04483 (!registrar || (registrar == ip->registrar))) { 04484 if (ipl) { 04485 ipl->next = ip->next; 04486 free(ip); 04487 } else { 04488 con->ignorepats = ip->next; 04489 free(ip); 04490 } 04491 ast_mutex_unlock(&con->lock); 04492 return 0; 04493 } 04494 ipl = ip; 04495 } 04496 04497 ast_mutex_unlock(&con->lock); 04498 errno = EINVAL; 04499 return -1; 04500 }
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 2727 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().
02728 { 02729 int ret = -1; 02730 struct ast_context *c = find_context_locked(context); 02731 02732 if (c) { 02733 /* found, remove include from this context ... */ 02734 ret = ast_context_remove_include2(c, include, registrar); 02735 ast_unlock_contexts(); 02736 } 02737 return ret; 02738 }
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 2748 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().
02749 { 02750 struct ast_include *i, *pi = NULL; 02751 int ret = -1; 02752 02753 ast_mutex_lock(&con->lock); 02754 02755 /* find our include */ 02756 for (i = con->includes; i; pi = i, i = i->next) { 02757 if (!strcmp(i->name, include) && 02758 (!registrar || !strcmp(i->registrar, registrar))) { 02759 /* remove from list */ 02760 if (pi) 02761 pi->next = i->next; 02762 else 02763 con->includes = i->next; 02764 /* free include and return */ 02765 free(i); 02766 ret = 0; 02767 break; 02768 } 02769 } 02770 02771 ast_mutex_unlock(&con->lock); 02772 return ret; 02773 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 2780 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
02781 { 02782 int ret = -1; /* default error return */ 02783 struct ast_context *c = find_context_locked(context); 02784 02785 if (c) { 02786 /* remove switch from this context ... */ 02787 ret = ast_context_remove_switch2(c, sw, data, registrar); 02788 ast_unlock_contexts(); 02789 } 02790 return ret; 02791 }
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 2801 of file pbx.c.
References 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_context::lock, ast_sw::name, and ast_sw::registrar.
Referenced by ast_context_remove_switch().
02802 { 02803 struct ast_sw *i; 02804 int ret = -1; 02805 02806 ast_mutex_lock(&con->lock); 02807 02808 /* walk switches */ 02809 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02810 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02811 (!registrar || !strcmp(i->registrar, registrar))) { 02812 /* found, remove from list */ 02813 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02814 free(i); /* free switch and return */ 02815 ret = 0; 02816 break; 02817 } 02818 } 02819 AST_LIST_TRAVERSE_SAFE_END 02820 02821 ast_mutex_unlock(&con->lock); 02822 02823 return ret; 02824 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 2958 of file pbx.c.
References ast_get_context_name(), ast_mutex_unlock(), ast_rdlock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by _macro_exec().
02959 { 02960 struct ast_context *c = NULL; 02961 int ret = -1; 02962 02963 ast_rdlock_contexts(); 02964 02965 while ((c = ast_walk_contexts(c))) { 02966 if (!strcmp(ast_get_context_name(c), context)) { 02967 ret = 0; 02968 break; 02969 } 02970 } 02971 02972 ast_unlock_contexts(); 02973 02974 /* if we found context, unlock macrolock */ 02975 if (ret == 0) 02976 ret = ast_mutex_unlock(&c->macrolock); 02977 02978 return ret; 02979 }
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 6419 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().
06420 { 06421 struct ast_include *inc = NULL; 06422 int res = 0; 06423 06424 while ( (inc = ast_walk_context_includes(con, inc)) ) { 06425 if (ast_context_find(inc->rname)) 06426 continue; 06427 06428 res = -1; 06429 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 06430 ast_get_context_name(con), inc->rname); 06431 break; 06432 } 06433 06434 return res; 06435 }
struct ast_custom_function* ast_custom_function_find | ( | const char * | name | ) |
Definition at line 1479 of file pbx.c.
References 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().
01480 { 01481 struct ast_custom_function *acf = NULL; 01482 01483 AST_LIST_LOCK(&acf_root); 01484 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01485 if (!strcmp(name, acf->name)) 01486 break; 01487 } 01488 AST_LIST_UNLOCK(&acf_root); 01489 01490 return acf; 01491 }
int ast_custom_function_register | ( | struct ast_custom_function * | acf | ) |
Reigster a custom function.
Definition at line 1515 of file pbx.c.
References 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().
01516 { 01517 struct ast_custom_function *cur; 01518 01519 if (!acf) 01520 return -1; 01521 01522 AST_LIST_LOCK(&acf_root); 01523 01524 if (ast_custom_function_find(acf->name)) { 01525 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01526 AST_LIST_UNLOCK(&acf_root); 01527 return -1; 01528 } 01529 01530 /* Store in alphabetical order */ 01531 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01532 if (strcasecmp(acf->name, cur->name) < 0) { 01533 AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist); 01534 break; 01535 } 01536 } 01537 AST_LIST_TRAVERSE_SAFE_END 01538 if (!cur) 01539 AST_LIST_INSERT_TAIL(&acf_root, acf, acflist); 01540 01541 AST_LIST_UNLOCK(&acf_root); 01542 01543 if (option_verbose > 1) 01544 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01545 01546 return 0; 01547 }
int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Unregister a custom function.
Definition at line 1493 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(), ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by odbc_unload_module(), reload(), and unload_module().
01494 { 01495 struct ast_custom_function *cur; 01496 01497 if (!acf) 01498 return -1; 01499 01500 AST_LIST_LOCK(&acf_root); 01501 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01502 if (cur == acf) { 01503 AST_LIST_REMOVE_CURRENT(&acf_root, acflist); 01504 if (option_verbose > 1) 01505 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01506 break; 01507 } 01508 } 01509 AST_LIST_TRAVERSE_SAFE_END 01510 AST_LIST_UNLOCK(&acf_root); 01511 01512 return acf ? 0 : -1; 01513 }
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 2315 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_pbx_outgoing_exten(), builtin_blindtransfer(), cb_events(), conf_run(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), dahdi_handle_dtmfup(), disa_exec(), do_atxfer(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), handle_stimulus_message(), leave_voicemail(), local_alloc(), local_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), misdn_overlap_dial_task(), park_call_full(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), process_ast_dsp(), register_peer_exten(), skinny_ss(), socket_process(), ss_thread(), and waitstream_core().
02316 { 02317 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH); 02318 }
int ast_explicit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4585 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, 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().
04586 { 04587 if (!chan) 04588 return -1; 04589 04590 ast_channel_lock(chan); 04591 04592 if (!ast_strlen_zero(context)) 04593 ast_copy_string(chan->context, context, sizeof(chan->context)); 04594 if (!ast_strlen_zero(exten)) 04595 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04596 if (priority > -1) { 04597 chan->priority = priority; 04598 /* see flag description in channel.h for explanation */ 04599 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04600 chan->priority--; 04601 } 04602 04603 ast_channel_unlock(chan); 04604 04605 return 0; 04606 }
int ast_extension_close | ( | const char * | pattern, | |
const char * | data, | |||
int | needmore | |||
) |
Definition at line 910 of file pbx.c.
References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.
Referenced by realtime_switch_common().
00911 { 00912 if (needmore != E_MATCHMORE && needmore != E_CANMATCH) 00913 ast_log(LOG_WARNING, "invalid argument %d\n", needmore); 00914 return extension_match_core(pattern, data, needmore); 00915 }
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 905 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().
00906 { 00907 return extension_match_core(pattern, data, E_MATCH); 00908 }
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 2039 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), and handle_request_subscribe().
02040 { 02041 struct ast_exten *e; 02042 02043 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 02044 if (!e) 02045 return -1; /* No hint, return -1 */ 02046 02047 return ast_extension_state2(e); /* Check all devices in the hint */ 02048 }
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 2027 of file pbx.c.
References extension_states.
Referenced by cb_extensionstate(), handle_request_subscribe(), and handle_show_hints().
02028 { 02029 int i; 02030 02031 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 02032 if (extension_states[i].extension_state == extension_state) 02033 return extension_states[i].text; 02034 } 02035 return "Unknown"; 02036 }
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 2094 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().
02096 { 02097 struct ast_hint *hint; 02098 struct ast_state_cb *cblist; 02099 struct ast_exten *e; 02100 02101 /* If there's no context and extension: add callback to statecbs list */ 02102 if (!context && !exten) { 02103 AST_LIST_LOCK(&hints); 02104 02105 for (cblist = statecbs; cblist; cblist = cblist->next) { 02106 if (cblist->callback == callback) { 02107 cblist->data = data; 02108 AST_LIST_UNLOCK(&hints); 02109 return 0; 02110 } 02111 } 02112 02113 /* Now insert the callback */ 02114 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02115 AST_LIST_UNLOCK(&hints); 02116 return -1; 02117 } 02118 cblist->id = 0; 02119 cblist->callback = callback; 02120 cblist->data = data; 02121 02122 cblist->next = statecbs; 02123 statecbs = cblist; 02124 02125 AST_LIST_UNLOCK(&hints); 02126 return 0; 02127 } 02128 02129 if (!context || !exten) 02130 return -1; 02131 02132 /* This callback type is for only one hint, so get the hint */ 02133 e = ast_hint_extension(NULL, context, exten); 02134 if (!e) { 02135 return -1; 02136 } 02137 02138 /* Find the hint in the list of hints */ 02139 AST_LIST_LOCK(&hints); 02140 02141 AST_LIST_TRAVERSE(&hints, hint, list) { 02142 if (hint->exten == e) 02143 break; 02144 } 02145 02146 if (!hint) { 02147 /* We have no hint, sorry */ 02148 AST_LIST_UNLOCK(&hints); 02149 return -1; 02150 } 02151 02152 /* Now insert the callback in the callback list */ 02153 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02154 AST_LIST_UNLOCK(&hints); 02155 return -1; 02156 } 02157 cblist->id = stateid++; /* Unique ID for this callback */ 02158 cblist->callback = callback; /* Pointer to callback routine */ 02159 cblist->data = data; /* Data for the callback */ 02160 02161 cblist->next = hint->callbacks; 02162 hint->callbacks = cblist; 02163 02164 AST_LIST_UNLOCK(&hints); 02165 return cblist->id; 02166 }
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 2169 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_hint::callbacks, free, ast_state_cb::next, and statecbs.
Referenced by __sip_destroy(), and handle_request_subscribe().
02170 { 02171 struct ast_state_cb **p_cur = NULL; /* address of pointer to us */ 02172 int ret = -1; 02173 02174 if (!id && !callback) 02175 return -1; 02176 02177 AST_LIST_LOCK(&hints); 02178 02179 if (!id) { /* id == 0 is a callback without extension */ 02180 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) { 02181 if ((*p_cur)->callback == callback) 02182 break; 02183 } 02184 } else { /* callback with extension, find the callback based on ID */ 02185 struct ast_hint *hint; 02186 AST_LIST_TRAVERSE(&hints, hint, list) { 02187 for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) { 02188 if ((*p_cur)->id == id) 02189 break; 02190 } 02191 if (*p_cur) /* found in the inner loop */ 02192 break; 02193 } 02194 } 02195 if (p_cur && *p_cur) { 02196 struct ast_state_cb *cur = *p_cur; 02197 *p_cur = cur->next; 02198 free(cur); 02199 ret = 0; 02200 } 02201 AST_LIST_UNLOCK(&hints); 02202 return ret; 02203 }
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 2320 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().
02321 { 02322 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL); 02323 }
int ast_findlabel_extension2 | ( | struct ast_channel * | c, | |
struct ast_context * | con, | |||
const char * | exten, | |||
const char * | label, | |||
const char * | callerid | |||
) |
Find the priority of an extension that has the specified label.
Definition at line 2325 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
02326 { 02327 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL); 02328 }
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 1569 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().
01570 { 01571 char *args = func_args(function); 01572 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01573 01574 if (acfptr == NULL) 01575 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01576 else if (!acfptr->read) 01577 ast_log(LOG_ERROR, "Function %s cannot be read\n", function); 01578 else 01579 return acfptr->read(chan, function, args, workspace, len); 01580 return -1; 01581 }
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 1583 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().
01584 { 01585 char *args = func_args(function); 01586 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01587 01588 if (acfptr == NULL) 01589 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01590 else if (!acfptr->write) 01591 ast_log(LOG_ERROR, "Function %s cannot be written to\n", function); 01592 else 01593 return acfptr->write(chan, function, args, value); 01594 01595 return -1; 01596 }
const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 6276 of file pbx.c.
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().
const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 6314 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06315 { 06316 return c ? c->registrar : NULL; 06317 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6344 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().
06345 { 06346 return e ? e->app : NULL; 06347 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6349 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06350 { 06351 return e ? e->data : NULL; 06352 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6339 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().
06340 { 06341 return e ? e->cidmatch : NULL; 06342 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
const char* ast_get_extension_label | ( | struct ast_exten * | e | ) |
Definition at line 6291 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 6334 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().
06335 { 06336 return e ? e->matchcid : 0; 06337 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6286 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 6306 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 6319 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06320 { 06321 return e ? e->registrar : NULL; 06322 }
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 2298 of file pbx.c.
References 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().
02299 { 02300 struct ast_exten *e = ast_hint_extension(c, context, exten); 02301 02302 if (e) { 02303 if (hint) 02304 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02305 if (name) { 02306 const char *tmp = ast_get_extension_app_data(e); 02307 if (tmp) 02308 ast_copy_string(name, tmp, namesize); 02309 } 02310 return -1; 02311 } 02312 return 0; 02313 }
const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6301 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().
06302 { 06303 return ip ? ip->pattern : NULL; 06304 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6329 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06330 { 06331 return ip ? ip->registrar : NULL; 06332 }
const char* ast_get_include_name | ( | struct ast_include * | include | ) |
Definition at line 6296 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 6324 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06325 { 06326 return i ? i->registrar : NULL; 06327 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6359 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06360 { 06361 return sw ? sw->data : NULL; 06362 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6354 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06355 { 06356 return sw ? sw->name : NULL; 06357 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6364 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06365 { 06366 return sw ? sw->registrar : NULL; 06367 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6457 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().
06458 { 06459 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06460 }
void ast_hint_state_changed | ( | const char * | device | ) |
Definition at line 2050 of file pbx.c.
References ast_extension_state2(), ast_get_extension_app(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, AST_MAX_EXTENSION, ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_exten::exten, ast_hint::exten, ast_hint::laststate, ast_state_cb::next, ast_exten::parent, parse(), statecbs, and strsep().
Referenced by do_state_change().
02051 { 02052 struct ast_hint *hint; 02053 02054 AST_LIST_LOCK(&hints); 02055 02056 AST_LIST_TRAVERSE(&hints, hint, list) { 02057 struct ast_state_cb *cblist; 02058 char buf[AST_MAX_EXTENSION]; 02059 char *parse = buf; 02060 char *cur; 02061 int state; 02062 02063 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 02064 while ( (cur = strsep(&parse, "&")) ) { 02065 if (!strcasecmp(cur, device)) 02066 break; 02067 } 02068 if (!cur) 02069 continue; 02070 02071 /* Get device state for this hint */ 02072 state = ast_extension_state2(hint->exten); 02073 02074 if ((state == -1) || (state == hint->laststate)) 02075 continue; 02076 02077 /* Device state changed since last check - notify the watchers */ 02078 02079 /* For general callbacks */ 02080 for (cblist = statecbs; cblist; cblist = cblist->next) 02081 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02082 02083 /* For extension callbacks */ 02084 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 02085 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02086 02087 hint->laststate = state; /* record we saw the change */ 02088 } 02089 02090 AST_LIST_UNLOCK(&hints); 02091 }
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 4551 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().
04552 { 04553 struct ast_context *con = ast_context_find(context); 04554 if (con) { 04555 struct ast_ignorepat *pat; 04556 for (pat = con->ignorepats; pat; pat = pat->next) { 04557 if (ast_extension_match(pat->pattern, pattern)) 04558 return 1; 04559 } 04560 } 04561 04562 return 0; 04563 }
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 6263 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().
06264 { 06265 return ast_mutex_lock(&con->lock); 06266 }
int ast_lock_contexts | ( | void | ) |
Locks the context list.
0 | on success | |
-1 | on error |
Definition at line 6240 of file pbx.c.
References ast_rwlock_wrlock().
Referenced by find_matching_endwhile().
06241 { 06242 return ast_rwlock_wrlock(&conlock); 06243 }
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 2335 of file pbx.c.
References E_MATCHMORE, and pbx_extension_helper().
Referenced by ast_app_dtget(), collect_digits(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_stimulus_message(), loopback_matchmore(), mgcp_ss(), skinny_ss(), and ss_thread().
02336 { 02337 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE); 02338 }
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 3952 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, ast_exten::exten, ast_hint::exten, store_hint::exten, free, ast_hint::laststate, store_hint::laststate, LOG_WARNING, 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().
03953 { 03954 struct ast_context *tmp, *lasttmp = NULL; 03955 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 03956 struct store_hint *this; 03957 struct ast_hint *hint; 03958 struct ast_exten *exten; 03959 int length; 03960 struct ast_state_cb *thiscb, *prevcb; 03961 03962 /* it is very important that this function hold the hint list lock _and_ the conlock 03963 during its operation; not only do we need to ensure that the list of contexts 03964 and extensions does not change, but also that no hint callbacks (watchers) are 03965 added or removed during the merge/delete process 03966 03967 in addition, the locks _must_ be taken in this order, because there are already 03968 other code paths that use this order 03969 */ 03970 ast_wrlock_contexts(); 03971 AST_LIST_LOCK(&hints); 03972 03973 /* preserve all watchers for hints associated with this registrar */ 03974 AST_LIST_TRAVERSE(&hints, hint, list) { 03975 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03976 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03977 if (!(this = ast_calloc(1, length))) 03978 continue; 03979 this->callbacks = hint->callbacks; 03980 hint->callbacks = NULL; 03981 this->laststate = hint->laststate; 03982 this->context = this->data; 03983 strcpy(this->data, hint->exten->parent->name); 03984 this->exten = this->data + strlen(this->context) + 1; 03985 strcpy(this->exten, hint->exten->exten); 03986 AST_LIST_INSERT_HEAD(&store, this, list); 03987 } 03988 } 03989 03990 tmp = *extcontexts; 03991 if (registrar) { 03992 /* XXX remove previous contexts from same registrar */ 03993 if (option_debug) 03994 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 03995 __ast_context_destroy(NULL,registrar); 03996 while (tmp) { 03997 lasttmp = tmp; 03998 tmp = tmp->next; 03999 } 04000 } else { 04001 /* XXX remove contexts with the same name */ 04002 while (tmp) { 04003 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 04004 __ast_context_destroy(tmp,tmp->registrar); 04005 lasttmp = tmp; 04006 tmp = tmp->next; 04007 } 04008 } 04009 if (lasttmp) { 04010 lasttmp->next = contexts; 04011 contexts = *extcontexts; 04012 *extcontexts = NULL; 04013 } else 04014 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 04015 04016 /* restore the watchers for hints that can be found; notify those that 04017 cannot be restored 04018 */ 04019 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 04020 struct pbx_find_info q = { .stacklen = 0 }; 04021 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 04022 /* Find the hint in the list of hints */ 04023 AST_LIST_TRAVERSE(&hints, hint, list) { 04024 if (hint->exten == exten) 04025 break; 04026 } 04027 if (!exten || !hint) { 04028 /* this hint has been removed, notify the watchers */ 04029 prevcb = NULL; 04030 thiscb = this->callbacks; 04031 while (thiscb) { 04032 prevcb = thiscb; 04033 thiscb = thiscb->next; 04034 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 04035 free(prevcb); 04036 } 04037 } else { 04038 thiscb = this->callbacks; 04039 while (thiscb->next) 04040 thiscb = thiscb->next; 04041 thiscb->next = hint->callbacks; 04042 hint->callbacks = this->callbacks; 04043 hint->laststate = this->laststate; 04044 } 04045 free(this); 04046 } 04047 04048 AST_LIST_UNLOCK(&hints); 04049 ast_unlock_contexts(); 04050 04051 return; 04052 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
This function will handle locking the channel as needed.
Definition at line 6467 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, exten, LOG_WARNING, ast_channel::priority, and strsep().
Referenced by _while_exec(), check_goto_on_transfer(), gosub_exec(), ivr_dispatch(), pbx_builtin_goto(), random_exec(), return_exec(), and while_continue_exec().
06468 { 06469 char *exten, *pri, *context; 06470 char *stringp; 06471 int ipri; 06472 int mode = 0; 06473 06474 if (ast_strlen_zero(goto_string)) { 06475 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06476 return -1; 06477 } 06478 stringp = ast_strdupa(goto_string); 06479 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06480 exten = strsep(&stringp, "|"); 06481 pri = strsep(&stringp, "|"); 06482 if (!exten) { /* Only a priority in this one */ 06483 pri = context; 06484 exten = NULL; 06485 context = NULL; 06486 } else if (!pri) { /* Only an extension and priority in this one */ 06487 pri = exten; 06488 exten = context; 06489 context = NULL; 06490 } 06491 if (*pri == '+') { 06492 mode = 1; 06493 pri++; 06494 } else if (*pri == '-') { 06495 mode = -1; 06496 pri++; 06497 } 06498 if (sscanf(pri, "%d", &ipri) != 1) { 06499 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06500 pri, chan->cid.cid_num)) < 1) { 06501 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06502 return -1; 06503 } else 06504 mode = 0; 06505 } 06506 /* At this point we have a priority and maybe an extension and a context */ 06507 06508 if (mode) 06509 ipri = chan->priority + (ipri * mode); 06510 06511 ast_explicit_goto(chan, context, exten, ipri); 06512 return 0; 06513 06514 }
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 5178 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_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().
05179 { 05180 struct ast_channel *chan; 05181 struct app_tmp *tmp; 05182 int res = -1, cdr_res = -1; 05183 struct outgoing_helper oh; 05184 pthread_attr_t attr; 05185 05186 memset(&oh, 0, sizeof(oh)); 05187 oh.vars = vars; 05188 oh.account = account; 05189 05190 if (locked_channel) 05191 *locked_channel = NULL; 05192 if (ast_strlen_zero(app)) { 05193 res = -1; 05194 goto outgoing_app_cleanup; 05195 } 05196 if (sync) { 05197 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05198 if (chan) { 05199 ast_set_variables(chan, vars); 05200 if (account) 05201 ast_cdr_setaccount(chan, account); 05202 if (chan->_state == AST_STATE_UP) { 05203 res = 0; 05204 if (option_verbose > 3) 05205 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05206 tmp = ast_calloc(1, sizeof(*tmp)); 05207 if (!tmp) 05208 res = -1; 05209 else { 05210 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05211 if (appdata) 05212 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05213 tmp->chan = chan; 05214 if (sync > 1) { 05215 if (locked_channel) 05216 ast_channel_unlock(chan); 05217 ast_pbx_run_app(tmp); 05218 } else { 05219 pthread_attr_init(&attr); 05220 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05221 if (locked_channel) 05222 ast_channel_lock(chan); 05223 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05224 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05225 free(tmp); 05226 if (locked_channel) 05227 ast_channel_unlock(chan); 05228 ast_hangup(chan); 05229 res = -1; 05230 } else { 05231 if (locked_channel) 05232 *locked_channel = chan; 05233 } 05234 pthread_attr_destroy(&attr); 05235 } 05236 } 05237 } else { 05238 if (option_verbose > 3) 05239 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05240 if (chan->cdr) { /* update the cdr */ 05241 /* here we update the status of the call, which sould be busy. 05242 * if that fails then we set the status to failed */ 05243 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05244 ast_cdr_failed(chan->cdr); 05245 } 05246 ast_hangup(chan); 05247 } 05248 } 05249 05250 if (res < 0) { /* the call failed for some reason */ 05251 if (*reason == 0) { /* if the call failed (not busy or no answer) 05252 * update the cdr with the failed message */ 05253 cdr_res = ast_pbx_outgoing_cdr_failed(); 05254 if (cdr_res != 0) { 05255 res = cdr_res; 05256 goto outgoing_app_cleanup; 05257 } 05258 } 05259 } 05260 05261 } else { 05262 struct async_stat *as; 05263 if (!(as = ast_calloc(1, sizeof(*as)))) { 05264 res = -1; 05265 goto outgoing_app_cleanup; 05266 } 05267 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05268 if (!chan) { 05269 free(as); 05270 res = -1; 05271 goto outgoing_app_cleanup; 05272 } 05273 as->chan = chan; 05274 ast_copy_string(as->app, app, sizeof(as->app)); 05275 if (appdata) 05276 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05277 as->timeout = timeout; 05278 ast_set_variables(chan, vars); 05279 if (account) 05280 ast_cdr_setaccount(chan, account); 05281 /* Start a new thread, and get something handling this channel. */ 05282 pthread_attr_init(&attr); 05283 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05284 if (locked_channel) 05285 ast_channel_lock(chan); 05286 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05287 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05288 free(as); 05289 if (locked_channel) 05290 ast_channel_unlock(chan); 05291 ast_hangup(chan); 05292 res = -1; 05293 pthread_attr_destroy(&attr); 05294 goto outgoing_app_cleanup; 05295 } else { 05296 if (locked_channel) 05297 *locked_channel = chan; 05298 } 05299 pthread_attr_destroy(&attr); 05300 res = 0; 05301 } 05302 outgoing_app_cleanup: 05303 ast_variables_destroy(vars); 05304 return res; 05305 }
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 5012 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_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, 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().
05013 { 05014 struct ast_channel *chan; 05015 struct async_stat *as; 05016 int res = -1, cdr_res = -1; 05017 struct outgoing_helper oh; 05018 pthread_attr_t attr; 05019 05020 if (sync) { 05021 LOAD_OH(oh); 05022 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05023 if (channel) { 05024 *channel = chan; 05025 if (chan) 05026 ast_channel_lock(chan); 05027 } 05028 if (chan) { 05029 if (chan->_state == AST_STATE_UP) { 05030 res = 0; 05031 if (option_verbose > 3) 05032 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05033 05034 if (sync > 1) { 05035 if (channel) 05036 ast_channel_unlock(chan); 05037 if (ast_pbx_run(chan)) { 05038 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05039 if (channel) 05040 *channel = NULL; 05041 ast_hangup(chan); 05042 chan = NULL; 05043 res = -1; 05044 } 05045 } else { 05046 if (ast_pbx_start(chan)) { 05047 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05048 if (channel) { 05049 *channel = NULL; 05050 ast_channel_unlock(chan); 05051 } 05052 ast_hangup(chan); 05053 res = -1; 05054 } 05055 chan = NULL; 05056 } 05057 } else { 05058 if (option_verbose > 3) 05059 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05060 05061 if (chan->cdr) { /* update the cdr */ 05062 /* here we update the status of the call, which sould be busy. 05063 * if that fails then we set the status to failed */ 05064 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05065 ast_cdr_failed(chan->cdr); 05066 } 05067 05068 if (channel) { 05069 *channel = NULL; 05070 ast_channel_unlock(chan); 05071 } 05072 ast_hangup(chan); 05073 chan = NULL; 05074 } 05075 } 05076 05077 if (res < 0) { /* the call failed for some reason */ 05078 if (*reason == 0) { /* if the call failed (not busy or no answer) 05079 * update the cdr with the failed message */ 05080 cdr_res = ast_pbx_outgoing_cdr_failed(); 05081 if (cdr_res != 0) { 05082 res = cdr_res; 05083 goto outgoing_exten_cleanup; 05084 } 05085 } 05086 05087 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05088 /* check if "failed" exists */ 05089 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05090 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05091 if (chan) { 05092 char failed_reason[4] = ""; 05093 if (!ast_strlen_zero(context)) 05094 ast_copy_string(chan->context, context, sizeof(chan->context)); 05095 set_ext_pri(chan, "failed", 1); 05096 ast_set_variables(chan, vars); 05097 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 05098 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 05099 if (account) 05100 ast_cdr_setaccount(chan, account); 05101 if (ast_pbx_run(chan)) { 05102 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05103 ast_hangup(chan); 05104 } 05105 chan = NULL; 05106 } 05107 } 05108 } 05109 } else { 05110 if (!(as = ast_calloc(1, sizeof(*as)))) { 05111 res = -1; 05112 goto outgoing_exten_cleanup; 05113 } 05114 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05115 if (channel) { 05116 *channel = chan; 05117 if (chan) 05118 ast_channel_lock(chan); 05119 } 05120 if (!chan) { 05121 free(as); 05122 res = -1; 05123 goto outgoing_exten_cleanup; 05124 } 05125 as->chan = chan; 05126 ast_copy_string(as->context, context, sizeof(as->context)); 05127 set_ext_pri(as->chan, exten, priority); 05128 as->timeout = timeout; 05129 ast_set_variables(chan, vars); 05130 if (account) 05131 ast_cdr_setaccount(chan, account); 05132 pthread_attr_init(&attr); 05133 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05134 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05135 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05136 free(as); 05137 if (channel) { 05138 *channel = NULL; 05139 ast_channel_unlock(chan); 05140 } 05141 ast_hangup(chan); 05142 res = -1; 05143 pthread_attr_destroy(&attr); 05144 goto outgoing_exten_cleanup; 05145 } 05146 pthread_attr_destroy(&attr); 05147 res = 0; 05148 } 05149 outgoing_exten_cleanup: 05150 ast_variables_destroy(vars); 05151 return res; 05152 }
enum ast_pbx_result ast_pbx_run | ( | struct ast_channel * | c | ) |
Execute the PBX in the current thread.
c | channel to run the pbx on |
Definition at line 2680 of file pbx.c.
References __ast_pbx_run(), AST_PBX_CALL_LIMIT, AST_PBX_SUCCESS, decrease_call_count(), and increase_call_count().
Referenced by ast_pbx_outgoing_exten(), async_wait(), mgcp_ss(), skinny_newcall(), and ss_thread().
02681 { 02682 enum ast_pbx_result res = AST_PBX_SUCCESS; 02683 02684 if (increase_call_count(c)) 02685 return AST_PBX_CALL_LIMIT; 02686 02687 res = __ast_pbx_run(c); 02688 decrease_call_count(); 02689 02690 return res; 02691 }
enum ast_pbx_result ast_pbx_start | ( | struct ast_channel * | c | ) |
Create a new thread and start the PBX.
c | channel to start the pbx on |
Definition at line 2654 of file pbx.c.
References ast_log(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_pthread_create, 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().
02655 { 02656 pthread_t t; 02657 pthread_attr_t attr; 02658 02659 if (!c) { 02660 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02661 return AST_PBX_FAILED; 02662 } 02663 02664 if (increase_call_count(c)) 02665 return AST_PBX_CALL_LIMIT; 02666 02667 /* Start a new thread, and get something handling this channel. */ 02668 pthread_attr_init(&attr); 02669 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02670 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02671 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02672 pthread_attr_destroy(&attr); 02673 return AST_PBX_FAILED; 02674 } 02675 pthread_attr_destroy(&attr); 02676 02677 return AST_PBX_SUCCESS; 02678 }
int ast_rdlock_contexts | ( | void | ) |
Definition at line 6245 of file pbx.c.
References ast_rwlock_rdlock().
Referenced by __ast_context_create(), _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_hint_extension(), 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().
06246 { 06247 return ast_rwlock_rdlock(&conlock); 06248 }
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 2982 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, LOG_WARNING, option_verbose, ast_app::synopsis, term_color(), and VERBOSE_PREFIX_2.
Referenced by load_module(), and load_pbx().
02983 { 02984 struct ast_app *tmp, *cur = NULL; 02985 char tmps[80]; 02986 int length; 02987 02988 AST_LIST_LOCK(&apps); 02989 AST_LIST_TRAVERSE(&apps, tmp, list) { 02990 if (!strcasecmp(app, tmp->name)) { 02991 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02992 AST_LIST_UNLOCK(&apps); 02993 return -1; 02994 } 02995 } 02996 02997 length = sizeof(*tmp) + strlen(app) + 1; 02998 02999 if (!(tmp = ast_calloc(1, length))) { 03000 AST_LIST_UNLOCK(&apps); 03001 return -1; 03002 } 03003 03004 strcpy(tmp->name, app); 03005 tmp->execute = execute; 03006 tmp->synopsis = synopsis; 03007 tmp->description = description; 03008 03009 /* Store in alphabetical order */ 03010 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 03011 if (strcasecmp(tmp->name, cur->name) < 0) { 03012 AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 03013 break; 03014 } 03015 } 03016 AST_LIST_TRAVERSE_SAFE_END 03017 if (!cur) 03018 AST_LIST_INSERT_TAIL(&apps, tmp, list); 03019 03020 if (option_verbose > 1) 03021 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 03022 03023 AST_LIST_UNLOCK(&apps); 03024 03025 return 0; 03026 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 3032 of file pbx.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), LOG_WARNING, and ast_switch::name.
Referenced by load_module().
03033 { 03034 struct ast_switch *tmp; 03035 03036 AST_LIST_LOCK(&switches); 03037 AST_LIST_TRAVERSE(&switches, tmp, list) { 03038 if (!strcasecmp(tmp->name, sw->name)) { 03039 AST_LIST_UNLOCK(&switches); 03040 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 03041 return -1; 03042 } 03043 } 03044 AST_LIST_INSERT_TAIL(&switches, sw, list); 03045 AST_LIST_UNLOCK(&switches); 03046 03047 return 0; 03048 }
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 2340 of file pbx.c.
References E_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), _macro_exec(), and loopback_exec().
02341 { 02342 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN); 02343 }
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 6268 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().
06269 { 06270 return ast_mutex_unlock(&con->lock); 06271 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 6255 of file pbx.c.
References ast_rwlock_unlock().
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_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().
06256 { 06257 return ast_rwlock_unlock(&conlock); 06258 }
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 3863 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, option_verbose, and VERBOSE_PREFIX_2.
Referenced by __unload_module(), and unload_module().
03864 { 03865 struct ast_app *tmp; 03866 03867 AST_LIST_LOCK(&apps); 03868 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03869 if (!strcasecmp(app, tmp->name)) { 03870 AST_LIST_REMOVE_CURRENT(&apps, list); 03871 if (option_verbose > 1) 03872 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03873 free(tmp); 03874 break; 03875 } 03876 } 03877 AST_LIST_TRAVERSE_SAFE_END 03878 AST_LIST_UNLOCK(&apps); 03879 03880 return tmp ? 0 : -1; 03881 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 3050 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_REMOVE, and AST_LIST_UNLOCK.
Referenced by __unload_module(), and unload_module().
03051 { 03052 AST_LIST_LOCK(&switches); 03053 AST_LIST_REMOVE(&switches, sw, list); 03054 AST_LIST_UNLOCK(&switches); 03055 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | priority | |||
) |
Definition at line 6377 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().
06379 { 06380 if (!exten) 06381 return con ? con->root : NULL; 06382 else 06383 return exten->next; 06384 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 6410 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().
06412 { 06413 if (!ip) 06414 return con ? con->ignorepats : NULL; 06415 else 06416 return ip->next; 06417 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 6401 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().
06403 { 06404 if (!inc) 06405 return con ? con->includes : NULL; 06406 else 06407 return inc->next; 06408 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 6386 of file pbx.c.
References AST_LIST_FIRST, and AST_LIST_NEXT.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06388 { 06389 if (!sw) 06390 return con ? AST_LIST_FIRST(&con->alts) : NULL; 06391 else 06392 return AST_LIST_NEXT(sw, list); 06393 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 6372 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 6395 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 6250 of file pbx.c.
References ast_rwlock_wrlock().
Referenced by ast_context_destroy(), ast_merge_contexts_and_delete(), and complete_context_dont_include_deprecated().
06251 { 06252 return ast_rwlock_wrlock(&conlock); 06253 }
void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 6016 of file pbx.c.
References AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), and ast_var_delete().
Referenced by handle_reload_extensions(), and reload().
06017 { 06018 struct ast_var_t *vardata; 06019 06020 ast_mutex_lock(&globalslock); 06021 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06022 ast_var_delete(vardata); 06023 ast_mutex_unlock(&globalslock); 06024 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5793 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), and ast_var_value().
Referenced by __login_exec(), _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), ast_bridge_call(), ast_channel_bridge(), ast_feature_interpret(), ast_monitor_stop(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dahdi_call(), dahdi_hangup(), dundi_exec(), dundi_helper(), get_also_info(), get_index(), get_refer_info(), global_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_call_full(), 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_calling(), try_suggested_sip_codec(), and wait_for_answer().
05794 { 05795 struct ast_var_t *variables; 05796 const char *ret = NULL; 05797 int i; 05798 struct varshead *places[2] = { NULL, &globals }; 05799 05800 if (!name) 05801 return NULL; 05802 05803 if (chan) { 05804 ast_channel_lock(chan); 05805 places[0] = &chan->varshead; 05806 } 05807 05808 for (i = 0; i < 2; i++) { 05809 if (!places[i]) 05810 continue; 05811 if (places[i] == &globals) 05812 ast_mutex_lock(&globalslock); 05813 AST_LIST_TRAVERSE(places[i], variables, entries) { 05814 if (!strcmp(name, ast_var_name(variables))) { 05815 ret = ast_var_value(variables); 05816 break; 05817 } 05818 } 05819 if (places[i] == &globals) 05820 ast_mutex_unlock(&globalslock); 05821 if (ret) 05822 break; 05823 } 05824 05825 if (chan) 05826 ast_channel_unlock(chan); 05827 05828 return ret; 05829 }
void pbx_builtin_pushvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5831 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(), LOG_WARNING, option_verbose, and VERBOSE_PREFIX_2.
Referenced by acf_odbc_read(), acf_odbc_write(), and gosub_exec().
05832 { 05833 struct ast_var_t *newvariable; 05834 struct varshead *headp; 05835 05836 if (name[strlen(name)-1] == ')') { 05837 char *function = ast_strdupa(name); 05838 05839 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05840 ast_func_write(chan, function, value); 05841 return; 05842 } 05843 05844 if (chan) { 05845 ast_channel_lock(chan); 05846 headp = &chan->varshead; 05847 } else { 05848 ast_mutex_lock(&globalslock); 05849 headp = &globals; 05850 } 05851 05852 if (value) { 05853 if ((option_verbose > 1) && (headp == &globals)) 05854 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05855 newvariable = ast_var_assign(name, value); 05856 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05857 } 05858 05859 if (chan) 05860 ast_channel_unlock(chan); 05861 else 05862 ast_mutex_unlock(&globalslock); 05863 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5762 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(), LOG_ERROR, total, var, and ast_channel::varshead.
Referenced by dumpchan_exec(), handle_showchan(), handle_showchan_deprecated(), and vars2manager().
05763 { 05764 struct ast_var_t *variables; 05765 const char *var, *val; 05766 int total = 0; 05767 05768 if (!chan) 05769 return 0; 05770 05771 memset(buf, 0, size); 05772 05773 ast_channel_lock(chan); 05774 05775 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05776 if ((var=ast_var_name(variables)) && (val=ast_var_value(variables)) 05777 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 05778 ) { 05779 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05780 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05781 break; 05782 } else 05783 total++; 05784 } else 05785 break; 05786 } 05787 05788 ast_channel_unlock(chan); 05789 05790 return total; 05791 }
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 5865 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(), 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(), app_exec(), aqm_exec(), array(), ast_bridge_call(), ast_channel_bridge(), 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(), 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(), 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(), try_calling(), tryexec_exec(), upqm_exec(), vm_box_exists(), vm_exec(), and vmauthenticate().
05866 { 05867 struct ast_var_t *newvariable; 05868 struct varshead *headp; 05869 const char *nametail = name; 05870 05871 if (name[strlen(name)-1] == ')') { 05872 char *function = ast_strdupa(name); 05873 05874 ast_func_write(chan, function, value); 05875 return; 05876 } 05877 05878 if (chan) { 05879 ast_channel_lock(chan); 05880 headp = &chan->varshead; 05881 } else { 05882 ast_mutex_lock(&globalslock); 05883 headp = &globals; 05884 } 05885 05886 /* For comparison purposes, we have to strip leading underscores */ 05887 if (*nametail == '_') { 05888 nametail++; 05889 if (*nametail == '_') 05890 nametail++; 05891 } 05892 05893 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05894 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 05895 /* there is already such a variable, delete it */ 05896 AST_LIST_REMOVE(headp, newvariable, entries); 05897 ast_var_delete(newvariable); 05898 break; 05899 } 05900 } 05901 05902 if (value) { 05903 if ((option_verbose > 1) && (headp == &globals)) 05904 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05905 newvariable = ast_var_assign(name, value); 05906 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05907 } 05908 05909 if (chan) 05910 ast_channel_unlock(chan); 05911 else 05912 ast_mutex_unlock(&globalslock); 05913 }
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 6026 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().
06027 { 06028 if (ast_strlen_zero(condition)) /* NULL or empty strings are false */ 06029 return 0; 06030 else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */ 06031 return atoi(condition); 06032 else /* Strings are true */ 06033 return 1; 06034 }
int pbx_exec | ( | struct ast_channel * | c, | |
struct ast_app * | app, | |||
void * | data | |||
) |
Execute an application.
c | channel to execute on | |
app | which app to execute | |
data | the data passed into the app |
c | Channel |
app | Application |
data | Data for execution |
Definition at line 537 of file pbx.c.
References app, ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_channel::cdr, ast_channel::data, and S_OR.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), milliwatt_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), 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, and AST_LIST_UNLOCK.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), milliwatt_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), 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 1173 of file pbx.c.
References ast_cause2str(), ast_channel_lock, ast_channel_unlock, ast_config_AST_SYSTEM_NAME, 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, ast_channel::hangupcause, offset, parse_variable_name(), ast_channel::priority, s, and substring().
Referenced by action_getvar(), handle_getvariable(), and pbx_substitute_variables_helper_full().
01174 { 01175 const char not_found = '\0'; 01176 char *tmpvar; 01177 const char *s; /* the result */ 01178 int offset, length; 01179 int i, need_substring; 01180 struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */ 01181 01182 if (c) { 01183 ast_channel_lock(c); 01184 places[0] = &c->varshead; 01185 } 01186 /* 01187 * Make a copy of var because parse_variable_name() modifies the string. 01188 * Then if called directly, we might need to run substring() on the result; 01189 * remember this for later in 'need_substring', 'offset' and 'length' 01190 */ 01191 tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */ 01192 need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */); 01193 01194 /* 01195 * Look first into predefined variables, then into variable lists. 01196 * Variable 's' points to the result, according to the following rules: 01197 * s == ¬_found (set at the beginning) means that we did not find a 01198 * matching variable and need to look into more places. 01199 * If s != ¬_found, s is a valid result string as follows: 01200 * s = NULL if the variable does not have a value; 01201 * you typically do this when looking for an unset predefined variable. 01202 * s = workspace if the result has been assembled there; 01203 * typically done when the result is built e.g. with an snprintf(), 01204 * so we don't need to do an additional copy. 01205 * s != workspace in case we have a string, that needs to be copied 01206 * (the ast_copy_string is done once for all at the end). 01207 * Typically done when the result is already available in some string. 01208 */ 01209 s = ¬_found; /* default value */ 01210 if (c) { /* This group requires a valid channel */ 01211 /* Names with common parts are looked up a piece at a time using strncmp. */ 01212 if (!strncmp(var, "CALL", 4)) { 01213 if (!strncmp(var + 4, "ING", 3)) { 01214 if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */ 01215 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 01216 s = workspace; 01217 } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */ 01218 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 01219 s = workspace; 01220 } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */ 01221 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 01222 s = workspace; 01223 } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */ 01224 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 01225 s = workspace; 01226 } 01227 } 01228 } else if (!strcmp(var, "HINT")) { 01229 s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL; 01230 } else if (!strcmp(var, "HINTNAME")) { 01231 s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL; 01232 } else if (!strcmp(var, "EXTEN")) { 01233 s = c->exten; 01234 } else if (!strcmp(var, "CONTEXT")) { 01235 s = c->context; 01236 } else if (!strcmp(var, "PRIORITY")) { 01237 snprintf(workspace, workspacelen, "%d", c->priority); 01238 s = workspace; 01239 } else if (!strcmp(var, "CHANNEL")) { 01240 s = c->name; 01241 } else if (!strcmp(var, "UNIQUEID")) { 01242 s = c->uniqueid; 01243 } else if (!strcmp(var, "HANGUPCAUSE")) { 01244 snprintf(workspace, workspacelen, "%d", c->hangupcause); 01245 s = workspace; 01246 } else if (c && !strcmp(var, "HANGUPCAUSESTR")) { 01247 ast_copy_string(workspace, ast_cause2str(c->hangupcause), workspacelen); 01248 *ret = workspace; 01249 } 01250 } 01251 if (s == ¬_found) { /* look for more */ 01252 if (!strcmp(var, "EPOCH")) { 01253 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 01254 s = workspace; 01255 } else if (!strcmp(var, "SYSTEMNAME")) { 01256 s = ast_config_AST_SYSTEM_NAME; 01257 } 01258 } 01259 /* if not found, look into chanvars or global vars */ 01260 for (i = 0; s == ¬_found && i < (sizeof(places) / sizeof(places[0])); i++) { 01261 struct ast_var_t *variables; 01262 if (!places[i]) 01263 continue; 01264 if (places[i] == &globals) 01265 ast_mutex_lock(&globalslock); 01266 AST_LIST_TRAVERSE(places[i], variables, entries) { 01267 if (strcasecmp(ast_var_name(variables), var)==0) { 01268 s = ast_var_value(variables); 01269 break; 01270 } 01271 } 01272 if (places[i] == &globals) 01273 ast_mutex_unlock(&globalslock); 01274 } 01275 if (s == ¬_found || s == NULL) 01276 *ret = NULL; 01277 else { 01278 if (s != workspace) 01279 ast_copy_string(workspace, s, workspacelen); 01280 *ret = workspace; 01281 if (need_substring) 01282 *ret = substring(*ret, offset, length, workspace, workspacelen); 01283 } 01284 01285 if (c) 01286 ast_channel_unlock(c); 01287 }
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 2698 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
02699 { 02700 int oldval = autofallthrough; 02701 autofallthrough = newval; 02702 return oldval; 02703 }
void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1792 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(), try_calling(), and tryexec_exec().
01793 { 01794 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 01795 }
void pbx_substitute_variables_varshead | ( | struct varshead * | headp, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1797 of file pbx.c.
References pbx_substitute_variables_helper_full().
Referenced by ast_add_extension2(), dundi_lookup_local(), and loopback_subst().
01798 { 01799 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 01800 }