#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_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 2708 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02709 { 02710 return countcalls; 02711 }
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 4585 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().
04588 { 04589 int ret = -1; 04590 struct ast_context *c = find_context_locked(context); 04591 04592 if (c) { 04593 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04594 application, data, datad, registrar); 04595 ast_unlock_contexts(); 04596 } 04597 return ret; 04598 }
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 4794 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().
04798 { 04799 /* 04800 * Sort extensions (or patterns) according to the rules indicated above. 04801 * These are implemented by the function ext_cmp()). 04802 * All priorities for the same ext/pattern/cid are kept in a list, 04803 * using the 'peer' field as a link field.. 04804 */ 04805 struct ast_exten *tmp, *e, *el = NULL; 04806 int res; 04807 int length; 04808 char *p; 04809 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04810 04811 /* if we are adding a hint, and there are global variables, and the hint 04812 contains variable references, then expand them 04813 */ 04814 ast_mutex_lock(&globalslock); 04815 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04816 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04817 application = expand_buf; 04818 } 04819 ast_mutex_unlock(&globalslock); 04820 04821 length = sizeof(struct ast_exten); 04822 length += strlen(extension) + 1; 04823 length += strlen(application) + 1; 04824 if (label) 04825 length += strlen(label) + 1; 04826 if (callerid) 04827 length += strlen(callerid) + 1; 04828 else 04829 length ++; /* just the '\0' */ 04830 04831 /* Be optimistic: Build the extension structure first */ 04832 if (!(tmp = ast_calloc(1, length))) 04833 return -1; 04834 04835 /* use p as dst in assignments, as the fields are const char * */ 04836 p = tmp->stuff; 04837 if (label) { 04838 tmp->label = p; 04839 strcpy(p, label); 04840 p += strlen(label) + 1; 04841 } 04842 tmp->exten = p; 04843 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04844 tmp->priority = priority; 04845 tmp->cidmatch = p; /* but use p for assignments below */ 04846 if (callerid) { 04847 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04848 tmp->matchcid = 1; 04849 } else { 04850 *p++ = '\0'; 04851 tmp->matchcid = 0; 04852 } 04853 tmp->app = p; 04854 strcpy(p, application); 04855 tmp->parent = con; 04856 tmp->data = data; 04857 tmp->datad = datad; 04858 tmp->registrar = registrar; 04859 04860 ast_mutex_lock(&con->lock); 04861 res = 0; /* some compilers will think it is uninitialized otherwise */ 04862 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04863 res = ext_cmp(e->exten, extension); 04864 if (res == 0) { /* extension match, now look at cidmatch */ 04865 if (!e->matchcid && !tmp->matchcid) 04866 res = 0; 04867 else if (tmp->matchcid && !e->matchcid) 04868 res = 1; 04869 else if (e->matchcid && !tmp->matchcid) 04870 res = -1; 04871 else 04872 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04873 } 04874 if (res >= 0) 04875 break; 04876 } 04877 if (e && res == 0) { /* exact match, insert in the pri chain */ 04878 res = add_pri(con, tmp, el, e, replace); 04879 ast_mutex_unlock(&con->lock); 04880 if (res < 0) { 04881 errno = EEXIST; /* XXX do we care ? */ 04882 return 0; /* XXX should we return -1 maybe ? */ 04883 } 04884 } else { 04885 /* 04886 * not an exact match, this is the first entry with this pattern, 04887 * so insert in the main list right before 'e' (if any) 04888 */ 04889 tmp->next = e; 04890 if (el) 04891 el->next = tmp; 04892 else 04893 con->root = tmp; 04894 ast_mutex_unlock(&con->lock); 04895 if (tmp->priority == PRIORITY_HINT) 04896 ast_add_hint(tmp); 04897 } 04898 if (option_debug) { 04899 if (tmp->matchcid) { 04900 if (option_debug) 04901 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04902 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04903 } else { 04904 if (option_debug) 04905 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04906 tmp->exten, tmp->priority, con->name); 04907 } 04908 } 04909 if (option_verbose > 2) { 04910 if (tmp->matchcid) { 04911 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04912 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04913 } else { 04914 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04915 tmp->exten, tmp->priority, con->name); 04916 } 04917 } 04918 return 0; 04919 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4623 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(), handle_request_bye(), handle_request_refer(), process_ast_dsp(), socket_process(), and zt_handle_dtmfup().
04624 { 04625 int res = 0; 04626 04627 ast_channel_lock(chan); 04628 04629 if (chan->pbx) { /* This channel is currently in the PBX */ 04630 ast_explicit_goto(chan, context, exten, priority); 04631 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04632 } else { 04633 /* In order to do it when the channel doesn't really exist within 04634 the PBX, we have to make a new channel, masquerade, and start the PBX 04635 at the new location */ 04636 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04637 if (!tmpchan) { 04638 res = -1; 04639 } else { 04640 if (chan->cdr) { 04641 ast_cdr_discard(tmpchan->cdr); 04642 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 04643 } 04644 /* Make formats okay */ 04645 tmpchan->readformat = chan->readformat; 04646 tmpchan->writeformat = chan->writeformat; 04647 /* Setup proper location */ 04648 ast_explicit_goto(tmpchan, 04649 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04650 04651 /* Masquerade into temp channel */ 04652 ast_channel_masquerade(tmpchan, chan); 04653 04654 /* Grab the locks and get going */ 04655 ast_channel_lock(tmpchan); 04656 ast_do_masquerade(tmpchan); 04657 ast_channel_unlock(tmpchan); 04658 /* Start the PBX going on our stolen channel */ 04659 if (ast_pbx_start(tmpchan)) { 04660 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04661 ast_hangup(tmpchan); 04662 res = -1; 04663 } 04664 } 04665 } 04666 ast_channel_unlock(chan); 04667 return res; 04668 }
int ast_async_goto_by_name | ( | const char * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4670 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04671 { 04672 struct ast_channel *chan; 04673 int res = -1; 04674 04675 chan = ast_get_channel_by_name_locked(channame); 04676 if (chan) { 04677 res = ast_async_goto(chan, context, exten, priority); 04678 ast_channel_unlock(chan); 04679 } 04680 return res; 04681 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6482 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06483 { 06484 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06485 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info | |||
) |
Definition at line 4268 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().
04269 { 04270 char info_save[256]; 04271 char *info; 04272 04273 /* Check for empty just in case */ 04274 if (ast_strlen_zero(info_in)) 04275 return 0; 04276 /* make a copy just in case we were passed a static string */ 04277 ast_copy_string(info_save, info_in, sizeof(info_save)); 04278 info = info_save; 04279 /* Assume everything except time */ 04280 i->monthmask = 0xfff; /* 12 bits */ 04281 i->daymask = 0x7fffffffU; /* 31 bits */ 04282 i->dowmask = 0x7f; /* 7 bits */ 04283 /* on each call, use strsep() to move info to the next argument */ 04284 get_timerange(i, strsep(&info, "|")); 04285 if (info) 04286 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04287 if (info) 04288 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04289 if (info) 04290 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04291 return 1; 04292 }
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 4294 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().
04295 { 04296 struct tm tm; 04297 time_t t = time(NULL); 04298 04299 ast_localtime(&t, &tm, NULL); 04300 04301 /* If it's not the right month, return */ 04302 if (!(i->monthmask & (1 << tm.tm_mon))) 04303 return 0; 04304 04305 /* If it's not that time of the month.... */ 04306 /* Warning, tm_mday has range 1..31! */ 04307 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04308 return 0; 04309 04310 /* If it's not the right day of the week */ 04311 if (!(i->dowmask & (1 << tm.tm_wday))) 04312 return 0; 04313 04314 /* Sanity check the hour just to be safe */ 04315 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04316 ast_log(LOG_WARNING, "Insane time...\n"); 04317 return 0; 04318 } 04319 04320 /* Now the tough part, we calculate if it fits 04321 in the right time based on min/hour */ 04322 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04323 return 0; 04324 04325 /* If we got this far, then we're good */ 04326 return 1; 04327 }
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 4521 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().
04522 { 04523 int ret = -1; 04524 struct ast_context *c = find_context_locked(context); 04525 04526 if (c) { 04527 ret = ast_context_add_ignorepat2(c, value, registrar); 04528 ast_unlock_contexts(); 04529 } 04530 return ret; 04531 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4533 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().
04534 { 04535 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04536 int length; 04537 length = sizeof(struct ast_ignorepat); 04538 length += strlen(value) + 1; 04539 if (!(ignorepat = ast_calloc(1, length))) 04540 return -1; 04541 /* The cast to char * is because we need to write the initial value. 04542 * The field is not supposed to be modified otherwise 04543 */ 04544 strcpy((char *)ignorepat->pattern, value); 04545 ignorepat->next = NULL; 04546 ignorepat->registrar = registrar; 04547 ast_mutex_lock(&con->lock); 04548 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04549 ignorepatl = ignorepatc; 04550 if (!strcasecmp(ignorepatc->pattern, value)) { 04551 /* Already there */ 04552 ast_mutex_unlock(&con->lock); 04553 errno = EEXIST; 04554 return -1; 04555 } 04556 } 04557 if (ignorepatl) 04558 ignorepatl->next = ignorepat; 04559 else 04560 con->ignorepats = ignorepat; 04561 ast_mutex_unlock(&con->lock); 04562 return 0; 04563 04564 }
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 4074 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().
04075 { 04076 int ret = -1; 04077 struct ast_context *c = find_context_locked(context); 04078 04079 if (c) { 04080 ret = ast_context_add_include2(c, include, registrar); 04081 ast_unlock_contexts(); 04082 } 04083 return ret; 04084 }
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 4336 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().
04338 { 04339 struct ast_include *new_include; 04340 char *c; 04341 struct ast_include *i, *il = NULL; /* include, include_last */ 04342 int length; 04343 char *p; 04344 04345 length = sizeof(struct ast_include); 04346 length += 2 * (strlen(value) + 1); 04347 04348 /* allocate new include structure ... */ 04349 if (!(new_include = ast_calloc(1, length))) 04350 return -1; 04351 /* Fill in this structure. Use 'p' for assignments, as the fields 04352 * in the structure are 'const char *' 04353 */ 04354 p = new_include->stuff; 04355 new_include->name = p; 04356 strcpy(p, value); 04357 p += strlen(value) + 1; 04358 new_include->rname = p; 04359 strcpy(p, value); 04360 /* Strip off timing info, and process if it is there */ 04361 if ( (c = strchr(p, '|')) ) { 04362 *c++ = '\0'; 04363 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04364 } 04365 new_include->next = NULL; 04366 new_include->registrar = registrar; 04367 04368 ast_mutex_lock(&con->lock); 04369 04370 /* ... go to last include and check if context is already included too... */ 04371 for (i = con->includes; i; i = i->next) { 04372 if (!strcasecmp(i->name, new_include->name)) { 04373 free(new_include); 04374 ast_mutex_unlock(&con->lock); 04375 errno = EEXIST; 04376 return -1; 04377 } 04378 il = i; 04379 } 04380 04381 /* ... include new context into context list, unlock, return */ 04382 if (il) 04383 il->next = new_include; 04384 else 04385 con->includes = new_include; 04386 if (option_verbose > 2) 04387 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04388 ast_mutex_unlock(&con->lock); 04389 04390 return 0; 04391 }
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 4398 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04399 { 04400 int ret = -1; 04401 struct ast_context *c = find_context_locked(context); 04402 04403 if (c) { /* found, add switch to this context */ 04404 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04405 ast_unlock_contexts(); 04406 } 04407 return ret; 04408 }
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 4417 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().
04419 { 04420 struct ast_sw *new_sw; 04421 struct ast_sw *i; 04422 int length; 04423 char *p; 04424 04425 length = sizeof(struct ast_sw); 04426 length += strlen(value) + 1; 04427 if (data) 04428 length += strlen(data); 04429 length++; 04430 04431 /* allocate new sw structure ... */ 04432 if (!(new_sw = ast_calloc(1, length))) 04433 return -1; 04434 /* ... fill in this structure ... */ 04435 p = new_sw->stuff; 04436 new_sw->name = p; 04437 strcpy(new_sw->name, value); 04438 p += strlen(value) + 1; 04439 new_sw->data = p; 04440 if (data) { 04441 strcpy(new_sw->data, data); 04442 p += strlen(data) + 1; 04443 } else { 04444 strcpy(new_sw->data, ""); 04445 p++; 04446 } 04447 new_sw->eval = eval; 04448 new_sw->registrar = registrar; 04449 04450 /* ... try to lock this context ... */ 04451 ast_mutex_lock(&con->lock); 04452 04453 /* ... go to last sw and check if context is already swd too... */ 04454 AST_LIST_TRAVERSE(&con->alts, i, list) { 04455 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04456 free(new_sw); 04457 ast_mutex_unlock(&con->lock); 04458 errno = EEXIST; 04459 return -1; 04460 } 04461 } 04462 04463 /* ... sw new context into context list, unlock, return */ 04464 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04465 04466 if (option_verbose > 2) 04467 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04468 04469 ast_mutex_unlock(&con->lock); 04470 04471 return 0; 04472 }
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 3944 of file pbx.c.
References __ast_context_create().
Referenced by do_parking_thread(), park_call_full(), and set_config().
03945 { 03946 return __ast_context_create(extcontexts, name, registrar, 0); 03947 }
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 5386 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().
05387 { 05388 ast_wrlock_contexts(); 05389 __ast_context_destroy(con,registrar); 05390 ast_unlock_contexts(); 05391 }
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 3949 of file pbx.c.
References __ast_context_create().
Referenced by pbx_load_config(), and pbx_load_users().
03950 { 03951 return __ast_context_create(extcontexts, name, registrar, 1); 03952 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 2945 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().
02946 { 02947 struct ast_context *c = NULL; 02948 int ret = -1; 02949 02950 ast_rdlock_contexts(); 02951 02952 while ((c = ast_walk_contexts(c))) { 02953 if (!strcmp(ast_get_context_name(c), context)) { 02954 ret = 0; 02955 break; 02956 } 02957 } 02958 02959 ast_unlock_contexts(); 02960 02961 /* if we found context, lock macrolock */ 02962 if (ret == 0) 02963 ret = ast_mutex_lock(&c->macrolock); 02964 02965 return ret; 02966 }
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 | |
registrar | registrar of the extension |
0 | on success | |
-1 | on failure |
Definition at line 2846 of file pbx.c.
References ast_context_remove_extension2(), ast_unlock_contexts(), and find_context_locked().
Referenced by destroy_station(), destroy_trunk(), handle_context_remove_extension(), handle_context_remove_extension_deprecated(), and register_peer_exten().
02847 { 02848 int ret = -1; /* default error return */ 02849 struct ast_context *c = find_context_locked(context); 02850 02851 if (c) { /* ... remove extension ... */ 02852 ret = ast_context_remove_extension2(c, extension, priority, registrar); 02853 ast_unlock_contexts(); 02854 } 02855 return ret; 02856 }
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 2868 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), destroy_exten(), exten, ast_context::lock, ast_exten::next, ast_exten::peer, and ast_context::root.
Referenced by ast_context_remove_extension(), do_parking_thread(), and park_exec().
02869 { 02870 struct ast_exten *exten, *prev_exten = NULL; 02871 struct ast_exten *peer; 02872 02873 ast_mutex_lock(&con->lock); 02874 02875 /* scan the extension list to find matching extension-registrar */ 02876 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02877 if (!strcmp(exten->exten, extension) && 02878 (!registrar || !strcmp(exten->registrar, registrar))) 02879 break; 02880 } 02881 if (!exten) { 02882 /* we can't find right extension */ 02883 ast_mutex_unlock(&con->lock); 02884 return -1; 02885 } 02886 02887 /* should we free all peers in this extension? (priority == 0)? */ 02888 if (priority == 0) { 02889 /* remove this extension from context list */ 02890 if (prev_exten) 02891 prev_exten->next = exten->next; 02892 else 02893 con->root = exten->next; 02894 02895 /* fire out all peers */ 02896 while ( (peer = exten) ) { 02897 exten = peer->peer; /* prepare for next entry */ 02898 destroy_exten(peer); 02899 } 02900 } else { 02901 /* scan the priority list to remove extension with exten->priority == priority */ 02902 struct ast_exten *previous_peer = NULL; 02903 02904 for (peer = exten; peer; previous_peer = peer, peer = peer->peer) { 02905 if (peer->priority == priority && 02906 (!registrar || !strcmp(peer->registrar, registrar) )) 02907 break; /* found our priority */ 02908 } 02909 if (!peer) { /* not found */ 02910 ast_mutex_unlock(&con->lock); 02911 return -1; 02912 } 02913 /* we are first priority extension? */ 02914 if (!previous_peer) { 02915 /* 02916 * We are first in the priority chain, so must update the extension chain. 02917 * The next node is either the next priority or the next extension 02918 */ 02919 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02920 02921 if (!prev_exten) /* change the root... */ 02922 con->root = next_node; 02923 else 02924 prev_exten->next = next_node; /* unlink */ 02925 if (peer->peer) /* XXX update the new head of the pri list */ 02926 peer->peer->next = peer->next; 02927 } else { /* easy, we are not first priority in extension */ 02928 previous_peer->peer = peer->peer; 02929 } 02930 02931 /* now, free whole priority extension */ 02932 destroy_exten(peer); 02933 /* XXX should we return -1 ? */ 02934 } 02935 ast_mutex_unlock(&con->lock); 02936 return 0; 02937 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4478 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().
04479 { 04480 int ret = -1; 04481 struct ast_context *c = find_context_locked(context); 04482 04483 if (c) { 04484 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04485 ast_unlock_contexts(); 04486 } 04487 return ret; 04488 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4490 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().
04491 { 04492 struct ast_ignorepat *ip, *ipl = NULL; 04493 04494 ast_mutex_lock(&con->lock); 04495 04496 for (ip = con->ignorepats; ip; ip = ip->next) { 04497 if (!strcmp(ip->pattern, ignorepat) && 04498 (!registrar || (registrar == ip->registrar))) { 04499 if (ipl) { 04500 ipl->next = ip->next; 04501 free(ip); 04502 } else { 04503 con->ignorepats = ip->next; 04504 free(ip); 04505 } 04506 ast_mutex_unlock(&con->lock); 04507 return 0; 04508 } 04509 ipl = ip; 04510 } 04511 04512 ast_mutex_unlock(&con->lock); 04513 errno = EINVAL; 04514 return -1; 04515 }
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 2742 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().
02743 { 02744 int ret = -1; 02745 struct ast_context *c = find_context_locked(context); 02746 02747 if (c) { 02748 /* found, remove include from this context ... */ 02749 ret = ast_context_remove_include2(c, include, registrar); 02750 ast_unlock_contexts(); 02751 } 02752 return ret; 02753 }
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 2763 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().
02764 { 02765 struct ast_include *i, *pi = NULL; 02766 int ret = -1; 02767 02768 ast_mutex_lock(&con->lock); 02769 02770 /* find our include */ 02771 for (i = con->includes; i; pi = i, i = i->next) { 02772 if (!strcmp(i->name, include) && 02773 (!registrar || !strcmp(i->registrar, registrar))) { 02774 /* remove from list */ 02775 if (pi) 02776 pi->next = i->next; 02777 else 02778 con->includes = i->next; 02779 /* free include and return */ 02780 free(i); 02781 ret = 0; 02782 break; 02783 } 02784 } 02785 02786 ast_mutex_unlock(&con->lock); 02787 return ret; 02788 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 2795 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
02796 { 02797 int ret = -1; /* default error return */ 02798 struct ast_context *c = find_context_locked(context); 02799 02800 if (c) { 02801 /* remove switch from this context ... */ 02802 ret = ast_context_remove_switch2(c, sw, data, registrar); 02803 ast_unlock_contexts(); 02804 } 02805 return ret; 02806 }
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 2816 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().
02817 { 02818 struct ast_sw *i; 02819 int ret = -1; 02820 02821 ast_mutex_lock(&con->lock); 02822 02823 /* walk switches */ 02824 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02825 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02826 (!registrar || !strcmp(i->registrar, registrar))) { 02827 /* found, remove from list */ 02828 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02829 free(i); /* free switch and return */ 02830 ret = 0; 02831 break; 02832 } 02833 } 02834 AST_LIST_TRAVERSE_SAFE_END 02835 02836 ast_mutex_unlock(&con->lock); 02837 02838 return ret; 02839 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 2973 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().
02974 { 02975 struct ast_context *c = NULL; 02976 int ret = -1; 02977 02978 ast_rdlock_contexts(); 02979 02980 while ((c = ast_walk_contexts(c))) { 02981 if (!strcmp(ast_get_context_name(c), context)) { 02982 ret = 0; 02983 break; 02984 } 02985 } 02986 02987 ast_unlock_contexts(); 02988 02989 /* if we found context, unlock macrolock */ 02990 if (ret == 0) 02991 ret = ast_mutex_unlock(&c->macrolock); 02992 02993 return ret; 02994 }
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 6439 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().
06440 { 06441 struct ast_include *inc = NULL; 06442 int res = 0; 06443 06444 while ( (inc = ast_walk_context_includes(con, inc)) ) { 06445 if (ast_context_find(inc->rname)) 06446 continue; 06447 06448 res = -1; 06449 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 06450 ast_get_context_name(con), inc->rname); 06451 break; 06452 } 06453 06454 return res; 06455 }
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(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), 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(), waitstream_core(), and zt_handle_dtmfup().
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 4600 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().
04601 { 04602 if (!chan) 04603 return -1; 04604 04605 ast_channel_lock(chan); 04606 04607 if (!ast_strlen_zero(context)) 04608 ast_copy_string(chan->context, context, sizeof(chan->context)); 04609 if (!ast_strlen_zero(exten)) 04610 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04611 if (priority > -1) { 04612 chan->priority = priority; 04613 /* see flag description in channel.h for explanation */ 04614 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04615 chan->priority--; 04616 } 04617 04618 ast_channel_unlock(chan); 04619 04620 return 0; 04621 }
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 6296 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 6334 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06335 { 06336 return c ? c->registrar : NULL; 06337 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6364 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().
06365 { 06366 return e ? e->app : NULL; 06367 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6369 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06370 { 06371 return e ? e->data : NULL; 06372 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6359 of file pbx.c.
References ast_exten::cidmatch.
Referenced by find_matching_priority(), and handle_save_dialplan().
06360 { 06361 return e ? e->cidmatch : NULL; 06362 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
const char* ast_get_extension_label | ( | struct ast_exten * | e | ) |
Definition at line 6311 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 6354 of file pbx.c.
References ast_exten::matchcid.
Referenced by find_matching_priority(), and handle_save_dialplan().
06355 { 06356 return e ? e->matchcid : 0; 06357 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6306 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 6326 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 6339 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06340 { 06341 return e ? e->registrar : NULL; 06342 }
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 6321 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().
06322 { 06323 return ip ? ip->pattern : NULL; 06324 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6349 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06350 { 06351 return ip ? ip->registrar : NULL; 06352 }
const char* ast_get_include_name | ( | struct ast_include * | include | ) |
Definition at line 6316 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 6344 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06345 { 06346 return i ? i->registrar : NULL; 06347 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6379 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06380 { 06381 return sw ? sw->data : NULL; 06382 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6374 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06375 { 06376 return sw ? sw->name : NULL; 06377 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6384 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06385 { 06386 return sw ? sw->registrar : NULL; 06387 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6477 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().
06478 { 06479 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06480 }
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 4566 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().
04567 { 04568 struct ast_context *con = ast_context_find(context); 04569 if (con) { 04570 struct ast_ignorepat *pat; 04571 for (pat = con->ignorepats; pat; pat = pat->next) { 04572 if (ast_extension_match(pat->pattern, pattern)) 04573 return 1; 04574 } 04575 } 04576 04577 return 0; 04578 }
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 6283 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().
06284 { 06285 return ast_mutex_lock(&con->lock); 06286 }
int ast_lock_contexts | ( | void | ) |
Locks the context list.
0 | on success | |
-1 | on error |
Definition at line 6260 of file pbx.c.
References ast_rwlock_wrlock().
Referenced by find_matching_endwhile().
06261 { 06262 return ast_rwlock_wrlock(&conlock); 06263 }
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 3967 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().
03968 { 03969 struct ast_context *tmp, *lasttmp = NULL; 03970 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 03971 struct store_hint *this; 03972 struct ast_hint *hint; 03973 struct ast_exten *exten; 03974 int length; 03975 struct ast_state_cb *thiscb, *prevcb; 03976 03977 /* it is very important that this function hold the hint list lock _and_ the conlock 03978 during its operation; not only do we need to ensure that the list of contexts 03979 and extensions does not change, but also that no hint callbacks (watchers) are 03980 added or removed during the merge/delete process 03981 03982 in addition, the locks _must_ be taken in this order, because there are already 03983 other code paths that use this order 03984 */ 03985 ast_wrlock_contexts(); 03986 AST_LIST_LOCK(&hints); 03987 03988 /* preserve all watchers for hints associated with this registrar */ 03989 AST_LIST_TRAVERSE(&hints, hint, list) { 03990 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03991 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03992 if (!(this = ast_calloc(1, length))) 03993 continue; 03994 this->callbacks = hint->callbacks; 03995 hint->callbacks = NULL; 03996 this->laststate = hint->laststate; 03997 this->context = this->data; 03998 strcpy(this->data, hint->exten->parent->name); 03999 this->exten = this->data + strlen(this->context) + 1; 04000 strcpy(this->exten, hint->exten->exten); 04001 AST_LIST_INSERT_HEAD(&store, this, list); 04002 } 04003 } 04004 04005 tmp = *extcontexts; 04006 if (registrar) { 04007 /* XXX remove previous contexts from same registrar */ 04008 if (option_debug) 04009 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 04010 __ast_context_destroy(NULL,registrar); 04011 while (tmp) { 04012 lasttmp = tmp; 04013 tmp = tmp->next; 04014 } 04015 } else { 04016 /* XXX remove contexts with the same name */ 04017 while (tmp) { 04018 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 04019 __ast_context_destroy(tmp,tmp->registrar); 04020 lasttmp = tmp; 04021 tmp = tmp->next; 04022 } 04023 } 04024 if (lasttmp) { 04025 lasttmp->next = contexts; 04026 contexts = *extcontexts; 04027 *extcontexts = NULL; 04028 } else 04029 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 04030 04031 /* restore the watchers for hints that can be found; notify those that 04032 cannot be restored 04033 */ 04034 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 04035 struct pbx_find_info q = { .stacklen = 0 }; 04036 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 04037 /* Find the hint in the list of hints */ 04038 AST_LIST_TRAVERSE(&hints, hint, list) { 04039 if (hint->exten == exten) 04040 break; 04041 } 04042 if (!exten || !hint) { 04043 /* this hint has been removed, notify the watchers */ 04044 prevcb = NULL; 04045 thiscb = this->callbacks; 04046 while (thiscb) { 04047 prevcb = thiscb; 04048 thiscb = thiscb->next; 04049 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 04050 free(prevcb); 04051 } 04052 } else { 04053 thiscb = this->callbacks; 04054 while (thiscb->next) 04055 thiscb = thiscb->next; 04056 thiscb->next = hint->callbacks; 04057 hint->callbacks = this->callbacks; 04058 hint->laststate = this->laststate; 04059 } 04060 free(this); 04061 } 04062 04063 AST_LIST_UNLOCK(&hints); 04064 ast_unlock_contexts(); 04065 04066 return; 04067 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
This function will handle locking the channel as needed.
Definition at line 6487 of file pbx.c.
References ast_cdr_update(), 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().
06488 { 06489 char *exten, *pri, *context; 06490 char *stringp; 06491 int ipri; 06492 int mode = 0; 06493 06494 if (ast_strlen_zero(goto_string)) { 06495 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06496 return -1; 06497 } 06498 stringp = ast_strdupa(goto_string); 06499 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06500 exten = strsep(&stringp, "|"); 06501 pri = strsep(&stringp, "|"); 06502 if (!exten) { /* Only a priority in this one */ 06503 pri = context; 06504 exten = NULL; 06505 context = NULL; 06506 } else if (!pri) { /* Only an extension and priority in this one */ 06507 pri = exten; 06508 exten = context; 06509 context = NULL; 06510 } 06511 if (*pri == '+') { 06512 mode = 1; 06513 pri++; 06514 } else if (*pri == '-') { 06515 mode = -1; 06516 pri++; 06517 } 06518 if (sscanf(pri, "%d", &ipri) != 1) { 06519 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06520 pri, chan->cid.cid_num)) < 1) { 06521 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06522 return -1; 06523 } else 06524 mode = 0; 06525 } 06526 /* At this point we have a priority and maybe an extension and a context */ 06527 06528 if (mode) 06529 ipri = chan->priority + (ipri * mode); 06530 06531 ast_explicit_goto(chan, context, exten, ipri); 06532 ast_cdr_update(chan); 06533 return 0; 06534 06535 }
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 5186 of file pbx.c.
References __ast_request_and_dial(), ast_calloc, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), 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(), ast_channel::cdr, async_stat::chan, errno, free, LOG_WARNING, option_verbose, ast_channel::pbx, outgoing_helper::vars, and VERBOSE_PREFIX_4.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_app().
05187 { 05188 struct ast_channel *chan; 05189 struct app_tmp *tmp; 05190 int res = -1, cdr_res = -1; 05191 struct outgoing_helper oh; 05192 pthread_attr_t attr; 05193 05194 memset(&oh, 0, sizeof(oh)); 05195 oh.vars = vars; 05196 oh.account = account; 05197 05198 if (locked_channel) 05199 *locked_channel = NULL; 05200 if (ast_strlen_zero(app)) { 05201 res = -1; 05202 goto outgoing_app_cleanup; 05203 } 05204 if (sync) { 05205 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05206 if (chan) { 05207 if (!chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 05208 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 05209 if(!chan->cdr) { 05210 /* allocation of the cdr failed */ 05211 free(chan->pbx); 05212 res = -1; 05213 goto outgoing_app_cleanup; 05214 } 05215 /* allocation of the cdr was successful */ 05216 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05217 ast_cdr_start(chan->cdr); 05218 } 05219 ast_set_variables(chan, vars); 05220 if (account) 05221 ast_cdr_setaccount(chan, account); 05222 if (chan->_state == AST_STATE_UP) { 05223 res = 0; 05224 if (option_verbose > 3) 05225 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05226 tmp = ast_calloc(1, sizeof(*tmp)); 05227 if (!tmp) 05228 res = -1; 05229 else { 05230 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05231 if (appdata) 05232 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05233 tmp->chan = chan; 05234 if (sync > 1) { 05235 if (locked_channel) 05236 ast_channel_unlock(chan); 05237 ast_pbx_run_app(tmp); 05238 } else { 05239 pthread_attr_init(&attr); 05240 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05241 if (locked_channel) 05242 ast_channel_lock(chan); 05243 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05244 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05245 free(tmp); 05246 if (locked_channel) 05247 ast_channel_unlock(chan); 05248 ast_hangup(chan); 05249 res = -1; 05250 } else { 05251 if (locked_channel) 05252 *locked_channel = chan; 05253 } 05254 pthread_attr_destroy(&attr); 05255 } 05256 } 05257 } else { 05258 if (option_verbose > 3) 05259 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05260 if (chan->cdr) { /* update the cdr */ 05261 /* here we update the status of the call, which sould be busy. 05262 * if that fails then we set the status to failed */ 05263 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05264 ast_cdr_failed(chan->cdr); 05265 } 05266 ast_hangup(chan); 05267 } 05268 } 05269 05270 if (res < 0) { /* the call failed for some reason */ 05271 if (*reason == 0) { /* if the call failed (not busy or no answer) 05272 * update the cdr with the failed message */ 05273 cdr_res = ast_pbx_outgoing_cdr_failed(); 05274 if (cdr_res != 0) { 05275 res = cdr_res; 05276 goto outgoing_app_cleanup; 05277 } 05278 } 05279 } 05280 05281 } else { 05282 struct async_stat *as; 05283 if (!(as = ast_calloc(1, sizeof(*as)))) { 05284 res = -1; 05285 goto outgoing_app_cleanup; 05286 } 05287 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05288 if (!chan) { 05289 free(as); 05290 res = -1; 05291 goto outgoing_app_cleanup; 05292 } 05293 as->chan = chan; 05294 ast_copy_string(as->app, app, sizeof(as->app)); 05295 if (appdata) 05296 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05297 as->timeout = timeout; 05298 ast_set_variables(chan, vars); 05299 if (account) 05300 ast_cdr_setaccount(chan, account); 05301 /* Start a new thread, and get something handling this channel. */ 05302 pthread_attr_init(&attr); 05303 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05304 if (locked_channel) 05305 ast_channel_lock(chan); 05306 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05307 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05308 free(as); 05309 if (locked_channel) 05310 ast_channel_unlock(chan); 05311 ast_hangup(chan); 05312 res = -1; 05313 pthread_attr_destroy(&attr); 05314 goto outgoing_app_cleanup; 05315 } else { 05316 if (locked_channel) 05317 *locked_channel = chan; 05318 } 05319 pthread_attr_destroy(&attr); 05320 res = 0; 05321 } 05322 outgoing_app_cleanup: 05323 ast_variables_destroy(vars); 05324 return res; 05325 }
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 5020 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().
05021 { 05022 struct ast_channel *chan; 05023 struct async_stat *as; 05024 int res = -1, cdr_res = -1; 05025 struct outgoing_helper oh; 05026 pthread_attr_t attr; 05027 05028 if (sync) { 05029 LOAD_OH(oh); 05030 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05031 if (channel) { 05032 *channel = chan; 05033 if (chan) 05034 ast_channel_lock(chan); 05035 } 05036 if (chan) { 05037 if (chan->_state == AST_STATE_UP) { 05038 res = 0; 05039 if (option_verbose > 3) 05040 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05041 05042 if (sync > 1) { 05043 if (channel) 05044 ast_channel_unlock(chan); 05045 if (ast_pbx_run(chan)) { 05046 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05047 if (channel) 05048 *channel = NULL; 05049 ast_hangup(chan); 05050 chan = NULL; 05051 res = -1; 05052 } 05053 } else { 05054 if (ast_pbx_start(chan)) { 05055 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05056 if (channel) { 05057 *channel = NULL; 05058 ast_channel_unlock(chan); 05059 } 05060 ast_hangup(chan); 05061 res = -1; 05062 } 05063 chan = NULL; 05064 } 05065 } else { 05066 if (option_verbose > 3) 05067 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05068 05069 if (chan->cdr) { /* update the cdr */ 05070 /* here we update the status of the call, which sould be busy. 05071 * if that fails then we set the status to failed */ 05072 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05073 ast_cdr_failed(chan->cdr); 05074 } 05075 05076 if (channel) { 05077 *channel = NULL; 05078 ast_channel_unlock(chan); 05079 } 05080 ast_hangup(chan); 05081 chan = NULL; 05082 } 05083 } 05084 05085 if (res < 0) { /* the call failed for some reason */ 05086 if (*reason == 0) { /* if the call failed (not busy or no answer) 05087 * update the cdr with the failed message */ 05088 cdr_res = ast_pbx_outgoing_cdr_failed(); 05089 if (cdr_res != 0) { 05090 res = cdr_res; 05091 goto outgoing_exten_cleanup; 05092 } 05093 } 05094 05095 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05096 /* check if "failed" exists */ 05097 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05098 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05099 if (chan) { 05100 char failed_reason[4] = ""; 05101 if (!ast_strlen_zero(context)) 05102 ast_copy_string(chan->context, context, sizeof(chan->context)); 05103 set_ext_pri(chan, "failed", 1); 05104 ast_set_variables(chan, vars); 05105 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 05106 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 05107 if (account) 05108 ast_cdr_setaccount(chan, account); 05109 if (ast_pbx_run(chan)) { 05110 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05111 ast_hangup(chan); 05112 } 05113 chan = NULL; 05114 } 05115 } 05116 } 05117 } else { 05118 if (!(as = ast_calloc(1, sizeof(*as)))) { 05119 res = -1; 05120 goto outgoing_exten_cleanup; 05121 } 05122 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05123 if (channel) { 05124 *channel = chan; 05125 if (chan) 05126 ast_channel_lock(chan); 05127 } 05128 if (!chan) { 05129 free(as); 05130 res = -1; 05131 goto outgoing_exten_cleanup; 05132 } 05133 as->chan = chan; 05134 ast_copy_string(as->context, context, sizeof(as->context)); 05135 set_ext_pri(as->chan, exten, priority); 05136 as->timeout = timeout; 05137 ast_set_variables(chan, vars); 05138 if (account) 05139 ast_cdr_setaccount(chan, account); 05140 pthread_attr_init(&attr); 05141 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05142 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05143 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05144 free(as); 05145 if (channel) { 05146 *channel = NULL; 05147 ast_channel_unlock(chan); 05148 } 05149 ast_hangup(chan); 05150 res = -1; 05151 pthread_attr_destroy(&attr); 05152 goto outgoing_exten_cleanup; 05153 } 05154 pthread_attr_destroy(&attr); 05155 res = 0; 05156 } 05157 outgoing_exten_cleanup: 05158 ast_variables_destroy(vars); 05159 return res; 05160 }
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 2695 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().
02696 { 02697 enum ast_pbx_result res = AST_PBX_SUCCESS; 02698 02699 if (increase_call_count(c)) 02700 return AST_PBX_CALL_LIMIT; 02701 02702 res = __ast_pbx_run(c); 02703 decrease_call_count(); 02704 02705 return res; 02706 }
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 2669 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(), 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(), skinny_new(), and zt_new().
02670 { 02671 pthread_t t; 02672 pthread_attr_t attr; 02673 02674 if (!c) { 02675 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02676 return AST_PBX_FAILED; 02677 } 02678 02679 if (increase_call_count(c)) 02680 return AST_PBX_CALL_LIMIT; 02681 02682 /* Start a new thread, and get something handling this channel. */ 02683 pthread_attr_init(&attr); 02684 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02685 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02686 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02687 pthread_attr_destroy(&attr); 02688 return AST_PBX_FAILED; 02689 } 02690 pthread_attr_destroy(&attr); 02691 02692 return AST_PBX_SUCCESS; 02693 }
int ast_rdlock_contexts | ( | void | ) |
Definition at line 6265 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().
06266 { 06267 return ast_rwlock_rdlock(&conlock); 06268 }
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 2997 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().
02998 { 02999 struct ast_app *tmp, *cur = NULL; 03000 char tmps[80]; 03001 int length; 03002 03003 AST_LIST_LOCK(&apps); 03004 AST_LIST_TRAVERSE(&apps, tmp, list) { 03005 if (!strcasecmp(app, tmp->name)) { 03006 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 03007 AST_LIST_UNLOCK(&apps); 03008 return -1; 03009 } 03010 } 03011 03012 length = sizeof(*tmp) + strlen(app) + 1; 03013 03014 if (!(tmp = ast_calloc(1, length))) { 03015 AST_LIST_UNLOCK(&apps); 03016 return -1; 03017 } 03018 03019 strcpy(tmp->name, app); 03020 tmp->execute = execute; 03021 tmp->synopsis = synopsis; 03022 tmp->description = description; 03023 03024 /* Store in alphabetical order */ 03025 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 03026 if (strcasecmp(tmp->name, cur->name) < 0) { 03027 AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 03028 break; 03029 } 03030 } 03031 AST_LIST_TRAVERSE_SAFE_END 03032 if (!cur) 03033 AST_LIST_INSERT_TAIL(&apps, tmp, list); 03034 03035 if (option_verbose > 1) 03036 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 03037 03038 AST_LIST_UNLOCK(&apps); 03039 03040 return 0; 03041 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 3047 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().
03048 { 03049 struct ast_switch *tmp; 03050 03051 AST_LIST_LOCK(&switches); 03052 AST_LIST_TRAVERSE(&switches, tmp, list) { 03053 if (!strcasecmp(tmp->name, sw->name)) { 03054 AST_LIST_UNLOCK(&switches); 03055 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 03056 return -1; 03057 } 03058 } 03059 AST_LIST_INSERT_TAIL(&switches, sw, list); 03060 AST_LIST_UNLOCK(&switches); 03061 03062 return 0; 03063 }
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 6288 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().
06289 { 06290 return ast_mutex_unlock(&con->lock); 06291 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 6275 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(), 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().
06276 { 06277 return ast_rwlock_unlock(&conlock); 06278 }
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 3878 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().
03879 { 03880 struct ast_app *tmp; 03881 03882 AST_LIST_LOCK(&apps); 03883 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03884 if (!strcasecmp(app, tmp->name)) { 03885 AST_LIST_REMOVE_CURRENT(&apps, list); 03886 if (option_verbose > 1) 03887 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03888 free(tmp); 03889 break; 03890 } 03891 } 03892 AST_LIST_TRAVERSE_SAFE_END 03893 AST_LIST_UNLOCK(&apps); 03894 03895 return tmp ? 0 : -1; 03896 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 3065 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_REMOVE, and AST_LIST_UNLOCK.
Referenced by __unload_module(), and unload_module().
03066 { 03067 AST_LIST_LOCK(&switches); 03068 AST_LIST_REMOVE(&switches, sw, list); 03069 AST_LIST_UNLOCK(&switches); 03070 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | priority | |||
) |
Definition at line 6397 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().
06399 { 06400 if (!exten) 06401 return con ? con->root : NULL; 06402 else 06403 return exten->next; 06404 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 6430 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().
06432 { 06433 if (!ip) 06434 return con ? con->ignorepats : NULL; 06435 else 06436 return ip->next; 06437 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 6421 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().
06423 { 06424 if (!inc) 06425 return con ? con->includes : NULL; 06426 else 06427 return inc->next; 06428 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 6406 of file pbx.c.
References AST_LIST_FIRST, and AST_LIST_NEXT.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06408 { 06409 if (!sw) 06410 return con ? AST_LIST_FIRST(&con->alts) : NULL; 06411 else 06412 return AST_LIST_NEXT(sw, list); 06413 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 6392 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 6415 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 6270 of file pbx.c.
References ast_rwlock_wrlock().
Referenced by ast_context_destroy(), ast_merge_contexts_and_delete(), and complete_context_dont_include_deprecated().
06271 { 06272 return ast_rwlock_wrlock(&conlock); 06273 }
void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 6036 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().
06037 { 06038 struct ast_var_t *vardata; 06039 06040 ast_mutex_lock(&globalslock); 06041 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06042 ast_var_delete(vardata); 06043 ast_mutex_unlock(&globalslock); 06044 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5813 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(), 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(), wait_for_answer(), zt_call(), and zt_hangup().
05814 { 05815 struct ast_var_t *variables; 05816 const char *ret = NULL; 05817 int i; 05818 struct varshead *places[2] = { NULL, &globals }; 05819 05820 if (!name) 05821 return NULL; 05822 05823 if (chan) { 05824 ast_channel_lock(chan); 05825 places[0] = &chan->varshead; 05826 } 05827 05828 for (i = 0; i < 2; i++) { 05829 if (!places[i]) 05830 continue; 05831 if (places[i] == &globals) 05832 ast_mutex_lock(&globalslock); 05833 AST_LIST_TRAVERSE(places[i], variables, entries) { 05834 if (!strcmp(name, ast_var_name(variables))) { 05835 ret = ast_var_value(variables); 05836 break; 05837 } 05838 } 05839 if (places[i] == &globals) 05840 ast_mutex_unlock(&globalslock); 05841 if (ret) 05842 break; 05843 } 05844 05845 if (chan) 05846 ast_channel_unlock(chan); 05847 05848 return ret; 05849 }
void pbx_builtin_pushvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5851 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().
05852 { 05853 struct ast_var_t *newvariable; 05854 struct varshead *headp; 05855 05856 if (name[strlen(name)-1] == ')') { 05857 char *function = ast_strdupa(name); 05858 05859 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05860 ast_func_write(chan, function, value); 05861 return; 05862 } 05863 05864 if (chan) { 05865 ast_channel_lock(chan); 05866 headp = &chan->varshead; 05867 } else { 05868 ast_mutex_lock(&globalslock); 05869 headp = &globals; 05870 } 05871 05872 if (value) { 05873 if ((option_verbose > 1) && (headp == &globals)) 05874 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05875 newvariable = ast_var_assign(name, value); 05876 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05877 } 05878 05879 if (chan) 05880 ast_channel_unlock(chan); 05881 else 05882 ast_mutex_unlock(&globalslock); 05883 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5782 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().
05783 { 05784 struct ast_var_t *variables; 05785 const char *var, *val; 05786 int total = 0; 05787 05788 if (!chan) 05789 return 0; 05790 05791 memset(buf, 0, size); 05792 05793 ast_channel_lock(chan); 05794 05795 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05796 if ((var=ast_var_name(variables)) && (val=ast_var_value(variables)) 05797 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 05798 ) { 05799 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05800 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05801 break; 05802 } else 05803 total++; 05804 } else 05805 break; 05806 } 05807 05808 ast_channel_unlock(chan); 05809 05810 return total; 05811 }
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 5885 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(), 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(), vmauthenticate(), zt_handle_dtmfup(), and zt_new().
05886 { 05887 struct ast_var_t *newvariable; 05888 struct varshead *headp; 05889 const char *nametail = name; 05890 05891 if (name[strlen(name)-1] == ')') { 05892 char *function = ast_strdupa(name); 05893 05894 ast_func_write(chan, function, value); 05895 return; 05896 } 05897 05898 if (chan) { 05899 ast_channel_lock(chan); 05900 headp = &chan->varshead; 05901 } else { 05902 ast_mutex_lock(&globalslock); 05903 headp = &globals; 05904 } 05905 05906 /* For comparison purposes, we have to strip leading underscores */ 05907 if (*nametail == '_') { 05908 nametail++; 05909 if (*nametail == '_') 05910 nametail++; 05911 } 05912 05913 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05914 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 05915 /* there is already such a variable, delete it */ 05916 AST_LIST_REMOVE(headp, newvariable, entries); 05917 ast_var_delete(newvariable); 05918 break; 05919 } 05920 } 05921 05922 if (value) { 05923 if ((option_verbose > 1) && (headp == &globals)) 05924 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05925 newvariable = ast_var_assign(name, value); 05926 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05927 } 05928 05929 if (chan) 05930 ast_channel_unlock(chan); 05931 else 05932 ast_mutex_unlock(&globalslock); 05933 }
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 6046 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().
06047 { 06048 if (ast_strlen_zero(condition)) /* NULL or empty strings are false */ 06049 return 0; 06050 else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */ 06051 return atoi(condition); 06052 else /* Strings are true */ 06053 return 1; 06054 }
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 2713 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
02714 { 02715 int oldval = autofallthrough; 02716 autofallthrough = newval; 02717 return oldval; 02718 }
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 }