#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/linkedlists.h"
Include dependency graph for pbx.h:
This graph shows which files directly or indirectly include this file:
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 } |
The result codes when starting the PBX on a channel with ast_pbx_start(). More... | |
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) |
Register a new context or find an existing one. | |
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 | |
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 hint exists, return non-zero. | |
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) |
Support for Asterisk built-in variables and functions in the dialplan. | |
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) |
Functions for returning values from structures | |
const char * | ast_get_context_name (struct ast_context *con) |
ast_context * | ast_get_extension_context (struct ast_exten *exten) |
const char * | ast_get_extension_name (struct ast_exten *exten) |
const char * | ast_get_ignorepat_name (struct ast_ignorepat *ip) |
const char * | ast_get_include_name (struct ast_include *include) |
const char * | ast_get_switch_data (struct ast_sw *sw) |
const char * | ast_get_switch_name (struct ast_sw *sw) |
Registrar info functions ... | |
const char * | ast_get_context_registrar (struct ast_context *c) |
const char * | ast_get_extension_registrar (struct ast_exten *e) |
const char * | ast_get_ignorepat_registrar (struct ast_ignorepat *ip) |
const char * | ast_get_include_registrar (struct ast_include *i) |
const char * | ast_get_switch_registrar (struct ast_sw *sw) |
Other Extension stuff | |
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) |
const char * | ast_get_extension_label (struct ast_exten *e) |
int | ast_get_extension_matchcid (struct ast_exten *e) |
int | ast_get_extension_priority (struct ast_exten *exten) |
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 50 of file pbx.h.
00050 { 00051 AST_EXTENSION_REMOVED = -2, /*!< Extension removed */ 00052 AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */ 00053 AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */ 00054 AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */ 00055 AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */ 00056 AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */ 00057 AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */ 00058 AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */ 00059 };
enum ast_pbx_result |
The result codes when starting the PBX on a channel with ast_pbx_start().
AST_PBX_CALL_LIMIT refers to the maxcalls call limit in asterisk.conf
Definition at line 236 of file pbx.h.
00236 { 00237 AST_PBX_SUCCESS = 0, 00238 AST_PBX_FAILED = -1, 00239 AST_PBX_CALL_LIMIT = -2, 00240 };
int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 2687 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02688 { 02689 return countcalls; 02690 }
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 4564 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().
04567 { 04568 int ret = -1; 04569 struct ast_context *c = find_context_locked(context); 04570 04571 if (c) { 04572 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04573 application, data, datad, registrar); 04574 ast_unlock_contexts(); 04575 } 04576 return ret; 04577 }
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 4773 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().
04777 { 04778 /* 04779 * Sort extensions (or patterns) according to the rules indicated above. 04780 * These are implemented by the function ext_cmp()). 04781 * All priorities for the same ext/pattern/cid are kept in a list, 04782 * using the 'peer' field as a link field.. 04783 */ 04784 struct ast_exten *tmp, *e, *el = NULL; 04785 int res; 04786 int length; 04787 char *p; 04788 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04789 04790 /* if we are adding a hint, and there are global variables, and the hint 04791 contains variable references, then expand them 04792 */ 04793 ast_mutex_lock(&globalslock); 04794 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04795 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04796 application = expand_buf; 04797 } 04798 ast_mutex_unlock(&globalslock); 04799 04800 length = sizeof(struct ast_exten); 04801 length += strlen(extension) + 1; 04802 length += strlen(application) + 1; 04803 if (label) 04804 length += strlen(label) + 1; 04805 if (callerid) 04806 length += strlen(callerid) + 1; 04807 else 04808 length ++; /* just the '\0' */ 04809 04810 /* Be optimistic: Build the extension structure first */ 04811 if (!(tmp = ast_calloc(1, length))) 04812 return -1; 04813 04814 /* use p as dst in assignments, as the fields are const char * */ 04815 p = tmp->stuff; 04816 if (label) { 04817 tmp->label = p; 04818 strcpy(p, label); 04819 p += strlen(label) + 1; 04820 } 04821 tmp->exten = p; 04822 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04823 tmp->priority = priority; 04824 tmp->cidmatch = p; /* but use p for assignments below */ 04825 if (callerid) { 04826 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04827 tmp->matchcid = 1; 04828 } else { 04829 *p++ = '\0'; 04830 tmp->matchcid = 0; 04831 } 04832 tmp->app = p; 04833 strcpy(p, application); 04834 tmp->parent = con; 04835 tmp->data = data; 04836 tmp->datad = datad; 04837 tmp->registrar = registrar; 04838 04839 ast_mutex_lock(&con->lock); 04840 res = 0; /* some compilers will think it is uninitialized otherwise */ 04841 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04842 res = ext_cmp(e->exten, extension); 04843 if (res == 0) { /* extension match, now look at cidmatch */ 04844 if (!e->matchcid && !tmp->matchcid) 04845 res = 0; 04846 else if (tmp->matchcid && !e->matchcid) 04847 res = 1; 04848 else if (e->matchcid && !tmp->matchcid) 04849 res = -1; 04850 else 04851 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04852 } 04853 if (res >= 0) 04854 break; 04855 } 04856 if (e && res == 0) { /* exact match, insert in the pri chain */ 04857 res = add_pri(con, tmp, el, e, replace); 04858 ast_mutex_unlock(&con->lock); 04859 if (res < 0) { 04860 errno = EEXIST; /* XXX do we care ? */ 04861 return 0; /* XXX should we return -1 maybe ? */ 04862 } 04863 } else { 04864 /* 04865 * not an exact match, this is the first entry with this pattern, 04866 * so insert in the main list right before 'e' (if any) 04867 */ 04868 tmp->next = e; 04869 if (el) 04870 el->next = tmp; 04871 else 04872 con->root = tmp; 04873 ast_mutex_unlock(&con->lock); 04874 if (tmp->priority == PRIORITY_HINT) 04875 ast_add_hint(tmp); 04876 } 04877 if (option_debug) { 04878 if (tmp->matchcid) { 04879 if (option_debug) 04880 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04881 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04882 } else { 04883 if (option_debug) 04884 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04885 tmp->exten, tmp->priority, con->name); 04886 } 04887 } 04888 if (option_verbose > 2) { 04889 if (tmp->matchcid) { 04890 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04891 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04892 } else { 04893 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04894 tmp->exten, tmp->priority, con->name); 04895 } 04896 } 04897 return 0; 04898 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4602 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().
04603 { 04604 int res = 0; 04605 04606 ast_channel_lock(chan); 04607 04608 if (chan->pbx) { /* This channel is currently in the PBX */ 04609 ast_explicit_goto(chan, context, exten, priority); 04610 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04611 } else { 04612 /* In order to do it when the channel doesn't really exist within 04613 the PBX, we have to make a new channel, masquerade, and start the PBX 04614 at the new location */ 04615 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04616 if (chan->cdr) { 04617 ast_cdr_discard(tmpchan->cdr); 04618 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 04619 } 04620 if (!tmpchan) 04621 res = -1; 04622 else { 04623 /* Make formats okay */ 04624 tmpchan->readformat = chan->readformat; 04625 tmpchan->writeformat = chan->writeformat; 04626 /* Setup proper location */ 04627 ast_explicit_goto(tmpchan, 04628 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04629 04630 /* Masquerade into temp channel */ 04631 ast_channel_masquerade(tmpchan, chan); 04632 04633 /* Grab the locks and get going */ 04634 ast_channel_lock(tmpchan); 04635 ast_do_masquerade(tmpchan); 04636 ast_channel_unlock(tmpchan); 04637 /* Start the PBX going on our stolen channel */ 04638 if (ast_pbx_start(tmpchan)) { 04639 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04640 ast_hangup(tmpchan); 04641 res = -1; 04642 } 04643 } 04644 } 04645 ast_channel_unlock(chan); 04646 return res; 04647 }
int ast_async_goto_by_name | ( | const char * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4649 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04650 { 04651 struct ast_channel *chan; 04652 int res = -1; 04653 04654 chan = ast_get_channel_by_name_locked(channame); 04655 if (chan) { 04656 res = ast_async_goto(chan, context, exten, priority); 04657 ast_channel_unlock(chan); 04658 } 04659 return res; 04660 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6367 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06368 { 06369 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06370 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info | |||
) |
Definition at line 4247 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().
04248 { 04249 char info_save[256]; 04250 char *info; 04251 04252 /* Check for empty just in case */ 04253 if (ast_strlen_zero(info_in)) 04254 return 0; 04255 /* make a copy just in case we were passed a static string */ 04256 ast_copy_string(info_save, info_in, sizeof(info_save)); 04257 info = info_save; 04258 /* Assume everything except time */ 04259 i->monthmask = 0xfff; /* 12 bits */ 04260 i->daymask = 0x7fffffffU; /* 31 bits */ 04261 i->dowmask = 0x7f; /* 7 bits */ 04262 /* on each call, use strsep() to move info to the next argument */ 04263 get_timerange(i, strsep(&info, "|")); 04264 if (info) 04265 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04266 if (info) 04267 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04268 if (info) 04269 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04270 return 1; 04271 }
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 2311 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(), nv_background_detect_exec(), nv_detectfax_exec(), phone_check_exception(), skinny_ss(), ss_thread(), and valid_exit().
02312 { 02313 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH); 02314 }
int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 4273 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().
04274 { 04275 struct tm tm; 04276 time_t t = time(NULL); 04277 04278 ast_localtime(&t, &tm, NULL); 04279 04280 /* If it's not the right month, return */ 04281 if (!(i->monthmask & (1 << tm.tm_mon))) 04282 return 0; 04283 04284 /* If it's not that time of the month.... */ 04285 /* Warning, tm_mday has range 1..31! */ 04286 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04287 return 0; 04288 04289 /* If it's not the right day of the week */ 04290 if (!(i->dowmask & (1 << tm.tm_wday))) 04291 return 0; 04292 04293 /* Sanity check the hour just to be safe */ 04294 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04295 ast_log(LOG_WARNING, "Insane time...\n"); 04296 return 0; 04297 } 04298 04299 /* Now the tough part, we calculate if it fits 04300 in the right time based on min/hour */ 04301 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04302 return 0; 04303 04304 /* If we got this far, then we're good */ 04305 return 1; 04306 }
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 4500 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().
04501 { 04502 int ret = -1; 04503 struct ast_context *c = find_context_locked(context); 04504 04505 if (c) { 04506 ret = ast_context_add_ignorepat2(c, value, registrar); 04507 ast_unlock_contexts(); 04508 } 04509 return ret; 04510 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4512 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().
04513 { 04514 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04515 int length; 04516 length = sizeof(struct ast_ignorepat); 04517 length += strlen(value) + 1; 04518 if (!(ignorepat = ast_calloc(1, length))) 04519 return -1; 04520 /* The cast to char * is because we need to write the initial value. 04521 * The field is not supposed to be modified otherwise 04522 */ 04523 strcpy((char *)ignorepat->pattern, value); 04524 ignorepat->next = NULL; 04525 ignorepat->registrar = registrar; 04526 ast_mutex_lock(&con->lock); 04527 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04528 ignorepatl = ignorepatc; 04529 if (!strcasecmp(ignorepatc->pattern, value)) { 04530 /* Already there */ 04531 ast_mutex_unlock(&con->lock); 04532 errno = EEXIST; 04533 return -1; 04534 } 04535 } 04536 if (ignorepatl) 04537 ignorepatl->next = ignorepat; 04538 else 04539 con->ignorepats = ignorepat; 04540 ast_mutex_unlock(&con->lock); 04541 return 0; 04542 04543 }
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 4053 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().
04054 { 04055 int ret = -1; 04056 struct ast_context *c = find_context_locked(context); 04057 04058 if (c) { 04059 ret = ast_context_add_include2(c, include, registrar); 04060 ast_unlock_contexts(); 04061 } 04062 return ret; 04063 }
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 4315 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().
04317 { 04318 struct ast_include *new_include; 04319 char *c; 04320 struct ast_include *i, *il = NULL; /* include, include_last */ 04321 int length; 04322 char *p; 04323 04324 length = sizeof(struct ast_include); 04325 length += 2 * (strlen(value) + 1); 04326 04327 /* allocate new include structure ... */ 04328 if (!(new_include = ast_calloc(1, length))) 04329 return -1; 04330 /* Fill in this structure. Use 'p' for assignments, as the fields 04331 * in the structure are 'const char *' 04332 */ 04333 p = new_include->stuff; 04334 new_include->name = p; 04335 strcpy(p, value); 04336 p += strlen(value) + 1; 04337 new_include->rname = p; 04338 strcpy(p, value); 04339 /* Strip off timing info, and process if it is there */ 04340 if ( (c = strchr(p, '|')) ) { 04341 *c++ = '\0'; 04342 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04343 } 04344 new_include->next = NULL; 04345 new_include->registrar = registrar; 04346 04347 ast_mutex_lock(&con->lock); 04348 04349 /* ... go to last include and check if context is already included too... */ 04350 for (i = con->includes; i; i = i->next) { 04351 if (!strcasecmp(i->name, new_include->name)) { 04352 free(new_include); 04353 ast_mutex_unlock(&con->lock); 04354 errno = EEXIST; 04355 return -1; 04356 } 04357 il = i; 04358 } 04359 04360 /* ... include new context into context list, unlock, return */ 04361 if (il) 04362 il->next = new_include; 04363 else 04364 con->includes = new_include; 04365 if (option_verbose > 2) 04366 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04367 ast_mutex_unlock(&con->lock); 04368 04369 return 0; 04370 }
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 4377 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04378 { 04379 int ret = -1; 04380 struct ast_context *c = find_context_locked(context); 04381 04382 if (c) { /* found, add switch to this context */ 04383 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04384 ast_unlock_contexts(); 04385 } 04386 return ret; 04387 }
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 4396 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().
04398 { 04399 struct ast_sw *new_sw; 04400 struct ast_sw *i; 04401 int length; 04402 char *p; 04403 04404 length = sizeof(struct ast_sw); 04405 length += strlen(value) + 1; 04406 if (data) 04407 length += strlen(data); 04408 length++; 04409 04410 /* allocate new sw structure ... */ 04411 if (!(new_sw = ast_calloc(1, length))) 04412 return -1; 04413 /* ... fill in this structure ... */ 04414 p = new_sw->stuff; 04415 new_sw->name = p; 04416 strcpy(new_sw->name, value); 04417 p += strlen(value) + 1; 04418 new_sw->data = p; 04419 if (data) { 04420 strcpy(new_sw->data, data); 04421 p += strlen(data) + 1; 04422 } else { 04423 strcpy(new_sw->data, ""); 04424 p++; 04425 } 04426 new_sw->eval = eval; 04427 new_sw->registrar = registrar; 04428 04429 /* ... try to lock this context ... */ 04430 ast_mutex_lock(&con->lock); 04431 04432 /* ... go to last sw and check if context is already swd too... */ 04433 AST_LIST_TRAVERSE(&con->alts, i, list) { 04434 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04435 free(new_sw); 04436 ast_mutex_unlock(&con->lock); 04437 errno = EEXIST; 04438 return -1; 04439 } 04440 } 04441 04442 /* ... sw new context into context list, unlock, return */ 04443 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04444 04445 if (option_verbose > 2) 04446 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04447 04448 ast_mutex_unlock(&con->lock); 04449 04450 return 0; 04451 }
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 3923 of file pbx.c.
References __ast_context_create().
Referenced by do_parking_thread(), park_call_full(), and set_config().
03924 { 03925 return __ast_context_create(extcontexts, name, registrar, 0); 03926 }
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 5365 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().
05366 { 05367 ast_wrlock_contexts(); 05368 __ast_context_destroy(con,registrar); 05369 ast_unlock_contexts(); 05370 }
struct ast_context* ast_context_find | ( | const char * | name | ) |
Find a context.
name | name of the context to find |
Definition at line 897 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().
00898 { 00899 struct ast_context *tmp = NULL; 00900 00901 ast_rdlock_contexts(); 00902 00903 while ( (tmp = ast_walk_contexts(tmp)) ) { 00904 if (!name || !strcasecmp(name, tmp->name)) 00905 break; 00906 } 00907 00908 ast_unlock_contexts(); 00909 00910 return tmp; 00911 }
struct ast_context* ast_context_find_or_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar | |||
) |
Register a new context or find an existing one.
extcontexts | pointer to the ast_context structure pointer | |
name | name of the new context | |
registrar | registrar of the context |
Definition at line 3928 of file pbx.c.
References __ast_context_create().
Referenced by pbx_load_config(), and pbx_load_users().
03929 { 03930 return __ast_context_create(extcontexts, name, registrar, 1); 03931 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 2924 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().
02925 { 02926 struct ast_context *c = NULL; 02927 int ret = -1; 02928 02929 ast_rdlock_contexts(); 02930 02931 while ((c = ast_walk_contexts(c))) { 02932 if (!strcmp(ast_get_context_name(c), context)) { 02933 ret = 0; 02934 break; 02935 } 02936 } 02937 02938 ast_unlock_contexts(); 02939 02940 /* if we found context, lock macrolock */ 02941 if (ret == 0) 02942 ret = ast_mutex_lock(&c->macrolock); 02943 02944 return ret; 02945 }
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 2825 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().
02826 { 02827 int ret = -1; /* default error return */ 02828 struct ast_context *c = find_context_locked(context); 02829 02830 if (c) { /* ... remove extension ... */ 02831 ret = ast_context_remove_extension2(c, extension, priority, registrar); 02832 ast_unlock_contexts(); 02833 } 02834 return ret; 02835 }
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 2847 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().
02848 { 02849 struct ast_exten *exten, *prev_exten = NULL; 02850 struct ast_exten *peer; 02851 02852 ast_mutex_lock(&con->lock); 02853 02854 /* scan the extension list to find matching extension-registrar */ 02855 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02856 if (!strcmp(exten->exten, extension) && 02857 (!registrar || !strcmp(exten->registrar, registrar))) 02858 break; 02859 } 02860 if (!exten) { 02861 /* we can't find right extension */ 02862 ast_mutex_unlock(&con->lock); 02863 return -1; 02864 } 02865 02866 /* should we free all peers in this extension? (priority == 0)? */ 02867 if (priority == 0) { 02868 /* remove this extension from context list */ 02869 if (prev_exten) 02870 prev_exten->next = exten->next; 02871 else 02872 con->root = exten->next; 02873 02874 /* fire out all peers */ 02875 while ( (peer = exten) ) { 02876 exten = peer->peer; /* prepare for next entry */ 02877 destroy_exten(peer); 02878 } 02879 } else { 02880 /* scan the priority list to remove extension with exten->priority == priority */ 02881 struct ast_exten *previous_peer = NULL; 02882 02883 for (peer = exten; peer; previous_peer = peer, peer = peer->peer) { 02884 if (peer->priority == priority && 02885 (!registrar || !strcmp(peer->registrar, registrar) )) 02886 break; /* found our priority */ 02887 } 02888 if (!peer) { /* not found */ 02889 ast_mutex_unlock(&con->lock); 02890 return -1; 02891 } 02892 /* we are first priority extension? */ 02893 if (!previous_peer) { 02894 /* 02895 * We are first in the priority chain, so must update the extension chain. 02896 * The next node is either the next priority or the next extension 02897 */ 02898 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02899 02900 if (!prev_exten) /* change the root... */ 02901 con->root = next_node; 02902 else 02903 prev_exten->next = next_node; /* unlink */ 02904 if (peer->peer) /* XXX update the new head of the pri list */ 02905 peer->peer->next = peer->next; 02906 } else { /* easy, we are not first priority in extension */ 02907 previous_peer->peer = peer->peer; 02908 } 02909 02910 /* now, free whole priority extension */ 02911 destroy_exten(peer); 02912 /* XXX should we return -1 ? */ 02913 } 02914 ast_mutex_unlock(&con->lock); 02915 return 0; 02916 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4457 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().
04458 { 04459 int ret = -1; 04460 struct ast_context *c = find_context_locked(context); 04461 04462 if (c) { 04463 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04464 ast_unlock_contexts(); 04465 } 04466 return ret; 04467 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4469 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().
04470 { 04471 struct ast_ignorepat *ip, *ipl = NULL; 04472 04473 ast_mutex_lock(&con->lock); 04474 04475 for (ip = con->ignorepats; ip; ip = ip->next) { 04476 if (!strcmp(ip->pattern, ignorepat) && 04477 (!registrar || (registrar == ip->registrar))) { 04478 if (ipl) { 04479 ipl->next = ip->next; 04480 free(ip); 04481 } else { 04482 con->ignorepats = ip->next; 04483 free(ip); 04484 } 04485 ast_mutex_unlock(&con->lock); 04486 return 0; 04487 } 04488 ipl = ip; 04489 } 04490 04491 ast_mutex_unlock(&con->lock); 04492 errno = EINVAL; 04493 return -1; 04494 }
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 2721 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().
02722 { 02723 int ret = -1; 02724 struct ast_context *c = find_context_locked(context); 02725 02726 if (c) { 02727 /* found, remove include from this context ... */ 02728 ret = ast_context_remove_include2(c, include, registrar); 02729 ast_unlock_contexts(); 02730 } 02731 return ret; 02732 }
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 2742 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().
02743 { 02744 struct ast_include *i, *pi = NULL; 02745 int ret = -1; 02746 02747 ast_mutex_lock(&con->lock); 02748 02749 /* find our include */ 02750 for (i = con->includes; i; pi = i, i = i->next) { 02751 if (!strcmp(i->name, include) && 02752 (!registrar || !strcmp(i->registrar, registrar))) { 02753 /* remove from list */ 02754 if (pi) 02755 pi->next = i->next; 02756 else 02757 con->includes = i->next; 02758 /* free include and return */ 02759 free(i); 02760 ret = 0; 02761 break; 02762 } 02763 } 02764 02765 ast_mutex_unlock(&con->lock); 02766 return ret; 02767 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 2774 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
02775 { 02776 int ret = -1; /* default error return */ 02777 struct ast_context *c = find_context_locked(context); 02778 02779 if (c) { 02780 /* remove switch from this context ... */ 02781 ret = ast_context_remove_switch2(c, sw, data, registrar); 02782 ast_unlock_contexts(); 02783 } 02784 return ret; 02785 }
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 2795 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().
02796 { 02797 struct ast_sw *i; 02798 int ret = -1; 02799 02800 ast_mutex_lock(&con->lock); 02801 02802 /* walk switches */ 02803 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02804 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02805 (!registrar || !strcmp(i->registrar, registrar))) { 02806 /* found, remove from list */ 02807 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02808 free(i); /* free switch and return */ 02809 ret = 0; 02810 break; 02811 } 02812 } 02813 AST_LIST_TRAVERSE_SAFE_END 02814 02815 ast_mutex_unlock(&con->lock); 02816 02817 return ret; 02818 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 2952 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().
02953 { 02954 struct ast_context *c = NULL; 02955 int ret = -1; 02956 02957 ast_rdlock_contexts(); 02958 02959 while ((c = ast_walk_contexts(c))) { 02960 if (!strcmp(ast_get_context_name(c), context)) { 02961 ret = 0; 02962 break; 02963 } 02964 } 02965 02966 ast_unlock_contexts(); 02967 02968 /* if we found context, unlock macrolock */ 02969 if (ret == 0) 02970 ret = ast_mutex_unlock(&c->macrolock); 02971 02972 return ret; 02973 }
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 6324 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().
06325 { 06326 struct ast_include *inc = NULL; 06327 int res = 0; 06328 06329 while ( (inc = ast_walk_context_includes(con, inc)) ) { 06330 if (ast_context_find(inc->rname)) 06331 continue; 06332 06333 res = -1; 06334 ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n", 06335 ast_get_context_name(con), inc->rname); 06336 break; 06337 } 06338 06339 return res; 06340 }
struct ast_custom_function* ast_custom_function_find | ( | const char * | name | ) |
Definition at line 1460 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().
01461 { 01462 struct ast_custom_function *acf = NULL; 01463 01464 AST_LIST_LOCK(&acf_root); 01465 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01466 if (!strcmp(name, acf->name)) 01467 break; 01468 } 01469 AST_LIST_UNLOCK(&acf_root); 01470 01471 return acf; 01472 }
int ast_custom_function_register | ( | struct ast_custom_function * | acf | ) |
Reigster a custom function.
Definition at line 1496 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().
01497 { 01498 struct ast_custom_function *cur; 01499 01500 if (!acf) 01501 return -1; 01502 01503 AST_LIST_LOCK(&acf_root); 01504 01505 if (ast_custom_function_find(acf->name)) { 01506 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01507 AST_LIST_UNLOCK(&acf_root); 01508 return -1; 01509 } 01510 01511 /* Store in alphabetical order */ 01512 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01513 if (strcasecmp(acf->name, cur->name) < 0) { 01514 AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist); 01515 break; 01516 } 01517 } 01518 AST_LIST_TRAVERSE_SAFE_END 01519 if (!cur) 01520 AST_LIST_INSERT_TAIL(&acf_root, acf, acflist); 01521 01522 AST_LIST_UNLOCK(&acf_root); 01523 01524 if (option_verbose > 1) 01525 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01526 01527 return 0; 01528 }
int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Unregister a custom function.
Definition at line 1474 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().
01475 { 01476 struct ast_custom_function *cur; 01477 01478 if (!acf) 01479 return -1; 01480 01481 AST_LIST_LOCK(&acf_root); 01482 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01483 if (cur == acf) { 01484 AST_LIST_REMOVE_CURRENT(&acf_root, acflist); 01485 if (option_verbose > 1) 01486 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01487 break; 01488 } 01489 } 01490 AST_LIST_TRAVERSE_SAFE_END 01491 AST_LIST_UNLOCK(&acf_root); 01492 01493 return acf ? 0 : -1; 01494 }
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 2296 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_atxfer(), builtin_blindtransfer(), cb_events(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), disa_exec(), 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(), nv_background_detect_exec(), nv_detectfax_exec(), 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().
02297 { 02298 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH); 02299 }
int ast_explicit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4579 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(), builtin_atxfer(), disa_exec(), do_bridge_masquerade(), and handle_setpriority().
04580 { 04581 if (!chan) 04582 return -1; 04583 04584 ast_channel_lock(chan); 04585 04586 if (!ast_strlen_zero(context)) 04587 ast_copy_string(chan->context, context, sizeof(chan->context)); 04588 if (!ast_strlen_zero(exten)) 04589 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04590 if (priority > -1) { 04591 chan->priority = priority; 04592 /* see flag description in channel.h for explanation */ 04593 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04594 chan->priority--; 04595 } 04596 04597 ast_channel_unlock(chan); 04598 04599 return 0; 04600 }
int ast_extension_close | ( | const char * | pattern, | |
const char * | data, | |||
int | needmore | |||
) |
Definition at line 890 of file pbx.c.
References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.
Referenced by realtime_switch_common().
00891 { 00892 if (needmore != E_MATCHMORE && needmore != E_CANMATCH) 00893 ast_log(LOG_WARNING, "invalid argument %d\n", needmore); 00894 return extension_match_core(pattern, data, needmore); 00895 }
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 885 of file pbx.c.
References E_MATCH, and extension_match_core().
Referenced by ast_ignore_pattern(), do_say(), find_matching_priority(), loopback_canmatch(), loopback_exec(), loopback_exists(), loopback_matchmore(), matchcid(), misdn_cfg_is_msn_valid(), realtime_switch_common(), and show_dialplan_helper().
00886 { 00887 return extension_match_core(pattern, data, E_MATCH); 00888 }
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 2020 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), and handle_request_subscribe().
02021 { 02022 struct ast_exten *e; 02023 02024 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 02025 if (!e) 02026 return -1; /* No hint, return -1 */ 02027 02028 return ast_extension_state2(e); /* Check all devices in the hint */ 02029 }
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 2008 of file pbx.c.
References extension_states.
Referenced by cb_extensionstate(), handle_request_subscribe(), and handle_show_hints().
02009 { 02010 int i; 02011 02012 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 02013 if (extension_states[i].extension_state == extension_state) 02014 return extension_states[i].text; 02015 } 02016 return "Unknown"; 02017 }
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 2075 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().
02077 { 02078 struct ast_hint *hint; 02079 struct ast_state_cb *cblist; 02080 struct ast_exten *e; 02081 02082 /* If there's no context and extension: add callback to statecbs list */ 02083 if (!context && !exten) { 02084 AST_LIST_LOCK(&hints); 02085 02086 for (cblist = statecbs; cblist; cblist = cblist->next) { 02087 if (cblist->callback == callback) { 02088 cblist->data = data; 02089 AST_LIST_UNLOCK(&hints); 02090 return 0; 02091 } 02092 } 02093 02094 /* Now insert the callback */ 02095 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02096 AST_LIST_UNLOCK(&hints); 02097 return -1; 02098 } 02099 cblist->id = 0; 02100 cblist->callback = callback; 02101 cblist->data = data; 02102 02103 cblist->next = statecbs; 02104 statecbs = cblist; 02105 02106 AST_LIST_UNLOCK(&hints); 02107 return 0; 02108 } 02109 02110 if (!context || !exten) 02111 return -1; 02112 02113 /* This callback type is for only one hint, so get the hint */ 02114 e = ast_hint_extension(NULL, context, exten); 02115 if (!e) { 02116 return -1; 02117 } 02118 02119 /* Find the hint in the list of hints */ 02120 AST_LIST_LOCK(&hints); 02121 02122 AST_LIST_TRAVERSE(&hints, hint, list) { 02123 if (hint->exten == e) 02124 break; 02125 } 02126 02127 if (!hint) { 02128 /* We have no hint, sorry */ 02129 AST_LIST_UNLOCK(&hints); 02130 return -1; 02131 } 02132 02133 /* Now insert the callback in the callback list */ 02134 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02135 AST_LIST_UNLOCK(&hints); 02136 return -1; 02137 } 02138 cblist->id = stateid++; /* Unique ID for this callback */ 02139 cblist->callback = callback; /* Pointer to callback routine */ 02140 cblist->data = data; /* Data for the callback */ 02141 02142 cblist->next = hint->callbacks; 02143 hint->callbacks = cblist; 02144 02145 AST_LIST_UNLOCK(&hints); 02146 return cblist->id; 02147 }
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 2150 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().
02151 { 02152 struct ast_state_cb **p_cur = NULL; /* address of pointer to us */ 02153 int ret = -1; 02154 02155 if (!id && !callback) 02156 return -1; 02157 02158 AST_LIST_LOCK(&hints); 02159 02160 if (!id) { /* id == 0 is a callback without extension */ 02161 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) { 02162 if ((*p_cur)->callback == callback) 02163 break; 02164 } 02165 } else { /* callback with extension, find the callback based on ID */ 02166 struct ast_hint *hint; 02167 AST_LIST_TRAVERSE(&hints, hint, list) { 02168 for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) { 02169 if ((*p_cur)->id == id) 02170 break; 02171 } 02172 if (*p_cur) /* found in the inner loop */ 02173 break; 02174 } 02175 } 02176 if (p_cur && *p_cur) { 02177 struct ast_state_cb *cur = *p_cur; 02178 *p_cur = cur->next; 02179 free(cur); 02180 ret = 0; 02181 } 02182 AST_LIST_UNLOCK(&hints); 02183 return ret; 02184 }
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 2301 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().
02302 { 02303 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL); 02304 }
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 2306 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
02307 { 02308 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL); 02309 }
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 1550 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().
01551 { 01552 char *args = func_args(function); 01553 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01554 01555 if (acfptr == NULL) 01556 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01557 else if (!acfptr->read) 01558 ast_log(LOG_ERROR, "Function %s cannot be read\n", function); 01559 else 01560 return acfptr->read(chan, function, args, workspace, len); 01561 return -1; 01562 }
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 1564 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().
01565 { 01566 char *args = func_args(function); 01567 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01568 01569 if (acfptr == NULL) 01570 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01571 else if (!acfptr->write) 01572 ast_log(LOG_ERROR, "Function %s cannot be written to\n", function); 01573 else 01574 return acfptr->write(chan, function, args, value); 01575 01576 return -1; 01577 }
const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 6181 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 6219 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06220 { 06221 return c ? c->registrar : NULL; 06222 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6249 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().
06250 { 06251 return e ? e->app : NULL; 06252 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6254 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06255 { 06256 return e ? e->data : NULL; 06257 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6244 of file pbx.c.
References ast_exten::cidmatch.
Referenced by find_matching_priority(), and handle_save_dialplan().
06245 { 06246 return e ? e->cidmatch : NULL; 06247 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
const char* ast_get_extension_label | ( | struct ast_exten * | e | ) |
Definition at line 6196 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 6239 of file pbx.c.
References ast_exten::matchcid.
Referenced by find_matching_priority(), and handle_save_dialplan().
06240 { 06241 return e ? e->matchcid : 0; 06242 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6191 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 6211 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 6224 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06225 { 06226 return e ? e->registrar : NULL; 06227 }
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 hint 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 2279 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().
02280 { 02281 struct ast_exten *e = ast_hint_extension(c, context, exten); 02282 02283 if (e) { 02284 if (hint) 02285 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02286 if (name) { 02287 const char *tmp = ast_get_extension_app_data(e); 02288 if (tmp) 02289 ast_copy_string(name, tmp, namesize); 02290 } 02291 return -1; 02292 } 02293 return 0; 02294 }
const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6206 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().
06207 { 06208 return ip ? ip->pattern : NULL; 06209 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6234 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06235 { 06236 return ip ? ip->registrar : NULL; 06237 }
const char* ast_get_include_name | ( | struct ast_include * | include | ) |
Definition at line 6201 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 6229 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06230 { 06231 return i ? i->registrar : NULL; 06232 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6264 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06265 { 06266 return sw ? sw->data : NULL; 06267 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6259 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06260 { 06261 return sw ? sw->name : NULL; 06262 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6269 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06270 { 06271 return sw ? sw->registrar : NULL; 06272 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6362 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().
06363 { 06364 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06365 }
void ast_hint_state_changed | ( | const char * | device | ) |
Definition at line 2031 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().
02032 { 02033 struct ast_hint *hint; 02034 02035 AST_LIST_LOCK(&hints); 02036 02037 AST_LIST_TRAVERSE(&hints, hint, list) { 02038 struct ast_state_cb *cblist; 02039 char buf[AST_MAX_EXTENSION]; 02040 char *parse = buf; 02041 char *cur; 02042 int state; 02043 02044 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 02045 while ( (cur = strsep(&parse, "&")) ) { 02046 if (!strcasecmp(cur, device)) 02047 break; 02048 } 02049 if (!cur) 02050 continue; 02051 02052 /* Get device state for this hint */ 02053 state = ast_extension_state2(hint->exten); 02054 02055 if ((state == -1) || (state == hint->laststate)) 02056 continue; 02057 02058 /* Device state changed since last check - notify the watchers */ 02059 02060 /* For general callbacks */ 02061 for (cblist = statecbs; cblist; cblist = cblist->next) 02062 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02063 02064 /* For extension callbacks */ 02065 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 02066 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02067 02068 hint->laststate = state; /* record we saw the change */ 02069 } 02070 02071 AST_LIST_UNLOCK(&hints); 02072 }
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 4545 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().
04546 { 04547 struct ast_context *con = ast_context_find(context); 04548 if (con) { 04549 struct ast_ignorepat *pat; 04550 for (pat = con->ignorepats; pat; pat = pat->next) { 04551 if (ast_extension_match(pat->pattern, pattern)) 04552 return 1; 04553 } 04554 } 04555 04556 return 0; 04557 }
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 6168 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().
06169 { 06170 return ast_mutex_lock(&con->lock); 06171 }
int ast_lock_contexts | ( | void | ) |
Locks the context list.
0 | on success | |
-1 | on error |
Definition at line 6145 of file pbx.c.
References ast_rwlock_wrlock().
Referenced by find_matching_endwhile().
06146 { 06147 return ast_rwlock_wrlock(&conlock); 06148 }
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 2316 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().
02317 { 02318 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE); 02319 }
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 3946 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().
03947 { 03948 struct ast_context *tmp, *lasttmp = NULL; 03949 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 03950 struct store_hint *this; 03951 struct ast_hint *hint; 03952 struct ast_exten *exten; 03953 int length; 03954 struct ast_state_cb *thiscb, *prevcb; 03955 03956 /* it is very important that this function hold the hint list lock _and_ the conlock 03957 during its operation; not only do we need to ensure that the list of contexts 03958 and extensions does not change, but also that no hint callbacks (watchers) are 03959 added or removed during the merge/delete process 03960 03961 in addition, the locks _must_ be taken in this order, because there are already 03962 other code paths that use this order 03963 */ 03964 ast_wrlock_contexts(); 03965 AST_LIST_LOCK(&hints); 03966 03967 /* preserve all watchers for hints associated with this registrar */ 03968 AST_LIST_TRAVERSE(&hints, hint, list) { 03969 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03970 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03971 if (!(this = ast_calloc(1, length))) 03972 continue; 03973 this->callbacks = hint->callbacks; 03974 hint->callbacks = NULL; 03975 this->laststate = hint->laststate; 03976 this->context = this->data; 03977 strcpy(this->data, hint->exten->parent->name); 03978 this->exten = this->data + strlen(this->context) + 1; 03979 strcpy(this->exten, hint->exten->exten); 03980 AST_LIST_INSERT_HEAD(&store, this, list); 03981 } 03982 } 03983 03984 tmp = *extcontexts; 03985 if (registrar) { 03986 /* XXX remove previous contexts from same registrar */ 03987 if (option_debug) 03988 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 03989 __ast_context_destroy(NULL,registrar); 03990 while (tmp) { 03991 lasttmp = tmp; 03992 tmp = tmp->next; 03993 } 03994 } else { 03995 /* XXX remove contexts with the same name */ 03996 while (tmp) { 03997 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 03998 __ast_context_destroy(tmp,tmp->registrar); 03999 lasttmp = tmp; 04000 tmp = tmp->next; 04001 } 04002 } 04003 if (lasttmp) { 04004 lasttmp->next = contexts; 04005 contexts = *extcontexts; 04006 *extcontexts = NULL; 04007 } else 04008 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 04009 04010 /* restore the watchers for hints that can be found; notify those that 04011 cannot be restored 04012 */ 04013 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 04014 struct pbx_find_info q = { .stacklen = 0 }; 04015 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 04016 /* Find the hint in the list of hints */ 04017 AST_LIST_TRAVERSE(&hints, hint, list) { 04018 if (hint->exten == exten) 04019 break; 04020 } 04021 if (!exten || !hint) { 04022 /* this hint has been removed, notify the watchers */ 04023 prevcb = NULL; 04024 thiscb = this->callbacks; 04025 while (thiscb) { 04026 prevcb = thiscb; 04027 thiscb = thiscb->next; 04028 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 04029 free(prevcb); 04030 } 04031 } else { 04032 thiscb = this->callbacks; 04033 while (thiscb->next) 04034 thiscb = thiscb->next; 04035 thiscb->next = hint->callbacks; 04036 hint->callbacks = this->callbacks; 04037 hint->laststate = this->laststate; 04038 } 04039 free(this); 04040 } 04041 04042 AST_LIST_UNLOCK(&hints); 04043 ast_unlock_contexts(); 04044 04045 return; 04046 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
This function will handle locking the channel as needed.
Definition at line 6372 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().
06373 { 06374 char *exten, *pri, *context; 06375 char *stringp; 06376 int ipri; 06377 int mode = 0; 06378 06379 if (ast_strlen_zero(goto_string)) { 06380 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06381 return -1; 06382 } 06383 stringp = ast_strdupa(goto_string); 06384 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06385 exten = strsep(&stringp, "|"); 06386 pri = strsep(&stringp, "|"); 06387 if (!exten) { /* Only a priority in this one */ 06388 pri = context; 06389 exten = NULL; 06390 context = NULL; 06391 } else if (!pri) { /* Only an extension and priority in this one */ 06392 pri = exten; 06393 exten = context; 06394 context = NULL; 06395 } 06396 if (*pri == '+') { 06397 mode = 1; 06398 pri++; 06399 } else if (*pri == '-') { 06400 mode = -1; 06401 pri++; 06402 } 06403 if (sscanf(pri, "%d", &ipri) != 1) { 06404 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06405 pri, chan->cid.cid_num)) < 1) { 06406 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06407 return -1; 06408 } else 06409 mode = 0; 06410 } 06411 /* At this point we have a priority and maybe an extension and a context */ 06412 06413 if (mode) 06414 ipri = chan->priority + (ipri * mode); 06415 06416 ast_explicit_goto(chan, context, exten, ipri); 06417 ast_cdr_update(chan); 06418 return 0; 06419 06420 }
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 5165 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().
05166 { 05167 struct ast_channel *chan; 05168 struct app_tmp *tmp; 05169 int res = -1, cdr_res = -1; 05170 struct outgoing_helper oh; 05171 pthread_attr_t attr; 05172 05173 memset(&oh, 0, sizeof(oh)); 05174 oh.vars = vars; 05175 oh.account = account; 05176 05177 if (locked_channel) 05178 *locked_channel = NULL; 05179 if (ast_strlen_zero(app)) { 05180 res = -1; 05181 goto outgoing_app_cleanup; 05182 } 05183 if (sync) { 05184 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05185 if (chan) { 05186 if (!chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 05187 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 05188 if(!chan->cdr) { 05189 /* allocation of the cdr failed */ 05190 free(chan->pbx); 05191 res = -1; 05192 goto outgoing_app_cleanup; 05193 } 05194 /* allocation of the cdr was successful */ 05195 ast_cdr_init(chan->cdr, chan); /* initialize our channel's cdr */ 05196 ast_cdr_start(chan->cdr); 05197 } 05198 ast_set_variables(chan, vars); 05199 if (account) 05200 ast_cdr_setaccount(chan, account); 05201 if (chan->_state == AST_STATE_UP) { 05202 res = 0; 05203 if (option_verbose > 3) 05204 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05205 tmp = ast_calloc(1, sizeof(*tmp)); 05206 if (!tmp) 05207 res = -1; 05208 else { 05209 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05210 if (appdata) 05211 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05212 tmp->chan = chan; 05213 if (sync > 1) { 05214 if (locked_channel) 05215 ast_channel_unlock(chan); 05216 ast_pbx_run_app(tmp); 05217 } else { 05218 pthread_attr_init(&attr); 05219 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05220 if (locked_channel) 05221 ast_channel_lock(chan); 05222 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05223 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05224 free(tmp); 05225 if (locked_channel) 05226 ast_channel_unlock(chan); 05227 ast_hangup(chan); 05228 res = -1; 05229 } else { 05230 if (locked_channel) 05231 *locked_channel = chan; 05232 } 05233 pthread_attr_destroy(&attr); 05234 } 05235 } 05236 } else { 05237 if (option_verbose > 3) 05238 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05239 if (chan->cdr) { /* update the cdr */ 05240 /* here we update the status of the call, which sould be busy. 05241 * if that fails then we set the status to failed */ 05242 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05243 ast_cdr_failed(chan->cdr); 05244 } 05245 ast_hangup(chan); 05246 } 05247 } 05248 05249 if (res < 0) { /* the call failed for some reason */ 05250 if (*reason == 0) { /* if the call failed (not busy or no answer) 05251 * update the cdr with the failed message */ 05252 cdr_res = ast_pbx_outgoing_cdr_failed(); 05253 if (cdr_res != 0) { 05254 res = cdr_res; 05255 goto outgoing_app_cleanup; 05256 } 05257 } 05258 } 05259 05260 } else { 05261 struct async_stat *as; 05262 if (!(as = ast_calloc(1, sizeof(*as)))) { 05263 res = -1; 05264 goto outgoing_app_cleanup; 05265 } 05266 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05267 if (!chan) { 05268 free(as); 05269 res = -1; 05270 goto outgoing_app_cleanup; 05271 } 05272 as->chan = chan; 05273 ast_copy_string(as->app, app, sizeof(as->app)); 05274 if (appdata) 05275 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05276 as->timeout = timeout; 05277 ast_set_variables(chan, vars); 05278 if (account) 05279 ast_cdr_setaccount(chan, account); 05280 /* Start a new thread, and get something handling this channel. */ 05281 pthread_attr_init(&attr); 05282 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05283 if (locked_channel) 05284 ast_channel_lock(chan); 05285 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05286 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05287 free(as); 05288 if (locked_channel) 05289 ast_channel_unlock(chan); 05290 ast_hangup(chan); 05291 res = -1; 05292 pthread_attr_destroy(&attr); 05293 goto outgoing_app_cleanup; 05294 } else { 05295 if (locked_channel) 05296 *locked_channel = chan; 05297 } 05298 pthread_attr_destroy(&attr); 05299 res = 0; 05300 } 05301 outgoing_app_cleanup: 05302 ast_variables_destroy(vars); 05303 return res; 05304 }
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 4999 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().
05000 { 05001 struct ast_channel *chan; 05002 struct async_stat *as; 05003 int res = -1, cdr_res = -1; 05004 struct outgoing_helper oh; 05005 pthread_attr_t attr; 05006 05007 if (sync) { 05008 LOAD_OH(oh); 05009 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05010 if (channel) { 05011 *channel = chan; 05012 if (chan) 05013 ast_channel_lock(chan); 05014 } 05015 if (chan) { 05016 if (chan->_state == AST_STATE_UP) { 05017 res = 0; 05018 if (option_verbose > 3) 05019 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05020 05021 if (sync > 1) { 05022 if (channel) 05023 ast_channel_unlock(chan); 05024 if (ast_pbx_run(chan)) { 05025 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05026 if (channel) 05027 *channel = NULL; 05028 ast_hangup(chan); 05029 chan = NULL; 05030 res = -1; 05031 } 05032 } else { 05033 if (ast_pbx_start(chan)) { 05034 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05035 if (channel) { 05036 *channel = NULL; 05037 ast_channel_unlock(chan); 05038 } 05039 ast_hangup(chan); 05040 res = -1; 05041 } 05042 chan = NULL; 05043 } 05044 } else { 05045 if (option_verbose > 3) 05046 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05047 05048 if (chan->cdr) { /* update the cdr */ 05049 /* here we update the status of the call, which sould be busy. 05050 * if that fails then we set the status to failed */ 05051 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05052 ast_cdr_failed(chan->cdr); 05053 } 05054 05055 if (channel) { 05056 *channel = NULL; 05057 ast_channel_unlock(chan); 05058 } 05059 ast_hangup(chan); 05060 chan = NULL; 05061 } 05062 } 05063 05064 if (res < 0) { /* the call failed for some reason */ 05065 if (*reason == 0) { /* if the call failed (not busy or no answer) 05066 * update the cdr with the failed message */ 05067 cdr_res = ast_pbx_outgoing_cdr_failed(); 05068 if (cdr_res != 0) { 05069 res = cdr_res; 05070 goto outgoing_exten_cleanup; 05071 } 05072 } 05073 05074 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05075 /* check if "failed" exists */ 05076 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05077 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05078 if (chan) { 05079 char failed_reason[4] = ""; 05080 if (!ast_strlen_zero(context)) 05081 ast_copy_string(chan->context, context, sizeof(chan->context)); 05082 set_ext_pri(chan, "failed", 1); 05083 ast_set_variables(chan, vars); 05084 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 05085 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 05086 if (account) 05087 ast_cdr_setaccount(chan, account); 05088 if (ast_pbx_run(chan)) { 05089 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05090 ast_hangup(chan); 05091 } 05092 chan = NULL; 05093 } 05094 } 05095 } 05096 } else { 05097 if (!(as = ast_calloc(1, sizeof(*as)))) { 05098 res = -1; 05099 goto outgoing_exten_cleanup; 05100 } 05101 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05102 if (channel) { 05103 *channel = chan; 05104 if (chan) 05105 ast_channel_lock(chan); 05106 } 05107 if (!chan) { 05108 free(as); 05109 res = -1; 05110 goto outgoing_exten_cleanup; 05111 } 05112 as->chan = chan; 05113 ast_copy_string(as->context, context, sizeof(as->context)); 05114 set_ext_pri(as->chan, exten, priority); 05115 as->timeout = timeout; 05116 ast_set_variables(chan, vars); 05117 if (account) 05118 ast_cdr_setaccount(chan, account); 05119 pthread_attr_init(&attr); 05120 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05121 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05122 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05123 free(as); 05124 if (channel) { 05125 *channel = NULL; 05126 ast_channel_unlock(chan); 05127 } 05128 ast_hangup(chan); 05129 res = -1; 05130 pthread_attr_destroy(&attr); 05131 goto outgoing_exten_cleanup; 05132 } 05133 pthread_attr_destroy(&attr); 05134 res = 0; 05135 } 05136 outgoing_exten_cleanup: 05137 ast_variables_destroy(vars); 05138 return res; 05139 }
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 2674 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().
02675 { 02676 enum ast_pbx_result res = AST_PBX_SUCCESS; 02677 02678 if (increase_call_count(c)) 02679 return AST_PBX_CALL_LIMIT; 02680 02681 res = __ast_pbx_run(c); 02682 decrease_call_count(); 02683 02684 return res; 02685 }
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 2648 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_bridge_call_thread(), ast_iax2_new(), ast_pbx_outgoing_exten(), bridge_exec(), 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().
02649 { 02650 pthread_t t; 02651 pthread_attr_t attr; 02652 02653 if (!c) { 02654 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02655 return AST_PBX_FAILED; 02656 } 02657 02658 if (increase_call_count(c)) 02659 return AST_PBX_CALL_LIMIT; 02660 02661 /* Start a new thread, and get something handling this channel. */ 02662 pthread_attr_init(&attr); 02663 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02664 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02665 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02666 pthread_attr_destroy(&attr); 02667 return AST_PBX_FAILED; 02668 } 02669 pthread_attr_destroy(&attr); 02670 02671 return AST_PBX_SUCCESS; 02672 }
int ast_rdlock_contexts | ( | void | ) |
Definition at line 6150 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().
06151 { 06152 return ast_rwlock_rdlock(&conlock); 06153 }
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 2976 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().
02977 { 02978 struct ast_app *tmp, *cur = NULL; 02979 char tmps[80]; 02980 int length; 02981 02982 AST_LIST_LOCK(&apps); 02983 AST_LIST_TRAVERSE(&apps, tmp, list) { 02984 if (!strcasecmp(app, tmp->name)) { 02985 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02986 AST_LIST_UNLOCK(&apps); 02987 return -1; 02988 } 02989 } 02990 02991 length = sizeof(*tmp) + strlen(app) + 1; 02992 02993 if (!(tmp = ast_calloc(1, length))) { 02994 AST_LIST_UNLOCK(&apps); 02995 return -1; 02996 } 02997 02998 strcpy(tmp->name, app); 02999 tmp->execute = execute; 03000 tmp->synopsis = synopsis; 03001 tmp->description = description; 03002 03003 /* Store in alphabetical order */ 03004 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 03005 if (strcasecmp(tmp->name, cur->name) < 0) { 03006 AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 03007 break; 03008 } 03009 } 03010 AST_LIST_TRAVERSE_SAFE_END 03011 if (!cur) 03012 AST_LIST_INSERT_TAIL(&apps, tmp, list); 03013 03014 if (option_verbose > 1) 03015 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 03016 03017 AST_LIST_UNLOCK(&apps); 03018 03019 return 0; 03020 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 3026 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().
03027 { 03028 struct ast_switch *tmp; 03029 03030 AST_LIST_LOCK(&switches); 03031 AST_LIST_TRAVERSE(&switches, tmp, list) { 03032 if (!strcasecmp(tmp->name, sw->name)) { 03033 AST_LIST_UNLOCK(&switches); 03034 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 03035 return -1; 03036 } 03037 } 03038 AST_LIST_INSERT_TAIL(&switches, sw, list); 03039 AST_LIST_UNLOCK(&switches); 03040 03041 return 0; 03042 }
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 2321 of file pbx.c.
References E_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), _macro_exec(), and loopback_exec().
02322 { 02323 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN); 02324 }
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 6173 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().
06174 { 06175 return ast_mutex_unlock(&con->lock); 06176 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 6160 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().
06161 { 06162 return ast_rwlock_unlock(&conlock); 06163 }
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 3857 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().
03858 { 03859 struct ast_app *tmp; 03860 03861 AST_LIST_LOCK(&apps); 03862 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03863 if (!strcasecmp(app, tmp->name)) { 03864 AST_LIST_REMOVE_CURRENT(&apps, list); 03865 if (option_verbose > 1) 03866 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03867 free(tmp); 03868 break; 03869 } 03870 } 03871 AST_LIST_TRAVERSE_SAFE_END 03872 AST_LIST_UNLOCK(&apps); 03873 03874 return tmp ? 0 : -1; 03875 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 3044 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_REMOVE, and AST_LIST_UNLOCK.
Referenced by __unload_module(), and unload_module().
03045 { 03046 AST_LIST_LOCK(&switches); 03047 AST_LIST_REMOVE(&switches, sw, list); 03048 AST_LIST_UNLOCK(&switches); 03049 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | priority | |||
) |
Definition at line 6282 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().
06284 { 06285 if (!exten) 06286 return con ? con->root : NULL; 06287 else 06288 return exten->next; 06289 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 6315 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().
06317 { 06318 if (!ip) 06319 return con ? con->ignorepats : NULL; 06320 else 06321 return ip->next; 06322 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 6306 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().
06308 { 06309 if (!inc) 06310 return con ? con->includes : NULL; 06311 else 06312 return inc->next; 06313 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 6291 of file pbx.c.
References AST_LIST_FIRST, and AST_LIST_NEXT.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06293 { 06294 if (!sw) 06295 return con ? AST_LIST_FIRST(&con->alts) : NULL; 06296 else 06297 return AST_LIST_NEXT(sw, list); 06298 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 6277 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 6300 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 6155 of file pbx.c.
References ast_rwlock_wrlock().
Referenced by ast_context_destroy(), ast_merge_contexts_and_delete(), and complete_context_dont_include_deprecated().
06156 { 06157 return ast_rwlock_wrlock(&conlock); 06158 }
void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 6021 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().
06022 { 06023 struct ast_var_t *vardata; 06024 06025 ast_mutex_lock(&globalslock); 06026 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06027 ast_var_delete(vardata); 06028 ast_mutex_unlock(&globalslock); 06029 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5798 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(), pop_exec(), queue_exec(), real_ctx(), retrydial_exec(), return_exec(), run_agi(), rxfax_exec(), set_config_flags(), sip_addheader(), sla_trunk_exec(), speech_background(), try_calling(), try_suggested_sip_codec(), txfax_exec(), wait_for_answer(), zt_call(), and zt_hangup().
05799 { 05800 struct ast_var_t *variables; 05801 const char *ret = NULL; 05802 int i; 05803 struct varshead *places[2] = { NULL, &globals }; 05804 05805 if (!name) 05806 return NULL; 05807 05808 if (chan) { 05809 ast_channel_lock(chan); 05810 places[0] = &chan->varshead; 05811 } 05812 05813 for (i = 0; i < 2; i++) { 05814 if (!places[i]) 05815 continue; 05816 if (places[i] == &globals) 05817 ast_mutex_lock(&globalslock); 05818 AST_LIST_TRAVERSE(places[i], variables, entries) { 05819 if (!strcmp(name, ast_var_name(variables))) { 05820 ret = ast_var_value(variables); 05821 break; 05822 } 05823 } 05824 if (places[i] == &globals) 05825 ast_mutex_unlock(&globalslock); 05826 if (ret) 05827 break; 05828 } 05829 05830 if (chan) 05831 ast_channel_unlock(chan); 05832 05833 return ret; 05834 }
void pbx_builtin_pushvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5836 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().
05837 { 05838 struct ast_var_t *newvariable; 05839 struct varshead *headp; 05840 05841 if (name[strlen(name)-1] == ')') { 05842 char *function = ast_strdupa(name); 05843 05844 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05845 ast_func_write(chan, function, value); 05846 return; 05847 } 05848 05849 if (chan) { 05850 ast_channel_lock(chan); 05851 headp = &chan->varshead; 05852 } else { 05853 ast_mutex_lock(&globalslock); 05854 headp = &globals; 05855 } 05856 05857 if (value) { 05858 if ((option_verbose > 1) && (headp == &globals)) 05859 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05860 newvariable = ast_var_assign(name, value); 05861 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05862 } 05863 05864 if (chan) 05865 ast_channel_unlock(chan); 05866 else 05867 ast_mutex_unlock(&globalslock); 05868 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5767 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().
05768 { 05769 struct ast_var_t *variables; 05770 const char *var, *val; 05771 int total = 0; 05772 05773 if (!chan) 05774 return 0; 05775 05776 memset(buf, 0, size); 05777 05778 ast_channel_lock(chan); 05779 05780 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05781 if ((var=ast_var_name(variables)) && (val=ast_var_value(variables)) 05782 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 05783 ) { 05784 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05785 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05786 break; 05787 } else 05788 total++; 05789 } else 05790 break; 05791 } 05792 05793 ast_channel_unlock(chan); 05794 05795 return total; 05796 }
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 5870 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(), aMYSQL_fetch(), 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(), bridge_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(), mwanalyze_exec(), MYSQL_exec(), nv_background_detect_exec(), nv_detectfax_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_exec(), parse_moved_contact(), pbx_builtin_importvar(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_load_config(), phase_e_handler(), pickdown_channel(), pickup_channel(), 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_asterisk_int(), 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(), steal_channel(), system_exec_helper(), transfer_exec(), try_calling(), tryexec_exec(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), zt_handle_dtmfup(), and zt_new().
05871 { 05872 struct ast_var_t *newvariable; 05873 struct varshead *headp; 05874 const char *nametail = name; 05875 05876 if (name[strlen(name)-1] == ')') { 05877 char *function = ast_strdupa(name); 05878 05879 ast_func_write(chan, function, value); 05880 return; 05881 } 05882 05883 if (chan) { 05884 ast_channel_lock(chan); 05885 headp = &chan->varshead; 05886 } else { 05887 ast_mutex_lock(&globalslock); 05888 headp = &globals; 05889 } 05890 05891 /* For comparison purposes, we have to strip leading underscores */ 05892 if (*nametail == '_') { 05893 nametail++; 05894 if (*nametail == '_') 05895 nametail++; 05896 } 05897 05898 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05899 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 05900 /* there is already such a variable, delete it */ 05901 AST_LIST_REMOVE(headp, newvariable, entries); 05902 ast_var_delete(newvariable); 05903 break; 05904 } 05905 } 05906 05907 if (value) { 05908 if ((option_verbose > 1) && (headp == &globals)) 05909 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05910 newvariable = ast_var_assign(name, value); 05911 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05912 } 05913 05914 if (chan) 05915 ast_channel_unlock(chan); 05916 else 05917 ast_mutex_unlock(&globalslock); 05918 }
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 6031 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().
06032 { 06033 if (ast_strlen_zero(condition)) /* NULL or empty strings are false */ 06034 return 0; 06035 else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */ 06036 return atoi(condition); 06037 else /* Strings are true */ 06038 return 1; 06039 }
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 517 of file pbx.c.
References app, ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_channel::cdr, ast_channel::data, and S_OR.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().
00520 { 00521 int res; 00522 00523 const char *saved_c_appl; 00524 const char *saved_c_data; 00525 00526 if (c->cdr && !ast_check_hangup(c)) 00527 ast_cdr_setapp(c->cdr, app->name, data); 00528 00529 /* save channel values */ 00530 saved_c_appl= c->appl; 00531 saved_c_data= c->data; 00532 00533 c->appl = app->name; 00534 c->data = data; 00535 /* XXX remember what to to when we have linked apps to modules */ 00536 if (app->module) { 00537 /* XXX LOCAL_USER_ADD(app->module) */ 00538 } 00539 res = app->execute(c, S_OR(data, "")); 00540 if (app->module) { 00541 /* XXX LOCAL_USER_REMOVE(app->module) */ 00542 } 00543 /* restore channel values */ 00544 c->appl = saved_c_appl; 00545 c->data = saved_c_data; 00546 return res; 00547 }
struct ast_app* pbx_findapp | ( | const char * | app | ) |
Look up an application.
app | name of the app |
Definition at line 555 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(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().
00556 { 00557 struct ast_app *tmp; 00558 00559 AST_LIST_LOCK(&apps); 00560 AST_LIST_TRAVERSE(&apps, tmp, list) { 00561 if (!strcasecmp(tmp->name, app)) 00562 break; 00563 } 00564 AST_LIST_UNLOCK(&apps); 00565 00566 return tmp; 00567 }
void pbx_retrieve_variable | ( | struct ast_channel * | c, | |
const char * | var, | |||
char ** | ret, | |||
char * | workspace, | |||
int | workspacelen, | |||
struct varshead * | headp | |||
) |
Support for Asterisk built-in variables and functions in the dialplan.
Definition at line 1157 of file pbx.c.
References 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(), function_fieldqty(), handle_getvariable(), and pbx_substitute_variables_helper_full().
01158 { 01159 const char not_found = '\0'; 01160 char *tmpvar; 01161 const char *s; /* the result */ 01162 int offset, length; 01163 int i, need_substring; 01164 struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */ 01165 01166 if (c) { 01167 ast_channel_lock(c); 01168 places[0] = &c->varshead; 01169 } 01170 /* 01171 * Make a copy of var because parse_variable_name() modifies the string. 01172 * Then if called directly, we might need to run substring() on the result; 01173 * remember this for later in 'need_substring', 'offset' and 'length' 01174 */ 01175 tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */ 01176 need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */); 01177 01178 /* 01179 * Look first into predefined variables, then into variable lists. 01180 * Variable 's' points to the result, according to the following rules: 01181 * s == ¬_found (set at the beginning) means that we did not find a 01182 * matching variable and need to look into more places. 01183 * If s != ¬_found, s is a valid result string as follows: 01184 * s = NULL if the variable does not have a value; 01185 * you typically do this when looking for an unset predefined variable. 01186 * s = workspace if the result has been assembled there; 01187 * typically done when the result is built e.g. with an snprintf(), 01188 * so we don't need to do an additional copy. 01189 * s != workspace in case we have a string, that needs to be copied 01190 * (the ast_copy_string is done once for all at the end). 01191 * Typically done when the result is already available in some string. 01192 */ 01193 s = ¬_found; /* default value */ 01194 if (c) { /* This group requires a valid channel */ 01195 /* Names with common parts are looked up a piece at a time using strncmp. */ 01196 if (!strncmp(var, "CALL", 4)) { 01197 if (!strncmp(var + 4, "ING", 3)) { 01198 if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */ 01199 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 01200 s = workspace; 01201 } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */ 01202 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 01203 s = workspace; 01204 } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */ 01205 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 01206 s = workspace; 01207 } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */ 01208 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 01209 s = workspace; 01210 } 01211 } 01212 } else if (!strcmp(var, "HINT")) { 01213 s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL; 01214 } else if (!strcmp(var, "HINTNAME")) { 01215 s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL; 01216 } else if (!strcmp(var, "EXTEN")) { 01217 s = c->exten; 01218 } else if (!strcmp(var, "CONTEXT")) { 01219 s = c->context; 01220 } else if (!strcmp(var, "PRIORITY")) { 01221 snprintf(workspace, workspacelen, "%d", c->priority); 01222 s = workspace; 01223 } else if (!strcmp(var, "CHANNEL")) { 01224 s = c->name; 01225 } else if (!strcmp(var, "UNIQUEID")) { 01226 s = c->uniqueid; 01227 } else if (!strcmp(var, "HANGUPCAUSE")) { 01228 snprintf(workspace, workspacelen, "%d", c->hangupcause); 01229 s = workspace; 01230 } 01231 } 01232 if (s == ¬_found) { /* look for more */ 01233 if (!strcmp(var, "EPOCH")) { 01234 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 01235 s = workspace; 01236 } else if (!strcmp(var, "SYSTEMNAME")) { 01237 s = ast_config_AST_SYSTEM_NAME; 01238 } 01239 } 01240 /* if not found, look into chanvars or global vars */ 01241 for (i = 0; s == ¬_found && i < (sizeof(places) / sizeof(places[0])); i++) { 01242 struct ast_var_t *variables; 01243 if (!places[i]) 01244 continue; 01245 if (places[i] == &globals) 01246 ast_mutex_lock(&globalslock); 01247 AST_LIST_TRAVERSE(places[i], variables, entries) { 01248 if (strcasecmp(ast_var_name(variables), var)==0) { 01249 s = ast_var_value(variables); 01250 break; 01251 } 01252 } 01253 if (places[i] == &globals) 01254 ast_mutex_unlock(&globalslock); 01255 } 01256 if (s == ¬_found || s == NULL) 01257 *ret = NULL; 01258 else { 01259 if (s != workspace) 01260 ast_copy_string(workspace, s, workspacelen); 01261 *ret = workspace; 01262 if (need_substring) 01263 *ret = substring(*ret, offset, length, workspace, workspacelen); 01264 } 01265 01266 if (c) 01267 ast_channel_unlock(c); 01268 }
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 2692 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
02693 { 02694 int oldval = autofallthrough; 02695 autofallthrough = newval; 02696 return oldval; 02697 }
void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1773 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(), 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().
01774 { 01775 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 01776 }
void pbx_substitute_variables_varshead | ( | struct varshead * | headp, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1778 of file pbx.c.
References pbx_substitute_variables_helper_full().
Referenced by ast_add_extension2(), dundi_lookup_local(), and loopback_helper().
01779 { 01780 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 01781 }