#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(), 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 2656 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02657 { 02658 return countcalls; 02659 }
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 4536 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().
04539 { 04540 int ret = -1; 04541 struct ast_context *c = find_context_locked(context); 04542 04543 if (c) { 04544 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04545 application, data, datad, registrar); 04546 ast_unlock_contexts(); 04547 } 04548 return ret; 04549 }
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 4740 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().
04744 { 04745 /* 04746 * Sort extensions (or patterns) according to the rules indicated above. 04747 * These are implemented by the function ext_cmp()). 04748 * All priorities for the same ext/pattern/cid are kept in a list, 04749 * using the 'peer' field as a link field.. 04750 */ 04751 struct ast_exten *tmp, *e, *el = NULL; 04752 int res; 04753 int length; 04754 char *p; 04755 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04756 04757 /* if we are adding a hint, and there are global variables, and the hint 04758 contains variable references, then expand them 04759 */ 04760 ast_mutex_lock(&globalslock); 04761 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04762 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04763 application = expand_buf; 04764 } 04765 ast_mutex_unlock(&globalslock); 04766 04767 length = sizeof(struct ast_exten); 04768 length += strlen(extension) + 1; 04769 length += strlen(application) + 1; 04770 if (label) 04771 length += strlen(label) + 1; 04772 if (callerid) 04773 length += strlen(callerid) + 1; 04774 else 04775 length ++; /* just the '\0' */ 04776 04777 /* Be optimistic: Build the extension structure first */ 04778 if (!(tmp = ast_calloc(1, length))) 04779 return -1; 04780 04781 /* use p as dst in assignments, as the fields are const char * */ 04782 p = tmp->stuff; 04783 if (label) { 04784 tmp->label = p; 04785 strcpy(p, label); 04786 p += strlen(label) + 1; 04787 } 04788 tmp->exten = p; 04789 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04790 tmp->priority = priority; 04791 tmp->cidmatch = p; /* but use p for assignments below */ 04792 if (callerid) { 04793 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04794 tmp->matchcid = 1; 04795 } else { 04796 *p++ = '\0'; 04797 tmp->matchcid = 0; 04798 } 04799 tmp->app = p; 04800 strcpy(p, application); 04801 tmp->parent = con; 04802 tmp->data = data; 04803 tmp->datad = datad; 04804 tmp->registrar = registrar; 04805 04806 ast_mutex_lock(&con->lock); 04807 res = 0; /* some compilers will think it is uninitialized otherwise */ 04808 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04809 res = ext_cmp(e->exten, extension); 04810 if (res == 0) { /* extension match, now look at cidmatch */ 04811 if (!e->matchcid && !tmp->matchcid) 04812 res = 0; 04813 else if (tmp->matchcid && !e->matchcid) 04814 res = 1; 04815 else if (e->matchcid && !tmp->matchcid) 04816 res = -1; 04817 else 04818 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04819 } 04820 if (res >= 0) 04821 break; 04822 } 04823 if (e && res == 0) { /* exact match, insert in the pri chain */ 04824 res = add_pri(con, tmp, el, e, replace); 04825 ast_mutex_unlock(&con->lock); 04826 if (res < 0) { 04827 errno = EEXIST; /* XXX do we care ? */ 04828 return 0; /* XXX should we return -1 maybe ? */ 04829 } 04830 } else { 04831 /* 04832 * not an exact match, this is the first entry with this pattern, 04833 * so insert in the main list right before 'e' (if any) 04834 */ 04835 tmp->next = e; 04836 if (el) 04837 el->next = tmp; 04838 else 04839 con->root = tmp; 04840 ast_mutex_unlock(&con->lock); 04841 if (tmp->priority == PRIORITY_HINT) 04842 ast_add_hint(tmp); 04843 } 04844 if (option_debug) { 04845 if (tmp->matchcid) { 04846 if (option_debug) 04847 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04848 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04849 } else { 04850 if (option_debug) 04851 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04852 tmp->exten, tmp->priority, con->name); 04853 } 04854 } 04855 if (option_verbose > 2) { 04856 if (tmp->matchcid) { 04857 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04858 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04859 } else { 04860 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04861 tmp->exten, tmp->priority, con->name); 04862 } 04863 } 04864 return 0; 04865 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4570 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().
04571 { 04572 int res = 0; 04573 04574 ast_channel_lock(chan); 04575 04576 if (chan->pbx) { /* This channel is currently in the PBX */ 04577 ast_explicit_goto(chan, context, exten, priority); 04578 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04579 } else { 04580 /* In order to do it when the channel doesn't really exist within 04581 the PBX, we have to make a new channel, masquerade, and start the PBX 04582 at the new location */ 04583 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04584 if (chan->cdr) { 04585 tmpchan->cdr = ast_cdr_dup(chan->cdr); 04586 } 04587 if (!tmpchan) 04588 res = -1; 04589 else { 04590 /* Make formats okay */ 04591 tmpchan->readformat = chan->readformat; 04592 tmpchan->writeformat = chan->writeformat; 04593 /* Setup proper location */ 04594 ast_explicit_goto(tmpchan, 04595 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04596 04597 /* Masquerade into temp channel */ 04598 ast_channel_masquerade(tmpchan, chan); 04599 04600 /* Grab the locks and get going */ 04601 ast_channel_lock(tmpchan); 04602 ast_do_masquerade(tmpchan); 04603 ast_channel_unlock(tmpchan); 04604 /* Start the PBX going on our stolen channel */ 04605 if (ast_pbx_start(tmpchan)) { 04606 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04607 ast_hangup(tmpchan); 04608 res = -1; 04609 } 04610 } 04611 } 04612 ast_channel_unlock(chan); 04613 return res; 04614 }
int ast_async_goto_by_name | ( | const char * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4616 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04617 { 04618 struct ast_channel *chan; 04619 int res = -1; 04620 04621 chan = ast_get_channel_by_name_locked(channame); 04622 if (chan) { 04623 res = ast_async_goto(chan, context, exten, priority); 04624 ast_channel_unlock(chan); 04625 } 04626 return res; 04627 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6281 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06282 { 06283 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06284 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info | |||
) |
Definition at line 4212 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().
04213 { 04214 char info_save[256]; 04215 char *info; 04216 04217 /* Check for empty just in case */ 04218 if (ast_strlen_zero(info_in)) 04219 return 0; 04220 /* make a copy just in case we were passed a static string */ 04221 ast_copy_string(info_save, info_in, sizeof(info_save)); 04222 info = info_save; 04223 /* Assume everything except time */ 04224 i->monthmask = 0xfff; /* 12 bits */ 04225 i->daymask = 0x7fffffffU; /* 31 bits */ 04226 i->dowmask = 0x7f; /* 7 bits */ 04227 /* on each call, use strsep() to move info to the next argument */ 04228 get_timerange(i, strsep(&info, "|")); 04229 if (info) 04230 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04231 if (info) 04232 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04233 if (info) 04234 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04235 return 1; 04236 }
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 4238 of file pbx.c.
References ast_localtime(), ast_log(), ast_timing::daymask, ast_timing::dowmask, LOG_WARNING, ast_timing::minmask, ast_timing::monthmask, and t.
Referenced by iftime(), include_valid(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
04239 { 04240 struct tm tm; 04241 time_t t = time(NULL); 04242 04243 ast_localtime(&t, &tm, NULL); 04244 04245 /* If it's not the right month, return */ 04246 if (!(i->monthmask & (1 << tm.tm_mon))) 04247 return 0; 04248 04249 /* If it's not that time of the month.... */ 04250 /* Warning, tm_mday has range 1..31! */ 04251 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04252 return 0; 04253 04254 /* If it's not the right day of the week */ 04255 if (!(i->dowmask & (1 << tm.tm_wday))) 04256 return 0; 04257 04258 /* Sanity check the hour just to be safe */ 04259 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04260 ast_log(LOG_WARNING, "Insane time...\n"); 04261 return 0; 04262 } 04263 04264 /* Now the tough part, we calculate if it fits 04265 in the right time based on min/hour */ 04266 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04267 return 0; 04268 04269 /* If we got this far, then we're good */ 04270 return 1; 04271 }
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 4472 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().
04473 { 04474 int ret = -1; 04475 struct ast_context *c = find_context_locked(context); 04476 04477 if (c) { 04478 ret = ast_context_add_ignorepat2(c, value, registrar); 04479 ast_unlock_contexts(); 04480 } 04481 return ret; 04482 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4484 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_context_add_ignorepat(), and pbx_load_config().
04485 { 04486 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04487 int length; 04488 length = sizeof(struct ast_ignorepat); 04489 length += strlen(value) + 1; 04490 if (!(ignorepat = ast_calloc(1, length))) 04491 return -1; 04492 /* The cast to char * is because we need to write the initial value. 04493 * The field is not supposed to be modified otherwise 04494 */ 04495 strcpy((char *)ignorepat->pattern, value); 04496 ignorepat->next = NULL; 04497 ignorepat->registrar = registrar; 04498 ast_mutex_lock(&con->lock); 04499 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04500 ignorepatl = ignorepatc; 04501 if (!strcasecmp(ignorepatc->pattern, value)) { 04502 /* Already there */ 04503 ast_mutex_unlock(&con->lock); 04504 errno = EEXIST; 04505 return -1; 04506 } 04507 } 04508 if (ignorepatl) 04509 ignorepatl->next = ignorepat; 04510 else 04511 con->ignorepats = ignorepat; 04512 ast_mutex_unlock(&con->lock); 04513 return 0; 04514 04515 }
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 4018 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().
04019 { 04020 int ret = -1; 04021 struct ast_context *c = find_context_locked(context); 04022 04023 if (c) { 04024 ret = ast_context_add_include2(c, include, registrar); 04025 ast_unlock_contexts(); 04026 } 04027 return ret; 04028 }
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 4280 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_context_add_include(), and pbx_load_config().
04282 { 04283 struct ast_include *new_include; 04284 char *c; 04285 struct ast_include *i, *il = NULL; /* include, include_last */ 04286 int length; 04287 char *p; 04288 04289 length = sizeof(struct ast_include); 04290 length += 2 * (strlen(value) + 1); 04291 04292 /* allocate new include structure ... */ 04293 if (!(new_include = ast_calloc(1, length))) 04294 return -1; 04295 /* Fill in this structure. Use 'p' for assignments, as the fields 04296 * in the structure are 'const char *' 04297 */ 04298 p = new_include->stuff; 04299 new_include->name = p; 04300 strcpy(p, value); 04301 p += strlen(value) + 1; 04302 new_include->rname = p; 04303 strcpy(p, value); 04304 /* Strip off timing info, and process if it is there */ 04305 if ( (c = strchr(p, '|')) ) { 04306 *c++ = '\0'; 04307 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04308 } 04309 new_include->next = NULL; 04310 new_include->registrar = registrar; 04311 04312 ast_mutex_lock(&con->lock); 04313 04314 /* ... go to last include and check if context is already included too... */ 04315 for (i = con->includes; i; i = i->next) { 04316 if (!strcasecmp(i->name, new_include->name)) { 04317 free(new_include); 04318 ast_mutex_unlock(&con->lock); 04319 errno = EEXIST; 04320 return -1; 04321 } 04322 il = i; 04323 } 04324 04325 /* ... include new context into context list, unlock, return */ 04326 if (il) 04327 il->next = new_include; 04328 else 04329 con->includes = new_include; 04330 if (option_verbose > 2) 04331 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04332 ast_mutex_unlock(&con->lock); 04333 04334 return 0; 04335 }
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 4342 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04343 { 04344 int ret = -1; 04345 struct ast_context *c = find_context_locked(context); 04346 04347 if (c) { /* found, add switch to this context */ 04348 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04349 ast_unlock_contexts(); 04350 } 04351 return ret; 04352 }
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 4361 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_context_add_switch(), and pbx_load_config().
04363 { 04364 struct ast_sw *new_sw; 04365 struct ast_sw *i; 04366 int length; 04367 char *p; 04368 04369 length = sizeof(struct ast_sw); 04370 length += strlen(value) + 1; 04371 if (data) 04372 length += strlen(data); 04373 length++; 04374 if (eval) { 04375 /* Create buffer for evaluation of variables */ 04376 length += SWITCH_DATA_LENGTH; 04377 length++; 04378 } 04379 04380 /* allocate new sw structure ... */ 04381 if (!(new_sw = ast_calloc(1, length))) 04382 return -1; 04383 /* ... fill in this structure ... */ 04384 p = new_sw->stuff; 04385 new_sw->name = p; 04386 strcpy(new_sw->name, value); 04387 p += strlen(value) + 1; 04388 new_sw->data = p; 04389 if (data) { 04390 strcpy(new_sw->data, data); 04391 p += strlen(data) + 1; 04392 } else { 04393 strcpy(new_sw->data, ""); 04394 p++; 04395 } 04396 if (eval) 04397 new_sw->tmpdata = p; 04398 new_sw->eval = eval; 04399 new_sw->registrar = registrar; 04400 04401 /* ... try to lock this context ... */ 04402 ast_mutex_lock(&con->lock); 04403 04404 /* ... go to last sw and check if context is already swd too... */ 04405 AST_LIST_TRAVERSE(&con->alts, i, list) { 04406 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04407 free(new_sw); 04408 ast_mutex_unlock(&con->lock); 04409 errno = EEXIST; 04410 return -1; 04411 } 04412 } 04413 04414 /* ... sw new context into context list, unlock, return */ 04415 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04416 04417 if (option_verbose > 2) 04418 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04419 04420 ast_mutex_unlock(&con->lock); 04421 04422 return 0; 04423 }
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 3889 of file pbx.c.
References __ast_context_create().
Referenced by ast_park_call(), do_parking_thread(), and set_config().
03890 { 03891 return __ast_context_create(extcontexts, name, registrar, 0); 03892 }
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 5326 of file pbx.c.
References __ast_context_destroy().
Referenced by cleanup_stale_contexts(), and unload_module().
05327 { 05328 __ast_context_destroy(con,registrar); 05329 }
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 3894 of file pbx.c.
References __ast_context_create().
Referenced by pbx_load_config(), and pbx_load_users().
03895 { 03896 return __ast_context_create(extcontexts, name, registrar, 1); 03897 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 2893 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().
02894 { 02895 struct ast_context *c = NULL; 02896 int ret = -1; 02897 02898 ast_lock_contexts(); 02899 02900 while ((c = ast_walk_contexts(c))) { 02901 if (!strcmp(ast_get_context_name(c), context)) { 02902 ret = 0; 02903 break; 02904 } 02905 } 02906 02907 ast_unlock_contexts(); 02908 02909 /* if we found context, lock macrolock */ 02910 if (ret == 0) 02911 ret = ast_mutex_lock(&c->macrolock); 02912 02913 return ret; 02914 }
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 2794 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().
02795 { 02796 int ret = -1; /* default error return */ 02797 struct ast_context *c = find_context_locked(context); 02798 02799 if (c) { /* ... remove extension ... */ 02800 ret = ast_context_remove_extension2(c, extension, priority, registrar); 02801 ast_unlock_contexts(); 02802 } 02803 return ret; 02804 }
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 2816 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().
02817 { 02818 struct ast_exten *exten, *prev_exten = NULL; 02819 struct ast_exten *peer; 02820 02821 ast_mutex_lock(&con->lock); 02822 02823 /* scan the extension list to find matching extension-registrar */ 02824 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02825 if (!strcmp(exten->exten, extension) && 02826 (!registrar || !strcmp(exten->registrar, registrar))) 02827 break; 02828 } 02829 if (!exten) { 02830 /* we can't find right extension */ 02831 ast_mutex_unlock(&con->lock); 02832 return -1; 02833 } 02834 02835 /* should we free all peers in this extension? (priority == 0)? */ 02836 if (priority == 0) { 02837 /* remove this extension from context list */ 02838 if (prev_exten) 02839 prev_exten->next = exten->next; 02840 else 02841 con->root = exten->next; 02842 02843 /* fire out all peers */ 02844 while ( (peer = exten) ) { 02845 exten = peer->peer; /* prepare for next entry */ 02846 destroy_exten(peer); 02847 } 02848 } else { 02849 /* scan the priority list to remove extension with exten->priority == priority */ 02850 struct ast_exten *previous_peer = NULL; 02851 02852 for (peer = exten; peer; previous_peer = peer, peer = peer->peer) { 02853 if (peer->priority == priority && 02854 (!registrar || !strcmp(peer->registrar, registrar) )) 02855 break; /* found our priority */ 02856 } 02857 if (!peer) { /* not found */ 02858 ast_mutex_unlock(&con->lock); 02859 return -1; 02860 } 02861 /* we are first priority extension? */ 02862 if (!previous_peer) { 02863 /* 02864 * We are first in the priority chain, so must update the extension chain. 02865 * The next node is either the next priority or the next extension 02866 */ 02867 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02868 02869 if (!prev_exten) /* change the root... */ 02870 con->root = next_node; 02871 else 02872 prev_exten->next = next_node; /* unlink */ 02873 if (peer->peer) /* XXX update the new head of the pri list */ 02874 peer->peer->next = peer->next; 02875 } else { /* easy, we are not first priority in extension */ 02876 previous_peer->peer = peer->peer; 02877 } 02878 02879 /* now, free whole priority extension */ 02880 destroy_exten(peer); 02881 /* XXX should we return -1 ? */ 02882 } 02883 ast_mutex_unlock(&con->lock); 02884 return 0; 02885 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4429 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().
04430 { 04431 int ret = -1; 04432 struct ast_context *c = find_context_locked(context); 04433 04434 if (c) { 04435 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04436 ast_unlock_contexts(); 04437 } 04438 return ret; 04439 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4441 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().
04442 { 04443 struct ast_ignorepat *ip, *ipl = NULL; 04444 04445 ast_mutex_lock(&con->lock); 04446 04447 for (ip = con->ignorepats; ip; ip = ip->next) { 04448 if (!strcmp(ip->pattern, ignorepat) && 04449 (!registrar || (registrar == ip->registrar))) { 04450 if (ipl) { 04451 ipl->next = ip->next; 04452 free(ip); 04453 } else { 04454 con->ignorepats = ip->next; 04455 free(ip); 04456 } 04457 ast_mutex_unlock(&con->lock); 04458 return 0; 04459 } 04460 ipl = ip; 04461 } 04462 04463 ast_mutex_unlock(&con->lock); 04464 errno = EINVAL; 04465 return -1; 04466 }
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 2690 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().
02691 { 02692 int ret = -1; 02693 struct ast_context *c = find_context_locked(context); 02694 02695 if (c) { 02696 /* found, remove include from this context ... */ 02697 ret = ast_context_remove_include2(c, include, registrar); 02698 ast_unlock_contexts(); 02699 } 02700 return ret; 02701 }
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 2711 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().
02712 { 02713 struct ast_include *i, *pi = NULL; 02714 int ret = -1; 02715 02716 ast_mutex_lock(&con->lock); 02717 02718 /* find our include */ 02719 for (i = con->includes; i; pi = i, i = i->next) { 02720 if (!strcmp(i->name, include) && 02721 (!registrar || !strcmp(i->registrar, registrar))) { 02722 /* remove from list */ 02723 if (pi) 02724 pi->next = i->next; 02725 else 02726 con->includes = i->next; 02727 /* free include and return */ 02728 free(i); 02729 ret = 0; 02730 break; 02731 } 02732 } 02733 02734 ast_mutex_unlock(&con->lock); 02735 return ret; 02736 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 2743 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
02744 { 02745 int ret = -1; /* default error return */ 02746 struct ast_context *c = find_context_locked(context); 02747 02748 if (c) { 02749 /* remove switch from this context ... */ 02750 ret = ast_context_remove_switch2(c, sw, data, registrar); 02751 ast_unlock_contexts(); 02752 } 02753 return ret; 02754 }
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 2764 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().
02765 { 02766 struct ast_sw *i; 02767 int ret = -1; 02768 02769 ast_mutex_lock(&con->lock); 02770 02771 /* walk switches */ 02772 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02773 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02774 (!registrar || !strcmp(i->registrar, registrar))) { 02775 /* found, remove from list */ 02776 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02777 free(i); /* free switch and return */ 02778 ret = 0; 02779 break; 02780 } 02781 } 02782 AST_LIST_TRAVERSE_SAFE_END 02783 02784 ast_mutex_unlock(&con->lock); 02785 02786 return ret; 02787 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 2921 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().
02922 { 02923 struct ast_context *c = NULL; 02924 int ret = -1; 02925 02926 ast_lock_contexts(); 02927 02928 while ((c = ast_walk_contexts(c))) { 02929 if (!strcmp(ast_get_context_name(c), context)) { 02930 ret = 0; 02931 break; 02932 } 02933 } 02934 02935 ast_unlock_contexts(); 02936 02937 /* if we found context, unlock macrolock */ 02938 if (ret == 0) 02939 ret = ast_mutex_unlock(&c->macrolock); 02940 02941 return ret; 02942 }
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 6242 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().
06243 { 06244 struct ast_include *inc = NULL; 06245 int res = 0; 06246 06247 while ( (inc = ast_walk_context_includes(con, inc)) ) 06248 if (!ast_context_find(inc->rname)) { 06249 res = -1; 06250 ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n", 06251 ast_get_context_name(con), inc->rname); 06252 } 06253 return res; 06254 }
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(), odbc_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 odbc_unload_module(), 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(), 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 4551 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().
04552 { 04553 if (!chan) 04554 return -1; 04555 04556 if (!ast_strlen_zero(context)) 04557 ast_copy_string(chan->context, context, sizeof(chan->context)); 04558 if (!ast_strlen_zero(exten)) 04559 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04560 if (priority > -1) { 04561 chan->priority = priority; 04562 /* see flag description in channel.h for explanation */ 04563 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04564 chan->priority--; 04565 } 04566 04567 return 0; 04568 }
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(), and handle_request_subscribe().
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 6099 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 6137 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06138 { 06139 return c ? c->registrar : NULL; 06140 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6167 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().
06168 { 06169 return e ? e->app : NULL; 06170 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6172 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06173 { 06174 return e ? e->data : NULL; 06175 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6162 of file pbx.c.
References ast_exten::cidmatch.
Referenced by find_matching_priority(), and handle_save_dialplan().
06163 { 06164 return e ? e->cidmatch : NULL; 06165 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
const char* ast_get_extension_label | ( | struct ast_exten * | e | ) |
Definition at line 6114 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 6157 of file pbx.c.
References ast_exten::matchcid.
Referenced by find_matching_priority(), and handle_save_dialplan().
06158 { 06159 return e ? e->matchcid : 0; 06160 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6109 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 6129 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 6142 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06143 { 06144 return e ? e->registrar : NULL; 06145 }
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 6124 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().
06125 { 06126 return ip ? ip->pattern : NULL; 06127 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6152 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06153 { 06154 return ip ? ip->registrar : NULL; 06155 }
const char* ast_get_include_name | ( | struct ast_include * | include | ) |
Definition at line 6119 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 6147 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06148 { 06149 return i ? i->registrar : NULL; 06150 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6182 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06183 { 06184 return sw ? sw->data : NULL; 06185 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6177 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06178 { 06179 return sw ? sw->name : NULL; 06180 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6187 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06188 { 06189 return sw ? sw->registrar : NULL; 06190 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6276 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().
06277 { 06278 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06279 }
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 4517 of file pbx.c.
References ast_context_find(), ast_extension_match(), ast_context::ignorepats, ast_ignorepat::next, and ast_ignorepat::pattern.
Referenced by ast_app_dtget(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_enbloc_call_message(), handle_soft_key_event_message(), handle_stimulus_message(), mgcp_ss(), skinny_ss(), and ss_thread().
04518 { 04519 struct ast_context *con = ast_context_find(context); 04520 if (con) { 04521 struct ast_ignorepat *pat; 04522 for (pat = con->ignorepats; pat; pat = pat->next) { 04523 if (ast_extension_match(pat->pattern, pattern)) 04524 return 1; 04525 } 04526 } 04527 04528 return 0; 04529 }
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 6086 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().
06087 { 06088 return ast_mutex_lock(&con->lock); 06089 }
int ast_lock_contexts | ( | void | ) |
Locks the context list.
0 | on success | |
-1 | on error |
Definition at line 6073 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().
06074 { 06075 return ast_mutex_lock(&conlock); 06076 }
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 3912 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().
03913 { 03914 struct ast_context *tmp, *lasttmp = NULL; 03915 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 03916 struct store_hint *this; 03917 struct ast_hint *hint; 03918 struct ast_exten *exten; 03919 int length; 03920 struct ast_state_cb *thiscb, *prevcb; 03921 03922 /* it is very important that this function hold the hint list lock _and_ the conlock 03923 during its operation; not only do we need to ensure that the list of contexts 03924 and extensions does not change, but also that no hint callbacks (watchers) are 03925 added or removed during the merge/delete process 03926 03927 in addition, the locks _must_ be taken in this order, because there are already 03928 other code paths that use this order 03929 */ 03930 ast_mutex_lock(&conlock); 03931 AST_LIST_LOCK(&hints); 03932 03933 /* preserve all watchers for hints associated with this registrar */ 03934 AST_LIST_TRAVERSE(&hints, hint, list) { 03935 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03936 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03937 if (!(this = ast_calloc(1, length))) 03938 continue; 03939 this->callbacks = hint->callbacks; 03940 hint->callbacks = NULL; 03941 this->laststate = hint->laststate; 03942 this->context = this->data; 03943 strcpy(this->data, hint->exten->parent->name); 03944 this->exten = this->data + strlen(this->context) + 1; 03945 strcpy(this->exten, hint->exten->exten); 03946 AST_LIST_INSERT_HEAD(&store, this, list); 03947 } 03948 } 03949 03950 tmp = *extcontexts; 03951 if (registrar) { 03952 /* XXX remove previous contexts from same registrar */ 03953 if (option_debug) 03954 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 03955 __ast_context_destroy(NULL,registrar); 03956 while (tmp) { 03957 lasttmp = tmp; 03958 tmp = tmp->next; 03959 } 03960 } else { 03961 /* XXX remove contexts with the same name */ 03962 while (tmp) { 03963 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 03964 __ast_context_destroy(tmp,tmp->registrar); 03965 lasttmp = tmp; 03966 tmp = tmp->next; 03967 } 03968 } 03969 if (lasttmp) { 03970 lasttmp->next = contexts; 03971 contexts = *extcontexts; 03972 *extcontexts = NULL; 03973 } else 03974 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 03975 03976 /* restore the watchers for hints that can be found; notify those that 03977 cannot be restored 03978 */ 03979 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 03980 exten = ast_hint_extension(NULL, this->context, this->exten); 03981 /* Find the hint in the list of hints */ 03982 AST_LIST_TRAVERSE(&hints, hint, list) { 03983 if (hint->exten == exten) 03984 break; 03985 } 03986 if (!exten || !hint) { 03987 /* this hint has been removed, notify the watchers */ 03988 prevcb = NULL; 03989 thiscb = this->callbacks; 03990 while (thiscb) { 03991 prevcb = thiscb; 03992 thiscb = thiscb->next; 03993 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 03994 free(prevcb); 03995 } 03996 } else { 03997 thiscb = this->callbacks; 03998 while (thiscb->next) 03999 thiscb = thiscb->next; 04000 thiscb->next = hint->callbacks; 04001 hint->callbacks = this->callbacks; 04002 hint->laststate = this->laststate; 04003 } 04004 free(this); 04005 } 04006 04007 AST_LIST_UNLOCK(&hints); 04008 ast_mutex_unlock(&conlock); 04009 04010 return; 04011 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
Definition at line 6286 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().
06287 { 06288 char *exten, *pri, *context; 06289 char *stringp; 06290 int ipri; 06291 int mode = 0; 06292 06293 if (ast_strlen_zero(goto_string)) { 06294 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06295 return -1; 06296 } 06297 stringp = ast_strdupa(goto_string); 06298 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06299 exten = strsep(&stringp, "|"); 06300 pri = strsep(&stringp, "|"); 06301 if (!exten) { /* Only a priority in this one */ 06302 pri = context; 06303 exten = NULL; 06304 context = NULL; 06305 } else if (!pri) { /* Only an extension and priority in this one */ 06306 pri = exten; 06307 exten = context; 06308 context = NULL; 06309 } 06310 if (*pri == '+') { 06311 mode = 1; 06312 pri++; 06313 } else if (*pri == '-') { 06314 mode = -1; 06315 pri++; 06316 } 06317 if (sscanf(pri, "%d", &ipri) != 1) { 06318 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06319 pri, chan->cid.cid_num)) < 1) { 06320 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06321 return -1; 06322 } else 06323 mode = 0; 06324 } 06325 /* At this point we have a priority and maybe an extension and a context */ 06326 06327 if (mode) 06328 ipri = chan->priority + (ipri * mode); 06329 06330 ast_explicit_goto(chan, context, exten, ipri); 06331 ast_cdr_update(chan); 06332 return 0; 06333 06334 }
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 5122 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().
05123 { 05124 struct ast_channel *chan; 05125 struct app_tmp *tmp; 05126 int res = -1, cdr_res = -1; 05127 struct outgoing_helper oh; 05128 pthread_attr_t attr; 05129 05130 memset(&oh, 0, sizeof(oh)); 05131 oh.vars = vars; 05132 oh.account = account; 05133 05134 if (locked_channel) 05135 *locked_channel = NULL; 05136 if (ast_strlen_zero(app)) { 05137 res = -1; 05138 goto outgoing_app_cleanup; 05139 } 05140 if (sync) { 05141 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05142 if (chan) { 05143 if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 05144 ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name); 05145 } else { 05146 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 05147 if(!chan->cdr) { 05148 /* allocation of the cdr failed */ 05149 free(chan->pbx); 05150 res = -1; 05151 goto outgoing_app_cleanup; 05152 } 05153 /* allocation of the cdr was successful */ 05154 ast_cdr_init(chan->cdr, chan); /* initialize our channel's cdr */ 05155 ast_cdr_start(chan->cdr); 05156 } 05157 ast_set_variables(chan, vars); 05158 if (account) 05159 ast_cdr_setaccount(chan, account); 05160 if (chan->_state == AST_STATE_UP) { 05161 res = 0; 05162 if (option_verbose > 3) 05163 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05164 tmp = ast_calloc(1, sizeof(*tmp)); 05165 if (!tmp) 05166 res = -1; 05167 else { 05168 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05169 if (appdata) 05170 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05171 tmp->chan = chan; 05172 if (sync > 1) { 05173 if (locked_channel) 05174 ast_channel_unlock(chan); 05175 ast_pbx_run_app(tmp); 05176 } else { 05177 pthread_attr_init(&attr); 05178 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05179 if (locked_channel) 05180 ast_channel_lock(chan); 05181 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05182 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05183 free(tmp); 05184 if (locked_channel) 05185 ast_channel_unlock(chan); 05186 ast_hangup(chan); 05187 res = -1; 05188 } else { 05189 if (locked_channel) 05190 *locked_channel = chan; 05191 } 05192 pthread_attr_destroy(&attr); 05193 } 05194 } 05195 } else { 05196 if (option_verbose > 3) 05197 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05198 if (chan->cdr) { /* update the cdr */ 05199 /* here we update the status of the call, which sould be busy. 05200 * if that fails then we set the status to failed */ 05201 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05202 ast_cdr_failed(chan->cdr); 05203 } 05204 ast_hangup(chan); 05205 } 05206 } 05207 05208 if (res < 0) { /* the call failed for some reason */ 05209 if (*reason == 0) { /* if the call failed (not busy or no answer) 05210 * update the cdr with the failed message */ 05211 cdr_res = ast_pbx_outgoing_cdr_failed(); 05212 if (cdr_res != 0) { 05213 res = cdr_res; 05214 goto outgoing_app_cleanup; 05215 } 05216 } 05217 } 05218 05219 } else { 05220 struct async_stat *as; 05221 if (!(as = ast_calloc(1, sizeof(*as)))) { 05222 res = -1; 05223 goto outgoing_app_cleanup; 05224 } 05225 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05226 if (!chan) { 05227 free(as); 05228 res = -1; 05229 goto outgoing_app_cleanup; 05230 } 05231 as->chan = chan; 05232 ast_copy_string(as->app, app, sizeof(as->app)); 05233 if (appdata) 05234 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05235 as->timeout = timeout; 05236 ast_set_variables(chan, vars); 05237 if (account) 05238 ast_cdr_setaccount(chan, account); 05239 /* Start a new thread, and get something handling this channel. */ 05240 pthread_attr_init(&attr); 05241 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05242 if (locked_channel) 05243 ast_channel_lock(chan); 05244 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05245 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05246 free(as); 05247 if (locked_channel) 05248 ast_channel_unlock(chan); 05249 ast_hangup(chan); 05250 res = -1; 05251 pthread_attr_destroy(&attr); 05252 goto outgoing_app_cleanup; 05253 } else { 05254 if (locked_channel) 05255 *locked_channel = chan; 05256 } 05257 pthread_attr_destroy(&attr); 05258 res = 0; 05259 } 05260 outgoing_app_cleanup: 05261 ast_variables_destroy(vars); 05262 return res; 05263 }
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 4966 of file pbx.c.
References __ast_request_and_dial(), ast_channel::_state, ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_alloc(), ast_channel_lock, ast_channel_unlock, ast_exists_extension(), ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create, ast_request_and_dial(), ast_set_variables(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, ast_channel::context, free, ast_channel::hangupcause, LOAD_OH, LOG_ERROR, LOG_WARNING, option_verbose, set_ext_pri(), outgoing_helper::vars, and VERBOSE_PREFIX_4.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_exten().
04967 { 04968 struct ast_channel *chan; 04969 struct async_stat *as; 04970 int res = -1, cdr_res = -1; 04971 struct outgoing_helper oh; 04972 pthread_attr_t attr; 04973 04974 if (sync) { 04975 LOAD_OH(oh); 04976 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 04977 if (channel) { 04978 *channel = chan; 04979 if (chan) 04980 ast_channel_lock(chan); 04981 } 04982 if (chan) { 04983 if (chan->_state == AST_STATE_UP) { 04984 res = 0; 04985 if (option_verbose > 3) 04986 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 04987 04988 if (sync > 1) { 04989 if (channel) 04990 ast_channel_unlock(chan); 04991 if (ast_pbx_run(chan)) { 04992 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 04993 if (channel) 04994 *channel = NULL; 04995 ast_hangup(chan); 04996 res = -1; 04997 } 04998 } else { 04999 if (ast_pbx_start(chan)) { 05000 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05001 if (channel) { 05002 *channel = NULL; 05003 ast_channel_unlock(chan); 05004 } 05005 ast_hangup(chan); 05006 res = -1; 05007 } 05008 } 05009 } else { 05010 if (option_verbose > 3) 05011 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05012 05013 if (chan->cdr) { /* update the cdr */ 05014 /* here we update the status of the call, which sould be busy. 05015 * if that fails then we set the status to failed */ 05016 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05017 ast_cdr_failed(chan->cdr); 05018 } 05019 05020 if (channel) { 05021 *channel = NULL; 05022 ast_channel_unlock(chan); 05023 } 05024 ast_hangup(chan); 05025 } 05026 } 05027 05028 if (res < 0) { /* the call failed for some reason */ 05029 if (*reason == 0) { /* if the call failed (not busy or no answer) 05030 * update the cdr with the failed message */ 05031 cdr_res = ast_pbx_outgoing_cdr_failed(); 05032 if (cdr_res != 0) { 05033 res = cdr_res; 05034 goto outgoing_exten_cleanup; 05035 } 05036 } 05037 05038 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05039 /* check if "failed" exists */ 05040 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05041 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05042 if (chan) { 05043 if (!ast_strlen_zero(context)) 05044 ast_copy_string(chan->context, context, sizeof(chan->context)); 05045 set_ext_pri(chan, "failed", 1); 05046 ast_set_variables(chan, vars); 05047 if (account) 05048 ast_cdr_setaccount(chan, account); 05049 ast_pbx_run(chan); 05050 } 05051 } 05052 } 05053 } else { 05054 if (!(as = ast_calloc(1, sizeof(*as)))) { 05055 res = -1; 05056 goto outgoing_exten_cleanup; 05057 } 05058 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05059 if (channel) { 05060 *channel = chan; 05061 if (chan) 05062 ast_channel_lock(chan); 05063 } 05064 if (!chan) { 05065 free(as); 05066 res = -1; 05067 goto outgoing_exten_cleanup; 05068 } 05069 as->chan = chan; 05070 ast_copy_string(as->context, context, sizeof(as->context)); 05071 set_ext_pri(as->chan, exten, priority); 05072 as->timeout = timeout; 05073 ast_set_variables(chan, vars); 05074 if (account) 05075 ast_cdr_setaccount(chan, account); 05076 pthread_attr_init(&attr); 05077 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05078 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05079 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05080 free(as); 05081 if (channel) { 05082 *channel = NULL; 05083 ast_channel_unlock(chan); 05084 } 05085 ast_hangup(chan); 05086 res = -1; 05087 pthread_attr_destroy(&attr); 05088 goto outgoing_exten_cleanup; 05089 } 05090 pthread_attr_destroy(&attr); 05091 res = 0; 05092 } 05093 outgoing_exten_cleanup: 05094 ast_variables_destroy(vars); 05095 return res; 05096 }
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 2643 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().
02644 { 02645 enum ast_pbx_result res = AST_PBX_SUCCESS; 02646 02647 if (increase_call_count(c)) 02648 return AST_PBX_CALL_LIMIT; 02649 02650 res = __ast_pbx_run(c); 02651 decrease_call_count(); 02652 02653 return res; 02654 }
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 2617 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().
02618 { 02619 pthread_t t; 02620 pthread_attr_t attr; 02621 02622 if (!c) { 02623 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02624 return AST_PBX_FAILED; 02625 } 02626 02627 if (increase_call_count(c)) 02628 return AST_PBX_CALL_LIMIT; 02629 02630 /* Start a new thread, and get something handling this channel. */ 02631 pthread_attr_init(&attr); 02632 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02633 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02634 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02635 pthread_attr_destroy(&attr); 02636 return AST_PBX_FAILED; 02637 } 02638 pthread_attr_destroy(&attr); 02639 02640 return AST_PBX_SUCCESS; 02641 }
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 2945 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().
02946 { 02947 struct ast_app *tmp, *cur = NULL; 02948 char tmps[80]; 02949 int length; 02950 02951 AST_LIST_LOCK(&apps); 02952 AST_LIST_TRAVERSE(&apps, tmp, list) { 02953 if (!strcasecmp(app, tmp->name)) { 02954 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02955 AST_LIST_UNLOCK(&apps); 02956 return -1; 02957 } 02958 } 02959 02960 length = sizeof(*tmp) + strlen(app) + 1; 02961 02962 if (!(tmp = ast_calloc(1, length))) { 02963 AST_LIST_UNLOCK(&apps); 02964 return -1; 02965 } 02966 02967 strcpy(tmp->name, app); 02968 tmp->execute = execute; 02969 tmp->synopsis = synopsis; 02970 tmp->description = description; 02971 02972 /* Store in alphabetical order */ 02973 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 02974 if (strcasecmp(tmp->name, cur->name) < 0) { 02975 AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 02976 break; 02977 } 02978 } 02979 AST_LIST_TRAVERSE_SAFE_END 02980 if (!cur) 02981 AST_LIST_INSERT_TAIL(&apps, tmp, list); 02982 02983 if (option_verbose > 1) 02984 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 02985 02986 AST_LIST_UNLOCK(&apps); 02987 02988 return 0; 02989 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 2995 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().
02996 { 02997 struct ast_switch *tmp; 02998 02999 AST_LIST_LOCK(&switches); 03000 AST_LIST_TRAVERSE(&switches, tmp, list) { 03001 if (!strcasecmp(tmp->name, sw->name)) { 03002 AST_LIST_UNLOCK(&switches); 03003 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 03004 return -1; 03005 } 03006 } 03007 AST_LIST_INSERT_TAIL(&switches, sw, list); 03008 AST_LIST_UNLOCK(&switches); 03009 03010 return 0; 03011 }
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 6091 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().
06092 { 06093 return ast_mutex_unlock(&con->lock); 06094 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 6078 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().
06079 { 06080 return ast_mutex_unlock(&conlock); 06081 }
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 3826 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().
03827 { 03828 struct ast_app *tmp; 03829 03830 AST_LIST_LOCK(&apps); 03831 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03832 if (!strcasecmp(app, tmp->name)) { 03833 AST_LIST_REMOVE_CURRENT(&apps, list); 03834 if (option_verbose > 1) 03835 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03836 free(tmp); 03837 break; 03838 } 03839 } 03840 AST_LIST_TRAVERSE_SAFE_END 03841 AST_LIST_UNLOCK(&apps); 03842 03843 return tmp ? 0 : -1; 03844 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 3013 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_REMOVE, and AST_LIST_UNLOCK.
Referenced by __unload_module(), and unload_module().
03014 { 03015 AST_LIST_LOCK(&switches); 03016 AST_LIST_REMOVE(&switches, sw, list); 03017 AST_LIST_UNLOCK(&switches); 03018 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | priority | |||
) |
Definition at line 6200 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().
06202 { 06203 if (!exten) 06204 return con ? con->root : NULL; 06205 else 06206 return exten->next; 06207 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 6233 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().
06235 { 06236 if (!ip) 06237 return con ? con->ignorepats : NULL; 06238 else 06239 return ip->next; 06240 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 6224 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().
06226 { 06227 if (!inc) 06228 return con ? con->includes : NULL; 06229 else 06230 return inc->next; 06231 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 6209 of file pbx.c.
References AST_LIST_FIRST, and AST_LIST_NEXT.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06211 { 06212 if (!sw) 06213 return con ? AST_LIST_FIRST(&con->alts) : NULL; 06214 else 06215 return AST_LIST_NEXT(sw, list); 06216 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 6195 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 6218 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 5949 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().
05950 { 05951 struct ast_var_t *vardata; 05952 05953 ast_mutex_lock(&globalslock); 05954 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 05955 ast_var_delete(vardata); 05956 ast_mutex_unlock(&globalslock); 05957 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5749 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(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), ast_bridge_call(), ast_channel_bridge(), 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(), 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(), sla_trunk_exec(), speech_background(), try_calling(), try_suggested_sip_codec(), txfax_exec(), wait_for_answer(), zt_call(), and zt_hangup().
05750 { 05751 struct ast_var_t *variables; 05752 const char *ret = NULL; 05753 int i; 05754 struct varshead *places[2] = { NULL, &globals }; 05755 05756 if (!name) 05757 return NULL; 05758 if (chan) 05759 places[0] = &chan->varshead; 05760 05761 for (i = 0; i < 2; i++) { 05762 if (!places[i]) 05763 continue; 05764 if (places[i] == &globals) 05765 ast_mutex_lock(&globalslock); 05766 AST_LIST_TRAVERSE(places[i], variables, entries) { 05767 if (!strcmp(name, ast_var_name(variables))) { 05768 ret = ast_var_value(variables); 05769 break; 05770 } 05771 } 05772 if (places[i] == &globals) 05773 ast_mutex_unlock(&globalslock); 05774 if (ret) 05775 break; 05776 } 05777 05778 return ret; 05779 }
void pbx_builtin_pushvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5781 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().
05782 { 05783 struct ast_var_t *newvariable; 05784 struct varshead *headp; 05785 05786 if (name[strlen(name)-1] == ')') { 05787 char *function = ast_strdupa(name); 05788 05789 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05790 ast_func_write(chan, function, value); 05791 return; 05792 } 05793 05794 headp = (chan) ? &chan->varshead : &globals; 05795 05796 if (value) { 05797 if ((option_verbose > 1) && (headp == &globals)) 05798 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05799 newvariable = ast_var_assign(name, value); 05800 if (headp == &globals) 05801 ast_mutex_lock(&globalslock); 05802 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05803 if (headp == &globals) 05804 ast_mutex_unlock(&globalslock); 05805 } 05806 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5722 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().
05723 { 05724 struct ast_var_t *variables; 05725 const char *var, *val; 05726 int total = 0; 05727 05728 if (!chan) 05729 return 0; 05730 05731 memset(buf, 0, size); 05732 05733 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05734 if ((var=ast_var_name(variables)) && (val=ast_var_value(variables)) 05735 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 05736 ) { 05737 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05738 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05739 break; 05740 } else 05741 total++; 05742 } else 05743 break; 05744 } 05745 05746 return total; 05747 }
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 5808 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_odbc_read(), acf_odbc_write(), action_setvar(), agi_exec_full(), aji_status_exec(), aMYSQL_fetch(), app_exec(), aqm_exec(), array(), ast_bridge_call(), ast_channel_bridge(), ast_feature_request_and_dial(), ast_iax2_new(), ast_monitor_start(), ast_set_variables(), background_detect_exec(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), controlplayback_exec(), count_exec(), disa_exec(), do_waiting(), export_aoc_vars(), export_ch(), function_db_delete(), function_db_exists(), function_db_read(), global_write(), handle_request_bye(), handle_request_refer(), handle_set_global(), handle_set_global_deprecated(), handle_setvariable(), hasvoicemail_exec(), isAnsweringMachine(), leave_voicemail(), local_hangup(), lookupblacklist_exec(), misdn_call(), mixmonitor_exec(), 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_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), ss_thread(), start_monitor_exec(), system_exec_helper(), transfer_exec(), try_calling(), tryexec_exec(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), zt_handle_dtmfup(), and zt_new().
05809 { 05810 struct ast_var_t *newvariable; 05811 struct varshead *headp; 05812 const char *nametail = name; 05813 05814 /* XXX may need locking on the channel ? */ 05815 if (name[strlen(name)-1] == ')') { 05816 char *function = ast_strdupa(name); 05817 05818 ast_func_write(chan, function, value); 05819 return; 05820 } 05821 05822 headp = (chan) ? &chan->varshead : &globals; 05823 05824 /* For comparison purposes, we have to strip leading underscores */ 05825 if (*nametail == '_') { 05826 nametail++; 05827 if (*nametail == '_') 05828 nametail++; 05829 } 05830 05831 if (headp == &globals) 05832 ast_mutex_lock(&globalslock); 05833 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05834 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 05835 /* there is already such a variable, delete it */ 05836 AST_LIST_REMOVE(headp, newvariable, entries); 05837 ast_var_delete(newvariable); 05838 break; 05839 } 05840 } 05841 05842 if (value) { 05843 if ((option_verbose > 1) && (headp == &globals)) 05844 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05845 newvariable = ast_var_assign(name, value); 05846 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05847 } 05848 05849 if (headp == &globals) 05850 ast_mutex_unlock(&globalslock); 05851 }
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 5959 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().
05960 { 05961 if (ast_strlen_zero(condition)) /* NULL or empty strings are false */ 05962 return 0; 05963 else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */ 05964 return atoi(condition); 05965 else /* Strings are true */ 05966 return 1; 05967 }
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 2661 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
02662 { 02663 int oldval = autofallthrough; 02664 autofallthrough = newval; 02665 return oldval; 02666 }
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(), add_extensions(), custom_log(), cut_internal(), exec_exec(), function_eval(), handle_getvariablefull(), launch_monitor_thread(), make_email_file(), pbx_builtin_importvar(), pbx_load_config(), pbx_substitute_variables(), realtime_exec(), rpt_do_lstats(), sendpage(), try_calling(), and tryexec_exec().
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 }