Fri Jul 3 06:31:55 2009

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 "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_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 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_KEEP   0

Definition at line 37 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 41 of file pbx.h.

Referenced by __ast_pbx_run(), _macro_exec(), agi_handle_command(), and run_agi().

#define AST_PBX_REPLACE   1

Definition at line 38 of file pbx.h.

#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 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 66 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 80 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 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

Enumerator:
AST_PBX_SUCCESS 
AST_PBX_FAILED 
AST_PBX_CALL_LIMIT 

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


Function Documentation

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.

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 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 
)

Note:
This function will handle locking the channel as needed.

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.

Parameters:
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
Note:
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
Returns:
If "exten" *could be* a valid extension in this context with or without some more digits, return non-zero. Basically, when this returns 0, no matter what you add to exten, it's not going to be a valid extension anymore

Definition at line 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.

Parameters:
context which context to add the ignorpattern to
ignorepat ignorepattern to set up for the extension
registrar registrar of the ignore pattern
Adds an ignore pattern to a particular context.

Return values:
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.

Parameters:
context context to add include to
include new include to add
registrar who's registering it
Adds an include taking a char * string as the context parameter

Return values:
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.

Parameters:
con context to add the include to
include include to add
registrar who registered the context
Adds an include taking a struct ast_context as the first parameter

Return values:
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.

Parameters:
context context to which to add the switch
sw switch to add
data data to pass to switch
eval whether to evaluate variables when running switch
registrar whoever registered the switch
This function registers a switch with the asterisk switch architecture

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

Note:
See ast_context_add_switch() for argument information, with the exception of the first argument. In this case, it's a pointer to an ast_context structure as opposed to the name.

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.

Parameters:
extcontexts pointer to the ast_context structure pointer
name name of the new context
registrar registrar of the context
This will first search for a context with your name. If it exists already, it will not create a new one. If it does not exist, it will create a new one with the given name and registrar.

Returns:
NULL on failure, and an ast_context structure on success

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).

Parameters:
con context to destroy
registrar who registered it
You can optionally leave out either parameter. It will find it based on either the ast_context or the registrar name.

Returns:
nothing

Definition at line 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.

Parameters:
name name of the context to find
Will search for the context with the given name.

Returns:
the ast_context on success, NULL on failure.

Definition at line 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

Note:
This function locks contexts list by &conlist, searches for the right context structure, and locks the macrolock mutex in that context. macrolock is used to limit a macro to be executed by one call at a time.

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.

Parameters:
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
This function removes an extension from a given context.

Return values:
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.

Note:
When do you want to call this function, make sure that &conlock is locked, because some process can handle with your *con context before you lock it.

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.

Note:
See ast_context_add_include for information on arguments
Return values:
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.

Note:
See ast_context_add_include2 for information on arguments
Return values:
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.

Note:
This function locks contexts list by &conlist, search for the rigt context structure, leave context list locked and call ast_context_remove_switch2 which removes switch, unlock contexts list and return ...

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.

Note:
When we call this function, &conlock lock must be locked, because when we giving *con argument, some process can remove/change this context and after that there can be segfault.

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.

Note:
This function locks contexts list by &conlist, searches for the right context structure, and unlocks the macrolock mutex in that context. macrolock is used to limit a macro to be executed by one call at a time.

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.

Parameters:
con context in which to verify the includes
Return values:
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.

Parameters:
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
Note:
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
Returns:
If an extension within the given context(or callerid) with the given priority is found a non zero value will be returned. Otherwise, 0 is returned.

Definition at line 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 
)

Note:
This function will handle locking the channel as needed.

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).

Parameters:
pattern pattern to match
extension extension to check against the pattern.
Checks whether or not the given extension matches the given pattern.

Return values:
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.

Parameters:
c this is not important
context which context to look in
exten which extension to get state
Returns:
extension state as defined in the ast_extension_states enum

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.

Parameters:
extension_state is the numerical state delivered by ast_extension_state
Returns:
the state of an extension as string

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.

Parameters:
context which context to look in
exten which extension to get state
callback callback to call if state changed
data to pass to callback
The callback is called if the state of an extension is changed.

Return values:
-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.

Parameters:
id of the callback to delete
callback callback
Removes the callback from list of callbacks

Return values:
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.

Parameters:
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
Note:
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
Returns:
the priority which matches the given label in the extension or -1 if not found.

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.

Note:
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur

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

Parameters:
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
This application executes a function in read mode on a given channel.

Returns:
zero on success, non-zero on failure

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

Parameters:
chan Channel to execute on
function Data containing the function call string (will be modified)
value A value parameter to pass for writing
This application executes a function in write mode on a given channel.

Returns:
zero on success, non-zero on failure

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  ) 

Definition at line 6167 of file pbx.c.

References exten.

Referenced by handle_show_hints().

06168 {
06169    return exten ? exten->parent : NULL;
06170 }

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().

06178 {
06179    return exten ? exten->label : NULL;
06180 }

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().

06173 {
06174    return exten ? exten->exten : NULL;
06175 }

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().

06193 {
06194    return exten ? exten->priority : -1;
06195 }

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.

Parameters:
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
Returns:
If an extension within the given context with the priority PRIORITY_HINT is found a non zero value will be returned. Otherwise, 0 is returned.

Definition at line 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().

06183 {
06184    return inc ? inc->name : NULL;
06185 }

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 
)

Note:
This function will handle locking the channel as needed.

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.

Parameters:
context context to search within
pattern to check whether it should be ignored or not
Check if a number should be ignored with respect to dialtone cancellation.

Return values:
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.

Parameters:
con context to lock
Return values:
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.

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

Parameters:
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
Note:
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
Returns:
If "exten" *could match* a valid extension in this context with some more digits, return non-zero. Does NOT return non-zero if this is an exact-match only. Basically, when this returns 0, no matter what you add to exten, it's not going to be a valid extension anymore

Definition at line 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.

Parameters:
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 
)

Note:
I can find neither parsable nor parseable at dictionary.com, but google gives me 169000 hits for parseable and only 49,800 for parsable

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.

Parameters:
c channel to run the pbx on
This executes the PBX on a given channel. It allocates a new PBX structure for the channel, and provides all PBX functionality. See ast_pbx_start for an asynchronous function to run the PBX in a new thread as opposed to the current one.

Returns:
Zero on success, non-zero on failure

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.

Parameters:
c channel to start the pbx on
See ast_pbx_run for a synchronous function to run the PBX in the current thread, as opposed to starting a new one.

Returns:
Zero on success, non-zero on failure

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.

Parameters:
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
This registers an application with Asterisk's internal application list.
Note:
The individual applications themselves are responsible for registering and unregistering and unregistering their own CLI commands.
Return values:
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.

Parameters:
sw switch to register
This function registers a populated ast_switch structure with the asterisk switching architecture.

Returns:
0 on success, and other than 0 on failure

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).

Parameters:
c not important
context which context to generate the extension within
exten new extension to add
priority priority of new extension
callerid callerid of extension
This adds a new extension to the asterisk extension list.

Note:
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
Return values:
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  ) 

Return values:
Unlocks the given context
Parameters:
con context to unlock
Return values:
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.

Return values:
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.

Parameters:
app name of the application (does not have to be the same string as the one that was registered)
This unregisters an application from Asterisk's internal application list.

Return values:
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.

Parameters:
sw switch to unregister
Unregisters a switch from asterisk.

Returns:
nothing

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 
)

Definition at line