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

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

Go to the source code of this file.
Data Structures | |
| struct | ast_custom_function |
| Data structure associated with a custom dialplan function. More... | |
| struct | ast_pbx |
| struct | ast_switch |
| struct | ast_timing |
Defines | |
| #define | AST_MAX_APP 32 |
| #define | AST_PBX_KEEP 0 |
| #define | AST_PBX_KEEPALIVE 10 |
| Special return values from applications to the PBX {. | |
| #define | AST_PBX_NO_HANGUP_PEER 11 |
| #define | AST_PBX_NO_HANGUP_PEER_PARKED 12 |
| #define | AST_PBX_REPLACE 1 |
| #define | PRIORITY_HINT -1 |
Typedefs | |
| typedef int(*) | ast_state_cb_type (char *context, char *id, enum ast_extension_states state, void *data) |
| Typedef for devicestate and hint callbacks. | |
| typedef int( | ast_switch_f )(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| All switch functions have the same interface, so define a type for them. | |
Enumerations | |
| enum | ast_extension_states { AST_EXTENSION_REMOVED = -2, AST_EXTENSION_DEACTIVATED = -1, AST_EXTENSION_NOT_INUSE = 0, AST_EXTENSION_INUSE = 1 << 0, AST_EXTENSION_BUSY = 1 << 1, AST_EXTENSION_UNAVAILABLE = 1 << 2, AST_EXTENSION_RINGING = 1 << 3, AST_EXTENSION_ONHOLD = 1 << 4 } |
| Extension states. More... | |
| enum | ast_pbx_result { AST_PBX_SUCCESS = 0, AST_PBX_FAILED = -1, AST_PBX_CALL_LIMIT = -2 } |
Functions | |
| int | ast_active_calls (void) |
| Retrieve the number of active calls. | |
| int | ast_add_extension (const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar) |
| Add and extension to an extension context. | |
| int | ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar) |
| Add an extension to an extension context, this time with an ast_context *. | |
| int | ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority) |
| int | ast_async_goto_by_name (const char *chan, const char *context, const char *exten, int priority) |
| int | ast_async_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
| int | ast_build_timing (struct ast_timing *i, const char *info) |
| int | ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| Looks for a valid matching extension. | |
| int | ast_check_timing (const struct ast_timing *i) |
| int | ast_context_add_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
| Add an ignorepat. | |
| int | ast_context_add_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar) |
| int | ast_context_add_include (const char *context, const char *include, const char *registrar) |
| Add a context include. | |
| int | ast_context_add_include2 (struct ast_context *con, const char *include, const char *registrar) |
| Add a context include. | |
| int | ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar) |
| Add a switch. | |
| int | ast_context_add_switch2 (struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar) |
| Adds a switch (first param is a ast_context). | |
| ast_context * | ast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar) |
| Register a new context. | |
| void | ast_context_destroy (struct ast_context *con, const char *registrar) |
| Destroy a context (matches the specified context (or ANY context if NULL). | |
| ast_context * | ast_context_find (const char *name) |
| Find a context. | |
| ast_context * | ast_context_find_or_create (struct ast_context **extcontexts, const char *name, const char *registrar) |
| int | ast_context_lockmacro (const char *macrocontext) |
| locks the macrolock in the given given context | |
| int | ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar) |
| Simply remove extension from context. | |
| int | ast_context_remove_extension2 (struct ast_context *con, const char *extension, int priority, const char *registrar) |
| This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return. | |
| int | ast_context_remove_extension_callerid (const char *context, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar) |
| int | ast_context_remove_extension_callerid2 (struct ast_context *con, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar) |
| int | ast_context_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
| int | ast_context_remove_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar) |
| int | ast_context_remove_include (const char *context, const char *include, const char *registrar) |
| Remove a context include. | |
| int | ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar) |
| Removes an include by an ast_context structure. | |
| int | ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar) |
| Remove a switch. | |
| int | ast_context_remove_switch2 (struct ast_context *con, const char *sw, const char *data, const char *registrar) |
| This function locks given context, removes switch, unlock context and return. | |
| int | ast_context_unlockmacro (const char *macrocontext) |
| Unlocks the macrolock in the given context. | |
| int | ast_context_verify_includes (struct ast_context *con) |
| Verifies includes in an ast_contect structure. | |
| ast_custom_function * | ast_custom_function_find (const char *name) |
| int | ast_custom_function_register (struct ast_custom_function *acf) |
| Reigster a custom function. | |
| int | ast_custom_function_unregister (struct ast_custom_function *acf) |
| Unregister a custom function. | |
| int | ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| Determine whether an extension exists. | |
| int | ast_explicit_goto (struct ast_channel *chan, const char *context, const char *exten, int priority) |
| int | ast_extension_close (const char *pattern, const char *data, int needmore) |
| int | ast_extension_match (const char *pattern, const char *extension) |
| Determine if a given extension matches a given pattern (in NXX format). | |
| int | ast_extension_patmatch (const char *pattern, const char *data) |
| int | ast_extension_state (struct ast_channel *c, const char *context, const char *exten) |
| Uses hint and devicestate callback to get the state of an extension. | |
| const char * | ast_extension_state2str (int extension_state) |
| Return string representation of the state of an extension. | |
| int | ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data) |
| Registers a state change callback. | |
| int | ast_extension_state_del (int id, ast_state_cb_type callback) |
| Deletes a registered state change callback by ID. | |
| int | ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid) |
| Find the priority of an extension that has the specified label. | |
| int | ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid) |
| Find the priority of an extension that has the specified label. | |
| int | ast_func_read (struct ast_channel *chan, char *function, char *workspace, size_t len) |
| executes a read operation on a function | |
| int | ast_func_write (struct ast_channel *chan, char *function, const char *value) |
| executes a write operation on a function | |
| const char * | ast_get_context_name (struct ast_context *con) |
| const char * | ast_get_context_registrar (struct ast_context *c) |
| const char * | ast_get_extension_app (struct ast_exten *e) |
| void * | ast_get_extension_app_data (struct ast_exten *e) |
| const char * | ast_get_extension_cidmatch (struct ast_exten *e) |
| ast_context * | ast_get_extension_context (struct ast_exten *exten) |
| const char * | ast_get_extension_label (struct ast_exten *e) |
| int | ast_get_extension_matchcid (struct ast_exten *e) |
| const char * | ast_get_extension_name (struct ast_exten *exten) |
| int | ast_get_extension_priority (struct ast_exten *exten) |
| const char * | ast_get_extension_registrar (struct ast_exten *e) |
| int | ast_get_hint (char *hint, int maxlen, char *name, int maxnamelen, struct ast_channel *c, const char *context, const char *exten) |
| If an extension exists, return non-zero. | |
| const char * | ast_get_ignorepat_name (struct ast_ignorepat *ip) |
| const char * | ast_get_ignorepat_registrar (struct ast_ignorepat *ip) |
| const char * | ast_get_include_name (struct ast_include *include) |
| const char * | ast_get_include_registrar (struct ast_include *i) |
| const char * | ast_get_switch_data (struct ast_sw *sw) |
| const char * | ast_get_switch_name (struct ast_sw *sw) |
| const char * | ast_get_switch_registrar (struct ast_sw *sw) |
| int | ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
| void | ast_hint_state_changed (const char *device) |
| int | ast_ignore_pattern (const char *context, const char *pattern) |
| Checks to see if a number should be ignored. | |
| int | ast_lock_context (struct ast_context *con) |
| Locks a given context. | |
| int | ast_lock_contexts (void) |
| Locks the context list. | |
| int | ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| Looks to see if adding anything to this extension might match something. (exists ^ canmatch). | |
| void | ast_merge_contexts_and_delete (struct ast_context **extcontexts, const char *registrar) |
| Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added. | |
| int | ast_parseable_goto (struct ast_channel *chan, const char *goto_string) |
| int | ast_pbx_outgoing_app (const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) |
| int | ast_pbx_outgoing_exten (const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) |
| enum ast_pbx_result | ast_pbx_run (struct ast_channel *c) |
| Execute the PBX in the current thread. | |
| enum ast_pbx_result | ast_pbx_start (struct ast_channel *c) |
| Create a new thread and start the PBX. | |
| int | ast_rdlock_contexts (void) |
| int | ast_register_application (const char *app, int(*execute)(struct ast_channel *, void *), const char *synopsis, const char *description) |
| Register an application. | |
| int | ast_register_switch (struct ast_switch *sw) |
| Register an alternative dialplan switch. | |
| int | ast_spawn_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| Launch a new extension (i.e. new stack). | |
| int | ast_unlock_context (struct ast_context *con) |
| int | ast_unlock_contexts (void) |
| Unlocks contexts. | |
| int | ast_unregister_application (const char *app) |
| Unregister an application. | |
| void | ast_unregister_switch (struct ast_switch *sw) |
| Unregister an alternative switch. | |
| ast_exten * | ast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority) |
| ast_ignorepat * | ast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip) |
| ast_include * | ast_walk_context_includes (struct ast_context *con, struct ast_include *inc) |
| ast_sw * | ast_walk_context_switches (struct ast_context *con, struct ast_sw *sw) |
| ast_context * | ast_walk_contexts (struct ast_context *con) |
| ast_exten * | ast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority) |
| int | ast_wrlock_contexts (void) |
| void | pbx_builtin_clear_globals (void) |
| const char * | pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name) |
| void | pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value) |
| int | pbx_builtin_serialize_variables (struct ast_channel *chan, char *buf, size_t size) |
| int | pbx_builtin_setvar (struct ast_channel *chan, void *data) |
| void | pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value) |
| int | pbx_checkcondition (const char *condition) |
| Evaluate a condition. | |
| int | pbx_exec (struct ast_channel *c, struct ast_app *app, void *data) |
| Execute an application. | |
| ast_app * | pbx_findapp (const char *app) |
| Look up an application. | |
| void | pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp) |
| pbx_retrieve_variable: Support for Asterisk built-in variables --- | |
| int | pbx_set_autofallthrough (int newval) |
| void | pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count) |
| void | pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count) |
Definition in file pbx.h.
| #define AST_MAX_APP 32 |
Max length of an application
Definition at line 34 of file pbx.h.
Referenced by destroy_station(), handle_show_application(), handle_show_application_deprecated(), handle_show_function(), and handle_show_function_deprecated().
| #define AST_PBX_KEEPALIVE 10 |
Special return values from applications to the PBX {.
Destroy the thread, but don't hang up the channel
Definition at line 40 of file pbx.h.
Referenced by __ast_pbx_run(), _macro_exec(), agi_handle_command(), ast_bridge_call(), builtin_blindtransfer(), builtin_parkcall(), feature_exec_app(), park_call_exec(), queue_exec(), run_agi(), and try_calling().
| #define AST_PBX_NO_HANGUP_PEER 11 |
The peer has been involved in a transfer
Definition at line 41 of file pbx.h.
Referenced by feature_exec_app(), park_exec(), and try_calling().
| #define AST_PBX_NO_HANGUP_PEER_PARKED 12 |
Don't touch the peer channel - it was sent to the parking lot and might be gone by now
Definition at line 42 of file pbx.h.
Referenced by ast_bridge_call(), builtin_blindtransfer(), builtin_parkcall(), feature_exec_app(), park_exec(), and try_calling().
| #define PRIORITY_HINT -1 |
} Special Priority for a hint
Definition at line 45 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 48 of file pbx.h.
00048 { 00049 AST_EXTENSION_REMOVED = -2, /*!< Extension removed */ 00050 AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */ 00051 AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */ 00052 AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */ 00053 AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */ 00054 AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */ 00055 AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */ 00056 AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */ 00057 };
| enum ast_pbx_result |
Definition at line 215 of file pbx.h.
00215 { 00216 AST_PBX_SUCCESS = 0, 00217 AST_PBX_FAILED = -1, 00218 AST_PBX_CALL_LIMIT = -2, 00219 };
| int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 2668 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02669 { 02670 return countcalls; 02671 }
| 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 4545 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().
04548 { 04549 int ret = -1; 04550 struct ast_context *c = find_context_locked(context); 04551 04552 if (c) { 04553 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04554 application, data, datad, registrar); 04555 ast_unlock_contexts(); 04556 } 04557 return ret; 04558 }
| 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 4760 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, ast_exten::label, ast_context::lock, ast_exten::matchcid, ast_exten::next, option_verbose, ast_exten::parent, pbx_substitute_variables_varshead(), ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, ast_context::root, ast_exten::stuff, VAR_BUF_SIZE, and VERBOSE_PREFIX_3.
Referenced by add_extensions(), ast_add_extension(), do_parking_thread(), park_call_full(), pbx_load_config(), and pbx_load_users().
04764 { 04765 /* 04766 * Sort extensions (or patterns) according to the rules indicated above. 04767 * These are implemented by the function ext_cmp()). 04768 * All priorities for the same ext/pattern/cid are kept in a list, 04769 * using the 'peer' field as a link field.. 04770 */ 04771 struct ast_exten *tmp, *e, *el = NULL; 04772 int res; 04773 int length; 04774 char *p; 04775 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04776 04777 /* if we are adding a hint, and there are global variables, and the hint 04778 contains variable references, then expand them 04779 */ 04780 ast_mutex_lock(&globalslock); 04781 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04782 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04783 application = expand_buf; 04784 } 04785 ast_mutex_unlock(&globalslock); 04786 04787 length = sizeof(struct ast_exten); 04788 length += strlen(extension) + 1; 04789 length += strlen(application) + 1; 04790 if (label) 04791 length += strlen(label) + 1; 04792 if (callerid) 04793 length += strlen(callerid) + 1; 04794 else 04795 length ++; /* just the '\0' */ 04796 04797 /* Be optimistic: Build the extension structure first */ 04798 if (!(tmp = ast_calloc(1, length))) 04799 return -1; 04800 04801 /* use p as dst in assignments, as the fields are const char * */ 04802 p = tmp->stuff; 04803 if (label) { 04804 tmp->label = p; 04805 strcpy(p, label); 04806 p += strlen(label) + 1; 04807 } 04808 tmp->exten = p; 04809 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04810 tmp->priority = priority; 04811 tmp->cidmatch = p; /* but use p for assignments below */ 04812 if (callerid) { 04813 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04814 tmp->matchcid = 1; 04815 } else { 04816 *p++ = '\0'; 04817 tmp->matchcid = 0; 04818 } 04819 tmp->app = p; 04820 strcpy(p, application); 04821 tmp->parent = con; 04822 tmp->data = data; 04823 tmp->datad = datad; 04824 tmp->registrar = registrar; 04825 04826 ast_mutex_lock(&con->lock); 04827 res = 0; /* some compilers will think it is uninitialized otherwise */ 04828 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04829 res = ext_cmp(e->exten, extension); 04830 if (res == 0) { /* extension match, now look at cidmatch */ 04831 if (!e->matchcid && !tmp->matchcid) 04832 res = 0; 04833 else if (tmp->matchcid && !e->matchcid) 04834 res = 1; 04835 else if (e->matchcid && !tmp->matchcid) 04836 res = -1; 04837 else 04838 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04839 } 04840 if (res >= 0) 04841 break; 04842 } 04843 if (e && res == 0) { /* exact match, insert in the pri chain */ 04844 res = add_pri(con, tmp, el, e, replace); 04845 ast_mutex_unlock(&con->lock); 04846 if (res < 0) { 04847 errno = EEXIST; /* XXX do we care ? */ 04848 return 0; /* XXX should we return -1 maybe ? */ 04849 } 04850 } else { 04851 /* 04852 * not an exact match, this is the first entry with this pattern, 04853 * so insert in the main list right before 'e' (if any) 04854 */ 04855 tmp->next = e; 04856 if (el) 04857 el->next = tmp; 04858 else 04859 con->root = tmp; 04860 ast_mutex_unlock(&con->lock); 04861 if (tmp->priority == PRIORITY_HINT) 04862 ast_add_hint(tmp); 04863 } 04864 if (option_debug) { 04865 if (tmp->matchcid) { 04866 if (option_debug) 04867 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04868 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04869 } else { 04870 if (option_debug) 04871 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04872 tmp->exten, tmp->priority, con->name); 04873 } 04874 } 04875 if (option_verbose > 2) { 04876 if (tmp->matchcid) { 04877 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04878 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04879 } else { 04880 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04881 tmp->exten, tmp->priority, con->name); 04882 } 04883 } 04884 return 0; 04885 }
| int ast_async_goto | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 4583 of file pbx.c.
References ast_channel::_state, 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::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().
04584 { 04585 int res = 0; 04586 04587 ast_channel_lock(chan); 04588 04589 if (chan->pbx) { /* This channel is currently in the PBX */ 04590 ast_explicit_goto(chan, context, exten, priority); 04591 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04592 } else { 04593 /* In order to do it when the channel doesn't really exist within 04594 the PBX, we have to make a new channel, masquerade, and start the PBX 04595 at the new location */ 04596 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04597 if (!tmpchan) { 04598 res = -1; 04599 } else { 04600 if (chan->cdr) { 04601 ast_cdr_discard(tmpchan->cdr); 04602 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 04603 } 04604 /* Make formats okay */ 04605 tmpchan->readformat = chan->readformat; 04606 tmpchan->writeformat = chan->writeformat; 04607 /* Setup proper location */ 04608 ast_explicit_goto(tmpchan, 04609 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04610 04611 /* Masquerade into temp channel */ 04612 if (ast_channel_masquerade(tmpchan, chan)) { 04613 /* Failed to set up the masquerade. It's probably chan_local 04614 * in the middle of optimizing itself out. Sad. :( */ 04615 ast_hangup(tmpchan); 04616 tmpchan = NULL; 04617 res = -1; 04618 } else { 04619 /* Grab the locks and get going */ 04620 ast_channel_lock(tmpchan); 04621 ast_do_masquerade(tmpchan);