Sat Nov 1 06:29:11 2008

Asterisk developer's documentation


pbx.h File Reference

Core PBX routines and definitions. More...

#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_contextast_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_contextast_context_find (const char *name)
 Find a context.
ast_contextast_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_functionast_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_contextast_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_extenast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority)
ast_ignorepatast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip)
ast_includeast_walk_context_includes (struct ast_context *con, struct ast_include *inc)
ast_swast_walk_context_switches (struct ast_context *con, struct ast_sw *sw)
ast_contextast_walk_contexts (struct ast_context *con)
ast_extenast_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_apppbx_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)


Detailed Description

Core PBX routines and definitions.

Definition in file pbx.h.


Define Documentation

#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_KEEP   0

Definition at line 36 of file pbx.h.

#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 AST_PBX_REPLACE   1

Definition at line 37 of file pbx.h.

#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 Documentation

typedef int(*) ast_state_cb_type(char *context, char *id, enum ast_extension_states state, void *data)

Typedef for devicestate and hint callbacks.

Definition at line 67 of file pbx.h.

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.

Data structure associated with an Asterisk switch

Definition at line 81 of file pbx.h.


Enumeration Type Documentation

enum ast_extension_states

Extension states.

Enumerator:
AST_EXTENSION_REMOVED  Extension removed
AST_EXTENSION_DEACTIVATED  Extension hint removed
AST_EXTENSION_NOT_INUSE  No device INUSE or BUSY
AST_EXTENSION_INUSE  One or more devices INUSE
AST_EXTENSION_BUSY  All devices BUSY
AST_EXTENSION_UNAVAILABLE  All devices UNAVAILABLE/UNREGISTERED
AST_EXTENSION_RINGING  All devices RINGING
AST_EXTENSION_ONHOLD  All devices ONHOLD

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

Enumerator:
AST_PBX_SUCCESS 
AST_PBX_FAILED 
AST_PBX_CALL_LIMIT 

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 };


Function Documentation

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.

Parameters:
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
Return values:
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);