Fri Sep 25 19:28:40 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 dependency graph for pbx.h:

Go to the source code of this file.

Data Structures

struct  ast_custom_function
 Data structure associated with a custom dialplan function. More...
struct  ast_pbx
struct  ast_switch
struct  ast_timing

Defines

#define AST_MAX_APP   32
#define AST_PBX_KEEP   0
#define AST_PBX_KEEPALIVE   10
 Special return values from applications to the PBX {.
#define AST_PBX_NO_HANGUP_PEER   11
#define AST_PBX_REPLACE   1
#define PRIORITY_HINT   -1

Typedefs

typedef int(* ast_state_cb_type )(char *context, char *id, enum ast_extension_states state, void *data, char *cid_num, char *cid_name)
 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).
struct 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).
struct ast_contextast_context_find (const char *name)
 Find a context.
struct 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_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.
struct 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)
struct 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, char *cid_num, char *cid_name)
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_app2 (const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, int callingpres, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, char *uniqueid)
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)
int ast_pbx_outgoing_exten2 (const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, int callingpres, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, char *uniqueid)
enum ast_pbx_result ast_pbx_run (struct ast_channel *c)
 Execute the PBX in the current thread.
void * ast_pbx_run_app (void *data)
 run the application and free the descriptor once done
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.
struct ast_extenast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority)
struct ast_ignorepatast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip)
struct ast_includeast_walk_context_includes (struct ast_context *con, struct ast_include *inc)
struct ast_swast_walk_context_switches (struct ast_context *con, struct ast_sw *sw)
struct ast_contextast_walk_contexts (struct ast_context *con)
struct 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.
struct 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

#define AST_PBX_KEEP   0

Definition at line 36 of file pbx.h.

#define AST_PBX_KEEPALIVE   10

Special return values from applications to the PBX {.

Destroy the thread, but don't hang up the channel

Definition at line 40 of file pbx.h.

Referenced by __ast_pbx_run(), _macro_exec(), agi_handle_command(), builtin_blindtransfer(), builtin_parkcall(), feature_exec_app(), park_call_exec(), queue_exec(), rpt_exec(), and run_agi().

#define AST_PBX_NO_HANGUP_PEER   11

#define AST_PBX_REPLACE   1

Definition at line 37 of file pbx.h.

#define PRIORITY_HINT   -1


Typedef Documentation

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

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

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

Enumerator:
AST_PBX_SUCCESS 
AST_PBX_FAILED 
AST_PBX_CALL_LIMIT 

Definition at line 216 of file pbx.h.

00216                     {
00217    AST_PBX_SUCCESS = 0,
00218    AST_PBX_FAILED = -1,
00219    AST_PBX_CALL_LIMIT = -2,
00220 };


Function Documentation

int ast_active_calls ( void   ) 

Retrieve the number of active calls.

Definition at line 2670 of file pbx.c.

References countcalls.

Referenced by handle_chanlist(), and handle_chanlist_deprecated().

02671 {
02672    return countcalls;
02673 }

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

04557 {
04558    int ret = -1;
04559    struct ast_context *c = find_context_locked(context);
04560 
04561    if (c) {
04562       ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
04563          application, data, datad, registrar);
04564       ast_unlock_contexts();
04565    }
04566    return ret;
04567 }

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

Note:
For details about the arguments, check ast_add_extension()
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 4762 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, ast_exten::label, ast_context::lock, LOG_DEBUG, ast_exten::matchcid, ast_exten::next, option_debug, 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(), ast_autoanswer_login(), autoanswer_reregister_extensions(), do_parking_thread(), load_config(), park_call_full(), pbx_load_config(), pbx_load_users(), sla_build_station(), and sla_build_trunk().

04766 {
04767    /*
04768     * Sort extensions (or patterns) according to the rules indicated above.
04769     * These are implemented by the function ext_cmp()).
04770     * All priorities for the same ext/pattern/cid are kept in a list,
04771     * using the 'peer' field  as a link field..
04772     */
04773    struct ast_exten *tmp, *e, *el = NULL;
04774    int res;
04775    int length;
04776    char *p;
04777    char expand_buf[VAR_BUF_SIZE] = { 0, };
04778 
04779    /* if we are adding a hint, and there are global variables, and the hint
04780       contains variable references, then expand them
04781    */
04782    ast_mutex_lock(&globalslock);
04783    if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) {
04784       pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf));
04785       application = expand_buf;
04786    }
04787    ast_mutex_unlock(&globalslock);
04788 
04789    length = sizeof(struct ast_exten);
04790    length += strlen(extension) + 1;
04791    length += strlen(application) + 1;
04792    if (label)
04793       length += strlen(label) + 1;
04794    if (callerid)
04795       length += strlen(callerid) + 1;
04796    else
04797       length ++;  /* just the '\0' */
04798 
04799    /* Be optimistic:  Build the extension structure first */
04800    if (!(tmp = ast_calloc(1, length)))
04801       return -1;
04802 
04803    /* use p as dst in assignments, as the fields are const char * */
04804    p = tmp->stuff;
04805    if (label) {
04806       tmp->label = p;
04807       strcpy(p, label);
04808       p += strlen(label) + 1;
04809    }
04810    tmp->exten = p;
04811    p += ext_strncpy(p, extension, strlen(extension) + 1) + 1;
04812    tmp->priority = priority;
04813    tmp->cidmatch = p;   /* but use p for assignments below */
04814    if (callerid) {
04815       p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1;
04816       tmp->matchcid = 1;
04817    } else {
04818       *p++ = '\0';
04819       tmp->matchcid = 0;
04820    }
04821    tmp->app = p;
04822    strcpy(p, application);
04823    tmp->parent = con;
04824    tmp->data = data;
04825    tmp->datad = datad;
04826    tmp->registrar = registrar;
04827 
04828    ast_mutex_lock(&con->lock);
04829    res = 0; /* some compilers will think it is uninitialized otherwise */
04830    for (e = con->root; e; el = e, e = e->next) {   /* scan the extension list */
04831       res = ext_cmp(e->exten, extension);
04832       if (res == 0) { /* extension match, now look at cidmatch */
04833          if (!e->matchcid && !tmp->matchcid)
04834             res = 0;
04835          else if (tmp->matchcid && !e->matchcid)
04836             res = 1;
04837          else if (e->matchcid && !tmp->matchcid)
04838             res = -1;
04839          else
04840             res = strcasecmp(e->cidmatch, tmp->cidmatch);
04841       }
04842       if (res >= 0)
04843          break;
04844    }
04845    if (e && res == 0) { /* exact match, insert in the pri chain */
04846       res = add_pri(con, tmp, el, e, replace);
04847       ast_mutex_unlock(&con->lock);
04848       if (res < 0) {
04849          errno = EEXIST;   /* XXX do we care ? */
04850          return 0; /* XXX should we return -1 maybe ? */
04851       }
04852    } else {
04853       /*
04854        * not an exact match, this is the first entry with this pattern,
04855        * so insert in the main list right before 'e' (if any)
04856        */
04857       tmp->next = e;
04858       if (el)
04859          el->next = tmp;
04860       else
04861          con->root = tmp;
04862       ast_mutex_unlock(&con->lock);
04863       if (tmp->priority == PRIORITY_HINT)
04864          ast_add_hint(tmp);
04865    }
04866    if (option_debug) {
04867       if (tmp->matchcid) {
04868          if (option_debug)
04869             ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n",
04870                tmp->exten, tmp->priority, tmp->cidmatch, con->name);
04871       } else {
04872          if (option_debug)
04873             ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n",
04874                tmp->exten, tmp->priority, con->name);
04875       }
04876    }
04877    if (option_verbose > 2) {
04878       if (tmp->matchcid) {
04879          ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n",
04880             tmp->exten, tmp->priority, tmp->cidmatch, con->name);
04881       } else {
04882          ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n",
04883             tmp->exten, tmp->priority, con->name);
04884       }
04885    }
04886    return 0;
04887 }

int ast_async_goto ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority 
)

Definition at line 4592 of file pbx.c.

References ast_channel::_state, ast_channel::amaflags, ast_cdr_dup(), ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_unlock, ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_pbx_start(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_channel::cdr, ast_channel::context, ast_channel::exten, LOG_WARNING, ast_channel::pbx, ast_channel::readformat, S_OR, and ast_channel::writeformat.

Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), console_transfer_deprecated(), handle_request_bye(), handle_request_refer(), process_ast_dsp(), socket_process(), and zt_handle_dtmfup().

04593 {
04594    int res = 0;
04595 
04596    ast_channel_lock(chan);
04597 
04598    if (chan->pbx) { /* This channel is currently in the PBX */
04599       ast_explicit_goto(chan, context, exten, priority);
04600       ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
04601    } else {
04602       /* In order to do it when the channel doesn't really exist within
04603          the PBX, we have to make a new channel, masquerade, and start the PBX
04604          at the new location */
04605       struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name);
04606       if (chan->cdr) {
04607          tmpchan->cdr = ast_cdr_dup(chan->cdr);
04608       }
04609       if (!tmpchan)
04610          res = -1;
04611       else {
04612          /* Make formats okay */
04613          tmpchan->readformat = chan->readformat;
04614          tmpchan->writeformat = chan->writeformat;
04615          /* Setup proper location */
04616          ast_explicit_goto(tmpchan,
04617             S_OR(context, chan->context), S_OR(exten, chan->exten), priority);
04618 
04619          /* Masquerade into temp channel */
04620          ast_channel_masquerade(tmpchan, chan);
04621 
04622          /* Grab the locks and get going */
04623          ast_channel_lock(tmpchan);
04624          ast_do_masquerade(tmpchan);
04625          ast_channel_unlock(tmpchan);
04626          /* Start the PBX going on our stolen channel */
04627          if (ast_pbx_start(tmpchan)) {
04628             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
04629             ast_hangup(tmpchan);
04630             res = -1;
04631          }
04632       }
04633    }
04634    ast_channel_unlock(chan);
04635    return res;
04636 }

int ast_async_goto_by_name ( const char *  chan,
const char *  context,
const char *  exten,
int  priority 
)

Definition at line 4638 of file pbx.c.

References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().

04639 {
04640    struct ast_channel *chan;
04641    int res = -1;
04642 
04643    chan = ast_get_channel_by_name_locked(channame);
04644    if (chan) {
04645       res = ast_async_goto(chan, context, exten, priority);
04646       ast_channel_unlock(chan);
04647    }
04648    return res;
04649 }

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 6360 of file pbx.c.

References __ast_goto_if_exists().

Referenced by asyncgoto_exec().

06361 {
06362    return __ast_goto_if_exists(chan, context, exten, priority, 1);
06363 }

int ast_build_timing ( struct ast_timing i,
const char *  info 
)

Definition at line 4230 of file pbx.c.

References ast_strlen_zero(), ast_timing::daymask, days, ast_timing::dowmask, get_range(), get_timerange(), ast_timing::monthmask, months, and strsep().

Referenced by ast_context_add_include2(), iftime(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().

04231 {
04232    char info_save[256];
04233    char *info;
04234 
04235    /* Check for empty just in case */
04236    if (ast_strlen_zero(info_in))
04237       return 0;
04238    /* make a copy just in case we were passed a static string */
04239    ast_copy_string(info_save, info_in, sizeof(info_save));
04240    info = info_save;
04241    /* Assume everything except time */
04242    i->monthmask = 0xfff;   /* 12 bits */
04243    i->daymask = 0x7fffffffU; /* 31 bits */
04244    i->dowmask = 0x7f; /* 7 bits */
04245    /* on each call, use strsep() to move info to the next argument */
04246    get_timerange(i, strsep(&info, "|"));
04247    if (info)
04248       i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week");
04249    if (info)
04250       i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day");
04251    if (info)
04252       i->monthmask = get_range(strsep(&info, "|"), 12, months, "month");
04253    return 1;
04254 }

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
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 2294 of file pbx.c.

References E_CANMATCH, and pbx_extension_helper().

Referenced by background_detect_exec(), cb_events(), 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().

02295 {
02296    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH);
02297 }

int ast_check_timing ( const struct ast_timing i  ) 

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

04257 {
04258    struct tm tm;
04259    time_t t = time(NULL);
04260 
04261    ast_localtime(&t, &tm, NULL);
04262 
04263    /* If it's not the right month, return */
04264    if (!(i->monthmask & (1 << tm.tm_mon)))
04265       return 0;
04266 
04267    /* If it's not that time of the month.... */
04268    /* Warning, tm_mday has range 1..31! */
04269    if (!(i->daymask & (1 << (tm.tm_mday-1))))
04270       return 0;
04271 
04272    /* If it's not the right day of the week */
04273    if (!(i->dowmask & (1 << tm.tm_wday)))
04274       return 0;
04275 
04276    /* Sanity check the hour just to be safe */
04277    if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
04278       ast_log(LOG_WARNING, "Insane time...\n");
04279       return 0;
04280    }
04281 
04282    /* Now the tough part, we calculate if it fits
04283       in the right time based on min/hour */
04284    if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
04285       return 0;
04286 
04287    /* If we got this far, then we're good */
04288    return 1;
04289 }

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

04491 {
04492    int ret = -1;
04493    struct ast_context *c = find_context_locked(context);
04494 
04495    if (c) {
04496       ret = ast_context_add_ignorepat2(c, value, registrar);
04497       ast_unlock_contexts();
04498    }
04499    return ret;
04500 }

int ast_context_add_ignorepat2 ( struct ast_context con,
const char *  ignorepat,
const char *  registrar 
)

Definition at line 4502 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_compile_ael2(), ast_context_add_ignorepat(), and pbx_load_config().

04503 {
04504    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
04505    int length;
04506    length = sizeof(struct ast_ignorepat);
04507    length += strlen(value) + 1;
04508    if (!(ignorepat = ast_calloc(1, length)))
04509       return -1;
04510    /* The cast to char * is because we need to write the initial value.
04511     * The field is not supposed to be modified otherwise
04512     */
04513    strcpy((char *)ignorepat->pattern, value);
04514    ignorepat->next = NULL;
04515    ignorepat->registrar = registrar;
04516    ast_mutex_lock(&con->lock);
04517    for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
04518       ignorepatl = ignorepatc;
04519       if (!strcasecmp(ignorepatc->pattern, value)) {
04520          /* Already there */
04521          ast_mutex_unlock(&con->lock);
04522          errno = EEXIST;
04523          return -1;
04524       }
04525    }
04526    if (ignorepatl)
04527       ignorepatl->next = ignorepat;
04528    else
04529       con->ignorepats = ignorepat;
04530    ast_mutex_unlock(&con->lock);
04531    return 0;
04532 
04533 }

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

04037 {
04038    int ret = -1;
04039    struct ast_context *c = find_context_locked(context);
04040 
04041    if (c) {
04042       ret = ast_context_add_include2(c, include, registrar);
04043       ast_unlock_contexts();
04044    }
04045    return ret;
04046 }

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 4298 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_compile_ael2(), ast_context_add_include(), and pbx_load_config().

04300 {
04301    struct ast_include *new_include;
04302    char *c;
04303    struct ast_include *i, *il = NULL; /* include, include_last */
04304    int length;
04305    char *p;
04306 
04307    length = sizeof(struct ast_include);
04308    length += 2 * (strlen(value) + 1);
04309 
04310    /* allocate new include structure ... */
04311    if (!(new_include = ast_calloc(1, length)))
04312       return -1;
04313    /* Fill in this structure. Use 'p' for assignments, as the fields
04314     * in the structure are 'const char *'
04315     */
04316    p = new_include->stuff;
04317    new_include->name = p;
04318    strcpy(p, value);
04319    p += strlen(value) + 1;
04320    new_include->rname = p;
04321    strcpy(p, value);
04322    /* Strip off timing info, and process if it is there */
04323    if ( (c = strchr(p, '|')) ) {
04324       *c++ = '\0';
04325            new_include->hastime = ast_build_timing(&(new_include->timing), c);
04326    }
04327    new_include->next      = NULL;
04328    new_include->registrar = registrar;
04329 
04330    ast_mutex_lock(&con->lock);
04331 
04332    /* ... go to last include and check if context is already included too... */
04333    for (i = con->includes; i; i = i->next) {
04334       if (!strcasecmp(i->name, new_include->name)) {
04335          free(new_include);
04336          ast_mutex_unlock(&con->lock);
04337          errno = EEXIST;
04338          return -1;
04339       }
04340       il = i;
04341    }
04342 
04343    /* ... include new context into context list, unlock, return */
04344    if (il)
04345       il->next = new_include;
04346    else
04347       con->includes = new_include;
04348    if (option_verbose > 2)
04349       ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
04350    ast_mutex_unlock(&con->lock);
04351 
04352    return 0;
04353 }

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 4360 of file pbx.c.

References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().

04361 {
04362    int ret = -1;
04363    struct ast_context *c = find_context_locked(context);
04364 
04365    if (c) { /* found, add switch to this context */
04366       ret = ast_context_add_switch2(c, sw, data, eval, registrar);
04367       ast_unlock_contexts();
04368    }
04369    return ret;
04370 }

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 4379 of file pbx.c.

References 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, ast_context::lock, ast_sw::name, option_verbose, ast_sw::registrar, SWITCH_DATA_LENGTH, and VERBOSE_PREFIX_3.

Referenced by ast_compile_ael2(), ast_context_add_switch(), and pbx_load_config().

04381 {
04382    struct ast_sw *new_sw;
04383    struct ast_sw *i;
04384    int length;
04385    char *p;
04386 
04387    length = sizeof(struct ast_sw);
04388    length += strlen(value) + 1;
04389    if (data)
04390       length += strlen(data);
04391    length++;
04392    if (eval) {
04393       /* Create buffer for evaluation of variables */
04394       length += SWITCH_DATA_LENGTH;
04395       length++;
04396    }
04397 
04398    /* allocate new sw structure ... */
04399    if (!(new_sw = ast_calloc(1, length)))
04400       return -1;
04401    /* ... fill in this structure ... */
04402    p = new_sw->stuff;
04403    new_sw->name = p;
04404    strcpy(new_sw->name, value);
04405    p += strlen(value) + 1;
04406    new_sw->data = p;
04407    if (data) {
04408       strcpy(new_sw->data, data);
04409       p += strlen(data) + 1;
04410    } else {
04411       strcpy(new_sw->data, "");
04412       p++;
04413    }
04414    if (eval)
04415       new_sw->tmpdata = p;
04416    new_sw->eval     = eval;
04417    new_sw->registrar = registrar;
04418 
04419    /* ... try to lock this context ... */
04420    ast_mutex_lock(&con->lock);
04421 
04422    /* ... go to last sw and check if context is already swd too... */
04423    AST_LIST_TRAVERSE(&con->alts, i, list) {
04424       if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
04425          free(new_sw);
04426          ast_mutex_unlock(&con->lock);
04427          errno = EEXIST;
04428          return -1;
04429       }
04430    }
04431 
04432    /* ... sw new context into context list, unlock, return */
04433    AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
04434 
04435    if (option_verbose > 2)
04436       ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
04437 
04438    ast_mutex_unlock(&con->lock);
04439 
04440    return 0;
04441 }

struct ast_context* ast_context_create ( struct ast_context **  extcontexts,
const char *  name,
const char *  registrar 
) [read]

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 3906 of file pbx.c.

References __ast_context_create().

Referenced by ast_autoanswer_login(), ast_compile_ael2(), autoanswer_reregister_extensions(), do_parking_thread(), load_config(), park_call_full(), reload_config(), and set_config().

03907 {
03908    return __ast_context_create(extcontexts, name, registrar, 0);
03909 }

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

05358 {
05359    ast_wrlock_contexts();
05360    __ast_context_destroy(con,registrar);
05361    ast_unlock_contexts();
05362 }

struct ast_context* ast_context_find ( const char *  name  )  [read]

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 890 of file pbx.c.

References ast_rdlock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().

Referenced by _macro_exec(), ast_autoanswer_login(), ast_context_verify_includes(), ast_ignore_pattern(), autoanswer_reregister_extensions(), cleanup_stale_contexts(), do_autoanswer_thread(), do_parking_thread(), load_config(), park_call_full(), park_exec(), register_peer_exten(), reload_config(), and set_config().

00891 {
00892    struct ast_context *tmp = NULL;
00893 
00894    ast_rdlock_contexts();
00895 
00896    while ( (tmp = ast_walk_contexts(tmp)) ) {
00897       if (!name || !strcasecmp(name, tmp->name))
00898          break;
00899    }
00900 
00901    ast_unlock_contexts();
00902 
00903    return tmp;
00904 }

struct ast_context* ast_context_find_or_create ( struct ast_context **  extcontexts,
const char *  name,
const char *  registrar 
) [read]

Definition at line 3911 of file pbx.c.

References __ast_context_create().

Referenced by ast_compile_ael2(), pbx_load_config(), pbx_load_users(), sla_build_station(), and sla_build_trunk().

03912 {
03913    return __ast_context_create(extcontexts, name, registrar, 1);
03914 }

int ast_context_lockmacro ( const char *  context  ) 

locks the macrolock in the given given context

Parameters:
macrocontext name of the macro-context to lock
Locks the given macro-context to ensure only one thread (call) can execute it at a time

Return values:
0 on success
-1 on failure
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 2907 of file pbx.c.

References ast_get_context_name(), ast_mutex_lock(), ast_rdlock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().

Referenced by _macro_exec().

02908 {
02909    struct ast_context *c = NULL;
02910    int ret = -1;
02911 
02912    ast_rdlock_contexts();
02913 
02914    while ((c = ast_walk_contexts(c))) {
02915       if (!strcmp(ast_get_context_name(c), context)) {
02916          ret = 0;
02917          break;
02918       }
02919    }
02920 
02921    ast_unlock_contexts();
02922 
02923    /* if we found context, lock macrolock */
02924    if (ret == 0) 
02925       ret = ast_mutex_lock(&c->macrolock);
02926 
02927    return ret;
02928 }

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
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 2808 of file pbx.c.

References ast_context_remove_extension2(), ast_unlock_contexts(), and find_context_locked().

Referenced by destroy_station(), destroy_trunk(), handle_context_remove_extension(), handle_context_remove_extension_deprecated(), and register_peer_exten().

02809 {
02810    int ret = -1; /* default error return */
02811    struct ast_context *c = find_context_locked(context);
02812 
02813    if (c) { /* ... remove extension ... */
02814       ret = ast_context_remove_extension2(c, extension, priority, registrar);
02815       ast_unlock_contexts();
02816    }
02817    return ret;
02818 }

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 2830 of file pbx.c.

References ast_mutex_lock(), ast_mutex_unlock(), destroy_exten(), ast_exten::exten, exten, ast_context::lock, ast_exten::next, ast_exten::peer, ast_exten::registrar, and ast_context::root.

Referenced by ast_context_remove_extension(), do_autoanswer_thread(), do_parking_thread(), load_config(), and park_exec().

02831 {
02832    struct ast_exten *exten, *prev_exten = NULL;
02833    struct ast_exten *peer;
02834 
02835    ast_mutex_lock(&con->lock);
02836 
02837    /* scan the extension list to find matching extension-registrar */
02838    for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
02839       if (!strcmp(exten->exten, extension) &&
02840          (!registrar || !strcmp(exten->registrar, registrar)))
02841          break;
02842    }
02843    if (!exten) {
02844       /* we can't find right extension */
02845       ast_mutex_unlock(&con->lock);
02846       return -1;
02847    }
02848 
02849    /* should we free all peers in this extension? (priority == 0)? */
02850    if (priority == 0) {
02851       /* remove this extension from context list */
02852       if (prev_exten)
02853          prev_exten->next = exten->next;
02854       else
02855          con->root = exten->next;
02856 
02857       /* fire out all peers */
02858       while ( (peer = exten) ) {
02859          exten = peer->peer; /* prepare for next entry */
02860          destroy_exten(peer);
02861       }
02862    } else {
02863       /* scan the priority list to remove extension with exten->priority == priority */
02864       struct ast_exten *previous_peer = NULL;
02865 
02866       for (peer = exten; peer; previous_peer = peer, peer = peer->peer) {
02867          if (peer->priority == priority &&
02868                (!registrar || !strcmp(peer->registrar, registrar) ))
02869             break; /* found our priority */
02870       }
02871       if (!peer) { /* not found */
02872          ast_mutex_unlock(&con->lock);
02873          return -1;
02874       }
02875       /* we are first priority extension? */
02876       if (!previous_peer) {
02877          /*
02878           * We are first in the priority chain, so must update the extension chain.
02879           * The next node is either the next priority or the next extension
02880           */
02881          struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
02882 
02883          if (!prev_exten)  /* change the root... */
02884             con->root = next_node;
02885          else
02886             prev_exten->next = next_node; /* unlink */
02887          if (peer->peer)   /* XXX update the new head of the pri list */
02888             peer->peer->next = peer->next;
02889       } else { /* easy, we are not first priority in extension */
02890          previous_peer->peer = peer->peer;
02891       }
02892 
02893       /* now, free whole priority extension */
02894       destroy_exten(peer);
02895       /* XXX should we return -1 ? */
02896    }
02897    ast_mutex_unlock(&con->lock);
02898    return 0;
02899 }

int ast_context_remove_ignorepat ( const char *  context,
const char *  ignorepat,
const char *  registrar 
)

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

04448 {
04449    int ret = -1;
04450    struct ast_context *c = find_context_locked(context);
04451 
04452    if (c) {
04453       ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
04454       ast_unlock_contexts();
04455    }
04456    return ret;
04457 }

int ast_context_remove_ignorepat2 ( struct ast_context con,
const char *  ignorepat,
const char *  registrar 
)

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

04460 {
04461    struct ast_ignorepat *ip, *ipl = NULL;
04462 
04463    ast_mutex_lock(&con->lock);
04464 
04465    for (ip = con->ignorepats; ip; ip = ip->next) {
04466       if (!strcmp(ip->pattern, ignorepat) &&
04467          (!registrar || (registrar == ip->registrar))) {
04468          if (ipl) {
04469             ipl->next = ip->next;
04470             free(ip);
04471          } else {
04472             con->ignorepats = ip->next;
04473             free(ip);
04474          }
04475          ast_mutex_unlock(&con->lock);
04476          return 0;
04477       }
04478       ipl = ip;
04479    }
04480 
04481    ast_mutex_unlock(&con->lock);
04482    errno = EINVAL;
04483    return -1;
04484 }

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

02705 {
02706    int ret = -1;
02707    struct ast_context *c = find_context_locked(context);
02708 
02709    if (c) {
02710       /* found, remove include from this context ... */
02711       ret = ast_context_remove_include2(c, include, registrar);
02712       ast_unlock_contexts();
02713    }
02714    return ret;
02715 }

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

02726 {
02727    struct ast_include *i, *pi = NULL;
02728    int ret = -1;
02729 
02730    ast_mutex_lock(&con->lock);
02731 
02732    /* find our include */
02733    for (i = con->includes; i; pi = i, i = i->next) {
02734       if (!strcmp(i->name, include) &&
02735             (!registrar || !strcmp(i->registrar, registrar))) {
02736          /* remove from list */
02737          if (pi)
02738             pi->next = i->next;
02739          else
02740             con->includes = i->next;
02741          /* free include and return */
02742          free(i);
02743          ret = 0;
02744          break;
02745       }
02746    }
02747 
02748    ast_mutex_unlock(&con->lock);
02749    return ret;
02750 }

int ast_context_remove_switch ( const char *  context,
const char *  sw,
const char *  data,
const char *  registrar 
)

Remove a switch.

Removes a switch with the given parameters

Return values:
0 on success
-1 on failure
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 2757 of file pbx.c.

References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().

02758 {
02759    int ret = -1; /* default error return */
02760    struct ast_context *c = find_context_locked(context);
02761 
02762    if (c) {
02763       /* remove switch from this context ... */
02764       ret = ast_context_remove_switch2(c, sw, data, registrar);
02765       ast_unlock_contexts();
02766    }
02767    return ret;
02768 }

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 2778 of file pbx.c.

References 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_context::lock, ast_sw::name, and ast_sw::registrar.

Referenced by ast_context_remove_switch().

02779 {
02780    struct ast_sw *i;
02781    int ret = -1;
02782 
02783    ast_mutex_lock(&con->lock);
02784 
02785    /* walk switches */
02786    AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
02787       if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
02788          (!registrar || !strcmp(i->registrar, registrar))) {
02789          /* found, remove from list */
02790          AST_LIST_REMOVE_CURRENT(&con->alts, list);
02791          free(i); /* free switch and return */
02792          ret = 0;
02793          break;
02794       }
02795    }
02796    AST_LIST_TRAVERSE_SAFE_END
02797 
02798    ast_mutex_unlock(&con->lock);
02799 
02800    return ret;
02801 }

int ast_context_unlockmacro ( const char *  context  ) 

Unlocks the macrolock in the given context.

Parameters:
macrocontext name of the macro-context to unlock
Unlocks the given macro-context so that another thread (call) can execute it

Return values:
0 on success
-1 on failure
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 2935 of file pbx.c.

References ast_get_context_name(), ast_mutex_unlock(), ast_rdlock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().

Referenced by _macro_exec().

02936 {
02937    struct ast_context *c = NULL;
02938    int ret = -1;
02939 
02940    ast_rdlock_contexts();
02941 
02942    while ((c = ast_walk_contexts(c))) {
02943       if (!strcmp(ast_get_context_name(c), context)) {
02944          ret = 0;
02945          break;
02946       }
02947    }
02948 
02949    ast_unlock_contexts();
02950 
02951    /* if we found context, unlock macrolock */
02952    if (ret == 0) 
02953       ret = ast_mutex_unlock(&c->macrolock);
02954 
02955    return ret;
02956 }

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

06322 {
06323    struct ast_include *inc = NULL;
06324    int res = 0;
06325 
06326    while ( (inc = ast_walk_context_includes(con, inc)) )
06327       if (!ast_context_find(inc->rname)) {
06328          res = -1;
06329          ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n",
06330                ast_get_context_name(con), inc->rname);
06331       }
06332    return res;
06333 }

struct ast_custom_function* ast_custom_function_find ( const char *  name  )  [read]

Definition at line 1443 of file pbx.c.

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

01444 {
01445    struct ast_custom_function *acf = NULL;
01446 
01447    AST_LIST_LOCK(&acf_root);
01448    AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
01449       if (!strcmp(name, acf->name))
01450          break;
01451    }
01452    AST_LIST_UNLOCK(&acf_root);
01453 
01454    return acf;
01455 }

int ast_custom_function_register ( struct ast_custom_function acf  ) 

Reigster a custom function.

Definition at line 1479 of file pbx.c.

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

01480 {
01481    struct ast_custom_function *cur;
01482 
01483    if (!acf)
01484       return -1;
01485 
01486    AST_LIST_LOCK(&acf_root);
01487 
01488    if (ast_custom_function_find(acf->name)) {
01489       ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
01490       AST_LIST_UNLOCK(&acf_root);
01491       return -1;
01492    }
01493 
01494    /* Store in alphabetical order */
01495    AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
01496       if (strcasecmp(acf->name, cur->name) < 0) {
01497          AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist);
01498          break;
01499       }
01500    }
01501    AST_LIST_TRAVERSE_SAFE_END
01502    if (!cur)
01503       AST_LIST_INSERT_TAIL(&acf_root, acf, acflist);
01504 
01505    AST_LIST_UNLOCK(&acf_root);
01506 
01507    if (option_verbose > 1)
01508       ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name);
01509 
01510    return 0;
01511 }

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

Definition at line 1457 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(), ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.

Referenced by odbc_unload_module(), reload(), and unload_module().

01458 {
01459    struct ast_custom_function *cur;
01460 
01461    if (!acf)
01462       return -1;
01463 
01464    AST_LIST_LOCK(&acf_root);
01465    AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
01466       if (cur == acf) {
01467          AST_LIST_REMOVE_CURRENT(&acf_root, acflist);
01468          if (option_verbose > 1)
01469             ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name);
01470          break;
01471       }
01472    }
01473    AST_LIST_TRAVERSE_SAFE_END
01474    AST_LIST_UNLOCK(&acf_root);
01475 
01476    return acf ? 0 : -1;
01477 }

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
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 2279 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_pbx_outgoing_exten2(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), 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_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), misdn_overlap_dial_task(), park_call_full(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), process_ast_dsp(), register_peer_exten(), rpt_exec(), skinny_ss(), socket_process(), ss_thread(), waitstream_core(), and zt_handle_dtmfup().

02280 {
02281    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH);
02282 }

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 4569 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, 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().

04570 {
04571    if (!chan)
04572       return -1;
04573 
04574    ast_channel_lock(chan);
04575 
04576    if (!ast_strlen_zero(context))
04577       ast_copy_string(chan->context, context, sizeof(chan->context));
04578    if (!ast_strlen_zero(exten))
04579       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
04580    if (priority > -1) {
04581       chan->priority = priority;
04582       /* see flag description in channel.h for explanation */
04583       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
04584          chan->priority--;
04585    }
04586 
04587    ast_channel_unlock(chan);
04588 
04589    return 0;
04590 }

int ast_extension_close ( const char *  pattern,
const char *  data,
int  needmore 
)

Definition at line 883 of file pbx.c.

References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.

Referenced by realtime_switch_common().

00884 {
00885    if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
00886       ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
00887    return extension_match_core(pattern, data, needmore);
00888 }

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 878 of file pbx.c.

References E_MATCH, and extension_match_core().

Referenced by ast_ignore_pattern(), do_say(), find_matching_priority(), loopback_canmatch(), loopback_exec(), loopback_exists(), loopback_matchmore(), matchcid(), misdn_cfg_is_msn_valid(), realtime_switch_common(), and show_dialplan_helper().

00879 {
00880    return extension_match_core(pattern, data, E_MATCH);
00881 }

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 2003 of file pbx.c.

References ast_extension_state2(), and ast_hint_extension().

Referenced by action_extensionstate(), and handle_request_subscribe().

02004 {
02005    struct ast_exten *e;
02006 
02007    e = ast_hint_extension(c, context, exten);   /* Do we have a hint for this extension ? */
02008    if (!e)
02009       return -1;           /* No hint, return -1 */
02010 
02011    return ast_extension_state2(e);        /* Check all devices in the hint */
02012 }

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 1991 of file pbx.c.

References extension_states, and cfextension_states::text.

Referenced by __sip_show_channels(), cb_extensionstate(), handle_request_subscribe(), and handle_show_hints().

01992 {
01993    int i;
01994 
01995    for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) {
01996       if (extension_states[i].extension_state == extension_state)
01997          return extension_states[i].text;
01998    }
01999    return "Unknown";
02000 }

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 2058 of file pbx.c.

References ast_calloc, ast_hint_extension(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_hint::exten, ast_state_cb::id, ast_state_cb::next, statecbs, and stateid.

Referenced by handle_request_subscribe(), init_manager(), and load_module().

02060 {
02061    struct ast_hint *hint;
02062    struct ast_state_cb *cblist;
02063    struct ast_exten *e;
02064 
02065    /* If there's no context and extension:  add callback to statecbs list */
02066    if (!context && !exten) {
02067       AST_LIST_LOCK(&hints);
02068 
02069       for (cblist = statecbs; cblist; cblist = cblist->next) {
02070          if (cblist->callback == callback) {
02071             cblist->data = data;
02072             AST_LIST_UNLOCK(&hints);
02073             return 0;
02074          }
02075       }
02076 
02077       /* Now insert the callback */
02078       if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
02079          AST_LIST_UNLOCK(&hints);
02080          return -1;
02081       }
02082       cblist->id = 0;
02083       cblist->callback = callback;
02084       cblist->data = data;
02085 
02086       cblist->next = statecbs;
02087       statecbs = cblist;
02088 
02089       AST_LIST_UNLOCK(&hints);
02090       return 0;
02091    }
02092 
02093    if (!context || !exten)
02094       return -1;
02095 
02096    /* This callback type is for only one hint, so get the hint */
02097    e = ast_hint_extension(NULL, context, exten);
02098    if (!e) {
02099       return -1;
02100    }
02101 
02102    /* Find the hint in the list of hints */
02103    AST_LIST_LOCK(&hints);
02104 
02105    AST_LIST_TRAVERSE(&hints, hint, list) {
02106       if (hint->exten == e)
02107          break;
02108    }
02109 
02110    if (!hint) {
02111       /* We have no hint, sorry */
02112       AST_LIST_UNLOCK(&hints);
02113       return -1;
02114    }
02115 
02116    /* Now insert the callback in the callback list  */
02117    if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
02118       AST_LIST_UNLOCK(&hints);
02119       return -1;
02120    }
02121    cblist->id = stateid++;    /* Unique ID for this callback */
02122    cblist->callback = callback;  /* Pointer to callback routine */
02123    cblist->data = data;    /* Data for the callback */
02124 
02125    cblist->next = hint->callbacks;
02126    hint->callbacks = cblist;
02127 
02128    AST_LIST_UNLOCK(&hints);
02129    return cblist->id;
02130 }

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 2133 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_hint::callbacks, free, ast_state_cb::next, and statecbs.

Referenced by __sip_destroy(), and handle_request_subscribe().

02134 {
02135    struct ast_state_cb **p_cur = NULL; /* address of pointer to us */
02136    int ret = -1;
02137 
02138    if (!id && !callback)
02139       return -1;
02140 
02141    AST_LIST_LOCK(&hints);
02142 
02143    if (!id) {  /* id == 0 is a callback without extension */
02144       for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) {
02145          if ((*p_cur)->callback == callback)
02146             break;
02147       }
02148    } else { /* callback with extension, find the callback based on ID */
02149       struct ast_hint *hint;
02150       AST_LIST_TRAVERSE(&hints, hint, list) {
02151          for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) {
02152             if ((*p_cur)->id == id)
02153                break;
02154          }
02155          if (*p_cur) /* found in the inner loop */
02156             break;
02157       }
02158    }
02159    if (p_cur && *p_cur) {
02160       struct ast_state_cb *cur = *p_cur;
02161       *p_cur = cur->next;
02162       free(cur);
02163       ret = 0;
02164    }
02165    AST_LIST_UNLOCK(&hints);
02166    return ret;
02167 }

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
Returns:
the priority which matches the given label in the extension or -1 if not found.

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

02285 {
02286    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL);
02287 }

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:
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 2289 of file pbx.c.

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

02290 {
02291    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL);
02292 }

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

01534 {
01535    char *args = func_args(function);
01536    struct ast_custom_function *acfptr = ast_custom_function_find(function);
01537 
01538    if (acfptr == NULL)
01539       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01540    else if (!acfptr->read)
01541       ast_log(LOG_ERROR, "Function %s cannot be read\n", function);
01542    else
01543       return acfptr->read(chan, function, args, workspace, len);
01544    return -1;
01545 }

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

01548 {
01549    char *args = func_args(function);
01550    struct ast_custom_function *acfptr = ast_custom_function_find(function);
01551 
01552    if (acfptr == NULL)
01553       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01554    else if (!acfptr->write)
01555       ast_log(LOG_ERROR, "Function %s cannot be written to\n", function);
01556    else
01557       return acfptr->write(chan, function, args, value);
01558 
01559    return -1;
01560 }

const char* ast_get_context_name ( struct ast_context con  ) 

const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 6216 of file pbx.c.

References ast_context::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06217 {
06218    return c ? c->registrar : NULL;
06219 }

const char* ast_get_extension_app ( struct ast_exten e  ) 

void* ast_get_extension_app_data ( struct ast_exten e  ) 

Definition at line 6251 of file pbx.c.

References ast_exten::data.

Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().

06252 {
06253    return e ? e->data : NULL;
06254 }

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 6241 of file pbx.c.

References ast_exten::cidmatch.

Referenced by find_matching_priority(), and handle_save_dialplan().

06242 {
06243    return e ? e->cidmatch : NULL;
06244 }

struct ast_context* ast_get_extension_context ( struct ast_exten exten  )  [read]

Definition at line 6183 of file pbx.c.

References ast_exten::parent.

Referenced by handle_show_hints().

06184 {
06185    return exten ? exten->parent : NULL;
06186 }

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 6193 of file pbx.c.

References ast_exten::label.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06194 {
06195    return exten ? exten->label : NULL;
06196 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 6236 of file pbx.c.

References ast_exten::matchcid.

Referenced by find_matching_priority(), and handle_save_dialplan().

06237 {
06238    return e ? e->matchcid : 0;
06239 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 

int ast_get_extension_priority ( struct ast_exten exten  ) 

Definition at line 6208 of file pbx.c.

References ast_exten::priority.

Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), handle_save_dialplan(), and print_ext().

06209 {
06210    return exten ? exten->priority : -1;
06211 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 6221 of file pbx.c.

References ast_exten::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06222 {
06223    return e ? e->registrar : NULL;
06224 }

int ast_get_hint ( char *  hint,
int  hintsize,
char *  name,
int  namesize,
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 2262 of file pbx.c.

References ast_get_extension_app(), ast_get_extension_app_data(), and ast_hint_extension().

Referenced by action_extensionstate(), get_cid_name(), get_destination(), manager_state_cb(), pbx_retrieve_variable(), and transmit_state_notify().

02263 {
02264    struct ast_exten *e = ast_hint_extension(c, context, exten);
02265 
02266    if (e) {
02267       if (hint)
02268          ast_copy_string(hint, ast_get_extension_app(e), hintsize);
02269       if (name) {
02270          const char *tmp = ast_get_extension_app_data(e);
02271          if (tmp)
02272             ast_copy_string(name, tmp, namesize);
02273       }
02274       return -1;
02275    }
02276    return 0;
02277 }

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 

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

06204 {
06205    return ip ? ip->pattern : NULL;
06206 }

const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

Definition at line 6231 of file pbx.c.

References ast_ignorepat::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06232 {
06233    return ip ? ip->registrar : NULL;
06234 }

const char* ast_get_include_name ( struct ast_include include  ) 

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

06199 {
06200    return inc ? inc->name : NULL;
06201 }

const char* ast_get_include_registrar ( struct ast_include i  ) 

Definition at line 6226 of file pbx.c.

References ast_include::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06227 {
06228    return i ? i->registrar : NULL;
06229 }

const char* ast_get_switch_data ( struct ast_sw sw  ) 

Definition at line 6261 of file pbx.c.

References ast_sw::data.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06262 {
06263    return sw ? sw->data : NULL;
06264 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

Definition at line 6256 of file pbx.c.

References ast_sw::name.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06257 {
06258    return sw ? sw->name : NULL;
06259 }

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

Definition at line 6266 of file pbx.c.

References ast_sw::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06267 {
06268    return sw ? sw->registrar : NULL;
06269 }

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,
char *  cid_num,
char *  cid_name 
)

Definition at line 2014 of file pbx.c.

References ast_extension_state2(), ast_get_extension_app(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, AST_MAX_EXTENSION, ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_exten::exten, ast_hint::exten, ast_hint::laststate, ast_state_cb::next, ast_exten::parent, parse(), statecbs, and strsep().

Referenced by do_state_change().

02015 {
02016    struct ast_hint *hint;
02017 
02018    AST_LIST_LOCK(&hints);
02019 
02020    AST_LIST_TRAVERSE(&hints, hint, list) {
02021       struct ast_state_cb *cblist;
02022       char buf[AST_MAX_EXTENSION];
02023       char *parse = buf;
02024       char *cur;
02025       int state;
02026 
02027       ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf));
02028       while ( (cur = strsep(&parse, "&")) ) {
02029          if (!strcasecmp(cur, device))
02030             break;
02031       }
02032       if (!cur)
02033          continue;
02034 
02035       /* Get device state for this hint */
02036       state = ast_extension_state2(hint->exten);
02037 
02038       if ((state == -1) || (state == hint->laststate))
02039          continue;
02040 
02041       /* Device state changed since last check - notify the watchers */
02042 
02043       /* For general callbacks */
02044       for (cblist = statecbs; cblist; cblist = cblist->next)
02045          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data, cid_num, cid_name);
02046 
02047       /* For extension callbacks */
02048       for (cblist = hint->callbacks; cblist; cblist = cblist->next)
02049          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data, cid_num, cid_name);
02050 
02051       hint->laststate = state;   /* record we saw the change */
02052    }
02053 
02054    AST_LIST_UNLOCK(&hints);
02055 }

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

04536 {
04537    struct ast_context *con = ast_context_find(context);
04538    if (con) {
04539       struct ast_ignorepat *pat;
04540       for (pat = con->ignorepats; pat; pat = pat->next) {
04541          if (ast_extension_match(pat->pattern, pattern))
04542             return 1;
04543       }
04544    }
04545 
04546    return 0;
04547 }

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

06166 {
06167    return ast_mutex_lock(&con->lock);
06168 }

int ast_lock_contexts ( void   ) 

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
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 2299 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(), skinny_ss(), and ss_thread().

02300 {
02301    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE);
02302 }

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 3929 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, ast_hint::callbacks, context, contexts, ast_state_cb::data, E_MATCH, ast_exten::exten, ast_hint::exten, exten, free, ast_hint::laststate, LOG_DEBUG, LOG_WARNING, ast_state_cb::next, ast_context::next, option_debug, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_context::registrar, and pbx_find_info::stacklen.

Referenced by pbx_load_module().

03930 {
03931    struct ast_context *tmp, *lasttmp = NULL;
03932    struct store_hints store = AST_LIST_HEAD_INIT_VALUE;
03933    struct store_hint *this;
03934    struct ast_hint *hint;
03935    struct ast_exten *exten;
03936    int length;
03937    struct ast_state_cb *thiscb, *prevcb;
03938 
03939    /* it is very important that this function hold the hint list lock _and_ the conlock
03940       during its operation; not only do we need to ensure that the list of contexts
03941       and extensions does not change, but also that no hint callbacks (watchers) are
03942       added or removed during the merge/delete process
03943 
03944       in addition, the locks _must_ be taken in this order, because there are already
03945       other code paths that use this order
03946    */
03947    ast_wrlock_contexts();
03948    AST_LIST_LOCK(&hints);
03949 
03950    /* preserve all watchers for hints associated with this registrar */
03951    AST_LIST_TRAVERSE(&hints, hint, list) {
03952       if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) {
03953          length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this);
03954          if (!(this = ast_calloc(1, length)))
03955             continue;
03956          this->callbacks = hint->callbacks;
03957          hint->callbacks = NULL;
03958          this->laststate = hint->laststate;
03959          this->context = this->data;
03960          strcpy(this->data, hint->exten->parent->name);
03961          this->exten = this->data + strlen(this->context) + 1;
03962          strcpy(this->exten, hint->exten->exten);
03963          AST_LIST_INSERT_HEAD(&store, this, list);
03964       }
03965    }
03966 
03967    tmp = *extcontexts;
03968    if (registrar) {
03969       /* XXX remove previous contexts from same registrar */
03970       if (option_debug)
03971          ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar);
03972       __ast_context_destroy(NULL,registrar);
03973       while (tmp) {
03974          lasttmp = tmp;
03975          tmp = tmp->next;
03976       }
03977    } else {
03978       /* XXX remove contexts with the same name */
03979       while (tmp) {
03980          ast_log(LOG_WARNING, "must remove %s  reg %s\n", tmp->name, tmp->registrar);
03981          __ast_context_destroy(tmp,tmp->registrar);
03982          lasttmp = tmp;
03983          tmp = tmp->next;
03984       }
03985    }
03986    if (lasttmp) {
03987       lasttmp->next = contexts;
03988       contexts = *extcontexts;
03989       *extcontexts = NULL;
03990    } else
03991       ast_log(LOG_WARNING, "Requested contexts didn't get merged\n");
03992 
03993    /* restore the watchers for hints that can be found; notify those that
03994       cannot be restored
03995    */
03996    while ((this = AST_LIST_REMOVE_HEAD(&store, list))) {
03997       struct pbx_find_info q = { .stacklen = 0 };
03998       exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH);
03999       /* Find the hint in the list of hints */
04000       AST_LIST_TRAVERSE(&hints, hint, list) {
04001          if (hint->exten == exten)
04002             break;
04003       }
04004       if (!exten || !hint) {
04005          /* this hint has been removed, notify the watchers */
04006          prevcb = NULL;
04007          thiscb = this->callbacks;
04008          while (thiscb) {
04009             prevcb = thiscb;
04010             thiscb = thiscb->next;
04011             prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data, NULL, NULL);
04012             free(prevcb);
04013             }
04014       } else {
04015          thiscb = this->callbacks;
04016          while (thiscb->next)
04017             thiscb = thiscb->next;
04018          thiscb->next = hint->callbacks;
04019          hint->callbacks = this->callbacks;
04020          hint->laststate = this->laststate;
04021       }
04022       free(this);
04023    }
04024 
04025    AST_LIST_UNLOCK(&hints);
04026    ast_unlock_contexts();
04027 
04028    return;
04029 }

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 6365 of file pbx.c.

References ast_cdr_update(), ast_explicit_goto(), ast_findlabel_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, exten, LOG_WARNING, ast_channel::priority, and strsep().

Referenced by _while_exec(), check_goto_on_transfer(), gosub_exec(), ivr_dispatch(), pbx_builtin_goto(), random_exec(), return_exec(), and while_continue_exec().

06366 {
06367    char *exten, *pri, *context;
06368    char *stringp;
06369    int ipri;
06370    int mode = 0;
06371 
06372    if (ast_strlen_zero(goto_string)) {
06373       ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
06374       return -1;
06375    }
06376    stringp = ast_strdupa(goto_string);
06377    context = strsep(&stringp, "|"); /* guaranteed non-null */
06378    exten = strsep(&stringp, "|");
06379    pri = strsep(&stringp, "|");
06380    if (!exten) {  /* Only a priority in this one */
06381       pri = context;
06382       exten = NULL;
06383       context = NULL;
06384    } else if (!pri) {   /* Only an extension and priority in this one */
06385       pri = exten;
06386       exten = context;
06387       context = NULL;
06388    }
06389    if (*pri == '+') {
06390       mode = 1;
06391       pri++;
06392    } else if (*pri == '-') {
06393       mode = -1;
06394       pri++;
06395    }
06396    if (sscanf(pri, "%d", &ipri) != 1) {
06397       if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten,
06398          pri, chan->cid.cid_num)) < 1) {
06399          ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);
06400          return -1;
06401       } else
06402          mode = 0;
06403    }
06404    /* At this point we have a priority and maybe an extension and a context */
06405 
06406    if (mode)
06407       ipri = chan->priority + (ipri * mode);
06408 
06409    ast_explicit_goto(chan, context, exten, ipri);
06410    ast_cdr_update(chan);
06411    return 0;
06412 
06413 }

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 5294 of file pbx.c.

References ast_pbx_outgoing_app2().

Referenced by attempt_thread(), and orig_app().

05295 {
05296     return ast_pbx_outgoing_app2(type, format, data, timeout, app, appdata, reason, sync, 0, cid_num, cid_name, vars, account, locked_channel, NULL);
05297 }

int ast_pbx_outgoing_app2 ( const char *  type,
int  format,
void *  data,
int  timeout,
const char *  app,
const char *  appdata,
int *  reason,
int  sync,
int  callingpres,
const char *  cid_num,
const char *  cid_name,
struct ast_variable vars,
const char *  account,
struct ast_channel **  locked_channel,
char *  uniqueid 
)

Synchronously or asynchronously make an outbound call and send it to a particular application with given extension (extended version with callinpres and uniqueid)

Definition at line 5151 of file pbx.c.

References __ast_request_and_dial(), ast_channel::_state, outgoing_helper::account, async_stat::app, app_tmp::app, async_stat::appdata, ast_calloc, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), ast_channel_lock, ast_channel_unlock, 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(), ast_channel::cdr, async_stat::chan, app_tmp::chan, app_tmp::data, errno, free, ast_channel::hangupcause, LOG_WARNING, option_verbose, async_stat::p, ast_channel::pbx, app_tmp::t, async_stat::timeout, outgoing_helper::vars, and VERBOSE_PREFIX_4.

Referenced by action_originate(), ast_pbx_outgoing_app(), and fast_originate().

05152 {
05153    struct ast_channel *chan;
05154    struct app_tmp *tmp;
05155    int res = -1, cdr_res = -1;
05156    struct outgoing_helper oh;
05157    pthread_attr_t attr;
05158 
05159    memset(&oh, 0, sizeof(oh));
05160    oh.vars = vars;
05161    oh.account = account;
05162 
05163    if (locked_channel)
05164       *locked_channel = NULL;
05165    if (ast_strlen_zero(app)) {
05166       res = -1;
05167       goto outgoing_app_cleanup;
05168    }
05169    if (sync) {
05170       chan = __ast_request_and_dial(type, format, data, timeout, reason, callingpres, cid_num, cid_name, &oh, uniqueid);
05171       if (chan) {
05172          if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */
05173             ast_log(LOG_WARNING, "%s already has a call detail record??\n", chan->name);
05174          } else {
05175             chan->cdr = ast_cdr_alloc();   /* allocate a cdr for the channel */
05176             if(!chan->cdr) {
05177                /* allocation of the cdr failed */
05178                free(chan->pbx);
05179                res = -1;
05180                goto outgoing_app_cleanup;
05181             }
05182             /* allocation of the cdr was successful */
05183             ast_cdr_init(chan->cdr, chan);  /* initilize our channel's cdr */
05184             ast_cdr_start(chan->cdr);
05185          }
05186          ast_set_variables(chan, vars);
05187          if (account)
05188             ast_cdr_setaccount(chan, account);
05189          if (chan->_state == AST_STATE_UP) {
05190             res = 0;
05191             if (option_verbose > 3)
05192                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
05193             tmp = ast_calloc(1, sizeof(*tmp));
05194             if (!tmp)
05195                res = -1;
05196             else {
05197                ast_copy_string(tmp->app, app, sizeof(tmp->app));
05198                if (appdata)
05199                   ast_copy_string(tmp->data, appdata, sizeof(tmp->data));
05200                tmp->chan = chan;
05201                if (sync > 1) {
05202                   if (locked_channel)
05203                      ast_channel_unlock(chan);
05204                   ast_pbx_run_app(tmp);
05205                } else {
05206                   pthread_attr_init(&attr);
05207                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05208                   if (locked_channel)
05209                      ast_channel_lock(chan);
05210                   if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) {
05211                      ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
05212                      free(tmp);
05213                      if (locked_channel)
05214                         ast_channel_unlock(chan);
05215                      ast_hangup(chan);
05216                      res = -1;
05217                   } else {
05218                      if (locked_channel)
05219                         *locked_channel = chan;
05220                   }
05221                   pthread_attr_destroy(&attr);
05222                }
05223             }
05224          } else {
05225             if (option_verbose > 3)
05226                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
05227             if (chan->cdr) { /* update the cdr */
05228                /* here we update the status of the call, which sould be busy.
05229                 * if that fails then we set the status to failed */
05230                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
05231                   ast_cdr_failed(chan->cdr);
05232             }
05233             ast_hangup(chan);
05234          }
05235       }
05236 
05237       if (res < 0) { /* the call failed for some reason */
05238          if (*reason == 0) { /* if the call failed (not busy or no answer)
05239                         * update the cdr with the failed message */
05240             cdr_res = ast_pbx_outgoing_cdr_failed();
05241             if (cdr_res != 0) {
05242                res = cdr_res;
05243                goto outgoing_app_cleanup;
05244             }
05245          }
05246       }
05247 
05248    } else {
05249       struct async_stat *as;
05250       if (!(as = ast_calloc(1, sizeof(*as)))) {
05251          res = -1;
05252          goto outgoing_app_cleanup;
05253       }
05254       chan = __ast_request_and_dial(type, format, data, timeout, reason, callingpres, cid_num, cid_name, &oh, uniqueid);
05255       if (!chan) {
05256          free(as);
05257          res = -1;
05258          goto outgoing_app_cleanup;
05259       }
05260       as->chan = chan;
05261       ast_copy_string(as->app, app, sizeof(as->app));
05262       if (appdata)
05263          ast_copy_string(as->appdata,  appdata, sizeof(as->appdata));
05264       as->timeout = timeout;
05265       ast_set_variables(chan, vars);
05266       if (account)
05267          ast_cdr_setaccount(chan, account);
05268       /* Start a new thread, and get something handling this channel. */
05269       pthread_attr_init(&attr);
05270       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05271       if (locked_channel)
05272          ast_channel_lock(chan);
05273       if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
05274          ast_log(LOG_WARNING, "Failed to start async wait\n");
05275          free(as);
05276          if (locked_channel)
05277             ast_channel_unlock(chan);
05278          ast_hangup(chan);
05279          res = -1;
05280          pthread_attr_destroy(&attr);
05281          goto outgoing_app_cleanup;
05282       } else {
05283          if (locked_channel)
05284             *locked_channel = chan;
05285       }
05286       pthread_attr_destroy(&attr);
05287       res = 0;
05288    }
05289 outgoing_app_cleanup:
05290    ast_variables_destroy(vars);
05291    return res;
05292 }

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 5123 of file pbx.c.

References ast_pbx_outgoing_exten2().

Referenced by attempt_thread(), and orig_exten().

05124 {
05125     return ast_pbx_outgoing_exten2(type, format, data, timeout, context, exten, priority, reason, sync, 0, cid_num, cid_name, vars, account, channel, NULL);
05126 }

int ast_pbx_outgoing_exten2 ( const char *  type,
int  format,
void *  data,
int  timeout,
const char *  context,
const char *  exten,
int  priority,
int *  reason,
int  sync,
int  callingpres,
const char *  cid_num,
const char *  cid_name,
struct ast_variable vars,
const char *  account,
struct ast_channel **  locked_channel,
char *  uniqueid 
)

Synchronously or asynchronously make an outbound call and send it to a particular extension (extended version with callinpres and uniqueid)

Definition at line 4988 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_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, async_stat::chan, async_stat::context, ast_channel::context, free, ast_channel::hangupcause, LOAD_OH, LOG_ERROR, LOG_WARNING, option_verbose, async_stat::p, pbx_builtin_setvar_helper(), set_ext_pri(), async_stat::timeout, and VERBOSE_PREFIX_4.

Referenced by action_originate(), ast_pbx_outgoing_exten(), and fast_originate().

04989 {
04990    struct ast_channel *chan;
04991    struct async_stat *as;
04992    int res = -1, cdr_res = -1;
04993    struct outgoing_helper oh;
04994    pthread_attr_t attr;
04995 
04996    if (sync) {
04997       LOAD_OH(oh);
04998       chan = __ast_request_and_dial(type, format, data, timeout, reason, callingpres, cid_num, cid_name, &oh, uniqueid);
04999       if (channel) {
05000          *channel = chan;
05001          if (chan)
05002             ast_channel_lock(chan);
05003       }
05004       if (chan) {
05005          if (chan->_state == AST_STATE_UP) {
05006                res = 0;
05007             if (option_verbose > 3)
05008                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
05009 
05010             if (sync > 1) {
05011                if (channel)
05012                   ast_channel_unlock(chan);
05013                if (ast_pbx_run(chan)) {
05014                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
05015                   if (channel)
05016                      *channel = NULL;
05017                   ast_hangup(chan);
05018                   res = -1;
05019                }
05020             } else {
05021                if (ast_pbx_start(chan)) {
05022                   ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name);
05023                   if (channel) {
05024                      *channel = NULL;
05025                      ast_channel_unlock(chan);
05026                   }
05027                   ast_hangup(chan);
05028                   res = -1;
05029                }
05030             }
05031          } else {
05032             if (option_verbose > 3)
05033                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
05034 
05035             if (chan->cdr) { /* update the cdr */
05036                /* here we update the status of the call, which sould be busy.
05037                 * if that fails then we set the status to failed */
05038                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
05039                   ast_cdr_failed(chan->cdr);
05040             }
05041 
05042             if (channel) {
05043                *channel = NULL;
05044                ast_channel_unlock(chan);
05045             }
05046             ast_hangup(chan);
05047          }
05048       }
05049 
05050       if (res < 0) { /* the call failed for some reason */
05051          if (*reason == 0) { /* if the call failed (not busy or no answer)
05052                         * update the cdr with the failed message */
05053             cdr_res = ast_pbx_outgoing_cdr_failed();
05054             if (cdr_res != 0) {
05055                res = cdr_res;
05056                goto outgoing_exten_cleanup;
05057             }
05058          }
05059 
05060          /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */
05061          /* check if "failed" exists */
05062          if (ast_exists_extension(chan, context, "failed", 1, NULL)) {
05063             chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed");
05064             if (chan) {
05065                char failed_reason[4] = "";
05066                if (!ast_strlen_zero(context))
05067                   ast_copy_string(chan->context, context, sizeof(chan->context));
05068                set_ext_pri(chan, "failed", 1);
05069                ast_set_variables(chan, vars);
05070                snprintf(failed_reason, sizeof(failed_reason), "%d", *reason);
05071                pbx_builtin_setvar_helper(chan, "REASON", failed_reason);
05072                if (account)
05073                   ast_cdr_setaccount(chan, account);
05074                ast_pbx_run(chan);
05075             }
05076          }
05077       }
05078    } else {
05079       if (!(as = ast_calloc(1, sizeof(*as)))) {
05080          res = -1;
05081          goto outgoing_exten_cleanup;
05082       }
05083       chan = ast_request_and_dial(type, format, data, timeout, reason, callingpres, cid_num, cid_name, uniqueid);
05084       if (channel) {
05085          *channel = chan;
05086          if (chan)
05087             ast_channel_lock(chan);
05088       }
05089       if (!chan) {
05090          free(as);
05091          res = -1;
05092          goto outgoing_exten_cleanup;
05093       }
05094       as->chan = chan;
05095       ast_copy_string(as->context, context, sizeof(as->context));
05096       set_ext_pri(as->chan,  exten, priority);
05097       as->timeout = timeout;
05098       ast_set_variables(chan, vars);
05099       if (account)
05100          ast_cdr_setaccount(chan, account);
05101       pthread_attr_init(&attr);
05102       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05103       if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
05104          ast_log(LOG_WARNING, "Failed to start async wait\n");
05105          free(as);
05106          if (channel) {
05107             *channel = NULL;
05108             ast_channel_unlock(chan);
05109          }
05110          ast_hangup(chan);
05111          res = -1;
05112          pthread_attr_destroy(&attr);
05113          goto outgoing_exten_cleanup;
05114       }
05115       pthread_attr_destroy(&attr);
05116       res = 0;
05117    }
05118 outgoing_exten_cleanup:
05119    ast_variables_destroy(vars);
05120    return res;
05121 }

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 2657 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_exten2(), async_wait(), mgcp_ss(), skinny_newcall(), and ss_thread().

02658 {
02659    enum ast_pbx_result res = AST_PBX_SUCCESS;
02660 
02661    if (increase_call_count(c))
02662       return AST_PBX_CALL_LIMIT;
02663 
02664    res = __ast_pbx_run(c);
02665    decrease_call_count();
02666 
02667    return res;
02668 }

void* ast_pbx_run_app ( void *  data  ) 

run the application and free the descriptor once done

Definition at line 5135 of file pbx.c.

References app_tmp::app, ast_hangup(), ast_log(), ast_verbose(), app_tmp::chan, app_tmp::data, free, LOG_WARNING, option_verbose, pbx_exec(), pbx_findapp(), and VERBOSE_PREFIX_4.

Referenced by ast_pbx_outgoing_app2().

05136 {
05137    struct app_tmp *tmp = data;
05138    struct ast_app *app;
05139    app = pbx_findapp(tmp->app);
05140    if (app) {
05141       if (option_verbose > 3)
05142          ast_verbose(VERBOSE_PREFIX_4 "Launching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name);
05143       pbx_exec(tmp->chan, app, tmp->data);
05144    } else
05145       ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app);
05146    ast_hangup(tmp->chan);
05147    free(tmp);
05148    return NULL;
05149 }

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 2631 of file pbx.c.

References ast_log(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_pthread_create, increase_call_count(), LOG_WARNING, pbx_thread(), and t.

Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_exten2(), check_goto_on_transfer(), 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(), skinny_new(), and zt_new().

02632 {
02633    pthread_t t;
02634    pthread_attr_t attr;
02635 
02636    if (!c) {
02637       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
02638       return AST_PBX_FAILED;
02639    }
02640 
02641    if (increase_call_count(c))
02642       return AST_PBX_CALL_LIMIT;
02643 
02644    /* Start a new thread, and get something handling this channel. */
02645    pthread_attr_init(&attr);
02646    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
02647    if (ast_pthread_create(&t, &attr, pbx_thread, c)) {
02648       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
02649       pthread_attr_destroy(&attr);
02650       return AST_PBX_FAILED;
02651    }
02652    pthread_attr_destroy(&attr);
02653 
02654    return AST_PBX_SUCCESS;
02655 }

int ast_rdlock_contexts ( void   ) 

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 2959 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, LOG_WARNING, option_verbose, ast_app::synopsis, term_color(), and VERBOSE_PREFIX_2.

Referenced by load_module(), and load_pbx().

02960 {
02961    struct ast_app *tmp, *cur = NULL;
02962    char tmps[80];
02963    int length;
02964 
02965    AST_LIST_LOCK(&apps);
02966    AST_LIST_TRAVERSE(&apps, tmp, list) {
02967       if (!strcasecmp(app, tmp->name)) {
02968          ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
02969          AST_LIST_UNLOCK(&apps);
02970          return -1;
02971       }
02972    }
02973 
02974    length = sizeof(*tmp) + strlen(app) + 1;
02975 
02976    if (!(tmp = ast_calloc(1, length))) {
02977       AST_LIST_UNLOCK(&apps);
02978       return -1;
02979    }
02980 
02981    strcpy(tmp->name, app);
02982    tmp->execute = execute;
02983    tmp->synopsis = synopsis;
02984    tmp->description = description;
02985 
02986    /* Store in alphabetical order */
02987    AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) {
02988       if (strcasecmp(tmp->name, cur->name) < 0) {
02989          AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list);
02990          break;
02991       }
02992    }
02993    AST_LIST_TRAVERSE_SAFE_END
02994    if (!cur)
02995       AST_LIST_INSERT_TAIL(&apps, tmp, list);
02996 
02997    if (option_verbose > 1)
02998       ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
02999 
03000    AST_LIST_UNLOCK(&apps);
03001 
03002    return 0;
03003 }

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 3009 of file pbx.c.

References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), LOG_WARNING, and ast_switch::name.

Referenced by load_module().

03010 {
03011    struct ast_switch *tmp;
03012 
03013    AST_LIST_LOCK(&switches);
03014    AST_LIST_TRAVERSE(&switches, tmp, list) {
03015       if (!strcasecmp(tmp->name, sw->name)) {
03016          AST_LIST_UNLOCK(&switches);
03017          ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
03018          return -1;
03019       }
03020    }
03021    AST_LIST_INSERT_TAIL(&switches, sw, list);
03022    AST_LIST_UNLOCK(&switches);
03023 
03024    return 0;
03025 }

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.

Return values:
0 on success
-1 on failure.

Definition at line 2304 of file pbx.c.

References E_SPAWN, and pbx_extension_helper().

Referenced by __ast_pbx_run(), _macro_exec(), and loopback_exec().

02305 {
02306    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN);
02307 }

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

06171 {
06172    return ast_mutex_unlock(&con->lock);
06173 }

int ast_unlock_contexts ( void   ) 

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 3840 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, option_verbose, and VERBOSE_PREFIX_2.

Referenced by __unload_module(), and unload_module().

03841 {
03842    struct ast_app *tmp;
03843 
03844    AST_LIST_LOCK(&apps);
03845    AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) {
03846       if (!strcasecmp(app, tmp->name)) {
03847          AST_LIST_REMOVE_CURRENT(&apps, list);
03848          if (option_verbose > 1)
03849             ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
03850          free(tmp);
03851          break;
03852       }
03853    }
03854    AST_LIST_TRAVERSE_SAFE_END
03855    AST_LIST_UNLOCK(&apps);
03856 
03857    return tmp ? 0 : -1;
03858 }

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 3027 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_REMOVE, and AST_LIST_UNLOCK.

Referenced by __unload_module(), and unload_module().

03028 {
03029    AST_LIST_LOCK(&switches);
03030    AST_LIST_REMOVE(&switches, sw, list);
03031    AST_LIST_UNLOCK(&switches);
03032 }

struct ast_exten* ast_walk_context_extensions ( struct ast_context con,
struct ast_exten priority 
) [read]

Definition at line 6279 of file pbx.c.

References ast_exten::next, and ast_context::root.

Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), dundi_precache_full(), find_matching_priority(), handle_save_dialplan(), pbx_find_extension(), and show_dialplan_helper().

06281 {
06282    if (!exten)
06283       return con ? con->root : NULL;
06284    else
06285       return exten->next;
06286 }

struct ast_ignorepat* ast_walk_context_ignorepats ( struct ast_context con,
struct ast_ignorepat ip 
) [read]

Definition at line 6312 of file pbx.c.

References ast_context::ignorepats, and ast_ignorepat::next.

Referenced by complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), handle_save_dialplan(), lookup_c_ip(), and show_dialplan_helper().

06314 {
06315    if (!ip)
06316       return con ? con->ignorepats : NULL;
06317    else
06318       return ip->next;
06319 }

struct ast_include* ast_walk_context_includes ( struct ast_context con,
struct ast_include inc 
) [read]

Definition at line 6303 of file pbx.c.

References ast_context::includes, and ast_include::next.

Referenced by ast_context_verify_includes(), complete_context_dont_include_deprecated(), complete_context_remove_include(), find_matching_priority(), handle_save_dialplan(), lookup_ci(), and show_dialplan_helper().

06305 {
06306    if (!inc)
06307       return con ? con->includes : NULL;
06308    else
06309       return inc->next;
06310 }

struct ast_sw* ast_walk_context_switches ( struct ast_context con,
struct ast_sw sw 
) [read]

Definition at line 6288 of file pbx.c.

References AST_LIST_FIRST, and AST_LIST_NEXT.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06290 {
06291    if (!sw)
06292       return con ? AST_LIST_FIRST(&con->alts) : NULL;
06293    else
06294       return AST_LIST_NEXT(sw, list);
06295 }

struct ast_context* ast_walk_contexts ( struct ast_context con  )  [read]

struct ast_exten* ast_walk_extension_priorities ( struct ast_exten exten,
struct ast_exten priority 
) [read]

Definition at line 6297 of file pbx.c.

References ast_exten::peer.

Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), handle_save_dialplan(), pbx_find_extension(), and show_dialplan_helper().

06299 {
06300    return priority ? priority->peer : exten;
06301 }

int ast_wrlock_contexts ( void   ) 

Definition at line 6152 of file pbx.c.

References ast_rwlock_wrlock().

Referenced by __ast_context_create(), ast_context_destroy(), and ast_merge_contexts_and_delete().

06153 {
06154    return ast_rwlock_wrlock(&conlock);
06155 }

void pbx_builtin_clear_globals ( void   ) 

Definition at line 6003 of file pbx.c.

References AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), ast_var_delete(), and globals.

Referenced by handle_reload_extensions(), and reload().

06004 {
06005    struct ast_var_t *vardata;
06006 
06007    ast_mutex_lock(&globalslock);
06008    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
06009       ast_var_delete(vardata);
06010    ast_mutex_unlock(&globalslock);
06011 }

const char* pbx_builtin_getvar_helper ( struct ast_channel chan,
const char *  name 
)

Note:
Will lock the channel.

Definition at line 5780 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), globals, and ast_channel::varshead.

Referenced by __ast_pbx_run(), __login_exec(), _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), ast_bridge_call(), ast_channel_bridge(), ast_feature_interpret(), ast_monitor_stop(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dundi_exec(), dundi_helper(), get_also_info(), get_index(), get_refer_info(), global_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_call_full(), pickup_by_mark(), queue_exec(), real_ctx(), retrydial_exec(), return_exec(), run_agi(), set_config_flags(), sip_addheader(), sla_trunk_exec(), speech_background(), try_calling(), try_suggested_sip_codec(), wait_for_answer(), zt_call(), and zt_hangup().

05781 {
05782    struct ast_var_t *variables;
05783    const char *ret = NULL;
05784    int i;
05785    struct varshead *places[2] = { NULL, &globals };
05786 
05787    if (!name)
05788       return NULL;
05789 
05790    if (chan) {
05791       ast_channel_lock(chan);
05792       places[0] = &chan->varshead;
05793    }
05794 
05795    for (i = 0; i < 2; i++) {
05796       if (!places[i])
05797          continue;
05798       if (places[i] == &globals)
05799          ast_mutex_lock(&globalslock);
05800       AST_LIST_TRAVERSE(places[i], variables, entries) {
05801          if (!strcmp(name, ast_var_name(variables))) {
05802             ret = ast_var_value(variables);
05803             break;
05804          }
05805       }
05806       if (places[i] == &globals)
05807          ast_mutex_unlock(&globalslock);
05808       if (ret)
05809          break;
05810    }
05811 
05812    if (chan)
05813       ast_channel_unlock(chan);
05814 
05815    return ret;
05816 }

void pbx_builtin_pushvar_helper ( struct ast_channel chan,
const char *  name,
const char *  value 
)

Note:
Will lock the channel.

Definition at line 5818 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_verbose(), globals, LOG_WARNING, option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2.

Referenced by acf_odbc_read(), acf_odbc_write(), and gosub_exec().

05819 {
05820    struct ast_var_t *newvariable;
05821    struct varshead *headp;
05822 
05823    if (name[strlen(name)-1] == ')') {
05824       char *function = ast_strdupa(name);
05825 
05826       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
05827       ast_func_write(chan, function, value);
05828       return;
05829    }
05830 
05831    if (chan) {
05832       ast_channel_lock(chan);
05833       headp = &chan->varshead;
05834    } else {
05835       ast_mutex_lock(&globalslock);
05836       headp = &globals;
05837    }
05838 
05839    if (value) {
05840       if ((option_verbose > 1) && (headp == &globals))
05841          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05842       newvariable = ast_var_assign(name, value);
05843       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05844    }
05845 
05846    if (chan)
05847       ast_channel_unlock(chan);
05848    else
05849       ast_mutex_unlock(&globalslock);
05850 }

int pbx_builtin_serialize_variables ( struct ast_channel chan,
char *  buf,
size_t  size 
)

Note:
Will lock the channel.

Definition at line 5749 of file pbx.c.

References ast_build_string(), ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_var_name(), ast_var_value(), LOG_ERROR, total, var, and ast_channel::varshead.

Referenced by dumpchan_exec(), handle_showchan(), handle_showchan_deprecated(), and vars2manager().

05750 {
05751    struct ast_var_t *variables;
05752    const char *var, *val;
05753    int total = 0;
05754 
05755    if (!chan)
05756       return 0;
05757 
05758    memset(buf, 0, size);
05759 
05760    ast_channel_lock(chan);
05761 
05762    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
05763       if ((var=ast_var_name(variables)) && (val=ast_var_value(variables))
05764          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
05765          ) {
05766          if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) {
05767             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
05768             break;
05769          } else
05770             total++;
05771       } else
05772          break;
05773    }
05774 
05775    ast_channel_unlock(chan);
05776 
05777    return total;
05778 }

int pbx_builtin_setvar ( struct ast_channel chan,
void *  data 
)

Note:
Will lock the channel.

void pbx_builtin_setvar_helper ( struct ast_channel chan,
const char *  name,
const char *  value 
)

Note:
Will lock the channel.

Definition at line 5852 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verbose(), globals, option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2.

Referenced by __ast_pbx_run(), __login_exec(), __oh323_new(), _macro_exec(), _while_exec(), acf_odbc_read(), acf_odbc_write(), action_setvar(), agi_exec_full(), aji_status_exec(), app_exec(), aqm_exec(), array(), ast_bridge_call(), ast_channel_bridge(), ast_feature_request_and_dial(), ast_iax2_new(), ast_monitor_start(), ast_pbx_outgoing_exten2(), ast_set_variables(), background_detect_exec(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), conf_run(), controlplayback_exec(), count_exec(), disa_exec(), do_waiting(), export_aoc_vars(), export_ch(), function_db_delete(), function_db_exists(), function_db_read(), global_write(), handle_request_bye(), handle_request_refer(), handle_set_global(), handle_set_global_deprecated(), handle_setvariable(), hasvoicemail_exec(), isAnsweringMachine(), leave_voicemail(), local_hangup(), lookupblacklist_exec(), misdn_call(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_exec(), parse_moved_contact(), pbx_builtin_importvar(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_load_config(), play_message_datetime(), playback_exec(), pop_exec(), pqm_exec(), prep_email_sub_vars(), privacy_exec(), process_ast_dsp(), read_exec(), readfile_exec(), realtime_exec(), realtime_update_exec(), record_exec(), return_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_hangup(), sip_new(), sla_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), ss_thread(), start_monitor_exec(), system_exec_helper(), transfer_exec(), try_calling(), tryexec_exec(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), zt_handle_dtmfup(), and zt_new().

05853 {
05854    struct ast_var_t *newvariable;
05855    struct varshead *headp;
05856    const char *nametail = name;
05857 
05858    if (name[strlen(name)-1] == ')') {
05859       char *function = ast_strdupa(name);
05860 
05861       ast_func_write(chan, function, value);
05862       return;
05863    }
05864 
05865    if (chan) {
05866       ast_channel_lock(chan);
05867       headp = &chan->varshead;
05868    } else {
05869       ast_mutex_lock(&globalslock);
05870       headp = &globals;
05871    }
05872 
05873    /* For comparison purposes, we have to strip leading underscores */
05874    if (*nametail == '_') {
05875       nametail++;
05876       if (*nametail == '_')
05877          nametail++;
05878    }
05879 
05880    AST_LIST_TRAVERSE (headp, newvariable, entries) {
05881       if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
05882          /* there is already such a variable, delete it */
05883          AST_LIST_REMOVE(headp, newvariable, entries);
05884          ast_var_delete(newvariable);
05885          break;
05886       }
05887    }
05888 
05889    if (value) {
05890       if ((option_verbose > 1) && (headp == &globals))
05891          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05892       newvariable = ast_var_assign(name, value);
05893       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05894    }
05895 
05896    if (chan)
05897       ast_channel_unlock(chan);
05898    else
05899       ast_mutex_unlock(&globalslock);
05900 }

int pbx_checkcondition ( const char *  condition  ) 

Evaluate a condition.

Return values:
0 if the condition is NULL or of zero length
int If the string is an integer, the integer representation of the integer is returned
1 Any other non-empty string

Definition at line 6013 of file pbx.c.

References ast_strlen_zero().

Referenced by _macro_exec(), _while_exec(), acf_if(), execif_exec(), gosubif_exec(), macroif_exec(), and pbx_builtin_gotoif().

06014 {
06015    if (ast_strlen_zero(condition))  /* NULL or empty strings are false */
06016       return 0;
06017    else if (*condition >= '0' && *condition <= '9')   /* Numbers are evaluated for truth */
06018       return atoi(condition);
06019    else  /* Strings are true */
06020       return 1;
06021 }

int pbx_exec ( struct ast_channel c,
struct ast_app app,
void *  data 
)

Execute an application.

Parameters:
c channel to execute on
app which app to execute
data the data passed into the app
This application executes an application on a given channel. It saves the stack and executes the given appliation passing in the given data.

Returns:
0 on success, and -1 on failure
Parameters:
c  Channel
app  Application
data  Data for execution

Definition at line 510 of file pbx.c.

References ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_channel::cdr, ast_channel::data, and ast_app::execute.

Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().

00513 {
00514    int res;
00515 
00516    const char *saved_c_appl;
00517    const char *saved_c_data;
00518 
00519    if (c->cdr &&  !ast_check_hangup(c))
00520       ast_cdr_setapp(c->cdr, app->name, data);
00521 
00522    /* save channel values */
00523    saved_c_appl= c->appl;
00524    saved_c_data= c->data;
00525 
00526    c->appl = app->name;
00527    c->data = data;
00528    /* XXX remember what to to when we have linked apps to modules */
00529    if (app->module) {
00530       /* XXX LOCAL_USER_ADD(app->module) */
00531    }
00532    res = app->execute(c, data);
00533    if (app->module) {
00534       /* XXX LOCAL_USER_REMOVE(app->module) */
00535    }
00536    /* restore channel values */
00537    c->appl = saved_c_appl;
00538    c->data = saved_c_data;
00539    return res;
00540 }

struct ast_app* pbx_findapp ( const char *  app  )  [read]

Look up an application.

Parameters:
app name of the app
This function searches for the ast_app structure within the apps that are registered for the one with the name you passed in.

Returns:
the ast_app structure that matches on success, or NULL on failure

Definition at line 548 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.

Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().

00549 {
00550    struct ast_app *tmp;
00551 
00552    AST_LIST_LOCK(&apps);
00553    AST_LIST_TRAVERSE(&apps, tmp, list) {
00554       if (!strcasecmp(tmp->name, app))
00555          break;
00556    }
00557    AST_LIST_UNLOCK(&apps);
00558 
00559    return tmp;
00560 }

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

Note:
Will lock the channel.

Definition at line 1140 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_config_AST_SYSTEM_NAME, ast_get_hint(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_name(), ast_var_value(), ast_channel::cid, ast_callerid::cid_ani2, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, globals, ast_channel::hangupcause, offset, parse_variable_name(), ast_channel::priority, s, substring(), and ast_channel::varshead.

Referenced by action_getvar(), handle_getvariable(), and pbx_substitute_variables_helper_full().

01141 {
01142    const char not_found = '\0';
01143    char *tmpvar;
01144    const char *s; /* the result */
01145    int offset, length;
01146    int i, need_substring;
01147    struct varshead *places[2] = { headp, &globals };  /* list of places where we may look */
01148 
01149    if (c) {
01150       ast_channel_lock(c);
01151       places[0] = &c->varshead;
01152    }
01153    /*
01154     * Make a copy of var because parse_variable_name() modifies the string.
01155     * Then if called directly, we might need to run substring() on the result;
01156     * remember this for later in 'need_substring', 'offset' and 'length'
01157     */
01158    tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */
01159    need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
01160 
01161    /*
01162     * Look first into predefined variables, then into variable lists.
01163     * Variable 's' points to the result, according to the following rules:
01164     * s == &not_found (set at the beginning) means that we did not find a
01165     * matching variable and need to look into more places.
01166     * If s != &not_found, s is a valid result string as follows:
01167     * s = NULL if the variable does not have a value;
01168     * you typically do this when looking for an unset predefined variable.
01169     * s = workspace if the result has been assembled there;
01170     * typically done when the result is built e.g. with an snprintf(),
01171     * so we don't need to do an additional copy.
01172     * s != workspace in case we have a string, that needs to be copied
01173     * (the ast_copy_string is done once for all at the end).
01174     * Typically done when the result is already available in some string.
01175     */
01176    s = &not_found;   /* default value */
01177    if (c) { /* This group requires a valid channel */
01178       /* Names with common parts are looked up a piece at a time using strncmp. */
01179       if (!strncmp(var, "CALL", 4)) {
01180          if (!strncmp(var + 4, "ING", 3)) {
01181             if (!strcmp(var + 7, "PRES")) {        /* CALLINGPRES */
01182                snprintf(workspace, workspacelen, "%d", c->cid.cid_pres);
01183                s = workspace;
01184             } else if (!strcmp(var + 7, "ANI2")) {    /* CALLINGANI2 */
01185                snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2);
01186                s = workspace;
01187             } else if (!strcmp(var + 7, "TON")) {     /* CALLINGTON */
01188                snprintf(workspace, workspacelen, "%d", c->cid.cid_ton);
01189                s = workspace;
01190             } else if (!strcmp(var + 7, "TNS")) {     /* CALLINGTNS */
01191                snprintf(workspace, workspacelen, "%d", c->cid.cid_tns);
01192                s = workspace;
01193             }
01194          }
01195       } else if (!strcmp(var, "HINT")) {
01196          s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL;
01197       } else if (!strcmp(var, "HINTNAME")) {
01198          s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL;
01199       } else if (!strcmp(var, "EXTEN")) {
01200          s = c->exten;
01201       } else if (!strcmp(var, "CONTEXT")) {
01202          s = c->context;
01203       } else if (!strcmp(var, "PRIORITY")) {
01204          snprintf(workspace, workspacelen, "%d", c->priority);
01205          s = workspace;
01206       } else if (!strcmp(var, "CHANNEL")) {
01207          s = c->name;
01208       } else if (!strcmp(var, "UNIQUEID")) {
01209          s = c->uniqueid;
01210       } else if (!strcmp(var, "HANGUPCAUSE")) {
01211          snprintf(workspace, workspacelen, "%d", c->hangupcause);
01212          s = workspace;
01213       }
01214    }
01215    if (s == &not_found) { /* look for more */
01216       if (!strcmp(var, "EPOCH")) {
01217          snprintf(workspace, workspacelen, "%u",(int)time(NULL));
01218          s = workspace;
01219       } else if (!strcmp(var, "SYSTEMNAME")) {
01220          s = ast_config_AST_SYSTEM_NAME;
01221       }
01222    }
01223    /* if not found, look into chanvars or global vars */
01224    for (i = 0; s == &not_found && i < (sizeof(places) / sizeof(places[0])); i++) {
01225       struct ast_var_t *variables;
01226       if (!places[i])
01227          continue;
01228       if (places[i] == &globals)
01229          ast_mutex_lock(&globalslock);
01230       AST_LIST_TRAVERSE(places[i], variables, entries) {
01231          if (strcasecmp(ast_var_name(variables), var)==0) {
01232             s = ast_var_value(variables);
01233             break;
01234          }
01235       }
01236       if (places[i] == &globals)
01237          ast_mutex_unlock(&globalslock);
01238    }
01239    if (s == &not_found || s == NULL)
01240       *ret = NULL;
01241    else {
01242       if (s != workspace)
01243          ast_copy_string(workspace, s, workspacelen);
01244       *ret = workspace;
01245       if (need_substring)
01246          *ret = substring(*ret, offset, length, workspace, workspacelen);
01247    }
01248 
01249    if (c)
01250       ast_channel_unlock(c);
01251 }

int pbx_set_autofallthrough ( int  newval  ) 

Set "autofallthrough" flag, if newval is <0, does not acutally set. If set to 1, sets to auto fall through. If newval set to 0, sets to no auto fall through (reads extension instead). Returns previous value.

Definition at line 2675 of file pbx.c.

References autofallthrough.

Referenced by pbx_load_module().

02676 {
02677    int oldval = autofallthrough;
02678    autofallthrough = newval;
02679    return oldval;
02680 }

void pbx_substitute_variables_helper ( struct ast_channel c,
const char *  cp1,
char *  cp2,
int  count 
)

void pbx_substitute_variables_varshead ( struct varshead *  headp,
const char *  cp1,
char *  cp2,
int  count 
)

Definition at line 1761 of file pbx.c.

References pbx_substitute_variables_helper_full().

Referenced by ast_add_extension2(), do_say(), dundi_lookup_local(), and loopback_helper().

01762 {
01763    pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
01764 }


Generated on Fri Sep 25 19:28:40 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.5