#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/linkedlists.h"
Go to the source code of this file.
Data Structures | |
struct | ast_custom_function |
Data structure associated with a custom dialplan function. More... | |
struct | ast_pbx |
struct | ast_switch |
struct | ast_timing |
Defines | |
#define | AST_MAX_APP 32 |
#define | AST_PBX_KEEP 0 |
#define | AST_PBX_KEEPALIVE 10 |
Special return values from applications to the PBX {. | |
#define | AST_PBX_REPLACE 1 |
#define | PRIORITY_HINT -1 |
Typedefs | |
typedef int(*) | ast_state_cb_type (char *context, char *id, enum ast_extension_states state, void *data) |
Typedef for devicestate and hint callbacks. | |
typedef int( | ast_switch_f )(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
All switch functions have the same interface, so define a type for them. | |
Enumerations | |
enum | ast_extension_states { AST_EXTENSION_REMOVED = -2, AST_EXTENSION_DEACTIVATED = -1, AST_EXTENSION_NOT_INUSE = 0, AST_EXTENSION_INUSE = 1 << 0, AST_EXTENSION_BUSY = 1 << 1, AST_EXTENSION_UNAVAILABLE = 1 << 2, AST_EXTENSION_RINGING = 1 << 3, AST_EXTENSION_ONHOLD = 1 << 4 } |
Extension states. More... | |
enum | ast_pbx_result { AST_PBX_SUCCESS = 0, AST_PBX_FAILED = -1, AST_PBX_CALL_LIMIT = -2 } |
Functions | |
int | ast_active_calls (void) |
Retrieve the number of active calls. | |
int | ast_add_extension (const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar) |
Add and extension to an extension context. | |
int | ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar) |
Add an extension to an extension context, this time with an ast_context *. | |
int | ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority) |
int | ast_async_goto_by_name (const char *chan, const char *context, const char *exten, int priority) |
int | ast_async_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
int | ast_build_timing (struct ast_timing *i, const char *info) |
int | ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
Looks for a valid matching extension. | |
int | ast_check_timing (const struct ast_timing *i) |
int | ast_context_add_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
Add an ignorepat. | |
int | ast_context_add_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar) |
int | ast_context_add_include (const char *context, const char *include, const char *registrar) |
Add a context include. | |
int | ast_context_add_include2 (struct ast_context *con, const char *include, const char *registrar) |
Add a context include. | |
int | ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar) |
Add a switch. | |
int | ast_context_add_switch2 (struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar) |
Adds a switch (first param is a ast_context). | |
ast_context * | ast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar) |
Register a new context. | |
void | ast_context_destroy (struct ast_context *con, const char *registrar) |
Destroy a context (matches the specified context (or ANY context if NULL). | |
ast_context * | ast_context_find (const char *name) |
Find a context. | |
ast_context * | ast_context_find_or_create (struct ast_context **extcontexts, const char *name, const char *registrar) |
int | ast_context_lockmacro (const char *macrocontext) |
locks the macrolock in the given given context | |
int | ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar) |
Simply remove extension from context. | |
int | ast_context_remove_extension2 (struct ast_context *con, const char *extension, int priority, const char *registrar) |
This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return. | |
int | ast_context_remove_extension_callerid (const char *context, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar) |
int | ast_context_remove_extension_callerid2 (struct ast_context *con, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar) |
int | ast_context_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
int | ast_context_remove_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar) |
int | ast_context_remove_include (const char *context, const char *include, const char *registrar) |
Remove a context include. | |
int | ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar) |
Removes an include by an ast_context structure. | |
int | ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar) |
Remove a switch. | |
int | ast_context_remove_switch2 (struct ast_context *con, const char *sw, const char *data, const char *registrar) |
This function locks given context, removes switch, unlock context and return. | |
int | ast_context_unlockmacro (const char *macrocontext) |
Unlocks the macrolock in the given context. | |
int | ast_context_verify_includes (struct ast_context *con) |
Verifies includes in an ast_contect structure. | |
ast_custom_function * | ast_custom_function_find (const char *name) |
int | ast_custom_function_register (struct ast_custom_function *acf) |
Reigster a custom function. | |
int | ast_custom_function_unregister (struct ast_custom_function *acf) |
Unregister a custom function. | |
int | ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
Determine whether an extension exists. | |
int | ast_explicit_goto (struct ast_channel *chan, const char *context, const char *exten, int priority) |
int | ast_extension_close (const char *pattern, const char *data, int needmore) |
int | ast_extension_match (const char *pattern, const char *extension) |
Determine if a given extension matches a given pattern (in NXX format). | |
int | ast_extension_patmatch (const char *pattern, const char *data) |
int | ast_extension_state (struct ast_channel *c, const char *context, const char *exten) |
Uses hint and devicestate callback to get the state of an extension. | |
const char * | ast_extension_state2str (int extension_state) |
Return string representation of the state of an extension. | |
int | ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data) |
Registers a state change callback. | |
int | ast_extension_state_del (int id, ast_state_cb_type callback) |
Deletes a registered state change callback by ID. | |
int | ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid) |
Find the priority of an extension that has the specified label. | |
int | ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid) |
Find the priority of an extension that has the specified label. | |
int | ast_func_read (struct ast_channel *chan, char *function, char *workspace, size_t len) |
executes a read operation on a function | |
int | ast_func_write (struct ast_channel *chan, char *function, const char *value) |
executes a write operation on a function | |
const char * | ast_get_context_name (struct ast_context *con) |
const char * | ast_get_context_registrar (struct ast_context *c) |
const char * | ast_get_extension_app (struct ast_exten *e) |
void * | ast_get_extension_app_data (struct ast_exten *e) |
const char * | ast_get_extension_cidmatch (struct ast_exten *e) |
ast_context * | ast_get_extension_context (struct ast_exten *exten) |
const char * | ast_get_extension_label (struct ast_exten *e) |
int | ast_get_extension_matchcid (struct ast_exten *e) |
const char * | ast_get_extension_name (struct ast_exten *exten) |
int | ast_get_extension_priority (struct ast_exten *exten) |
const char * | ast_get_extension_registrar (struct ast_exten *e) |
int | ast_get_hint (char *hint, int maxlen, char *name, int maxnamelen, struct ast_channel *c, const char *context, const char *exten) |
If an extension exists, return non-zero. | |
const char * | ast_get_ignorepat_name (struct ast_ignorepat *ip) |
const char * | ast_get_ignorepat_registrar (struct ast_ignorepat *ip) |
const char * | ast_get_include_name (struct ast_include *include) |
const char * | ast_get_include_registrar (struct ast_include *i) |
const char * | ast_get_switch_data (struct ast_sw *sw) |
const char * | ast_get_switch_name (struct ast_sw *sw) |
const char * | ast_get_switch_registrar (struct ast_sw *sw) |
int | ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
void | ast_hint_state_changed (const char *device) |
int | ast_ignore_pattern (const char *context, const char *pattern) |
Checks to see if a number should be ignored. | |
int | ast_lock_context (struct ast_context *con) |
Locks a given context. | |
int | ast_lock_contexts (void) |
Locks the context list. | |
int | ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
Looks to see if adding anything to this extension might match something. (exists ^ canmatch). | |
void | ast_merge_contexts_and_delete (struct ast_context **extcontexts, const char *registrar) |
Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added. | |
int | ast_parseable_goto (struct ast_channel *chan, const char *goto_string) |
int | ast_pbx_outgoing_app (const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) |
int | ast_pbx_outgoing_exten (const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) |
enum ast_pbx_result | ast_pbx_run (struct ast_channel *c) |
Execute the PBX in the current thread. | |
enum ast_pbx_result | ast_pbx_start (struct ast_channel *c) |
Create a new thread and start the PBX. | |
int | ast_rdlock_contexts (void) |
int | ast_register_application (const char *app, int(*execute)(struct ast_channel *, void *), const char *synopsis, const char *description) |
Register an application. | |
int | ast_register_switch (struct ast_switch *sw) |
Register an alternative dialplan switch. | |
int | ast_spawn_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
Launch a new extension (i.e. new stack). | |
int | ast_unlock_context (struct ast_context *con) |
int | ast_unlock_contexts (void) |
Unlocks contexts. | |
int | ast_unregister_application (const char *app) |
Unregister an application. | |
void | ast_unregister_switch (struct ast_switch *sw) |
Unregister an alternative switch. | |
ast_exten * | ast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority) |
ast_ignorepat * | ast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip) |
ast_include * | ast_walk_context_includes (struct ast_context *con, struct ast_include *inc) |
ast_sw * | ast_walk_context_switches (struct ast_context *con, struct ast_sw *sw) |
ast_context * | ast_walk_contexts (struct ast_context *con) |
ast_exten * | ast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority) |
int | ast_wrlock_contexts (void) |
void | pbx_builtin_clear_globals (void) |
const char * | pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name) |
void | pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value) |
int | pbx_builtin_serialize_variables (struct ast_channel *chan, char *buf, size_t size) |
int | pbx_builtin_setvar (struct ast_channel *chan, void *data) |
void | pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value) |
int | pbx_checkcondition (const char *condition) |
Evaluate a condition. | |
int | pbx_exec (struct ast_channel *c, struct ast_app *app, void *data) |
Execute an application. | |
ast_app * | pbx_findapp (const char *app) |
Look up an application. | |
void | pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp) |
pbx_retrieve_variable: Support for Asterisk built-in variables --- | |
int | pbx_set_autofallthrough (int newval) |
void | pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count) |
void | pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count) |
Definition in file pbx.h.
#define AST_MAX_APP 32 |
Max length of an application
Definition at line 34 of file pbx.h.
Referenced by destroy_station(), handle_show_application(), handle_show_application_deprecated(), handle_show_function(), and handle_show_function_deprecated().
#define AST_PBX_KEEPALIVE 10 |
Special return values from applications to the PBX {.
Destroy the thread, but don't hang up the channel
Definition at line 40 of file pbx.h.
Referenced by __ast_pbx_run(), _macro_exec(), agi_handle_command(), and run_agi().
#define PRIORITY_HINT -1 |
} Special Priority for a hint
Definition at line 43 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 46 of file pbx.h.
00046 { 00047 AST_EXTENSION_REMOVED = -2, /*!< Extension removed */ 00048 AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */ 00049 AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */ 00050 AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */ 00051 AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */ 00052 AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */ 00053 AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */ 00054 AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */ 00055 };
enum ast_pbx_result |
Definition at line 213 of file pbx.h.
00213 { 00214 AST_PBX_SUCCESS = 0, 00215 AST_PBX_FAILED = -1, 00216 AST_PBX_CALL_LIMIT = -2, 00217 };
int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 2709 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02710 { 02711 return countcalls; 02712 }
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 4591 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().
04594 { 04595 int ret = -1; 04596 struct ast_context *c = find_context_locked(context); 04597 04598 if (c) { 04599 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04600 application, data, datad, registrar); 04601 ast_unlock_contexts(); 04602 } 04603 return ret; 04604 }
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 4806 of file pbx.c.
References add_pri(), ast_exten::app, ast_add_hint(), ast_calloc, AST_LIST_FIRST, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_exten::cidmatch, ast_exten::data, ast_exten::datad, el, errno, ext_cmp(), ext_strncpy(), ast_exten::exten, globals, globalslock, ast_exten::label, ast_context::lock, ast_exten::matchcid, ast_context::name, ast_exten::next, option_verbose, ast_exten::parent, pbx_substitute_variables_varshead(), ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, ast_context::root, ast_exten::stuff, VAR_BUF_SIZE, and VERBOSE_PREFIX_3.
Referenced by add_extensions(), ast_add_extension(), do_parking_thread(), park_call_full(), pbx_load_config(), and pbx_load_users().
04810 { 04811 /* 04812 * Sort extensions (or patterns) according to the rules indicated above. 04813 * These are implemented by the function ext_cmp()). 04814 * All priorities for the same ext/pattern/cid are kept in a list, 04815 * using the 'peer' field as a link field.. 04816 */ 04817 struct ast_exten *tmp, *e, *el = NULL; 04818 int res; 04819 int length; 04820 char *p; 04821 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04822 04823 /* if we are adding a hint, and there are global variables, and the hint 04824 contains variable references, then expand them 04825 */ 04826 ast_mutex_lock(&globalslock); 04827 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04828 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04829 application = expand_buf; 04830 } 04831 ast_mutex_unlock(&globalslock); 04832 04833 length = sizeof(struct ast_exten); 04834 length += strlen(extension) + 1; 04835 length += strlen(application) + 1; 04836 if (label) 04837 length += strlen(label) + 1; 04838 if (callerid) 04839 length += strlen(callerid) + 1; 04840 else 04841 length ++; /* just the '\0' */ 04842 04843 /* Be optimistic: Build the extension structure first */ 04844 if (!(tmp = ast_calloc(1, length))) 04845 return -1; 04846 04847 /* use p as dst in assignments, as the fields are const char * */ 04848 p = tmp->stuff; 04849 if (label) { 04850 tmp->label = p; 04851 strcpy(p, label); 04852 p += strlen(label) + 1; 04853 } 04854 tmp->exten = p; 04855 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04856 tmp->priority = priority; 04857 tmp->cidmatch = p; /* but use p for assignments below */ 04858 if (callerid) { 04859 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04860 tmp->matchcid = 1; 04861 } else { 04862 *p++ = '\0'; 04863 tmp->matchcid = 0; 04864 } 04865 tmp->app = p; 04866 strcpy(p, application); 04867 tmp->parent = con; 04868 tmp->data = data; 04869 tmp->datad = datad; 04870 tmp->registrar = registrar; 04871 04872 ast_mutex_lock(&con->lock); 04873 res = 0; /* some compilers will think it is uninitialized otherwise */ 04874 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04875 res = ext_cmp(e->exten, tmp->exten); 04876 if (res == 0) { /* extension match, now look at cidmatch */ 04877 if (!e->matchcid && !tmp->matchcid) 04878 res = 0; 04879 else if (tmp->matchcid && !e->matchcid) 04880 res = 1; 04881 else if (e->matchcid && !tmp->matchcid) 04882 res = -1; 04883 else 04884 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04885 } 04886 if (res >= 0) 04887 break; 04888 } 04889 if (e && res == 0) { /* exact match, insert in the pri chain */ 04890 res = add_pri(con, tmp, el, e, replace); 04891 ast_mutex_unlock(&con->lock); 04892 if (res < 0) { 04893 errno = EEXIST; /* XXX do we care ? */ 04894 return 0; /* XXX should we return -1 maybe ? */ 04895 } 04896 } else { 04897 /* 04898 * not an exact match, this is the first entry with this pattern, 04899 * so insert in the main list right before 'e' (if any) 04900 */ 04901 tmp->next = e; 04902 if (el) 04903 el->next = tmp; 04904 else 04905 con->root = tmp; 04906 ast_mutex_unlock(&con->lock); 04907 if (tmp->priority == PRIORITY_HINT) 04908 ast_add_hint(tmp); 04909 } 04910 if (option_debug) { 04911 if (tmp->matchcid) { 04912 if (option_debug) 04913 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04914 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04915 } else { 04916 if (option_debug) 04917 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04918 tmp->exten, tmp->priority, con->name); 04919 } 04920 } 04921 if (option_verbose > 2) { 04922 if (tmp->matchcid) { 04923 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04924 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04925 } else { 04926 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04927 tmp->exten, tmp->priority, con->name); 04928 } 04929 } 04930 return 0; 04931 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4629 of file pbx.c.
References ast_channel::_state, ast_channel::accountcode, ast_channel::amaflags, ast_cdr_discard(), ast_cdr_dup(), ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_unlock, ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_pbx_start(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_channel::cdr, ast_channel::context, ast_channel::exten, LOG_WARNING, ast_channel::name, ast_channel::pbx, ast_channel::readformat, S_OR, and ast_channel::writeformat.
Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), console_transfer_deprecated(), dahdi_handle_dtmfup(), handle_request_bye(), handle_request_refer(), process_ast_dsp(), and socket_process().
04630 { 04631 int res = 0; 04632 04633 ast_channel_lock(chan); 04634 04635 if (chan->pbx) { /* This channel is currently in the PBX */ 04636 ast_explicit_goto(chan, context, exten, priority); 04637 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04638 } else { 04639 /* In order to do it when the channel doesn't really exist within 04640 the PBX, we have to make a new channel, masquerade, and start the PBX 04641 at the new location */ 04642 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04643 if (!tmpchan) { 04644 res = -1; 04645 } else { 04646 if (chan->cdr) { 04647 ast_cdr_discard(tmpchan->cdr); 04648 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 04649 } 04650 /* Make formats okay */ 04651 tmpchan->readformat = chan->readformat; 04652 tmpchan->writeformat = chan->writeformat; 04653 /* Setup proper location */ 04654 ast_explicit_goto(tmpchan, 04655 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04656 04657 /* Masquerade into temp channel */ 04658 if (ast_channel_masquerade(tmpchan, chan)) { 04659 /* Failed to set up the masquerade. It's probably chan_local 04660 * in the middle of optimizing itself out. Sad. :( */ 04661 ast_hangup(tmpchan); 04662 tmpchan = NULL; 04663 res = -1; 04664 } else { 04665 /* Grab the locks and get going */ 04666 ast_channel_lock(tmpchan); 04667 ast_do_masquerade(tmpchan); 04668 ast_channel_unlock(tmpchan); 04669 /* Start the PBX going on our stolen channel */ 04670 if (ast_pbx_start(tmpchan)) { 04671 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04672 ast_hangup(tmpchan); 04673 res = -1; 04674 } 04675 } 04676 } 04677 } 04678 ast_channel_unlock(chan); 04679 return res; 04680 }
int ast_async_goto_by_name | ( | const char * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4682 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04683 { 04684 struct ast_channel *chan; 04685 int res = -1; 04686 04687 chan = ast_get_channel_by_name_locked(channame); 04688 if (chan) { 04689 res = ast_async_goto(chan, context, exten, priority); 04690 ast_channel_unlock(chan); 04691 } 04692 return res; 04693 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6483 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06484 { 06485 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06486 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info | |||
) |
Definition at line 4269 of file pbx.c.
References ast_copy_string(), ast_strlen_zero(), ast_timing::daymask, days, ast_timing::dowmask, get_range(), get_timerange(), ast_timing::monthmask, and months.
Referenced by ast_context_add_include2(), iftime(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
04270 { 04271 char info_save[256]; 04272 char *info; 04273 04274 /* Check for empty just in case */ 04275 if (ast_strlen_zero(info_in)) 04276 return 0; 04277 /* make a copy just in case we were passed a static string */ 04278 ast_copy_string(info_save, info_in, sizeof(info_save)); 04279 info = info_save; 04280 /* Assume everything except time */ 04281 i->monthmask = 0xfff; /* 12 bits */ 04282 i->daymask = 0x7fffffffU; /* 31 bits */ 04283 i->dowmask = 0x7f; /* 7 bits */ 04284 /* on each call, use strsep() to move info to the next argument */ 04285 get_timerange(i, strsep(&info, "|")); 04286 if (info) 04287 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04288 if (info) 04289 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04290 if (info) 04291 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04292 return 1; 04293 }
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 2333 of file pbx.c.
References E_CANMATCH, and pbx_extension_helper().
Referenced by background_detect_exec(), cb_events(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), handle_link_data(), handle_link_phone_dtmf(), local_dtmf_helper(), loopback_canmatch(), mgcp_ss(), phone_check_exception(), skinny_ss(), ss_thread(), and valid_exit().
02334 { 02335 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH); 02336 }
int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 4295 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().
04296 { 04297 struct tm tm; 04298 time_t t = time(NULL); 04299 04300 ast_localtime(&t, &tm, NULL); 04301 04302 /* If it's not the right month, return */ 04303 if (!(i->monthmask & (1 << tm.tm_mon))) 04304 return 0; 04305 04306 /* If it's not that time of the month.... */ 04307 /* Warning, tm_mday has range 1..31! */ 04308 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04309 return 0; 04310 04311 /* If it's not the right day of the week */ 04312 if (!(i->dowmask & (1 << tm.tm_wday))) 04313 return 0; 04314 04315 /* Sanity check the hour just to be safe */ 04316 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04317 ast_log(LOG_WARNING, "Insane time...\n"); 04318 return 0; 04319 } 04320 04321 /* Now the tough part, we calculate if it fits 04322 in the right time based on min/hour */ 04323 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04324 return 0; 04325 04326 /* If we got this far, then we're good */ 04327 return 1; 04328 }
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 4522 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().
04523 { 04524 int ret = -1; 04525 struct ast_context *c = find_context_locked(context); 04526 04527 if (c) { 04528 ret = ast_context_add_ignorepat2(c, value, registrar); 04529 ast_unlock_contexts(); 04530 } 04531 return ret; 04532 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4534 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().
04535 { 04536 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04537 int length; 04538 char *pattern; 04539 length = sizeof(struct ast_ignorepat); 04540 length += strlen(value) + 1; 04541 if (!(ignorepat = ast_calloc(1, length))) 04542 return -1; 04543 /* The cast to char * is because we need to write the initial value. 04544 * The field is not supposed to be modified otherwise. Also, gcc 4.2 04545 * sees the cast as dereferencing a type-punned pointer and warns about 04546 * it. This is the workaround (we're telling gcc, yes, that's really 04547 * what we wanted to do). 04548 */ 04549 pattern = (char *) ignorepat->pattern; 04550 strcpy(pattern, value); 04551 ignorepat->next = NULL; 04552 ignorepat->registrar = registrar; 04553 ast_mutex_lock(&con->lock); 04554 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04555 ignorepatl = ignorepatc; 04556 if (!strcasecmp(ignorepatc->pattern, value)) { 04557 /* Already there */ 04558 ast_mutex_unlock(&con->lock); 04559 errno = EEXIST; 04560 return -1; 04561 } 04562 } 04563 if (ignorepatl) 04564 ignorepatl->next = ignorepat; 04565 else 04566 con->ignorepats = ignorepat; 04567 ast_mutex_unlock(&con->lock); 04568 return 0; 04569 04570 }
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 4075 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().
04076 { 04077 int ret = -1; 04078 struct ast_context *c = find_context_locked(context); 04079 04080 if (c) { 04081 ret = ast_context_add_include2(c, include, registrar); 04082 ast_unlock_contexts(); 04083 } 04084 return ret; 04085 }
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 4337 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().
04339 { 04340 struct ast_include *new_include; 04341 char *c; 04342 struct ast_include *i, *il = NULL; /* include, include_last */ 04343 int length; 04344 char *p; 04345 04346 length = sizeof(struct ast_include); 04347 length += 2 * (strlen(value) + 1); 04348 04349 /* allocate new include structure ... */ 04350 if (!(new_include = ast_calloc(1, length))) 04351 return -1; 04352 /* Fill in this structure. Use 'p' for assignments, as the fields 04353 * in the structure are 'const char *' 04354 */ 04355 p = new_include->stuff; 04356 new_include->name = p; 04357 strcpy(p, value); 04358 p += strlen(value) + 1; 04359 new_include->rname = p; 04360 strcpy(p, value); 04361 /* Strip off timing info, and process if it is there */ 04362 if ( (c = strchr(p, '|')) ) { 04363 *c++ = '\0'; 04364 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04365 } 04366 new_include->next = NULL; 04367 new_include->registrar = registrar; 04368 04369 ast_mutex_lock(&con->lock); 04370 04371 /* ... go to last include and check if context is already included too... */ 04372 for (i = con->includes; i; i = i->next) { 04373 if (!strcasecmp(i->name, new_include->name)) { 04374 free(new_include); 04375 ast_mutex_unlock(&con->lock); 04376 errno = EEXIST; 04377 return -1; 04378 } 04379 il = i; 04380 } 04381 04382 /* ... include new context into context list, unlock, return */ 04383 if (il) 04384 il->next = new_include; 04385 else 04386 con->includes = new_include; 04387 if (option_verbose > 2) 04388 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04389 ast_mutex_unlock(&con->lock); 04390 04391 return 0; 04392 }
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 4399 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04400 { 04401 int ret = -1; 04402 struct ast_context *c = find_context_locked(context); 04403 04404 if (c) { /* found, add switch to this context */ 04405 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04406 ast_unlock_contexts(); 04407 } 04408 return ret; 04409 }
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 4418 of file pbx.c.
References ast_context::alts, ast_calloc, ast_get_context_name(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_sw::data, errno, ast_sw::eval, free, store_hint::list, ast_context::lock, ast_sw::name, option_verbose, ast_sw::registrar, ast_sw::stuff, and VERBOSE_PREFIX_3.
Referenced by ast_context_add_switch(), and pbx_load_config().
04420 { 04421 struct ast_sw *new_sw; 04422 struct ast_sw *i; 04423 int length; 04424 char *p; 04425 04426 length = sizeof(struct ast_sw); 04427 length += strlen(value) + 1; 04428 if (data) 04429 length += strlen(data); 04430 length++; 04431 04432 /* allocate new sw structure ... */ 04433 if (!(new_sw = ast_calloc(1, length))) 04434 return -1; 04435 /* ... fill in this structure ... */ 04436 p = new_sw->stuff; 04437 new_sw->name = p; 04438 strcpy(new_sw->name, value); 04439 p += strlen(value) + 1; 04440 new_sw->data = p; 04441 if (data) { 04442 strcpy(new_sw->data, data); 04443 p += strlen(data) + 1; 04444 } else { 04445 strcpy(new_sw->data, ""); 04446 p++; 04447 } 04448 new_sw->eval = eval; 04449 new_sw->registrar = registrar; 04450 04451 /* ... try to lock this context ... */ 04452 ast_mutex_lock(&con->lock); 04453 04454 /* ... go to last sw and check if context is already swd too... */ 04455 AST_LIST_TRAVERSE(&con->alts, i, list) { 04456 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04457 free(new_sw); 04458 ast_mutex_unlock(&con->lock); 04459 errno = EEXIST; 04460 return -1; 04461 } 04462 } 04463 04464 /* ... sw new context into context list, unlock, return */ 04465 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04466 04467 if (option_verbose > 2) 04468 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04469 04470 ast_mutex_unlock(&con->lock); 04471 04472 return 0; 04473 }
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 3945 of file pbx.c.
References __ast_context_create().
Referenced by do_parking_thread(), park_call_full(), and set_config().
03946 { 03947 return __ast_context_create(extcontexts, name, registrar, 0); 03948 }
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 5387 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().
05388 { 05389 ast_wrlock_contexts(); 05390 __ast_context_destroy(con,registrar); 05391 ast_unlock_contexts(); 05392 }
struct ast_context* ast_context_find | ( | const char * | name | ) |
Find a context.
name | name of the context to find |
Definition at line 918 of file pbx.c.
References ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::name.
Referenced by _macro_exec(), ast_context_verify_includes(), ast_ignore_pattern(), cleanup_stale_contexts(), do_parking_thread(), park_call_full(), park_exec(), register_peer_exten(), and set_config().
00919 { 00920 struct ast_context *tmp = NULL; 00921 00922 ast_rdlock_contexts(); 00923 00924 while ( (tmp = ast_walk_contexts(tmp)) ) { 00925 if (!name || !strcasecmp(name, tmp->name)) 00926 break; 00927 } 00928 00929 ast_unlock_contexts(); 00930 00931 return tmp; 00932 }
struct ast_context* ast_context_find_or_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar | |||
) |
Definition at line 3950 of file pbx.c.
References __ast_context_create().
Referenced by pbx_load_config(), and pbx_load_users().
03951 { 03952 return __ast_context_create(extcontexts, name, registrar, 1); 03953 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 2946 of file pbx.c.
References ast_get_context_name(), ast_mutex_lock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::macrolock.
Referenced by _macro_exec().
02947 { 02948 struct ast_context *c = NULL; 02949 int ret = -1; 02950 02951 ast_rdlock_contexts(); 02952 02953 while ((c = ast_walk_contexts(c))) { 02954 if (!strcmp(ast_get_context_name(c), context)) { 02955 ret = 0; 02956 break; 02957 } 02958 } 02959 02960 ast_unlock_contexts(); 02961 02962 /* if we found context, lock macrolock */ 02963 if (ret == 0) 02964 ret = ast_mutex_lock(&c->macrolock); 02965 02966 return ret; 02967 }
int ast_context_remove_extension | ( | const char * | context, | |
const char * | extension, | |||
int | priority, | |||
const char * | registrar | |||
) |
Simply remove extension from context.
context | context to remove extension from | |
extension | which extension to remove | |
priority | priority of extension to remove (0 to remove all) | |
callerid | NULL to remove all; non-NULL to match a single record per priority | |
matchcid | non-zero to match callerid element (if non-NULL); 0 to match default case | |
registrar | registrar of the extension |
0 | on success | |
-1 | on failure |
Definition at line 2847 of file pbx.c.
References ast_context_remove_extension_callerid().
Referenced by destroy_station(), destroy_trunk(), and register_peer_exten().
02848 { 02849 return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar); 02850 }
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 2874 of file pbx.c.
References ast_context_remove_extension_callerid2().
Referenced by do_parking_thread(), and park_exec().
02875 { 02876 return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar); 02877 }
int ast_context_remove_extension_callerid | ( | const char * | context, | |
const char * | extension, | |||
int | priority, | |||
const char * | callerid, | |||
int | matchcid, | |||
const char * | registrar | |||
) |
Definition at line 2852 of file pbx.c.
References ast_context_remove_extension_callerid2(), ast_unlock_contexts(), and find_context_locked().
Referenced by ast_context_remove_extension(), handle_context_remove_extension(), and handle_context_remove_extension_deprecated().
02853 { 02854 int ret = -1; /* default error return */ 02855 struct ast_context *c = find_context_locked(context); 02856 02857 if (c) { /* ... remove extension ... */ 02858 ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar); 02859 ast_unlock_contexts(); 02860 } 02861 return ret; 02862 }
int ast_context_remove_extension_callerid2 | ( | struct ast_context * | con, | |
const char * | extension, | |||
int | priority, | |||
const char * | callerid, | |||
int | matchcid, | |||
const char * | registrar | |||
) |
Definition at line 2879 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_exten::cidmatch, destroy_exten(), ast_exten::exten, exten, ast_context::lock, ast_exten::next, ast_exten::peer, ast_exten::priority, ast_exten::registrar, and ast_context::root.
Referenced by ast_context_remove_extension2(), and ast_context_remove_extension_callerid().
02880 { 02881 struct ast_exten *exten, *prev_exten = NULL; 02882 struct ast_exten *peer; 02883 struct ast_exten *previous_peer = NULL; 02884 struct ast_exten *next_peer = NULL; 02885 int found = 0; 02886 02887 ast_mutex_lock(&con->lock); 02888 02889 /* scan the extension list to find first matching extension-registrar */ 02890 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02891 if (!strcmp(exten->exten, extension) && 02892 (!registrar || !strcmp(exten->registrar, registrar))) 02893 break; 02894 } 02895 if (!exten) { 02896 /* we can't find right extension */ 02897 ast_mutex_unlock(&con->lock); 02898 return -1; 02899 } 02900 02901 /* scan the priority list to remove extension with exten->priority == priority */ 02902 for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next; 02903 peer && !strcmp(peer->exten, extension); 02904 peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) { 02905 if ((priority == 0 || peer->priority == priority) && 02906 (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) && 02907 (!registrar || !strcmp(peer->registrar, registrar) )) { 02908 found = 1; 02909 02910 /* we are first priority extension? */ 02911 if (!previous_peer) { 02912 /* 02913 * We are first in the priority chain, so must update the extension chain. 02914 * The next node is either the next priority or the next extension 02915 */ 02916 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02917 02918 if (!prev_exten) { /* change the root... */ 02919 con->root = next_node; 02920 } else { 02921 prev_exten->next = next_node; /* unlink */ 02922 } 02923 if (peer->peer) { /* update the new head of the pri list */ 02924 peer->peer->next = peer->next; 02925 } 02926 } else { /* easy, we are not first priority in extension */ 02927 previous_peer->peer = peer->peer; 02928 } 02929 02930 /* now, free whole priority extension */ 02931 destroy_exten(peer); 02932 } else { 02933 previous_peer = peer; 02934 } 02935 } 02936 ast_mutex_unlock(&con->lock); 02937 return found ? 0 : -1; 02938 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4479 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().
04480 { 04481 int ret = -1; 04482 struct ast_context *c = find_context_locked(context); 04483 04484 if (c) { 04485 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04486 ast_unlock_contexts(); 04487 } 04488 return ret; 04489 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4491 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().
04492 { 04493 struct ast_ignorepat *ip, *ipl = NULL; 04494 04495 ast_mutex_lock(&con->lock); 04496 04497 for (ip = con->ignorepats; ip; ip = ip->next) { 04498 if (!strcmp(ip->pattern, ignorepat) && 04499 (!registrar || (registrar == ip->registrar))) { 04500 if (ipl) { 04501 ipl->next = ip->next; 04502 free(ip); 04503 } else { 04504 con->ignorepats = ip->next; 04505 free(ip); 04506 } 04507 ast_mutex_unlock(&con->lock); 04508 return 0; 04509 } 04510 ipl = ip; 04511 } 04512 04513 ast_mutex_unlock(&con->lock); 04514 errno = EINVAL; 04515 return -1; 04516 }
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 2743 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().
02744 { 02745 int ret = -1; 02746 struct ast_context *c = find_context_locked(context); 02747 02748 if (c) { 02749 /* found, remove include from this context ... */ 02750 ret = ast_context_remove_include2(c, include, registrar); 02751 ast_unlock_contexts(); 02752 } 02753 return ret; 02754 }
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 2764 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().
02765 { 02766 struct ast_include *i, *pi = NULL; 02767 int ret = -1; 02768 02769 ast_mutex_lock(&con->lock); 02770 02771 /* find our include */ 02772 for (i = con->includes; i; pi = i, i = i->next) { 02773 if (!strcmp(i->name, include) && 02774 (!registrar || !strcmp(i->registrar, registrar))) { 02775 /* remove from list */ 02776 if (pi) 02777 pi->next = i->next; 02778 else 02779 con->includes = i->next; 02780 /* free include and return */ 02781 free(i); 02782 ret = 0; 02783 break; 02784 } 02785 } 02786 02787 ast_mutex_unlock(&con->lock); 02788 return ret; 02789 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 2796 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
02797 { 02798 int ret = -1; /* default error return */ 02799 struct ast_context *c = find_context_locked(context); 02800 02801 if (c) { 02802 /* remove switch from this context ... */ 02803 ret = ast_context_remove_switch2(c, sw, data, registrar); 02804 ast_unlock_contexts(); 02805 } 02806 return ret; 02807 }
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 2817 of file pbx.c.
References ast_context::alts, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), ast_sw::data, free, ast_sw::list, ast_context::lock, ast_sw::name, and ast_sw::registrar.
Referenced by ast_context_remove_switch().
02818 { 02819 struct ast_sw *i; 02820 int ret = -1; 02821 02822 ast_mutex_lock(&con->lock); 02823 02824 /* walk switches */ 02825 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02826 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02827 (!registrar || !strcmp(i->registrar, registrar))) { 02828 /* found, remove from list */ 02829 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02830 free(i); /* free switch and return */ 02831 ret = 0; 02832 break; 02833 } 02834 } 02835 AST_LIST_TRAVERSE_SAFE_END 02836 02837 ast_mutex_unlock(&con->lock); 02838 02839 return ret; 02840 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 2974 of file pbx.c.
References ast_get_context_name(), ast_mutex_unlock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::macrolock.
Referenced by _macro_exec().
02975 { 02976 struct ast_context *c = NULL; 02977 int ret = -1; 02978 02979 ast_rdlock_contexts(); 02980 02981 while ((c = ast_walk_contexts(c))) { 02982 if (!strcmp(ast_get_context_name(c), context)) { 02983 ret = 0; 02984 break; 02985 } 02986 } 02987 02988 ast_unlock_contexts(); 02989 02990 /* if we found context, unlock macrolock */ 02991 if (ret == 0) 02992 ret = ast_mutex_unlock(&c->macrolock); 02993 02994 return ret; 02995 }
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 6440 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().
06441 { 06442 struct ast_include *inc = NULL; 06443 int res = 0; 06444 06445 while ( (inc = ast_walk_context_includes(con, inc)) ) { 06446 if (ast_context_find(inc->rname)) 06447 continue; 06448 06449 res = -1; 06450 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 06451 ast_get_context_name(con), inc->rname); 06452 break; 06453 } 06454 06455 return res; 06456 }
struct ast_custom_function* ast_custom_function_find | ( | const char * | name | ) |
Definition at line 1480 of file pbx.c.
References ast_custom_function::acflist, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_custom_function::name.
Referenced by ast_custom_function_register(), ast_func_read(), ast_func_write(), handle_show_function(), and handle_show_function_deprecated().
01481 { 01482 struct ast_custom_function *acf = NULL; 01483 01484 AST_LIST_LOCK(&acf_root); 01485 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01486 if (!strcmp(name, acf->name)) 01487 break; 01488 } 01489 AST_LIST_UNLOCK(&acf_root); 01490 01491 return acf; 01492 }
int ast_custom_function_register | ( | struct ast_custom_function * | acf | ) |
Reigster a custom function.
Definition at line 1516 of file pbx.c.
References ast_custom_function::acflist, ast_custom_function_find(), AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), LOG_ERROR, ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by load_module(), odbc_load_module(), and reload().
01517 { 01518 struct ast_custom_function *cur; 01519 01520 if (!acf) 01521 return -1; 01522 01523 AST_LIST_LOCK(&acf_root); 01524 01525 if (ast_custom_function_find(acf->name)) { 01526 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01527 AST_LIST_UNLOCK(&acf_root); 01528 return -1; 01529 } 01530 01531 /* Store in alphabetical order */ 01532 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01533 if (strcasecmp(acf->name, cur->name) < 0) { 01534 AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist); 01535 break; 01536 } 01537 } 01538 AST_LIST_TRAVERSE_SAFE_END 01539 if (!cur) 01540 AST_LIST_INSERT_TAIL(&acf_root, acf, acflist); 01541 01542 AST_LIST_UNLOCK(&acf_root); 01543 01544 if (option_verbose > 1) 01545 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01546 01547 return 0; 01548 }
int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Unregister a custom function.
Definition at line 1494 of file pbx.c.
References ast_custom_function::acflist, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by odbc_unload_module(), reload(), and unload_module().
01495 { 01496 struct ast_custom_function *cur; 01497 01498 if (!acf) 01499 return -1; 01500 01501 AST_LIST_LOCK(&acf_root); 01502 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01503 if (cur == acf) { 01504 AST_LIST_REMOVE_CURRENT(&acf_root, acflist); 01505 if (option_verbose > 1) 01506 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01507 break; 01508 } 01509 } 01510 AST_LIST_TRAVERSE_SAFE_END 01511 AST_LIST_UNLOCK(&acf_root); 01512 01513 return acf ? 0 : -1; 01514 }
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 2318 of file pbx.c.
References E_MATCH, and pbx_extension_helper().
Referenced by __ast_goto_if_exists(), __ast_pbx_run(), __login_exec(), _macro_exec(), agentmonitoroutgoing_exec(), answer_call(), ast_app_dtget(), ast_bridge_call(), ast_pbx_outgoing_exten(), builtin_blindtransfer(), cb_events(), conf_run(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), dahdi_handle_dtmfup(), disa_exec(), do_atxfer(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), handle_stimulus_message(), leave_voicemail(), local_alloc(), local_call(), local_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), misdn_overlap_dial_task(), park_space_reserve(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), pri_dchannel(), process_ast_dsp(), register_peer_exten(), skinny_ss(), socket_process(), ss_thread(), and waitstream_core().
02319 { 02320 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH); 02321 }
int ast_explicit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4606 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_FLAG_IN_AUTOLOOP, ast_strlen_zero(), ast_test_flag, ast_channel::context, ast_channel::exten, and ast_channel::priority.
Referenced by __ast_goto_if_exists(), ast_async_goto(), ast_parseable_goto(), disa_exec(), do_atxfer(), and handle_setpriority().
04607 { 04608 if (!chan) 04609 return -1; 04610 04611 ast_channel_lock(chan); 04612 04613 if (!ast_strlen_zero(context)) 04614 ast_copy_string(chan->context, context, sizeof(chan->context)); 04615 if (!ast_strlen_zero(exten)) 04616 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04617 if (priority > -1) { 04618 chan->priority = priority; 04619 /* see flag description in channel.h for explanation */ 04620 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04621 chan->priority--; 04622 } 04623 04624 ast_channel_unlock(chan); 04625 04626 return 0; 04627 }
int ast_extension_close | ( | const char * | pattern, | |
const char * | data, | |||
int | needmore | |||
) |
Definition at line 911 of file pbx.c.
References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.
Referenced by realtime_switch_common().
00912 { 00913 if (needmore != E_MATCHMORE && needmore != E_CANMATCH) 00914 ast_log(LOG_WARNING, "invalid argument %d\n", needmore); 00915 return extension_match_core(pattern, data, needmore); 00916 }
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 906 of file pbx.c.
References E_MATCH, and extension_match_core().
Referenced by ast_ignore_pattern(), do_say(), find_matching_priority(), loopback_canmatch(), loopback_exists(), loopback_matchmore(), matchcid(), misdn_cfg_is_msn_valid(), realtime_switch_common(), and show_dialplan_helper().
00907 { 00908 return extension_match_core(pattern, data, E_MATCH); 00909 }
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 2040 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), and handle_request_subscribe().
02041 { 02042 struct ast_exten *e; 02043 02044 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 02045 if (!e) 02046 return -1; /* No hint, return -1 */ 02047 02048 return ast_extension_state2(e); /* Check all devices in the hint */ 02049 }
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 2028 of file pbx.c.
References extension_states.
Referenced by cb_extensionstate(), handle_request_subscribe(), and handle_show_hints().
02029 { 02030 int i; 02031 02032 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 02033 if (extension_states[i].extension_state == extension_state) 02034 return extension_states[i].text; 02035 } 02036 return "Unknown"; 02037 }
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 2097 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().
02099 { 02100 struct ast_hint *hint; 02101 struct ast_state_cb *cblist; 02102 struct ast_exten *e; 02103 02104 /* If there's no context and extension: add callback to statecbs list */ 02105 if (!context && !exten) { 02106 AST_LIST_LOCK(&hints); 02107 02108 for (cblist = statecbs; cblist; cblist = cblist->next) { 02109 if (cblist->callback == callback) { 02110 cblist->data = data; 02111 AST_LIST_UNLOCK(&hints); 02112 return 0; 02113 } 02114 } 02115 02116 /* Now insert the callback */ 02117 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02118 AST_LIST_UNLOCK(&hints); 02119 return -1; 02120 } 02121 cblist->id = 0; 02122 cblist->callback = callback; 02123 cblist->data = data; 02124 02125 cblist->next = statecbs; 02126 statecbs = cblist; 02127 02128 AST_LIST_UNLOCK(&hints); 02129 return 0; 02130 } 02131 02132 if (!context || !exten) 02133 return -1; 02134 02135 /* This callback type is for only one hint, so get the hint */ 02136 e = ast_hint_extension(NULL, context, exten); 02137 if (!e) { 02138 return -1; 02139 } 02140 02141 /* Find the hint in the list of hints */ 02142 AST_LIST_LOCK(&hints); 02143 02144 AST_LIST_TRAVERSE(&hints, hint, list) { 02145 if (hint->exten == e) 02146 break; 02147 } 02148 02149 if (!hint) { 02150 /* We have no hint, sorry */ 02151 AST_LIST_UNLOCK(&hints); 02152 return -1; 02153 } 02154 02155 /* Now insert the callback in the callback list */ 02156 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02157 AST_LIST_UNLOCK(&hints); 02158 return -1; 02159 } 02160 cblist->id = stateid++; /* Unique ID for this callback */ 02161 cblist->callback = callback; /* Pointer to callback routine */ 02162 cblist->data = data; /* Data for the callback */ 02163 02164 cblist->next = hint->callbacks; 02165 hint->callbacks = cblist; 02166 02167 AST_LIST_UNLOCK(&hints); 02168 return cblist->id; 02169 }
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 2172 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_hint::callbacks, free, ast_sw::list, ast_state_cb::next, and statecbs.
Referenced by __sip_destroy(), and handle_request_subscribe().
02173 { 02174 struct ast_state_cb **p_cur = NULL; /* address of pointer to us */ 02175 int ret = -1; 02176 02177 if (!id && !callback) 02178 return -1; 02179 02180 AST_LIST_LOCK(&hints); 02181 02182 if (!id) { /* id == 0 is a callback without extension */ 02183 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) { 02184 if ((*p_cur)->callback == callback) 02185 break; 02186 } 02187 } else { /* callback with extension, find the callback based on ID */ 02188 struct ast_hint *hint; 02189 AST_LIST_TRAVERSE(&hints, hint, list) { 02190 for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) { 02191 if ((*p_cur)->id == id) 02192 break; 02193 } 02194 if (*p_cur) /* found in the inner loop */ 02195 break; 02196 } 02197 } 02198 if (p_cur && *p_cur) { 02199 struct ast_state_cb *cur = *p_cur; 02200 *p_cur = cur->next; 02201 free(cur); 02202 ret = 0; 02203 } 02204 AST_LIST_UNLOCK(&hints); 02205 return ret; 02206 }
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 2323 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().
02324 { 02325 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL); 02326 }
int ast_findlabel_extension2 | ( | struct ast_channel * | c, | |
struct ast_context * | con, | |||
const char * | exten, | |||
const char * | label, | |||
const char * | callerid | |||
) |
Find the priority of an extension that has the specified label.
This function is the same as ast_findlabel_extension, except that it accepts a pointer to an ast_context structure to specify the context instead of the name of the context. Otherwise, the functions behave the same.
Definition at line 2328 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
02329 { 02330 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL); 02331 }
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 1570 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().
01571 { 01572 char *args = func_args(function); 01573 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01574 01575 if (acfptr == NULL) 01576 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01577 else if (!acfptr->read) 01578 ast_log(LOG_ERROR, "Function %s cannot be read\n", function); 01579 else 01580 return acfptr->read(chan, function, args, workspace, len); 01581 return -1; 01582 }
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 1584 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().
01585 { 01586 char *args = func_args(function); 01587 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01588 01589 if (acfptr == NULL) 01590 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01591 else if (!acfptr->write) 01592 ast_log(LOG_ERROR, "Function %s cannot be written to\n", function); 01593 else 01594 return acfptr->write(chan, function, args, value); 01595 01596 return -1; 01597 }
const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 6297 of file pbx.c.
References ast_context::name.
Referenced by _macro_exec(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_context_verify_includes(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper().
06298 { 06299 return con ? con->name : NULL; 06300 }
const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 6335 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06336 { 06337 return c ? c->registrar : NULL; 06338 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6365 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().
06366 { 06367 return e ? e->app : NULL; 06368 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6370 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06371 { 06372 return e ? e->data : NULL; 06373 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6360 of file pbx.c.
References ast_exten::cidmatch.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), and handle_save_dialplan().
06361 { 06362 return e ? e->cidmatch : NULL; 06363 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
const char* ast_get_extension_label | ( | struct ast_exten * | e | ) |
Definition at line 6312 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 6355 of file pbx.c.
References ast_exten::matchcid.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), and handle_save_dialplan().
06356 { 06357 return e ? e->matchcid : 0; 06358 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6307 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 6327 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 6340 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06341 { 06342 return e ? e->registrar : NULL; 06343 }
int ast_get_hint | ( | char * | hint, | |
int | maxlen, | |||
char * | name, | |||
int | maxnamelen, | |||
struct ast_channel * | c, | |||
const char * | context, | |||
const char * | exten | |||
) |
If an extension exists, return non-zero.
hint | buffer for hint | |
maxlen | size of hint buffer | |
name | buffer for name portion of hint | |
maxnamelen | size of name buffer | |
c | this is not important | |
context | which context to look in | |
exten | which extension to search for |
Definition at line 2301 of file pbx.c.
References ast_copy_string(), ast_get_extension_app(), ast_get_extension_app_data(), and ast_hint_extension().
Referenced by action_extensionstate(), get_cid_name(), get_destination(), pbx_retrieve_variable(), and transmit_state_notify().
02302 { 02303 struct ast_exten *e = ast_hint_extension(c, context, exten); 02304 02305 if (e) { 02306 if (hint) 02307 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02308 if (name) { 02309 const char *tmp = ast_get_extension_app_data(e); 02310 if (tmp) 02311 ast_copy_string(name, tmp, namesize); 02312 } 02313 return -1; 02314 } 02315 return 0; 02316 }
const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6322 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().
06323 { 06324 return ip ? ip->pattern : NULL; 06325 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6350 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06351 { 06352 return ip ? ip->registrar : NULL; 06353 }
const char* ast_get_include_name | ( | struct ast_include * | include | ) |
Definition at line 6317 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 6345 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06346 { 06347 return i ? i->registrar : NULL; 06348 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6380 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06381 { 06382 return sw ? sw->data : NULL; 06383 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6375 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06376 { 06377 return sw ? sw->name : NULL; 06378 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6385 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06386 { 06387 return sw ? sw->registrar : NULL; 06388 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6478 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().
06479 { 06480 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06481 }
void ast_hint_state_changed | ( | const char * | device | ) |
Definition at line 2051 of file pbx.c.
References ast_copy_string(), ast_extension_state2(), ast_get_extension_app(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, AST_MAX_EXTENSION, ast_rdlock_contexts(), ast_unlock_contexts(), ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_exten::exten, ast_hint::exten, ast_hint::laststate, ast_sw::list, ast_context::name, ast_state_cb::next, ast_exten::parent, parse(), and statecbs.
Referenced by do_state_change().
02052 { 02053 struct ast_hint *hint; 02054 02055 ast_rdlock_contexts(); 02056 AST_LIST_LOCK(&hints); 02057 02058 AST_LIST_TRAVERSE(&hints, hint, list) { 02059 struct ast_state_cb *cblist; 02060 char buf[AST_MAX_EXTENSION]; 02061 char *parse = buf; 02062 char *cur; 02063 int state; 02064 02065 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 02066 while ( (cur = strsep(&parse, "&")) ) { 02067 if (!strcasecmp(cur, device)) 02068 break; 02069 } 02070 if (!cur) 02071 continue; 02072 02073 /* Get device state for this hint */ 02074 state = ast_extension_state2(hint->exten); 02075 02076 if ((state == -1) || (state == hint->laststate)) 02077 continue; 02078 02079 /* Device state changed since last check - notify the watchers */ 02080 02081 /* For general callbacks */ 02082 for (cblist = statecbs; cblist; cblist = cblist->next) 02083 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02084 02085 /* For extension callbacks */ 02086 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 02087 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02088 02089 hint->laststate = state; /* record we saw the change */ 02090 } 02091 02092 AST_LIST_UNLOCK(&hints); 02093 ast_unlock_contexts(); 02094 }
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 4572 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().
04573 { 04574 struct ast_context *con = ast_context_find(context); 04575 if (con) { 04576 struct ast_ignorepat *pat; 04577 for (pat = con->ignorepats; pat; pat = pat->next) { 04578 if (ast_extension_match(pat->pattern, pattern)) 04579 return 1; 04580 } 04581 } 04582 04583 return 0; 04584 }
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 6284 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().
06285 { 06286 return ast_mutex_lock(&con->lock); 06287 }
int ast_lock_contexts | ( | void | ) |
Locks the context list.
0 | on success | |
-1 | on error |
Definition at line 6261 of file pbx.c.
References ast_rwlock_wrlock(), and conlock.
Referenced by find_matching_endwhile().
06262 { 06263 return ast_rwlock_wrlock(&conlock); 06264 }
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 2338 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().
02339 { 02340 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE); 02341 }
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 3968 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, store_hint::list, LOG_WARNING, ast_context::name, ast_state_cb::next, ast_context::next, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_context::registrar, and pbx_find_info::stacklen.
Referenced by pbx_load_module().
03969 { 03970 struct ast_context *tmp, *lasttmp = NULL; 03971 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 03972 struct store_hint *this; 03973 struct ast_hint *hint; 03974 struct ast_exten *exten; 03975 int length; 03976 struct ast_state_cb *thiscb, *prevcb; 03977 03978 /* it is very important that this function hold the hint list lock _and_ the conlock 03979 during its operation; not only do we need to ensure that the list of contexts 03980 and extensions does not change, but also that no hint callbacks (watchers) are 03981 added or removed during the merge/delete process 03982 03983 in addition, the locks _must_ be taken in this order, because there are already 03984 other code paths that use this order 03985 */ 03986 ast_wrlock_contexts(); 03987 AST_LIST_LOCK(&hints); 03988 03989 /* preserve all watchers for hints associated with this registrar */ 03990 AST_LIST_TRAVERSE(&hints, hint, list) { 03991 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03992 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03993 if (!(this = ast_calloc(1, length))) 03994 continue; 03995 this->callbacks = hint->callbacks; 03996 hint->callbacks = NULL; 03997 this->laststate = hint->laststate; 03998 this->context = this->data; 03999 strcpy(this->data, hint->exten->parent->name); 04000 this->exten = this->data + strlen(this->context) + 1; 04001 strcpy(this->exten, hint->exten->exten); 04002 AST_LIST_INSERT_HEAD(&store, this, list); 04003 } 04004 } 04005 04006 tmp = *extcontexts; 04007 if (registrar) { 04008 /* XXX remove previous contexts from same registrar */ 04009 if (option_debug) 04010 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 04011 __ast_context_destroy(NULL,registrar); 04012 while (tmp) { 04013 lasttmp = tmp; 04014 tmp = tmp->next; 04015 } 04016 } else { 04017 /* XXX remove contexts with the same name */ 04018 while (tmp) { 04019 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 04020 __ast_context_destroy(tmp,tmp->registrar); 04021 lasttmp = tmp; 04022 tmp = tmp->next; 04023 } 04024 } 04025 if (lasttmp) { 04026 lasttmp->next = contexts; 04027 contexts = *extcontexts; 04028 *extcontexts = NULL; 04029 } else 04030 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 04031 04032 /* restore the watchers for hints that can be found; notify those that 04033 cannot be restored 04034 */ 04035 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 04036 struct pbx_find_info q = { .stacklen = 0 }; 04037 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 04038 /* Find the hint in the list of hints */ 04039 AST_LIST_TRAVERSE(&hints, hint, list) { 04040 if (hint->exten == exten) 04041 break; 04042 } 04043 if (!exten || !hint) { 04044 /* this hint has been removed, notify the watchers */ 04045 prevcb = NULL; 04046 thiscb = this->callbacks; 04047 while (thiscb) { 04048 prevcb = thiscb; 04049 thiscb = thiscb->next; 04050 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 04051 free(prevcb); 04052 } 04053 } else { 04054 thiscb = this->callbacks; 04055 while (thiscb->next) 04056 thiscb = thiscb->next; 04057 thiscb->next = hint->callbacks; 04058 hint->callbacks = this->callbacks; 04059 hint->laststate = this->laststate; 04060 } 04061 free(this); 04062 } 04063 04064 AST_LIST_UNLOCK(&hints); 04065 ast_unlock_contexts(); 04066 04067 return; 04068 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
This function will handle locking the channel as needed.
Definition at line 6488 of file pbx.c.
References ast_explicit_goto(), ast_findlabel_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, exten, LOG_WARNING, and ast_channel::priority.
Referenced by _while_exec(), check_goto_on_transfer(), gosub_exec(), ivr_dispatch(), pbx_builtin_goto(), random_exec(), return_exec(), and while_continue_exec().
06489 { 06490 char *exten, *pri, *context; 06491 char *stringp; 06492 int ipri; 06493 int mode = 0; 06494 06495 if (ast_strlen_zero(goto_string)) { 06496 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06497 return -1; 06498 } 06499 stringp = ast_strdupa(goto_string); 06500 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06501 exten = strsep(&stringp, "|"); 06502 pri = strsep(&stringp, "|"); 06503 if (!exten) { /* Only a priority in this one */ 06504 pri = context; 06505 exten = NULL; 06506 context = NULL; 06507 } else if (!pri) { /* Only an extension and priority in this one */ 06508 pri = exten; 06509 exten = context; 06510 context = NULL; 06511 } 06512 if (*pri == '+') { 06513 mode = 1; 06514 pri++; 06515 } else if (*pri == '-') { 06516 mode = -1; 06517 pri++; 06518 } 06519 if (sscanf(pri, "%d", &ipri) != 1) { 06520 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06521 pri, chan->cid.cid_num)) < 1) { 06522 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06523 return -1; 06524 } else 06525 mode = 0; 06526 } 06527 /* At this point we have a priority and maybe an extension and a context */ 06528 06529 if (mode) 06530 ipri = chan->priority + (ipri * mode); 06531 06532 ast_explicit_goto(chan, context, exten, ipri); 06533 return 0; 06534 06535 }
int ast_pbx_outgoing_app | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int | timeout, | |||
const char * | app, | |||
const char * | appdata, | |||
int * | reason, | |||
int | sync, | |||
const char * | cid_num, | |||
const char * | cid_name, | |||
struct ast_variable * | vars, | |||
const char * | account, | |||
struct ast_channel ** | locked_channel | |||
) |
Synchronously or asynchronously make an outbound call and send it to a particular application with given extension
Definition at line 5199 of file pbx.c.
References __ast_request_and_dial(), ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), async_stat::chan, errno, free, LOG_WARNING, option_verbose, outgoing_helper::vars, and VERBOSE_PREFIX_4.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_app().
05200 { 05201 struct ast_channel *chan; 05202 struct app_tmp *tmp; 05203 int res = -1, cdr_res = -1; 05204 struct outgoing_helper oh; 05205 pthread_attr_t attr; 05206 05207 memset(&oh, 0, sizeof(oh)); 05208 oh.vars = vars; 05209 oh.account = account; 05210 05211 if (locked_channel) 05212 *locked_channel = NULL; 05213 if (ast_strlen_zero(app)) { 05214 res = -1; 05215 goto outgoing_app_cleanup; 05216 } 05217 if (sync) { 05218 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05219 if (chan) { 05220 ast_set_variables(chan, vars); 05221 if (account) 05222 ast_cdr_setaccount(chan, account); 05223 if (chan->_state == AST_STATE_UP) { 05224 res = 0; 05225 if (option_verbose > 3) 05226 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05227 tmp = ast_calloc(1, sizeof(*tmp)); 05228 if (!tmp) 05229 res = -1; 05230 else { 05231 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05232 if (appdata) 05233 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05234 tmp->chan = chan; 05235 if (sync > 1) { 05236 if (locked_channel) 05237 ast_channel_unlock(chan); 05238 ast_pbx_run_app(tmp); 05239 } else { 05240 pthread_attr_init(&attr); 05241 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05242 if (locked_channel) 05243 ast_channel_lock(chan); 05244 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05245 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05246 free(tmp); 05247 if (locked_channel) 05248 ast_channel_unlock(chan); 05249 ast_hangup(chan); 05250 res = -1; 05251 } else { 05252 if (locked_channel) 05253 *locked_channel = chan; 05254 } 05255 pthread_attr_destroy(&attr); 05256 } 05257 } 05258 } else { 05259 if (option_verbose > 3) 05260 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05261 if (chan->cdr) { /* update the cdr */ 05262 /* here we update the status of the call, which sould be busy. 05263 * if that fails then we set the status to failed */ 05264 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05265 ast_cdr_failed(chan->cdr); 05266 } 05267 ast_hangup(chan); 05268 } 05269 } 05270 05271 if (res < 0) { /* the call failed for some reason */ 05272 if (*reason == 0) { /* if the call failed (not busy or no answer) 05273 * update the cdr with the failed message */ 05274 cdr_res = ast_pbx_outgoing_cdr_failed(); 05275 if (cdr_res != 0) { 05276 res = cdr_res; 05277 goto outgoing_app_cleanup; 05278 } 05279 } 05280 } 05281 05282 } else { 05283 struct async_stat *as; 05284 if (!(as = ast_calloc(1, sizeof(*as)))) { 05285 res = -1; 05286 goto outgoing_app_cleanup; 05287 } 05288 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05289 if (!chan) { 05290 free(as); 05291 res = -1; 05292 goto outgoing_app_cleanup; 05293 } 05294 as->chan = chan; 05295 ast_copy_string(as->app, app, sizeof(as->app)); 05296 if (appdata) 05297 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05298 as->timeout = timeout; 05299 ast_set_variables(chan, vars); 05300 if (account) 05301 ast_cdr_setaccount(chan, account); 05302 /* Start a new thread, and get something handling this channel. */ 05303 pthread_attr_init(&attr); 05304 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05305 if (locked_channel) 05306 ast_channel_lock(chan); 05307 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05308 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05309 free(as); 05310 if (locked_channel) 05311 ast_channel_unlock(chan); 05312 ast_hangup(chan); 05313 res = -1; 05314 pthread_attr_destroy(&attr); 05315 goto outgoing_app_cleanup; 05316 } else { 05317 if (locked_channel) 05318 *locked_channel = chan; 05319 } 05320 pthread_attr_destroy(&attr); 05321 res = 0; 05322 } 05323 outgoing_app_cleanup: 05324 ast_variables_destroy(vars); 05325 return res; 05326 }
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 5033 of file pbx.c.
References __ast_request_and_dial(), ast_channel::_state, ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_alloc(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_exists_extension(), ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create, ast_request_and_dial(), ast_set_variables(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, ast_channel::context, free, ast_channel::hangupcause, LOAD_OH, LOG_ERROR, LOG_WARNING, ast_channel::name, option_verbose, pbx_builtin_setvar_helper(), set_ext_pri(), outgoing_helper::vars, and VERBOSE_PREFIX_4.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_exten().
05034 { 05035 struct ast_channel *chan; 05036 struct async_stat *as; 05037 int res = -1, cdr_res = -1; 05038 struct outgoing_helper oh; 05039 pthread_attr_t attr; 05040 05041 if (sync) { 05042 LOAD_OH(oh); 05043 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05044 if (channel) { 05045 *channel = chan; 05046 if (chan) 05047 ast_channel_lock(chan); 05048 } 05049 if (chan) { 05050 if (chan->_state == AST_STATE_UP) { 05051 res = 0; 05052 if (option_verbose > 3) 05053 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05054 05055 if (sync > 1) { 05056 if (channel) 05057 ast_channel_unlock(chan); 05058 if (ast_pbx_run(chan)) { 05059 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05060 if (channel) 05061 *channel = NULL; 05062 ast_hangup(chan); 05063 chan = NULL; 05064 res = -1; 05065 } 05066 } else { 05067 if (ast_pbx_start(chan)) { 05068 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05069 if (channel) { 05070 *channel = NULL; 05071 ast_channel_unlock(chan); 05072 } 05073 ast_hangup(chan); 05074 res = -1; 05075 } 05076 chan = NULL; 05077 } 05078 } else { 05079 if (option_verbose > 3) 05080 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05081 05082 if (chan->cdr) { /* update the cdr */ 05083 /* here we update the status of the call, which sould be busy. 05084 * if that fails then we set the status to failed */ 05085 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05086 ast_cdr_failed(chan->cdr); 05087 } 05088 05089 if (channel) { 05090 *channel = NULL; 05091 ast_channel_unlock(chan); 05092 } 05093 ast_hangup(chan); 05094 chan = NULL; 05095 } 05096 } 05097 05098 if (res < 0) { /* the call failed for some reason */ 05099 if (*reason == 0) { /* if the call failed (not busy or no answer) 05100 * update the cdr with the failed message */ 05101 cdr_res = ast_pbx_outgoing_cdr_failed(); 05102 if (cdr_res != 0) { 05103 res = cdr_res; 05104 goto outgoing_exten_cleanup; 05105 } 05106 } 05107 05108 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05109 /* check if "failed" exists */ 05110 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05111 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05112 if (chan) { 05113 char failed_reason[4] = ""; 05114 if (!ast_strlen_zero(context)) 05115 ast_copy_string(chan->context, context, sizeof(chan->context)); 05116 set_ext_pri(chan, "failed", 1); 05117 ast_set_variables(chan, vars); 05118 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 05119 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 05120 if (account) 05121 ast_cdr_setaccount(chan, account); 05122 if (ast_pbx_run(chan)) { 05123 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05124 ast_hangup(chan); 05125 } 05126 chan = NULL; 05127 } 05128 } 05129 } 05130 } else { 05131 if (!(as = ast_calloc(1, sizeof(*as)))) { 05132 res = -1; 05133 goto outgoing_exten_cleanup; 05134 } 05135 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05136 if (channel) { 05137 *channel = chan; 05138 if (chan) 05139 ast_channel_lock(chan); 05140 } 05141 if (!chan) { 05142 free(as); 05143 res = -1; 05144 goto outgoing_exten_cleanup; 05145 } 05146 as->chan = chan; 05147 ast_copy_string(as->context, context, sizeof(as->context)); 05148 set_ext_pri(as->chan, exten, priority); 05149 as->timeout = timeout; 05150 ast_set_variables(chan, vars); 05151 if (account) 05152 ast_cdr_setaccount(chan, account); 05153 pthread_attr_init(&attr); 05154 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05155 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05156 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05157 free(as); 05158 if (channel) { 05159 *channel = NULL; 05160 ast_channel_unlock(chan); 05161 } 05162 ast_hangup(chan); 05163 res = -1; 05164 pthread_attr_destroy(&attr); 05165 goto outgoing_exten_cleanup; 05166 } 05167 pthread_attr_destroy(&attr); 05168 res = 0; 05169 } 05170 outgoing_exten_cleanup: 05171 ast_variables_destroy(vars); 05172 return res; 05173 }
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 2696 of file pbx.c.
References __ast_pbx_run(), AST_PBX_CALL_LIMIT, AST_PBX_SUCCESS, decrease_call_count(), and increase_call_count().
Referenced by ast_pbx_outgoing_exten(), async_wait(), do_idle_thread(), mgcp_ss(), skinny_newcall(), and ss_thread().
02697 { 02698 enum ast_pbx_result res = AST_PBX_SUCCESS; 02699 02700 if (increase_call_count(c)) 02701 return AST_PBX_CALL_LIMIT; 02702 02703 res = __ast_pbx_run(c); 02704 decrease_call_count(); 02705 02706 return res; 02707 }
enum ast_pbx_result ast_pbx_start | ( | struct ast_channel * | c | ) |
Create a new thread and start the PBX.
c | channel to start the pbx on |
Definition at line 2669 of file pbx.c.
References ast_log(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_pthread_create, decrease_call_count(), increase_call_count(), LOG_WARNING, pbx_thread(), and t.
Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_exten(), check_goto_on_transfer(), dahdi_new(), do_parking_thread(), gtalk_new(), gtalk_newcall(), handle_request_invite(), local_call(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), and skinny_new().
02670 { 02671 pthread_t t; 02672 pthread_attr_t attr; 02673 02674 if (!c) { 02675 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02676 return AST_PBX_FAILED; 02677 } 02678 02679 if (increase_call_count(c)) 02680 return AST_PBX_CALL_LIMIT; 02681 02682 /* Start a new thread, and get something handling this channel. */ 02683 pthread_attr_init(&attr); 02684 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02685 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02686 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02687 pthread_attr_destroy(&attr); 02688 decrease_call_count(); 02689 return AST_PBX_FAILED; 02690 } 02691 pthread_attr_destroy(&attr); 02692 02693 return AST_PBX_SUCCESS; 02694 }
int ast_rdlock_contexts | ( | void | ) |
Definition at line 6266 of file pbx.c.
References ast_rwlock_rdlock(), and conlock.
Referenced by __ast_context_create(), _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_hint_extension(), ast_hint_state_changed(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), handle_save_dialplan(), pbx_extension_helper(), and show_dialplan_helper().
06267 { 06268 return ast_rwlock_rdlock(&conlock); 06269 }
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 2998 of file pbx.c.
References ast_calloc, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), COLOR_BRCYAN, ast_app::description, ast_app::execute, ast_app::list, LOG_WARNING, ast_app::name, option_verbose, ast_app::synopsis, term_color(), and VERBOSE_PREFIX_2.
Referenced by load_module(), and load_pbx().
02999 { 03000 struct ast_app *tmp, *cur = NULL; 03001 char tmps[80]; 03002 int length; 03003 03004 AST_LIST_LOCK(&apps); 03005 AST_LIST_TRAVERSE(&apps, tmp, list) { 03006 if (!strcasecmp(app, tmp->name)) { 03007 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 03008 AST_LIST_UNLOCK(&apps); 03009 return -1; 03010 } 03011 } 03012 03013 length = sizeof(*tmp) + strlen(app) + 1; 03014 03015 if (!(tmp = ast_calloc(1, length))) { 03016 AST_LIST_UNLOCK(&apps); 03017 return -1; 03018 } 03019 03020 strcpy(tmp->name, app); 03021 tmp->execute = execute; 03022 tmp->synopsis = synopsis; 03023 tmp->description = description; 03024 03025 /* Store in alphabetical order */ 03026 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 03027 if (strcasecmp(tmp->name, cur->name) < 0) { 03028 AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 03029 break; 03030 } 03031 } 03032 AST_LIST_TRAVERSE_SAFE_END 03033 if (!cur) 03034 AST_LIST_INSERT_TAIL(&apps, tmp, list); 03035 03036 if (option_verbose > 1) 03037 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 03038 03039 AST_LIST_UNLOCK(&apps); 03040 03041 return 0; 03042 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 3048 of file pbx.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_switch::list, LOG_WARNING, and ast_switch::name.
Referenced by load_module().
03049 { 03050 struct ast_switch *tmp; 03051 03052 AST_LIST_LOCK(&switches); 03053 AST_LIST_TRAVERSE(&switches, tmp, list) { 03054 if (!strcasecmp(tmp->name, sw->name)) { 03055 AST_LIST_UNLOCK(&switches); 03056 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 03057 return -1; 03058 } 03059 } 03060 AST_LIST_INSERT_TAIL(&switches, sw, list); 03061 AST_LIST_UNLOCK(&switches); 03062 03063 return 0; 03064 }
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 2343 of file pbx.c.
References E_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), _macro_exec(), ast_bridge_call(), and loopback_exec().
02344 { 02345 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN); 02346 }
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 6289 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().
06290 { 06291 return ast_mutex_unlock(&con->lock); 06292 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 6276 of file pbx.c.
References ast_rwlock_unlock(), and conlock.
Referenced by __ast_context_create(), _macro_exec(), ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_destroy(), ast_context_find(), ast_context_lockmacro(), ast_context_remove_extension_callerid(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_unlockmacro(), ast_hint_extension(), ast_hint_state_changed(), ast_merge_contexts_and_delete(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_save_dialplan(), pbx_extension_helper(), and show_dialplan_helper().
06277 { 06278 return ast_rwlock_unlock(&conlock); 06279 }
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 3879 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), free, ast_app::list, ast_app::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by __unload_module(), and unload_module().
03880 { 03881 struct ast_app *tmp; 03882 03883 AST_LIST_LOCK(&apps); 03884 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03885 if (!strcasecmp(app, tmp->name)) { 03886 AST_LIST_REMOVE_CURRENT(&apps, list); 03887 if (option_verbose > 1) 03888 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03889 free(tmp); 03890 break; 03891 } 03892 } 03893 AST_LIST_TRAVERSE_SAFE_END 03894 AST_LIST_UNLOCK(&apps); 03895 03896 return tmp ? 0 : -1; 03897 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 3066 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, and ast_switch::list.
Referenced by __unload_module(), and unload_module().
03067 { 03068 AST_LIST_LOCK(&switches); 03069 AST_LIST_REMOVE(&switches, sw, list); 03070 AST_LIST_UNLOCK(&switches); 03071 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | priority | |||
) |
Definition at line 6398 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().
06400 { 06401 if (!exten) 06402 return con ? con->root : NULL; 06403 else 06404 return exten->next; 06405 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 6431 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().
06433 { 06434 if (!ip) 06435 return con ? con->ignorepats : NULL; 06436 else 06437 return ip->next; 06438 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 6422 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().
06424 { 06425 if (!inc) 06426 return con ? con->includes : NULL; 06427 else 06428 return inc->next; 06429 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 6407 of file pbx.c.
References ast_context::alts, AST_LIST_FIRST, AST_LIST_NEXT, and ast_sw::list.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06409 { 06410 if (!sw) 06411 return con ? AST_LIST_FIRST(&con->alts) : NULL; 06412 else 06413 return AST_LIST_NEXT(sw, list); 06414 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 6393 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 6416 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 6271 of file pbx.c.
References ast_rwlock_wrlock(), and conlock.
Referenced by ast_context_destroy(), ast_merge_contexts_and_delete(), and complete_context_dont_include_deprecated().
06272 { 06273 return ast_rwlock_wrlock(&conlock); 06274 }
void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 6037 of file pbx.c.
References AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), ast_var_delete(), ast_var_t::entries, globals, and globalslock.
Referenced by handle_reload_extensions(), and reload().
06038 { 06039 struct ast_var_t *vardata; 06040 06041 ast_mutex_lock(&globalslock); 06042 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06043 ast_var_delete(vardata); 06044 ast_mutex_unlock(&globalslock); 06045 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5814 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), globals, and globalslock.
Referenced by __login_exec(), _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), ast_bridge_call(), ast_channel_bridge(), ast_feature_interpret(), ast_monitor_stop(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dahdi_call(), dahdi_hangup(), dundi_exec(), dundi_helper(), get_also_info(), get_index(), get_refer_info(), global_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), macro_fixup(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_call_full(), park_space_reserve(), pickup_by_mark(), queue_exec(), real_ctx(), retrydial_exec(), return_exec(), ring_entry(), run_agi(), set_config_flags(), sip_addheader(), sla_trunk_exec(), speech_background(), try_calling(), try_suggested_sip_codec(), and wait_for_answer().
05815 { 05816 struct ast_var_t *variables; 05817 const char *ret = NULL; 05818 int i; 05819 struct varshead *places[2] = { NULL, &globals }; 05820 05821 if (!name) 05822 return NULL; 05823 05824 if (chan) { 05825 ast_channel_lock(chan); 05826 places[0] = &chan->varshead; 05827 } 05828 05829 for (i = 0; i < 2; i++) { 05830 if (!places[i]) 05831 continue; 05832 if (places[i] == &globals) 05833 ast_mutex_lock(&globalslock); 05834 AST_LIST_TRAVERSE(places[i], variables, entries) { 05835 if (!strcmp(name, ast_var_name(variables))) { 05836 ret = ast_var_value(variables); 05837 break; 05838 } 05839 } 05840 if (places[i] == &globals) 05841 ast_mutex_unlock(&globalslock); 05842 if (ret) 05843 break; 05844 } 05845 05846 if (chan) 05847 ast_channel_unlock(chan); 05848 05849 return ret; 05850 }
void pbx_builtin_pushvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5852 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_verbose(), globals, globalslock, LOG_WARNING, option_verbose, and VERBOSE_PREFIX_2.
Referenced by acf_odbc_read(), acf_odbc_write(), and gosub_exec().
05853 { 05854 struct ast_var_t *newvariable; 05855 struct varshead *headp; 05856 05857 if (name[strlen(name)-1] == ')') { 05858 char *function = ast_strdupa(name); 05859 05860 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05861 ast_func_write(chan, function, value); 05862 return; 05863 } 05864 05865 if (chan) { 05866 ast_channel_lock(chan); 05867 headp = &chan->varshead; 05868 } else { 05869 ast_mutex_lock(&globalslock); 05870 headp = &globals; 05871 } 05872 05873 if (value) { 05874 if ((option_verbose > 1) && (headp == &globals)) 05875 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05876 newvariable = ast_var_assign(name, value); 05877 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05878 } 05879 05880 if (chan) 05881 ast_channel_unlock(chan); 05882 else 05883 ast_mutex_unlock(&globalslock); 05884 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5783 of file pbx.c.
References ast_build_string(), ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_var_name(), ast_var_value(), ast_var_t::entries, LOG_ERROR, total, var, and ast_channel::varshead.
Referenced by dumpchan_exec(), handle_showchan(), handle_showchan_deprecated(), and vars2manager().
05784 { 05785 struct ast_var_t *variables; 05786 const char *var, *val; 05787 int total = 0; 05788 05789 if (!chan) 05790 return 0; 05791 05792 memset(buf, 0, size); 05793 05794 ast_channel_lock(chan); 05795 05796 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05797 if ((var=ast_var_name(variables)) && (val=ast_var_value(variables)) 05798 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 05799 ) { 05800 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05801 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05802 break; 05803 } else 05804 total++; 05805 } else 05806 break; 05807 } 05808 05809 ast_channel_unlock(chan); 05810 05811 return total; 05812 }
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 5886 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verbose(), globals, globalslock, option_verbose, and VERBOSE_PREFIX_2.
Referenced by __oh323_new(), _macro_exec(), _while_exec(), acf_odbc_read(), acf_odbc_write(), action_setvar(), agi_exec_full(), aji_status_exec(), aqm_exec(), array(), ast_bridge_call(), ast_channel_bridge(), ast_feature_request_and_dial(), ast_iax2_new(), ast_monitor_start(), ast_pbx_outgoing_exten(), ast_set_variables(), background_detect_exec(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), controlplayback_exec(), count_exec(), dahdi_handle_dtmfup(), dahdi_new(), disa_exec(), do_waiting(), end_bridge_callback(), export_aoc_vars(), export_ch(), function_db_delete(), function_db_exists(), function_db_read(), global_write(), handle_request_bye(), handle_request_refer(), handle_set_global(), handle_set_global_deprecated(), handle_setvariable(), hasvoicemail_exec(), isAnsweringMachine(), leave_voicemail(), local_hangup(), lookupblacklist_exec(), macro_fixup(), misdn_call(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_exec(), parse_moved_contact(), pbx_builtin_importvar(), pbx_builtin_saydate(), pbx_builtin_saytime(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_load_config(), play_message_datetime(), playback_exec(), pop_exec(), pqm_exec(), prep_email_sub_vars(), privacy_exec(), process_ast_dsp(), read_exec(), readfile_exec(), realtime_exec(), realtime_update_exec(), record_exec(), return_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_hangup(), sip_new(), sla_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), ss_thread(), start_monitor_exec(), system_exec_helper(), transfer_exec(), try_calling(), tryexec_exec(), upqm_exec(), vm_box_exists(), vm_exec(), and vmauthenticate().
05887 { 05888 struct ast_var_t *newvariable; 05889 struct varshead *headp; 05890 const char *nametail = name; 05891 05892 if (name[strlen(name)-1] == ')') { 05893 char *function = ast_strdupa(name); 05894 05895 ast_func_write(chan, function, value); 05896 return; 05897 } 05898 05899 if (chan) { 05900 ast_channel_lock(chan); 05901 headp = &chan->varshead; 05902 } else { 05903 ast_mutex_lock(&globalslock); 05904 headp = &globals; 05905 } 05906 05907 /* For comparison purposes, we have to strip leading underscores */ 05908 if (*nametail == '_') { 05909 nametail++; 05910 if (*nametail == '_') 05911 nametail++; 05912 } 05913 05914 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05915 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 05916 /* there is already such a variable, delete it */ 05917 AST_LIST_REMOVE(headp, newvariable, entries); 05918 ast_var_delete(newvariable); 05919 break; 05920 } 05921 } 05922 05923 if (value) { 05924 if ((option_verbose > 1) && (headp == &globals)) 05925 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05926 newvariable = ast_var_assign(name, value); 05927 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05928 } 05929 05930 if (chan) 05931 ast_channel_unlock(chan); 05932 else 05933 ast_mutex_unlock(&globalslock); 05934 }
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 6047 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().
06048 { 06049 if (ast_strlen_zero(condition)) /* NULL or empty strings are false */ 06050 return 0; 06051 else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */ 06052 return atoi(condition); 06053 else /* Strings are true */ 06054 return 1; 06055 }
int pbx_exec | ( | struct ast_channel * | c, | |
struct ast_app * | app, | |||
void * | data | |||
) |
Execute an application.
c | channel to execute on | |
app | which app to execute | |
data | the data passed into the app |
c | Channel |
app | Application |
data | Data for execution |
Definition at line 537 of file pbx.c.
References app, ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_channel::cdr, ast_channel::data, and S_OR.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), milliwatt_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().
00540 { 00541 int res; 00542 00543 const char *saved_c_appl; 00544 const char *saved_c_data; 00545 00546 if (c->cdr && !ast_check_hangup(c)) 00547 ast_cdr_setapp(c->cdr, app->name, data); 00548 00549 /* save channel values */ 00550 saved_c_appl= c->appl; 00551 saved_c_data= c->data; 00552 00553 c->appl = app->name; 00554 c->data = data; 00555 /* XXX remember what to to when we have linked apps to modules */ 00556 if (app->module) { 00557 /* XXX LOCAL_USER_ADD(app->module) */ 00558 } 00559 res = app->execute(c, S_OR(data, "")); 00560 if (app->module) { 00561 /* XXX LOCAL_USER_REMOVE(app->module) */ 00562 } 00563 /* restore channel values */ 00564 c->appl = saved_c_appl; 00565 c->data = saved_c_data; 00566 return res; 00567 }
struct ast_app* pbx_findapp | ( | const char * | app | ) |
Look up an application.
app | name of the app |
Definition at line 575 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sw::list, and ast_app::name.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), milliwatt_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().
00576 { 00577 struct ast_app *tmp; 00578 00579 AST_LIST_LOCK(&apps); 00580 AST_LIST_TRAVERSE(&apps, tmp, list) { 00581 if (!strcasecmp(tmp->name, app)) 00582 break; 00583 } 00584 AST_LIST_UNLOCK(&apps); 00585 00586 return tmp; 00587 }
void pbx_retrieve_variable | ( | struct ast_channel * | c, | |
const char * | var, | |||
char ** | ret, | |||
char * | workspace, | |||
int | workspacelen, | |||
struct varshead * | headp | |||
) |
pbx_retrieve_variable: Support for Asterisk built-in variables ---
Definition at line 1174 of file pbx.c.
References ast_cause2str(), ast_channel_lock, ast_channel_unlock, ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_get_hint(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_name(), ast_var_value(), ast_channel::cid, ast_callerid::cid_ani2, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, globals, globalslock, ast_channel::hangupcause, ast_channel::name, offset, parse_variable_name(), ast_channel::priority, s, substring(), and ast_channel::uniqueid.
Referenced by action_getvar(), handle_getvariable(), and pbx_substitute_variables_helper_full().
01175 { 01176 const char not_found = '\0'; 01177 char *tmpvar; 01178 const char *s; /* the result */ 01179 int offset, length; 01180 int i, need_substring; 01181 struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */ 01182 01183 if (c) { 01184 ast_channel_lock(c); 01185 places[0] = &c->varshead; 01186 } 01187 /* 01188 * Make a copy of var because parse_variable_name() modifies the string. 01189 * Then if called directly, we might need to run substring() on the result; 01190 * remember this for later in 'need_substring', 'offset' and 'length' 01191 */ 01192 tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */ 01193 need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */); 01194 01195 /* 01196 * Look first into predefined variables, then into variable lists. 01197 * Variable 's' points to the result, according to the following rules: 01198 * s == ¬_found (set at the beginning) means that we did not find a 01199 * matching variable and need to look into more places. 01200 * If s != ¬_found, s is a valid result string as follows: 01201 * s = NULL if the variable does not have a value; 01202 * you typically do this when looking for an unset predefined variable. 01203 * s = workspace if the result has been assembled there; 01204 * typically done when the result is built e.g. with an snprintf(), 01205 * so we don't need to do an additional copy. 01206 * s != workspace in case we have a string, that needs to be copied 01207 * (the ast_copy_string is done once for all at the end). 01208 * Typically done when the result is already available in some string. 01209 */ 01210 s = ¬_found; /* default value */ 01211 if (c) { /* This group requires a valid channel */ 01212 /* Names with common parts are looked up a piece at a time using strncmp. */ 01213 if (!strncmp(var, "CALL", 4)) { 01214 if (!strncmp(var + 4, "ING", 3)) { 01215 if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */ 01216 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 01217 s = workspace; 01218 } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */ 01219 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 01220 s = workspace; 01221 } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */ 01222 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 01223 s = workspace; 01224 } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */ 01225 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 01226 s = workspace; 01227 } 01228 } 01229 } else if (!strcmp(var, "HINT")) { 01230 s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL; 01231 } else if (!strcmp(var, "HINTNAME")) { 01232 s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL; 01233 } else if (!strcmp(var, "EXTEN")) { 01234 s = c->exten; 01235 } else if (!strcmp(var, "CONTEXT")) { 01236 s = c->context; 01237 } else if (!strcmp(var, "PRIORITY")) { 01238 snprintf(workspace, workspacelen, "%d", c->priority); 01239 s = workspace; 01240 } else if (!strcmp(var, "CHANNEL")) { 01241 s = c->name; 01242 } else if (!strcmp(var, "UNIQUEID")) { 01243 s = c->uniqueid; 01244 } else if (!strcmp(var, "HANGUPCAUSE")) { 01245 snprintf(workspace, workspacelen, "%d", c->hangupcause); 01246 s = workspace; 01247 } else if (c && !strcmp(var, "HANGUPCAUSESTR")) { 01248 ast_copy_string(workspace, ast_cause2str(c->hangupcause), workspacelen); 01249 *ret = workspace; 01250 } 01251 } 01252 if (s == ¬_found) { /* look for more */ 01253 if (!strcmp(var, "EPOCH")) { 01254 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 01255 s = workspace; 01256 } else if (!strcmp(var, "SYSTEMNAME")) { 01257 s = ast_config_AST_SYSTEM_NAME; 01258 } 01259 } 01260 /* if not found, look into chanvars or global vars */ 01261 for (i = 0; s == ¬_found && i < (sizeof(places) / sizeof(places[0])); i++) { 01262 struct ast_var_t *variables; 01263 if (!places[i]) 01264 continue; 01265 if (places[i] == &globals) 01266 ast_mutex_lock(&globalslock); 01267 AST_LIST_TRAVERSE(places[i], variables, entries) { 01268 if (strcasecmp(ast_var_name(variables), var)==0) { 01269 s = ast_var_value(variables); 01270 break; 01271 } 01272 } 01273 if (places[i] == &globals) 01274 ast_mutex_unlock(&globalslock); 01275 } 01276 if (s == ¬_found || s == NULL) 01277 *ret = NULL; 01278 else { 01279 if (s != workspace) 01280 ast_copy_string(workspace, s, workspacelen); 01281 *ret = workspace; 01282 if (need_substring) 01283 *ret = substring(*ret, offset, length, workspace, workspacelen); 01284 } 01285 01286 if (c) 01287 ast_channel_unlock(c); 01288 }
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 2714 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
02715 { 02716 int oldval = autofallthrough; 02717 autofallthrough = newval; 02718 return oldval; 02719 }
void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1793 of file pbx.c.
References pbx_substitute_variables_helper_full(), and ast_channel::varshead.
Referenced by _macro_exec(), acf_odbc_read(), acf_odbc_write(), add_extensions(), custom_log(), cut_internal(), exec_exec(), function_eval(), function_fieldqty(), handle_getvariablefull(), launch_monitor_thread(), make_email_file(), pbx_builtin_importvar(), pbx_load_config(), pbx_substitute_variables(), realtime_exec(), rpt_do_lstats(), sendpage(), try_calling(), and tryexec_exec().
01794 { 01795 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 01796 }
void pbx_substitute_variables_varshead | ( | struct varshead * | headp, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1798 of file pbx.c.
References pbx_substitute_variables_helper_full().
Referenced by ast_add_extension2(), dundi_lookup_local(), and loopback_subst().
01799 { 01800 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 01801 }