#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/linkedlists.h"
Include dependency graph for pbx.h:
This graph shows which files directly or indirectly include this file:
Go to the source code of this file.
Data Structures | |
struct | ast_custom_function |
Data structure associated with a custom dialplan function. More... | |
struct | ast_pbx |
struct | ast_switch |
struct | ast_timing |
Defines | |
#define | AST_MAX_APP 32 |
#define | AST_PBX_KEEP 0 |
#define | AST_PBX_KEEPALIVE 10 |
Special return values from applications to the PBX {. | |
#define | AST_PBX_NO_HANGUP_PEER 11 |
#define | AST_PBX_REPLACE 1 |
#define | PRIORITY_HINT -1 |
Typedefs | |
typedef int(*) | ast_state_cb_type (char *context, char *id, enum ast_extension_states state, void *data) |
Typedef for devicestate and hint callbacks. | |
typedef int( | ast_switch_f )(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
All switch functions have the same interface, so define a type for them. | |
Enumerations | |
enum | ast_extension_states { AST_EXTENSION_REMOVED = -2, AST_EXTENSION_DEACTIVATED = -1, AST_EXTENSION_NOT_INUSE = 0, AST_EXTENSION_INUSE = 1 << 0, AST_EXTENSION_BUSY = 1 << 1, AST_EXTENSION_UNAVAILABLE = 1 << 2, AST_EXTENSION_RINGING = 1 << 3, AST_EXTENSION_ONHOLD = 1 << 4 } |
Extension states. More... | |
enum | ast_pbx_result { AST_PBX_SUCCESS = 0, AST_PBX_FAILED = -1, AST_PBX_CALL_LIMIT = -2 } |
The result codes when starting the PBX on a channel with ast_pbx_start(). More... | |
Functions | |
int | ast_active_calls (void) |
Retrieve the number of active calls. | |
int | ast_add_extension (const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar) |
Add and extension to an extension context. | |
int | ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar) |
Add an extension to an extension context, this time with an ast_context *. | |
int | ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority) |
int | ast_async_goto_by_name (const char *chan, const char *context, const char *exten, int priority) |
int | ast_async_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
int | ast_build_timing (struct ast_timing *i, const char *info) |
int | ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
Looks for a valid matching extension. | |
int | ast_check_timing (const struct ast_timing *i) |
int | ast_context_add_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
Add an ignorepat. | |
int | ast_context_add_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar) |
int | ast_context_add_include (const char *context, const char *include, const char *registrar) |
Add a context include. | |
int | ast_context_add_include2 (struct ast_context *con, const char *include, const char *registrar) |
Add a context include. | |
int | ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar) |
Add a switch. | |
int | ast_context_add_switch2 (struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar) |
Adds a switch (first param is a ast_context). | |
ast_context * | ast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar) |
Register a new context. | |
void | ast_context_destroy (struct ast_context *con, const char *registrar) |
Destroy a context (matches the specified context (or ANY context if NULL). | |
ast_context * | ast_context_find (const char *name) |
Find a context. | |
ast_context * | ast_context_find_or_create (struct ast_context **extcontexts, const char *name, const char *registrar) |
Register a new context or find an existing one. | |
int | ast_context_lockmacro (const char *macrocontext) |
locks the macrolock in the given given context | |
int | ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar) |
Simply remove extension from context. | |
int | ast_context_remove_extension2 (struct ast_context *con, const char *extension, int priority, const char *registrar) |
This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return. | |
int | ast_context_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
int | ast_context_remove_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar) |
int | ast_context_remove_include (const char *context, const char *include, const char *registrar) |
Remove a context include. | |
int | ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar) |
Removes an include by an ast_context structure. | |
int | ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar) |
Remove a switch. | |
int | ast_context_remove_switch2 (struct ast_context *con, const char *sw, const char *data, const char *registrar) |
This function locks given context, removes switch, unlock context and return. | |
int | ast_context_unlockmacro (const char *macrocontext) |
Unlocks the macrolock in the given context. | |
int | ast_context_verify_includes (struct ast_context *con) |
Verifies includes in an ast_contect structure. | |
ast_custom_function * | ast_custom_function_find (const char *name) |
int | ast_custom_function_register (struct ast_custom_function *acf) |
Reigster a custom function. | |
int | ast_custom_function_unregister (struct ast_custom_function *acf) |
Unregister a custom function. | |
int | ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
Determine whether an extension exists. | |
int | ast_explicit_goto (struct ast_channel *chan, const char *context, const char *exten, int priority) |
int | ast_extension_close (const char *pattern, const char *data, int needmore) |
int | ast_extension_match (const char *pattern, const char *extension) |
Determine if a given extension matches a given pattern (in NXX format). | |
int | ast_extension_patmatch (const char *pattern, const char *data) |
int | ast_extension_state (struct ast_channel *c, const char *context, const char *exten) |
Uses hint and devicestate callback to get the state of an extension. | |
const char * | ast_extension_state2str (int extension_state) |
Return string representation of the state of an extension. | |
int | ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data) |
Registers a state change callback. | |
int | ast_extension_state_del (int id, ast_state_cb_type callback) |
Deletes a registered state change callback by ID. | |
int | ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid) |
Find the priority of an extension that has the specified label. | |
int | ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid) |
Find the priority of an extension that has the specified label. | |
int | ast_func_read (struct ast_channel *chan, char *function, char *workspace, size_t len) |
executes a read operation on a function | |
int | ast_func_write (struct ast_channel *chan, char *function, const char *value) |
executes a write operation on a function | |
int | ast_get_hint (char *hint, int maxlen, char *name, int maxnamelen, struct ast_channel *c, const char *context, const char *exten) |
If an extension hint exists, return non-zero. | |
int | ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
void | ast_hint_state_changed (const char *device) |
int | ast_ignore_pattern (const char *context, const char *pattern) |
Checks to see if a number should be ignored. | |
int | ast_lock_context (struct ast_context *con) |
Locks a given context. | |
int | ast_lock_contexts (void) |
Locks the context list. | |
int | ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
Looks to see if adding anything to this extension might match something. (exists ^ canmatch). | |
void | ast_merge_contexts_and_delete (struct ast_context **extcontexts, const char *registrar) |
Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added. | |
int | ast_parseable_goto (struct ast_channel *chan, const char *goto_string) |
int | ast_pbx_outgoing_app (const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) |
int | ast_pbx_outgoing_exten (const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) |
enum ast_pbx_result | ast_pbx_run (struct ast_channel *c) |
Execute the PBX in the current thread. | |
enum ast_pbx_result | ast_pbx_start (struct ast_channel *c) |
Create a new thread and start the PBX. | |
int | ast_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) |
void | pbx_builtin_clear_globals (void) |
const char * | pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name) |
void | pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value) |
int | pbx_builtin_serialize_variables (struct ast_channel *chan, char *buf, size_t size) |
int | pbx_builtin_setvar (struct ast_channel *chan, void *data) |
void | pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value) |
int | pbx_checkcondition (const char *condition) |
Evaluate a condition. | |
int | pbx_exec (struct ast_channel *c, struct ast_app *app, void *data) |
Execute an application. | |
ast_app * | pbx_findapp (const char *app) |
Look up an application. | |
void | pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp) |
Support for Asterisk built-in variables and functions in the dialplan. | |
int | pbx_set_autofallthrough (int newval) |
void | pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count) |
void | pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count) |
Functions for returning values from structures | |
const char * | ast_get_context_name (struct ast_context *con) |
ast_context * | ast_get_extension_context (struct ast_exten *exten) |
const char * | ast_get_extension_name (struct ast_exten *exten) |
const char * | ast_get_ignorepat_name (struct ast_ignorepat *ip) |
const char * | ast_get_include_name (struct ast_include *include) |
const char * | ast_get_switch_data (struct ast_sw *sw) |
const char * | ast_get_switch_name (struct ast_sw *sw) |
Registrar info functions ... | |
const char * | ast_get_context_registrar (struct ast_context *c) |
const char * | ast_get_extension_registrar (struct ast_exten *e) |
const char * | ast_get_ignorepat_registrar (struct ast_ignorepat *ip) |
const char * | ast_get_include_registrar (struct ast_include *i) |
const char * | ast_get_switch_registrar (struct ast_sw *sw) |
Other Extension stuff | |
const char * | ast_get_extension_app (struct ast_exten *e) |
void * | ast_get_extension_app_data (struct ast_exten *e) |
const char * | ast_get_extension_cidmatch (struct ast_exten *e) |
const char * | ast_get_extension_label (struct ast_exten *e) |
int | ast_get_extension_matchcid (struct ast_exten *e) |
int | ast_get_extension_priority (struct ast_exten *exten) |
Definition in file pbx.h.
#define AST_MAX_APP 32 |
Max length of an application
Definition at line 34 of file pbx.h.
Referenced by destroy_station(), handle_show_application(), handle_show_application_deprecated(), handle_show_function(), and handle_show_function_deprecated().
#define AST_PBX_KEEPALIVE 10 |
Special return values from applications to the PBX {.
Destroy the thread, but don't hang up the channel
Definition at line 40 of file pbx.h.
Referenced by __ast_pbx_run(), _macro_exec(), agi_handle_command(), builtin_blindtransfer(), builtin_parkcall(), feature_exec_app(), park_call_exec(), queue_exec(), rpt_exec(), and run_agi().
#define AST_PBX_NO_HANGUP_PEER 11 |
Definition at line 41 of file pbx.h.
Referenced by builtin_blindtransfer(), builtin_parkcall(), feature_exec_app(), park_exec(), and try_calling().
#define PRIORITY_HINT -1 |
} Special Priority for a hint
Definition at line 44 of file pbx.h.
Referenced by add_extensions(), add_pri(), ast_add_extension2(), ast_hint_extension(), destroy_exten(), destroy_station(), handle_context_add_extension(), handle_context_add_extension_deprecated(), handle_context_remove_extension(), handle_context_remove_extension_deprecated(), handle_save_dialplan(), park_add_hints(), pbx_load_config(), and print_ext().
typedef int(*) ast_state_cb_type(char *context, char *id, enum ast_extension_states state, void *data) |
typedef int( ast_switch_f)(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
enum ast_extension_states |
Extension states.
Definition at line 50 of file pbx.h.
00050 { 00051 AST_EXTENSION_REMOVED = -2, /*!< Extension removed */ 00052 AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */ 00053 AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */ 00054 AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */ 00055 AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */ 00056 AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */ 00057 AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */ 00058 AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */ 00059 };
enum ast_pbx_result |
The result codes when starting the PBX on a channel with ast_pbx_start().
AST_PBX_CALL_LIMIT refers to the maxcalls call limit in asterisk.conf
Definition at line 236 of file pbx.h.
00236 { 00237 AST_PBX_SUCCESS = 0, 00238 AST_PBX_FAILED = -1, 00239 AST_PBX_CALL_LIMIT = -2, 00240 };
int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 2654 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02655 { 02656 return countcalls; 02657 }
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 4534 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().
04537 { 04538 int ret = -1; 04539 struct ast_context *c = find_context_locked(context); 04540 04541 if (c) { 04542 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04543 application, data, datad, registrar); 04544 ast_unlock_contexts(); 04545 } 04546 return ret; 04547 }
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 4738 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, ext_cmp(), ext_strncpy(), ast_exten::exten, ast_exten::label, ast_context::lock, ast_exten::matchcid, ast_exten::next, option_verbose, ast_exten::parent, pbx_substitute_variables_varshead(), ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, ast_context::root, ast_exten::stuff, VAR_BUF_SIZE, and VERBOSE_PREFIX_3.
Referenced by add_extensions(), ast_add_extension(), ast_park_call(), do_parking_thread(), pbx_load_config(), and pbx_load_users().
04742 { 04743 /* 04744 * Sort extensions (or patterns) according to the rules indicated above. 04745 * These are implemented by the function ext_cmp()). 04746 * All priorities for the same ext/pattern/cid are kept in a list, 04747 * using the 'peer' field as a link field.. 04748 */ 04749 struct ast_exten *tmp, *e, *el = NULL; 04750 int res; 04751 int length; 04752 char *p; 04753 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04754 04755 /* if we are adding a hint, and there are global variables, and the hint 04756 contains variable references, then expand them 04757 */ 04758 ast_mutex_lock(&globalslock); 04759 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04760 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04761 application = expand_buf; 04762 } 04763 ast_mutex_unlock(&globalslock); 04764 04765 length = sizeof(struct ast_exten); 04766 length += strlen(extension) + 1; 04767 length += strlen(application) + 1; 04768 if (label) 04769 length += strlen(label) + 1; 04770 if (callerid) 04771 length += strlen(callerid) + 1; 04772 else 04773 length ++; /* just the '\0' */ 04774 04775 /* Be optimistic: Build the extension structure first */ 04776 if (!(tmp = ast_calloc(1, length))) 04777 return -1; 04778 04779 /* use p as dst in assignments, as the fields are const char * */ 04780 p = tmp->stuff; 04781 if (label) { 04782 tmp->label = p; 04783 strcpy(p, label); 04784 p += strlen(label) + 1; 04785 } 04786 tmp->exten = p; 04787 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04788 tmp->priority = priority; 04789 tmp->cidmatch = p; /* but use p for assignments below */ 04790 if (callerid) { 04791 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04792 tmp->matchcid = 1; 04793 } else { 04794 *p++ = '\0'; 04795 tmp->matchcid = 0; 04796 } 04797 tmp->app = p; 04798 strcpy(p, application); 04799 tmp->parent = con; 04800 tmp->data = data; 04801 tmp->datad = datad; 04802 tmp->registrar = registrar; 04803 04804 ast_mutex_lock(&con->lock); 04805 res = 0; /* some compilers will think it is uninitialized otherwise */ 04806 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04807 res = ext_cmp(e->exten, extension); 04808 if (res == 0) { /* extension match, now look at cidmatch */ 04809 if (!e->matchcid && !tmp->matchcid) 04810 res = 0; 04811 else if (tmp->matchcid && !e->matchcid) 04812 res = 1; 04813 else if (e->matchcid && !tmp->matchcid) 04814 res = -1; 04815 else 04816 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04817 } 04818 if (res >= 0) 04819 break; 04820 } 04821 if (e && res == 0) { /* exact match, insert in the pri chain */ 04822 res = add_pri(con, tmp, el, e, replace); 04823 ast_mutex_unlock(&con->lock); 04824 if (res < 0) { 04825 errno = EEXIST; /* XXX do we care ? */ 04826 return 0; /* XXX should we return -1 maybe ? */ 04827 } 04828 } else { 04829 /* 04830 * not an exact match, this is the first entry with this pattern, 04831 * so insert in the main list right before 'e' (if any) 04832 */ 04833 tmp->next = e; 04834 if (el) 04835 el->next = tmp; 04836 else 04837 con->root = tmp; 04838 ast_mutex_unlock(&con->lock); 04839 if (tmp->priority == PRIORITY_HINT) 04840 ast_add_hint(tmp); 04841 } 04842 if (option_debug) { 04843 if (tmp->matchcid) { 04844 if (option_debug) 04845 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04846 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04847 } else { 04848 if (option_debug) 04849 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04850 tmp->exten, tmp->priority, con->name); 04851 } 04852 } 04853 if (option_verbose > 2) { 04854 if (tmp->matchcid) { 04855 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04856 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04857 } else { 04858 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04859 tmp->exten, tmp->priority, con->name); 04860 } 04861 } 04862 return 0; 04863 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4568 of file pbx.c.
References ast_channel::_state, ast_channel::amaflags, ast_cdr_dup(), ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_unlock, ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_pbx_start(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_channel::cdr, ast_channel::context, ast_channel::exten, LOG_WARNING, ast_channel::pbx, ast_channel::readformat, S_OR, and ast_channel::writeformat.
Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), console_transfer_deprecated(), handle_request_bye(), handle_request_refer(), process_ast_dsp(), socket_process(), and zt_handle_dtmfup().
04569 { 04570 int res = 0; 04571 04572 ast_channel_lock(chan); 04573 04574 if (chan->pbx) { /* This channel is currently in the PBX */ 04575 ast_explicit_goto(chan, context, exten, priority); 04576 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04577 } else { 04578 /* In order to do it when the channel doesn't really exist within 04579 the PBX, we have to make a new channel, masquerade, and start the PBX 04580 at the new location */ 04581 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04582 if (chan->cdr) { 04583 tmpchan->cdr = ast_cdr_dup(chan->cdr); 04584 } 04585 if (!tmpchan) 04586 res = -1; 04587 else { 04588 /* Make formats okay */ 04589 tmpchan->readformat = chan->readformat; 04590 tmpchan->writeformat = chan->writeformat; 04591 /* Setup proper location */ 04592 ast_explicit_goto(tmpchan, 04593 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04594 04595 /* Masquerade into temp channel */ 04596 ast_channel_masquerade(tmpchan, chan); 04597 04598 /* Grab the locks and get going */ 04599 ast_channel_lock(tmpchan); 04600 ast_do_masquerade(tmpchan); 04601 ast_channel_unlock(tmpchan); 04602 /* Start the PBX going on our stolen channel */ 04603 if (ast_pbx_start(tmpchan)) { 04604 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04605 ast_hangup(tmpchan); 04606 res = -1; 04607 } 04608 } 04609 } 04610 ast_channel_unlock(chan); 04611 return res; 04612 }
int ast_async_goto_by_name | ( | const char * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4614 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04615 { 04616 struct ast_channel *chan; 04617 int res = -1; 04618 04619 chan = ast_get_channel_by_name_locked(channame); 04620 if (chan) { 04621 res = ast_async_goto(chan, context, exten, priority); 04622 ast_channel_unlock(chan); 04623 } 04624 return res; 04625 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6293 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06294 { 06295 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06296 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info | |||
) |
Definition at line 4210 of file pbx.c.
References ast_strlen_zero(), ast_timing::daymask, days, ast_timing::dowmask, get_range(), get_timerange(), ast_timing::monthmask, months, and strsep().
Referenced by ast_context_add_include2(), iftime(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
04211 { 04212 char info_save[256]; 04213 char *info; 04214 04215 /* Check for empty just in case */ 04216 if (ast_strlen_zero(info_in)) 04217 return 0; 04218 /* make a copy just in case we were passed a static string */ 04219 ast_copy_string(info_save, info_in, sizeof(info_save)); 04220 info = info_save; 04221 /* Assume everything except time */ 04222 i->monthmask = 0xfff; /* 12 bits */ 04223 i->daymask = 0x7fffffffU; /* 31 bits */ 04224 i->dowmask = 0x7f; /* 7 bits */ 04225 /* on each call, use strsep() to move info to the next argument */ 04226 get_timerange(i, strsep(&info, "|")); 04227 if (info) 04228 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04229 if (info) 04230 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04231 if (info) 04232 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04233 return 1; 04234 }
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 2282 of file pbx.c.
References E_CANMATCH, and pbx_extension_helper().
Referenced by background_detect_exec(), cb_events(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), handle_link_data(), handle_link_phone_dtmf(), local_dtmf_helper(), loopback_canmatch(), mgcp_ss(), nv_background_detect_exec(), nv_detectfax_exec(), phone_check_exception(), skinny_ss(), ss_thread(), and valid_exit().
02283 { 02284 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH); 02285 }
int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 4236 of file pbx.c.
References 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().
04237 { 04238 struct tm tm; 04239 time_t t = time(NULL); 04240 04241 localtime_r(&t,&tm); 04242 04243 /* If it's not the right month, return */ 04244 if (!(i->monthmask & (1 << tm.tm_mon))) 04245 return 0; 04246 04247 /* If it's not that time of the month.... */ 04248 /* Warning, tm_mday has range 1..31! */ 04249 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04250 return 0; 04251 04252 /* If it's not the right day of the week */ 04253 if (!(i->dowmask & (1 << tm.tm_wday))) 04254 return 0; 04255 04256 /* Sanity check the hour just to be safe */ 04257 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04258 ast_log(LOG_WARNING, "Insane time...\n"); 04259 return 0; 04260 } 04261 04262 /* Now the tough part, we calculate if it fits 04263 in the right time based on min/hour */ 04264 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04265 return 0; 04266 04267 /* If we got this far, then we're good */ 04268 return 1; 04269 }
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 4470 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().
04471 { 04472 int ret = -1; 04473 struct ast_context *c = find_context_locked(context); 04474 04475 if (c) { 04476 ret = ast_context_add_ignorepat2(c, value, registrar); 04477 ast_unlock_contexts(); 04478 } 04479 return ret; 04480 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4482 of file pbx.c.
References ast_calloc, ast_mutex_lock(), ast_mutex_unlock(), ast_context::ignorepats, ast_context::lock, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.
Referenced by ast_compile_ael2(), ast_context_add_ignorepat(), and pbx_load_config().
04483 { 04484 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04485 int length; 04486 length = sizeof(struct ast_ignorepat); 04487 length += strlen(value) + 1; 04488 if (!(ignorepat = ast_calloc(1, length))) 04489 return -1; 04490 /* The cast to char * is because we need to write the initial value. 04491 * The field is not supposed to be modified otherwise 04492 */ 04493 strcpy((char *)ignorepat->pattern, value); 04494 ignorepat->next = NULL; 04495 ignorepat->registrar = registrar; 04496 ast_mutex_lock(&con->lock); 04497 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04498 ignorepatl = ignorepatc; 04499 if (!strcasecmp(ignorepatc->pattern, value)) { 04500 /* Already there */ 04501 ast_mutex_unlock(&con->lock); 04502 errno = EEXIST; 04503 return -1; 04504 } 04505 } 04506 if (ignorepatl) 04507 ignorepatl->next = ignorepat; 04508 else 04509 con->ignorepats = ignorepat; 04510 ast_mutex_unlock(&con->lock); 04511 return 0; 04512 04513 }
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 4016 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().
04017 { 04018 int ret = -1; 04019 struct ast_context *c = find_context_locked(context); 04020 04021 if (c) { 04022 ret = ast_context_add_include2(c, include, registrar); 04023 ast_unlock_contexts(); 04024 } 04025 return ret; 04026 }
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 4278 of file pbx.c.
References ast_build_timing(), ast_calloc, ast_get_context_name(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), 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_compile_ael2(), ast_context_add_include(), and pbx_load_config().
04280 { 04281 struct ast_include *new_include; 04282 char *c; 04283 struct ast_include *i, *il = NULL; /* include, include_last */ 04284 int length; 04285 char *p; 04286 04287 length = sizeof(struct ast_include); 04288 length += 2 * (strlen(value) + 1); 04289 04290 /* allocate new include structure ... */ 04291 if (!(new_include = ast_calloc(1, length))) 04292 return -1; 04293 /* Fill in this structure. Use 'p' for assignments, as the fields 04294 * in the structure are 'const char *' 04295 */ 04296 p = new_include->stuff; 04297 new_include->name = p; 04298 strcpy(p, value); 04299 p += strlen(value) + 1; 04300 new_include->rname = p; 04301 strcpy(p, value); 04302 /* Strip off timing info, and process if it is there */ 04303 if ( (c = strchr(p, '|')) ) { 04304 *c++ = '\0'; 04305 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04306 } 04307 new_include->next = NULL; 04308 new_include->registrar = registrar; 04309 04310 ast_mutex_lock(&con->lock); 04311 04312 /* ... go to last include and check if context is already included too... */ 04313 for (i = con->includes; i; i = i->next) { 04314 if (!strcasecmp(i->name, new_include->name)) { 04315 free(new_include); 04316 ast_mutex_unlock(&con->lock); 04317 errno = EEXIST; 04318 return -1; 04319 } 04320 il = i; 04321 } 04322 04323 /* ... include new context into context list, unlock, return */ 04324 if (il) 04325 il->next = new_include; 04326 else 04327 con->includes = new_include; 04328 if (option_verbose > 2) 04329 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04330 ast_mutex_unlock(&con->lock); 04331 04332 return 0; 04333 }
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 4340 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04341 { 04342 int ret = -1; 04343 struct ast_context *c = find_context_locked(context); 04344 04345 if (c) { /* found, add switch to this context */ 04346 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04347 ast_unlock_contexts(); 04348 } 04349 return ret; 04350 }
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 4359 of file pbx.c.
References ast_calloc, ast_get_context_name(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_sw::data, ast_sw::eval, free, ast_context::lock, ast_sw::name, option_verbose, ast_sw::registrar, SWITCH_DATA_LENGTH, and VERBOSE_PREFIX_3.
Referenced by ast_compile_ael2(), ast_context_add_switch(), and pbx_load_config().
04361 { 04362 struct ast_sw *new_sw; 04363 struct ast_sw *i; 04364 int length; 04365 char *p; 04366 04367 length = sizeof(struct ast_sw); 04368 length += strlen(value) + 1; 04369 if (data) 04370 length += strlen(data); 04371 length++; 04372 if (eval) { 04373 /* Create buffer for evaluation of variables */ 04374 length += SWITCH_DATA_LENGTH; 04375 length++; 04376 } 04377 04378 /* allocate new sw structure ... */ 04379 if (!(new_sw = ast_calloc(1, length))) 04380 return -1; 04381 /* ... fill in this structure ... */ 04382 p = new_sw->stuff; 04383 new_sw->name = p; 04384 strcpy(new_sw->name, value); 04385 p += strlen(value) + 1; 04386 new_sw->data = p; 04387 if (data) { 04388 strcpy(new_sw->data, data); 04389 p += strlen(data) + 1; 04390 } else { 04391 strcpy(new_sw->data, ""); 04392 p++; 04393 } 04394 if (eval) 04395 new_sw->tmpdata = p; 04396 new_sw->eval = eval; 04397 new_sw->registrar = registrar; 04398 04399 /* ... try to lock this context ... */ 04400 ast_mutex_lock(&con->lock); 04401 04402 /* ... go to last sw and check if context is already swd too... */ 04403 AST_LIST_TRAVERSE(&con->alts, i, list) { 04404 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04405 free(new_sw); 04406 ast_mutex_unlock(&con->lock); 04407 errno = EEXIST; 04408 return -1; 04409 } 04410 } 04411 04412 /* ... sw new context into context list, unlock, return */ 04413 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04414 04415 if (option_verbose > 2) 04416 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04417 04418 ast_mutex_unlock(&con->lock); 04419 04420 return 0; 04421 }
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 3887 of file pbx.c.
References __ast_context_create().
Referenced by ast_compile_ael2(), ast_park_call(), do_parking_thread(), and set_config().
03888 { 03889 return __ast_context_create(extcontexts, name, registrar, 0); 03890 }
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 5338 of file pbx.c.
References __ast_context_destroy().
Referenced by cleanup_stale_contexts(), and unload_module().
05339 { 05340 __ast_context_destroy(con,registrar); 05341 }
struct ast_context* ast_context_find | ( | const char * | name | ) |
Find a context.
name | name of the context to find |
Definition at line 892 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), and ast_walk_contexts().
Referenced by _macro_exec(), ast_context_verify_includes(), ast_ignore_pattern(), ast_park_call(), cleanup_stale_contexts(), do_parking_thread(), park_exec(), register_peer_exten(), and set_config().
00893 { 00894 struct ast_context *tmp = NULL; 00895 ast_mutex_lock(&conlock); 00896 while ( (tmp = ast_walk_contexts(tmp)) ) { 00897 if (!name || !strcasecmp(name, tmp->name)) 00898 break; 00899 } 00900 ast_mutex_unlock(&conlock); 00901 return tmp; 00902 }
struct ast_context* ast_context_find_or_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar | |||
) |
Register a new context or find an existing one.
extcontexts | pointer to the ast_context structure pointer | |
name | name of the new context | |
registrar | registrar of the context |
Definition at line 3892 of file pbx.c.
References __ast_context_create().
Referenced by pbx_load_config(), and pbx_load_users().
03893 { 03894 return __ast_context_create(extcontexts, name, registrar, 1); 03895 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 2891 of file pbx.c.
References ast_get_context_name(), ast_lock_contexts(), ast_mutex_lock(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by _macro_exec().
02892 { 02893 struct ast_context *c = NULL; 02894 int ret = -1; 02895 02896 ast_lock_contexts(); 02897 02898 while ((c = ast_walk_contexts(c))) { 02899 if (!strcmp(ast_get_context_name(c), context)) { 02900 ret = 0; 02901 break; 02902 } 02903 } 02904 02905 ast_unlock_contexts(); 02906 02907 /* if we found context, lock macrolock */ 02908 if (ret == 0) 02909 ret = ast_mutex_lock(&c->macrolock); 02910 02911 return ret; 02912 }
int ast_context_remove_extension | ( | const char * | context, | |
const char * | extension, | |||
int | priority, | |||
const char * | registrar | |||
) |
Simply remove extension from context.
context | context to remove extension from | |
extension | which extension to remove | |
priority | priority of extension to remove | |
registrar | registrar of the extension |
0 | on success | |
-1 | on failure |
Definition at line 2792 of file pbx.c.
References ast_context_remove_extension2(), ast_unlock_contexts(), and find_context_locked().
Referenced by destroy_station(), destroy_trunk(), handle_context_remove_extension(), handle_context_remove_extension_deprecated(), and register_peer_exten().
02793 { 02794 int ret = -1; /* default error return */ 02795 struct ast_context *c = find_context_locked(context); 02796 02797 if (c) { /* ... remove extension ... */ 02798 ret = ast_context_remove_extension2(c, extension, priority, registrar); 02799 ast_unlock_contexts(); 02800 } 02801 return ret; 02802 }
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 2814 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), destroy_exten(), exten, ast_context::lock, ast_exten::next, ast_exten::peer, and ast_context::root.
Referenced by ast_context_remove_extension(), do_parking_thread(), and park_exec().
02815 { 02816 struct ast_exten *exten, *prev_exten = NULL; 02817 struct ast_exten *peer; 02818 02819 ast_mutex_lock(&con->lock); 02820 02821 /* scan the extension list to find matching extension-registrar */ 02822 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02823 if (!strcmp(exten->exten, extension) && 02824 (!registrar || !strcmp(exten->registrar, registrar))) 02825 break; 02826 } 02827 if (!exten) { 02828 /* we can't find right extension */ 02829 ast_mutex_unlock(&con->lock); 02830 return -1; 02831 } 02832 02833 /* should we free all peers in this extension? (priority == 0)? */ 02834 if (priority == 0) { 02835 /* remove this extension from context list */ 02836 if (prev_exten) 02837 prev_exten->next = exten->next; 02838 else 02839 con->root = exten->next; 02840 02841 /* fire out all peers */ 02842 while ( (peer = exten) ) { 02843 exten = peer->peer; /* prepare for next entry */ 02844 destroy_exten(peer); 02845 } 02846 } else { 02847 /* scan the priority list to remove extension with exten->priority == priority */ 02848 struct ast_exten *previous_peer = NULL; 02849 02850 for (peer = exten; peer; previous_peer = peer, peer = peer->peer) { 02851 if (peer->priority == priority && 02852 (!registrar || !strcmp(peer->registrar, registrar) )) 02853 break; /* found our priority */ 02854 } 02855 if (!peer) { /* not found */ 02856 ast_mutex_unlock(&con->lock); 02857 return -1; 02858 } 02859 /* we are first priority extension? */ 02860 if (!previous_peer) { 02861 /* 02862 * We are first in the priority chain, so must update the extension chain. 02863 * The next node is either the next priority or the next extension 02864 */ 02865 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02866 02867 if (!prev_exten) /* change the root... */ 02868 con->root = next_node; 02869 else 02870 prev_exten->next = next_node; /* unlink */ 02871 if (peer->peer) /* XXX update the new head of the pri list */ 02872 peer->peer->next = peer->next; 02873 } else { /* easy, we are not first priority in extension */ 02874 previous_peer->peer = peer->peer; 02875 } 02876 02877 /* now, free whole priority extension */ 02878 destroy_exten(peer); 02879 /* XXX should we return -1 ? */ 02880 } 02881 ast_mutex_unlock(&con->lock); 02882 return 0; 02883 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4427 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().
04428 { 04429 int ret = -1; 04430 struct ast_context *c = find_context_locked(context); 04431 04432 if (c) { 04433 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04434 ast_unlock_contexts(); 04435 } 04436 return ret; 04437 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4439 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), free, ast_context::ignorepats, ast_context::lock, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.
Referenced by ast_context_remove_ignorepat().
04440 { 04441 struct ast_ignorepat *ip, *ipl = NULL; 04442 04443 ast_mutex_lock(&con->lock); 04444 04445 for (ip = con->ignorepats; ip; ip = ip->next) { 04446 if (!strcmp(ip->pattern, ignorepat) && 04447 (!registrar || (registrar == ip->registrar))) { 04448 if (ipl) { 04449 ipl->next = ip->next; 04450 free(ip); 04451 } else { 04452 con->ignorepats = ip->next; 04453 free(ip); 04454 } 04455 ast_mutex_unlock(&con->lock); 04456 return 0; 04457 } 04458 ipl = ip; 04459 } 04460 04461 ast_mutex_unlock(&con->lock); 04462 errno = EINVAL; 04463 return -1; 04464 }
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 2688 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().
02689 { 02690 int ret = -1; 02691 struct ast_context *c = find_context_locked(context); 02692 02693 if (c) { 02694 /* found, remove include from this context ... */ 02695 ret = ast_context_remove_include2(c, include, registrar); 02696 ast_unlock_contexts(); 02697 } 02698 return ret; 02699 }
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 2709 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().
02710 { 02711 struct ast_include *i, *pi = NULL; 02712 int ret = -1; 02713 02714 ast_mutex_lock(&con->lock); 02715 02716 /* find our include */ 02717 for (i = con->includes; i; pi = i, i = i->next) { 02718 if (!strcmp(i->name, include) && 02719 (!registrar || !strcmp(i->registrar, registrar))) { 02720 /* remove from list */ 02721 if (pi) 02722 pi->next = i->next; 02723 else 02724 con->includes = i->next; 02725 /* free include and return */ 02726 free(i); 02727 ret = 0; 02728 break; 02729 } 02730 } 02731 02732 ast_mutex_unlock(&con->lock); 02733 return ret; 02734 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 2741 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
02742 { 02743 int ret = -1; /* default error return */ 02744 struct ast_context *c = find_context_locked(context); 02745 02746 if (c) { 02747 /* remove switch from this context ... */ 02748 ret = ast_context_remove_switch2(c, sw, data, registrar); 02749 ast_unlock_contexts(); 02750 } 02751 return ret; 02752 }
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 2762 of file pbx.c.
References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), ast_sw::data, free, ast_context::lock, ast_sw::name, and ast_sw::registrar.
Referenced by ast_context_remove_switch().
02763 { 02764 struct ast_sw *i; 02765 int ret = -1; 02766 02767 ast_mutex_lock(&con->lock); 02768 02769 /* walk switches */ 02770 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02771 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02772 (!registrar || !strcmp(i->registrar, registrar))) { 02773 /* found, remove from list */ 02774 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02775 free(i); /* free switch and return */ 02776 ret = 0; 02777 break; 02778 } 02779 } 02780 AST_LIST_TRAVERSE_SAFE_END 02781 02782 ast_mutex_unlock(&con->lock); 02783 02784 return ret; 02785 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 2919 of file pbx.c.
References ast_get_context_name(), ast_lock_contexts(), ast_mutex_unlock(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by _macro_exec().
02920 { 02921 struct ast_context *c = NULL; 02922 int ret = -1; 02923 02924 ast_lock_contexts(); 02925 02926 while ((c = ast_walk_contexts(c))) { 02927 if (!strcmp(ast_get_context_name(c), context)) { 02928 ret = 0; 02929 break; 02930 } 02931 } 02932 02933 ast_unlock_contexts(); 02934 02935 /* if we found context, unlock macrolock */ 02936 if (ret == 0) 02937 ret = ast_mutex_unlock(&c->macrolock); 02938 02939 return ret; 02940 }
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 6254 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().
06255 { 06256 struct ast_include *inc = NULL; 06257 int res = 0; 06258 06259 while ( (inc = ast_walk_context_includes(con, inc)) ) 06260 if (!ast_context_find(inc->rname)) { 06261 res = -1; 06262 ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n", 06263 ast_get_context_name(con), inc->rname); 06264 } 06265 return res; 06266 }
struct ast_custom_function* ast_custom_function_find | ( | const char * | name | ) |
Definition at line 1433 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_custom_function::name.
Referenced by ast_custom_function_register(), ast_func_read(), ast_func_write(), handle_show_function(), and handle_show_function_deprecated().
01434 { 01435 struct ast_custom_function *acf = NULL; 01436 01437 AST_LIST_LOCK(&acf_root); 01438 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01439 if (!strcmp(name, acf->name)) 01440 break; 01441 } 01442 AST_LIST_UNLOCK(&acf_root); 01443 01444 return acf; 01445 }
int ast_custom_function_register | ( | struct ast_custom_function * | acf | ) |
Reigster a custom function.
Definition at line 1469 of file pbx.c.
References ast_custom_function_find(), AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), LOG_ERROR, ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by load_module(), and reload().
01470 { 01471 struct ast_custom_function *cur; 01472 01473 if (!acf) 01474 return -1; 01475 01476 AST_LIST_LOCK(&acf_root); 01477 01478 if (ast_custom_function_find(acf->name)) { 01479 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01480 AST_LIST_UNLOCK(&acf_root); 01481 return -1; 01482 } 01483 01484 /* Store in alphabetical order */ 01485 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01486 if (strcasecmp(acf->name, cur->name) < 0) { 01487 AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist); 01488 break; 01489 } 01490 } 01491 AST_LIST_TRAVERSE_SAFE_END 01492 if (!cur) 01493 AST_LIST_INSERT_TAIL(&acf_root, acf, acflist); 01494 01495 AST_LIST_UNLOCK(&acf_root); 01496 01497 if (option_verbose > 1) 01498 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01499 01500 return 0; 01501 }
int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Unregister a custom function.
Definition at line 1447 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by reload(), and unload_module().
01448 { 01449 struct ast_custom_function *cur; 01450 01451 if (!acf) 01452 return -1; 01453 01454 AST_LIST_LOCK(&acf_root); 01455 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01456 if (cur == acf) { 01457 AST_LIST_REMOVE_CURRENT(&acf_root, acflist); 01458 if (option_verbose > 1) 01459 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01460 break; 01461 } 01462 } 01463 AST_LIST_TRAVERSE_SAFE_END 01464 AST_LIST_UNLOCK(&acf_root); 01465 01466 return acf ? 0 : -1; 01467 }
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 2267 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_park_call(), ast_pbx_outgoing_exten(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), disa_exec(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), handle_stimulus_message(), leave_voicemail(), local_alloc(), local_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), misdn_overlap_dial_task(), nv_background_detect_exec(), nv_detectfax_exec(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), process_ast_dsp(), register_peer_exten(), rpt_exec(), skinny_ss(), socket_process(), ss_thread(), waitstream_core(), and zt_handle_dtmfup().
02268 { 02269 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH); 02270 }
int ast_explicit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4549 of file pbx.c.
References AST_FLAG_IN_AUTOLOOP, ast_strlen_zero(), ast_test_flag, ast_channel::context, ast_channel::exten, and ast_channel::priority.
Referenced by __ast_goto_if_exists(), ast_async_goto(), ast_parseable_goto(), builtin_atxfer(), disa_exec(), and handle_setpriority().
04550 { 04551 if (!chan) 04552 return -1; 04553 04554 if (!ast_strlen_zero(context)) 04555 ast_copy_string(chan->context, context, sizeof(chan->context)); 04556 if (!ast_strlen_zero(exten)) 04557 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04558 if (priority > -1) { 04559 chan->priority = priority; 04560 /* see flag description in channel.h for explanation */ 04561 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04562 chan->priority--; 04563 } 04564 04565 return 0; 04566 }
int ast_extension_close | ( | const char * | pattern, | |
const char * | data, | |||
int | needmore | |||
) |
Definition at line 885 of file pbx.c.
References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.
Referenced by realtime_switch_common().
00886 { 00887 if (needmore != E_MATCHMORE && needmore != E_CANMATCH) 00888 ast_log(LOG_WARNING, "invalid argument %d\n", needmore); 00889 return extension_match_core(pattern, data, needmore); 00890 }
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 880 of file pbx.c.
References E_MATCH, and extension_match_core().
Referenced by ast_ignore_pattern(), do_say(), find_matching_priority(), loopback_canmatch(), loopback_exec(), loopback_exists(), loopback_matchmore(), matchcid(), misdn_cfg_is_msn_valid(), realtime_switch_common(), and show_dialplan_helper().
00881 { 00882 return extension_match_core(pattern, data, E_MATCH); 00883 }
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 1991 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), and handle_request_subscribe().
01992 { 01993 struct ast_exten *e; 01994 01995 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 01996 if (!e) 01997 return -1; /* No hint, return -1 */ 01998 01999 return ast_extension_state2(e); /* Check all devices in the hint */ 02000 }
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 1979 of file pbx.c.
References extension_states.
Referenced by cb_extensionstate(), handle_request_subscribe(), and handle_show_hints().
01980 { 01981 int i; 01982 01983 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 01984 if (extension_states[i].extension_state == extension_state) 01985 return extension_states[i].text; 01986 } 01987 return "Unknown"; 01988 }
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 2046 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().
02048 { 02049 struct ast_hint *hint; 02050 struct ast_state_cb *cblist; 02051 struct ast_exten *e; 02052 02053 /* If there's no context and extension: add callback to statecbs list */ 02054 if (!context && !exten) { 02055 AST_LIST_LOCK(&hints); 02056 02057 for (cblist = statecbs; cblist; cblist = cblist->next) { 02058 if (cblist->callback == callback) { 02059 cblist->data = data; 02060 AST_LIST_UNLOCK(&hints); 02061 return 0; 02062 } 02063 } 02064 02065 /* Now insert the callback */ 02066 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02067 AST_LIST_UNLOCK(&hints); 02068 return -1; 02069 } 02070 cblist->id = 0; 02071 cblist->callback = callback; 02072 cblist->data = data; 02073 02074 cblist->next = statecbs; 02075 statecbs = cblist; 02076 02077 AST_LIST_UNLOCK(&hints); 02078 return 0; 02079 } 02080 02081 if (!context || !exten) 02082 return -1; 02083 02084 /* This callback type is for only one hint, so get the hint */ 02085 e = ast_hint_extension(NULL, context, exten); 02086 if (!e) { 02087 return -1; 02088 } 02089 02090 /* Find the hint in the list of hints */ 02091 AST_LIST_LOCK(&hints); 02092 02093 AST_LIST_TRAVERSE(&hints, hint, list) { 02094 if (hint->exten == e) 02095 break; 02096 } 02097 02098 if (!hint) { 02099 /* We have no hint, sorry */ 02100 AST_LIST_UNLOCK(&hints); 02101 return -1; 02102 } 02103 02104 /* Now insert the callback in the callback list */ 02105 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02106 AST_LIST_UNLOCK(&hints); 02107 return -1; 02108 } 02109 cblist->id = stateid++; /* Unique ID for this callback */ 02110 cblist->callback = callback; /* Pointer to callback routine */ 02111 cblist->data = data; /* Data for the callback */ 02112 02113 cblist->next = hint->callbacks; 02114 hint->callbacks = cblist; 02115 02116 AST_LIST_UNLOCK(&hints); 02117 return cblist->id; 02118 }
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 2121 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_hint::callbacks, free, ast_state_cb::next, and statecbs.
Referenced by __sip_destroy().
02122 { 02123 struct ast_state_cb **p_cur = NULL; /* address of pointer to us */ 02124 int ret = -1; 02125 02126 if (!id && !callback) 02127 return -1; 02128 02129 AST_LIST_LOCK(&hints); 02130 02131 if (!id) { /* id == 0 is a callback without extension */ 02132 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) { 02133 if ((*p_cur)->callback == callback) 02134 break; 02135 } 02136 } else { /* callback with extension, find the callback based on ID */ 02137 struct ast_hint *hint; 02138 AST_LIST_TRAVERSE(&hints, hint, list) { 02139 for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) { 02140 if ((*p_cur)->id == id) 02141 break; 02142 } 02143 if (*p_cur) /* found in the inner loop */ 02144 break; 02145 } 02146 } 02147 if (p_cur && *p_cur) { 02148 struct ast_state_cb *cur = *p_cur; 02149 *p_cur = cur->next; 02150 free(cur); 02151 ret = 0; 02152 } 02153 AST_LIST_UNLOCK(&hints); 02154 return ret; 02155 }
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 2272 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().
02273 { 02274 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL); 02275 }
int ast_findlabel_extension2 | ( | struct ast_channel * | c, | |
struct ast_context * | con, | |||
const char * | exten, | |||
const char * | label, | |||
const char * | callerid | |||
) |
Find the priority of an extension that has the specified label.
Definition at line 2277 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
02278 { 02279 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL); 02280 }
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 1523 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().
01524 { 01525 char *args = func_args(function); 01526 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01527 01528 if (acfptr == NULL) 01529 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01530 else if (!acfptr->read) 01531 ast_log(LOG_ERROR, "Function %s cannot be read\n", function); 01532 else 01533 return acfptr->read(chan, function, args, workspace, len); 01534 return -1; 01535 }
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 1537 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().
01538 { 01539 char *args = func_args(function); 01540 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01541 01542 if (acfptr == NULL) 01543 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01544 else if (!acfptr->write) 01545 ast_log(LOG_ERROR, "Function %s cannot be written to\n", function); 01546 else 01547 return acfptr->write(chan, function, args, value); 01548 01549 return -1; 01550 }
const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 6111 of file pbx.c.
Referenced by _macro_exec(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_context_verify_includes(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper().
const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 6149 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06150 { 06151 return c ? c->registrar : NULL; 06152 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6179 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().
06180 { 06181 return e ? e->app : NULL; 06182 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6184 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06185 { 06186 return e ? e->data : NULL; 06187 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6174 of file pbx.c.
References ast_exten::cidmatch.
Referenced by find_matching_priority(), and handle_save_dialplan().
06175 { 06176 return e ? e->cidmatch : NULL; 06177 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
const char* ast_get_extension_label | ( | struct ast_exten * | e | ) |
Definition at line 6126 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 6169 of file pbx.c.
References ast_exten::matchcid.
Referenced by find_matching_priority(), and handle_save_dialplan().
06170 { 06171 return e ? e->matchcid : 0; 06172 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6121 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 6141 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 6154 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06155 { 06156 return e ? e->registrar : NULL; 06157 }
int ast_get_hint | ( | char * | hint, | |
int | maxlen, | |||
char * | name, | |||
int | maxnamelen, | |||
struct ast_channel * | c, | |||
const char * | context, | |||
const char * | exten | |||
) |
If an extension hint exists, return non-zero.
hint | buffer for hint | |
maxlen | size of hint buffer | |
name | buffer for name portion of hint | |
maxnamelen | size of name buffer | |
c | this is not important | |
context | which context to look in | |
exten | which extension to search for |
Definition at line 2250 of file pbx.c.
References ast_get_extension_app(), ast_get_extension_app_data(), and ast_hint_extension().
Referenced by action_extensionstate(), get_cid_name(), pbx_retrieve_variable(), and transmit_state_notify().
02251 { 02252 struct ast_exten *e = ast_hint_extension(c, context, exten); 02253 02254 if (e) { 02255 if (hint) 02256 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02257 if (name) { 02258 const char *tmp = ast_get_extension_app_data(e); 02259 if (tmp) 02260 ast_copy_string(name, tmp, namesize); 02261 } 02262 return -1; 02263 } 02264 return 0; 02265 }
const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6136 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().
06137 { 06138 return ip ? ip->pattern : NULL; 06139 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6164 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06165 { 06166 return ip ? ip->registrar : NULL; 06167 }
const char* ast_get_include_name | ( | struct ast_include * | include | ) |
Definition at line 6131 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 6159 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06160 { 06161 return i ? i->registrar : NULL; 06162 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6194 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06195 { 06196 return sw ? sw->data : NULL; 06197 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6189 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06190 { 06191 return sw ? sw->name : NULL; 06192 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6199 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06200 { 06201 return sw ? sw->registrar : NULL; 06202 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6288 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().
06289 { 06290 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06291 }
void ast_hint_state_changed | ( | const char * | device | ) |
Definition at line 2002 of file pbx.c.
References ast_extension_state2(), ast_get_extension_app(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, AST_MAX_EXTENSION, ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_exten::exten, ast_hint::exten, ast_hint::laststate, ast_state_cb::next, ast_exten::parent, parse(), statecbs, and strsep().
Referenced by do_state_change().
02003 { 02004 struct ast_hint *hint; 02005 02006 AST_LIST_LOCK(&hints); 02007 02008 AST_LIST_TRAVERSE(&hints, hint, list) { 02009 struct ast_state_cb *cblist; 02010 char buf[AST_MAX_EXTENSION]; 02011 char *parse = buf; 02012 char *cur; 02013 int state; 02014 02015 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 02016 while ( (cur = strsep(&parse, "&")) ) { 02017 if (!strcasecmp(cur, device)) 02018 break; 02019 } 02020 if (!cur) 02021 continue; 02022 02023 /* Get device state for this hint */ 02024 state = ast_extension_state2(hint->exten); 02025 02026 if ((state == -1) || (state == hint->laststate)) 02027 continue; 02028 02029 /* Device state changed since last check - notify the watchers */ 02030 02031 /* For general callbacks */ 02032 for (cblist = statecbs; cblist; cblist = cblist->next) 02033 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02034 02035 /* For extension callbacks */ 02036 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 02037 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02038 02039 hint->laststate = state; /* record we saw the change */ 02040 } 02041 02042 AST_LIST_UNLOCK(&hints); 02043 }
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 4515 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_soft_key_event_message(), handle_stimulus_message(), mgcp_ss(), skinny_ss(), and ss_thread().
04516 { 04517 struct ast_context *con = ast_context_find(context); 04518 if (con) { 04519 struct ast_ignorepat *pat; 04520 for (pat = con->ignorepats; pat; pat = pat->next) { 04521 if (ast_extension_match(pat->pattern, pattern)) 04522 return 1; 04523 } 04524 } 04525 04526 return 0; 04527 }
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 6098 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().
06099 { 06100 return ast_mutex_lock(&con->lock); 06101 }
int ast_lock_contexts | ( | void | ) |
Locks the context list.
0 | on success | |
-1 | on error |
Definition at line 6085 of file pbx.c.
References ast_mutex_lock().
Referenced by _macro_exec(), 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(), handle_save_dialplan(), and show_dialplan_helper().
06086 { 06087 return ast_mutex_lock(&conlock); 06088 }
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 2287 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().
02288 { 02289 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE); 02290 }
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 3910 of file pbx.c.
References __ast_context_destroy(), ast_calloc, AST_EXTENSION_REMOVED, ast_hint_extension(), 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_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, store_hint::callbacks, ast_hint::callbacks, store_hint::context, contexts, ast_state_cb::data, ast_exten::exten, ast_hint::exten, store_hint::exten, free, ast_hint::laststate, store_hint::laststate, LOG_WARNING, ast_state_cb::next, ast_context::next, ast_exten::parent, and ast_context::registrar.
Referenced by pbx_load_module().
03911 { 03912 struct ast_context *tmp, *lasttmp = NULL; 03913 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 03914 struct store_hint *this; 03915 struct ast_hint *hint; 03916 struct ast_exten *exten; 03917 int length; 03918 struct ast_state_cb *thiscb, *prevcb; 03919 03920 /* it is very important that this function hold the hint list lock _and_ the conlock 03921 during its operation; not only do we need to ensure that the list of contexts 03922 and extensions does not change, but also that no hint callbacks (watchers) are 03923 added or removed during the merge/delete process 03924 03925 in addition, the locks _must_ be taken in this order, because there are already 03926 other code paths that use this order 03927 */ 03928 ast_mutex_lock(&conlock); 03929 AST_LIST_LOCK(&hints); 03930 03931 /* preserve all watchers for hints associated with this registrar */ 03932 AST_LIST_TRAVERSE(&hints, hint, list) { 03933 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03934 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03935 if (!(this = ast_calloc(1, length))) 03936 continue; 03937 this->callbacks = hint->callbacks; 03938 hint->callbacks = NULL; 03939 this->laststate = hint->laststate; 03940 this->context = this->data; 03941 strcpy(this->data, hint->exten->parent->name); 03942 this->exten = this->data + strlen(this->context) + 1; 03943 strcpy(this->exten, hint->exten->exten); 03944 AST_LIST_INSERT_HEAD(&store, this, list); 03945 } 03946 } 03947 03948 tmp = *extcontexts; 03949 if (registrar) { 03950 /* XXX remove previous contexts from same registrar */ 03951 if (option_debug) 03952 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 03953 __ast_context_destroy(NULL,registrar); 03954 while (tmp) { 03955 lasttmp = tmp; 03956 tmp = tmp->next; 03957 } 03958 } else { 03959 /* XXX remove contexts with the same name */ 03960 while (tmp) { 03961 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 03962 __ast_context_destroy(tmp,tmp->registrar); 03963 lasttmp = tmp; 03964 tmp = tmp->next; 03965 } 03966 } 03967 if (lasttmp) { 03968 lasttmp->next = contexts; 03969 contexts = *extcontexts; 03970 *extcontexts = NULL; 03971 } else 03972 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 03973 03974 /* restore the watchers for hints that can be found; notify those that 03975 cannot be restored 03976 */ 03977 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 03978 exten = ast_hint_extension(NULL, this->context, this->exten); 03979 /* Find the hint in the list of hints */ 03980 AST_LIST_TRAVERSE(&hints, hint, list) { 03981 if (hint->exten == exten) 03982 break; 03983 } 03984 if (!exten || !hint) { 03985 /* this hint has been removed, notify the watchers */ 03986 prevcb = NULL; 03987 thiscb = this->callbacks; 03988 while (thiscb) { 03989 prevcb = thiscb; 03990 thiscb = thiscb->next; 03991 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 03992 free(prevcb); 03993 } 03994 } else { 03995 thiscb = this->callbacks; 03996 while (thiscb->next) 03997 thiscb = thiscb->next; 03998 thiscb->next = hint->callbacks; 03999 hint->callbacks = this->callbacks; 04000 hint->laststate = this->laststate; 04001 } 04002 free(this); 04003 } 04004 04005 AST_LIST_UNLOCK(&hints); 04006 ast_mutex_unlock(&conlock); 04007 04008 return; 04009 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
Definition at line 6298 of file pbx.c.
References ast_cdr_update(), ast_explicit_goto(), ast_findlabel_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, exten, LOG_WARNING, ast_channel::priority, and strsep().
Referenced by _while_exec(), check_goto_on_transfer(), gosub_exec(), ivr_dispatch(), pbx_builtin_goto(), random_exec(), return_exec(), and while_continue_exec().
06299 { 06300 char *exten, *pri, *context; 06301 char *stringp; 06302 int ipri; 06303 int mode = 0; 06304 06305 if (ast_strlen_zero(goto_string)) { 06306 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06307 return -1; 06308 } 06309 stringp = ast_strdupa(goto_string); 06310 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06311 exten = strsep(&stringp, "|"); 06312 pri = strsep(&stringp, "|"); 06313 if (!exten) { /* Only a priority in this one */ 06314 pri = context; 06315 exten = NULL; 06316 context = NULL; 06317 } else if (!pri) { /* Only an extension and priority in this one */ 06318 pri = exten; 06319 exten = context; 06320 context = NULL; 06321 } 06322 if (*pri == '+') { 06323 mode = 1; 06324 pri++; 06325 } else if (*pri == '-') { 06326 mode = -1; 06327 pri++; 06328 } 06329 if (sscanf(pri, "%d", &ipri) != 1) { 06330 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06331 pri, chan->cid.cid_num)) < 1) { 06332 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06333 return -1; 06334 } else 06335 mode = 0; 06336 } 06337 /* At this point we have a priority and maybe an extension and a context */ 06338 06339 if (mode) 06340 ipri = chan->priority + (ipri * mode); 06341 06342 ast_explicit_goto(chan, context, exten, ipri); 06343 ast_cdr_update(chan); 06344 return 0; 06345 06346 }
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 5134 of file pbx.c.
References __ast_request_and_dial(), ast_calloc, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), ast_channel_lock, ast_channel_unlock, ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, async_stat::chan, free, LOG_WARNING, option_verbose, ast_channel::pbx, outgoing_helper::vars, and VERBOSE_PREFIX_4.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_app().
05135 { 05136 struct ast_channel *chan; 05137 struct app_tmp *tmp; 05138 int res = -1, cdr_res = -1; 05139 struct outgoing_helper oh; 05140 pthread_attr_t attr; 05141 05142 memset(&oh, 0, sizeof(oh)); 05143 oh.vars = vars; 05144 oh.account = account; 05145 05146 if (locked_channel) 05147 *locked_channel = NULL; 05148 if (ast_strlen_zero(app)) { 05149 res = -1; 05150 goto outgoing_app_cleanup; 05151 } 05152 if (sync) { 05153 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05154 if (chan) { 05155 if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 05156 ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name); 05157 } else { 05158 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 05159 if(!chan->cdr) { 05160 /* allocation of the cdr failed */ 05161 free(chan->pbx); 05162 res = -1; 05163 goto outgoing_app_cleanup; 05164 } 05165 /* allocation of the cdr was successful */ 05166 ast_cdr_init(chan->cdr, chan); /* initialize our channel's cdr */ 05167 ast_cdr_start(chan->cdr); 05168 } 05169 ast_set_variables(chan, vars); 05170 if (account) 05171 ast_cdr_setaccount(chan, account); 05172 if (chan->_state == AST_STATE_UP) { 05173 res = 0; 05174 if (option_verbose > 3) 05175 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05176 tmp = ast_calloc(1, sizeof(*tmp)); 05177 if (!tmp) 05178 res = -1; 05179 else { 05180 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05181 if (appdata) 05182 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05183 tmp->chan = chan; 05184 if (sync > 1) { 05185 if (locked_channel) 05186 ast_channel_unlock(chan); 05187 ast_pbx_run_app(tmp); 05188 } else { 05189 pthread_attr_init(&attr); 05190 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05191 if (locked_channel) 05192 ast_channel_lock(chan); 05193 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05194 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05195 free(tmp); 05196 if (locked_channel) 05197 ast_channel_unlock(chan); 05198 ast_hangup(chan); 05199 res = -1; 05200 } else { 05201 if (locked_channel) 05202 *locked_channel = chan; 05203 } 05204 pthread_attr_destroy(&attr); 05205 } 05206 } 05207 } else { 05208 if (option_verbose > 3) 05209 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05210 if (chan->cdr) { /* update the cdr */ 05211 /* here we update the status of the call, which sould be busy. 05212 * if that fails then we set the status to failed */ 05213 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05214 ast_cdr_failed(chan->cdr); 05215 } 05216 ast_hangup(chan); 05217 } 05218 } 05219 05220 if (res < 0) { /* the call failed for some reason */ 05221 if (*reason == 0) { /* if the call failed (not busy or no answer) 05222 * update the cdr with the failed message */ 05223 cdr_res = ast_pbx_outgoing_cdr_failed(); 05224 if (cdr_res != 0) { 05225 res = cdr_res; 05226 goto outgoing_app_cleanup; 05227 } 05228 } 05229 } 05230 05231 } else { 05232 struct async_stat *as; 05233 if (!(as = ast_calloc(1, sizeof(*as)))) { 05234 res = -1; 05235 goto outgoing_app_cleanup; 05236 } 05237 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05238 if (!chan) { 05239 free(as); 05240 res = -1; 05241 goto outgoing_app_cleanup; 05242 } 05243 as->chan = chan; 05244 ast_copy_string(as->app, app, sizeof(as->app)); 05245 if (appdata) 05246 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05247 as->timeout = timeout; 05248 ast_set_variables(chan, vars); 05249 if (account) 05250 ast_cdr_setaccount(chan, account); 05251 /* Start a new thread, and get something handling this channel. */ 05252 pthread_attr_init(&attr); 05253 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05254 if (locked_channel) 05255 ast_channel_lock(chan); 05256 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05257 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05258 free(as); 05259 if (locked_channel) 05260 ast_channel_unlock(chan); 05261 ast_hangup(chan); 05262 res = -1; 05263 pthread_attr_destroy(&attr); 05264 goto outgoing_app_cleanup; 05265 } else { 05266 if (locked_channel) 05267 *locked_channel = chan; 05268 } 05269 pthread_attr_destroy(&attr); 05270 res = 0; 05271 } 05272 outgoing_app_cleanup: 05273 ast_variables_destroy(vars); 05274 return res; 05275 }
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 4964 of file pbx.c.
References __ast_request_and_dial(), ast_channel::_state, ast_calloc, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), ast_channel_alloc(), ast_channel_lock, ast_channel_unlock, ast_exists_extension(), ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create, ast_request_and_dial(), ast_set_variables(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, ast_channel::context, free, ast_channel::hangupcause, LOAD_OH, LOG_ERROR, LOG_WARNING, option_verbose, ast_channel::pbx, set_ext_pri(), outgoing_helper::vars, and VERBOSE_PREFIX_4.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_exten().
04965 { 04966 struct ast_channel *chan; 04967 struct async_stat *as; 04968 int res = -1, cdr_res = -1; 04969 struct outgoing_helper oh; 04970 pthread_attr_t attr; 04971 04972 if (sync) { 04973 LOAD_OH(oh); 04974 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 04975 if (channel) { 04976 *channel = chan; 04977 if (chan) 04978 ast_channel_lock(chan); 04979 } 04980 if (chan) { 04981 if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 04982 ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name); 04983 } else { 04984 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 04985 if (!chan->cdr) { 04986 /* allocation of the cdr failed */ 04987 free(chan->pbx); 04988 res = -1; 04989 goto outgoing_exten_cleanup; 04990 } 04991 /* allocation of the cdr was successful */ 04992 ast_cdr_init(chan->cdr, chan); /* initialize our channel's cdr */ 04993 ast_cdr_start(chan->cdr); 04994 } 04995 if (chan->_state == AST_STATE_UP) { 04996 res = 0; 04997 if (option_verbose > 3) 04998 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 04999 05000 if (sync > 1) { 05001 if (channel) 05002 ast_channel_unlock(chan); 05003 if (ast_pbx_run(chan)) { 05004 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05005 if (channel) 05006 *channel = NULL; 05007 ast_hangup(chan); 05008 res = -1; 05009 } 05010 } else { 05011 if (ast_pbx_start(chan)) { 05012 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05013 if (channel) { 05014 *channel = NULL; 05015 ast_channel_unlock(chan); 05016 } 05017 ast_hangup(chan); 05018 res = -1; 05019 } 05020 } 05021 } else { 05022 if (option_verbose > 3) 05023 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05024 05025 if(chan->cdr) { /* update the cdr */ 05026 /* here we update the status of the call, which sould be busy. 05027 * if that fails then we set the status to failed */ 05028 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05029 ast_cdr_failed(chan->cdr); 05030 } 05031 05032 if (channel) { 05033 *channel = NULL; 05034 ast_channel_unlock(chan); 05035 } 05036 ast_hangup(chan); 05037 } 05038 } 05039 05040 if (res < 0) { /* the call failed for some reason */ 05041 if (*reason == 0) { /* if the call failed (not busy or no answer) 05042 * update the cdr with the failed message */ 05043 cdr_res = ast_pbx_outgoing_cdr_failed(); 05044 if (cdr_res != 0) { 05045 res = cdr_res; 05046 goto outgoing_exten_cleanup; 05047 } 05048 } 05049 05050 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05051 /* check if "failed" exists */ 05052 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05053 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05054 if (chan) { 05055 if (!ast_strlen_zero(context)) 05056 ast_copy_string(chan->context, context, sizeof(chan->context)); 05057 set_ext_pri(chan, "failed", 1); 05058 ast_set_variables(chan, vars); 05059 if (account) 05060 ast_cdr_setaccount(chan, account); 05061 ast_pbx_run(chan); 05062 } 05063 } 05064 } 05065 } else { 05066 if (!(as = ast_calloc(1, sizeof(*as)))) { 05067 res = -1; 05068 goto outgoing_exten_cleanup; 05069 } 05070 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05071 if (channel) { 05072 *channel = chan; 05073 if (chan) 05074 ast_channel_lock(chan); 05075 } 05076 if (!chan) { 05077 free(as); 05078 res = -1; 05079 goto outgoing_exten_cleanup; 05080 } 05081 as->chan = chan; 05082 ast_copy_string(as->context, context, sizeof(as->context)); 05083 set_ext_pri(as->chan, exten, priority); 05084 as->timeout = timeout; 05085 ast_set_variables(chan, vars); 05086 if (account) 05087 ast_cdr_setaccount(chan, account); 05088 pthread_attr_init(&attr); 05089 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05090 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05091 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05092 free(as); 05093 if (channel) { 05094 *channel = NULL; 05095 ast_channel_unlock(chan); 05096 } 05097 ast_hangup(chan); 05098 res = -1; 05099 pthread_attr_destroy(&attr); 05100 goto outgoing_exten_cleanup; 05101 } 05102 pthread_attr_destroy(&attr); 05103 res = 0; 05104 } 05105 outgoing_exten_cleanup: 05106 ast_variables_destroy(vars); 05107 return res; 05108 }
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 2641 of file pbx.c.
References __ast_pbx_run(), AST_PBX_CALL_LIMIT, AST_PBX_SUCCESS, decrease_call_count(), and increase_call_count().
Referenced by ast_pbx_outgoing_exten(), async_wait(), mgcp_ss(), skinny_newcall(), and ss_thread().
02642 { 02643 enum ast_pbx_result res = AST_PBX_SUCCESS; 02644 02645 if (increase_call_count(c)) 02646 return AST_PBX_CALL_LIMIT; 02647 02648 res = __ast_pbx_run(c); 02649 decrease_call_count(); 02650 02651 return res; 02652 }
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 2615 of file pbx.c.
References ast_log(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_pthread_create, increase_call_count(), LOG_WARNING, pbx_thread(), and t.
Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_exten(), check_goto_on_transfer(), do_parking_thread(), gtalk_new(), gtalk_newcall(), handle_request_invite(), local_call(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), skinny_new(), and zt_new().
02616 { 02617 pthread_t t; 02618 pthread_attr_t attr; 02619 02620 if (!c) { 02621 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02622 return AST_PBX_FAILED; 02623 } 02624 02625 if (increase_call_count(c)) 02626 return AST_PBX_CALL_LIMIT; 02627 02628 /* Start a new thread, and get something handling this channel. */ 02629 pthread_attr_init(&attr); 02630 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02631 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02632 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02633 pthread_attr_destroy(&attr); 02634 return AST_PBX_FAILED; 02635 } 02636 pthread_attr_destroy(&attr); 02637 02638 return AST_PBX_SUCCESS; 02639 }
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 2943 of file pbx.c.
References ast_calloc, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), COLOR_BRCYAN, ast_app::description, ast_app::execute, LOG_WARNING, option_verbose, ast_app::synopsis, term_color(), and VERBOSE_PREFIX_2.
Referenced by load_module(), and load_pbx().
02944 { 02945 struct ast_app *tmp, *cur = NULL; 02946 char tmps[80]; 02947 int length; 02948 02949 AST_LIST_LOCK(&apps); 02950 AST_LIST_TRAVERSE(&apps, tmp, list) { 02951 if (!strcasecmp(app, tmp->name)) { 02952 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02953 AST_LIST_UNLOCK(&apps); 02954 return -1; 02955 } 02956 } 02957 02958 length = sizeof(*tmp) + strlen(app) + 1; 02959 02960 if (!(tmp = ast_calloc(1, length))) { 02961 AST_LIST_UNLOCK(&apps); 02962 return -1; 02963 } 02964 02965 strcpy(tmp->name, app); 02966 tmp->execute = execute; 02967 tmp->synopsis = synopsis; 02968 tmp->description = description; 02969 02970 /* Store in alphabetical order */ 02971 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 02972 if (strcasecmp(tmp->name, cur->name) < 0) { 02973 AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 02974 break; 02975 } 02976 } 02977 AST_LIST_TRAVERSE_SAFE_END 02978 if (!cur) 02979 AST_LIST_INSERT_TAIL(&apps, tmp, list); 02980 02981 if (option_verbose > 1) 02982 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 02983 02984 AST_LIST_UNLOCK(&apps); 02985 02986 return 0; 02987 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 2993 of file pbx.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), LOG_WARNING, and ast_switch::name.
Referenced by load_module().
02994 { 02995 struct ast_switch *tmp; 02996 02997 AST_LIST_LOCK(&switches); 02998 AST_LIST_TRAVERSE(&switches, tmp, list) { 02999 if (!strcasecmp(tmp->name, sw->name)) { 03000 AST_LIST_UNLOCK(&switches); 03001 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 03002 return -1; 03003 } 03004 } 03005 AST_LIST_INSERT_TAIL(&switches, sw, list); 03006 AST_LIST_UNLOCK(&switches); 03007 03008 return 0; 03009 }
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 2292 of file pbx.c.
References E_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), _macro_exec(), and loopback_exec().
02293 { 02294 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN); 02295 }
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 6103 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().
06104 { 06105 return ast_mutex_unlock(&con->lock); 06106 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 6090 of file pbx.c.
References ast_mutex_unlock().
Referenced by _macro_exec(), ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_lockmacro(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), 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(), handle_save_dialplan(), and show_dialplan_helper().
06091 { 06092 return ast_mutex_unlock(&conlock); 06093 }
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 3824 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), free, option_verbose, and VERBOSE_PREFIX_2.
Referenced by __unload_module(), and unload_module().
03825 { 03826 struct ast_app *tmp; 03827 03828 AST_LIST_LOCK(&apps); 03829 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03830 if (!strcasecmp(app, tmp->name)) { 03831 AST_LIST_REMOVE_CURRENT(&apps, list); 03832 if (option_verbose > 1) 03833 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03834 free(tmp); 03835 break; 03836 } 03837 } 03838 AST_LIST_TRAVERSE_SAFE_END 03839 AST_LIST_UNLOCK(&apps); 03840 03841 return tmp ? 0 : -1; 03842 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 3011 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_REMOVE, and AST_LIST_UNLOCK.
Referenced by __unload_module(), and unload_module().
03012 { 03013 AST_LIST_LOCK(&switches); 03014 AST_LIST_REMOVE(&switches, sw, list); 03015 AST_LIST_UNLOCK(&switches); 03016 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | priority | |||
) |
Definition at line 6212 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().
06214 { 06215 if (!exten) 06216 return con ? con->root : NULL; 06217 else 06218 return exten->next; 06219 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 6245 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().
06247 { 06248 if (!ip) 06249 return con ? con->ignorepats : NULL; 06250 else 06251 return ip->next; 06252 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 6236 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().
06238 { 06239 if (!inc) 06240 return con ? con->includes : NULL; 06241 else 06242 return inc->next; 06243 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 6221 of file pbx.c.
References AST_LIST_FIRST, and AST_LIST_NEXT.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06223 { 06224 if (!sw) 06225 return con ? AST_LIST_FIRST(&con->alts) : NULL; 06226 else 06227 return AST_LIST_NEXT(sw, list); 06228 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 6207 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 6230 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().
void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 5961 of file pbx.c.
References AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), and ast_var_delete().
Referenced by handle_reload_extensions(), and reload().
05962 { 05963 struct ast_var_t *vardata; 05964 05965 ast_mutex_lock(&globalslock); 05966 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 05967 ast_var_delete(vardata); 05968 ast_mutex_unlock(&globalslock); 05969 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5761 of file pbx.c.
References AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), and ast_channel::varshead.
Referenced by __login_exec(), _macro_exec(), _while_exec(), acf_iaxvar_read(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), array(), ast_bridge_call(), ast_feature_interpret(), ast_monitor_stop(), ast_park_call(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dundi_exec(), dundi_helper(), get_also_info(), get_index(), get_refer_info(), global_read(), hash_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), pickup_by_mark(), pop_exec(), queue_exec(), real_ctx(), retrydial_exec(), return_exec(), run_agi(), rxfax_exec(), set_config_flags(), sip_addheader(), try_calling(), try_suggested_sip_codec(), txfax_exec(), wait_for_answer(), zt_call(), and zt_hangup().
05762 { 05763 struct ast_var_t *variables; 05764 const char *ret = NULL; 05765 int i; 05766 struct varshead *places[2] = { NULL, &globals }; 05767 05768 if (!name) 05769 return NULL; 05770 if (chan) 05771 places[0] = &chan->varshead; 05772 05773 for (i = 0; i < 2; i++) { 05774 if (!places[i]) 05775 continue; 05776 if (places[i] == &globals) 05777 ast_mutex_lock(&globalslock); 05778 AST_LIST_TRAVERSE(places[i], variables, entries) { 05779 if (!strcmp(name, ast_var_name(variables))) { 05780 ret = ast_var_value(variables); 05781 break; 05782 } 05783 } 05784 if (places[i] == &globals) 05785 ast_mutex_unlock(&globalslock); 05786 if (ret) 05787 break; 05788 } 05789 05790 return ret; 05791 }
void pbx_builtin_pushvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5793 of file pbx.c.
References ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_verbose(), LOG_WARNING, option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2.
Referenced by acf_odbc_read(), acf_odbc_write(), and gosub_exec().
05794 { 05795 struct ast_var_t *newvariable; 05796 struct varshead *headp; 05797 05798 if (name[strlen(name)-1] == ')') { 05799 char *function = ast_strdupa(name); 05800 05801 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05802 ast_func_write(chan, function, value); 05803 return; 05804 } 05805 05806 headp = (chan) ? &chan->varshead : &globals; 05807 05808 if (value) { 05809 if ((option_verbose > 1) && (headp == &globals)) 05810 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05811 newvariable = ast_var_assign(name, value); 05812 if (headp == &globals) 05813 ast_mutex_lock(&globalslock); 05814 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05815 if (headp == &globals) 05816 ast_mutex_unlock(&globalslock); 05817 } 05818 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5734 of file pbx.c.
References ast_build_string(), AST_LIST_TRAVERSE, ast_log(), ast_var_name(), ast_var_value(), LOG_ERROR, total, var, and ast_channel::varshead.
Referenced by dumpchan_exec(), handle_showchan(), handle_showchan_deprecated(), and vars2manager().
05735 { 05736 struct ast_var_t *variables; 05737 const char *var, *val; 05738 int total = 0; 05739 05740 if (!chan) 05741 return 0; 05742 05743 memset(buf, 0, size); 05744 05745 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05746 if ((var=ast_var_name(variables)) && (val=ast_var_value(variables)) 05747 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 05748 ) { 05749 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05750 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05751 break; 05752 } else 05753 total++; 05754 } else 05755 break; 05756 } 05757 05758 return total; 05759 }
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 5820 of file pbx.c.
References ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verbose(), option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2.
Referenced by __oh323_new(), _macro_exec(), _while_exec(), acf_iaxvar_write(), acf_odbc_read(), acf_odbc_write(), action_setvar(), agi_exec_full(), aji_status_exec(), aMYSQL_fetch(), app_exec(), aqm_exec(), array(), ast_bridge_call(), ast_feature_request_and_dial(), ast_iax2_new(), ast_monitor_start(), ast_set_variables(), background_detect_exec(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), controlplayback_exec(), count_exec(), disa_exec(), do_waiting(), export_aoc_vars(), export_ch(), function_db_delete(), function_db_exists(), function_db_read(), global_write(), handle_request_bye(), handle_request_refer(), handle_set_global(), handle_set_global_deprecated(), handle_setvariable(), hash_read(), hash_write(), hasvoicemail_exec(), isAnsweringMachine(), leave_voicemail(), local_hangup(), lookupblacklist_exec(), misdn_call(), mixmonitor_exec(), mwanalyze_exec(), MYSQL_exec(), nv_background_detect_exec(), nv_detectfax_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_exec(), parse_moved_contact(), pbx_builtin_importvar(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_extension_helper(), pbx_load_config(), phase_e_handler(), play_message_datetime(), playback_exec(), pop_exec(), pqm_exec(), prep_email_sub_vars(), privacy_exec(), process_ast_dsp(), read_exec(), readfile_exec(), realtime_exec(), realtime_update_exec(), record_exec(), return_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set(), set_agentbycallerid(), set_asterisk_int(), set_queue_result(), sip_addheader(), sip_hangup(), sip_new(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), ss_thread(), start_monitor_exec(), system_exec_helper(), transfer_exec(), try_calling(), tryexec_exec(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), zt_handle_dtmfup(), and zt_new().
05821 { 05822 struct ast_var_t *newvariable; 05823 struct varshead *headp; 05824 const char *nametail = name; 05825 05826 /* XXX may need locking on the channel ? */ 05827 if (name[strlen(name)-1] == ')') { 05828 char *function = ast_strdupa(name); 05829 05830 ast_func_write(chan, function, value); 05831 return; 05832 } 05833 05834 headp = (chan) ? &chan->varshead : &globals; 05835 05836 /* For comparison purposes, we have to strip leading underscores */ 05837 if (*nametail == '_') { 05838 nametail++; 05839 if (*nametail == '_') 05840 nametail++; 05841 } 05842 05843 if (headp == &globals) 05844 ast_mutex_lock(&globalslock); 05845 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05846 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 05847 /* there is already such a variable, delete it */ 05848 AST_LIST_REMOVE(headp, newvariable, entries); 05849 ast_var_delete(newvariable); 05850 break; 05851 } 05852 } 05853 05854 if (value) { 05855 if ((option_verbose > 1) && (headp == &globals)) 05856 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05857 newvariable = ast_var_assign(name, value); 05858 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05859 } 05860 05861 if (headp == &globals) 05862 ast_mutex_unlock(&globalslock); 05863 }
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 5971 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().
05972 { 05973 if (ast_strlen_zero(condition)) /* NULL or empty strings are false */ 05974 return 0; 05975 else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */ 05976 return atoi(condition); 05977 else /* Strings are true */ 05978 return 1; 05979 }
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 512 of file pbx.c.
References app, ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_channel::cdr, and ast_channel::data.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().
00515 { 00516 int res; 00517 00518 const char *saved_c_appl; 00519 const char *saved_c_data; 00520 00521 if (c->cdr && !ast_check_hangup(c)) 00522 ast_cdr_setapp(c->cdr, app->name, data); 00523 00524 /* save channel values */ 00525 saved_c_appl= c->appl; 00526 saved_c_data= c->data; 00527 00528 c->appl = app->name; 00529 c->data = data; 00530 /* XXX remember what to to when we have linked apps to modules */ 00531 if (app->module) { 00532 /* XXX LOCAL_USER_ADD(app->module) */ 00533 } 00534 res = app->execute(c, data); 00535 if (app->module) { 00536 /* XXX LOCAL_USER_REMOVE(app->module) */ 00537 } 00538 /* restore channel values */ 00539 c->appl = saved_c_appl; 00540 c->data = saved_c_data; 00541 return res; 00542 }
struct ast_app* pbx_findapp | ( | const char * | app | ) |
Look up an application.
app | name of the app |
Definition at line 550 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().
00551 { 00552 struct ast_app *tmp; 00553 00554 AST_LIST_LOCK(&apps); 00555 AST_LIST_TRAVERSE(&apps, tmp, list) { 00556 if (!strcasecmp(tmp->name, app)) 00557 break; 00558 } 00559 AST_LIST_UNLOCK(&apps); 00560 00561 return tmp; 00562 }
void pbx_retrieve_variable | ( | struct ast_channel * | c, | |
const char * | var, | |||
char ** | ret, | |||
char * | workspace, | |||
int | workspacelen, | |||
struct varshead * | headp | |||
) |
Support for Asterisk built-in variables and functions in the dialplan.
Definition at line 1134 of file pbx.c.
References ast_config_AST_SYSTEM_NAME, ast_get_hint(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_name(), ast_var_value(), ast_channel::cid, ast_callerid::cid_ani2, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, ast_channel::hangupcause, offset, parse_variable_name(), ast_channel::priority, s, substring(), and ast_channel::varshead.
Referenced by action_getvar(), function_fieldqty(), handle_getvariable(), and pbx_substitute_variables_helper_full().
01135 { 01136 const char not_found = '\0'; 01137 char *tmpvar; 01138 const char *s; /* the result */ 01139 int offset, length; 01140 int i, need_substring; 01141 struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */ 01142 01143 if (c) { 01144 places[0] = &c->varshead; 01145 } 01146 /* 01147 * Make a copy of var because parse_variable_name() modifies the string. 01148 * Then if called directly, we might need to run substring() on the result; 01149 * remember this for later in 'need_substring', 'offset' and 'length' 01150 */ 01151 tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */ 01152 need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */); 01153 01154 /* 01155 * Look first into predefined variables, then into variable lists. 01156 * Variable 's' points to the result, according to the following rules: 01157 * s == ¬_found (set at the beginning) means that we did not find a 01158 * matching variable and need to look into more places. 01159 * If s != ¬_found, s is a valid result string as follows: 01160 * s = NULL if the variable does not have a value; 01161 * you typically do this when looking for an unset predefined variable. 01162 * s = workspace if the result has been assembled there; 01163 * typically done when the result is built e.g. with an snprintf(), 01164 * so we don't need to do an additional copy. 01165 * s != workspace in case we have a string, that needs to be copied 01166 * (the ast_copy_string is done once for all at the end). 01167 * Typically done when the result is already available in some string. 01168 */ 01169 s = ¬_found; /* default value */ 01170 if (c) { /* This group requires a valid channel */ 01171 /* Names with common parts are looked up a piece at a time using strncmp. */ 01172 if (!strncmp(var, "CALL", 4)) { 01173 if (!strncmp(var + 4, "ING", 3)) { 01174 if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */ 01175 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 01176 s = workspace; 01177 } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */ 01178 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 01179 s = workspace; 01180 } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */ 01181 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 01182 s = workspace; 01183 } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */ 01184 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 01185 s = workspace; 01186 } 01187 } 01188 } else if (!strcmp(var, "HINT")) { 01189 s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL; 01190 } else if (!strcmp(var, "HINTNAME")) { 01191 s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL; 01192 } else if (!strcmp(var, "EXTEN")) { 01193 s = c->exten; 01194 } else if (!strcmp(var, "CONTEXT")) { 01195 s = c->context; 01196 } else if (!strcmp(var, "PRIORITY")) { 01197 snprintf(workspace, workspacelen, "%d", c->priority); 01198 s = workspace; 01199 } else if (!strcmp(var, "CHANNEL")) { 01200 s = c->name; 01201 } else if (!strcmp(var, "UNIQUEID")) { 01202 s = c->uniqueid; 01203 } else if (!strcmp(var, "HANGUPCAUSE")) { 01204 snprintf(workspace, workspacelen, "%d", c->hangupcause); 01205 s = workspace; 01206 } 01207 } 01208 if (s == ¬_found) { /* look for more */ 01209 if (!strcmp(var, "EPOCH")) { 01210 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 01211 s = workspace; 01212 } else if (!strcmp(var, "SYSTEMNAME")) { 01213 s = ast_config_AST_SYSTEM_NAME; 01214 } 01215 } 01216 /* if not found, look into chanvars or global vars */ 01217 for (i = 0; s == ¬_found && i < (sizeof(places) / sizeof(places[0])); i++) { 01218 struct ast_var_t *variables; 01219 if (!places[i]) 01220 continue; 01221 if (places[i] == &globals) 01222 ast_mutex_lock(&globalslock); 01223 AST_LIST_TRAVERSE(places[i], variables, entries) { 01224 if (strcasecmp(ast_var_name(variables), var)==0) { 01225 s = ast_var_value(variables); 01226 break; 01227 } 01228 } 01229 if (places[i] == &globals) 01230 ast_mutex_unlock(&globalslock); 01231 } 01232 if (s == ¬_found || s == NULL) 01233 *ret = NULL; 01234 else { 01235 if (s != workspace) 01236 ast_copy_string(workspace, s, workspacelen); 01237 *ret = workspace; 01238 if (need_substring) 01239 *ret = substring(*ret, offset, length, workspace, workspacelen); 01240 } 01241 }
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 2659 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
02660 { 02661 int oldval = autofallthrough; 02662 autofallthrough = newval; 02663 return oldval; 02664 }
void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1745 of file pbx.c.
References pbx_substitute_variables_helper_full(), and ast_channel::varshead.
Referenced by _macro_exec(), acf_odbc_read(), acf_odbc_write(), custom_log(), cut_internal(), exec_exec(), function_eval(), handle_getvariablefull(), launch_monitor_thread(), make_email_file(), pbx_builtin_importvar(), pbx_load_config(), pbx_substitute_variables(), realtime_exec(), rpt_do_lstats(), rpt_exec(), sendpage(), try_calling(), and tryexec_exec().
01746 { 01747 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 01748 }
void pbx_substitute_variables_varshead | ( | struct varshead * | headp, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1750 of file pbx.c.
References pbx_substitute_variables_helper_full().
Referenced by ast_add_extension2(), dundi_lookup_local(), and loopback_helper().
01751 { 01752 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 01753 }