#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/linkedlists.h"
#include "asterisk/devicestate.h"
Include dependency graph for pbx.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
Data Structures | |
| struct | ast_custom_function |
| Data structure associated with a custom dialplan function. More... | |
| struct | ast_pbx |
| struct | ast_switch |
| struct | ast_timing |
Defines | |
| #define | AST_MAX_APP 32 |
| #define | AST_PBX_KEEP 0 |
| #define | AST_PBX_KEEPALIVE 10 |
| Special return values from applications to the PBX {. | |
| #define | AST_PBX_REPLACE 1 |
| #define | PRIORITY_HINT -1 |
Typedefs | |
| typedef int(*) | ast_state_cb_type (char *context, char *id, enum ast_extension_states state, void *data) |
| Typedef for devicestate and hint callbacks. | |
| typedef int( | ast_switch_f )(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| All switch functions have the same interface, so define a type for them. | |
Enumerations | |
| enum | ast_extension_states { AST_EXTENSION_REMOVED = -2, AST_EXTENSION_DEACTIVATED = -1, AST_EXTENSION_NOT_INUSE = 0, AST_EXTENSION_INUSE = 1 << 0, AST_EXTENSION_BUSY = 1 << 1, AST_EXTENSION_UNAVAILABLE = 1 << 2, AST_EXTENSION_RINGING = 1 << 3, AST_EXTENSION_ONHOLD = 1 << 4 } |
| Extension states. More... | |
| enum | ast_pbx_result { AST_PBX_SUCCESS = 0, AST_PBX_FAILED = -1, AST_PBX_CALL_LIMIT = -2 } |
Functions | |
| int | ast_active_calls (void) |
| Retrieve the number of active calls. | |
| int | ast_add_extension (const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar) |
| Add and extension to an extension context. | |
| int | ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar) |
| Add an extension to an extension context, this time with an ast_context *. | |
| int | ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority) |
| int | ast_async_goto_by_name (const char *chan, const char *context, const char *exten, int priority) |
| int | ast_async_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
| int | ast_build_timing (struct ast_timing *i, const char *info) |
| int | ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| Looks for a valid matching extension. | |
| int | ast_check_timing (const struct ast_timing *i) |
| int | ast_context_add_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
| Add an ignorepat. | |
| int | ast_context_add_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar) |
| int | ast_context_add_include (const char *context, const char *include, const char *registrar) |
| Add a context include. | |
| int | ast_context_add_include2 (struct ast_context *con, const char *include, const char *registrar) |
| Add a context include. | |
| int | ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar) |
| Add a switch. | |
| int | ast_context_add_switch2 (struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar) |
| Adds a switch (first param is a ast_context). | |
| ast_context * | ast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar) |
| Register a new context. | |
| void | ast_context_destroy (struct ast_context *con, const char *registrar) |
| Destroy a context (matches the specified context (or ANY context if NULL). | |
| ast_context * | ast_context_find (const char *name) |
| Find a context. | |
| ast_context * | ast_context_find_or_create (struct ast_context **extcontexts, const char *name, const char *registrar) |
| int | ast_context_lockmacro (const char *macrocontext) |
| locks the macrolock in the given given context | |
| int | ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar) |
| Simply remove extension from context. | |
| int | ast_context_remove_extension2 (struct ast_context *con, const char *extension, int priority, const char *registrar) |
| This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return. | |
| int | ast_context_remove_extension_callerid (const char *context, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar) |
| int | ast_context_remove_extension_callerid2 (struct ast_context *con, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar) |
| int | ast_context_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
| int | ast_context_remove_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar) |
| int | ast_context_remove_include (const char *context, const char *include, const char *registrar) |
| Remove a context include. | |
| int | ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar) |
| Removes an include by an ast_context structure. | |
| int | ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar) |
| Remove a switch. | |
| int | ast_context_remove_switch2 (struct ast_context *con, const char *sw, const char *data, const char *registrar) |
| This function locks given context, removes switch, unlock context and return. | |
| int | ast_context_unlockmacro (const char *macrocontext) |
| Unlocks the macrolock in the given context. | |
| int | ast_context_verify_includes (struct ast_context *con) |
| Verifies includes in an ast_contect structure. | |
| ast_custom_function * | ast_custom_function_find (const char *name) |
| int | ast_custom_function_register (struct ast_custom_function *acf) |
| Reigster a custom function. | |
| int | ast_custom_function_unregister (struct ast_custom_function *acf) |
| Unregister a custom function. | |
| int | ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| Determine whether an extension exists. | |
| int | ast_explicit_goto (struct ast_channel *chan, const char *context, const char *exten, int priority) |
| int | ast_extension_close (const char *pattern, const char *data, int needmore) |
| int | ast_extension_match (const char *pattern, const char *extension) |
| Determine if a given extension matches a given pattern (in NXX format). | |
| int | ast_extension_patmatch (const char *pattern, const char *data) |
| int | ast_extension_state (struct ast_channel *c, const char *context, const char *exten) |
| Uses hint and devicestate callback to get the state of an extension. | |
| const char * | ast_extension_state2str (int extension_state) |
| Return string representation of the state of an extension. | |
| int | ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data) |
| Registers a state change callback. | |
| int | ast_extension_state_del (int id, ast_state_cb_type callback) |
| Deletes a registered state change callback by ID. | |
| int | ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid) |
| Find the priority of an extension that has the specified label. | |
| int | ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid) |
| Find the priority of an extension that has the specified label. | |
| int | ast_func_read (struct ast_channel *chan, char *function, char *workspace, size_t len) |
| executes a read operation on a function | |
| int | ast_func_write (struct ast_channel *chan, char *function, const char *value) |
| executes a write operation on a function | |
| const char * | ast_get_context_name (struct ast_context *con) |
| const char * | ast_get_context_registrar (struct ast_context *c) |
| const char * | ast_get_extension_app (struct ast_exten *e) |
| void * | ast_get_extension_app_data (struct ast_exten *e) |
| const char * | ast_get_extension_cidmatch (struct ast_exten *e) |
| ast_context * | ast_get_extension_context (struct ast_exten *exten) |
| const char * | ast_get_extension_label (struct ast_exten *e) |
| int | ast_get_extension_matchcid (struct ast_exten *e) |
| const char * | ast_get_extension_name (struct ast_exten *exten) |
| int | ast_get_extension_priority (struct ast_exten *exten) |
| const char * | ast_get_extension_registrar (struct ast_exten *e) |
| int | ast_get_hint (char *hint, int maxlen, char *name, int maxnamelen, struct ast_channel *c, const char *context, const char *exten) |
| If an extension exists, return non-zero. | |
| const char * | ast_get_ignorepat_name (struct ast_ignorepat *ip) |
| const char * | ast_get_ignorepat_registrar (struct ast_ignorepat *ip) |
| const char * | ast_get_include_name (struct ast_include *include) |
| const char * | ast_get_include_registrar (struct ast_include *i) |
| const char * | ast_get_switch_data (struct ast_sw *sw) |
| const char * | ast_get_switch_name (struct ast_sw *sw) |
| const char * | ast_get_switch_registrar (struct ast_sw *sw) |
| int | ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
| void | ast_hint_state_changed (const char *device) |
| int | ast_ignore_pattern (const char *context, const char *pattern) |
| Checks to see if a number should be ignored. | |
| int | ast_lock_context (struct ast_context *con) |
| Locks a given context. | |
| int | ast_lock_contexts (void) |
| Locks the context list. | |
| int | ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| Looks to see if adding anything to this extension might match something. (exists ^ canmatch). | |
| void | ast_merge_contexts_and_delete (struct ast_context **extcontexts, const char *registrar) |
| Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added. | |
| int | ast_parseable_goto (struct ast_channel *chan, const char *goto_string) |
| int | ast_pbx_outgoing_app (const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) |
| int | ast_pbx_outgoing_exten (const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) |
| enum ast_pbx_result | ast_pbx_run (struct ast_channel *c) |
| Execute the PBX in the current thread. | |
| enum ast_pbx_result | ast_pbx_start (struct ast_channel *c) |
| Create a new thread and start the PBX. | |
| int | ast_rdlock_contexts (void) |
| int | ast_register_application (const char *app, int(*execute)(struct ast_channel *, void *), const char *synopsis, const char *description) |
| Register an application. | |
| int | ast_register_switch (struct ast_switch *sw) |
| Register an alternative dialplan switch. | |
| int | ast_spawn_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| Launch a new extension (i.e. new stack). | |
| int | ast_unlock_context (struct ast_context *con) |
| int | ast_unlock_contexts (void) |
| Unlocks contexts. | |
| int | ast_unregister_application (const char *app) |
| Unregister an application. | |
| void | ast_unregister_switch (struct ast_switch *sw) |
| Unregister an alternative switch. | |
| ast_exten * | ast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority) |
| ast_ignorepat * | ast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip) |
| ast_include * | ast_walk_context_includes (struct ast_context *con, struct ast_include *inc) |
| ast_sw * | ast_walk_context_switches (struct ast_context *con, struct ast_sw *sw) |
| ast_context * | ast_walk_contexts (struct ast_context *con) |
| ast_exten * | ast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority) |
| int | ast_wrlock_contexts (void) |
| void | pbx_builtin_clear_globals (void) |
| const char * | pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name) |
| void | pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value) |
| int | pbx_builtin_serialize_variables (struct ast_channel *chan, char *buf, size_t size) |
| int | pbx_builtin_setvar (struct ast_channel *chan, void *data) |
| void | pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value) |
| int | pbx_checkcondition (const char *condition) |
| Evaluate a condition. | |
| int | pbx_exec (struct ast_channel *c, struct ast_app *app, void *data) |
| Execute an application. | |
| ast_app * | pbx_findapp (const char *app) |
| Look up an application. | |
| void | pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp) |
| pbx_retrieve_variable: Support for Asterisk built-in variables --- | |
| int | pbx_set_autofallthrough (int newval) |
| void | pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count) |
| void | pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count) |
Definition in file pbx.h.
| #define AST_MAX_APP 32 |
Max length of an application
Definition at line 35 of file pbx.h.
Referenced by destroy_station(), handle_show_application(), handle_show_application_deprecated(), handle_show_function(), and handle_show_function_deprecated().
| #define AST_PBX_KEEPALIVE 10 |
Special return values from applications to the PBX {.
Destroy the thread, but don't hang up the channel
Definition at line 41 of file pbx.h.
Referenced by __ast_pbx_run(), _macro_exec(), agi_handle_command(), and run_agi().
| #define PRIORITY_HINT -1 |
} Special Priority for a hint
Definition at line 44 of file pbx.h.
Referenced by add_extensions(), add_pri(), ast_add_extension2(), ast_hint_extension(), ast_merge_contexts_and_delete(), destroy_exten(), destroy_station(), handle_context_add_extension(), handle_context_add_extension_deprecated(), handle_context_remove_extension(), handle_context_remove_extension_deprecated(), handle_save_dialplan(), park_add_hints(), pbx_load_config(), and print_ext().
| typedef int(*) ast_state_cb_type(char *context, char *id, enum ast_extension_states state, void *data) |
| typedef int( ast_switch_f)(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| enum ast_extension_states |
Extension states.
Definition at line 47 of file pbx.h.
00047 { 00048 AST_EXTENSION_REMOVED = -2, /*!< Extension removed */ 00049 AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */ 00050 AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */ 00051 AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */ 00052 AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */ 00053 AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */ 00054 AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */ 00055 AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */ 00056 };
| enum ast_pbx_result |
Definition at line 214 of file pbx.h.
00214 { 00215 AST_PBX_SUCCESS = 0, 00216 AST_PBX_FAILED = -1, 00217 AST_PBX_CALL_LIMIT = -2, 00218 };
| int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 2621 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02622 { 02623 return countcalls; 02624 }
| int ast_add_extension | ( | const char * | context, | |
| int | replace, | |||
| const char * | extension, | |||
| int | priority, | |||
| const char * | label, | |||
| const char * | callerid, | |||
| const char * | application, | |||
| void * | data, | |||
| void(*)(void *) | datad, | |||
| const char * | registrar | |||
| ) |
Add and extension to an extension context.
| context | context to add the extension to | |
| replace | ||
| extension | extension to add | |
| priority | priority level of extension addition | |
| label | extension label | |
| callerid | pattern to match CallerID, or NULL to match any CallerID | |
| application | application to run on the extension with that priority level | |
| data | data to pass to the application | |
| datad | ||
| registrar | who registered the extension |
| 0 | success | |
| -1 | failure |
Definition at line 4534 of file pbx.c.
References ast_add_extension2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_context_add_extension(), handle_context_add_extension_deprecated(), park_add_hints(), and register_peer_exten().
04537 { 04538 int ret = -1; 04539 struct ast_context *c = find_context_locked(context); 04540 04541 if (c) { 04542 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04543 application, data, datad, registrar); 04544 ast_unlock_contexts(); 04545 } 04546 return ret; 04547 }
| int ast_add_extension2 | ( | struct ast_context * | con, | |
| int | replace, | |||
| const char * | extension, | |||
| int | priority, | |||
| const char * | label, | |||
| const char * | callerid, | |||
| const char * | application, | |||
| void * | data, | |||
| void(*)(void *) | datad, | |||
| const char * | registrar | |||
| ) |
Add an extension to an extension context, this time with an ast_context *.
We sort extensions in order of matching preference, so that we can stop the search as soon as we find a suitable match. This ordering also takes care of wildcards such as '.' (meaning "one or more of any character") and '!' (which is 'earlymatch', meaning "zero or more of any character" but also impacts the return value from CANMATCH and EARLYMATCH.
The extension match rules defined in the devmeeting 2006.05.05 are quite simple: WE SELECT THE LONGEST MATCH. In detail, "longest" means the number of matched characters in the extension. In case of ties (e.g. _XXX and 333) in the length of a pattern, we give priority to entries with the smallest cardinality (e.g, [5-9] comes before [2-8] before the former has only 5 elements, while the latter has 7, etc. In case of same cardinality, the first element in the range counts. If we still have a tie, any final '!' will make this as a possibly less specific pattern.
EBUSY - can't lock EEXIST - extension with the same priority exist and no replace is set
Definition at line 4749 of file pbx.c.
References add_pri(), ast_exten::app, ast_add_hint(), ast_calloc, AST_LIST_FIRST, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_exten::cidmatch, ast_exten::data, ast_exten::datad, el, errno, ext_cmp(), ext_strncpy(), ast_exten::exten, globals, globalslock, ast_exten::label, ast_context::lock, ast_exten::matchcid, ast_context::name, ast_exten::next, option_verbose, ast_exten::parent, pbx_substitute_variables_varshead(), ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, ast_context::root, ast_exten::stuff, VAR_BUF_SIZE, and VERBOSE_PREFIX_3.
Referenced by add_extensions(), ast_add_extension(), do_parking_thread(), park_call_full(), pbx_load_config(), and pbx_load_users().
04753 { 04754 /* 04755 * Sort extensions (or patterns) according to the rules indicated above. 04756 * These are implemented by the function ext_cmp()). 04757 * All priorities for the same ext/pattern/cid are kept in a list, 04758 * using the 'peer' field as a link field.. 04759 */ 04760 struct ast_exten *tmp, *e, *el = NULL; 04761 int res; 04762 int length; 04763 char *p; 04764 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04765 04766 /* if we are adding a hint, and there are global variables, and the hint 04767 contains variable references, then expand them 04768 */ 04769 ast_mutex_lock(&globalslock); 04770 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04771 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04772 application = expand_buf; 04773 } 04774 ast_mutex_unlock(&globalslock); 04775 04776 length = sizeof(struct ast_exten); 04777 length += strlen(extension) + 1; 04778 length += strlen(application) + 1; 04779 if (label) 04780 length += strlen(label) + 1; 04781 if (callerid) 04782 length += strlen(callerid) + 1; 04783 else 04784 length ++; /* just the '\0' */ 04785 04786 /* Be optimistic: Build the extension structure first */ 04787 if (!(tmp = ast_calloc(1, length))) 04788 return -1; 04789 04790 /* use p as dst in assignments, as the fields are const char * */ 04791 p = tmp->stuff; 04792 if (label) { 04793 tmp->label = p; 04794 strcpy(p, label); 04795 p += strlen(label) + 1; 04796 } 04797 tmp->exten = p; 04798 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04799 tmp->priority = priority; 04800 tmp->cidmatch = p; /* but use p for assignments below */ 04801 if (callerid) { 04802 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04803 tmp->matchcid = 1; 04804 } else { 04805 *p++ = '\0'; 04806 tmp->matchcid = 0; 04807 } 04808 tmp->app = p; 04809 strcpy(p, application); 04810 tmp->parent = con; 04811 tmp->data = data; 04812 tmp->datad = datad; 04813 tmp->registrar = registrar; 04814 04815 ast_mutex_lock(&con->lock); 04816 res = 0; /* some compilers will think it is uninitialized otherwise */ 04817 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04818 res = ext_cmp(e->exten, tmp->exten); 04819 if (res == 0) { /* extension match, now look at cidmatch */ 04820 if (!e->matchcid && !tmp->matchcid) 04821 res = 0; 04822 else if (tmp->matchcid && !e->matchcid) 04823 res = 1; 04824 else if (e->matchcid && !tmp->matchcid) 04825 res = -1; 04826 else 04827 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04828 } 04829 if (res >= 0) 04830 break; 04831 } 04832 if (e && res == 0) { /* exact match, insert in the pri chain */ 04833 res = add_pri(con, tmp, el, e, replace); 04834 ast_mutex_unlock(&con->lock); 04835 if (res < 0) { 04836 errno = EEXIST; /* XXX do we care ? */ 04837 return 0; /* XXX should we return -1 maybe ? */ 04838 } 04839 } else { 04840 /* 04841 * not an exact match, this is the first entry with this pattern, 04842 * so insert in the main list right before 'e' (if any) 04843 */ 04844 tmp->next = e; 04845 if (el) 04846 el->next = tmp; 04847 else 04848 con->root = tmp; 04849 ast_mutex_unlock(&con->lock); 04850 if (tmp->priority == PRIORITY_HINT) 04851 ast_add_hint(tmp); 04852 } 04853 if (option_debug) { 04854 if (tmp->matchcid) { 04855 if (option_debug) 04856 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04857 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04858 } else { 04859 if (option_debug) 04860 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04861 tmp->exten, tmp->priority, con->name); 04862 } 04863 } 04864 if (option_verbose > 2) { 04865 if (tmp->matchcid) { 04866 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04867 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04868 } else { 04869 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04870 tmp->exten, tmp->priority, con->name); 04871 } 04872 } 04873 return 0; 04874 }
| int ast_async_goto | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 4572 of file pbx.c.
References ast_channel::_state, ast_channel::accountcode, ast_channel::amaflags, ast_cdr_discard(), ast_cdr_dup(), ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_unlock, ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_pbx_start(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_channel::cdr, ast_channel::context, ast_channel::exten, LOG_WARNING, ast_channel::name, ast_channel::pbx, ast_channel::readformat, S_OR, and ast_channel::writeformat.
Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), console_transfer_deprecated(), dahdi_handle_dtmfup(), handle_request_bye(), handle_request_refer(), process_ast_dsp(), and socket_process().
04573 { 04574 int res = 0; 04575 04576 ast_channel_lock(chan); 04577 04578 if (chan->pbx) { /* This channel is currently in the PBX */ 04579 ast_explicit_goto(chan, context, exten, priority); 04580 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04581 } else { 04582 /* In order to do it when the channel doesn't really exist within 04583 the PBX, we have to make a new channel, masquerade, and start the PBX 04584 at the new location */ 04585 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04586 if (!tmpchan) { 04587 res = -1; 04588 } else { 04589 if (chan->cdr) { 04590 ast_cdr_discard(tmpchan->cdr); 04591 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 04592 } 04593 /* Make formats okay */ 04594 tmpchan->readformat = chan->readformat; 04595 tmpchan->writeformat = chan->writeformat; 04596 /* Setup proper location */ 04597 ast_explicit_goto(tmpchan, 04598 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04599 04600 /* Masquerade into temp channel */ 04601 if (ast_channel_masquerade(tmpchan, chan)) { 04602 /* Failed to set up the masquerade. It's probably chan_local 04603 * in the middle of optimizing itself out. Sad. :( */ 04604 ast_hangup(tmpchan); 04605 tmpchan = NULL; 04606 res = -1; 04607 } else { 04608 /* Grab the locks and get going */ 04609 ast_channel_lock(tmpchan); 04610 ast_do_masquerade(tmpchan); 04611 ast_channel_unlock(tmpchan); 04612 /* Start the PBX going on our stolen channel */ 04613 if (ast_pbx_start(tmpchan)) { 04614 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04615 ast_hangup(tmpchan); 04616 res = -1; 04617 } 04618 } 04619 } 04620 } 04621 ast_channel_unlock(chan); 04622 return res; 04623 }
| int ast_async_goto_by_name | ( | const char * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 4625 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04626 { 04627 struct ast_channel *chan; 04628 int res = -1; 04629 04630 chan = ast_get_channel_by_name_locked(channame); 04631 if (chan) { 04632 res = ast_async_goto(chan, context, exten, priority); 04633 ast_channel_unlock(chan); 04634 } 04635 return res; 04636 }
| int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 6348 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06349 { 06350 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06351 }
| int ast_build_timing | ( | struct ast_timing * | i, | |
| const char * | info | |||
| ) |
Definition at line 4212 of file pbx.c.
References ast_copy_string(), ast_strlen_zero(), ast_timing::daymask, days, ast_timing::dowmask, get_range(), get_timerange(), ast_timing::monthmask, and months.
Referenced by ast_context_add_include2(), iftime(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
04213 { 04214 char info_save[256]; 04215 char *info; 04216 04217 /* Check for empty just in case */ 04218 if (ast_strlen_zero(info_in)) 04219 return 0; 04220 /* make a copy just in case we were passed a static string */ 04221 ast_copy_string(info_save, info_in, sizeof(info_save)); 04222 info = info_save; 04223 /* Assume everything except time */ 04224 i->monthmask = 0xfff; /* 12 bits */ 04225 i->daymask = 0x7fffffffU; /* 31 bits */ 04226 i->dowmask = 0x7f; /* 7 bits */ 04227 /* on each call, use strsep() to move info to the next argument */ 04228 get_timerange(i, strsep(&info, "|")); 04229 if (info) 04230 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04231 if (info) 04232 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04233 if (info) 04234 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04235 return 1; 04236 }
| int ast_canmatch_extension | ( | struct ast_channel * | c, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| const char * | callerid | |||
| ) |
Looks for a valid matching extension.
| c | not really important | |
| context | context to serach within | |
| exten | extension to check | |
| priority | priority of extension path | |
| callerid | callerid of extension being searched for |
Definition at line 2245 of file pbx.c.
References E_CANMATCH, and pbx_extension_helper().
Referenced by background_detect_exec(), cb_events(), do_immediate_setup(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), handle_link_data(), handle_link_phone_dtmf(), local_dtmf_helper(), loopback_canmatch(), mgcp_ss(), phone_check_exception(), skinny_ss(), ss_thread(), and valid_exit().
02246 { 02247 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH); 02248 }
| int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 4238 of file pbx.c.
References ast_localtime(), ast_log(), ast_timing::daymask, ast_timing::dowmask, LOG_WARNING, ast_timing::minmask, ast_timing::monthmask, and t.
Referenced by iftime(), include_valid(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
04239 { 04240 struct tm tm; 04241 time_t t = time(NULL); 04242 04243 ast_localtime(&t, &tm, NULL); 04244 04245 /* If it's not the right month, return */ 04246 if (!(i->monthmask & (1 << tm.tm_mon))) 04247 return 0; 04248 04249 /* If it's not that time of the month.... */ 04250 /* Warning, tm_mday has range 1..31! */ 04251 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04252 return 0; 04253 04254 /* If it's not the right day of the week */ 04255 if (!(i->dowmask & (1 << tm.tm_wday))) 04256 return 0; 04257 04258 /* Sanity check the hour just to be safe */ 04259 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04260 ast_log(LOG_WARNING, "Insane time...\n"); 04261 return 0; 04262 } 04263 04264 /* Now the tough part, we calculate if it fits 04265 in the right time based on min/hour */ 04266 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04267 return 0; 04268 04269 /* If we got this far, then we're good */ 04270 return 1; 04271 }
| int ast_context_add_ignorepat | ( | const char * | context, | |
| const char * | ignorepat, | |||
| const char * | registrar | |||
| ) |
Add an ignorepat.
| context | which context to add the ignorpattern to | |
| ignorepat | ignorepattern to set up for the extension | |
| registrar | registrar of the ignore pattern |
| 0 | on success | |
| -1 | on failure |
Definition at line 4465 of file pbx.c.
References ast_context_add_ignorepat2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_context_add_ignorepat(), and handle_context_add_ignorepat_deprecated().
04466 { 04467 int ret = -1; 04468 struct ast_context *c = find_context_locked(context); 04469 04470 if (c) { 04471 ret = ast_context_add_ignorepat2(c, value, registrar); 04472 ast_unlock_contexts(); 04473 } 04474 return ret; 04475 }
| int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
| const char * | ignorepat, | |||
| const char * | registrar | |||
| ) |
Definition at line 4477 of file pbx.c.
References ast_calloc, ast_mutex_lock(), ast_mutex_unlock(), errno, ast_context::ignorepats, ast_context::lock, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.
Referenced by ast_context_add_ignorepat(), and pbx_load_config().
04478 { 04479 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04480 int length; 04481 char *pattern; 04482 length = sizeof(struct ast_ignorepat); 04483 length += strlen(value) + 1; 04484 if (!(ignorepat = ast_calloc(1, length))) 04485 return -1; 04486 /* The cast to char * is because we need to write the initial value. 04487 * The field is not supposed to be modified otherwise. Also, gcc 4.2 04488 * sees the cast as dereferencing a type-punned pointer and warns about 04489 * it. This is the workaround (we're telling gcc, yes, that's really 04490 * what we wanted to do). 04491 */ 04492 pattern = (char *) ignorepat->pattern; 04493 strcpy(pattern, value); 04494 ignorepat->next = NULL; 04495 ignorepat->registrar = registrar; 04496 ast_mutex_lock(&con->lock); 04497 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04498 ignorepatl = ignorepatc; 04499 if (!strcasecmp(ignorepatc->pattern, value)) { 04500 /* Already there */ 04501 ast_mutex_unlock(&con->lock); 04502 errno = EEXIST; 04503 return -1; 04504 } 04505 } 04506 if (ignorepatl) 04507 ignorepatl->next = ignorepat; 04508 else 04509 con->ignorepats = ignorepat; 04510 ast_mutex_unlock(&con->lock); 04511 return 0; 04512 04513 }
| int ast_context_add_include | ( | const char * | context, | |
| const char * | include, | |||
| const char * | registrar | |||
| ) |
Add a context include.
| context | context to add include to | |
| include | new include to add | |
| registrar | who's registering it |
| 0 | on success | |
| -1 | on error |
Definition at line 4018 of file pbx.c.
References ast_context_add_include2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_context_add_include(), and handle_context_add_include_deprecated().
04019 { 04020 int ret = -1; 04021 struct ast_context *c = find_context_locked(context); 04022 04023 if (c) { 04024 ret = ast_context_add_include2(c, include, registrar); 04025 ast_unlock_contexts(); 04026 } 04027 return ret; 04028 }
| int ast_context_add_include2 | ( | struct ast_context * | con, | |
| const char * | include, | |||
| const char * | registrar | |||
| ) |
Add a context include.
| con | context to add the include to | |
| include | include to add | |
| registrar | who registered the context |
| 0 | on success | |
| -1 | on failure |
Definition at line 4280 of file pbx.c.
References ast_build_timing(), ast_calloc, ast_get_context_name(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), errno, free, ast_include::hastime, ast_context::includes, ast_context::lock, ast_include::name, ast_include::next, option_verbose, ast_include::registrar, ast_include::rname, ast_include::stuff, ast_include::timing, and VERBOSE_PREFIX_3.
Referenced by ast_context_add_include(), and pbx_load_config().
04282 { 04283 struct ast_include *new_include; 04284 char *c; 04285 struct ast_include *i, *il = NULL; /* include, include_last */ 04286 int length; 04287 char *p; 04288 04289 length = sizeof(struct ast_include); 04290 length += 2 * (strlen(value) + 1); 04291 04292 /* allocate new include structure ... */ 04293 if (!(new_include = ast_calloc(1, length))) 04294 return -1; 04295 /* Fill in this structure. Use 'p' for assignments, as the fields 04296 * in the structure are 'const char *' 04297 */ 04298 p = new_include->stuff; 04299 new_include->name = p; 04300 strcpy(p, value); 04301 p += strlen(value) + 1; 04302 new_include->rname = p; 04303 strcpy(p, value); 04304 /* Strip off timing info, and process if it is there */ 04305 if ( (c = strchr(p, '|')) ) { 04306 *c++ = '\0'; 04307 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04308 } 04309 new_include->next = NULL; 04310 new_include->registrar = registrar; 04311 04312 ast_mutex_lock(&con->lock); 04313 04314 /* ... go to last include and check if context is already included too... */ 04315 for (i = con->includes; i; i = i->next) { 04316 if (!strcasecmp(i->name, new_include->name)) { 04317 free(new_include); 04318 ast_mutex_unlock(&con->lock); 04319 errno = EEXIST; 04320 return -1; 04321 } 04322 il = i; 04323 } 04324 04325 /* ... include new context into context list, unlock, return */ 04326 if (il) 04327 il->next = new_include; 04328 else 04329 con->includes = new_include; 04330 if (option_verbose > 2) 04331 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04332 ast_mutex_unlock(&con->lock); 04333 04334 return 0; 04335 }
| int ast_context_add_switch | ( | const char * | context, | |
| const char * | sw, | |||
| const char * | data, | |||
| int | eval, | |||
| const char * | registrar | |||
| ) |
Add a switch.
| context | context to which to add the switch | |
| sw | switch to add | |
| data | data to pass to switch | |
| eval | whether to evaluate variables when running switch | |
| registrar | whoever registered the switch |
| 0 | on success | |
| -1 | on failure |
Definition at line 4342 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04343 { 04344 int ret = -1; 04345 struct ast_context *c = find_context_locked(context); 04346 04347 if (c) { /* found, add switch to this context */ 04348 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04349 ast_unlock_contexts(); 04350 } 04351 return ret; 04352 }
| int ast_context_add_switch2 | ( | struct ast_context * | con, | |
| const char * | sw, | |||
| const char * | data, | |||
| int | eval, | |||
| const char * | registrar | |||
| ) |
Adds a switch (first param is a ast_context).
Definition at line 4361 of file pbx.c.
References ast_context::alts, ast_calloc, ast_get_context_name(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_sw::data, errno, ast_sw::eval, free, store_hint::list, ast_context::lock, ast_sw::name, option_verbose, ast_sw::registrar, ast_sw::stuff, and VERBOSE_PREFIX_3.
Referenced by ast_context_add_switch(), and pbx_load_config().
04363 { 04364 struct ast_sw *new_sw; 04365 struct ast_sw *i; 04366 int length; 04367 char *p; 04368 04369 length = sizeof(struct ast_sw); 04370 length += strlen(value) + 1; 04371 if (data) 04372 length += strlen(data); 04373 length++; 04374 04375 /* allocate new sw structure ... */ 04376 if (!(new_sw = ast_calloc(1, length))) 04377 return -1; 04378 /* ... fill in this structure ... */ 04379 p = new_sw->stuff; 04380 new_sw->name = p; 04381 strcpy(new_sw->name, value); 04382 p += strlen(value) + 1; 04383 new_sw->data = p; 04384 if (data) { 04385 strcpy(new_sw->data, data); 04386 p += strlen(data) + 1; 04387 } else { 04388 strcpy(new_sw->data, ""); 04389 p++; 04390 } 04391 new_sw->eval = eval; 04392 new_sw->registrar = registrar; 04393 04394 /* ... try to lock this context ... */ 04395 ast_mutex_lock(&con->lock); 04396 04397 /* ... go to last sw and check if context is already swd too... */ 04398 AST_LIST_TRAVERSE(&con->alts, i, list) { 04399 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04400 free(new_sw); 04401 ast_mutex_unlock(&con->lock); 04402 errno = EEXIST; 04403 return -1; 04404 } 04405 } 04406 04407 /* ... sw new context into context list, unlock, return */ 04408 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04409 04410 if (option_verbose > 2) 04411 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04412 04413 ast_mutex_unlock(&con->lock); 04414 04415 return 0; 04416 }
| struct ast_context* ast_context_create | ( | struct ast_context ** | extcontexts, | |
| const char * | name, | |||
| const char * | registrar | |||
| ) |
Register a new context.
| extcontexts | pointer to the ast_context structure pointer | |
| name | name of the new context | |
| registrar | registrar of the context |
Definition at line 3888 of file pbx.c.
References __ast_context_create().
Referenced by do_parking_thread(), park_call_full(), and set_config().
03889 { 03890 return __ast_context_create(extcontexts, name, registrar, 0); 03891 }
| void ast_context_destroy | ( | struct ast_context * | con, | |
| const char * | registrar | |||
| ) |
Destroy a context (matches the specified context (or ANY context if NULL).
| con | context to destroy | |
| registrar | who registered it |
Definition at line 5330 of file pbx.c.
References __ast_context_destroy(), ast_unlock_contexts(), and ast_wrlock_contexts().
Referenced by cleanup_stale_contexts(), sla_destroy(), and unload_module().
05331 { 05332 ast_wrlock_contexts(); 05333 __ast_context_destroy(con,registrar); 05334 ast_unlock_contexts(); 05335 }
| struct ast_context* ast_context_find | ( | const char * | name | ) |
Find a context.
| name | name of the context to find |
Definition at line 895 of file pbx.c.
References ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::name.
Referenced by _macro_exec(), ast_context_verify_includes(), ast_ignore_pattern(), cleanup_stale_contexts(), do_parking_thread(), park_call_full(), park_exec(), register_peer_exten(), and set_config().
00896 { 00897 struct ast_context *tmp = NULL; 00898 00899 ast_rdlock_contexts(); 00900 00901 while ( (tmp = ast_walk_contexts(tmp)) ) { 00902 if (!name || !strcasecmp(name, tmp->name)) 00903 break; 00904 } 00905 00906 ast_unlock_contexts(); 00907 00908 return tmp; 00909 }
| struct ast_context* ast_context_find_or_create | ( | struct ast_context ** | extcontexts, | |
| const char * | name, | |||
| const char * | registrar | |||
| ) |
Definition at line 3893 of file pbx.c.
References __ast_context_create().
Referenced by pbx_load_config(), and pbx_load_users().
03894 { 03895 return __ast_context_create(extcontexts, name, registrar, 1); 03896 }
| int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 2858 of file pbx.c.
References ast_get_context_name(), ast_mutex_lock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::macrolock.
Referenced by _macro_exec().
02859 { 02860 struct ast_context *c = NULL; 02861 int ret = -1; 02862 02863 ast_rdlock_contexts(); 02864 02865 while ((c = ast_walk_contexts(c))) { 02866 if (!strcmp(ast_get_context_name(c), context)) { 02867 ret = 0; 02868 break; 02869 } 02870 } 02871 02872 ast_unlock_contexts(); 02873 02874 /* if we found context, lock macrolock */ 02875 if (ret == 0) 02876 ret = ast_mutex_lock(&c->macrolock); 02877 02878 return ret; 02879 }
| int ast_context_remove_extension | ( | const char * | context, | |
| const char * | extension, | |||
| int | priority, | |||
| const char * | registrar | |||
| ) |
Simply remove extension from context.
| context | context to remove extension from | |
| extension | which extension to remove | |
| priority | priority of extension to remove (0 to remove all) | |
| callerid | NULL to remove all; non-NULL to match a single record per priority | |
| matchcid | non-zero to match callerid element (if non-NULL); 0 to match default case | |
| registrar | registrar of the extension |
| 0 | on success | |
| -1 | on failure |
Definition at line 2759 of file pbx.c.
References ast_context_remove_extension_callerid().
Referenced by destroy_station(), destroy_trunk(), and register_peer_exten().
02760 { 02761 return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar); 02762 }
| 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 2786 of file pbx.c.
References ast_context_remove_extension_callerid2().
Referenced by do_parking_thread(), and park_exec().
02787 { 02788 return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar); 02789 }
| int ast_context_remove_extension_callerid | ( | const char * | context, | |
| const char * | extension, | |||
| int | priority, | |||
| const char * | callerid, | |||
| int | matchcid, | |||
| const char * | registrar | |||
| ) |
Definition at line 2764 of file pbx.c.
References ast_context_remove_extension_callerid2(), ast_unlock_contexts(), and find_context_locked().
Referenced by ast_context_remove_extension(), handle_context_remove_extension(), and handle_context_remove_extension_deprecated().
02765 { 02766 int ret = -1; /* default error return */ 02767 struct ast_context *c = find_context_locked(context); 02768 02769 if (c) { /* ... remove extension ... */ 02770 ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar); 02771 ast_unlock_contexts(); 02772 } 02773 return ret; 02774 }
| int ast_context_remove_extension_callerid2 | ( | struct ast_context * | con, | |
| const char * | extension, | |||
| int | priority, | |||
| const char * | callerid, | |||
| int | matchcid, | |||
| const char * | registrar | |||
| ) |
Definition at line 2791 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_exten::cidmatch, destroy_exten(), ast_exten::exten, exten, ast_context::lock, ast_exten::next, ast_exten::peer, ast_exten::priority, ast_exten::registrar, and ast_context::root.
Referenced by ast_context_remove_extension2(), and ast_context_remove_extension_callerid().
02792 { 02793 struct ast_exten *exten, *prev_exten = NULL; 02794 struct ast_exten *peer; 02795 struct ast_exten *previous_peer = NULL; 02796 struct ast_exten *next_peer = NULL; 02797 int found = 0; 02798 02799 ast_mutex_lock(&con->lock); 02800 02801 /* scan the extension list to find first matching extension-registrar */ 02802 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02803 if (!strcmp(exten->exten, extension) && 02804 (!registrar || !strcmp(exten->registrar, registrar))) 02805 break; 02806 } 02807 if (!exten) { 02808 /* we can't find right extension */ 02809 ast_mutex_unlock(&con->lock); 02810 return -1; 02811 } 02812 02813 /* scan the priority list to remove extension with exten->priority == priority */ 02814 for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next; 02815 peer && !strcmp(peer->exten, extension); 02816 peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) { 02817 if ((priority == 0 || peer->priority == priority) && 02818 (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) && 02819 (!registrar || !strcmp(peer->registrar, registrar) )) { 02820 found = 1; 02821 02822 /* we are first priority extension? */ 02823 if (!previous_peer) { 02824 /* 02825 * We are first in the priority chain, so must update the extension chain. 02826 * The next node is either the next priority or the next extension 02827 */ 02828 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02829 02830 if (!prev_exten) { /* change the root... */ 02831 con->root = next_node; 02832 } else { 02833 prev_exten->next = next_node; /* unlink */ 02834 } 02835 if (peer->peer) { /* update the new head of the pri list */ 02836 peer->peer->next = peer->next; 02837 } 02838 } else { /* easy, we are not first priority in extension */ 02839 previous_peer->peer = peer->peer; 02840 } 02841 02842 /* now, free whole priority extension */ 02843 destroy_exten(peer); 02844 } else { 02845 previous_peer = peer; 02846 } 02847 } 02848 ast_mutex_unlock(&con->lock); 02849 return found ? 0 : -1; 02850 }
| int ast_context_remove_ignorepat | ( | const char * | context, | |
| const char * | ignorepat, | |||
| const char * | registrar | |||
| ) |
Definition at line 4422 of file pbx.c.
References ast_context_remove_ignorepat2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_context_remove_ignorepat(), and handle_context_remove_ignorepat_deprecated().
04423 { 04424 int ret = -1; 04425 struct ast_context *c = find_context_locked(context); 04426 04427 if (c) { 04428 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04429 ast_unlock_contexts(); 04430 } 04431 return ret; 04432 }
| int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
| const char * | ignorepat, | |||
| const char * | registrar | |||
| ) |
Definition at line 4434 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), errno, free, ast_context::ignorepats, ast_context::lock, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.
Referenced by ast_context_remove_ignorepat().
04435 { 04436 struct ast_ignorepat *ip, *ipl = NULL; 04437 04438 ast_mutex_lock(&con->lock); 04439 04440 for (ip = con->ignorepats; ip; ip = ip->next) { 04441 if (!strcmp(ip->pattern, ignorepat) && 04442 (!registrar || (registrar == ip->registrar))) { 04443 if (ipl) { 04444 ipl->next = ip->next; 04445 free(ip); 04446 } else { 04447 con->ignorepats = ip->next; 04448 free(ip); 04449 } 04450 ast_mutex_unlock(&con->lock); 04451 return 0; 04452 } 04453 ipl = ip; 04454 } 04455 04456 ast_mutex_unlock(&con->lock); 04457 errno = EINVAL; 04458 return -1; 04459 }
| int ast_context_remove_include | ( | const char * | context, | |
| const char * | include, | |||
| const char * | registrar | |||
| ) |
Remove a context include.
| 0 | on success | |
| -1 | on failure |
Definition at line 2655 of file pbx.c.
References ast_context_remove_include2(), ast_unlock_contexts(), and find_context_locked().
Referenced by handle_context_dont_include_deprecated(), and handle_context_remove_include().
02656 { 02657 int ret = -1; 02658 struct ast_context *c = find_context_locked(context); 02659 02660 if (c) { 02661 /* found, remove include from this context ... */ 02662 ret = ast_context_remove_include2(c, include, registrar); 02663 ast_unlock_contexts(); 02664 } 02665 return ret; 02666 }
| int ast_context_remove_include2 | ( | struct ast_context * | con, | |
| const char * | include, | |||
| const char * | registrar | |||
| ) |
Removes an include by an ast_context structure.
| 0 | on success | |
| -1 | on success |
Definition at line 2676 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().
02677 { 02678 struct ast_include *i, *pi = NULL; 02679 int ret = -1; 02680 02681 ast_mutex_lock(&con->lock); 02682 02683 /* find our include */ 02684 for (i = con->includes; i; pi = i, i = i->next) { 02685 if (!strcmp(i->name, include) && 02686 (!registrar || !strcmp(i->registrar, registrar))) { 02687 /* remove from list */ 02688 if (pi) 02689 pi->next = i->next; 02690 else 02691 con->includes = i->next; 02692 /* free include and return */ 02693 free(i); 02694 ret = 0; 02695 break; 02696 } 02697 } 02698 02699 ast_mutex_unlock(&con->lock); 02700 return ret; 02701 }
| int ast_context_remove_switch | ( | const char * | context, | |
| const char * | sw, | |||
| const char * | data, | |||
| const char * | registrar | |||
| ) |
Remove a switch.
Definition at line 2708 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
02709 { 02710 int ret = -1; /* default error return */ 02711 struct ast_context *c = find_context_locked(context); 02712 02713 if (c) { 02714 /* remove switch from this context ... */ 02715 ret = ast_context_remove_switch2(c, sw, data, registrar); 02716 ast_unlock_contexts(); 02717 } 02718 return ret; 02719 }
| 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 2729 of file pbx.c.
References ast_context::alts, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), ast_sw::data, free, ast_sw::list, ast_context::lock, ast_sw::name, and ast_sw::registrar.
Referenced by ast_context_remove_switch().
02730 { 02731 struct ast_sw *i; 02732 int ret = -1; 02733 02734 ast_mutex_lock(&con->lock); 02735 02736 /* walk switches */ 02737 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02738 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02739 (!registrar || !strcmp(i->registrar, registrar))) { 02740 /* found, remove from list */ 02741 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02742 free(i); /* free switch and return */ 02743 ret = 0; 02744 break; 02745 } 02746 } 02747 AST_LIST_TRAVERSE_SAFE_END 02748 02749 ast_mutex_unlock(&con->lock); 02750 02751 return ret; 02752 }
| int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 2886 of file pbx.c.
References ast_get_context_name(), ast_mutex_unlock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::macrolock.
Referenced by _macro_exec().
02887 { 02888 struct ast_context *c = NULL; 02889 int ret = -1; 02890 02891 ast_rdlock_contexts(); 02892 02893 while ((c = ast_walk_contexts(c))) { 02894 if (!strcmp(ast_get_context_name(c), context)) { 02895 ret = 0; 02896 break; 02897 } 02898 } 02899 02900 ast_unlock_contexts(); 02901 02902 /* if we found context, unlock macrolock */ 02903 if (ret == 0) 02904 ret = ast_mutex_unlock(&c->macrolock); 02905 02906 return ret; 02907 }
| int ast_context_verify_includes | ( | struct ast_context * | con | ) |
Verifies includes in an ast_contect structure.
| con | context in which to verify the includes |
| 0 | if no problems found | |
| -1 | if there were any missing context |
Definition at line 6305 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().
06306 { 06307 struct ast_include *inc = NULL; 06308 int res = 0; 06309 06310 while ( (inc = ast_walk_context_includes(con, inc)) ) { 06311 if (ast_context_find(inc->rname)) 06312 continue; 06313 06314 res = -1; 06315 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 06316 ast_get_context_name(con), inc->rname); 06317 break; 06318 } 06319 06320 return res; 06321 }
| struct ast_custom_function* ast_custom_function_find | ( | const char * | name | ) |
Definition at line 1454 of file pbx.c.
References ast_custom_function::acflist, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_custom_function::name.
Referenced by ast_custom_function_register(), ast_func_read(), ast_func_write(), handle_show_function(), and handle_show_function_deprecated().
01455 { 01456 struct ast_custom_function *acf = NULL; 01457 01458 AST_LIST_LOCK(&acf_root); 01459 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01460 if (!strcmp(name, acf->name)) 01461 break; 01462 } 01463 AST_LIST_UNLOCK(&acf_root); 01464 01465 return acf; 01466 }
| int ast_custom_function_register | ( | struct ast_custom_function * | acf | ) |
Reigster a custom function.
Definition at line 1490 of file pbx.c.
References ast_custom_function::acflist, ast_custom_function_find(), AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), LOG_ERROR, ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by load_module(), odbc_load_module(), and reload().
01491 { 01492 struct ast_custom_function *cur; 01493 01494 if (!acf) 01495 return -1; 01496 01497 AST_LIST_LOCK(&acf_root); 01498 01499 if (ast_custom_function_find(acf->name)) { 01500 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01501 AST_LIST_UNLOCK(&acf_root); 01502 return -1; 01503 } 01504 01505 /* Store in alphabetical order */ 01506 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01507 if (strcasecmp(acf->name, cur->name) < 0) { 01508 AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist); 01509 break; 01510 } 01511 } 01512 AST_LIST_TRAVERSE_SAFE_END 01513 if (!cur) 01514 AST_LIST_INSERT_TAIL(&acf_root, acf, acflist); 01515 01516 AST_LIST_UNLOCK(&acf_root); 01517 01518 if (option_verbose > 1) 01519 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01520 01521 return 0; 01522 }
| int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Unregister a custom function.
Definition at line 1468 of file pbx.c.
References ast_custom_function::acflist, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by odbc_unload_module(), reload(), and unload_module().
01469 { 01470 struct ast_custom_function *cur; 01471 01472 if (!acf) 01473 return -1; 01474 01475 AST_LIST_LOCK(&acf_root); 01476 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01477 if (cur == acf) { 01478 AST_LIST_REMOVE_CURRENT(&acf_root, acflist); 01479 if (option_verbose > 1) 01480 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01481 break; 01482 } 01483 } 01484 AST_LIST_TRAVERSE_SAFE_END 01485 AST_LIST_UNLOCK(&acf_root); 01486 01487 return acf ? 0 : -1; 01488 }
| int ast_exists_extension | ( | struct ast_channel * | c, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| const char * | callerid | |||
| ) |
Determine whether an extension exists.
| c | this is not important | |
| context | which context to look in | |
| exten | which extension to search for | |
| priority | priority of the action within the extension | |
| callerid | callerid to search for |
Definition at line 2230 of file pbx.c.
References E_MATCH, and pbx_extension_helper().
Referenced by __ast_goto_if_exists(), __ast_pbx_run(), __login_exec(), _macro_exec(), agentmonitoroutgoing_exec(), answer_call(), ast_app_dtget(), ast_bridge_call(), ast_pbx_outgoing_exten(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), conf_run(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), dahdi_handle_dtmfup(), disa_exec(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), handle_stimulus_message(), leave_voicemail(), local_alloc(), local_call(), local_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), misdn_overlap_dial_task(), park_space_reserve(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), process_ast_dsp(), register_peer_exten(), skinny_ss(), socket_process(), ss_thread(), and waitstream_core().
02231 { 02232 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH); 02233 }
| int ast_explicit_goto | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 4549 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_FLAG_IN_AUTOLOOP, ast_strlen_zero(), ast_test_flag, ast_channel::context, ast_channel::exten, and ast_channel::priority.
Referenced by __ast_goto_if_exists(), ast_async_goto(), ast_parseable_goto(), builtin_atxfer(), disa_exec(), and handle_setpriority().
04550 { 04551 if (!chan) 04552 return -1; 04553 04554 ast_channel_lock(chan); 04555 04556 if (!ast_strlen_zero(context)) 04557 ast_copy_string(chan->context, context, sizeof(chan->context)); 04558 if (!ast_strlen_zero(exten)) 04559 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04560 if (priority > -1) { 04561 chan->priority = priority; 04562 /* see flag description in channel.h for explanation */ 04563 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04564 chan->priority--; 04565 } 04566 04567 ast_channel_unlock(chan); 04568 04569 return 0; 04570 }
| int ast_extension_close | ( | const char * | pattern, | |
| const char * | data, | |||
| int | needmore | |||
| ) |
Definition at line 888 of file pbx.c.
References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.
Referenced by realtime_switch_common().
00889 { 00890 if (needmore != E_MATCHMORE && needmore != E_CANMATCH) 00891 ast_log(LOG_WARNING, "invalid argument %d\n", needmore); 00892 return extension_match_core(pattern, data, needmore); 00893 }
| int ast_extension_match | ( | const char * | pattern, | |
| const char * | extension | |||
| ) |
Determine if a given extension matches a given pattern (in NXX format).
| pattern | pattern to match | |
| extension | extension to check against the pattern. |
| 1 | on match | |
| 0 | on failure |
Definition at line 883 of file pbx.c.
References E_MATCH, and extension_match_core().
Referenced by ast_ignore_pattern(), do_say(), find_matching_priority(), loopback_canmatch(), loopback_exists(), loopback_matchmore(), matchcid(), misdn_cfg_is_msn_valid(), realtime_switch_common(), and show_dialplan_helper().
00884 { 00885 return extension_match_core(pattern, data, E_MATCH); 00886 }
| int ast_extension_patmatch | ( | const char * | pattern, | |
| const char * | data | |||
| ) |
| int ast_extension_state | ( | struct ast_channel * | c, | |
| const char * | context, | |||
| const char * | exten | |||
| ) |
Uses hint and devicestate callback to get the state of an extension.
| c | this is not important | |
| context | which context to look in | |
| exten | which extension to get state |
Definition at line 1952 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), and handle_request_subscribe().
01953 { 01954 struct ast_exten *e; 01955 01956 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 01957 if (!e) 01958 return -1; /* No hint, return -1 */ 01959 01960 return ast_extension_state2(e); /* Check all devices in the hint */ 01961 }
| const char* ast_extension_state2str | ( | int | extension_state | ) |
Return string representation of the state of an extension.
| extension_state | is the numerical state delivered by ast_extension_state |
Definition at line 1940 of file pbx.c.
References extension_states.
Referenced by cb_extensionstate(), handle_request_subscribe(), and handle_show_hints().
01941 { 01942 int i; 01943 01944 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 01945 if (extension_states[i].extension_state == extension_state) 01946 return extension_states[i].text; 01947 } 01948 return "Unknown"; 01949 }
| int ast_extension_state_add | ( | const char * | context, | |
| const char * | exten, | |||
| ast_state_cb_type | callback, | |||
| void * | data | |||
| ) |
Registers a state change callback.
| context | which context to look in | |
| exten | which extension to get state | |
| callback | callback to call if state changed | |
| data | to pass to callback |
| -1 | on failure | |
| ID | on success |
Definition at line 2009 of file pbx.c.
References ast_calloc, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_state_cb::callback, ast_state_cb::data, ast_state_cb::next, and statecbs.
Referenced by handle_request_subscribe(), and init_manager().
02011 { 02012 struct ast_hint *hint; 02013 struct ast_state_cb *cblist; 02014 struct ast_exten *e; 02015 02016 /* If there's no context and extension: add callback to statecbs list */ 02017 if (!context && !exten) { 02018 AST_LIST_LOCK(&hints); 02019 02020 for (cblist = statecbs; cblist; cblist = cblist->next) { 02021 if (cblist->callback == callback) { 02022 cblist->data = data; 02023 AST_LIST_UNLOCK(&hints); 02024 return 0; 02025 } 02026 } 02027 02028 /* Now insert the callback */ 02029 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02030 AST_LIST_UNLOCK(&hints); 02031 return -1; 02032 } 02033 cblist->id = 0; 02034 cblist->callback = callback; 02035 cblist->data = data; 02036 02037 cblist->next = statecbs; 02038 statecbs = cblist; 02039 02040 AST_LIST_UNLOCK(&hints); 02041 return 0; 02042 } 02043 02044 if (!context || !exten) 02045 return -1; 02046 02047 /* This callback type is for only one hint, so get the hint */ 02048 e = ast_hint_extension(NULL, context, exten); 02049 if (!e) { 02050 return -1; 02051 } 02052 02053 /* Find the hint in the list of hints */ 02054 AST_LIST_LOCK(&hints); 02055 02056 AST_LIST_TRAVERSE(&hints, hint, list) { 02057 if (hint->exten == e) 02058 break; 02059 } 02060 02061 if (!hint) { 02062 /* We have no hint, sorry */ 02063 AST_LIST_UNLOCK(&hints); 02064 return -1; 02065 } 02066 02067 /* Now insert the callback in the callback list */ 02068 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02069 AST_LIST_UNLOCK(&hints); 02070 return -1; 02071 } 02072 cblist->id = stateid++; /* Unique ID for this callback */ 02073 cblist->callback = callback; /* Pointer to callback routine */ 02074 cblist->data = data; /* Data for the callback */ 02075 02076 cblist->next = hint->callbacks; 02077 hint->callbacks = cblist; 02078 02079 AST_LIST_UNLOCK(&hints); 02080 return cblist->id; 02081 }
| int ast_extension_state_del | ( | int | id, | |
| ast_state_cb_type | callback | |||
| ) |
Deletes a registered state change callback by ID.
| id | of the callback to delete | |
| callback | callback |
| 0 | success | |
| -1 | failure |
Definition at line 2084 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_hint::callbacks, free, ast_sw::list, ast_state_cb::next, and statecbs.
Referenced by __sip_destroy(), and handle_request_subscribe().
02085 { 02086 struct ast_state_cb **p_cur = NULL; /* address of pointer to us */ 02087 int ret = -1; 02088 02089 if (!id && !callback) 02090 return -1; 02091 02092 AST_LIST_LOCK(&hints); 02093 02094 if (!id) { /* id == 0 is a callback without extension */ 02095 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) { 02096 if ((*p_cur)->callback == callback) 02097 break; 02098 } 02099 } else { /* callback with extension, find the callback based on ID */ 02100 struct ast_hint *hint; 02101 AST_LIST_TRAVERSE(&hints, hint, list) { 02102 for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) { 02103 if ((*p_cur)->id == id) 02104 break; 02105 } 02106 if (*p_cur) /* found in the inner loop */ 02107 break; 02108 } 02109 } 02110 if (p_cur && *p_cur) { 02111 struct ast_state_cb *cur = *p_cur; 02112 *p_cur = cur->next; 02113 free(cur); 02114 ret = 0; 02115 } 02116 AST_LIST_UNLOCK(&hints); 02117 return ret; 02118 }
| int ast_findlabel_extension | ( | struct ast_channel * | c, | |
| const char * | context, | |||
| const char * | exten, | |||
| const char * | label, | |||
| const char * | callerid | |||
| ) |
Find the priority of an extension that has the specified label.
| c | this is not important | |
| context | which context to look in | |
| exten | which extension to search for | |
| label | label of the action within the extension to match to priority | |
| callerid | callerid to search for |
Definition at line 2235 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by action_originate(), action_redirect(), ast_parseable_goto(), asyncgoto_exec(), and handle_setpriority().
02236 { 02237 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL); 02238 }
| int ast_findlabel_extension2 | ( | struct ast_channel * | c, | |
| struct ast_context * | con, | |||
| const char * | exten, | |||
| const char * | label, | |||
| const char * | callerid | |||
| ) |
Find the priority of an extension that has the specified label.
This function is the same as ast_findlabel_extension, except that it accepts a pointer to an ast_context structure to specify the context instead of the name of the context. Otherwise, the functions behave the same.
Definition at line 2240 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
02241 { 02242 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL); 02243 }
| int ast_func_read | ( | struct ast_channel * | chan, | |
| char * | function, | |||
| char * | workspace, | |||
| size_t | len | |||
| ) |
executes a read operation on a function
| chan | Channel to execute on | |
| function | Data containing the function call string (will be modified) | |
| workspace | A pointer to safe memory to use for a return value | |
| len | the number of bytes in workspace |
Definition at line 1544 of file pbx.c.
References ast_custom_function_find(), ast_log(), func_args(), LOG_ERROR, and ast_custom_function::read.
Referenced by action_getvar(), handle_getvariable(), and pbx_substitute_variables_helper_full().
01545 { 01546 char *args = func_args(function); 01547 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01548 01549 if (acfptr == NULL) 01550 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01551 else if (!acfptr->read) 01552 ast_log(LOG_ERROR, "Function %s cannot be read\n", function); 01553 else 01554 return acfptr->read(chan, function, args, workspace, len); 01555 return -1; 01556 }
| int ast_func_write | ( | struct ast_channel * | chan, | |
| char * | function, | |||
| const char * | value | |||
| ) |
executes a write operation on a function
| chan | Channel to execute on | |
| function | Data containing the function call string (will be modified) | |
| value | A value parameter to pass for writing |
Definition at line 1558 of file pbx.c.
References ast_custom_function_find(), ast_log(), func_args(), LOG_ERROR, and ast_custom_function::write.
Referenced by pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().
01559 { 01560 char *args = func_args(function); 01561 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01562 01563 if (acfptr == NULL) 01564 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01565 else if (!acfptr->write) 01566 ast_log(LOG_ERROR, "Function %s cannot be written to\n", function); 01567 else 01568 return acfptr->write(chan, function, args, value); 01569 01570 return -1; 01571 }
| const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 6162 of file pbx.c.
References ast_context::name.
Referenced by _macro_exec(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_context_verify_includes(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper().
06163 { 06164 return con ? con->name : NULL; 06165 }
| const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 6200 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06201 { 06202 return c ? c->registrar : NULL; 06203 }
| const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6230 of file pbx.c.
References ast_exten::app.
Referenced by _macro_exec(), ast_add_hint(), ast_extension_state2(), ast_get_hint(), ast_hint_state_changed(), find_matching_endwhile(), handle_save_dialplan(), handle_show_hints(), and print_ext().
06231 { 06232 return e ? e->app : NULL; 06233 }
| void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6235 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06236 { 06237 return e ? e->data : NULL; 06238 }
| const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6225 of file pbx.c.
References ast_exten::cidmatch.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), and handle_save_dialplan().
06226 { 06227 return e ? e->cidmatch : NULL; 06228 }
| struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
| const char* ast_get_extension_label | ( | struct ast_exten * | e | ) |
Definition at line 6177 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 6220 of file pbx.c.
References ast_exten::matchcid.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), and handle_save_dialplan().
06221 { 06222 return e ? e->matchcid : 0; 06223 }
| const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6172 of file pbx.c.
References exten.
Referenced by ast_add_hint(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), dundi_precache_full(), find_matching_priority(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper().
| int ast_get_extension_priority | ( | struct ast_exten * | exten | ) |
Definition at line 6192 of file pbx.c.
References exten.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), handle_save_dialplan(), and print_ext().
| const char* ast_get_extension_registrar | ( | struct ast_exten * | e | ) |
Definition at line 6205 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06206 { 06207 return e ? e->registrar : NULL; 06208 }
| int ast_get_hint | ( | char * | hint, | |
| int | maxlen, | |||
| char * | name, | |||
| int | maxnamelen, | |||
| struct ast_channel * | c, | |||
| const char * | context, | |||
| const char * | exten | |||
| ) |
If an extension exists, return non-zero.
| hint | buffer for hint | |
| maxlen | size of hint buffer | |
| name | buffer for name portion of hint | |
| maxnamelen | size of name buffer | |
| c | this is not important | |
| context | which context to look in | |
| exten | which extension to search for |
Definition at line 2213 of file pbx.c.
References ast_copy_string(), ast_get_extension_app(), ast_get_extension_app_data(), and ast_hint_extension().
Referenced by action_extensionstate(), get_cid_name(), get_destination(), pbx_retrieve_variable(), and transmit_state_notify().
02214 { 02215 struct ast_exten *e = ast_hint_extension(c, context, exten); 02216 02217 if (e) { 02218 if (hint) 02219 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02220 if (name) { 02221 const char *tmp = ast_get_extension_app_data(e); 02222 if (tmp) 02223 ast_copy_string(name, tmp, namesize); 02224 } 02225 return -1; 02226 } 02227 return 0; 02228 }
| const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6187 of file pbx.c.
References ast_ignorepat::pattern.
Referenced by complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), handle_save_dialplan(), lookup_c_ip(), and show_dialplan_helper().
06188 { 06189 return ip ? ip->pattern : NULL; 06190 }
| const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6215 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06216 { 06217 return ip ? ip->registrar : NULL; 06218 }
| const char* ast_get_include_name | ( | struct ast_include * | include | ) |
Definition at line 6182 of file pbx.c.
References ast_include::name.
Referenced by complete_context_dont_include_deprecated(), complete_context_remove_include(), find_matching_priority(), handle_save_dialplan(), lookup_ci(), and show_dialplan_helper().
| const char* ast_get_include_registrar | ( | struct ast_include * | i | ) |
Definition at line 6210 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06211 { 06212 return i ? i->registrar : NULL; 06213 }
| const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6245 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06246 { 06247 return sw ? sw->data : NULL; 06248 }
| const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6240 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06241 { 06242 return sw ? sw->name : NULL; 06243 }
| const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6250 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06251 { 06252 return sw ? sw->registrar : NULL; 06253 }
| int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 6343 of file pbx.c.
References __ast_goto_if_exists().
Referenced by aqm_exec(), background_detect_exec(), chanavail_exec(), conf_run(), controlplayback_exec(), do_directory(), hasvoicemail_exec(), leave_voicemail(), lookupblacklist_exec(), onedigit_goto(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), play_mailbox_owner(), playback_exec(), pqm_exec(), privacy_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), system_exec_helper(), transfer_exec(), upqm_exec(), valid_exit(), vm_box_exists(), vm_exec(), and wait_for_answer().
06344 { 06345 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06346 }
| void ast_hint_state_changed | ( | const char * | device | ) |
Definition at line 1963 of file pbx.c.
References ast_copy_string(), ast_extension_state2(), ast_get_extension_app(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, AST_MAX_EXTENSION, ast_rdlock_contexts(), ast_unlock_contexts(), ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_exten::exten, ast_hint::exten, ast_hint::laststate, ast_sw::list, ast_context::name, ast_state_cb::next, ast_exten::parent, parse(), and statecbs.
Referenced by do_state_change().
01964 { 01965 struct ast_hint *hint; 01966 01967 ast_rdlock_contexts(); 01968 AST_LIST_LOCK(&hints); 01969 01970 AST_LIST_TRAVERSE(&hints, hint, list) { 01971 struct ast_state_cb *cblist; 01972 char buf[AST_MAX_EXTENSION]; 01973 char *parse = buf; 01974 char *cur; 01975 int state; 01976 01977 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 01978 while ( (cur = strsep(&parse, "&")) ) { 01979 if (!strcasecmp(cur, device)) 01980 break; 01981 } 01982 if (!cur) 01983 continue; 01984 01985 /* Get device state for this hint */ 01986 state = ast_extension_state2(hint->exten); 01987 01988 if ((state == -1) || (state == hint->laststate)) 01989 continue; 01990 01991 /* Device state changed since last check - notify the watchers */ 01992 01993 /* For general callbacks */ 01994 for (cblist = statecbs; cblist; cblist = cblist->next) 01995 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 01996 01997 /* For extension callbacks */ 01998 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 01999 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02000 02001 hint->laststate = state; /* record we saw the change */ 02002 } 02003 02004 AST_LIST_UNLOCK(&hints); 02005 ast_unlock_contexts(); 02006 }
| int ast_ignore_pattern | ( | const char * | context, | |
| const char * | pattern | |||
| ) |
Checks to see if a number should be ignored.
| context | context to search within | |
| pattern | to check whether it should be ignored or not |
| 0 | if the pattern should not be ignored | |
| non-zero | if the pattern should be ignored |
Definition at line 4515 of file pbx.c.
References ast_context_find(), ast_extension_match(), ast_context::ignorepats, ast_ignorepat::next, and ast_ignorepat::pattern.
Referenced by ast_app_dtget(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_enbloc_call_message(), handle_soft_key_event_message(), handle_stimulus_message(), mgcp_ss(), skinny_ss(), and ss_thread().
04516 { 04517 struct ast_context *con = ast_context_find(context); 04518 if (con) { 04519 struct ast_ignorepat *pat; 04520 for (pat = con->ignorepats; pat; pat = pat->next) { 04521 if (ast_extension_match(pat->pattern, pattern)) 04522 return 1; 04523 } 04524 } 04525 04526 return 0; 04527 }
| int ast_lock_context | ( | struct ast_context * | con | ) |
Locks a given context.
| con | context to lock |
| 0 | on success | |
| -1 | on failure |
Definition at line 6149 of file pbx.c.
References ast_mutex_lock(), and ast_context::lock.
Referenced by _macro_exec(), complete_context_dont_include_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), lookup_c_ip(), lookup_ci(), and show_dialplan_helper().
06150 { 06151 return ast_mutex_lock(&con->lock); 06152 }
| int ast_lock_contexts | ( | void | ) |
Locks the context list.
| 0 | on success | |
| -1 | on error |
Definition at line 6126 of file pbx.c.
References ast_rwlock_wrlock(), and conlock.
Referenced by find_matching_endwhile().
06127 { 06128 return ast_rwlock_wrlock(&conlock); 06129 }
| int ast_matchmore_extension | ( | struct ast_channel * | c, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| const char * | callerid | |||
| ) |
Looks to see if adding anything to this extension might match something. (exists ^ canmatch).
| c | not really important XXX | |
| context | context to serach within | |
| exten | extension to check | |
| priority | priority of extension path | |
| callerid | callerid of extension being searched for |
Definition at line 2250 of file pbx.c.
References E_MATCHMORE, and pbx_extension_helper().
Referenced by ast_app_dtget(), collect_digits(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_stimulus_message(), loopback_matchmore(), mgcp_ss(), pbx_builtin_background(), skinny_ss(), and ss_thread().
02251 { 02252 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE); 02253 }
| void ast_merge_contexts_and_delete | ( | struct ast_context ** | extcontexts, | |
| const char * | registrar | |||
| ) |
Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added.
| extcontexts | pointer to the ast_context structure pointer | |
| registrar | of the context; if it's set the routine will delete all contexts that belong to that registrar; if NULL only the contexts that are specified in extcontexts |
Definition at line 3911 of file pbx.c.
References __ast_context_destroy(), ast_calloc, AST_EXTENSION_REMOVED, AST_LIST_HEAD_INIT_VALUE, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_unlock_contexts(), ast_wrlock_contexts(), ast_state_cb::callback, store_hint::callbacks, ast_hint::callbacks, store_hint::context, contexts, ast_state_cb::data, E_MATCH, store_hint::exten, ast_exten::exten, ast_hint::exten, free, ast_hint::laststate, store_hint::laststate, store_hint::list, LOG_WARNING, ast_context::name, ast_state_cb::next, ast_context::next, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_context::registrar, and pbx_find_info::stacklen.
Referenced by pbx_load_module().
03912 { 03913 struct ast_context *tmp, *lasttmp = NULL; 03914 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 03915 struct store_hint *this; 03916 struct ast_hint *hint; 03917 struct ast_exten *exten; 03918 int length; 03919 struct ast_state_cb *thiscb, *prevcb; 03920 03921 /* it is very important that this function hold the hint list lock _and_ the conlock 03922 during its operation; not only do we need to ensure that the list of contexts 03923 and extensions does not change, but also that no hint callbacks (watchers) are 03924 added or removed during the merge/delete process 03925 03926 in addition, the locks _must_ be taken in this order, because there are already 03927 other code paths that use this order 03928 */ 03929 ast_wrlock_contexts(); 03930 AST_LIST_LOCK(&hints); 03931 03932 /* preserve all watchers for hints associated with this registrar */ 03933 AST_LIST_TRAVERSE(&hints, hint, list) { 03934 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03935 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03936 if (!(this = ast_calloc(1, length))) 03937 continue; 03938 this->callbacks = hint->callbacks; 03939 hint->callbacks = NULL; 03940 this->laststate = hint->laststate; 03941 this->context = this->data; 03942 strcpy(this->data, hint->exten->parent->name); 03943 this->exten = this->data + strlen(this->context) + 1; 03944 strcpy(this->exten, hint->exten->exten); 03945 AST_LIST_INSERT_HEAD(&store, this, list); 03946 } 03947 } 03948 03949 tmp = *extcontexts; 03950 if (registrar) { 03951 /* XXX remove previous contexts from same registrar */ 03952 if (option_debug) 03953 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 03954 __ast_context_destroy(NULL,registrar); 03955 while (tmp) { 03956 lasttmp = tmp; 03957 tmp = tmp->next; 03958 } 03959 } else { 03960 /* XXX remove contexts with the same name */ 03961 while (tmp) { 03962 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 03963 __ast_context_destroy(tmp,tmp->registrar); 03964 lasttmp = tmp; 03965 tmp = tmp->next; 03966 } 03967 } 03968 if (lasttmp) { 03969 lasttmp->next = contexts; 03970 contexts = *extcontexts; 03971 *extcontexts = NULL; 03972 } else 03973 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 03974 03975 /* restore the watchers for hints that can be found; notify those that 03976 cannot be restored 03977 */ 03978 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 03979 struct pbx_find_info q = { .stacklen = 0 }; 03980 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 03981 /* Find the hint in the list of hints */ 03982 AST_LIST_TRAVERSE(&hints, hint, list) { 03983 if (hint->exten == exten) 03984 break; 03985 } 03986 if (!exten || !hint) { 03987 /* this hint has been removed, notify the watchers */ 03988 prevcb = NULL; 03989 thiscb = this->callbacks; 03990 while (thiscb) { 03991 prevcb = thiscb; 03992 thiscb = thiscb->next; 03993 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 03994 free(prevcb); 03995 } 03996 } else { 03997 thiscb = this->callbacks; 03998 while (thiscb->next) 03999 thiscb = thiscb->next; 04000 thiscb->next = hint->callbacks; 04001 hint->callbacks = this->callbacks; 04002 hint->laststate = this->laststate; 04003 } 04004 free(this); 04005 } 04006 04007 AST_LIST_UNLOCK(&hints); 04008 ast_unlock_contexts(); 04009 04010 return; 04011 }
| int ast_parseable_goto | ( | struct ast_channel * | chan, | |
| const char * | goto_string | |||
| ) |
This function will handle locking the channel as needed.
Definition at line 6353 of file pbx.c.
References ast_explicit_goto(), ast_findlabel_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, LOG_WARNING, and ast_channel::priority.
Referenced by _while_exec(), check_goto_on_transfer(), gosub_exec(), ivr_dispatch(), pbx_builtin_goto(), random_exec(), return_exec(), and while_continue_exec().
06354 { 06355 char *exten, *pri, *context; 06356 char *stringp; 06357 int ipri; 06358 int mode = 0; 06359 06360 if (ast_strlen_zero(goto_string)) { 06361 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06362 return -1; 06363 } 06364 stringp = ast_strdupa(goto_string); 06365 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06366 exten = strsep(&stringp, "|"); 06367 pri = strsep(&stringp, "|"); 06368 if (!exten) { /* Only a priority in this one */ 06369 pri = context; 06370 exten = NULL; 06371 context = NULL; 06372 } else if (!pri) { /* Only an extension and priority in this one */ 06373 pri = exten; 06374 exten = context; 06375 context = NULL; 06376 } 06377 if (*pri == '+') { 06378 mode = 1; 06379 pri++; 06380 } else if (*pri == '-') { 06381 mode = -1; 06382 pri++; 06383 } 06384 if (sscanf(pri, "%d", &ipri) != 1) { 06385 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06386 pri, chan->cid.cid_num)) < 1) { 06387 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06388 return -1; 06389 } else 06390 mode = 0; 06391 } 06392 /* At this point we have a priority and maybe an extension and a context */ 06393 06394 if (mode) 06395 ipri = chan->priority + (ipri * mode); 06396 06397 ast_explicit_goto(chan, context, exten, ipri); 06398 return 0; 06399 06400 }
| int ast_pbx_outgoing_app | ( | const char * | type, | |
| int | format, | |||
| void * | data, | |||
| int | timeout, | |||
| const char * | app, | |||
| const char * | appdata, | |||
| int * | reason, | |||
| int | sync, | |||
| const char * | cid_num, | |||
| const char * | cid_name, | |||
| struct ast_variable * | vars, | |||
| const char * | account, | |||
| struct ast_channel ** | locked_channel | |||
| ) |
Synchronously or asynchronously make an outbound call and send it to a particular application with given extension
Definition at line 5142 of file pbx.c.
References __ast_request_and_dial(), ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), async_stat::chan, errno, free, LOG_WARNING, option_verbose, outgoing_helper::vars, and VERBOSE_PREFIX_4.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_app().
05143 { 05144 struct ast_channel *chan; 05145 struct app_tmp *tmp; 05146 int res = -1, cdr_res = -1; 05147 struct outgoing_helper oh; 05148 pthread_attr_t attr; 05149 05150 memset(&oh, 0, sizeof(oh)); 05151 oh.vars = vars; 05152 oh.account = account; 05153 05154 if (locked_channel) 05155 *locked_channel = NULL; 05156 if (ast_strlen_zero(app)) { 05157 res = -1; 05158 goto outgoing_app_cleanup; 05159 } 05160 if (sync) { 05161 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05162 if (chan) { 05163 ast_set_variables(chan, vars); 05164 if (account) 05165 ast_cdr_setaccount(chan, account); 05166 if (chan->_state == AST_STATE_UP) { 05167 res = 0; 05168 if (option_verbose > 3) 05169 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05170 tmp = ast_calloc(1, sizeof(*tmp)); 05171 if (!tmp) 05172 res = -1; 05173 else { 05174 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05175 if (appdata) 05176 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05177 tmp->chan = chan; 05178 if (sync > 1) { 05179 if (locked_channel) 05180 ast_channel_unlock(chan); 05181 ast_pbx_run_app(tmp); 05182 } else { 05183 pthread_attr_init(&attr); 05184 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05185 if (locked_channel) 05186 ast_channel_lock(chan); 05187 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05188 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05189 free(tmp); 05190 if (locked_channel) 05191 ast_channel_unlock(chan); 05192 ast_hangup(chan); 05193 res = -1; 05194 } else { 05195 if (locked_channel) 05196 *locked_channel = chan; 05197 } 05198 pthread_attr_destroy(&attr); 05199 } 05200 } 05201 } else { 05202 if (option_verbose > 3) 05203 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05204 if (chan->cdr) { /* update the cdr */ 05205 /* here we update the status of the call, which sould be busy. 05206 * if that fails then we set the status to failed */ 05207 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05208 ast_cdr_failed(chan->cdr); 05209 } 05210 ast_hangup(chan); 05211 } 05212 } 05213 05214 if (res < 0) { /* the call failed for some reason */ 05215 if (*reason == 0) { /* if the call failed (not busy or no answer) 05216 * update the cdr with the failed message */ 05217 cdr_res = ast_pbx_outgoing_cdr_failed(); 05218 if (cdr_res != 0) { 05219 res = cdr_res; 05220 goto outgoing_app_cleanup; 05221 } 05222 } 05223 } 05224 05225 } else { 05226 struct async_stat *as; 05227 if (!(as = ast_calloc(1, sizeof(*as)))) { 05228 res = -1; 05229 goto outgoing_app_cleanup; 05230 } 05231 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05232 if (!chan) { 05233 free(as); 05234 res = -1; 05235 goto outgoing_app_cleanup; 05236 } 05237 as->chan = chan; 05238 ast_copy_string(as->app, app, sizeof(as->app)); 05239 if (appdata) 05240 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05241 as->timeout = timeout; 05242 ast_set_variables(chan, vars); 05243 if (account) 05244 ast_cdr_setaccount(chan, account); 05245 /* Start a new thread, and get something handling this channel. */ 05246 pthread_attr_init(&attr); 05247 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05248 if (locked_channel) 05249 ast_channel_lock(chan); 05250 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05251 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05252 free(as); 05253 if (locked_channel) 05254 ast_channel_unlock(chan); 05255 ast_hangup(chan); 05256 res = -1; 05257 pthread_attr_destroy(&attr); 05258 goto outgoing_app_cleanup; 05259 } else { 05260 if (locked_channel) 05261 *locked_channel = chan; 05262 } 05263 pthread_attr_destroy(&attr); 05264 res = 0; 05265 } 05266 outgoing_app_cleanup: 05267 ast_variables_destroy(vars); 05268 return res; 05269 }
| int ast_pbx_outgoing_exten | ( | const char * | type, | |
| int | format, | |||
| void * | data, | |||
| int | timeout, | |||
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| int * | reason, | |||
| int | sync, | |||
| const char * | cid_num, | |||
| const char * | cid_name, | |||
| struct ast_variable * | vars, | |||
| const char * | account, | |||
| struct ast_channel ** | locked_channel | |||
| ) |
Synchronously or asynchronously make an outbound call and send it to a particular extension
Definition at line 4976 of file pbx.c.
References __ast_request_and_dial(), ast_channel::_state, ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_alloc(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_exists_extension(), ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create, ast_request_and_dial(), ast_set_variables(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, ast_channel::context, free, ast_channel::hangupcause, LOAD_OH, LOG_ERROR, LOG_WARNING, ast_channel::name, option_verbose, pbx_builtin_setvar_helper(), set_ext_pri(), outgoing_helper::vars, and VERBOSE_PREFIX_4.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_exten().
04977 { 04978 struct ast_channel *chan; 04979 struct async_stat *as; 04980 int res = -1, cdr_res = -1; 04981 struct outgoing_helper oh; 04982 pthread_attr_t attr; 04983 04984 if (sync) { 04985 LOAD_OH(oh); 04986 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 04987 if (channel) { 04988 *channel = chan; 04989 if (chan) 04990 ast_channel_lock(chan); 04991 } 04992 if (chan) { 04993 if (chan->_state == AST_STATE_UP) { 04994 res = 0; 04995 if (option_verbose > 3) 04996 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 04997 04998 if (sync > 1) { 04999 if (channel) 05000 ast_channel_unlock(chan); 05001 if (ast_pbx_run(chan)) { 05002 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05003 if (channel) 05004 *channel = NULL; 05005 ast_hangup(chan); 05006 chan = NULL; 05007 res = -1; 05008 } 05009 } else { 05010 if (ast_pbx_start(chan)) { 05011 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05012 if (channel) { 05013 *channel = NULL; 05014 ast_channel_unlock(chan); 05015 } 05016 ast_hangup(chan); 05017 res = -1; 05018 } 05019 chan = NULL; 05020 } 05021 } else { 05022 if (option_verbose > 3) 05023 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05024 05025 if (chan->cdr) { /* update the cdr */ 05026 /* here we update the status of the call, which sould be busy. 05027 * if that fails then we set the status to failed */ 05028 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05029 ast_cdr_failed(chan->cdr); 05030 } 05031 05032 if (channel) { 05033 *channel = NULL; 05034 ast_channel_unlock(chan); 05035 } 05036 ast_hangup(chan); 05037 chan = NULL; 05038 } 05039 } 05040 05041 if (res < 0) { /* the call failed for some reason */ 05042 if (*reason == 0) { /* if the call failed (not busy or no answer) 05043 * update the cdr with the failed message */ 05044 cdr_res = ast_pbx_outgoing_cdr_failed(); 05045 if (cdr_res != 0) { 05046 res = cdr_res; 05047 goto outgoing_exten_cleanup; 05048 } 05049 } 05050 05051 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05052 /* check if "failed" exists */ 05053 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05054 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05055 if (chan) { 05056 char failed_reason[4] = ""; 05057 if (!ast_strlen_zero(context)) 05058 ast_copy_string(chan->context, context, sizeof(chan->context)); 05059 set_ext_pri(chan, "failed", 1); 05060 ast_set_variables(chan, vars); 05061 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 05062 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 05063 if (account) 05064 ast_cdr_setaccount(chan, account); 05065 if (ast_pbx_run(chan)) { 05066 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05067 ast_hangup(chan); 05068 } 05069 chan = NULL; 05070 } 05071 } 05072 } 05073 } else { 05074 if (!(as = ast_calloc(1, sizeof(*as)))) { 05075 res = -1; 05076 goto outgoing_exten_cleanup; 05077 } 05078 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05079 if (channel) { 05080 *channel = chan; 05081 if (chan) 05082 ast_channel_lock(chan); 05083 } 05084 if (!chan) { 05085 free(as); 05086 res = -1; 05087 goto outgoing_exten_cleanup; 05088 } 05089 as->chan = chan; 05090 ast_copy_string(as->context, context, sizeof(as->context)); 05091 set_ext_pri(as->chan, exten, priority); 05092 as->timeout = timeout; 05093 ast_set_variables(chan, vars); 05094 if (account) 05095 ast_cdr_setaccount(chan, account); 05096 pthread_attr_init(&attr); 05097 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05098 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05099 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05100 free(as); 05101 if (channel) { 05102 *channel = NULL; 05103 ast_channel_unlock(chan); 05104 } 05105 ast_hangup(chan); 05106 res = -1; 05107 pthread_attr_destroy(&attr); 05108 goto outgoing_exten_cleanup; 05109 } 05110 pthread_attr_destroy(&attr); 05111 res = 0; 05112 } 05113 outgoing_exten_cleanup: 05114 ast_variables_destroy(vars); 05115 return res; 05116 }
| enum ast_pbx_result ast_pbx_run | ( | struct ast_channel * | c | ) |
Execute the PBX in the current thread.
| c | channel to run the pbx on |
Definition at line 2608 of file pbx.c.
References __ast_pbx_run(), AST_PBX_CALL_LIMIT, AST_PBX_SUCCESS, decrease_call_count(), and increase_call_count().
Referenced by ast_pbx_outgoing_exten(), async_wait(), mgcp_ss(), skinny_newcall(), and ss_thread().
02609 { 02610 enum ast_pbx_result res = AST_PBX_SUCCESS; 02611 02612 if (increase_call_count(c)) 02613 return AST_PBX_CALL_LIMIT; 02614 02615 res = __ast_pbx_run(c); 02616 decrease_call_count(); 02617 02618 return res; 02619 }
| enum ast_pbx_result ast_pbx_start | ( | struct ast_channel * | c | ) |
Create a new thread and start the PBX.
| c | channel to start the pbx on |
Definition at line 2581 of file pbx.c.
References ast_log(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_pthread_create, decrease_call_count(), increase_call_count(), LOG_WARNING, pbx_thread(), and t.
Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_exten(), check_goto_on_transfer(), dahdi_new(), do_parking_thread(), gtalk_new(), gtalk_newcall(), handle_request_invite(), local_call(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), and skinny_new().
02582 { 02583 pthread_t t; 02584 pthread_attr_t attr; 02585 02586 if (!c) { 02587 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02588 return AST_PBX_FAILED; 02589 } 02590 02591 if (increase_call_count(c)) 02592 return AST_PBX_CALL_LIMIT; 02593 02594 /* Start a new thread, and get something handling this channel. */ 02595 pthread_attr_init(&attr); 02596 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02597 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02598 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02599 pthread_attr_destroy(&attr); 02600 decrease_call_count(); 02601 return AST_PBX_FAILED; 02602 } 02603 pthread_attr_destroy(&attr); 02604 02605 return AST_PBX_SUCCESS; 02606 }
| int ast_rdlock_contexts | ( | void | ) |
Definition at line 6131 of file pbx.c.
References ast_rwlock_rdlock(), and conlock.
Referenced by __ast_context_create(), _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_hint_extension(), ast_hint_state_changed(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), handle_save_dialplan(), pbx_extension_helper(), and show_dialplan_helper().
06132 { 06133 return ast_rwlock_rdlock(&conlock); 06134 }
| int ast_register_application | ( | const char * | app, | |
| int(*)(struct ast_channel *, void *) | execute, | |||
| const char * | synopsis, | |||
| const char * | description | |||
| ) |
Register an application.
| app | Short name of the application | |
| execute | a function callback to execute the application. It should return non-zero if the channel needs to be hung up. | |
| synopsis | a short description (one line synopsis) of the application | |
| description | long description with all of the details about the use of the application |
| 0 | success | |
| -1 | failure. |
Definition at line 2910 of file pbx.c.
References ast_calloc, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), COLOR_BRCYAN, ast_app::description, ast_app::execute, ast_app::list, LOG_WARNING, ast_app::name, option_verbose, ast_app::synopsis, term_color(), and VERBOSE_PREFIX_2.
Referenced by load_module(), and load_pbx().
02911 { 02912 struct ast_app *tmp, *cur = NULL; 02913 char tmps[80]; 02914 int length; 02915 02916 AST_LIST_LOCK(&apps); 02917 AST_LIST_TRAVERSE(&apps, tmp, list) { 02918 if (!strcasecmp(app, tmp->name)) { 02919 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02920 AST_LIST_UNLOCK(&apps); 02921 return -1; 02922 } 02923 } 02924 02925 length = sizeof(*tmp) + strlen(app) + 1; 02926 02927 if (!(tmp = ast_calloc(1, length))) { 02928 AST_LIST_UNLOCK(&apps); 02929 return -1; 02930 } 02931 02932 strcpy(tmp->name, app); 02933 tmp->execute = execute; 02934 tmp->synopsis = synopsis; 02935 tmp->description = description; 02936 02937 /* Store in alphabetical order */ 02938 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 02939 if (strcasecmp(tmp->name, cur->name) < 0) { 02940 AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 02941 break; 02942 } 02943 } 02944 AST_LIST_TRAVERSE_SAFE_END 02945 if (!cur) 02946 AST_LIST_INSERT_TAIL(&apps, tmp, list); 02947 02948 if (option_verbose > 1) 02949 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 02950 02951 AST_LIST_UNLOCK(&apps); 02952 02953 return 0; 02954 }
| int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
| sw | switch to register |
Definition at line 2960 of file pbx.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_switch::list, LOG_WARNING, and ast_switch::name.
Referenced by load_module().
02961 { 02962 struct ast_switch *tmp; 02963 02964 AST_LIST_LOCK(&switches); 02965 AST_LIST_TRAVERSE(&switches, tmp, list) { 02966 if (!strcasecmp(tmp->name, sw->name)) { 02967 AST_LIST_UNLOCK(&switches); 02968 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 02969 return -1; 02970 } 02971 } 02972 AST_LIST_INSERT_TAIL(&switches, sw, list); 02973 AST_LIST_UNLOCK(&switches); 02974 02975 return 0; 02976 }
| int ast_spawn_extension | ( | struct ast_channel * | c, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| const char * | callerid | |||
| ) |
Launch a new extension (i.e. new stack).
| c | not important | |
| context | which context to generate the extension within | |
| exten | new extension to add | |
| priority | priority of new extension | |
| callerid | callerid of extension |
| 0 | on success | |
| -1 | on failure. |
Definition at line 2255 of file pbx.c.
References E_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), _macro_exec(), ast_bridge_call(), and loopback_exec().
02256 { 02257 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN); 02258 }
| int ast_unlock_context | ( | struct ast_context * | con | ) |
| Unlocks | the given context |
| con | context to unlock |
| 0 | on success | |
| -1 | on failure |
Definition at line 6154 of file pbx.c.
References ast_mutex_unlock(), and ast_context::lock.
Referenced by _macro_exec(), complete_context_dont_include_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), lookup_c_ip(), lookup_ci(), and show_dialplan_helper().
06155 { 06156 return ast_mutex_unlock(&con->lock); 06157 }
| int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
| 0 | on success | |
| -1 | on failure |
Definition at line 6141 of file pbx.c.
References ast_rwlock_unlock(), and conlock.
Referenced by __ast_context_create(), _macro_exec(), ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_destroy(), ast_context_find(), ast_context_lockmacro(), ast_context_remove_extension_callerid(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_unlockmacro(), ast_hint_extension(), ast_hint_state_changed(), ast_merge_contexts_and_delete(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_save_dialplan(), pbx_extension_helper(), and show_dialplan_helper().
06142 { 06143 return ast_rwlock_unlock(&conlock); 06144 }
| int ast_unregister_application | ( | const char * | app | ) |
Unregister an application.
| app | name of the application (does not have to be the same string as the one that was registered) |
| 0 | success | |
| -1 | failure |
Definition at line 3822 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), free, ast_app::list, ast_app::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by __unload_module(), and unload_module().
03823 { 03824 struct ast_app *tmp; 03825 03826 AST_LIST_LOCK(&apps); 03827 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03828 if (!strcasecmp(app, tmp->name)) { 03829 AST_LIST_REMOVE_CURRENT(&apps, list); 03830 if (option_verbose > 1) 03831 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03832 free(tmp); 03833 break; 03834 } 03835 } 03836 AST_LIST_TRAVERSE_SAFE_END 03837 AST_LIST_UNLOCK(&apps); 03838 03839 return tmp ? 0 : -1; 03840 }
| void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
| sw | switch to unregister |
Definition at line 2978 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, and ast_switch::list.
Referenced by __unload_module(), and unload_module().
02979 { 02980 AST_LIST_LOCK(&switches); 02981 AST_LIST_REMOVE(&switches, sw, list); 02982 AST_LIST_UNLOCK(&switches); 02983 }
| struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
| struct ast_exten * | priority | |||
| ) |