#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 2695 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02696 { 02697 return countcalls; 02698 }
int ast_add_extension | ( | const char * | context, | |
int | replace, | |||
const char * | extension, | |||
int | priority, | |||
const char * | label, | |||
const char * | callerid, | |||
const char * | application, | |||
void * | data, | |||
void(*)(void *) | datad, | |||
const char * | registrar | |||
) |
Add and extension to an extension context.
context | context to add the extension to | |
replace | ||
extension | extension to add | |
priority | priority level of extension addition | |
label | extension label | |
callerid | pattern to match CallerID, or NULL to match any CallerID | |
application | application to run on the extension with that priority level | |
data | data to pass to the application | |
datad | ||
registrar | who registered the extension |
0 | success | |
-1 | failure |
Definition at line 4577 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().
04580 { 04581 int ret = -1; 04582 struct ast_context *c = find_context_locked(context); 04583 04584 if (c) { 04585 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04586 application, data, datad, registrar); 04587 ast_unlock_contexts(); 04588 } 04589 return ret; 04590 }
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 4792 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().
04796 { 04797 /* 04798 * Sort extensions (or patterns) according to the rules indicated above. 04799 * These are implemented by the function ext_cmp()). 04800 * All priorities for the same ext/pattern/cid are kept in a list, 04801 * using the 'peer' field as a link field.. 04802 */ 04803 struct ast_exten *tmp, *e, *el = NULL; 04804 int res; 04805 int length; 04806 char *p; 04807 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04808 04809 /* if we are adding a hint, and there are global variables, and the hint 04810 contains variable references, then expand them 04811 */ 04812 ast_mutex_lock(&globalslock); 04813 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04814 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04815 application = expand_buf; 04816 } 04817 ast_mutex_unlock(&globalslock); 04818 04819 length = sizeof(struct ast_exten); 04820 length += strlen(extension) + 1; 04821 length += strlen(application) + 1; 04822 if (label) 04823 length += strlen(label) + 1; 04824 if (callerid) 04825 length += strlen(callerid) + 1; 04826 else 04827 length ++; /* just the '\0' */ 04828 04829 /* Be optimistic: Build the extension structure first */ 04830 if (!(tmp = ast_calloc(1, length))) 04831 return -1; 04832 04833 /* use p as dst in assignments, as the fields are const char * */ 04834 p = tmp->stuff; 04835 if (label) { 04836 tmp->label = p; 04837 strcpy(p, label); 04838 p += strlen(label) + 1; 04839 } 04840 tmp->exten = p; 04841 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04842 tmp->priority = priority; 04843 tmp->cidmatch = p; /* but use p for assignments below */ 04844 if (callerid) { 04845 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04846 tmp->matchcid = 1; 04847 } else { 04848 *p++ = '\0'; 04849 tmp->matchcid = 0; 04850 } 04851 tmp->app = p; 04852 strcpy(p, application); 04853 tmp->parent = con; 04854 tmp->data = data; 04855 tmp->datad = datad; 04856 tmp->registrar = registrar; 04857 04858 ast_mutex_lock(&con->lock); 04859 res = 0; /* some compilers will think it is uninitialized otherwise */ 04860 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04861 res = ext_cmp(e->exten, tmp->exten); 04862 if (res == 0) { /* extension match, now look at cidmatch */ 04863 if (!e->matchcid && !tmp->matchcid) 04864 res = 0; 04865 else if (tmp->matchcid && !e->matchcid) 04866 res = 1; 04867 else if (e->matchcid && !tmp->matchcid) 04868 res = -1; 04869 else 04870 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04871 } 04872 if (res >= 0) 04873 break; 04874 } 04875 if (e && res == 0) { /* exact match, insert in the pri chain */ 04876 res = add_pri(con, tmp, el, e, replace); 04877 ast_mutex_unlock(&con->lock); 04878 if (res < 0) { 04879 errno = EEXIST; /* XXX do we care ? */ 04880 return 0; /* XXX should we return -1 maybe ? */ 04881 } 04882 } else { 04883 /* 04884 * not an exact match, this is the first entry with this pattern, 04885 * so insert in the main list right before 'e' (if any) 04886 */ 04887 tmp->next = e; 04888 if (el) 04889 el->next = tmp; 04890 else 04891 con->root = tmp; 04892 ast_mutex_unlock(&con->lock); 04893 if (tmp->priority == PRIORITY_HINT) 04894 ast_add_hint(tmp); 04895 } 04896 if (option_debug) { 04897 if (tmp->matchcid) { 04898 if (option_debug) 04899 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04900 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04901 } else { 04902 if (option_debug) 04903 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04904 tmp->exten, tmp->priority, con->name); 04905 } 04906 } 04907 if (option_verbose > 2) { 04908 if (tmp->matchcid) { 04909 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04910 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04911 } else { 04912 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04913 tmp->exten, tmp->priority, con->name); 04914 } 04915 } 04916 return 0; 04917 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4615 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().
04616 { 04617 int res = 0; 04618 04619 ast_channel_lock(chan); 04620 04621 if (chan->pbx) { /* This channel is currently in the PBX */ 04622 ast_explicit_goto(chan, context, exten, priority); 04623 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04624 } else { 04625 /* In order to do it when the channel doesn't really exist within 04626 the PBX, we have to make a new channel, masquerade, and start the PBX 04627 at the new location */ 04628 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04629 if (!tmpchan) { 04630 res = -1; 04631 } else { 04632 if (chan->cdr) { 04633 ast_cdr_discard(tmpchan->cdr); 04634 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 04635 } 04636 /* Make formats okay */ 04637 tmpchan->readformat = chan->readformat; 04638 tmpchan->writeformat = chan->writeformat; 04639 /* Setup proper location */ 04640 ast_explicit_goto(tmpchan, 04641 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04642 04643 /* Masquerade into temp channel */ 04644 if (ast_channel_masquerade(tmpchan, chan)) { 04645 /* Failed to set up the masquerade. It's probably chan_local 04646 * in the middle of optimizing itself out. Sad. :( */ 04647 ast_hangup(tmpchan); 04648 tmpchan = NULL; 04649 res = -1; 04650 } else { 04651 /* Grab the locks and get going */ 04652 ast_channel_lock(tmpchan); 04653 ast_do_masquerade(tmpchan); 04654 ast_channel_unlock(tmpchan); 04655 /* Start the PBX going on our stolen channel */ 04656 if (ast_pbx_start(tmpchan)) { 04657 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04658 ast_hangup(tmpchan); 04659 res = -1; 04660 } 04661 } 04662 } 04663 } 04664 ast_channel_unlock(chan); 04665 return res; 04666 }
int ast_async_goto_by_name | ( | const char * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4668 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04669 { 04670 struct ast_channel *chan; 04671 int res = -1; 04672 04673 chan = ast_get_channel_by_name_locked(channame); 04674 if (chan) { 04675 res = ast_async_goto(chan, context, exten, priority); 04676 ast_channel_unlock(chan); 04677 } 04678 return res; 04679 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6469 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06470 { 06471 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06472 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info | |||
) |
Definition at line 4255 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().
04256 { 04257 char info_save[256]; 04258 char *info; 04259 04260 /* Check for empty just in case */ 04261 if (ast_strlen_zero(info_in)) 04262 return 0; 04263 /* make a copy just in case we were passed a static string */ 04264 ast_copy_string(info_save, info_in, sizeof(info_save)); 04265 info = info_save; 04266 /* Assume everything except time */ 04267 i->monthmask = 0xfff; /* 12 bits */ 04268 i->daymask = 0x7fffffffU; /* 31 bits */ 04269 i->dowmask = 0x7f; /* 7 bits */ 04270 /* on each call, use strsep() to move info to the next argument */ 04271 get_timerange(i, strsep(&info, "|")); 04272 if (info) 04273 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04274 if (info) 04275 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04276 if (info) 04277 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04278 return 1; 04279 }
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 2331 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().
02332 { 02333 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH); 02334 }
int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 4281 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().
04282 { 04283 struct tm tm; 04284 time_t t = time(NULL); 04285 04286 ast_localtime(&t, &tm, NULL); 04287 04288 /* If it's not the right month, return */ 04289 if (!(i->monthmask & (1 << tm.tm_mon))) 04290 return 0; 04291 04292 /* If it's not that time of the month.... */ 04293 /* Warning, tm_mday has range 1..31! */ 04294 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04295 return 0; 04296 04297 /* If it's not the right day of the week */ 04298 if (!(i->dowmask & (1 << tm.tm_wday))) 04299 return 0; 04300 04301 /* Sanity check the hour just to be safe */ 04302 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04303 ast_log(LOG_WARNING, "Insane time...\n"); 04304 return 0; 04305 } 04306 04307 /* Now the tough part, we calculate if it fits 04308 in the right time based on min/hour */ 04309 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04310 return 0; 04311 04312 /* If we got this far, then we're good */ 04313 return 1; 04314 }
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 4508 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().
04509 { 04510 int ret = -1; 04511 struct ast_context *c = find_context_locked(context); 04512 04513 if (c) { 04514 ret = ast_context_add_ignorepat2(c, value, registrar); 04515 ast_unlock_contexts(); 04516 } 04517 return ret; 04518 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4520 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().
04521 { 04522 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04523 int length; 04524 char *pattern; 04525 length = sizeof(struct ast_ignorepat); 04526 length += strlen(value) + 1; 04527 if (!(ignorepat = ast_calloc(1, length))) 04528 return -1; 04529 /* The cast to char * is because we need to write the initial value. 04530 * The field is not supposed to be modified otherwise. Also, gcc 4.2 04531 * sees the cast as dereferencing a type-punned pointer and warns about 04532 * it. This is the workaround (we're telling gcc, yes, that's really 04533 * what we wanted to do). 04534 */ 04535 pattern = (char *) ignorepat->pattern; 04536 strcpy(pattern, value); 04537 ignorepat->next = NULL; 04538 ignorepat->registrar = registrar; 04539 ast_mutex_lock(&con->lock); 04540 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04541 ignorepatl = ignorepatc; 04542 if (!strcasecmp(ignorepatc->pattern, value)) { 04543 /* Already there */ 04544 ast_mutex_unlock(&con->lock); 04545 errno = EEXIST; 04546 return -1; 04547 } 04548 } 04549 if (ignorepatl) 04550 ignorepatl->next = ignorepat; 04551 else 04552 con->ignorepats = ignorepat; 04553 ast_mutex_unlock(&con->lock); 04554 return 0; 04555 04556 }
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 4061 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().
04062 { 04063 int ret = -1; 04064 struct ast_context *c = find_context_locked(context); 04065 04066 if (c) { 04067 ret = ast_context_add_include2(c, include, registrar); 04068 ast_unlock_contexts(); 04069 } 04070 return ret; 04071 }
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 4323 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().
04325 { 04326 struct ast_include *new_include; 04327 char *c; 04328 struct ast_include *i, *il = NULL; /* include, include_last */ 04329 int length; 04330 char *p; 04331 04332 length = sizeof(struct ast_include); 04333 length += 2 * (strlen(value) + 1); 04334 04335 /* allocate new include structure ... */ 04336 if (!(new_include = ast_calloc(1, length))) 04337 return -1; 04338 /* Fill in this structure. Use 'p' for assignments, as the fields 04339 * in the structure are 'const char *' 04340 */ 04341 p = new_include->stuff; 04342 new_include->name = p; 04343 strcpy(p, value); 04344 p += strlen(value) + 1; 04345 new_include->rname = p; 04346 strcpy(p, value); 04347 /* Strip off timing info, and process if it is there */ 04348 if ( (c = strchr(p, '|')) ) { 04349 *c++ = '\0'; 04350 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04351 } 04352 new_include->next = NULL; 04353 new_include->registrar = registrar; 04354 04355 ast_mutex_lock(&con->lock); 04356 04357 /* ... go to last include and check if context is already included too... */ 04358 for (i = con->includes; i; i = i->next) { 04359 if (!strcasecmp(i->name, new_include->name)) { 04360 free(new_include); 04361 ast_mutex_unlock(&con->lock); 04362 errno = EEXIST; 04363 return -1; 04364 } 04365 il = i; 04366 } 04367 04368 /* ... include new context into context list, unlock, return */ 04369 if (il) 04370 il->next = new_include; 04371 else 04372 con->includes = new_include; 04373 if (option_verbose > 2) 04374 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04375 ast_mutex_unlock(&con->lock); 04376 04377 return 0; 04378 }
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 4385 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04386 { 04387 int ret = -1; 04388 struct ast_context *c = find_context_locked(context); 04389 04390 if (c) { /* found, add switch to this context */ 04391 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04392 ast_unlock_contexts(); 04393 } 04394 return ret; 04395 }
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 4404 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().
04406 { 04407 struct ast_sw *new_sw; 04408 struct ast_sw *i; 04409 int length; 04410 char *p; 04411 04412 length = sizeof(struct ast_sw); 04413 length += strlen(value) + 1; 04414 if (data) 04415 length += strlen(data); 04416 length++; 04417 04418 /* allocate new sw structure ... */ 04419 if (!(new_sw = ast_calloc(1, length))) 04420 return -1; 04421 /* ... fill in this structure ... */ 04422 p = new_sw->stuff; 04423 new_sw->name = p; 04424 strcpy(new_sw->name, value); 04425 p += strlen(value) + 1; 04426 new_sw->data = p; 04427 if (data) { 04428 strcpy(new_sw->data, data); 04429 p += strlen(data) + 1; 04430 } else { 04431 strcpy(new_sw->data, ""); 04432 p++; 04433 } 04434 new_sw->eval = eval; 04435 new_sw->registrar = registrar; 04436 04437 /* ... try to lock this context ... */ 04438 ast_mutex_lock(&con->lock); 04439 04440 /* ... go to last sw and check if context is already swd too... */ 04441 AST_LIST_TRAVERSE(&con->alts, i, list) { 04442 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04443 free(new_sw); 04444 ast_mutex_unlock(&con->lock); 04445 errno = EEXIST; 04446 return -1; 04447 } 04448 } 04449 04450 /* ... sw new context into context list, unlock, return */ 04451 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04452 04453 if (option_verbose > 2) 04454 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04455 04456 ast_mutex_unlock(&con->lock); 04457 04458 return 0; 04459 }
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 3931 of file pbx.c.
References __ast_context_create().
Referenced by do_parking_thread(), park_call_full(), and set_config().
03932 { 03933 return __ast_context_create(extcontexts, name, registrar, 0); 03934 }
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 5373 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().
05374 { 05375 ast_wrlock_contexts(); 05376 __ast_context_destroy(con,registrar); 05377 ast_unlock_contexts(); 05378 }
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 3936 of file pbx.c.
References __ast_context_create().
Referenced by pbx_load_config(), and pbx_load_users().
03937 { 03938 return __ast_context_create(extcontexts, name, registrar, 1); 03939 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 2932 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().
02933 { 02934 struct ast_context *c = NULL; 02935 int ret = -1; 02936 02937 ast_rdlock_contexts(); 02938 02939 while ((c = ast_walk_contexts(c))) { 02940 if (!strcmp(ast_get_context_name(c), context)) { 02941 ret = 0; 02942 break; 02943 } 02944 } 02945 02946 ast_unlock_contexts(); 02947 02948 /* if we found context, lock macrolock */ 02949 if (ret == 0) 02950 ret = ast_mutex_lock(&c->macrolock); 02951 02952 return ret; 02953 }
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 2833 of file pbx.c.
References ast_context_remove_extension_callerid().
Referenced by destroy_station(), destroy_trunk(), and register_peer_exten().
02834 { 02835 return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar); 02836 }
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 2860 of file pbx.c.
References ast_context_remove_extension_callerid2().
Referenced by do_parking_thread(), and park_exec().
02861 { 02862 return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar); 02863 }
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 2838 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().
02839 { 02840 int ret = -1; /* default error return */ 02841 struct ast_context *c = find_context_locked(context); 02842 02843 if (c) { /* ... remove extension ... */ 02844 ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar); 02845 ast_unlock_contexts(); 02846 } 02847 return ret; 02848 }
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 2865 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().
02866 { 02867 struct ast_exten *exten, *prev_exten = NULL; 02868 struct ast_exten *peer; 02869 struct ast_exten *previous_peer = NULL; 02870 struct ast_exten *next_peer = NULL; 02871 int found = 0; 02872 02873 ast_mutex_lock(&con->lock); 02874 02875 /* scan the extension list to find first matching extension-registrar */ 02876 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02877 if (!strcmp(exten->exten, extension) && 02878 (!registrar || !strcmp(exten->registrar, registrar))) 02879 break; 02880 } 02881 if (!exten) { 02882 /* we can't find right extension */ 02883 ast_mutex_unlock(&con->lock); 02884 return -1; 02885 } 02886 02887 /* scan the priority list to remove extension with exten->priority == priority */ 02888 for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next; 02889 peer && !strcmp(peer->exten, extension); 02890 peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) { 02891 if ((priority == 0 || peer->priority == priority) && 02892 (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) && 02893 (!registrar || !strcmp(peer->registrar, registrar) )) { 02894 found = 1; 02895 02896 /* we are first priority extension? */ 02897 if (!previous_peer) { 02898 /* 02899 * We are first in the priority chain, so must update the extension chain. 02900 * The next node is either the next priority or the next extension 02901 */ 02902 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02903 02904 if (!prev_exten) { /* change the root... */ 02905 con->root = next_node; 02906 } else { 02907 prev_exten->next = next_node; /* unlink */ 02908 } 02909 if (peer->peer) { /* update the new head of the pri list */ 02910 peer->peer->next = peer->next; 02911 } 02912 } else { /* easy, we are not first priority in extension */ 02913 previous_peer->peer = peer->peer; 02914 } 02915 02916 /* now, free whole priority extension */ 02917 destroy_exten(peer); 02918 } else { 02919 previous_peer = peer; 02920 } 02921 } 02922 ast_mutex_unlock(&con->lock); 02923 return found ? 0 : -1; 02924 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4465 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().
04466 { 04467 int ret = -1; 04468 struct ast_context *c = find_context_locked(context); 04469 04470 if (c) { 04471 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04472 ast_unlock_contexts(); 04473 } 04474 return ret; 04475 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4477 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().
04478 { 04479 struct ast_ignorepat *ip, *ipl = NULL; 04480 04481 ast_mutex_lock(&con->lock); 04482 04483 for (ip = con->ignorepats; ip; ip = ip->next) { 04484 if (!strcmp(ip->pattern, ignorepat) && 04485 (!registrar || (registrar == ip->registrar))) { 04486 if (ipl) { 04487 ipl->next = ip->next; 04488 free(ip); 04489 } else { 04490 con->ignorepats = ip->next; 04491 free(ip); 04492 } 04493 ast_mutex_unlock(&con->lock); 04494 return 0; 04495 } 04496 ipl = ip; 04497 } 04498 04499 ast_mutex_unlock(&con->lock); 04500 errno = EINVAL; 04501 return -1; 04502 }
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 2729 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().
02730 { 02731 int ret = -1; 02732 struct ast_context *c = find_context_locked(context); 02733 02734 if (c) { 02735 /* found, remove include from this context ... */ 02736 ret = ast_context_remove_include2(c, include, registrar); 02737 ast_unlock_contexts(); 02738 } 02739 return ret; 02740 }
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 2750 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().
02751 { 02752 struct ast_include *i, *pi = NULL; 02753 int ret = -1; 02754 02755 ast_mutex_lock(&con->lock); 02756 02757 /* find our include */ 02758 for (i = con->includes; i; pi = i, i = i->next) { 02759 if (!strcmp(i->name, include) && 02760 (!registrar || !strcmp(i->registrar, registrar))) { 02761 /* remove from list */ 02762 if (pi) 02763 pi->next = i->next; 02764 else 02765 con->includes = i->next; 02766 /* free include and return */ 02767 free(i); 02768 ret = 0; 02769 break; 02770 } 02771 } 02772 02773 ast_mutex_unlock(&con->lock); 02774 return ret; 02775 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 2782 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
02783 { 02784 int ret = -1; /* default error return */ 02785 struct ast_context *c = find_context_locked(context); 02786 02787 if (c) { 02788 /* remove switch from this context ... */ 02789 ret = ast_context_remove_switch2(c, sw, data, registrar); 02790 ast_unlock_contexts(); 02791 } 02792 return ret; 02793 }
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 2803 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().
02804 { 02805 struct ast_sw *i; 02806 int ret = -1; 02807 02808 ast_mutex_lock(&con->lock); 02809 02810 /* walk switches */ 02811 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02812 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02813 (!registrar || !strcmp(i->registrar, registrar))) { 02814 /* found, remove from list */ 02815 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02816 free(i); /* free switch and return */ 02817 ret = 0; 02818 break; 02819 } 02820 } 02821 AST_LIST_TRAVERSE_SAFE_END 02822 02823 ast_mutex_unlock(&con->lock); 02824 02825 return ret; 02826 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 2960 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().
02961 { 02962 struct ast_context *c = NULL; 02963 int ret = -1; 02964 02965 ast_rdlock_contexts(); 02966 02967 while ((c = ast_walk_contexts(c))) { 02968 if (!strcmp(ast_get_context_name(c), context)) { 02969 ret = 0; 02970 break; 02971 } 02972 } 02973 02974 ast_unlock_contexts(); 02975 02976 /* if we found context, unlock macrolock */ 02977 if (ret == 0) 02978 ret = ast_mutex_unlock(&c->macrolock); 02979 02980 return ret; 02981 }
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 6426 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().
06427 { 06428 struct ast_include *inc = NULL; 06429 int res = 0; 06430 06431 while ( (inc = ast_walk_context_includes(con, inc)) ) { 06432 if (ast_context_find(inc->rname)) 06433 continue; 06434 06435 res = -1; 06436 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 06437 ast_get_context_name(con), inc->rname); 06438 break; 06439 } 06440 06441 return res; 06442 }
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 2316 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_call_full(), 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().
02317 { 02318 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH); 02319 }
int ast_explicit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4592 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().
04593 { 04594 if (!chan) 04595 return -1; 04596 04597 ast_channel_lock(chan); 04598 04599 if (!ast_strlen_zero(context)) 04600 ast_copy_string(chan->context, context, sizeof(chan->context)); 04601 if (!ast_strlen_zero(exten)) 04602 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04603 if (priority > -1) { 04604 chan->priority = priority; 04605 /* see flag description in channel.h for explanation */ 04606 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04607 chan->priority--; 04608 } 04609 04610 ast_channel_unlock(chan); 04611 04612 return 0; 04613 }
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 2095 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().
02097 { 02098 struct ast_hint *hint; 02099 struct ast_state_cb *cblist; 02100 struct ast_exten *e; 02101 02102 /* If there's no context and extension: add callback to statecbs list */ 02103 if (!context && !exten) { 02104 AST_LIST_LOCK(&hints); 02105 02106 for (cblist = statecbs; cblist; cblist = cblist->next) { 02107 if (cblist->callback == callback) { 02108 cblist->data = data; 02109 AST_LIST_UNLOCK(&hints); 02110 return 0; 02111 } 02112 } 02113 02114 /* Now insert the callback */ 02115 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02116 AST_LIST_UNLOCK(&hints); 02117 return -1; 02118 } 02119 cblist->id = 0; 02120 cblist->callback = callback; 02121 cblist->data = data; 02122 02123 cblist->next = statecbs; 02124 statecbs = cblist; 02125 02126 AST_LIST_UNLOCK(&hints); 02127 return 0; 02128 } 02129 02130 if (!context || !exten) 02131 return -1; 02132 02133 /* This callback type is for only one hint, so get the hint */ 02134 e = ast_hint_extension(NULL, context, exten); 02135 if (!e) { 02136 return -1; 02137 } 02138 02139 /* Find the hint in the list of hints */ 02140 AST_LIST_LOCK(&hints); 02141 02142 AST_LIST_TRAVERSE(&hints, hint, list) { 02143 if (hint->exten == e) 02144 break; 02145 } 02146 02147 if (!hint) { 02148 /* We have no hint, sorry */ 02149 AST_LIST_UNLOCK(&hints); 02150 return -1; 02151 } 02152 02153 /* Now insert the callback in the callback list */ 02154 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02155 AST_LIST_UNLOCK(&hints); 02156 return -1; 02157 } 02158 cblist->id = stateid++; /* Unique ID for this callback */ 02159 cblist->callback = callback; /* Pointer to callback routine */ 02160 cblist->data = data; /* Data for the callback */ 02161 02162 cblist->next = hint->callbacks; 02163 hint->callbacks = cblist; 02164 02165 AST_LIST_UNLOCK(&hints); 02166 return cblist->id; 02167 }
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 2170 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().
02171 { 02172 struct ast_state_cb **p_cur = NULL; /* address of pointer to us */ 02173 int ret = -1; 02174 02175 if (!id && !callback) 02176 return -1; 02177 02178 AST_LIST_LOCK(&hints); 02179 02180 if (!id) { /* id == 0 is a callback without extension */ 02181 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) { 02182 if ((*p_cur)->callback == callback) 02183 break; 02184 } 02185 } else { /* callback with extension, find the callback based on ID */ 02186 struct ast_hint *hint; 02187 AST_LIST_TRAVERSE(&hints, hint, list) { 02188 for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) { 02189 if ((*p_cur)->id == id) 02190 break; 02191 } 02192 if (*p_cur) /* found in the inner loop */ 02193 break; 02194 } 02195 } 02196 if (p_cur && *p_cur) { 02197 struct ast_state_cb *cur = *p_cur; 02198 *p_cur = cur->next; 02199 free(cur); 02200 ret = 0; 02201 } 02202 AST_LIST_UNLOCK(&hints); 02203 return ret; 02204 }
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 2321 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().
02322 { 02323 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL); 02324 }
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 2326 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
02327 { 02328 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL); 02329 }
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 6283 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().
06284 { 06285 return con ? con->name : NULL; 06286 }
const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 6321 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06322 { 06323 return c ? c->registrar : NULL; 06324 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6351 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().
06352 { 06353 return e ? e->app : NULL; 06354 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6356 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06357 { 06358 return e ? e->data : NULL; 06359 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6346 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().
06347 { 06348 return e ? e->cidmatch : NULL; 06349 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
const char* ast_get_extension_label | ( | struct ast_exten * | e | ) |
Definition at line 6298 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 6341 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().
06342 { 06343 return e ? e->matchcid : 0; 06344 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6293 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 6313 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 6326 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06327 { 06328 return e ? e->registrar : NULL; 06329 }
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 2299 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().
02300 { 02301 struct ast_exten *e = ast_hint_extension(c, context, exten); 02302 02303 if (e) { 02304 if (hint) 02305 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02306 if (name) { 02307 const char *tmp = ast_get_extension_app_data(e); 02308 if (tmp) 02309 ast_copy_string(name, tmp, namesize); 02310 } 02311 return -1; 02312 } 02313 return 0; 02314 }
const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6308 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().
06309 { 06310 return ip ? ip->pattern : NULL; 06311 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6336 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06337 { 06338 return ip ? ip->registrar : NULL; 06339 }
const char* ast_get_include_name | ( | struct ast_include * | include | ) |
Definition at line 6303 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 6331 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06332 { 06333 return i ? i->registrar : NULL; 06334 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6366 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06367 { 06368 return sw ? sw->data : NULL; 06369 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6361 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06362 { 06363 return sw ? sw->name : NULL; 06364 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6371 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06372 { 06373 return sw ? sw->registrar : NULL; 06374 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6464 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().
06465 { 06466 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06467 }
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_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_LIST_LOCK(&hints); 02056 02057 AST_LIST_TRAVERSE(&hints, hint, list) { 02058 struct ast_state_cb *cblist; 02059 char buf[AST_MAX_EXTENSION]; 02060 char *parse = buf; 02061 char *cur; 02062 int state; 02063 02064 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 02065 while ( (cur = strsep(&parse, "&")) ) { 02066 if (!strcasecmp(cur, device)) 02067 break; 02068 } 02069 if (!cur) 02070 continue; 02071 02072 /* Get device state for this hint */ 02073 state = ast_extension_state2(hint->exten); 02074 02075 if ((state == -1) || (state == hint->laststate)) 02076 continue; 02077 02078 /* Device state changed since last check - notify the watchers */ 02079 02080 /* For general callbacks */ 02081 for (cblist = statecbs; cblist; cblist = cblist->next) 02082 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02083 02084 /* For extension callbacks */ 02085 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 02086 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02087 02088 hint->laststate = state; /* record we saw the change */ 02089 } 02090 02091 AST_LIST_UNLOCK(&hints); 02092 }
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 4558 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().
04559 { 04560 struct ast_context *con = ast_context_find(context); 04561 if (con) { 04562 struct ast_ignorepat *pat; 04563 for (pat = con->ignorepats; pat; pat = pat->next) { 04564 if (ast_extension_match(pat->pattern, pattern)) 04565 return 1; 04566 } 04567 } 04568 04569 return 0; 04570 }
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 6270 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().
06271 { 06272 return ast_mutex_lock(&con->lock); 06273 }
int ast_lock_contexts | ( | void | ) |
Locks the context list.
0 | on success | |
-1 | on error |
Definition at line 6247 of file pbx.c.
References ast_rwlock_wrlock(), and conlock.
Referenced by find_matching_endwhile().
06248 { 06249 return ast_rwlock_wrlock(&conlock); 06250 }
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 2336 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().
02337 { 02338 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE); 02339 }
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 3954 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().
03955 { 03956 struct ast_context *tmp, *lasttmp = NULL; 03957 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 03958 struct store_hint *this; 03959 struct ast_hint *hint; 03960 struct ast_exten *exten; 03961 int length; 03962 struct ast_state_cb *thiscb, *prevcb; 03963 03964 /* it is very important that this function hold the hint list lock _and_ the conlock 03965 during its operation; not only do we need to ensure that the list of contexts 03966 and extensions does not change, but also that no hint callbacks (watchers) are 03967 added or removed during the merge/delete process 03968 03969 in addition, the locks _must_ be taken in this order, because there are already 03970 other code paths that use this order 03971 */ 03972 ast_wrlock_contexts(); 03973 AST_LIST_LOCK(&hints); 03974 03975 /* preserve all watchers for hints associated with this registrar */ 03976 AST_LIST_TRAVERSE(&hints, hint, list) { 03977 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03978 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03979 if (!(this = ast_calloc(1, length))) 03980 continue; 03981 this->callbacks = hint->callbacks; 03982 hint->callbacks = NULL; 03983 this->laststate = hint->laststate; 03984 this->context = this->data; 03985 strcpy(this->data, hint->exten->parent->name); 03986 this->exten = this->data + strlen(this->context) + 1; 03987 strcpy(this->exten, hint->exten->exten); 03988 AST_LIST_INSERT_HEAD(&store, this, list); 03989 } 03990 } 03991 03992 tmp = *extcontexts; 03993 if (registrar) { 03994 /* XXX remove previous contexts from same registrar */ 03995 if (option_debug) 03996 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 03997 __ast_context_destroy(NULL,registrar); 03998 while (tmp) { 03999 lasttmp = tmp; 04000 tmp = tmp->next; 04001 } 04002 } else { 04003 /* XXX remove contexts with the same name */ 04004 while (tmp) { 04005 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 04006 __ast_context_destroy(tmp,tmp->registrar); 04007 lasttmp = tmp; 04008 tmp = tmp->next; 04009 } 04010 } 04011 if (lasttmp) { 04012 lasttmp->next = contexts; 04013 contexts = *extcontexts; 04014 *extcontexts = NULL; 04015 } else 04016 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 04017 04018 /* restore the watchers for hints that can be found; notify those that 04019 cannot be restored 04020 */ 04021 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 04022 struct pbx_find_info q = { .stacklen = 0 }; 04023 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 04024 /* Find the hint in the list of hints */ 04025 AST_LIST_TRAVERSE(&hints, hint, list) { 04026 if (hint->exten == exten) 04027 break; 04028 } 04029 if (!exten || !hint) { 04030 /* this hint has been removed, notify the watchers */ 04031 prevcb = NULL; 04032 thiscb = this->callbacks; 04033 while (thiscb) { 04034 prevcb = thiscb; 04035 thiscb = thiscb->next; 04036 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 04037 free(prevcb); 04038 } 04039 } else { 04040 thiscb = this->callbacks; 04041 while (thiscb->next) 04042 thiscb = thiscb->next; 04043 thiscb->next = hint->callbacks; 04044 hint->callbacks = this->callbacks; 04045 hint->laststate = this->laststate; 04046 } 04047 free(this); 04048 } 04049 04050 AST_LIST_UNLOCK(&hints); 04051 ast_unlock_contexts(); 04052 04053 return; 04054 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
This function will handle locking the channel as needed.
Definition at line 6474 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().
06475 { 06476 char *exten, *pri, *context; 06477 char *stringp; 06478 int ipri; 06479 int mode = 0; 06480 06481 if (ast_strlen_zero(goto_string)) { 06482 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06483 return -1; 06484 } 06485 stringp = ast_strdupa(goto_string); 06486 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06487 exten = strsep(&stringp, "|"); 06488 pri = strsep(&stringp, "|"); 06489 if (!exten) { /* Only a priority in this one */ 06490 pri = context; 06491 exten = NULL; 06492 context = NULL; 06493 } else if (!pri) { /* Only an extension and priority in this one */ 06494 pri = exten; 06495 exten = context; 06496 context = NULL; 06497 } 06498 if (*pri == '+') { 06499 mode = 1; 06500 pri++; 06501 } else if (*pri == '-') { 06502 mode = -1; 06503 pri++; 06504 } 06505 if (sscanf(pri, "%d", &ipri) != 1) { 06506 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06507 pri, chan->cid.cid_num)) < 1) { 06508 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06509 return -1; 06510 } else 06511 mode = 0; 06512 } 06513 /* At this point we have a priority and maybe an extension and a context */ 06514 06515 if (mode) 06516 ipri = chan->priority + (ipri * mode); 06517 06518 ast_explicit_goto(chan, context, exten, ipri); 06519 return 0; 06520 06521 }
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 5185 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().
05186 { 05187 struct ast_channel *chan; 05188 struct app_tmp *tmp; 05189 int res = -1, cdr_res = -1; 05190 struct outgoing_helper oh; 05191 pthread_attr_t attr; 05192 05193 memset(&oh, 0, sizeof(oh)); 05194 oh.vars = vars; 05195 oh.account = account; 05196 05197 if (locked_channel) 05198 *locked_channel = NULL; 05199 if (ast_strlen_zero(app)) { 05200 res = -1; 05201 goto outgoing_app_cleanup; 05202 } 05203 if (sync) { 05204 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05205 if (chan) { 05206 ast_set_variables(chan, vars); 05207 if (account) 05208 ast_cdr_setaccount(chan, account); 05209 if (chan->_state == AST_STATE_UP) { 05210 res = 0; 05211 if (option_verbose > 3) 05212 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05213 tmp = ast_calloc(1, sizeof(*tmp)); 05214 if (!tmp) 05215 res = -1; 05216 else { 05217 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05218 if (appdata) 05219 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05220 tmp->chan = chan; 05221 if (sync > 1) { 05222 if (locked_channel) 05223 ast_channel_unlock(chan); 05224 ast_pbx_run_app(tmp); 05225 } else { 05226 pthread_attr_init(&attr); 05227 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05228 if (locked_channel) 05229 ast_channel_lock(chan); 05230 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05231 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05232 free(tmp); 05233 if (locked_channel) 05234 ast_channel_unlock(chan); 05235 ast_hangup(chan); 05236 res = -1; 05237 } else { 05238 if (locked_channel) 05239 *locked_channel = chan; 05240 } 05241 pthread_attr_destroy(&attr); 05242 } 05243 } 05244 } else { 05245 if (option_verbose > 3) 05246 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05247 if (chan->cdr) { /* update the cdr */ 05248 /* here we update the status of the call, which sould be busy. 05249 * if that fails then we set the status to failed */ 05250 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05251 ast_cdr_failed(chan->cdr); 05252 } 05253 ast_hangup(chan); 05254 } 05255 } 05256 05257 if (res < 0) { /* the call failed for some reason */ 05258 if (*reason == 0) { /* if the call failed (not busy or no answer) 05259 * update the cdr with the failed message */ 05260 cdr_res = ast_pbx_outgoing_cdr_failed(); 05261 if (cdr_res != 0) { 05262 res = cdr_res; 05263 goto outgoing_app_cleanup; 05264 } 05265 } 05266 } 05267 05268 } else { 05269 struct async_stat *as; 05270 if (!(as = ast_calloc(1, sizeof(*as)))) { 05271 res = -1; 05272 goto outgoing_app_cleanup; 05273 } 05274 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05275 if (!chan) { 05276 free(as); 05277 res = -1; 05278 goto outgoing_app_cleanup; 05279 } 05280 as->chan = chan; 05281 ast_copy_string(as->app, app, sizeof(as->app)); 05282 if (appdata) 05283 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05284 as->timeout = timeout; 05285 ast_set_variables(chan, vars); 05286 if (account) 05287 ast_cdr_setaccount(chan, account); 05288 /* Start a new thread, and get something handling this channel. */ 05289 pthread_attr_init(&attr); 05290 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05291 if (locked_channel) 05292 ast_channel_lock(chan); 05293 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05294 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05295 free(as); 05296 if (locked_channel) 05297 ast_channel_unlock(chan); 05298 ast_hangup(chan); 05299 res = -1; 05300 pthread_attr_destroy(&attr); 05301 goto outgoing_app_cleanup; 05302 } else { 05303 if (locked_channel) 05304 *locked_channel = chan; 05305 } 05306 pthread_attr_destroy(&attr); 05307 res = 0; 05308 } 05309 outgoing_app_cleanup: 05310 ast_variables_destroy(vars); 05311 return res; 05312 }
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 5019 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().
05020 { 05021 struct ast_channel *chan; 05022 struct async_stat *as; 05023 int res = -1, cdr_res = -1; 05024 struct outgoing_helper oh; 05025 pthread_attr_t attr; 05026 05027 if (sync) { 05028 LOAD_OH(oh); 05029 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05030 if (channel) { 05031 *channel = chan; 05032 if (chan) 05033 ast_channel_lock(chan); 05034 } 05035 if (chan) { 05036 if (chan->_state == AST_STATE_UP) { 05037 res = 0; 05038 if (option_verbose > 3) 05039 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05040 05041 if (sync > 1) { 05042 if (channel) 05043 ast_channel_unlock(chan); 05044 if (ast_pbx_run(chan)) { 05045 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05046 if (channel) 05047 *channel = NULL; 05048 ast_hangup(chan); 05049 chan = NULL; 05050 res = -1; 05051 } 05052 } else { 05053 if (ast_pbx_start(chan)) { 05054 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05055 if (channel) { 05056 *channel = NULL; 05057 ast_channel_unlock(chan); 05058 } 05059 ast_hangup(chan); 05060 res = -1; 05061 } 05062 chan = NULL; 05063 } 05064 } else { 05065 if (option_verbose > 3) 05066 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05067 05068 if (chan->cdr) { /* update the cdr */ 05069 /* here we update the status of the call, which sould be busy. 05070 * if that fails then we set the status to failed */ 05071 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05072 ast_cdr_failed(chan->cdr); 05073 } 05074 05075 if (channel) { 05076 *channel = NULL; 05077 ast_channel_unlock(chan); 05078 } 05079 ast_hangup(chan); 05080 chan = NULL; 05081 } 05082 } 05083 05084 if (res < 0) { /* the call failed for some reason */ 05085 if (*reason == 0) { /* if the call failed (not busy or no answer) 05086 * update the cdr with the failed message */ 05087 cdr_res = ast_pbx_outgoing_cdr_failed(); 05088 if (cdr_res != 0) { 05089 res = cdr_res; 05090 goto outgoing_exten_cleanup; 05091 } 05092 } 05093 05094 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05095 /* check if "failed" exists */ 05096 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05097 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05098 if (chan) { 05099 char failed_reason[4] = ""; 05100 if (!ast_strlen_zero(context)) 05101 ast_copy_string(chan->context, context, sizeof(chan->context)); 05102 set_ext_pri(chan, "failed", 1); 05103 ast_set_variables(chan, vars); 05104 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 05105 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 05106 if (account) 05107 ast_cdr_setaccount(chan, account); 05108 if (ast_pbx_run(chan)) { 05109 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05110 ast_hangup(chan); 05111 } 05112 chan = NULL; 05113 } 05114 } 05115 } 05116 } else { 05117 if (!(as = ast_calloc(1, sizeof(*as)))) { 05118 res = -1; 05119 goto outgoing_exten_cleanup; 05120 } 05121 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05122 if (channel) { 05123 *channel = chan; 05124 if (chan) 05125 ast_channel_lock(chan); 05126 } 05127 if (!chan) { 05128 free(as); 05129 res = -1; 05130 goto outgoing_exten_cleanup; 05131 } 05132 as->chan = chan; 05133 ast_copy_string(as->context, context, sizeof(as->context)); 05134 set_ext_pri(as->chan, exten, priority); 05135 as->timeout = timeout; 05136 ast_set_variables(chan, vars); 05137 if (account) 05138 ast_cdr_setaccount(chan, account); 05139 pthread_attr_init(&attr); 05140 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05141 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05142 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05143 free(as); 05144 if (channel) { 05145 *channel = NULL; 05146 ast_channel_unlock(chan); 05147 } 05148 ast_hangup(chan); 05149 res = -1; 05150 pthread_attr_destroy(&attr); 05151 goto outgoing_exten_cleanup; 05152 } 05153 pthread_attr_destroy(&attr); 05154 res = 0; 05155 } 05156 outgoing_exten_cleanup: 05157 ast_variables_destroy(vars); 05158 return res; 05159 }
enum ast_pbx_result ast_pbx_run | ( | struct ast_channel * | c | ) |
Execute the PBX in the current thread.
c | channel to run the pbx on |
Definition at line 2682 of file pbx.c.
References __ast_pbx_run(), AST_PBX_CALL_LIMIT, AST_PBX_SUCCESS, decrease_call_count(), and increase_call_count().
Referenced by ast_pbx_outgoing_exten(), async_wait(), do_idle_thread(), mgcp_ss(), skinny_newcall(), and ss_thread().
02683 { 02684 enum ast_pbx_result res = AST_PBX_SUCCESS; 02685 02686 if (increase_call_count(c)) 02687 return AST_PBX_CALL_LIMIT; 02688 02689 res = __ast_pbx_run(c); 02690 decrease_call_count(); 02691 02692 return res; 02693 }
enum ast_pbx_result ast_pbx_start | ( | struct ast_channel * | c | ) |
Create a new thread and start the PBX.
c | channel to start the pbx on |
Definition at line 2655 of file pbx.c.
References ast_log(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_pthread_create, decrease_call_count(), increase_call_count(), LOG_WARNING, pbx_thread(), and t.
Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_exten(), check_goto_on_transfer(), dahdi_new(), do_parking_thread(), gtalk_new(), gtalk_newcall(), handle_request_invite(), local_call(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), and skinny_new().
02656 { 02657 pthread_t t; 02658 pthread_attr_t attr; 02659 02660 if (!c) { 02661 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02662 return AST_PBX_FAILED; 02663 } 02664 02665 if (increase_call_count(c)) 02666 return AST_PBX_CALL_LIMIT; 02667 02668 /* Start a new thread, and get something handling this channel. */ 02669 pthread_attr_init(&attr); 02670 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02671 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02672 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02673 pthread_attr_destroy(&attr); 02674 decrease_call_count(); 02675 return AST_PBX_FAILED; 02676 } 02677 pthread_attr_destroy(&attr); 02678 02679 return AST_PBX_SUCCESS; 02680 }
int ast_rdlock_contexts | ( | void | ) |
Definition at line 6252 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(), 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().
06253 { 06254 return ast_rwlock_rdlock(&conlock); 06255 }
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 2984 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().
02985 { 02986 struct ast_app *tmp, *cur = NULL; 02987 char tmps[80]; 02988 int length; 02989 02990 AST_LIST_LOCK(&apps); 02991 AST_LIST_TRAVERSE(&apps, tmp, list) { 02992 if (!strcasecmp(app, tmp->name)) { 02993 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02994 AST_LIST_UNLOCK(&apps); 02995 return -1; 02996 } 02997 } 02998 02999 length = sizeof(*tmp) + strlen(app) + 1; 03000 03001 if (!(tmp = ast_calloc(1, length))) { 03002 AST_LIST_UNLOCK(&apps); 03003 return -1; 03004 } 03005 03006 strcpy(tmp->name, app); 03007 tmp->execute = execute; 03008 tmp->synopsis = synopsis; 03009 tmp->description = description; 03010 03011 /* Store in alphabetical order */ 03012 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 03013 if (strcasecmp(tmp->name, cur->name) < 0) { 03014 AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 03015 break; 03016 } 03017 } 03018 AST_LIST_TRAVERSE_SAFE_END 03019 if (!cur) 03020 AST_LIST_INSERT_TAIL(&apps, tmp, list); 03021 03022 if (option_verbose > 1) 03023 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 03024 03025 AST_LIST_UNLOCK(&apps); 03026 03027 return 0; 03028 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 3034 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().
03035 { 03036 struct ast_switch *tmp; 03037 03038 AST_LIST_LOCK(&switches); 03039 AST_LIST_TRAVERSE(&switches, tmp, list) { 03040 if (!strcasecmp(tmp->name, sw->name)) { 03041 AST_LIST_UNLOCK(&switches); 03042 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 03043 return -1; 03044 } 03045 } 03046 AST_LIST_INSERT_TAIL(&switches, sw, list); 03047 AST_LIST_UNLOCK(&switches); 03048 03049 return 0; 03050 }
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 2341 of file pbx.c.
References E_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), _macro_exec(), ast_bridge_call(), and loopback_exec().
02342 { 02343 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN); 02344 }
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 6275 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().
06276 { 06277 return ast_mutex_unlock(&con->lock); 06278 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 6262 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_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().
06263 { 06264 return ast_rwlock_unlock(&conlock); 06265 }
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 3865 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().
03866 { 03867 struct ast_app *tmp; 03868 03869 AST_LIST_LOCK(&apps); 03870 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03871 if (!strcasecmp(app, tmp->name)) { 03872 AST_LIST_REMOVE_CURRENT(&apps, list); 03873 if (option_verbose > 1) 03874 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03875 free(tmp); 03876 break; 03877 } 03878 } 03879 AST_LIST_TRAVERSE_SAFE_END 03880 AST_LIST_UNLOCK(&apps); 03881 03882 return tmp ? 0 : -1; 03883 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 3052 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().
03053 { 03054 AST_LIST_LOCK(&switches); 03055 AST_LIST_REMOVE(&switches, sw, list); 03056 AST_LIST_UNLOCK(&switches); 03057 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | priority | |||
) |
Definition at line 6384 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().
06386 { 06387 if (!exten) 06388 return con ? con->root : NULL; 06389 else 06390 return exten->next; 06391 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 6417 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().
06419 { 06420 if (!ip) 06421 return con ? con->ignorepats : NULL; 06422 else 06423 return ip->next; 06424 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 6408 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().
06410 { 06411 if (!inc) 06412 return con ? con->includes : NULL; 06413 else 06414 return inc->next; 06415 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 6393 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().
06395 { 06396 if (!sw) 06397 return con ? AST_LIST_FIRST(&con->alts) : NULL; 06398 else 06399 return AST_LIST_NEXT(sw, list); 06400 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 6379 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 6402 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 6257 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().
06258 { 06259 return ast_rwlock_wrlock(&conlock); 06260 }
void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 6023 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().
06024 { 06025 struct ast_var_t *vardata; 06026 06027 ast_mutex_lock(&globalslock); 06028 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06029 ast_var_delete(vardata); 06030 ast_mutex_unlock(&globalslock); 06031 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5800 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(), 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().
05801 { 05802 struct ast_var_t *variables; 05803 const char *ret = NULL; 05804 int i; 05805 struct varshead *places[2] = { NULL, &globals }; 05806 05807 if (!name) 05808 return NULL; 05809 05810 if (chan) { 05811 ast_channel_lock(chan); 05812 places[0] = &chan->varshead; 05813 } 05814 05815 for (i = 0; i < 2; i++) { 05816 if (!places[i]) 05817 continue; 05818 if (places[i] == &globals) 05819 ast_mutex_lock(&globalslock); 05820 AST_LIST_TRAVERSE(places[i], variables, entries) { 05821 if (!strcmp(name, ast_var_name(variables))) { 05822 ret = ast_var_value(variables); 05823 break; 05824 } 05825 } 05826 if (places[i] == &globals) 05827 ast_mutex_unlock(&globalslock); 05828 if (ret) 05829 break; 05830 } 05831 05832 if (chan) 05833 ast_channel_unlock(chan); 05834 05835 return ret; 05836 }
void pbx_builtin_pushvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5838 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().
05839 { 05840 struct ast_var_t *newvariable; 05841 struct varshead *headp; 05842 05843 if (name[strlen(name)-1] == ')') { 05844 char *function = ast_strdupa(name); 05845 05846 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05847 ast_func_write(chan, function, value); 05848 return; 05849 } 05850 05851 if (chan) { 05852 ast_channel_lock(chan); 05853 headp = &chan->varshead; 05854 } else { 05855 ast_mutex_lock(&globalslock); 05856 headp = &globals; 05857 } 05858 05859 if (value) { 05860 if ((option_verbose > 1) && (headp == &globals)) 05861 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05862 newvariable = ast_var_assign(name, value); 05863 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05864 } 05865 05866 if (chan) 05867 ast_channel_unlock(chan); 05868 else 05869 ast_mutex_unlock(&globalslock); 05870 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5769 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().
05770 { 05771 struct ast_var_t *variables; 05772 const char *var, *val; 05773 int total = 0; 05774 05775 if (!chan) 05776 return 0; 05777 05778 memset(buf, 0, size); 05779 05780 ast_channel_lock(chan); 05781 05782 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05783 if ((var=ast_var_name(variables)) && (val=ast_var_value(variables)) 05784 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 05785 ) { 05786 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05787 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05788 break; 05789 } else 05790 total++; 05791 } else 05792 break; 05793 } 05794 05795 ast_channel_unlock(chan); 05796 05797 return total; 05798 }
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 5872 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().
05873 { 05874 struct ast_var_t *newvariable; 05875 struct varshead *headp; 05876 const char *nametail = name; 05877 05878 if (name[strlen(name)-1] == ')') { 05879 char *function = ast_strdupa(name); 05880 05881 ast_func_write(chan, function, value); 05882 return; 05883 } 05884 05885 if (chan) { 05886 ast_channel_lock(chan); 05887 headp = &chan->varshead; 05888 } else { 05889 ast_mutex_lock(&globalslock); 05890 headp = &globals; 05891 } 05892 05893 /* For comparison purposes, we have to strip leading underscores */ 05894 if (*nametail == '_') { 05895 nametail++; 05896 if (*nametail == '_') 05897 nametail++; 05898 } 05899 05900 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05901 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 05902 /* there is already such a variable, delete it */ 05903 AST_LIST_REMOVE(headp, newvariable, entries); 05904 ast_var_delete(newvariable); 05905 break; 05906 } 05907 } 05908 05909 if (value) { 05910 if ((option_verbose > 1) && (headp == &globals)) 05911 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05912 newvariable = ast_var_assign(name, value); 05913 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05914 } 05915 05916 if (chan) 05917 ast_channel_unlock(chan); 05918 else 05919 ast_mutex_unlock(&globalslock); 05920 }
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 6033 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().
06034 { 06035 if (ast_strlen_zero(condition)) /* NULL or empty strings are false */ 06036 return 0; 06037 else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */ 06038 return atoi(condition); 06039 else /* Strings are true */ 06040 return 1; 06041 }
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 2700 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
02701 { 02702 int oldval = autofallthrough; 02703 autofallthrough = newval; 02704 return oldval; 02705 }
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 }