#include "asterisk/sched.h"
#include "asterisk/channel.h"
Go to the source code of this file.
Data Structures | |
struct | ast_custom_function |
struct | ast_pbx |
struct | ast_switch |
struct | ast_timing |
struct | cfextension_states |
Defines | |
#define | AST_MAX_APP 32 |
#define | AST_PBX_KEEP 0 |
#define | AST_PBX_KEEPALIVE 10 |
#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) |
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 } |
enum | ast_pbx_result { AST_PBX_SUCCESS = 0, AST_PBX_FAILED = -1, AST_PBX_CALL_LIMIT = -2 } |
Functions | |
int | ast_active_calls (void) |
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) |
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) |
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, char *context, char *exten, int priority) |
int | ast_build_timing (struct ast_timing *i, char *info) |
int | ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
int | ast_check_timing (struct ast_timing *i) |
int | ast_context_add_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
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) |
int | ast_context_add_include2 (struct ast_context *con, const char *include, const char *registrar) |
int | ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar) |
int | ast_context_add_switch2 (struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar) |
ast_context * | ast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar) |
void | ast_context_destroy (struct ast_context *con, const char *registrar) |
ast_context * | ast_context_find (const char *name) |
int | ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar) |
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) |
int | ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar) |
int | ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar) |
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_verify_includes (struct ast_context *con) |
ast_custom_function * | ast_custom_function_find (char *name) |
int | ast_custom_function_register (struct ast_custom_function *acf) |
int | ast_custom_function_unregister (struct ast_custom_function *acf) |
int | ast_exec_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
int | ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
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) |
int | ast_extension_patmatch (const char *pattern, const char *data) |
int | ast_extension_state (struct ast_channel *c, char *context, char *exten) |
ast_extension_state: Check extension state for an extension by using hint | |
const char * | ast_extension_state2str (int extension_state) |
ast_extension_state2str: Return extension_state as string | |
int | ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data) |
ast_extension_state_add: Add watcher for extension states | |
int | ast_extension_state_del (int id, ast_state_cb_type callback) |
ast_extension_state_del: Remove a watcher from the callback list | |
int | ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid) |
int | ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid) |
char * | ast_func_read (struct ast_channel *chan, const char *in, char *workspace, size_t len) |
void | ast_func_write (struct ast_channel *chan, const char *in, const char *value) |
const char * | ast_get_context_name (struct ast_context *con) |
const char * | ast_get_context_registrar (struct ast_context *c) |
const char * | ast_get_extension_app (struct ast_exten *e) |
void * | ast_get_extension_app_data (struct ast_exten *e) |
const char * | ast_get_extension_cidmatch (struct ast_exten *e) |
const char * | ast_get_extension_label (struct ast_exten *e) |
int | ast_get_extension_matchcid (struct ast_exten *e) |
const char * | ast_get_extension_name (struct ast_exten *exten) |
int | ast_get_extension_priority (struct ast_exten *exten) |
const char * | ast_get_extension_registrar (struct ast_exten *e) |
int | ast_get_hint (char *hint, int maxlen, char *name, int maxnamelen, struct ast_channel *c, const char *context, const char *exten) |
ast_get_hint: Get hint for channel | |
const char * | ast_get_ignorepat_name (struct ast_ignorepat *ip) |
const char * | ast_get_ignorepat_registrar (struct ast_ignorepat *ip) |
const char * | ast_get_include_name (struct ast_include *include) |
const char * | ast_get_include_registrar (struct ast_include *i) |
const char * | ast_get_switch_data (struct ast_sw *sw) |
const char * | ast_get_switch_name (struct ast_sw *sw) |
const char * | ast_get_switch_registrar (struct ast_sw *sw) |
int | ast_goto_if_exists (struct ast_channel *chan, char *context, char *exten, int priority) |
void | ast_hint_state_changed (const char *device) |
int | ast_ignore_pattern (const char *context, const char *pattern) |
int | ast_lock_context (struct ast_context *con) |
int | ast_lock_contexts (void) |
int | ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
void | ast_merge_contexts_and_delete (struct ast_context **extcontexts, const char *registrar) |
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) |
enum ast_pbx_result | ast_pbx_start (struct ast_channel *c) |
int | ast_register_application (const char *app, int(*execute)(struct ast_channel *, void *), const char *synopsis, const char *description) |
Dynamically register a new dial plan application. | |
int | ast_register_switch (struct ast_switch *sw) |
int | ast_spawn_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
int | ast_unlock_context (struct ast_context *con) |
int | ast_unlock_contexts (void) |
int | ast_unregister_application (const char *app) |
void | ast_unregister_switch (struct ast_switch *sw) |
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) |
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 (char *condition) |
int | pbx_exec (struct ast_channel *c, struct ast_app *app, void *data, int newstack) |
ast_app * | pbx_findapp (const char *app) |
Find application handle in linked list. | |
void | pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp) |
pbx_retrieve_variable: Support for Asterisk built-in variables 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) |
Variables | |
static struct cfextension_states | extension_states [] |
Definition in file pbx.h.
#define AST_MAX_APP 32 |
Max length of an application
Definition at line 37 of file pbx.h.
Referenced by handle_show_application(), and handle_show_function().
#define AST_PBX_KEEPALIVE 10 |
Special return values from applications to the PBX
Definition at line 40 of file pbx.h.
Referenced by __ast_pbx_run(), agi_handle_command(), builtin_blindtransfer(), dial_exec_full(), feature_exec_app(), macro_exec(), park_call_exec(), queue_exec(), rpt_exec(), and run_agi().
#define AST_PBX_NO_HANGUP_PEER 11 |
Definition at line 41 of file pbx.h.
Referenced by builtin_blindtransfer(), dial_exec_full(), feature_exec_app(), park_exec(), and try_calling().
#define PRIORITY_HINT -1 |
Special Priority for an hint
Definition at line 44 of file pbx.h.
Referenced by ast_add_extension2(), ast_context_remove_extension2(), ast_hint_extension(), destroy_exten(), handle_context_add_extension(), handle_context_remove_extension(), handle_save_dialplan(), park_add_hints(), pbx_load_module(), and show_dialplan_helper().
typedef int(*) ast_state_cb_type(char *context, char *id, enum ast_extension_states state, void *data) |
enum ast_extension_states |
Extension states
Definition at line 47 of file pbx.h.
00047 { 00048 /*! Extension removed */ 00049 AST_EXTENSION_REMOVED = -2, 00050 /*! Extension hint removed */ 00051 AST_EXTENSION_DEACTIVATED = -1, 00052 /*! No device INUSE or BUSY */ 00053 AST_EXTENSION_NOT_INUSE = 0, 00054 /*! One or more devices INUSE */ 00055 AST_EXTENSION_INUSE = 1 << 0, 00056 /*! All devices BUSY */ 00057 AST_EXTENSION_BUSY = 1 << 1, 00058 /*! All devices UNAVAILABLE/UNREGISTERED */ 00059 AST_EXTENSION_UNAVAILABLE = 1 << 2, 00060 /*! All devices RINGING */ 00061 AST_EXTENSION_RINGING = 1 << 3, 00062 };
enum ast_pbx_result |
Definition at line 209 of file pbx.h.
00209 { 00210 AST_PBX_SUCCESS = 0, 00211 AST_PBX_FAILED = -1, 00212 AST_PBX_CALL_LIMIT = -2, 00213 };
int ast_active_calls | ( | void | ) |
Definition at line 2562 of file pbx.c.
References countcalls.
Referenced by handle_chanlist().
02563 { 02564 return countcalls; 02565 }
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 | |||
) |
context | context to add the extension to | |
replace | ||
extension | extension to add | |
priority | priority level of extension addition | |
label | extension label | |
callerid | callerid of extension | |
application | application to run on the extension with that priority level | |
data | data to pass to the application | |
datad | ||
registrar | who registered the extension Add and extension to an extension context. Callerid is a pattern to match CallerID, or NULL to match any callerid Returns 0 on success, -1 on failure |
Definition at line 4505 of file pbx.c.
References ast_add_extension2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by handle_context_add_extension(), park_add_hints(), and register_peer_exten().
04507 { 04508 struct ast_context *c; 04509 04510 if (ast_lock_contexts()) { 04511 errno = EBUSY; 04512 return -1; 04513 } 04514 04515 c = ast_walk_contexts(NULL); 04516 while (c) { 04517 if (!strcmp(context, ast_get_context_name(c))) { 04518 int ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04519 application, data, datad, registrar); 04520 ast_unlock_contexts(); 04521 return ret; 04522 } 04523 c = ast_walk_contexts(c); 04524 } 04525 04526 ast_unlock_contexts(); 04527 errno = ENOENT; 04528 return -1; 04529 }
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 | |||
) |
For details about the arguements, check ast_add_extension()
Definition at line 4644 of file pbx.c.
References ast_add_hint(), ast_change_hint(), AST_LIST_FIRST, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_exten::cidmatch, ast_exten::data, ast_exten::datad, el, ext_strncpy(), ast_exten::exten, free, globals, ast_context::lock, LOG, LOG_ERROR, LOG_WARNING, malloc, ast_exten::matchcid, ast_context::name, ast_exten::next, null_datad(), pbx_substitute_variables_varshead(), ast_exten::peer, ast_exten::priority, PRIORITY_HINT, ast_context::registrar, ast_context::root, and VAR_BUF_SIZE.
Referenced by __build_step(), ast_add_extension(), ast_park_call(), do_parking_thread(), fillin_process(), handle_macro(), load_config(), and pbx_load_module().
04648 { 04649 04650 #define LOG do { if (option_debug) {\ 04651 if (tmp->matchcid) { \ 04652 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \ 04653 } else { \ 04654 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \ 04655 } \ 04656 } else if (option_verbose > 2) { \ 04657 if (tmp->matchcid) { \ 04658 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \ 04659 } else { \ 04660 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \ 04661 } \ 04662 } } while(0) 04663 04664 /* 04665 * This is a fairly complex routine. Different extensions are kept 04666 * in order by the extension number. Then, extensions of different 04667 * priorities (same extension) are kept in a list, according to the 04668 * peer pointer. 04669 */ 04670 struct ast_exten *tmp, *e, *el = NULL, *ep = NULL; 04671 int res; 04672 int length; 04673 char *p; 04674 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04675 04676 /* if we are adding a hint, and there are global variables, and the hint 04677 contains variable references, then expand them 04678 */ 04679 ast_mutex_lock(&globalslock); 04680 if ((priority == PRIORITY_HINT) && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04681 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04682 application = expand_buf; 04683 } 04684 ast_mutex_unlock(&globalslock); 04685 04686 length = sizeof(struct ast_exten); 04687 length += strlen(extension) + 1; 04688 length += strlen(application) + 1; 04689 if (label) 04690 length += strlen(label) + 1; 04691 if (callerid) 04692 length += strlen(callerid) + 1; 04693 else 04694 length ++; 04695 04696 /* Be optimistic: Build the extension structure first */ 04697 if (datad == NULL) 04698 datad = null_datad; 04699 tmp = malloc(length); 04700 if (tmp) { 04701 memset(tmp, 0, length); 04702 p = tmp->stuff; 04703 if (label) { 04704 tmp->label = p; 04705 strcpy(tmp->label, label); 04706 p += strlen(label) + 1; 04707 } 04708 tmp->exten = p; 04709 p += ext_strncpy(tmp->exten, extension, strlen(extension) + 1) + 1; 04710 tmp->priority = priority; 04711 tmp->cidmatch = p; 04712 if (callerid) { 04713 p += ext_strncpy(tmp->cidmatch, callerid, strlen(callerid) + 1) + 1; 04714 tmp->matchcid = 1; 04715 } else { 04716 tmp->cidmatch[0] = '\0'; 04717 tmp->matchcid = 0; 04718 p++; 04719 } 04720 tmp->app = p; 04721 strcpy(tmp->app, application); 04722 tmp->parent = con; 04723 tmp->data = data; 04724 tmp->datad = datad; 04725 tmp->registrar = registrar; 04726 tmp->peer = NULL; 04727 tmp->next = NULL; 04728 } else { 04729 ast_log(LOG_ERROR, "Out of memory\n"); 04730 errno = ENOMEM; 04731 return -1; 04732 } 04733 if (ast_mutex_lock(&con->lock)) { 04734 free(tmp); 04735 /* And properly destroy the data */ 04736 datad(data); 04737 ast_log(LOG_WARNING, "Failed to lock context '%s'\n", con->name); 04738 errno = EBUSY; 04739 return -1; 04740 } 04741 e = con->root; 04742 while(e) { 04743 /* Make sure patterns are always last! */ 04744 if ((e->exten[0] != '_') && (extension[0] == '_')) 04745 res = -1; 04746 else if ((e->exten[0] == '_') && (extension[0] != '_')) 04747 res = 1; 04748 else 04749 res= strcmp(e->exten, extension); 04750 if (!res) { 04751 if (!e->matchcid && !tmp->matchcid) 04752 res = 0; 04753 else if (tmp->matchcid && !e->matchcid) 04754 res = 1; 04755 else if (e->matchcid && !tmp->matchcid) 04756 res = -1; 04757 else 04758 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04759 } 04760 if (res == 0) { 04761 /* We have an exact match, now we find where we are 04762 and be sure there's no duplicates */ 04763 while(e) { 04764 if (e->priority == tmp->priority) { 04765 /* Can't have something exactly the same. Is this a 04766 replacement? If so, replace, otherwise, bonk. */ 04767 if (replace) { 04768 if (ep) { 04769 /* We're in the peer list, insert ourselves */ 04770 ep->peer = tmp; 04771 tmp->peer = e->peer; 04772 } else if (el) { 04773 /* We're the first extension. Take over e's functions */ 04774 el->next = tmp; 04775 tmp->next = e->next; 04776 tmp->peer = e->peer; 04777 } else { 04778 /* We're the very first extension. */ 04779 con->root = tmp; 04780 tmp->next = e->next; 04781 tmp->peer = e->peer; 04782 } 04783 if (tmp->priority == PRIORITY_HINT) 04784 ast_change_hint(e,tmp); 04785 /* Destroy the old one */ 04786 e->datad(e->data); 04787 free(e); 04788 ast_mutex_unlock(&con->lock); 04789 if (tmp->priority == PRIORITY_HINT) 04790 ast_change_hint(e, tmp); 04791 /* And immediately return success. */ 04792 LOG; 04793 return 0; 04794 } else { 04795 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name); 04796 tmp->datad(tmp->data); 04797 free(tmp); 04798 ast_mutex_unlock(&con->lock); 04799 errno = EEXIST; 04800 return -1; 04801 } 04802 } else if (e->priority > tmp->priority) { 04803 /* Slip ourselves in just before e */ 04804 if (ep) { 04805 /* Easy enough, we're just in the peer list */ 04806 ep->peer = tmp; 04807 tmp->peer = e; 04808 } else if (el) { 04809 /* We're the first extension in this peer list */ 04810 el->next = tmp; 04811 tmp->next = e->next; 04812 e->next = NULL; 04813 tmp->peer = e; 04814 } else { 04815 /* We're the very first extension altogether */ 04816 tmp->next = con->root->next; 04817 /* Con->root must always exist or we couldn't get here */ 04818 tmp->peer = con->root; 04819 con->root = tmp; 04820 } 04821 ast_mutex_unlock(&con->lock); 04822 04823 /* And immediately return success. */ 04824 if (tmp->priority == PRIORITY_HINT) 04825 ast_add_hint(tmp); 04826 04827 LOG; 04828 return 0; 04829 } 04830 ep = e; 04831 e = e->peer; 04832 } 04833 /* If we make it here, then it's time for us to go at the very end. 04834 ep *must* be defined or we couldn't have gotten here. */ 04835 ep->peer = tmp; 04836 ast_mutex_unlock(&con->lock); 04837 if (tmp->priority == PRIORITY_HINT) 04838 ast_add_hint(tmp); 04839 04840 /* And immediately return success. */ 04841 LOG; 04842 return 0; 04843 04844 } else if (res > 0) { 04845 /* Insert ourselves just before 'e'. We're the first extension of 04846 this kind */ 04847 tmp->next = e; 04848 if (el) { 04849 /* We're in the list somewhere */ 04850 el->next = tmp; 04851 } else { 04852 /* We're at the top of the list */ 04853 con->root = tmp; 04854 } 04855 ast_mutex_unlock(&con->lock); 04856 if (tmp->priority == PRIORITY_HINT) 04857 ast_add_hint(tmp); 04858 04859 /* And immediately return success. */ 04860 LOG; 04861 return 0; 04862 } 04863 04864 el = e; 04865 e = e->next; 04866 } 04867 /* If we fall all the way through to here, then we need to be on the end. */ 04868 if (el) 04869 el->next = tmp; 04870 else 04871 con->root = tmp; 04872 ast_mutex_unlock(&con->lock); 04873 if (tmp->priority == PRIORITY_HINT) 04874 ast_add_hint(tmp); 04875 LOG; 04876 return 0; 04877 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4550 of file pbx.c.
References ast_channel::_state, ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_setstate(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_strlen_zero(), ast_channel::context, ast_channel::exten, ast_channel::lock, LOG_WARNING, ast_channel::name, ast_channel::pbx, ast_channel::readformat, and ast_channel::writeformat.
Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), handle_request_bye(), handle_request_refer(), monitor_handle_owned(), process_ast_dsp(), socket_read(), and zt_read().
04551 { 04552 int res = 0; 04553 04554 ast_mutex_lock(&chan->lock); 04555 04556 if (chan->pbx) { 04557 /* This channel is currently in the PBX */ 04558 ast_explicit_goto(chan, context, exten, priority); 04559 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04560 } else { 04561 /* In order to do it when the channel doesn't really exist within 04562 the PBX, we have to make a new channel, masquerade, and start the PBX 04563 at the new location */ 04564 struct ast_channel *tmpchan; 04565 tmpchan = ast_channel_alloc(0); 04566 if (tmpchan) { 04567 snprintf(tmpchan->name, sizeof(tmpchan->name), "AsyncGoto/%s", chan->name); 04568 ast_setstate(tmpchan, chan->_state); 04569 /* Make formats okay */ 04570 tmpchan->readformat = chan->readformat; 04571 tmpchan->writeformat = chan->writeformat; 04572 /* Setup proper location */ 04573 ast_explicit_goto(tmpchan, 04574 (!ast_strlen_zero(context)) ? context : chan->context, 04575 (!ast_strlen_zero(exten)) ? exten : chan->exten, 04576 priority); 04577 04578 /* Masquerade into temp channel */ 04579 ast_channel_masquerade(tmpchan, chan); 04580 04581 /* Grab the locks and get going */ 04582 ast_mutex_lock(&tmpchan->lock); 04583 ast_do_masquerade(tmpchan); 04584 ast_mutex_unlock(&tmpchan->lock); 04585 /* Start the PBX going on our stolen channel */ 04586 if (ast_pbx_start(tmpchan)) { 04587 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04588 ast_hangup(tmpchan); 04589 res = -1; 04590 } 04591 } else { 04592 res = -1; 04593 } 04594 } 04595 ast_mutex_unlock(&chan->lock); 04596 return res; 04597 }
int ast_async_goto_by_name | ( | const char * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4599 of file pbx.c.
References ast_async_goto(), ast_get_channel_by_name_locked(), ast_mutex_unlock(), and ast_channel::lock.
04600 { 04601 struct ast_channel *chan; 04602 int res = -1; 04603 04604 chan = ast_get_channel_by_name_locked(channame); 04605 if (chan) { 04606 res = ast_async_goto(chan, context, exten, priority); 04607 ast_mutex_unlock(&chan->lock); 04608 } 04609 return res; 04610 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
char * | context, | |||
char * | exten, | |||
int | priority | |||
) |
Definition at line 6471 of file pbx.c.
References __ast_goto_if_exists().
06471 { 06472 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06473 }
int ast_build_timing | ( | struct ast_timing * | i, | |
char * | info | |||
) |
Definition at line 4083 of file pbx.c.
References ast_strlen_zero(), ast_timing::daymask, ast_timing::dowmask, FIND_NEXT, get_day(), get_dow(), get_month(), get_timerange(), and ast_timing::monthmask.
Referenced by ast_context_add_include2(), builtin_function_iftime(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
04084 { 04085 char info_save[256]; 04086 char *info; 04087 char *c; 04088 04089 /* Check for empty just in case */ 04090 if (ast_strlen_zero(info_in)) 04091 return 0; 04092 /* make a copy just in case we were passed a static string */ 04093 ast_copy_string(info_save, info_in, sizeof(info_save)); 04094 info = info_save; 04095 /* Assume everything except time */ 04096 i->monthmask = (1 << 12) - 1; 04097 i->daymask = (1 << 30) - 1 + (1 << 30); 04098 i->dowmask = (1 << 7) - 1; 04099 /* Avoid using str tok */ 04100 FIND_NEXT; 04101 /* Info has the time range, start with that */ 04102 get_timerange(i, info); 04103 info = c; 04104 if (!info) 04105 return 1; 04106 FIND_NEXT; 04107 /* Now check for day of week */ 04108 i->dowmask = get_dow(info); 04109 04110 info = c; 04111 if (!info) 04112 return 1; 04113 FIND_NEXT; 04114 /* Now check for the day of the month */ 04115 i->daymask = get_day(info); 04116 info = c; 04117 if (!info) 04118 return 1; 04119 FIND_NEXT; 04120 /* And finally go for the month */ 04121 i->monthmask = get_month(info); 04122 04123 return 1; 04124 }
int ast_canmatch_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) |
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 If "exten" *could be* a valid extension in this context with or without some more digits, return non-zero. Basically, when this returns 0, no matter what you add to exten, it's not going to be a valid extension anymore |
Definition at line 2218 of file pbx.c.
References HELPER_CANMATCH, and pbx_extension_helper().
Referenced by background_detect_exec(), cb_events(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), loopback_canmatch(), mgcp_ss(), monitor_handle_notowned(), phone_check_exception(), rpt(), skinny_ss(), ss_thread(), and valid_exit().
02219 { 02220 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_CANMATCH); 02221 }
int ast_check_timing | ( | struct ast_timing * | i | ) |
Definition at line 4126 of file pbx.c.
References ast_log(), ast_timing::daymask, ast_timing::dowmask, LOG_WARNING, ast_timing::minmask, ast_timing::monthmask, and t.
Referenced by builtin_function_iftime(), include_valid(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
04127 { 04128 struct tm tm; 04129 time_t t; 04130 04131 time(&t); 04132 localtime_r(&t,&tm); 04133 04134 /* If it's not the right month, return */ 04135 if (!(i->monthmask & (1 << tm.tm_mon))) { 04136 return 0; 04137 } 04138 04139 /* If it's not that time of the month.... */ 04140 /* Warning, tm_mday has range 1..31! */ 04141 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04142 return 0; 04143 04144 /* If it's not the right day of the week */ 04145 if (!(i->dowmask & (1 << tm.tm_wday))) 04146 return 0; 04147 04148 /* Sanity check the hour just to be safe */ 04149 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04150 ast_log(LOG_WARNING, "Insane time...\n"); 04151 return 0; 04152 } 04153 04154 /* Now the tough part, we calculate if it fits 04155 in the right time based on min/hour */ 04156 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04157 return 0; 04158 04159 /* If we got this far, then we're good */ 04160 return 1; 04161 }
int ast_context_add_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
context | which context to add the ignorpattern to | |
ignorepat | ignorepattern to set up for the extension | |
registrar | registrar of the ignore pattern Adds an ignore pattern to a particular context. Returns 0 on success, -1 on failure |
Definition at line 4422 of file pbx.c.
References ast_context_add_ignorepat2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by handle_context_add_ignorepat().
04423 { 04424 struct ast_context *c; 04425 04426 if (ast_lock_contexts()) { 04427 errno = EBUSY; 04428 return -1; 04429 } 04430 04431 c = ast_walk_contexts(NULL); 04432 while (c) { 04433 if (!strcmp(ast_get_context_name(c), con)) { 04434 int ret = ast_context_add_ignorepat2(c, value, registrar); 04435 ast_unlock_contexts(); 04436 return ret; 04437 } 04438 c = ast_walk_contexts(c); 04439 } 04440 04441 ast_unlock_contexts(); 04442 errno = ENOENT; 04443 return -1; 04444 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4446 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_context::ignorepats, ast_context::lock, LOG_ERROR, malloc, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.
Referenced by ast_context_add_ignorepat(), handle_context(), and pbx_load_module().
04447 { 04448 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04449 int length; 04450 length = sizeof(struct ast_ignorepat); 04451 length += strlen(value) + 1; 04452 ignorepat = malloc(length); 04453 if (!ignorepat) { 04454 ast_log(LOG_ERROR, "Out of memory\n"); 04455 errno = ENOMEM; 04456 return -1; 04457 } 04458 memset(ignorepat, 0, length); 04459 strcpy(ignorepat->pattern, value); 04460 ignorepat->next = NULL; 04461 ignorepat->registrar = registrar; 04462 ast_mutex_lock(&con->lock); 04463 ignorepatc = con->ignorepats; 04464 while(ignorepatc) { 04465 ignorepatl = ignorepatc; 04466 if (!strcasecmp(ignorepatc->pattern, value)) { 04467 /* Already there */ 04468 ast_mutex_unlock(&con->lock); 04469 errno = EEXIST; 04470 return -1; 04471 } 04472 ignorepatc = ignorepatc->next; 04473 } 04474 if (ignorepatl) 04475 ignorepatl->next = ignorepat; 04476 else 04477 con->ignorepats = ignorepat; 04478 ast_mutex_unlock(&con->lock); 04479 return 0; 04480 04481 }
int ast_context_add_include | ( | const char * | context, | |
const char * | include, | |||
const char * | registrar | |||
) |
context | context to add include to | |
include | new include to add | |
registrar | who's registering it Adds an include taking a char * string as the context parameter Returns 0 on success, -1 on error |
Definition at line 3805 of file pbx.c.
References ast_context_add_include2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by handle_context_add_include().
03806 { 03807 struct ast_context *c; 03808 03809 if (ast_lock_contexts()) { 03810 errno = EBUSY; 03811 return -1; 03812 } 03813 03814 /* walk contexts ... */ 03815 c = ast_walk_contexts(NULL); 03816 while (c) { 03817 /* ... search for the right one ... */ 03818 if (!strcmp(ast_get_context_name(c), context)) { 03819 int ret = ast_context_add_include2(c, include, registrar); 03820 /* ... unlock contexts list and return */ 03821 ast_unlock_contexts(); 03822 return ret; 03823 } 03824 c = ast_walk_contexts(c); 03825 } 03826 03827 /* we can't find the right context */ 03828 ast_unlock_contexts(); 03829 errno = ENOENT; 03830 return -1; 03831 }
int ast_context_add_include2 | ( | struct ast_context * | con, | |
const char * | include, | |||
const char * | registrar | |||
) |
con | context to add the include to | |
include | include to add | |
registrar | who registered the context Adds an include taking a struct ast_context as the first parameter Returns 0 on success, -1 on failure |
Definition at line 4170 of file pbx.c.
References ast_build_timing(), ast_get_context_name(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, ast_include::hastime, ast_context::includes, ast_context::lock, LOG_ERROR, malloc, 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(), handle_context(), and pbx_load_module().
04172 { 04173 struct ast_include *new_include; 04174 char *c; 04175 struct ast_include *i, *il = NULL; /* include, include_last */ 04176 int length; 04177 char *p; 04178 04179 length = sizeof(struct ast_include); 04180 length += 2 * (strlen(value) + 1); 04181 04182 /* allocate new include structure ... */ 04183 if (!(new_include = malloc(length))) { 04184 ast_log(LOG_ERROR, "Out of memory\n"); 04185 errno = ENOMEM; 04186 return -1; 04187 } 04188 04189 /* ... fill in this structure ... */ 04190 memset(new_include, 0, length); 04191 p = new_include->stuff; 04192 new_include->name = p; 04193 strcpy(new_include->name, value); 04194 p += strlen(value) + 1; 04195 new_include->rname = p; 04196 strcpy(new_include->rname, value); 04197 c = new_include->rname; 04198 /* Strip off timing info */ 04199 while(*c && (*c != '|')) 04200 c++; 04201 /* Process if it's there */ 04202 if (*c) { 04203 new_include->hastime = ast_build_timing(&(new_include->timing), c+1); 04204 *c = '\0'; 04205 } 04206 new_include->next = NULL; 04207 new_include->registrar = registrar; 04208 04209 /* ... try to lock this context ... */ 04210 if (ast_mutex_lock(&con->lock)) { 04211 free(new_include); 04212 errno = EBUSY; 04213 return -1; 04214 } 04215 04216 /* ... go to last include and check if context is already included too... */ 04217 i = con->includes; 04218 while (i) { 04219 if (!strcasecmp(i->name, new_include->name)) { 04220 free(new_include); 04221 ast_mutex_unlock(&con->lock); 04222 errno = EEXIST; 04223 return -1; 04224 } 04225 il = i; 04226 i = i->next; 04227 } 04228 04229 /* ... include new context into context list, unlock, return */ 04230 if (il) 04231 il->next = new_include; 04232 else 04233 con->includes = new_include; 04234 if (option_verbose > 2) 04235 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04236 ast_mutex_unlock(&con->lock); 04237 04238 return 0; 04239 }
int ast_context_add_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
int | eval, | |||
const char * | registrar | |||
) |
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 This function registers a switch with the asterisk switch architecture It returns 0 on success, -1 on failure |
Definition at line 4246 of file pbx.c.
References ast_context_add_switch2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
04247 { 04248 struct ast_context *c; 04249 04250 if (ast_lock_contexts()) { 04251 errno = EBUSY; 04252 return -1; 04253 } 04254 04255 /* walk contexts ... */ 04256 c = ast_walk_contexts(NULL); 04257 while (c) { 04258 /* ... search for the right one ... */ 04259 if (!strcmp(ast_get_context_name(c), context)) { 04260 int ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04261 /* ... unlock contexts list and return */ 04262 ast_unlock_contexts(); 04263 return ret; 04264 } 04265 c = ast_walk_contexts(c); 04266 } 04267 04268 /* we can't find the right context */ 04269 ast_unlock_contexts(); 04270 errno = ENOENT; 04271 return -1; 04272 }
int ast_context_add_switch2 | ( | struct ast_context * | con, | |
const char * | sw, | |||
const char * | data, | |||
int | eval, | |||
const char * | registrar | |||
) |
Definition at line 4281 of file pbx.c.
References ast_context::alts, ast_get_context_name(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_sw::data, ast_sw::eval, free, ast_context::lock, LOG_ERROR, malloc, ast_sw::name, ast_sw::next, option_verbose, ast_sw::registrar, ast_sw::stuff, SWITCH_DATA_LENGTH, ast_sw::tmpdata, and VERBOSE_PREFIX_3.
Referenced by ast_context_add_switch(), handle_context(), and pbx_load_module().
04283 { 04284 struct ast_sw *new_sw; 04285 struct ast_sw *i, *il = NULL; /* sw, sw_last */ 04286 int length; 04287 char *p; 04288 04289 length = sizeof(struct ast_sw); 04290 length += strlen(value) + 1; 04291 if (data) 04292 length += strlen(data); 04293 length++; 04294 if (eval) { 04295 /* Create buffer for evaluation of variables */ 04296 length += SWITCH_DATA_LENGTH; 04297 length++; 04298 } 04299 04300 /* allocate new sw structure ... */ 04301 if (!(new_sw = malloc(length))) { 04302 ast_log(LOG_ERROR, "Out of memory\n"); 04303 errno = ENOMEM; 04304 return -1; 04305 } 04306 04307 /* ... fill in this structure ... */ 04308 memset(new_sw, 0, length); 04309 p = new_sw->stuff; 04310 new_sw->name = p; 04311 strcpy(new_sw->name, value); 04312 p += strlen(value) + 1; 04313 new_sw->data = p; 04314 if (data) { 04315 strcpy(new_sw->data, data); 04316 p += strlen(data) + 1; 04317 } else { 04318 strcpy(new_sw->data, ""); 04319 p++; 04320 } 04321 if (eval) 04322 new_sw->tmpdata = p; 04323 new_sw->next = NULL; 04324 new_sw->eval = eval; 04325 new_sw->registrar = registrar; 04326 04327 /* ... try to lock this context ... */ 04328 if (ast_mutex_lock(&con->lock)) { 04329 free(new_sw); 04330 errno = EBUSY; 04331 return -1; 04332 } 04333 04334 /* ... go to last sw and check if context is already swd too... */ 04335 i = con->alts; 04336 while (i) { 04337 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04338 free(new_sw); 04339 ast_mutex_unlock(&con->lock); 04340 errno = EEXIST; 04341 return -1; 04342 } 04343 il = i; 04344 i = i->next; 04345 } 04346 04347 /* ... sw new context into context list, unlock, return */ 04348 if (il) 04349 il->next = new_sw; 04350 else 04351 con->alts = new_sw; 04352 if (option_verbose > 2) 04353 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04354 ast_mutex_unlock(&con->lock); 04355 04356 return 0; 04357 }
struct ast_context* ast_context_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar | |||
) |
extcontexts | pointer to the ast_context structure pointer | |
name | name of the new context | |
registrar | registrar of the context This will first search for a context with your name. If it exists already, it will not create a new one. If it does not exist, it will create a new one with the given name and registrar. It returns NULL on failure, and an ast_context structure on success |
Definition at line 3640 of file pbx.c.
References ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), contexts, ast_context::includes, local_contexts, LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, ast_context::name, ast_context::next, option_debug, option_verbose, and VERBOSE_PREFIX_3.
Referenced by ast_park_call(), do_parking_thread(), handle_context(), handle_macro(), load_config(), pbx_load_module(), reload_config(), and set_config().
03641 { 03642 struct ast_context *tmp, **local_contexts; 03643 int length; 03644 length = sizeof(struct ast_context); 03645 length += strlen(name) + 1; 03646 if (!extcontexts) { 03647 local_contexts = &contexts; 03648 ast_mutex_lock(&conlock); 03649 } else 03650 local_contexts = extcontexts; 03651 03652 tmp = *local_contexts; 03653 while(tmp) { 03654 if (!strcasecmp(tmp->name, name)) { 03655 ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name); 03656 if (!extcontexts) 03657 ast_mutex_unlock(&conlock); 03658 return NULL; 03659 } 03660 tmp = tmp->next; 03661 } 03662 tmp = malloc(length); 03663 if (tmp) { 03664 memset(tmp, 0, length); 03665 ast_mutex_init(&tmp->lock); 03666 strcpy(tmp->name, name); 03667 tmp->root = NULL; 03668 tmp->registrar = registrar; 03669 tmp->next = *local_contexts; 03670 tmp->includes = NULL; 03671 tmp->ignorepats = NULL; 03672 *local_contexts = tmp; 03673 if (option_debug) 03674 ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name); 03675 else if (option_verbose > 2) 03676 ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name); 03677 } else 03678 ast_log(LOG_ERROR, "Out of memory\n"); 03679 03680 if (!extcontexts) 03681 ast_mutex_unlock(&conlock); 03682 return tmp; 03683 }
void ast_context_destroy | ( | struct ast_context * | con, | |
const char * | registrar | |||
) |
con | context to destroy | |
registrar | who registered it You can optionally leave out either parameter. It will find it based on either the ast_context or the registrar name. Returns nothing |
Definition at line 5386 of file pbx.c.
References __ast_context_destroy().
Referenced by ael_reload(), reload(), and unload_module().
05387 { 05388 __ast_context_destroy(con,registrar); 05389 }
struct ast_context* ast_context_find | ( | const char * | name | ) |
name | name of the context to find Will search for the context with the given name. Returns the ast_context on success, NULL on failure. |
Definition at line 736 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), contexts, ast_context::name, and ast_context::next.
Referenced by ast_context_verify_includes(), ast_ignore_pattern(), ast_park_call(), do_parking_thread(), load_config(), macro_exec(), park_exec(), reload_config(), and set_config().
00737 { 00738 struct ast_context *tmp; 00739 ast_mutex_lock(&conlock); 00740 if (name) { 00741 tmp = contexts; 00742 while(tmp) { 00743 if (!strcasecmp(name, tmp->name)) 00744 break; 00745 tmp = tmp->next; 00746 } 00747 } else 00748 tmp = contexts; 00749 ast_mutex_unlock(&conlock); 00750 return tmp; 00751 }
int ast_context_remove_extension | ( | const char * | context, | |
const char * | extension, | |||
int | priority, | |||
const char * | registrar | |||
) |
context | context to remove extension from | |
extension | which extension to remove | |
priority | priority of extension to remove | |
registrar | registrar of the extension This function removes an extension from a given context. Returns 0 on success, -1 on failure |
Definition at line 2725 of file pbx.c.
References ast_context_remove_extension2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by handle_context_remove_extension(), and register_peer_exten().
02726 { 02727 struct ast_context *c; 02728 02729 if (ast_lock_contexts()) return -1; 02730 02731 /* walk contexts ... */ 02732 c = ast_walk_contexts(NULL); 02733 while (c) { 02734 /* ... search for the right one ... */ 02735 if (!strcmp(ast_get_context_name(c), context)) { 02736 /* ... remove extension ... */ 02737 int ret = ast_context_remove_extension2(c, extension, priority, 02738 registrar); 02739 /* ... unlock contexts list and return */ 02740 ast_unlock_contexts(); 02741 return ret; 02742 } 02743 c = ast_walk_contexts(c); 02744 } 02745 02746 /* we can't find the right context */ 02747 ast_unlock_contexts(); 02748 return -1; 02749 }
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 2761 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_remove_hint(), exten, free, ast_context::lock, ast_exten::next, ast_exten::peer, ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, and ast_context::root.
Referenced by ast_context_remove_extension(), do_parking_thread(), load_config(), and park_exec().
02762 { 02763 struct ast_exten *exten, *prev_exten = NULL; 02764 02765 if (ast_mutex_lock(&con->lock)) return -1; 02766 02767 /* go through all extensions in context and search the right one ... */ 02768 exten = con->root; 02769 while (exten) { 02770 02771 /* look for right extension */ 02772 if (!strcmp(exten->exten, extension) && 02773 (!registrar || !strcmp(exten->registrar, registrar))) { 02774 struct ast_exten *peer; 02775 02776 /* should we free all peers in this extension? (priority == 0)? */ 02777 if (priority == 0) { 02778 /* remove this extension from context list */ 02779 if (prev_exten) 02780 prev_exten->next = exten->next; 02781 else 02782 con->root = exten->next; 02783 02784 /* fire out all peers */ 02785 peer = exten; 02786 while (peer) { 02787 exten = peer->peer; 02788 02789 if (!peer->priority==PRIORITY_HINT) 02790 ast_remove_hint(peer); 02791 02792 peer->datad(peer->data); 02793 free(peer); 02794 02795 peer = exten; 02796 } 02797 02798 ast_mutex_unlock(&con->lock); 02799 return 0; 02800 } else { 02801 /* remove only extension with exten->priority == priority */ 02802 struct ast_exten *previous_peer = NULL; 02803 02804 peer = exten; 02805 while (peer) { 02806 /* is this our extension? */ 02807 if (peer->priority == priority && 02808 (!registrar || !strcmp(peer->registrar, registrar) )) { 02809 /* we are first priority extension? */ 02810 if (!previous_peer) { 02811 /* exists previous extension here? */ 02812 if (prev_exten) { 02813 /* yes, so we must change next pointer in 02814 * previous connection to next peer 02815 */ 02816 if (peer->peer) { 02817 prev_exten->next = peer->peer; 02818 peer->peer->next = exten->next; 02819 } else 02820 prev_exten->next = exten->next; 02821 } else { 02822 /* no previous extension, we are first 02823 * extension, so change con->root ... 02824 */ 02825 if (peer->peer) 02826 con->root = peer->peer; 02827 else 02828 con->root = exten->next; 02829 } 02830 } else { 02831 /* we are not first priority in extension */ 02832 previous_peer->peer = peer->peer; 02833 } 02834 02835 /* now, free whole priority extension */ 02836 if (peer->priority==PRIORITY_HINT) 02837 ast_remove_hint(peer); 02838 peer->datad(peer->data); 02839 free(peer); 02840 02841 ast_mutex_unlock(&con->lock); 02842 return 0; 02843 } else { 02844 /* this is not right extension, skip to next peer */ 02845 previous_peer = peer; 02846 peer = peer->peer; 02847 } 02848 } 02849 02850 ast_mutex_unlock(&con->lock); 02851 return -1; 02852 } 02853 } 02854 02855 prev_exten = exten; 02856 exten = exten->next; 02857 } 02858 02859 /* we can't find right extension */ 02860 ast_mutex_unlock(&con->lock); 02861 return -1; 02862 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
context | context from which to remove the pattern | |
ignorepat | the pattern to remove | |
registrar | the registrar of the ignore pattern This removes the given ignorepattern Returns 0 on success, -1 on failure |
Definition at line 4363 of file pbx.c.
References ast_context_remove_ignorepat2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by handle_context_remove_ignorepat().
04364 { 04365 struct ast_context *c; 04366 04367 if (ast_lock_contexts()) { 04368 errno = EBUSY; 04369 return -1; 04370 } 04371 04372 c = ast_walk_contexts(NULL); 04373 while (c) { 04374 if (!strcmp(ast_get_context_name(c), context)) { 04375 int ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04376 ast_unlock_contexts(); 04377 return ret; 04378 } 04379 c = ast_walk_contexts(c); 04380 } 04381 04382 ast_unlock_contexts(); 04383 errno = ENOENT; 04384 return -1; 04385 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4387 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().
04388 { 04389 struct ast_ignorepat *ip, *ipl = NULL; 04390 04391 if (ast_mutex_lock(&con->lock)) { 04392 errno = EBUSY; 04393 return -1; 04394 } 04395 04396 ip = con->ignorepats; 04397 while (ip) { 04398 if (!strcmp(ip->pattern, ignorepat) && 04399 (!registrar || (registrar == ip->registrar))) { 04400 if (ipl) { 04401 ipl->next = ip->next; 04402 free(ip); 04403 } else { 04404 con->ignorepats = ip->next; 04405 free(ip); 04406 } 04407 ast_mutex_unlock(&con->lock); 04408 return 0; 04409 } 04410 ipl = ip; ip = ip->next; 04411 } 04412 04413 ast_mutex_unlock(&con->lock); 04414 errno = EINVAL; 04415 return -1; 04416 }
int ast_context_remove_include | ( | const char * | context, | |
const char * | include, | |||
const char * | registrar | |||
) |
See add_include
Definition at line 2581 of file pbx.c.
References ast_context_remove_include2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by handle_context_dont_include().
02582 { 02583 struct ast_context *c; 02584 02585 if (ast_lock_contexts()) return -1; 02586 02587 /* walk contexts and search for the right one ...*/ 02588 c = ast_walk_contexts(NULL); 02589 while (c) { 02590 /* we found one ... */ 02591 if (!strcmp(ast_get_context_name(c), context)) { 02592 int ret; 02593 /* remove include from this context ... */ 02594 ret = ast_context_remove_include2(c, include, registrar); 02595 02596 ast_unlock_contexts(); 02597 02598 /* ... return results */ 02599 return ret; 02600 } 02601 c = ast_walk_contexts(c); 02602 } 02603 02604 /* we can't find the right one context */ 02605 ast_unlock_contexts(); 02606 return -1; 02607 }
int ast_context_remove_include2 | ( | struct ast_context * | con, | |
const char * | include, | |||
const char * | registrar | |||
) |
See add_include2
Definition at line 2617 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().
02618 { 02619 struct ast_include *i, *pi = NULL; 02620 02621 if (ast_mutex_lock(&con->lock)) return -1; 02622 02623 /* walk includes */ 02624 i = con->includes; 02625 while (i) { 02626 /* find our include */ 02627 if (!strcmp(i->name, include) && 02628 (!registrar || !strcmp(i->registrar, registrar))) { 02629 /* remove from list */ 02630 if (pi) 02631 pi->next = i->next; 02632 else 02633 con->includes = i->next; 02634 /* free include and return */ 02635 free(i); 02636 ast_mutex_unlock(&con->lock); 02637 return 0; 02638 } 02639 pi = i; 02640 i = i->next; 02641 } 02642 02643 /* we can't find the right include */ 02644 ast_mutex_unlock(&con->lock); 02645 return -1; 02646 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Definition at line 2653 of file pbx.c.
References ast_context_remove_switch2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
02654 { 02655 struct ast_context *c; 02656 02657 if (ast_lock_contexts()) return -1; 02658 02659 /* walk contexts and search for the right one ...*/ 02660 c = ast_walk_contexts(NULL); 02661 while (c) { 02662 /* we found one ... */ 02663 if (!strcmp(ast_get_context_name(c), context)) { 02664 int ret; 02665 /* remove switch from this context ... */ 02666 ret = ast_context_remove_switch2(c, sw, data, registrar); 02667 02668 ast_unlock_contexts(); 02669 02670 /* ... return results */ 02671 return ret; 02672 } 02673 c = ast_walk_contexts(c); 02674 } 02675 02676 /* we can't find the right one context */ 02677 ast_unlock_contexts(); 02678 return -1; 02679 }
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 2689 of file pbx.c.
References ast_context::alts, ast_mutex_lock(), ast_mutex_unlock(), ast_sw::data, free, ast_context::lock, ast_sw::name, ast_sw::next, and ast_sw::registrar.
Referenced by ast_context_remove_switch().
02690 { 02691 struct ast_sw *i, *pi = NULL; 02692 02693 if (ast_mutex_lock(&con->lock)) return -1; 02694 02695 /* walk switchs */ 02696 i = con->alts; 02697 while (i) { 02698 /* find our switch */ 02699 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02700 (!registrar || !strcmp(i->registrar, registrar))) { 02701 /* remove from list */ 02702 if (pi) 02703 pi->next = i->next; 02704 else 02705 con->alts = i->next; 02706 /* free switch and return */ 02707 free(i); 02708 ast_mutex_unlock(&con->lock); 02709 return 0; 02710 } 02711 pi = i; 02712 i = i->next; 02713 } 02714 02715 /* we can't find the right switch */ 02716 ast_mutex_unlock(&con->lock); 02717 return -1; 02718 }
int ast_context_verify_includes | ( | struct ast_context * | con | ) |
con | context in which to verify the includes Returns 0 if no problems found, -1 if there were any missing context |
Definition at line 6435 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().
06436 { 06437 struct ast_include *inc; 06438 int res = 0; 06439 06440 for (inc = ast_walk_context_includes(con, NULL); inc; inc = ast_walk_context_includes(con, inc)) 06441 if (!ast_context_find(inc->rname)) { 06442 res = -1; 06443 ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n", 06444 ast_get_context_name(con), inc->rname); 06445 } 06446 return res; 06447 }
struct ast_custom_function* ast_custom_function_find | ( | char * | name | ) |
Definition at line 1267 of file pbx.c.
References acf_root, ast_log(), ast_mutex_lock(), LOG_ERROR, ast_custom_function::name, and ast_custom_function::next.
Referenced by ast_custom_function_register(), ast_func_read(), ast_func_write(), and handle_show_function().
01268 { 01269 struct ast_custom_function *acfptr; 01270 01271 /* try to lock functions list ... */ 01272 if (ast_mutex_lock(&acflock)) { 01273 ast_log(LOG_ERROR, "Unable to lock function list\n"); 01274 return NULL; 01275 } 01276 01277 for (acfptr = acf_root; acfptr; acfptr = acfptr->next) { 01278 if (!strcmp(name, acfptr->name)) { 01279 break; 01280 } 01281 } 01282 01283 ast_mutex_unlock(&acflock); 01284 01285 return acfptr; 01286 }
int ast_custom_function_register | ( | struct ast_custom_function * | acf | ) |
Definition at line 1323 of file pbx.c.
References acf_root, ast_custom_function_find(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), LOG_ERROR, ast_custom_function::name, ast_custom_function::next, option_verbose, and VERBOSE_PREFIX_2.
Referenced by load_module().
01324 { 01325 if (!acf) 01326 return -1; 01327 01328 /* try to lock functions list ... */ 01329 if (ast_mutex_lock(&acflock)) { 01330 ast_log(LOG_ERROR, "Unable to lock function list. Failed registering function %s\n", acf->name); 01331 return -1; 01332 } 01333 01334 if (ast_custom_function_find(acf->name)) { 01335 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01336 ast_mutex_unlock(&acflock); 01337 return -1; 01338 } 01339 01340 acf->next = acf_root; 01341 acf_root = acf; 01342 01343 ast_mutex_unlock(&acflock); 01344 01345 if (option_verbose > 1) 01346 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01347 01348 return 0; 01349 }
int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Definition at line 1288 of file pbx.c.
References acf_root, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), LOG_ERROR, ast_custom_function::name, ast_custom_function::next, option_verbose, and VERBOSE_PREFIX_2.
Referenced by unload_module().
01289 { 01290 struct ast_custom_function *acfptr, *lastacf = NULL; 01291 int res = -1; 01292 01293 if (!acf) 01294 return -1; 01295 01296 /* try to lock functions list ... */ 01297 if (ast_mutex_lock(&acflock)) { 01298 ast_log(LOG_ERROR, "Unable to lock function list\n"); 01299 return -1; 01300 } 01301 01302 for (acfptr = acf_root; acfptr; acfptr = acfptr->next) { 01303 if (acfptr == acf) { 01304 if (lastacf) { 01305 lastacf->next = acf->next; 01306 } else { 01307 acf_root = acf->next; 01308 } 01309 res = 0; 01310 break; 01311 } 01312 lastacf = acfptr; 01313 } 01314 01315 ast_mutex_unlock(&acflock); 01316 01317 if (!res && (option_verbose > 1)) 01318 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01319 01320 return res; 01321 }
int ast_exec_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) |
c | channel to execute upon | |
context | which context extension is in | |
exten | extension to execute | |
priority | priority to execute within the given extension | |
callerid | Caller-ID If it's not available, do whatever you should do for default extensions and halt the thread if necessary. This function does not return, except on error. |
Definition at line 2233 of file pbx.c.
References HELPER_EXEC, and pbx_extension_helper().
Referenced by loopback_exec().
02234 { 02235 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_EXEC); 02236 }
int ast_exists_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) |
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 If an extension within the given context(or callerid) with the given priority is found a non zero value will be returned. Otherwise, 0 is returned. |
Definition at line 2203 of file pbx.c.
References HELPER_EXISTS, and pbx_extension_helper().
Referenced by __ast_goto_if_exists(), __ast_pbx_run(), __login_exec(), agentmonitoroutgoing_exec(), ast_app_dtget(), ast_pbx_outgoing_exten(), ast_waitstream_exten(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), console_dial(), console_transfer(), disa_exec(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), leave_voicemail(), local_alloc(), local_devicestate(), loopback_exists(), macro_exec(), mgcp_ss(), monitor_handle_notowned(), monitor_handle_owned(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), process_ast_dsp(), register_peer_exten(), rpt(), rpt_exec(), skinny_ss(), socket_read(), ss_thread(), and zt_read().
02204 { 02205 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_EXISTS); 02206 }
int ast_explicit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4531 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().
04532 { 04533 if (!chan) 04534 return -1; 04535 04536 if (!ast_strlen_zero(context)) 04537 ast_copy_string(chan->context, context, sizeof(chan->context)); 04538 if (!ast_strlen_zero(exten)) 04539 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04540 if (priority > -1) { 04541 chan->priority = priority; 04542 /* see flag description in channel.h for explanation */ 04543 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04544 chan->priority--; 04545 } 04546 04547 return 0; 04548 }
int ast_extension_close | ( | const char * | pattern, | |
const char * | data, | |||
int | needmore | |||
) |
Definition at line 715 of file pbx.c.
References ast_strlen_zero(), EXTENSION_MATCH_CORE, and match().
Referenced by pbx_find_extension(), and realtime_switch_common().
00716 { 00717 int match; 00718 /* If "data" is longer, it can'be a subset of pattern unless 00719 pattern is a pattern match */ 00720 if ((strlen(pattern) < strlen(data)) && (pattern[0] != '_')) 00721 return 0; 00722 00723 if ((ast_strlen_zero((char *)data) || !strncasecmp(pattern, data, strlen(data))) && 00724 (!needmore || (strlen(pattern) > strlen(data)))) { 00725 return 1; 00726 } 00727 EXTENSION_MATCH_CORE(data,pattern,match); 00728 /* If there's more or we don't care about more, or if it's a possible early match, 00729 return non-zero; otherwise it's a miss */ 00730 if (!needmore || *pattern || match == 2) { 00731 return match; 00732 } else 00733 return 0; 00734 }
int ast_extension_match | ( | const char * | pattern, | |
const char * | extension | |||
) |
pattern | pattern to match | |
extension | extension to check against the pattern. Checks whether or not the given extension matches the given pattern. Returns 1 on match, 0 on failure |
Definition at line 702 of file pbx.c.
References EXTENSION_MATCH_CORE, and match().
Referenced by ast_ignore_pattern(), find_matching_priority(), loopback_canmatch(), loopback_exec(), loopback_exists(), loopback_matchmore(), matchcid(), misdn_cfg_is_msn_valid(), pbx_find_extension(), realtime_switch_common(), and show_dialplan_helper().
00703 { 00704 int match; 00705 /* If they're the same return */ 00706 if (!strcmp(pattern, data)) 00707 return 1; 00708 EXTENSION_MATCH_CORE(data,pattern,match); 00709 /* Must be at the end of both */ 00710 if (*data || (*pattern && (*pattern != '/'))) 00711 match = 0; 00712 return match; 00713 }
int ast_extension_patmatch | ( | const char * | pattern, | |
const char * | data | |||
) |
int ast_extension_state | ( | struct ast_channel * | c, | |
char * | context, | |||
char * | exten | |||
) |
ast_extension_state: Check extension state for an extension by using hint
c | this is not important | |
context | which context to look in | |
exten | which extension to get state Returns extension state !! = AST_EXTENSION_??? |
Definition at line 1875 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), and handle_request_subscribe().
01876 { 01877 struct ast_exten *e; 01878 01879 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 01880 if (!e) 01881 return -1; /* No hint, return -1 */ 01882 01883 return ast_extension_state2(e); /* Check all devices in the hint */ 01884 }
const char* ast_extension_state2str | ( | int | extension_state | ) |
ast_extension_state2str: Return extension_state as string
extension_state | is the numerical state delivered by ast_extension_state Returns the state of an extension as string |
Definition at line 1862 of file pbx.c.
References extension_states.
Referenced by __sip_show_channels(), cb_extensionstate(), handle_request_subscribe(), and handle_show_hints().
01863 { 01864 int i; 01865 01866 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 01867 if (extension_states[i].extension_state == extension_state) { 01868 return extension_states[i].text; 01869 } 01870 } 01871 return "Unknown"; 01872 }
int ast_extension_state_add | ( | const char * | context, | |
const char * | exten, | |||
ast_state_cb_type | callback, | |||
void * | data | |||
) |
ast_extension_state_add: Add watcher for extension states
context | which context to look in | |
exten | which extension to get state | |
callback | callback to call if state changed | |
data | to pass to callback The callback is called if the state for extension is changed Return -1 on failure, ID on success |
Definition at line 1929 of file pbx.c.
References ast_hint_extension(), ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_state_cb::data, hints, ast_state_cb::id, list, malloc, ast_imager::next, ast_state_cb::next, statecbs, and stateid.
Referenced by handle_request_subscribe(), and init_manager().
01931 { 01932 struct ast_hint *list; 01933 struct ast_state_cb *cblist; 01934 struct ast_exten *e; 01935 01936 /* If there's no context and extension: add callback to statecbs list */ 01937 if (!context && !exten) { 01938 ast_mutex_lock(&hintlock); 01939 01940 cblist = statecbs; 01941 while (cblist) { 01942 if (cblist->callback == callback) { 01943 cblist->data = data; 01944 ast_mutex_unlock(&hintlock); 01945 return 0; 01946 } 01947 cblist = cblist->next; 01948 } 01949 01950 /* Now insert the callback */ 01951 cblist = malloc(sizeof(struct ast_state_cb)); 01952 if (!cblist) { 01953 ast_mutex_unlock(&hintlock); 01954 return -1; 01955 } 01956 memset(cblist, 0, sizeof(struct ast_state_cb)); 01957 cblist->id = 0; 01958 cblist->callback = callback; 01959 cblist->data = data; 01960 01961 cblist->next = statecbs; 01962 statecbs = cblist; 01963 01964 ast_mutex_unlock(&hintlock); 01965 return 0; 01966 } 01967 01968 if (!context || !exten) 01969 return -1; 01970 01971 /* This callback type is for only one hint, so get the hint */ 01972 e = ast_hint_extension(NULL, context, exten); 01973 if (!e) { 01974 return -1; 01975 } 01976 01977 /* Find the hint in the list of hints */ 01978 ast_mutex_lock(&hintlock); 01979 list = hints; 01980 01981 while (list) { 01982 if (list->exten == e) 01983 break; 01984 list = list->next; 01985 } 01986 01987 if (!list) { 01988 /* We have no hint, sorry */ 01989 ast_mutex_unlock(&hintlock); 01990 return -1; 01991 } 01992 01993 /* Now insert the callback in the callback list */ 01994 cblist = malloc(sizeof(struct ast_state_cb)); 01995 if (!cblist) { 01996 ast_mutex_unlock(&hintlock); 01997 return -1; 01998 } 01999 memset(cblist, 0, sizeof(struct ast_state_cb)); 02000 cblist->id = stateid++; /* Unique ID for this callback */ 02001 cblist->callback = callback; /* Pointer to callback routine */ 02002 cblist->data = data; /* Data for the callback */ 02003 02004 cblist->next = list->callbacks; 02005 list->callbacks = cblist; 02006 02007 ast_mutex_unlock(&hintlock); 02008 return cblist->id; 02009 }
int ast_extension_state_del | ( | int | id, | |
ast_state_cb_type | callback | |||
) |
ast_extension_state_del: Remove a watcher from the callback list
id | of the callback to delete | |
callback | callback Removes the callback from list of callbacks Return 0 on success, -1 on failure |
Definition at line 2012 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, free, hints, ast_state_cb::id, list, ast_imager::next, ast_state_cb::next, and statecbs.
Referenced by __sip_destroy().
02013 { 02014 struct ast_hint *list; 02015 struct ast_state_cb *cblist, *cbprev; 02016 02017 if (!id && !callback) 02018 return -1; 02019 02020 ast_mutex_lock(&hintlock); 02021 02022 /* id is zero is a callback without extension */ 02023 if (!id) { 02024 cbprev = NULL; 02025 cblist = statecbs; 02026 while (cblist) { 02027 if (cblist->callback == callback) { 02028 if (!cbprev) 02029 statecbs = cblist->next; 02030 else 02031 cbprev->next = cblist->next; 02032 02033 free(cblist); 02034 02035 ast_mutex_unlock(&hintlock); 02036 return 0; 02037 } 02038 cbprev = cblist; 02039 cblist = cblist->next; 02040 } 02041 02042 ast_mutex_unlock(&hintlock); 02043 return -1; 02044 } 02045 02046 /* id greater than zero is a callback with extension */ 02047 /* Find the callback based on ID */ 02048 list = hints; 02049 while (list) { 02050 cblist = list->callbacks; 02051 cbprev = NULL; 02052 while (cblist) { 02053 if (cblist->id==id) { 02054 if (!cbprev) 02055 list->callbacks = cblist->next; 02056 else 02057 cbprev->next = cblist->next; 02058 02059 free(cblist); 02060 02061 ast_mutex_unlock(&hintlock); 02062 return 0; 02063 } 02064 cbprev = cblist; 02065 cblist = cblist->next; 02066 } 02067 list = list->next; 02068 } 02069 02070 ast_mutex_unlock(&hintlock); 02071 return -1; 02072 }
int ast_findlabel_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
const char * | label, | |||
const char * | callerid | |||
) |
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 If an priority which matches given label in extension or -1 if not found. \ |
Definition at line 2208 of file pbx.c.
References HELPER_FINDLABEL, and pbx_extension_helper().
Referenced by ast_parseable_goto(), and handle_setpriority().
02209 { 02210 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, HELPER_FINDLABEL); 02211 }
int ast_findlabel_extension2 | ( | struct ast_channel * | c, | |
struct ast_context * | con, | |||
const char * | exten, | |||
const char * | label, | |||
const char * | callerid | |||
) |
Definition at line 2213 of file pbx.c.
References HELPER_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_module().
02214 { 02215 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, HELPER_FINDLABEL); 02216 }
char* ast_func_read | ( | struct ast_channel * | chan, | |
const char * | in, | |||
char * | workspace, | |||
size_t | len | |||
) |
chan | Channel to execute on | |
in | Data containing the function call string | |
workspace | A pointer to safe memory to use for a return value | |
len | the number of bytes in workspace This application executes an function in read mode on a given channel. It returns a pointer to workspace if the buffer contains any new data or NULL if there was a problem. |
Definition at line 1351 of file pbx.c.
References ast_custom_function_find(), ast_log(), ast_strdupa, LOG_ERROR, LOG_WARNING, and ast_custom_function::read.
Referenced by handle_getvariable(), and pbx_substitute_variables_helper_full().
01352 { 01353 char *args = NULL, *function, *p; 01354 char *ret = "0"; 01355 struct ast_custom_function *acfptr; 01356 01357 function = ast_strdupa(in); 01358 if (!function) { 01359 ast_log(LOG_ERROR, "Out of memory\n"); 01360 return ret; 01361 } 01362 if ((args = strchr(function, '('))) { 01363 *args = '\0'; 01364 args++; 01365 if ((p = strrchr(args, ')'))) { 01366 *p = '\0'; 01367 } else { 01368 ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n"); 01369 } 01370 } else { 01371 ast_log(LOG_WARNING, "Function doesn't contain parentheses. Assuming null argument.\n"); 01372 } 01373 01374 if ((acfptr = ast_custom_function_find(function))) { 01375 /* run the custom function */ 01376 if (acfptr->read) { 01377 return acfptr->read(chan, function, args, workspace, len); 01378 } else { 01379 ast_log(LOG_ERROR, "Function %s cannot be read\n", function); 01380 } 01381 } else { 01382 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01383 } 01384 return ret; 01385 }
void ast_func_write | ( | struct ast_channel * | chan, | |
const char * | in, | |||
const char * | value | |||
) |
chan | Channel to execute on | |
in | Data containing the function call string | |
value | A value parameter to pass for writing This application executes an function in write mode on a given channel. It has no return value. |
Definition at line 1387 of file pbx.c.
References ast_custom_function_find(), ast_log(), ast_strdupa, LOG_ERROR, LOG_WARNING, and ast_custom_function::write.
Referenced by pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().
01388 { 01389 char *args = NULL, *function, *p; 01390 struct ast_custom_function *acfptr; 01391 01392 function = ast_strdupa(in); 01393 if (!function) { 01394 ast_log(LOG_ERROR, "Out of memory\n"); 01395 return; 01396 } 01397 if ((args = strchr(function, '('))) { 01398 *args = '\0'; 01399 args++; 01400 if ((p = strrchr(args, ')'))) { 01401 *p = '\0'; 01402 } else { 01403 ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n"); 01404 } 01405 } else { 01406 ast_log(LOG_WARNING, "Function doesn't contain parentheses. Assuming null argument.\n"); 01407 } 01408 01409 if ((acfptr = ast_custom_function_find(function))) { 01410 /* run the custom function */ 01411 if (acfptr->write) { 01412 acfptr->write(chan, function, args, value); 01413 } else { 01414 ast_log(LOG_ERROR, "Function %s is read-only, it cannot be written to\n", function); 01415 } 01416 } else { 01417 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01418 } 01419 }
const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 6291 of file pbx.c.
References ast_context::name.
Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_include2(), ast_context_add_switch(), ast_context_add_switch2(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_verify_includes(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_show_dialplan_context(), dundi_precache_full(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper().
06292 { 06293 return con ? con->name : NULL; 06294 }
const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 6324 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06325 { 06326 return c ? c->registrar : NULL; 06327 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6354 of file pbx.c.
References ast_exten::app.
Referenced by ast_add_hint(), ast_extension_state2(), ast_get_hint(), ast_hint_state_changed(), find_matching_endwhile(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper().
06355 { 06356 return e ? e->app : NULL; 06357 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6359 of file pbx.c.
References ast_exten::data.
Referenced by ast_get_hint(), handle_save_dialplan(), and show_dialplan_helper().
06360 { 06361 return e ? e->data : NULL; 06362 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6349 of file pbx.c.
References ast_exten::cidmatch.
Referenced by find_matching_priority(), and handle_save_dialplan().
06350 { 06351 return e ? e->cidmatch : NULL; 06352 }
const char* ast_get_extension_label | ( | struct ast_exten * | e | ) |
Definition at line 6301 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 6344 of file pbx.c.
References ast_exten::matchcid.
Referenced by find_matching_priority(), and handle_save_dialplan().
06345 { 06346 return e ? e->matchcid : 0; 06347 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6296 of file pbx.c.
References exten.
Referenced by ast_add_hint(), complete_context_remove_extension(), 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 6316 of file pbx.c.
References exten.
Referenced by complete_context_remove_extension(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper().
const char* ast_get_extension_registrar | ( | struct ast_exten * | e | ) |
Definition at line 6329 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06330 { 06331 return e ? e->registrar : NULL; 06332 }
int ast_get_hint | ( | char * | hint, | |
int | maxlen, | |||
char * | name, | |||
int | maxnamelen, | |||
struct ast_channel * | c, | |||
const char * | context, | |||
const char * | exten | |||
) |
ast_get_hint: Get hint for channel
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 If an extension within the given context with the priority PRIORITY_HINT is found a non zero value will be returned. Otherwise, 0 is returned. |
Definition at line 2184 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().
02185 { 02186 struct ast_exten *e; 02187 void *tmp; 02188 02189 e = ast_hint_extension(c, context, exten); 02190 if (e) { 02191 if (hint) 02192 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02193 if (name) { 02194 tmp = ast_get_extension_app_data(e); 02195 if (tmp) 02196 ast_copy_string(name, (char *) tmp, namesize); 02197 } 02198 return -1; 02199 } 02200 return 0; 02201 }
const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6311 of file pbx.c.
References ast_ignorepat::pattern.
Referenced by complete_context_add_ignorepat(), complete_context_remove_ignorepat(), handle_save_dialplan(), and show_dialplan_helper().
06312 { 06313 return ip ? ip->pattern : NULL; 06314 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6339 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06340 { 06341 return ip ? ip->registrar : NULL; 06342 }
const char* ast_get_include_name | ( | struct ast_include * | include | ) |
Definition at line 6306 of file pbx.c.
References ast_include::name.
Referenced by complete_context_add_include(), complete_context_dont_include(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper().
const char* ast_get_include_registrar | ( | struct ast_include * | i | ) |
Definition at line 6334 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06335 { 06336 return i ? i->registrar : NULL; 06337 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6369 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06370 { 06371 return sw ? sw->data : NULL; 06372 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6364 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06365 { 06366 return sw ? sw->name : NULL; 06367 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6374 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06375 { 06376 return sw ? sw->registrar : NULL; 06377 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
char * | context, | |||
char * | exten, | |||
int | priority | |||
) |
Definition at line 6467 of file pbx.c.
References __ast_goto_if_exists().
Referenced by aqm_exec(), auth_exec(), background_detect_exec(), chanavail_exec(), conf_run(), controlplayback_exec(), dial_exec_full(), do_directory(), dundi_lookup_exec(), enumlookup_exec(), get_exec(), group_check_exec(), hasvoicemail_exec(), leave_voicemail(), lookupblacklist_exec(), md5check_exec(), onedigit_goto(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), play_mailbox_owner(), playback_exec(), pqm_exec(), privacy_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), sip_getheader(), system_exec_helper(), transfer_exec(), txtcidname_exec(), upqm_exec(), valid_exit(), vm_box_exists(), vm_exec(), and wait_for_answer().
06467 { 06468 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06469 }
void ast_hint_state_changed | ( | const char * | device | ) |
Definition at line 1886 of file pbx.c.
References ast_extension_state2(), ast_get_extension_app(), AST_MAX_EXTENSION, ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_exten::exten, ast_hint::exten, hints, ast_hint::laststate, ast_context::name, ast_state_cb::next, ast_hint::next, ast_exten::parent, parse(), statecbs, and strsep().
Referenced by do_state_change().
01887 { 01888 struct ast_hint *hint; 01889 struct ast_state_cb *cblist; 01890 char buf[AST_MAX_EXTENSION]; 01891 char *parse; 01892 char *cur; 01893 int state; 01894 01895 ast_mutex_lock(&hintlock); 01896 01897 for (hint = hints; hint; hint = hint->next) { 01898 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 01899 parse = buf; 01900 for (cur = strsep(&parse, "&"); cur; cur = strsep(&parse, "&")) { 01901 if (strcasecmp(cur, device)) 01902 continue; 01903 01904 /* Get device state for this hint */ 01905 state = ast_extension_state2(hint->exten); 01906 01907 if ((state == -1) || (state == hint->laststate)) 01908 continue; 01909 01910 /* Device state changed since last check - notify the watchers */ 01911 01912 /* For general callbacks */ 01913 for (cblist = statecbs; cblist; cblist = cblist->next) 01914 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 01915 01916 /* For extension callbacks */ 01917 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 01918 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 01919 01920 hint->laststate = state; 01921 break; 01922 } 01923 } 01924 01925 ast_mutex_unlock(&hintlock); 01926 }
int ast_ignore_pattern | ( | const char * | context, | |
const char * | pattern | |||
) |
context | context to search within | |
pattern | to check whether it should be ignored or not Check if a number should be ignored with respect to dialtone cancellation. Returns 0 if the pattern should not be ignored, or non-zero if the pattern should be ignored |
Definition at line 4483 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(), mgcp_ss(), skinny_ss(), and ss_thread().
04484 { 04485 struct ast_context *con; 04486 struct ast_ignorepat *pat; 04487 04488 con = ast_context_find(context); 04489 if (con) { 04490 pat = con->ignorepats; 04491 while (pat) { 04492 if (ast_extension_match(pat->pattern, pattern)) 04493 return 1; 04494 pat = pat->next; 04495 } 04496 } 04497 return 0; 04498 }
int ast_lock_context | ( | struct ast_context * | con | ) |
con | context to lock Locks the context. Returns 0 on success, -1 on failure |
Definition at line 6278 of file pbx.c.
References ast_mutex_lock(), and ast_context::lock.
Referenced by complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_ignorepat(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), and show_dialplan_helper().
06279 { 06280 return ast_mutex_lock(&con->lock); 06281 }
int ast_lock_contexts | ( | void | ) |
Locks the context list Returns 0 on success, -1 on error
Definition at line 6265 of file pbx.c.
References ast_mutex_lock().
Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_show_dialplan_context(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), and show_dialplan_helper().
06266 { 06267 return ast_mutex_lock(&conlock); 06268 }
int ast_matchmore_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) |
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 If "exten" *could match* a valid extension in this context with some more digits, return non-zero. Does NOT return non-zero if this is an exact-match only. Basically, when this returns 0, no matter what you add to exten, it's not going to be a valid extension anymore |
Definition at line 2223 of file pbx.c.
References HELPER_MATCHMORE, and pbx_extension_helper().
Referenced by ast_app_dtget(), disa_exec(), dp_lookup(), dundi_lookup_local(), loopback_matchmore(), mgcp_ss(), skinny_ss(), and ss_thread().
02224 { 02225 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_MATCHMORE); 02226 }
void ast_merge_contexts_and_delete | ( | struct ast_context ** | extcontexts, | |
const char * | registrar | |||
) |
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 3698 of file pbx.c.
References AST_LIST_HEAD_INIT, AST_LIST_INSERT_HEAD, ast_log(), ast_mutex_lock(), store_hint::callbacks, ast_hint::callbacks, calloc, store_hint::context, ast_exten::exten, ast_hint::exten, store_hint::exten, hints, ast_hint::laststate, store_hint::laststate, list, LOG_WARNING, ast_context::name, ast_hint::next, ast_exten::parent, and ast_context::registrar.
Referenced by pbx_load_module().
03699 { 03700 struct ast_context *tmp, *lasttmp = NULL; 03701 struct store_hints store; 03702 struct store_hint *this; 03703 struct ast_hint *hint; 03704 struct ast_exten *exten; 03705 int length; 03706 struct ast_state_cb *thiscb, *prevcb; 03707 03708 memset(&store, 0, sizeof(store)); 03709 AST_LIST_HEAD_INIT(&store); 03710 03711 /* it is very important that this function hold the hintlock _and_ the conlock 03712 during its operation; not only do we need to ensure that the list of contexts 03713 and extensions does not change, but also that no hint callbacks (watchers) are 03714 added or removed during the merge/delete process 03715 03716 in addition, the locks _must_ be taken in this order, because there are already 03717 other code paths that use this order 03718 */ 03719 ast_mutex_lock(&conlock); 03720 ast_mutex_lock(&hintlock); 03721 03722 /* preserve all watchers for hints associated with this registrar */ 03723 for (hint = hints; hint; hint = hint->next) { 03724 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03725 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03726 this = calloc(1, length); 03727 if (!this) { 03728 ast_log(LOG_WARNING, "Could not allocate memory to preserve hint\n"); 03729 continue; 03730 } 03731 this->callbacks = hint->callbacks; 03732 hint->callbacks = NULL; 03733 this->laststate = hint->laststate; 03734 this->context = this->data; 03735 strcpy(this->data, hint->exten->parent->name); 03736 this->exten = this->data + strlen(this->context) + 1; 03737 strcpy(this->exten, hint->exten->exten); 03738 AST_LIST_INSERT_HEAD(&store, this, list); 03739 } 03740 } 03741 03742 tmp = *extcontexts; 03743 if (registrar) { 03744 __ast_context_destroy(NULL,registrar); 03745 while (tmp) { 03746 lasttmp = tmp; 03747 tmp = tmp->next; 03748 } 03749 } else { 03750 while (tmp) { 03751 __ast_context_destroy(tmp,tmp->registrar); 03752 lasttmp = tmp; 03753 tmp = tmp->next; 03754 } 03755 } 03756 if (lasttmp) { 03757 lasttmp->next = contexts; 03758 contexts = *extcontexts; 03759 *extcontexts = NULL; 03760 } else 03761 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 03762 03763 /* restore the watchers for hints that can be found; notify those that 03764 cannot be restored 03765 */ 03766 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 03767 exten = ast_hint_extension(NULL, this->context, this->exten); 03768 /* Find the hint in the list of hints */ 03769 for (hint = hints; hint; hint = hint->next) { 03770 if (hint->exten == exten) 03771 break; 03772 } 03773 if (!exten || !hint) { 03774 /* this hint has been removed, notify the watchers */ 03775 prevcb = NULL; 03776 thiscb = this->callbacks; 03777 while (thiscb) { 03778 prevcb = thiscb; 03779 thiscb = thiscb->next; 03780 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 03781 free(prevcb); 03782 } 03783 } else { 03784 thiscb = this->callbacks; 03785 while (thiscb->next) 03786 thiscb = thiscb->next; 03787 thiscb->next = hint->callbacks; 03788 hint->callbacks = this->callbacks; 03789 hint->laststate = this->laststate; 03790 } 03791 free(this); 03792 } 03793 03794 ast_mutex_unlock(&hintlock); 03795 ast_mutex_unlock(&conlock); 03796 03797 return; 03798 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
Definition at line 6475 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, s, and strsep().
Referenced by _while_exec(), check_goto_on_transfer(), dial_exec_full(), gosub_exec(), ivr_dispatch(), pbx_builtin_goto(), random_exec(), and return_exec().
06476 { 06477 char *s; 06478 char *exten, *pri, *context; 06479 char *stringp=NULL; 06480 int ipri; 06481 int mode = 0; 06482 06483 if (ast_strlen_zero(goto_string)) { 06484 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06485 return -1; 06486 } 06487 s = ast_strdupa(goto_string); 06488 stringp=s; 06489 context = strsep(&stringp, "|"); 06490 exten = strsep(&stringp, "|"); 06491 if (!exten) { 06492 /* Only a priority in this one */ 06493 pri = context; 06494 exten = NULL; 06495 context = NULL; 06496 } else { 06497 pri = strsep(&stringp, "|"); 06498 if (!pri) { 06499 /* Only an extension and priority in this one */ 06500 pri = exten; 06501 exten = context; 06502 context = NULL; 06503 } 06504 } 06505 if (*pri == '+') { 06506 mode = 1; 06507 pri++; 06508 } else if (*pri == '-') { 06509 mode = -1; 06510 pri++; 06511 } 06512 if (sscanf(pri, "%d", &ipri) != 1) { 06513 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, (exten && strcasecmp(exten, "BYEXTENSION")) ? exten : chan->exten, 06514 pri, chan->cid.cid_num)) < 1) { 06515 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06516 return -1; 06517 } else 06518 mode = 0; 06519 } 06520 /* At this point we have a priority and maybe an extension and a context */ 06521 06522 if (exten && !strcasecmp(exten, "BYEXTENSION")) 06523 exten = NULL; 06524 06525 if (mode) 06526 ipri = chan->priority + (ipri * mode); 06527 06528 ast_explicit_goto(chan, context, exten, ipri); 06529 ast_cdr_update(chan); 06530 return 0; 06531 06532 }
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 | |||
) |
Definition at line 5158 of file pbx.c.
References __ast_request_and_dial(), async_stat::app, async_stat::appdata, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), 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_ERROR, LOG_WARNING, malloc, ast_channel::name, option_verbose, async_stat::p, ast_channel::pbx, async_stat::timeout, outgoing_helper::vars, and VERBOSE_PREFIX_4.
Referenced by action_originate(), attempt_thread(), fast_originate(), and page_thread().
05159 { 05160 struct ast_channel *chan; 05161 struct async_stat *as; 05162 struct app_tmp *tmp; 05163 int res = -1, cdr_res = -1; 05164 struct outgoing_helper oh; 05165 pthread_attr_t attr; 05166 05167 memset(&oh, 0, sizeof(oh)); 05168 oh.vars = vars; 05169 oh.account = account; 05170 05171 if (locked_channel) 05172 *locked_channel = NULL; 05173 if (ast_strlen_zero(app)) { 05174 res = -1; 05175 goto outgoing_app_cleanup; 05176 } 05177 if (sync) { 05178 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05179 if (chan) { 05180 if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 05181 ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name); 05182 } else { 05183 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 05184 if(!chan->cdr) { 05185 /* allocation of the cdr failed */ 05186 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 05187 free(chan->pbx); 05188 res = -1; 05189 goto outgoing_app_cleanup; 05190 } 05191 /* allocation of the cdr was successful */ 05192 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05193 ast_cdr_start(chan->cdr); 05194 } 05195 ast_set_variables(chan, vars); 05196 if (account) 05197 ast_cdr_setaccount(chan, account); 05198 if (chan->_state == AST_STATE_UP) { 05199 res = 0; 05200 if (option_verbose > 3) 05201 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05202 tmp = malloc(sizeof(struct app_tmp)); 05203 if (tmp) { 05204 memset(tmp, 0, sizeof(struct app_tmp)); 05205 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05206 if (appdata) 05207 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05208 tmp->chan = chan; 05209 if (sync > 1) { 05210 if (locked_channel) 05211 ast_mutex_unlock(&chan->lock); 05212 ast_pbx_run_app(tmp); 05213 } else { 05214 pthread_attr_init(&attr); 05215 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05216 if (locked_channel) 05217 ast_mutex_lock(&chan->lock); 05218 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05219 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05220 free(tmp); 05221 if (locked_channel) 05222 ast_mutex_unlock(&chan->lock); 05223 ast_hangup(chan); 05224 res = -1; 05225 } else { 05226 if (locked_channel) 05227 *locked_channel = chan; 05228 } 05229 } 05230 } else { 05231 ast_log(LOG_ERROR, "Out of memory :(\n"); 05232 res = -1; 05233 } 05234 } else { 05235 if (option_verbose > 3) 05236 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05237 if (chan->cdr) { /* update the cdr */ 05238 /* here we update the status of the call, which sould be busy. 05239 * if that fails then we set the status to failed */ 05240 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05241 ast_cdr_failed(chan->cdr); 05242 } 05243 ast_hangup(chan); 05244 } 05245 } 05246 05247 if (res < 0) { /* the call failed for some reason */ 05248 if (*reason == 0) { /* if the call failed (not busy or no answer) 05249 * update the cdr with the failed message */ 05250 cdr_res = ast_pbx_outgoing_cdr_failed(); 05251 if (cdr_res != 0) { 05252 res = cdr_res; 05253 goto outgoing_app_cleanup; 05254 } 05255 } 05256 } 05257 05258 } else { 05259 as = malloc(sizeof(struct async_stat)); 05260 if (!as) { 05261 res = -1; 05262 goto outgoing_app_cleanup; 05263 } 05264 memset(as, 0, sizeof(struct async_stat)); 05265 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05266 if (!chan) { 05267 free(as); 05268 res = -1; 05269 goto outgoing_app_cleanup; 05270 } 05271 as->chan = chan; 05272 ast_copy_string(as->app, app, sizeof(as->app)); 05273 if (appdata) 05274 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05275 as->timeout = timeout; 05276 ast_set_variables(chan, vars); 05277 if (account) 05278 ast_cdr_setaccount(chan, account); 05279 /* Start a new thread, and get something handling this channel. */ 05280 pthread_attr_init(&attr); 05281 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05282 if (locked_channel) 05283 ast_mutex_lock(&chan->lock); 05284 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05285 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05286 free(as); 05287 if (locked_channel) 05288 ast_mutex_unlock(&chan->lock); 05289 ast_hangup(chan); 05290 res = -1; 05291 goto outgoing_app_cleanup; 05292 } else { 05293 if (locked_channel) 05294 *locked_channel = chan; 05295 } 05296 res = 0; 05297 } 05298 outgoing_app_cleanup: 05299 ast_variables_destroy(vars); 05300 return res; 05301 }
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 | |||
) |
Definition at line 4984 of file pbx.c.
References __ast_request_and_dial(), ast_channel::_state, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), ast_channel_alloc(), ast_exists_extension(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create, ast_request_and_dial(), ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, async_stat::chan, async_stat::context, ast_channel::context, async_stat::exten, ast_channel::exten, free, ast_channel::hangupcause, LOAD_OH, ast_channel::lock, LOG_ERROR, LOG_WARNING, malloc, ast_channel::name, option_verbose, async_stat::p, ast_channel::pbx, async_stat::priority, ast_channel::priority, async_stat::timeout, outgoing_helper::vars, and VERBOSE_PREFIX_4.
Referenced by action_originate(), attempt_thread(), and fast_originate().
04985 { 04986 struct ast_channel *chan; 04987 struct async_stat *as; 04988 int res = -1, cdr_res = -1; 04989 struct outgoing_helper oh; 04990 pthread_attr_t attr; 04991 04992 if (sync) { 04993 LOAD_OH(oh); 04994 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 04995 if (channel) { 04996 *channel = chan; 04997 if (chan) 04998 ast_mutex_lock(&chan->lock); 04999 } 05000 if (chan) { 05001 if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 05002 ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name); 05003 } else { 05004 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 05005 if (!chan->cdr) { 05006 /* allocation of the cdr failed */ 05007 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 05008 free(chan->pbx); 05009 res = -1; 05010 goto outgoing_exten_cleanup; 05011 } 05012 /* allocation of the cdr was successful */ 05013 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05014 ast_cdr_start(chan->cdr); 05015 } 05016 if (chan->_state == AST_STATE_UP) { 05017 res = 0; 05018 if (option_verbose > 3) 05019 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05020 05021 if (sync > 1) { 05022 if (channel) 05023 ast_mutex_unlock(&chan->lock); 05024 if (ast_pbx_run(chan)) { 05025 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05026 if (channel) 05027 *channel = NULL; 05028 ast_hangup(chan); 05029 res = -1; 05030 } 05031 } else { 05032 if (ast_pbx_start(chan)) { 05033 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05034 if (channel) { 05035 *channel = NULL; 05036 ast_mutex_unlock(&chan->lock); 05037 } 05038 ast_hangup(chan); 05039 res = -1; 05040 } 05041 } 05042 } else { 05043 if (option_verbose > 3) 05044 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05045 05046 if(chan->cdr) { /* update the cdr */ 05047 /* here we update the status of the call, which sould be busy. 05048 * if that fails then we set the status to failed */ 05049 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05050 ast_cdr_failed(chan->cdr); 05051 } 05052 05053 if (channel) { 05054 *channel = NULL; 05055 ast_mutex_unlock(&chan->lock); 05056 } 05057 ast_hangup(chan); 05058 } 05059 } 05060 05061 if (res < 0) { /* the call failed for some reason */ 05062 if (*reason == 0) { /* if the call failed (not busy or no answer) 05063 * update the cdr with the failed message */ 05064 cdr_res = ast_pbx_outgoing_cdr_failed(); 05065 if (cdr_res != 0) { 05066 res = cdr_res; 05067 goto outgoing_exten_cleanup; 05068 } 05069 } 05070 05071 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05072 /* check if "failed" exists */ 05073 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05074 chan = ast_channel_alloc(0); 05075 if (chan) { 05076 ast_copy_string(chan->name, "OutgoingSpoolFailed", sizeof(chan->name)); 05077 if (!ast_strlen_zero(context)) 05078 ast_copy_string(chan->context, context, sizeof(chan->context)); 05079 ast_copy_string(chan->exten, "failed", sizeof(chan->exten)); 05080 chan->priority = 1; 05081 ast_set_variables(chan, vars); 05082 if (account) 05083 ast_cdr_setaccount(chan, account); 05084 ast_pbx_run(chan); 05085 } else 05086 ast_log(LOG_WARNING, "Can't allocate the channel structure, skipping execution of extension 'failed'\n"); 05087 } 05088 } 05089 } else { 05090 as = malloc(sizeof(struct async_stat)); 05091 if (!as) { 05092 res = -1; 05093 goto outgoing_exten_cleanup; 05094 } 05095 memset(as, 0, sizeof(struct async_stat)); 05096 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05097 if (channel) { 05098 *channel = chan; 05099 if (chan) 05100 ast_mutex_lock(&chan->lock); 05101 } 05102 if (!chan) { 05103 free(as); 05104 res = -1; 05105 goto outgoing_exten_cleanup; 05106 } 05107 as->chan = chan; 05108 ast_copy_string(as->context, context, sizeof(as->context)); 05109 ast_copy_string(as->exten, exten, sizeof(as->exten)); 05110 as->priority = priority; 05111 as->timeout = timeout; 05112 ast_set_variables(chan, vars); 05113 if (account) 05114 ast_cdr_setaccount(chan, account); 05115 pthread_attr_init(&attr); 05116 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05117 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05118 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05119 free(as); 05120 if (channel) { 05121 *channel = NULL; 05122 ast_mutex_unlock(&chan->lock); 05123 } 05124 ast_hangup(chan); 05125 res = -1; 05126 goto outgoing_exten_cleanup; 05127 } 05128 res = 0; 05129 } 05130 outgoing_exten_cleanup: 05131 ast_variables_destroy(vars); 05132 return res; 05133 }
enum ast_pbx_result ast_pbx_run | ( | struct ast_channel * | c | ) |
c | channel to run the pbx on |
Definition at line 2549 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_ss(), and ss_thread().
02550 { 02551 enum ast_pbx_result res = AST_PBX_SUCCESS; 02552 02553 if (increase_call_count(c)) 02554 return AST_PBX_CALL_LIMIT; 02555 02556 res = __ast_pbx_run(c); 02557 decrease_call_count(); 02558 02559 return res; 02560 }
enum ast_pbx_result ast_pbx_start | ( | struct ast_channel * | c | ) |
c | channel to start the pbx on |
Definition at line 2525 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_modem_new(), ast_pbx_outgoing_exten(), check_goto_on_transfer(), dial_exec_full(), do_parking_thread(), handle_request_invite(), local_call(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), skinny_new(), vpb_new(), and zt_new().
02526 { 02527 pthread_t t; 02528 pthread_attr_t attr; 02529 02530 if (!c) { 02531 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02532 return AST_PBX_FAILED; 02533 } 02534 02535 if (increase_call_count(c)) 02536 return AST_PBX_CALL_LIMIT; 02537 02538 /* Start a new thread, and get something handling this channel. */ 02539 pthread_attr_init(&attr); 02540 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02541 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02542 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02543 return AST_PBX_FAILED; 02544 } 02545 02546 return AST_PBX_SUCCESS; 02547 }
int ast_register_application | ( | const char * | app, | |
int(*)(struct ast_channel *, void *) | execute, | |||
const char * | synopsis, | |||
const char * | description | |||
) |
Dynamically register a new dial plan application.
app | Short name of the application | |
execute | a function callback to execute the application | |
synopsis | a short description of the application | |
description | long description of the application Include a one-line synopsis (e.g. 'hangs up a channel') and a more lengthy, multiline description with more detail, including under what conditions the application will return 0 or -1. This registers an application with asterisks internal application list. Please note: The individual applications themselves are responsible for registering and unregistering CLI commands. It returns 0 on success, -1 on failure. |
Definition at line 2866 of file pbx.c.
References apps, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), COLOR_BRCYAN, LOG_ERROR, LOG_WARNING, malloc, ast_app::name, ast_app::next, option_verbose, term_color(), and VERBOSE_PREFIX_2.
Referenced by load_module(), and load_pbx().
02867 { 02868 struct ast_app *tmp, *prev, *cur; 02869 char tmps[80]; 02870 int length; 02871 length = sizeof(struct ast_app); 02872 length += strlen(app) + 1; 02873 if (ast_mutex_lock(&applock)) { 02874 ast_log(LOG_ERROR, "Unable to lock application list\n"); 02875 return -1; 02876 } 02877 tmp = apps; 02878 while(tmp) { 02879 if (!strcasecmp(app, tmp->name)) { 02880 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02881 ast_mutex_unlock(&applock); 02882 return -1; 02883 } 02884 tmp = tmp->next; 02885 } 02886 tmp = malloc(length); 02887 if (tmp) { 02888 memset(tmp, 0, length); 02889 strcpy(tmp->name, app); 02890 tmp->execute = execute; 02891 tmp->synopsis = synopsis; 02892 tmp->description = description; 02893 /* Store in alphabetical order */ 02894 cur = apps; 02895 prev = NULL; 02896 while(cur) { 02897 if (strcasecmp(tmp->name, cur->name) < 0) 02898 break; 02899 prev = cur; 02900 cur = cur->next; 02901 } 02902 if (prev) { 02903 tmp->next = prev->next; 02904 prev->next = tmp; 02905 } else { 02906 tmp->next = apps; 02907 apps = tmp; 02908 } 02909 } else { 02910 ast_log(LOG_ERROR, "Out of memory\n"); 02911 ast_mutex_unlock(&applock); 02912 return -1; 02913 } 02914 if (option_verbose > 1) 02915 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 02916 ast_mutex_unlock(&applock); 02917 return 0; 02918 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
sw | switch to register This function registers a populated ast_switch structure with the asterisk switching architecture. It returns 0 on success, and other than 0 on failure |
Definition at line 2920 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, LOG_WARNING, ast_switch::name, ast_switch::next, and switches.
Referenced by load_module().
02921 { 02922 struct ast_switch *tmp, *prev=NULL; 02923 if (ast_mutex_lock(&switchlock)) { 02924 ast_log(LOG_ERROR, "Unable to lock switch lock\n"); 02925 return -1; 02926 } 02927 tmp = switches; 02928 while(tmp) { 02929 if (!strcasecmp(tmp->name, sw->name)) 02930 break; 02931 prev = tmp; 02932 tmp = tmp->next; 02933 } 02934 if (tmp) { 02935 ast_mutex_unlock(&switchlock); 02936 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 02937 return -1; 02938 } 02939 sw->next = NULL; 02940 if (prev) 02941 prev->next = sw; 02942 else 02943 switches = sw; 02944 ast_mutex_unlock(&switchlock); 02945 return 0; 02946 }
int ast_spawn_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) |
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 This adds a new extension to the asterisk extension list. It returns 0 on success, -1 on failure. |
Definition at line 2228 of file pbx.c.
References HELPER_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), loopback_exec(), and macro_exec().
02229 { 02230 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_SPAWN); 02231 }
int ast_unlock_context | ( | struct ast_context * | con | ) |
con | context to unlock Unlocks the given context Returns 0 on success, -1 on failure |
Definition at line 6283 of file pbx.c.
References ast_mutex_unlock(), and ast_context::lock.
Referenced by complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_ignorepat(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), and show_dialplan_helper().
06284 { 06285 return ast_mutex_unlock(&con->lock); 06286 }
int ast_unlock_contexts | ( | void | ) |
Returns 0 on success, -1 on failure
Definition at line 6270 of file pbx.c.
References ast_mutex_unlock().
Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_show_dialplan_context(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), and show_dialplan_helper().
06271 { 06272 return ast_mutex_unlock(&conlock); 06273 }
int ast_unregister_application | ( | const char * | app | ) |
app | name of the application (does not have to be the same string as the one that was registered) This unregisters an application from asterisk's internal registration mechanisms. It returns 0 on success, and -1 on failure. |
Definition at line 3613 of file pbx.c.
References apps, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, LOG_ERROR, ast_app::name, ast_app::next, option_verbose, and VERBOSE_PREFIX_2.
Referenced by __unload_module(), and unload_module().
03614 { 03615 struct ast_app *tmp, *tmpl = NULL; 03616 if (ast_mutex_lock(&applock)) { 03617 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03618 return -1; 03619 } 03620 tmp = apps; 03621 while(tmp) { 03622 if (!strcasecmp(app, tmp->name)) { 03623 if (tmpl) 03624 tmpl->next = tmp->next; 03625 else 03626 apps = tmp->next; 03627 if (option_verbose > 1) 03628 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03629 free(tmp); 03630 ast_mutex_unlock(&applock); 03631 return 0; 03632 } 03633 tmpl = tmp; 03634 tmp = tmp->next; 03635 } 03636 ast_mutex_unlock(&applock); 03637 return -1; 03638 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
sw | switch to unregister Unregisters a switch from asterisk. Returns nothing |
Definition at line 2948 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, ast_switch::next, and switches.
Referenced by __unload_module(), and unload_module().
02949 { 02950 struct ast_switch *tmp, *prev=NULL; 02951 if (ast_mutex_lock(&switchlock)) { 02952 ast_log(LOG_ERROR, "Unable to lock switch lock\n"); 02953 return; 02954 } 02955 tmp = switches; 02956 while(tmp) { 02957 if (tmp == sw) { 02958 if (prev) 02959 prev->next = tmp->next; 02960 else 02961 switches = tmp->next; 02962 tmp->next = NULL; 02963 break; 02964 } 02965 prev = tmp; 02966 tmp = tmp->next; 02967 } 02968 ast_mutex_unlock(&switchlock); 02969 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | priority | |||
) |
Definition at line 6390 of file pbx.c.
References exten, and ast_context::root.
Referenced by complete_context_remove_extension(), dundi_precache_full(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper().
06392 { 06393 if (!exten) 06394 return con ? con->root : NULL; 06395 else 06396 return exten->next; 06397 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 6426 of file pbx.c.
References ast_context::ignorepats, and ast_ignorepat::next.
Referenced by complete_context_add_ignorepat(), complete_context_remove_ignorepat(), handle_save_dialplan(), and show_dialplan_helper().
06428 { 06429 if (!ip) 06430 return con ? con->ignorepats : NULL; 06431 else 06432 return ip->next; 06433 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 6417 of file pbx.c.
References ast_context::includes, and ast_include::next.
Referenced by ast_context_verify_includes(), complete_context_add_include(), complete_context_dont_include(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper().
06419 { 06420 if (!inc) 06421 return con ? con->includes : NULL; 06422 else 06423 return inc->next; 06424 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 6399 of file pbx.c.
References ast_context::alts, and ast_sw::next.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06401 { 06402 if (!sw) 06403 return con ? con->alts : NULL; 06404 else 06405 return sw->next; 06406 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 6382 of file pbx.c.
References contexts, and ast_context::next.
Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_show_dialplan_context(), dundi_precache_full(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), 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 6408 of file pbx.c.
References exten, and ast_exten::priority.
Referenced by complete_context_remove_extension(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper().
void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 6127 of file pbx.c.
References AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), ast_var_delete(), and globals.
Referenced by reload().
06128 { 06129 struct ast_var_t *vardata; 06130 06131 ast_mutex_lock(&globalslock); 06132 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06133 ast_var_delete(vardata); 06134 ast_mutex_unlock(&globalslock); 06135 }
char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5922 of file pbx.c.
References AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), globals, and ast_channel::varshead.
Referenced by __login_exec(), _while_exec(), action_getvar(), agentmonitoroutgoing_exec(), ast_app_group_get_count(), ast_app_group_match_get_count(), ast_bridge_call(), ast_feature_interpret(), ast_monitor_stop(), ast_osp_lookup(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), chanspy_exec(), check_goto_on_transfer(), conf_exec(), conf_run(), dial_exec_full(), do_chanreads(), dundi_exec(), dundi_helper(), get_index(), get_refer_info(), group_check_exec(), group_count_exec(), group_count_function_read(), group_function_read(), iax2_exec(), import_ch(), leave_voicemail(), macro_exec(), misdn_answer(), misdn_hangup(), oh323_hangup(), ospfinished_exec(), ospnext_exec(), queue_exec(), retrydial_exec(), return_exec(), rxfax_exec(), set_config_flags(), sip_addheader(), try_calling(), try_suggested_sip_codec(), txfax_exec(), wait_for_answer(), zt_call(), and zt_hangup().
05923 { 05924 struct ast_var_t *variables; 05925 char *ret = NULL; 05926 int i; 05927 struct varshead *places[2] = { NULL, &globals }; 05928 05929 if (!name) 05930 return NULL; 05931 if (chan) 05932 places[0] = &chan->varshead; 05933 05934 for (i = 0; i < 2; i++) { 05935 if (!places[i]) 05936 continue; 05937 if (places[i] == &globals) 05938 ast_mutex_lock(&globalslock); 05939 AST_LIST_TRAVERSE(places[i], variables, entries) { 05940 if (!strcmp(name, ast_var_name(variables))) { 05941 ret = ast_var_value(variables); 05942 break; 05943 } 05944 } 05945 if (places[i] == &globals) 05946 ast_mutex_unlock(&globalslock); 05947 if (ret) 05948 break; 05949 } 05950 05951 return ret; 05952 }
void pbx_builtin_pushvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5954 of file pbx.c.
References ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_var_assign(), ast_verbose(), globals, LOG_WARNING, option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2.
Referenced by gosub_exec().
05955 { 05956 struct ast_var_t *newvariable; 05957 struct varshead *headp; 05958 05959 if (name[strlen(name)-1] == ')') { 05960 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05961 return ast_func_write(chan, name, value); 05962 } 05963 05964 headp = (chan) ? &chan->varshead : &globals; 05965 05966 if (value) { 05967 if ((option_verbose > 1) && (headp == &globals)) 05968 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05969 newvariable = ast_var_assign(name, value); 05970 if (headp == &globals) 05971 ast_mutex_lock(&globalslock); 05972 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05973 if (headp == &globals) 05974 ast_mutex_unlock(&globalslock); 05975 } 05976 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5897 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(), and handle_showchan().
05898 { 05899 struct ast_var_t *variables; 05900 char *var, *val; 05901 int total = 0; 05902 05903 if (!chan) 05904 return 0; 05905 05906 memset(buf, 0, size); 05907 05908 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05909 if ((var = ast_var_name(variables)) && (val = ast_var_value(variables))) { 05910 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05911 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05912 break; 05913 } else 05914 total++; 05915 } else 05916 break; 05917 } 05918 05919 return total; 05920 }
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 5978 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_var_assign(), ast_var_delete(), ast_var_name(), ast_verbose(), globals, option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2.
Referenced by _while_exec(), action_setvar(), aPGSQL_connect(), aPGSQL_fetch(), aPGSQL_query(), aqm_exec(), ast_app_group_set_channel(), ast_bridge_call(), ast_iax2_new(), ast_monitor_start(), ast_set_variables(), background_detect_exec(), builtin_blindtransfer(), builtin_function_set(), cb_events(), chanavail_exec(), controlplayback_exec(), count_exec(), curl_exec(), cut_exec(), dial_exec_full(), disa_exec(), do_waiting(), dundi_lookup_exec(), enumlookup_exec(), eval_exec(), export_ch(), function_db_exists(), function_db_read(), get_exec(), get_refer_info(), group_check_exec(), group_count_exec(), group_match_count_exec(), handle_setvariable(), hasvoicemail_exec(), leave_voicemail(), lookupblacklist_exec(), macro_exec(), math_exec(), md5_exec(), md5check_exec(), misdn_call(), mixmonitor_exec(), monitor_handle_owned(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), pbx_builtin_importvar(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_extension_helper(), pbx_load_module(), 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(), record_exec(), return_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_getheader(), sip_new(), sort_exec(), start_monitor_exec(), system_exec_helper(), transfer_exec(), txtcidname_exec(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), zt_new(), and zt_read().
05979 { 05980 struct ast_var_t *newvariable; 05981 struct varshead *headp; 05982 const char *nametail = name; 05983 05984 if (name[strlen(name)-1] == ')') 05985 return ast_func_write(chan, name, value); 05986 05987 headp = (chan) ? &chan->varshead : &globals; 05988 05989 /* For comparison purposes, we have to strip leading underscores */ 05990 if (*nametail == '_') { 05991 nametail++; 05992 if (*nametail == '_') 05993 nametail++; 05994 } 05995 05996 if (headp == &globals) 05997 ast_mutex_lock(&globalslock); 05998 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05999 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 06000 /* there is already such a variable, delete it */ 06001 AST_LIST_REMOVE(headp, newvariable, entries); 06002 ast_var_delete(newvariable); 06003 break; 06004 } 06005 } 06006 06007 if (value) { 06008 if ((option_verbose > 1) && (headp == &globals)) 06009 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 06010 newvariable = ast_var_assign(name, value); 06011 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 06012 } 06013 06014 if (headp == &globals) 06015 ast_mutex_unlock(&globalslock); 06016 }
int pbx_checkcondition | ( | char * | condition | ) |
Definition at line 6137 of file pbx.c.
Referenced by _while_exec(), builtin_function_if(), execif_exec(), gosubif_exec(), macroif_exec(), and pbx_builtin_gotoif().
06138 { 06139 if (condition) { 06140 if (*condition == '\0') { 06141 /* Empty strings are false */ 06142 return 0; 06143 } else if (*condition >= '0' && *condition <= '9') { 06144 /* Numbers are evaluated for truth */ 06145 return atoi(condition); 06146 } else { 06147 /* Strings are true */ 06148 return 1; 06149 } 06150 } else { 06151 /* NULL is also false */ 06152 return 0; 06153 } 06154 }
int pbx_exec | ( | struct ast_channel * | c, | |
struct ast_app * | app, | |||
void * | data, | |||
int | newstack | |||
) |
c | channel to execute on | |
app | which app to execute | |
data | the data passed into the app | |
newstack | stack pointer This application executes an application on a given channel. It saves the stack and executes the given appliation passing in the given data. It returns 0 on success, and -1 on failure |
c | Channel |
app | Application |
data | Data for execution |
newstack | Force stack increment |
Definition at line 531 of file pbx.c.
References app, ast_channel::appl, ast_cdr_setapp(), ast_log(), ast_channel::cdr, ast_channel::data, and LOG_WARNING.
Referenced by ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dial_exec_full(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), and realtime_exec().
00535 { 00536 int res; 00537 00538 char *saved_c_appl; 00539 char *saved_c_data; 00540 00541 int (*execute)(struct ast_channel *chan, void *data) = app->execute; 00542 00543 if (newstack) { 00544 if (c->cdr) 00545 ast_cdr_setapp(c->cdr, app->name, data); 00546 00547 /* save channel values */ 00548 saved_c_appl= c->appl; 00549 saved_c_data= c->data; 00550 00551 c->appl = app->name; 00552 c->data = data; 00553 res = execute(c, data); 00554 /* restore channel values */ 00555 c->appl= saved_c_appl; 00556 c->data= saved_c_data; 00557 return res; 00558 } else 00559 ast_log(LOG_WARNING, "You really didn't want to call this function with newstack set to 0\n"); 00560 return -1; 00561 }
struct ast_app* pbx_findapp | ( | const char * | app | ) |
Find application handle in linked list.
app | name of the app This function searches for the ast_app structure within the apps that are registered for the one with the name you passed in. Returns the ast_app structure that matches on success, or NULL on failure |
Definition at line 576 of file pbx.c.
References apps, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, ast_app::name, and ast_app::next.
Referenced by ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dial_exec_full(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), and realtime_exec().
00577 { 00578 struct ast_app *tmp; 00579 00580 if (ast_mutex_lock(&applock)) { 00581 ast_log(LOG_WARNING, "Unable to obtain application lock\n"); 00582 return NULL; 00583 } 00584 tmp = apps; 00585 while(tmp) { 00586 if (!strcasecmp(tmp->name, app)) 00587 break; 00588 tmp = tmp->next; 00589 } 00590 ast_mutex_unlock(&applock); 00591 return tmp; 00592 }
void pbx_retrieve_variable | ( | struct ast_channel * | c, | |
const char * | var, | |||
char ** | ret, | |||
char * | workspace, | |||
int | workspacelen, | |||
struct varshead * | headp | |||
) |
pbx_retrieve_variable: Support for Asterisk built-in variables and functions in the dialplan ---
Definition at line 979 of file pbx.c.
References ast_channel::accountcode, ast_get_hint(), AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_ani2, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, globals, ast_channel::hangupcause, ast_channel::language, LOG_WARNING, ast_channel::name, offset, parse_variable_name(), pbx_retrieve_variable(), ast_channel::priority, substring(), ast_channel::uniqueid, and ast_channel::varshead.
Referenced by function_fieldqty(), handle_getvariable(), pbx_retrieve_variable(), and pbx_substitute_variables_helper_full().
00980 { 00981 char tmpvar[80]; 00982 time_t thistime; 00983 struct tm brokentime; 00984 int offset, offset2, isfunc; 00985 struct ast_var_t *variables; 00986 00987 if (c) 00988 headp=&c->varshead; 00989 *ret=NULL; 00990 ast_copy_string(tmpvar, var, sizeof(tmpvar)); 00991 if (parse_variable_name(tmpvar, &offset, &offset2, &isfunc)) { 00992 pbx_retrieve_variable(c, tmpvar, ret, workspace, workspacelen, headp); 00993 if (!(*ret)) 00994 return; 00995 *ret = substring(*ret, offset, offset2, workspace, workspacelen); 00996 } else if (c && !strncmp(var, "CALL", 4)) { 00997 if (!strncmp(var + 4, "ER", 2)) { 00998 if (!strncmp(var + 6, "ID", 2)) { 00999 if (!var[8]) { /* CALLERID */ 01000 if (c->cid.cid_num) { 01001 if (c->cid.cid_name) { 01002 snprintf(workspace, workspacelen, "\"%s\" <%s>", c->cid.cid_name, c->cid.cid_num); 01003 } else { 01004 ast_copy_string(workspace, c->cid.cid_num, workspacelen); 01005 } 01006 *ret = workspace; 01007 } else if (c->cid.cid_name) { 01008 ast_copy_string(workspace, c->cid.cid_name, workspacelen); 01009 *ret = workspace; 01010 } else 01011 *ret = NULL; 01012 } else if (!strcmp(var + 8, "NUM")) { 01013 /* CALLERIDNUM */ 01014 if (c->cid.cid_num) { 01015 ast_copy_string(workspace, c->cid.cid_num, workspacelen); 01016 *ret = workspace; 01017 } else 01018 *ret = NULL; 01019 } else if (!strcmp(var + 8, "NAME")) { 01020 /* CALLERIDNAME */ 01021 if (c->cid.cid_name) { 01022 ast_copy_string(workspace, c->cid.cid_name, workspacelen); 01023 *ret = workspace; 01024 } else 01025 *ret = NULL; 01026 } else 01027 goto icky; 01028 } else if (!strcmp(var + 6, "ANI")) { 01029 /* CALLERANI */ 01030 if (c->cid.cid_ani) { 01031 ast_copy_string(workspace, c->cid.cid_ani, workspacelen); 01032 *ret = workspace; 01033 } else 01034 *ret = NULL; 01035 } else 01036 goto icky; 01037 } else if (!strncmp(var + 4, "ING", 3)) { 01038 if (!strcmp(var + 7, "PRES")) { 01039 /* CALLINGPRES */ 01040 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 01041 *ret = workspace; 01042 } else if (!strcmp(var + 7, "ANI2")) { 01043 /* CALLINGANI2 */ 01044 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 01045 *ret = workspace; 01046 } else if (!strcmp(var + 7, "TON")) { 01047 /* CALLINGTON */ 01048 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 01049 *ret = workspace; 01050 } else if (!strcmp(var + 7, "TNS")) { 01051 /* CALLINGTNS */ 01052 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 01053 *ret = workspace; 01054 } else 01055 goto icky; 01056 } else 01057 goto icky; 01058 } else if (c && !strcmp(var, "DNID")) { 01059 if (c->cid.cid_dnid) { 01060 ast_copy_string(workspace, c->cid.cid_dnid, workspacelen); 01061 *ret = workspace; 01062 } else 01063 *ret = NULL; 01064 } else if (c && !strcmp(var, "HINT")) { 01065 if (!ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten)) 01066 *ret = NULL; 01067 else 01068 *ret = workspace; 01069 } else if (c && !strcmp(var, "HINTNAME")) { 01070 if (!ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten)) 01071 *ret = NULL; 01072 else 01073 *ret = workspace; 01074 } else if (c && !strcmp(var, "EXTEN")) { 01075 ast_copy_string(workspace, c->exten, workspacelen); 01076 *ret = workspace; 01077 } else if (c && !strcmp(var, "RDNIS")) { 01078 if (c->cid.cid_rdnis) { 01079 ast_copy_string(workspace, c->cid.cid_rdnis, workspacelen); 01080 *ret = workspace; 01081 } else 01082 *ret = NULL; 01083 } else if (c && !strcmp(var, "CONTEXT")) { 01084 ast_copy_string(workspace, c->context, workspacelen); 01085 *ret = workspace; 01086 } else if (c && !strcmp(var, "PRIORITY")) { 01087 snprintf(workspace, workspacelen, "%d", c->priority); 01088 *ret = workspace; 01089 } else if (c && !strcmp(var, "CHANNEL")) { 01090 ast_copy_string(workspace, c->name, workspacelen); 01091 *ret = workspace; 01092 } else if (!strcmp(var, "EPOCH")) { 01093 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 01094 *ret = workspace; 01095 } else if (!strcmp(var, "DATETIME")) { 01096 thistime=time(NULL); 01097 localtime_r(&thistime, &brokentime); 01098 snprintf(workspace, workspacelen, "%02d%02d%04d-%02d:%02d:%02d", 01099 brokentime.tm_mday, 01100 brokentime.tm_mon+1, 01101 brokentime.tm_year+1900, 01102 brokentime.tm_hour, 01103 brokentime.tm_min, 01104 brokentime.tm_sec 01105 ); 01106 *ret = workspace; 01107 } else if (!strcmp(var, "TIMESTAMP")) { 01108 thistime=time(NULL); 01109 localtime_r(&thistime, &brokentime); 01110 /* 20031130-150612 */ 01111 snprintf(workspace, workspacelen, "%04d%02d%02d-%02d%02d%02d", 01112 brokentime.tm_year+1900, 01113 brokentime.tm_mon+1, 01114 brokentime.tm_mday, 01115 brokentime.tm_hour, 01116 brokentime.tm_min, 01117 brokentime.tm_sec 01118 ); 01119 *ret = workspace; 01120 } else if (c && !strcmp(var, "UNIQUEID")) { 01121 snprintf(workspace, workspacelen, "%s", c->uniqueid); 01122 *ret = workspace; 01123 } else if (c && !strcmp(var, "HANGUPCAUSE")) { 01124 snprintf(workspace, workspacelen, "%d", c->hangupcause); 01125 *ret = workspace; 01126 } else if (c && !strcmp(var, "ACCOUNTCODE")) { 01127 ast_copy_string(workspace, c->accountcode, workspacelen); 01128 *ret = workspace; 01129 } else if (c && !strcmp(var, "LANGUAGE")) { 01130 ast_copy_string(workspace, c->language, workspacelen); 01131 *ret = workspace; 01132 } else { 01133 icky: 01134 if (headp) { 01135 AST_LIST_TRAVERSE(headp,variables,entries) { 01136 #if 0 01137 ast_log(LOG_WARNING,"Comparing variable '%s' with '%s'\n",var,ast_var_name(variables)); 01138 #endif 01139 if (strcasecmp(ast_var_name(variables),var)==0) { 01140 *ret=ast_var_value(variables); 01141 if (*ret) { 01142 ast_copy_string(workspace, *ret, workspacelen); 01143 *ret = workspace; 01144 } 01145 break; 01146 } 01147 } 01148 } 01149 if (!(*ret)) { 01150 /* Try globals */ 01151 ast_mutex_lock(&globalslock); 01152 AST_LIST_TRAVERSE(&globals,variables,entries) { 01153 if (strcasecmp(ast_var_name(variables),var)==0) { 01154 *ret = ast_var_value(variables); 01155 if (*ret) { 01156 ast_copy_string(workspace, *ret, workspacelen); 01157 *ret = workspace; 01158 } 01159 } 01160 } 01161 ast_mutex_unlock(&globalslock); 01162 } 01163 } 01164 }
int pbx_set_autofallthrough | ( | int | newval | ) |
Definition at line 2567 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
02568 { 02569 int oldval; 02570 oldval = autofallthrough; 02571 if (oldval != newval) 02572 autofallthrough = newval; 02573 return oldval; 02574 }
void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1598 of file pbx.c.
References pbx_substitute_variables_helper_full(), and ast_channel::varshead.
Referenced by custom_log(), cut_internal(), eval_exec(), exec_exec(), function_eval(), handle_getvariablefull(), launch_monitor_thread(), pbx_builtin_importvar(), pbx_load_module(), pbx_substitute_variables(), realtime_exec(), rpt_exec(), sendmail(), and sendpage().
01599 { 01600 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 01601 }
void pbx_substitute_variables_varshead | ( | struct varshead * | headp, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1603 of file pbx.c.
References pbx_substitute_variables_helper_full().
Referenced by ast_add_extension2(), dundi_lookup_local(), and loopback_helper().
01604 { 01605 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 01606 }
struct cfextension_states extension_states[] [static] |
Referenced by ast_extension_state2str().