Fri Aug 24 02:27:06 2007

Asterisk developer's documentation


pbx.h File Reference

Core PBX routines and definitions. More...

#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/linkedlists.h"

Include dependency graph for pbx.h:

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

Go to the source code of this file.

Data Structures

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

Defines

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

Typedefs

typedef int(*) ast_state_cb_type (char *context, char *id, enum ast_extension_states state, void *data)
 Typedef for devicestate and hint callbacks.
typedef int( ast_switch_f )(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 All switch functions have the same interface, so define a type for them.

Enumerations

enum  ast_extension_states {
  AST_EXTENSION_REMOVED = -2, AST_EXTENSION_DEACTIVATED = -1, AST_EXTENSION_NOT_INUSE = 0, AST_EXTENSION_INUSE = 1 << 0,
  AST_EXTENSION_BUSY = 1 << 1, AST_EXTENSION_UNAVAILABLE = 1 << 2, AST_EXTENSION_RINGING = 1 << 3, AST_EXTENSION_ONHOLD = 1 << 4
}
 Extension states. More...
enum  ast_pbx_result { AST_PBX_SUCCESS = 0, AST_PBX_FAILED = -1, AST_PBX_CALL_LIMIT = -2 }
 The result codes when starting the PBX on a channel with ast_pbx_start(). More...

Functions

int ast_active_calls (void)
 Retrieve the number of active calls.
int ast_add_extension (const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 Add and extension to an extension context.
int ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 Add an extension to an extension context, this time with an ast_context *.
int ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_async_goto_by_name (const char *chan, const char *context, const char *exten, int priority)
int ast_async_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_build_timing (struct ast_timing *i, const char *info)
int ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Looks for a valid matching extension.
int ast_check_timing (const struct ast_timing *i)
int ast_context_add_ignorepat (const char *context, const char *ignorepat, const char *registrar)
 Add an ignorepat.
int ast_context_add_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar)
int ast_context_add_include (const char *context, const char *include, const char *registrar)
 Add a context include.
int ast_context_add_include2 (struct ast_context *con, const char *include, const char *registrar)
 Add a context include.
int ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar)
 Add a switch.
int ast_context_add_switch2 (struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar)
 Adds a switch (first param is a ast_context).
ast_contextast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar)
 Register a new context.
void ast_context_destroy (struct ast_context *con, const char *registrar)
 Destroy a context (matches the specified context (or ANY context if NULL).
ast_contextast_context_find (const char *name)
 Find a context.
ast_contextast_context_find_or_create (struct ast_context **extcontexts, const char *name, const char *registrar)
 Register a new context or find an existing one.
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.
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
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 hint exists, return non-zero.
int ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority)
void ast_hint_state_changed (const char *device)
int ast_ignore_pattern (const char *context, const char *pattern)
 Checks to see if a number should be ignored.
int ast_lock_context (struct ast_context *con)
 Locks a given context.
int ast_lock_contexts (void)
 Locks the context list.
int ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Looks to see if adding anything to this extension might match something. (exists ^ canmatch).
void ast_merge_contexts_and_delete (struct ast_context **extcontexts, const char *registrar)
 Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added.
int ast_parseable_goto (struct ast_channel *chan, const char *goto_string)
int ast_pbx_outgoing_app (const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
int ast_pbx_outgoing_exten (const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
enum ast_pbx_result ast_pbx_run (struct ast_channel *c)
 Execute the PBX in the current thread.
enum ast_pbx_result ast_pbx_start (struct ast_channel *c)
 Create a new thread and start the PBX.
int ast_register_application (const char *app, int(*execute)(struct ast_channel *, void *), const char *synopsis, const char *description)
 Register an application.
int ast_register_switch (struct ast_switch *sw)
 Register an alternative dialplan switch.
int ast_spawn_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Launch a new extension (i.e. new stack).
int ast_unlock_context (struct ast_context *con)
int ast_unlock_contexts (void)
 Unlocks contexts.
int ast_unregister_application (const char *app)
 Unregister an application.
void ast_unregister_switch (struct ast_switch *sw)
 Unregister an alternative switch.
ast_extenast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority)
ast_ignorepatast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip)
ast_includeast_walk_context_includes (struct ast_context *con, struct ast_include *inc)
ast_swast_walk_context_switches (struct ast_context *con, struct ast_sw *sw)
ast_contextast_walk_contexts (struct ast_context *con)
ast_extenast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority)
void pbx_builtin_clear_globals (void)
const char * pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name)
void pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value)
int pbx_builtin_serialize_variables (struct ast_channel *chan, char *buf, size_t size)
int pbx_builtin_setvar (struct ast_channel *chan, void *data)
void pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value)
int pbx_checkcondition (const char *condition)
 Evaluate a condition.
int pbx_exec (struct ast_channel *c, struct ast_app *app, void *data)
 Execute an application.
ast_apppbx_findapp (const char *app)
 Look up an application.
void pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
 Support for Asterisk built-in variables and functions in the dialplan.
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)
Functions for returning values from structures

const char * ast_get_context_name (struct ast_context *con)
ast_contextast_get_extension_context (struct ast_exten *exten)
const char * ast_get_extension_name (struct ast_exten *exten)
const char * ast_get_ignorepat_name (struct ast_ignorepat *ip)
const char * ast_get_include_name (struct ast_include *include)
const char * ast_get_switch_data (struct ast_sw *sw)
const char * ast_get_switch_name (struct ast_sw *sw)
Registrar info functions ...
const char * ast_get_context_registrar (struct ast_context *c)
const char * ast_get_extension_registrar (struct ast_exten *e)
const char * ast_get_ignorepat_registrar (struct ast_ignorepat *ip)
const char * ast_get_include_registrar (struct ast_include *i)
const char * ast_get_switch_registrar (struct ast_sw *sw)
Other Extension stuff
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)
const char * ast_get_extension_label (struct ast_exten *e)
int ast_get_extension_matchcid (struct ast_exten *e)
int ast_get_extension_priority (struct ast_exten *exten)


Detailed Description

Core PBX routines and definitions.

Definition in file pbx.h.


Define Documentation

#define AST_MAX_APP   32

Max length of an application

Definition at line 34 of file pbx.h.

Referenced by destroy_station(), handle_show_application(), handle_show_application_deprecated(), handle_show_function(), and handle_show_function_deprecated().

#define AST_PBX_KEEP   0

Definition at line 36 of file pbx.h.

#define AST_PBX_KEEPALIVE   10

Special return values from applications to the PBX {.

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

Definition at line 40 of file pbx.h.

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

#define AST_PBX_NO_HANGUP_PEER   11

Definition at line 41 of file pbx.h.

Referenced by builtin_blindtransfer(), builtin_parkcall(), feature_exec_app(), park_exec(), and try_calling().

#define AST_PBX_REPLACE   1

Definition at line 37 of file pbx.h.

#define PRIORITY_HINT   -1

} Special Priority for a hint

Definition at line 44 of file pbx.h.

Referenced by add_extensions(), add_pri(), ast_add_extension2(), ast_hint_extension(), destroy_exten(), destroy_station(), handle_context_add_extension(), handle_context_add_extension_deprecated(), handle_context_remove_extension(), handle_context_remove_extension_deprecated(), handle_save_dialplan(), park_add_hints(), pbx_load_config(), and print_ext().


Typedef Documentation

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

Typedef for devicestate and hint callbacks.

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


Enumeration Type Documentation

enum ast_extension_states

Extension states.

Note:
States can be combined
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 50 of file pbx.h.

00050                           {
00051    AST_EXTENSION_REMOVED = -2,   /*!< Extension removed */
00052    AST_EXTENSION_DEACTIVATED = -1,  /*!< Extension hint removed */
00053    AST_EXTENSION_NOT_INUSE = 0,  /*!< No device INUSE or BUSY  */
00054    AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */
00055    AST_EXTENSION_BUSY = 1 << 1,  /*!< All devices BUSY */
00056    AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */
00057    AST_EXTENSION_RINGING = 1 << 3,  /*!< All devices RINGING */
00058    AST_EXTENSION_ONHOLD = 1 << 4,   /*!< All devices ONHOLD */
00059 };

enum ast_pbx_result

The result codes when starting the PBX on a channel with ast_pbx_start().

AST_PBX_CALL_LIMIT refers to the maxcalls call limit in asterisk.conf

Enumerator:
AST_PBX_SUCCESS 
AST_PBX_FAILED 
AST_PBX_CALL_LIMIT 

Definition at line 236 of file pbx.h.

00236                     {
00237    AST_PBX_SUCCESS = 0,
00238    AST_PBX_FAILED = -1,
00239    AST_PBX_CALL_LIMIT = -2,
00240 };


Function Documentation

int ast_active_calls ( void   ) 

Retrieve the number of active calls.

Definition at line 2656 of file pbx.c.

References countcalls.

Referenced by handle_chanlist(), and handle_chanlist_deprecated().

02657 {
02658    return countcalls;
02659 }

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

04539 {
04540    int ret = -1;
04541    struct ast_context *c = find_context_locked(context);
04542 
04543    if (c) {
04544       ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
04545          application, data, datad, registrar);
04546       ast_unlock_contexts();
04547    }
04548    return ret;
04549 }

int ast_add_extension2 ( struct ast_context con,
int  replace,
const char *  extension,
int  priority,
const char *  label,
const char *  callerid,
const char *  application,
void *  data,
void(*)(void *)  datad,
const char *  registrar 
)

Add an extension to an extension context, this time with an ast_context *.

We sort extensions in order of matching preference, so that we can stop the search as soon as we find a suitable match. This ordering also takes care of wildcards such as '.' (meaning "one or more of any character") and '!' (which is 'earlymatch', meaning "zero or more of any character" but also impacts the return value from CANMATCH and EARLYMATCH.

The extension match rules defined in the devmeeting 2006.05.05 are quite simple: WE SELECT THE LONGEST MATCH. In detail, "longest" means the number of matched characters in the extension. In case of ties (e.g. _XXX and 333) in the length of a pattern, we give priority to entries with the smallest cardinality (e.g, [5-9] comes before [2-8] before the former has only 5 elements, while the latter has 7, etc. In case of same cardinality, the first element in the range counts. If we still have a tie, any final '!' will make this as a possibly less specific pattern.

EBUSY - can't lock EEXIST - extension with the same priority exist and no replace is set

Definition at line 4740 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, ext_cmp(), ext_strncpy(), ast_exten::exten, ast_exten::label, ast_context::lock, ast_exten::matchcid, ast_exten::next, option_verbose, ast_exten::parent, pbx_substitute_variables_varshead(), ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, ast_context::root, ast_exten::stuff, VAR_BUF_SIZE, and VERBOSE_PREFIX_3.

Referenced by add_extensions(), ast_add_extension(), ast_park_call(), do_parking_thread(), pbx_load_config(), and pbx_load_users().

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

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

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

04571 {
04572    int res = 0;
04573 
04574    ast_channel_lock(chan);
04575 
04576    if (chan->pbx) { /* This channel is currently in the PBX */
04577       ast_explicit_goto(chan, context, exten, priority);
04578       ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
04579    } else {
04580       /* In order to do it when the channel doesn't really exist within
04581          the PBX, we have to make a new channel, masquerade, and start the PBX
04582          at the new location */
04583       struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name);
04584       if (chan->cdr) {
04585          tmpchan->cdr = ast_cdr_dup(chan->cdr);
04586       }
04587       if (!tmpchan)
04588          res = -1;
04589       else {
04590          /* Make formats okay */
04591          tmpchan->readformat = chan->readformat;
04592          tmpchan->writeformat = chan->writeformat;
04593          /* Setup proper location */
04594          ast_explicit_goto(tmpchan,
04595             S_OR(context, chan->context), S_OR(exten, chan->exten), priority);
04596 
04597          /* Masquerade into temp channel */
04598          ast_channel_masquerade(tmpchan, chan);
04599 
04600          /* Grab the locks and get going */
04601          ast_channel_lock(tmpchan);
04602          ast_do_masquerade(tmpchan);
04603          ast_channel_unlock(tmpchan);
04604          /* Start the PBX going on our stolen channel */
04605          if (ast_pbx_start(tmpchan)) {
04606             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
04607             ast_hangup(tmpchan);
04608             res = -1;
04609          }
04610       }
04611    }
04612    ast_channel_unlock(chan);
04613    return res;
04614 }

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

Definition at line 4616 of file pbx.c.

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

04617 {
04618    struct ast_channel *chan;
04619    int res = -1;
04620 
04621    chan = ast_get_channel_by_name_locked(channame);
04622    if (chan) {
04623       res = ast_async_goto(chan, context, exten, priority);
04624       ast_channel_unlock(chan);
04625    }
04626    return res;
04627 }

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

Definition at line 6281 of file pbx.c.

References __ast_goto_if_exists().

Referenced by asyncgoto_exec().

06282 {
06283    return __ast_goto_if_exists(chan, context, exten, priority, 1);
06284 }

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

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

04213 {
04214    char info_save[256];
04215    char *info;
04216 
04217    /* Check for empty just in case */
04218    if (ast_strlen_zero(info_in))
04219       return 0;
04220    /* make a copy just in case we were passed a static string */
04221    ast_copy_string(info_save, info_in, sizeof(info_save));
04222    info = info_save;
04223    /* Assume everything except time */
04224    i->monthmask = 0xfff;   /* 12 bits */
04225    i->daymask = 0x7fffffffU; /* 31 bits */
04226    i->dowmask = 0x7f; /* 7 bits */
04227    /* on each call, use strsep() to move info to the next argument */
04228    get_timerange(i, strsep(&info, "|"));
04229    if (info)
04230       i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week");
04231    if (info)
04232       i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day");
04233    if (info)
04234       i->monthmask = get_range(strsep(&info, "|"), 12, months, "month");
04235    return 1;
04236 }

int ast_canmatch_extension ( struct ast_channel c,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid 
)

Looks for a valid matching extension.

Parameters:
c not really important
context context to serach within
exten extension to check
priority priority of extension path
callerid callerid of extension being searched for
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 2282 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(), nv_background_detect_exec(), nv_detectfax_exec(), phone_check_exception(), skinny_ss(), ss_thread(), and valid_exit().

02283 {
02284    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH);
02285 }

int ast_check_timing ( const struct ast_timing i  ) 

Definition at line 4238 of file pbx.c.

References ast_localtime(), ast_log(), ast_timing::daymask, ast_timing::dowmask, LOG_WARNING, ast_timing::minmask, ast_timing::monthmask, and t.

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

04239 {
04240    struct tm tm;
04241    time_t t = time(NULL);
04242 
04243    ast_localtime(&t, &tm, NULL);
04244 
04245    /* If it's not the right month, return */
04246    if (!(i->monthmask & (1 << tm.tm_mon)))
04247       return 0;
04248 
04249    /* If it's not that time of the month.... */
04250    /* Warning, tm_mday has range 1..31! */
04251    if (!(i->daymask & (1 << (tm.tm_mday-1))))
04252       return 0;
04253 
04254    /* If it's not the right day of the week */
04255    if (!(i->dowmask & (1 << tm.tm_wday)))
04256       return 0;
04257 
04258    /* Sanity check the hour just to be safe */
04259    if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
04260       ast_log(LOG_WARNING, "Insane time...\n");
04261       return 0;
04262    }
04263 
04264    /* Now the tough part, we calculate if it fits
04265       in the right time based on min/hour */
04266    if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
04267       return 0;
04268 
04269    /* If we got this far, then we're good */
04270    return 1;
04271 }

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

Add an ignorepat.

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

Return values:
0 on success
-1 on failure

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

04473 {
04474    int ret = -1;
04475    struct ast_context *c = find_context_locked(context);
04476 
04477    if (c) {
04478       ret = ast_context_add_ignorepat2(c, value, registrar);
04479       ast_unlock_contexts();
04480    }
04481    return ret;
04482 }

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

Definition at line 4484 of file pbx.c.

References ast_calloc, ast_mutex_lock(), ast_mutex_unlock(), ast_context::ignorepats, ast_context::lock, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.

Referenced by ast_context_add_ignorepat(), and pbx_load_config().

04485 {
04486    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
04487    int length;
04488    length = sizeof(struct ast_ignorepat);
04489    length += strlen(value) + 1;
04490    if (!(ignorepat = ast_calloc(1, length)))
04491       return -1;
04492    /* The cast to char * is because we need to write the initial value.
04493     * The field is not supposed to be modified otherwise
04494     */
04495    strcpy((char *)ignorepat->pattern, value);
04496    ignorepat->next = NULL;
04497    ignorepat->registrar = registrar;
04498    ast_mutex_lock(&con->lock);
04499    for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
04500       ignorepatl = ignorepatc;
04501       if (!strcasecmp(ignorepatc->pattern, value)) {
04502          /* Already there */
04503          ast_mutex_unlock(&con->lock);
04504          errno = EEXIST;
04505          return -1;
04506       }
04507    }
04508    if (ignorepatl)
04509       ignorepatl->next = ignorepat;
04510    else
04511       con->ignorepats = ignorepat;
04512    ast_mutex_unlock(&con->lock);
04513    return 0;
04514 
04515 }

int ast_context_add_include ( const char *  context,
const char *  include,
const char *  registrar 
)

Add a context include.

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

Return values:
0 on success
-1 on error

Definition at line 4018 of file pbx.c.

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

Referenced by handle_context_add_include(), and handle_context_add_include_deprecated().

04019 {
04020    int ret = -1;
04021    struct ast_context *c = find_context_locked(context);
04022 
04023    if (c) {
04024       ret = ast_context_add_include2(c, include, registrar);
04025       ast_unlock_contexts();
04026    }
04027    return ret;
04028 }

int ast_context_add_include2 ( struct ast_context con,
const char *  include,
const char *  registrar 
)

Add a context include.

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

Return values:
0 on success
-1 on failure

Definition at line 4280 of file pbx.c.

References ast_build_timing(), ast_calloc, ast_get_context_name(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, ast_include::hastime, ast_context::includes, ast_context::lock, ast_include::name, ast_include::next, option_verbose, ast_include::registrar, ast_include::rname, ast_include::stuff, ast_include::timing, and VERBOSE_PREFIX_3.

Referenced by ast_context_add_include(), and pbx_load_config().

04282 {
04283    struct ast_include *new_include;
04284    char *c;
04285    struct ast_include *i, *il = NULL; /* include, include_last */
04286    int length;
04287    char *p;
04288 
04289    length = sizeof(struct ast_include);
04290    length += 2 * (strlen(value) + 1);
04291 
04292    /* allocate new include structure ... */
04293    if (!(new_include = ast_calloc(1, length)))
04294       return -1;
04295    /* Fill in this structure. Use 'p' for assignments, as the fields
04296     * in the structure are 'const char *'
04297     */
04298    p = new_include->stuff;
04299    new_include->name = p;
04300    strcpy(p, value);
04301    p += strlen(value) + 1;
04302    new_include->rname = p;
04303    strcpy(p, value);
04304    /* Strip off timing info, and process if it is there */
04305    if ( (c = strchr(p, '|')) ) {
04306       *c++ = '\0';
04307            new_include->hastime = ast_build_timing(&(new_include->timing), c);
04308    }
04309    new_include->next      = NULL;
04310    new_include->registrar = registrar;
04311 
04312    ast_mutex_lock(&con->lock);
04313 
04314    /* ... go to last include and check if context is already included too... */
04315    for (i = con->includes; i; i = i->next) {
04316       if (!strcasecmp(i->name, new_include->name)) {
04317          free(new_include);
04318          ast_mutex_unlock(&con->lock);
04319          errno = EEXIST;
04320          return -1;
04321       }
04322       il = i;
04323    }
04324 
04325    /* ... include new context into context list, unlock, return */
04326    if (il)
04327       il->next = new_include;
04328    else
04329       con->includes = new_include;
04330    if (option_verbose > 2)
04331       ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
04332    ast_mutex_unlock(&con->lock);
04333 
04334    return 0;
04335 }

int ast_context_add_switch ( const char *  context,
const char *  sw,
const char *  data,
int  eval,
const char *  registrar 
)

Add a switch.

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

Return values:
0 on success
-1 on failure

Definition at line 4342 of file pbx.c.

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

04343 {
04344    int ret = -1;
04345    struct ast_context *c = find_context_locked(context);
04346 
04347    if (c) { /* found, add switch to this context */
04348       ret = ast_context_add_switch2(c, sw, data, eval, registrar);
04349       ast_unlock_contexts();
04350    }
04351    return ret;
04352 }

int ast_context_add_switch2 ( struct ast_context con,
const char *  sw,
const char *  data,
int  eval,
const char *  registrar 
)

Adds a switch (first param is a ast_context).

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

Definition at line 4361 of file pbx.c.

References ast_calloc, ast_get_context_name(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_sw::data, 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_context_add_switch(), and pbx_load_config().

04363 {
04364    struct ast_sw *new_sw;
04365    struct ast_sw *i;
04366    int length;
04367    char *p;
04368 
04369    length = sizeof(struct ast_sw);
04370    length += strlen(value) + 1;
04371    if (data)
04372       length += strlen(data);
04373    length++;
04374    if (eval) {
04375       /* Create buffer for evaluation of variables */
04376       length += SWITCH_DATA_LENGTH;
04377       length++;
04378    }
04379 
04380    /* allocate new sw structure ... */
04381    if (!(new_sw = ast_calloc(1, length)))
04382       return -1;
04383    /* ... fill in this structure ... */
04384    p = new_sw->stuff;
04385    new_sw->name = p;
04386    strcpy(new_sw->name, value);
04387    p += strlen(value) + 1;
04388    new_sw->data = p;
04389    if (data) {
04390       strcpy(new_sw->data, data);
04391       p += strlen(data) + 1;
04392    } else {
04393       strcpy(new_sw->data, "");
04394       p++;
04395    }
04396    if (eval)
04397       new_sw->tmpdata = p;
04398    new_sw->eval     = eval;
04399    new_sw->registrar = registrar;
04400 
04401    /* ... try to lock this context ... */
04402    ast_mutex_lock(&con->lock);
04403 
04404    /* ... go to last sw and check if context is already swd too... */
04405    AST_LIST_TRAVERSE(&con->alts, i, list) {
04406       if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
04407          free(new_sw);
04408          ast_mutex_unlock(&con->lock);
04409          errno = EEXIST;
04410          return -1;
04411       }
04412    }
04413 
04414    /* ... sw new context into context list, unlock, return */
04415    AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
04416 
04417    if (option_verbose > 2)
04418       ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
04419 
04420    ast_mutex_unlock(&con->lock);
04421 
04422    return 0;
04423 }

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

Register a new context.

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

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

Definition at line 3889 of file pbx.c.

References __ast_context_create().

Referenced by ast_park_call(), do_parking_thread(), and set_config().

03890 {
03891    return __ast_context_create(extcontexts, name, registrar, 0);
03892 }

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

References __ast_context_destroy().

Referenced by cleanup_stale_contexts(), and unload_module().

05327 {
05328    __ast_context_destroy(con,registrar);
05329 }

struct ast_context* ast_context_find ( const char *  name  ) 

Find a context.

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

Returns:
the ast_context on success, NULL on failure.

Definition at line 892 of file pbx.c.

References ast_mutex_lock(), ast_mutex_unlock(), and ast_walk_contexts().

Referenced by _macro_exec(), ast_context_verify_includes(), ast_ignore_pattern(), ast_park_call(), cleanup_stale_contexts(), do_parking_thread(), park_exec(), register_peer_exten(), and set_config().

00893 {
00894    struct ast_context *tmp = NULL;
00895    ast_mutex_lock(&conlock);
00896    while ( (tmp = ast_walk_contexts(tmp)) ) {
00897       if (!name || !strcasecmp(name, tmp->name))
00898          break;
00899    }
00900    ast_mutex_unlock(&conlock);
00901    return tmp;
00902 }

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

Register a new context or find an existing one.

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

References __ast_context_create().

Referenced by pbx_load_config(), and pbx_load_users().

03895 {
03896    return __ast_context_create(extcontexts, name, registrar, 1);
03897 }

int ast_context_lockmacro ( const char *  context  ) 

locks the macrolock in the given given context

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

Definition at line 2893 of file pbx.c.

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

Referenced by _macro_exec().

02894 {
02895    struct ast_context *c = NULL;
02896    int ret = -1;
02897 
02898    ast_lock_contexts();
02899 
02900    while ((c = ast_walk_contexts(c))) {
02901       if (!strcmp(ast_get_context_name(c), context)) {
02902          ret = 0;
02903          break;
02904       }
02905    }
02906 
02907    ast_unlock_contexts();
02908 
02909    /* if we found context, lock macrolock */
02910    if (ret == 0) 
02911       ret = ast_mutex_lock(&c->macrolock);
02912 
02913    return ret;
02914 }

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

02795 {
02796    int ret = -1; /* default error return */
02797    struct ast_context *c = find_context_locked(context);
02798 
02799    if (c) { /* ... remove extension ... */
02800       ret = ast_context_remove_extension2(c, extension, priority, registrar);
02801       ast_unlock_contexts();
02802    }
02803    return ret;
02804 }

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

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

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

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

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

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

04430 {
04431    int ret = -1;
04432    struct ast_context *c = find_context_locked(context);
04433 
04434    if (c) {
04435       ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
04436       ast_unlock_contexts();
04437    }
04438    return ret;
04439 }

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

Definition at line 4441 of file pbx.c.

References ast_mutex_lock(), ast_mutex_unlock(), free, ast_context::ignorepats, ast_context::lock, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.

Referenced by ast_context_remove_ignorepat().

04442 {
04443    struct ast_ignorepat *ip, *ipl = NULL;
04444 
04445    ast_mutex_lock(&con->lock);
04446 
04447    for (ip = con->ignorepats; ip; ip = ip->next) {
04448       if (!strcmp(ip->pattern, ignorepat) &&
04449          (!registrar || (registrar == ip->registrar))) {
04450          if (ipl) {
04451             ipl->next = ip->next;
04452             free(ip);
04453          } else {
04454             con->ignorepats = ip->next;
04455             free(ip);
04456          }
04457          ast_mutex_unlock(&con->lock);
04458          return 0;
04459       }
04460       ipl = ip;
04461    }
04462 
04463    ast_mutex_unlock(&con->lock);
04464    errno = EINVAL;
04465    return -1;
04466 }

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

02691 {
02692    int ret = -1;
02693    struct ast_context *c = find_context_locked(context);
02694 
02695    if (c) {
02696       /* found, remove include from this context ... */
02697       ret = ast_context_remove_include2(c, include, registrar);
02698       ast_unlock_contexts();
02699    }
02700    return ret;
02701 }

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

02712 {
02713    struct ast_include *i, *pi = NULL;
02714    int ret = -1;
02715 
02716    ast_mutex_lock(&con->lock);
02717 
02718    /* find our include */
02719    for (i = con->includes; i; pi = i, i = i->next) {
02720       if (!strcmp(i->name, include) &&
02721             (!registrar || !strcmp(i->registrar, registrar))) {
02722          /* remove from list */
02723          if (pi)
02724             pi->next = i->next;
02725          else
02726             con->includes = i->next;
02727          /* free include and return */
02728          free(i);
02729          ret = 0;
02730          break;
02731       }
02732    }
02733 
02734    ast_mutex_unlock(&con->lock);
02735    return ret;
02736 }

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

Remove a switch.

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

Definition at line 2743 of file pbx.c.

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

02744 {
02745    int ret = -1; /* default error return */
02746    struct ast_context *c = find_context_locked(context);
02747 
02748    if (c) {
02749       /* remove switch from this context ... */
02750       ret = ast_context_remove_switch2(c, sw, data, registrar);
02751       ast_unlock_contexts();
02752    }
02753    return ret;
02754 }

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

02765 {
02766    struct ast_sw *i;
02767    int ret = -1;
02768 
02769    ast_mutex_lock(&con->lock);
02770 
02771    /* walk switches */
02772    AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
02773       if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
02774          (!registrar || !strcmp(i->registrar, registrar))) {
02775          /* found, remove from list */
02776          AST_LIST_REMOVE_CURRENT(&con->alts, list);
02777          free(i); /* free switch and return */
02778          ret = 0;
02779          break;
02780       }
02781    }
02782    AST_LIST_TRAVERSE_SAFE_END
02783 
02784    ast_mutex_unlock(&con->lock);
02785 
02786    return ret;
02787 }

int ast_context_unlockmacro ( const char *  context  ) 

Unlocks the macrolock in the given context.

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

Definition at line 2921 of file pbx.c.

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

Referenced by _macro_exec().

02922 {
02923    struct ast_context *c = NULL;
02924    int ret = -1;
02925 
02926    ast_lock_contexts();
02927 
02928    while ((c = ast_walk_contexts(c))) {
02929       if (!strcmp(ast_get_context_name(c), context)) {
02930          ret = 0;
02931          break;
02932       }
02933    }
02934 
02935    ast_unlock_contexts();
02936 
02937    /* if we found context, unlock macrolock */
02938    if (ret == 0) 
02939       ret = ast_mutex_unlock(&c->macrolock);
02940 
02941    return ret;
02942 }

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

06243 {
06244    struct ast_include *inc = NULL;
06245    int res = 0;
06246 
06247    while ( (inc = ast_walk_context_includes(con, inc)) )
06248       if (!ast_context_find(inc->rname)) {
06249          res = -1;
06250          ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n",
06251                ast_get_context_name(con), inc->rname);
06252       }
06253    return res;
06254 }

struct ast_custom_function* ast_custom_function_find ( const char *  name  ) 

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

01434 {
01435    struct ast_custom_function *acf = NULL;
01436 
01437    AST_LIST_LOCK(&acf_root);
01438    AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
01439       if (!strcmp(name, acf->name))
01440          break;
01441    }
01442    AST_LIST_UNLOCK(&acf_root);
01443 
01444    return acf;
01445 }

int ast_custom_function_register ( struct ast_custom_function acf  ) 

Reigster a custom function.

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

01470 {
01471    struct ast_custom_function *cur;
01472 
01473    if (!acf)
01474       return -1;
01475 
01476    AST_LIST_LOCK(&acf_root);
01477 
01478    if (ast_custom_function_find(acf->name)) {
01479       ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
01480       AST_LIST_UNLOCK(&acf_root);
01481       return -1;
01482    }
01483 
01484    /* Store in alphabetical order */
01485    AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
01486       if (strcasecmp(acf->name, cur->name) < 0) {
01487          AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist);
01488          break;
01489       }
01490    }
01491    AST_LIST_TRAVERSE_SAFE_END
01492    if (!cur)
01493       AST_LIST_INSERT_TAIL(&acf_root, acf, acflist);
01494 
01495    AST_LIST_UNLOCK(&acf_root);
01496 
01497    if (option_verbose > 1)
01498       ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name);
01499 
01500    return 0;
01501 }

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

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

01448 {
01449    struct ast_custom_function *cur;
01450 
01451    if (!acf)
01452       return -1;
01453 
01454    AST_LIST_LOCK(&acf_root);
01455    AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
01456       if (cur == acf) {
01457          AST_LIST_REMOVE_CURRENT(&acf_root, acflist);
01458          if (option_verbose > 1)
01459             ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name);
01460          break;
01461       }
01462    }
01463    AST_LIST_TRAVERSE_SAFE_END
01464    AST_LIST_UNLOCK(&acf_root);
01465 
01466    return acf ? 0 : -1;
01467 }

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 2267 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_park_call(), ast_pbx_outgoing_exten(), 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(), nv_background_detect_exec(), nv_detectfax_exec(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), process_ast_dsp(), register_peer_exten(), skinny_ss(), socket_process(), ss_thread(), waitstream_core(), and zt_handle_dtmfup().

02268 {
02269    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH);
02270 }

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

Definition at line 4551 of file pbx.c.

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

04552 {
04553    if (!chan)
04554       return -1;
04555 
04556    if (!ast_strlen_zero(context))
04557       ast_copy_string(chan->context, context, sizeof(chan->context));
04558    if (!ast_strlen_zero(exten))
04559       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
04560    if (priority > -1) {
04561       chan->priority = priority;
04562       /* see flag description in channel.h for explanation */
04563       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
04564          chan->priority--;
04565    }
04566 
04567    return 0;
04568 }

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

Definition at line 885 of file pbx.c.

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

Referenced by realtime_switch_common().

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

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

00881 {
00882    return extension_match_core(pattern, data, E_MATCH);
00883 }

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

References ast_extension_state2(), and ast_hint_extension().

Referenced by action_extensionstate(), and handle_request_subscribe().

01992 {
01993    struct ast_exten *e;
01994 
01995    e = ast_hint_extension(c, context, exten);   /* Do we have a hint for this extension ? */
01996    if (!e)
01997       return -1;           /* No hint, return -1 */
01998 
01999    return ast_extension_state2(e);        /* Check all devices in the hint */
02000 }

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

References extension_states.

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

01980 {
01981    int i;
01982 
01983    for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) {
01984       if (extension_states[i].extension_state == extension_state)
01985          return extension_states[i].text;
01986    }
01987    return "Unknown";
01988 }

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

References ast_calloc, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_state_cb::callback, ast_state_cb::data, ast_state_cb::next, and statecbs.

Referenced by handle_request_subscribe(), and init_manager().

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

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

02122 {
02123    struct ast_state_cb **p_cur = NULL; /* address of pointer to us */
02124    int ret = -1;
02125 
02126    if (!id && !callback)
02127       return -1;
02128 
02129    AST_LIST_LOCK(&hints);
02130 
02131    if (!id) {  /* id == 0 is a callback without extension */
02132       for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) {
02133          if ((*p_cur)->callback == callback)
02134             break;
02135       }
02136    } else { /* callback with extension, find the callback based on ID */
02137       struct ast_hint *hint;
02138       AST_LIST_TRAVERSE(&hints, hint, list) {
02139          for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) {
02140             if ((*p_cur)->id == id)
02141                break;
02142          }
02143          if (*p_cur) /* found in the inner loop */
02144             break;
02145       }
02146    }
02147    if (p_cur && *p_cur) {
02148       struct ast_state_cb *cur = *p_cur;
02149       *p_cur = cur->next;
02150       free(cur);
02151       ret = 0;
02152    }
02153    AST_LIST_UNLOCK(&hints);
02154    return ret;
02155 }

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

02273 {
02274    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL);
02275 }

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

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

02278 {
02279    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL);
02280 }

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

01524 {
01525    char *args = func_args(function);
01526    struct ast_custom_function *acfptr = ast_custom_function_find(function);
01527 
01528    if (acfptr == NULL)
01529       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01530    else if (!acfptr->read)
01531       ast_log(LOG_ERROR, "Function %s cannot be read\n", function);
01532    else
01533       return acfptr->read(chan, function, args, workspace, len);
01534    return -1;
01535 }

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

01538 {
01539    char *args = func_args(function);
01540    struct ast_custom_function *acfptr = ast_custom_function_find(function);
01541 
01542    if (acfptr == NULL)
01543       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01544    else if (!acfptr->write)
01545       ast_log(LOG_ERROR, "Function %s cannot be written to\n", function);
01546    else
01547       return acfptr->write(chan, function, args, value);
01548 
01549    return -1;
01550 }

const char* ast_get_context_name ( struct ast_context con  ) 

Definition at line 6099 of file pbx.c.

Referenced by _macro_exec(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_context_verify_includes(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper().

06100 {
06101    return con ? con->name : NULL;
06102 }

const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 6137 of file pbx.c.

References ast_context::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06138 {
06139    return c ? c->registrar : NULL;
06140 }

const char* ast_get_extension_app ( struct ast_exten e  ) 

Definition at line 6167 of file pbx.c.

References ast_exten::app.

Referenced by _macro_exec(), ast_add_hint(), ast_extension_state2(), ast_get_hint(), ast_hint_state_changed(), find_matching_endwhile(), handle_save_dialplan(), handle_show_hints(), and print_ext().

06168 {
06169    return e ? e->app : NULL;
06170 }

void* ast_get_extension_app_data ( struct ast_exten e  ) 

Definition at line 6172 of file pbx.c.

References ast_exten::data.

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

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

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 6162 of file pbx.c.

References ast_exten::cidmatch.

Referenced by find_matching_priority(), and handle_save_dialplan().

06163 {
06164    return e ? e->cidmatch : NULL;
06165 }

struct ast_context* ast_get_extension_context ( struct ast_exten exten  ) 

Definition at line 6104 of file pbx.c.

References exten.

Referenced by handle_show_hints().

06105 {
06106    return exten ? exten->parent : NULL;
06107 }

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 6114 of file pbx.c.

References exten.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06115 {
06116    return exten ? exten->label : NULL;
06117 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 6157 of file pbx.c.

References ast_exten::matchcid.

Referenced by find_matching_priority(), and handle_save_dialplan().

06158 {
06159    return e ? e->matchcid : 0;
06160 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 

Definition at line 6109 of file pbx.c.

References exten.

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

06110 {
06111    return exten ? exten->exten : NULL;
06112 }

int ast_get_extension_priority ( struct ast_exten exten  ) 

Definition at line 6129 of file pbx.c.

References exten.

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

06130 {
06131    return exten ? exten->priority : -1;
06132 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 6142 of file pbx.c.

References ast_exten::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06143 {
06144    return e ? e->registrar : NULL;
06145 }

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 hint 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 2250 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(), pbx_retrieve_variable(), and transmit_state_notify().

02251 {
02252    struct ast_exten *e = ast_hint_extension(c, context, exten);
02253 
02254    if (e) {
02255       if (hint)
02256          ast_copy_string(hint, ast_get_extension_app(e), hintsize);
02257       if (name) {
02258          const char *tmp = ast_get_extension_app_data(e);
02259          if (tmp)
02260             ast_copy_string(name, tmp, namesize);
02261       }
02262       return -1;
02263    }
02264    return 0;
02265 }

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 

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

06125 {
06126    return ip ? ip->pattern : NULL;
06127 }

const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

Definition at line 6152 of file pbx.c.

References ast_ignorepat::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06153 {
06154    return ip ? ip->registrar : NULL;
06155 }

const char* ast_get_include_name ( struct ast_include include  ) 

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

06120 {
06121    return inc ? inc->name : NULL;
06122 }

const char* ast_get_include_registrar ( struct ast_include i  ) 

Definition at line 6147 of file pbx.c.

References ast_include::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06148 {
06149    return i ? i->registrar : NULL;
06150 }

const char* ast_get_switch_data ( struct ast_sw sw  ) 

Definition at line 6182 of file pbx.c.

References ast_sw::data.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06183 {
06184    return sw ? sw->data : NULL;
06185 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

Definition at line 6177 of file pbx.c.

References ast_sw::name.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06178 {
06179    return sw ? sw->name : NULL;
06180 }

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

Definition at line 6187 of file pbx.c.

References ast_sw::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06188 {
06189    return sw ? sw->registrar : NULL;
06190 }

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

Definition at line 6276 of file pbx.c.

References __ast_goto_if_exists().

Referenced by aqm_exec(), background_detect_exec(), chanavail_exec(), conf_run(), controlplayback_exec(), do_directory(), hasvoicemail_exec(), leave_voicemail(), lookupblacklist_exec(), onedigit_goto(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), play_mailbox_owner(), playback_exec(), pqm_exec(), privacy_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), system_exec_helper(), transfer_exec(), upqm_exec(), valid_exit(), vm_box_exists(), vm_exec(), and wait_for_answer().

06277 {
06278    return __ast_goto_if_exists(chan, context, exten, priority, 0);
06279 }

void ast_hint_state_changed ( const char *  device  ) 

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

02003 {
02004    struct ast_hint *hint;
02005 
02006    AST_LIST_LOCK(&hints);
02007 
02008    AST_LIST_TRAVERSE(&hints, hint, list) {
02009       struct ast_state_cb *cblist;
02010       char buf[AST_MAX_EXTENSION];
02011       char *parse = buf;
02012       char *cur;
02013       int state;
02014 
02015       ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf));
02016       while ( (cur = strsep(&parse, "&")) ) {
02017          if (!strcasecmp(cur, device))
02018             break;
02019       }
02020       if (!cur)
02021          continue;
02022 
02023       /* Get device state for this hint */
02024       state = ast_extension_state2(hint->exten);
02025 
02026       if ((state == -1) || (state == hint->laststate))
02027          continue;
02028 
02029       /* Device state changed since last check - notify the watchers */
02030 
02031       /* For general callbacks */
02032       for (cblist = statecbs; cblist; cblist = cblist->next)
02033          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
02034 
02035       /* For extension callbacks */
02036       for (cblist = hint->callbacks; cblist; cblist = cblist->next)
02037          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
02038 
02039       hint->laststate = state;   /* record we saw the change */
02040    }
02041 
02042    AST_LIST_UNLOCK(&hints);
02043 }

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

04518 {
04519    struct ast_context *con = ast_context_find(context);
04520    if (con) {
04521       struct ast_ignorepat *pat;
04522       for (pat = con->ignorepats; pat; pat = pat->next) {
04523          if (ast_extension_match(pat->pattern, pattern))
04524             return 1;
04525       }
04526    }
04527 
04528    return 0;
04529 }

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

06087 {
06088    return ast_mutex_lock(&con->lock);
06089 }

int ast_lock_contexts ( void   ) 

Locks the context list.

Return values:
0 on success
-1 on error

Definition at line 6073 of file pbx.c.

References ast_mutex_lock().

Referenced by _macro_exec(), ast_context_lockmacro(), ast_context_unlockmacro(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_save_dialplan(), and show_dialplan_helper().

06074 {
06075    return ast_mutex_lock(&conlock);
06076 }

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

02288 {
02289    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE);
02290 }

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

References __ast_context_destroy(), ast_calloc, AST_EXTENSION_REMOVED, ast_hint_extension(), 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_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, store_hint::callbacks, ast_hint::callbacks, store_hint::context, contexts, ast_state_cb::data, ast_exten::exten, ast_hint::exten, store_hint::exten, free, ast_hint::laststate, store_hint::laststate, LOG_WARNING, ast_state_cb::next, ast_context::next, ast_exten::parent, and ast_context::registrar.

Referenced by pbx_load_module().

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

int ast_parseable_goto ( struct ast_channel chan,
const char *  goto_string 
)

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

06287 {
06288    char *exten, *pri, *context;
06289    char *stringp;
06290    int ipri;
06291    int mode = 0;
06292 
06293    if (ast_strlen_zero(goto_string)) {
06294       ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
06295       return -1;
06296    }
06297    stringp = ast_strdupa(goto_string);
06298    context = strsep(&stringp, "|"); /* guaranteed non-null */
06299    exten = strsep(&stringp, "|");
06300    pri = strsep(&stringp, "|");
06301    if (!exten) {  /* Only a priority in this one */
06302       pri = context;
06303       exten = NULL;
06304       context = NULL;
06305    } else if (!pri) {   /* Only an extension and priority in this one */
06306       pri = exten;
06307       exten = context;
06308       context = NULL;
06309    }
06310    if (*pri == '+') {
06311       mode = 1;
06312       pri++;
06313    } else if (*pri == '-') {
06314       mode = -1;
06315       pri++;
06316    }
06317    if (sscanf(pri, "%d", &ipri) != 1) {
06318       if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten,
06319          pri, chan->cid.cid_num)) < 1) {
06320          ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);
06321          return -1;
06322       } else
06323          mode = 0;
06324    }
06325    /* At this point we have a priority and maybe an extension and a context */
06326 
06327    if (mode)
06328       ipri = chan->priority + (ipri * mode);
06329 
06330    ast_explicit_goto(chan, context, exten, ipri);
06331    ast_cdr_update(chan);
06332    return 0;
06333 
06334 }

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

References __ast_request_and_dial(), 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, free, LOG_WARNING, option_verbose, ast_channel::pbx, outgoing_helper::vars, and VERBOSE_PREFIX_4.

Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_app().

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

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 4966 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, ast_channel::context, free, ast_channel::hangupcause, LOAD_OH, LOG_ERROR, LOG_WARNING, option_verbose, set_ext_pri(), outgoing_helper::vars, and VERBOSE_PREFIX_4.

Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_exten().

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

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

References __ast_pbx_run(), AST_PBX_CALL_LIMIT, AST_PBX_SUCCESS, decrease_call_count(), and increase_call_count().

Referenced by ast_pbx_outgoing_exten(), async_wait(), mgcp_ss(), skinny_newcall(), and ss_thread().

02644 {
02645    enum ast_pbx_result res = AST_PBX_SUCCESS;
02646 
02647    if (increase_call_count(c))
02648       return AST_PBX_CALL_LIMIT;
02649 
02650    res = __ast_pbx_run(c);
02651    decrease_call_count();
02652 
02653    return res;
02654 }

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 2617 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_exten(), 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().

02618 {
02619    pthread_t t;
02620    pthread_attr_t attr;
02621 
02622    if (!c) {
02623       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
02624       return AST_PBX_FAILED;
02625    }
02626 
02627    if (increase_call_count(c))
02628       return AST_PBX_CALL_LIMIT;
02629 
02630    /* Start a new thread, and get something handling this channel. */
02631    pthread_attr_init(&attr);
02632    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
02633    if (ast_pthread_create(&t, &attr, pbx_thread, c)) {
02634       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
02635       pthread_attr_destroy(&attr);
02636       return AST_PBX_FAILED;
02637    }
02638    pthread_attr_destroy(&attr);
02639 
02640    return AST_PBX_SUCCESS;
02641 }

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

02946 {
02947    struct ast_app *tmp, *cur = NULL;
02948    char tmps[80];
02949    int length;
02950 
02951    AST_LIST_LOCK(&apps);
02952    AST_LIST_TRAVERSE(&apps, tmp, list) {
02953       if (!strcasecmp(app, tmp->name)) {
02954          ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
02955          AST_LIST_UNLOCK(&apps);
02956          return -1;
02957       }
02958    }
02959 
02960    length = sizeof(*tmp) + strlen(app) + 1;
02961 
02962    if (!(tmp = ast_calloc(1, length))) {
02963       AST_LIST_UNLOCK(&apps);
02964       return -1;
02965    }
02966 
02967    strcpy(tmp->name, app);
02968    tmp->execute = execute;
02969    tmp->synopsis = synopsis;
02970    tmp->description = description;
02971 
02972    /* Store in alphabetical order */
02973    AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) {
02974       if (strcasecmp(tmp->name, cur->name) < 0) {
02975          AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list);
02976          break;
02977       }
02978    }
02979    AST_LIST_TRAVERSE_SAFE_END
02980    if (!cur)
02981       AST_LIST_INSERT_TAIL(&apps, tmp, list);
02982 
02983    if (option_verbose > 1)
02984       ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
02985 
02986    AST_LIST_UNLOCK(&apps);
02987 
02988    return 0;
02989 }

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

02996 {
02997    struct ast_switch *tmp;
02998 
02999    AST_LIST_LOCK(&switches);
03000    AST_LIST_TRAVERSE(&switches, tmp, list) {
03001       if (!strcasecmp(tmp->name, sw->name)) {
03002          AST_LIST_UNLOCK(&switches);
03003          ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
03004          return -1;
03005       }
03006    }
03007    AST_LIST_INSERT_TAIL(&switches, sw, list);
03008    AST_LIST_UNLOCK(&switches);
03009 
03010    return 0;
03011 }

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

References E_SPAWN, and pbx_extension_helper().

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

02293 {
02294    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN);
02295 }

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

06092 {
06093    return ast_mutex_unlock(&con->lock);
06094 }

int ast_unlock_contexts ( void   ) 

Unlocks contexts.

Return values:
0 on success
-1 on failure

Definition at line 6078 of file pbx.c.

References ast_mutex_unlock().

Referenced by _macro_exec(), ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_lockmacro(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_unlockmacro(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_save_dialplan(), and show_dialplan_helper().

06079 {
06080    return ast_mutex_unlock(&conlock);
06081 }

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

03827 {
03828    struct ast_app *tmp;
03829 
03830    AST_LIST_LOCK(&apps);
03831    AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) {
03832       if (!strcasecmp(app, tmp->name)) {
03833          AST_LIST_REMOVE_CURRENT(&apps, list);
03834          if (option_verbose > 1)
03835             ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
03836          free(tmp);
03837          break;
03838       }
03839    }
03840    AST_LIST_TRAVERSE_SAFE_END
03841    AST_LIST_UNLOCK(&apps);
03842 
03843    return tmp ? 0 : -1;
03844 }

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

References AST_LIST_LOCK, AST_LIST_REMOVE, and AST_LIST_UNLOCK.

Referenced by __unload_module(), and unload_module().

03014 {
03015    AST_LIST_LOCK(&switches);
03016    AST_LIST_REMOVE(&switches, sw, list);
03017    AST_LIST_UNLOCK(&switches);
03018 }

struct ast_exten* ast_walk_context_extensions ( struct ast_context con,
struct ast_exten priority 
)

Definition at line 6200 of file pbx.c.

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

06202 {
06203    if (!exten)
06204       return con ? con->root : NULL;
06205    else
06206       return exten->next;
06207 }

struct ast_ignorepat* ast_walk_context_ignorepats ( struct ast_context con,
struct ast_ignorepat ip 
)

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

06235 {
06236    if (!ip)
06237       return con ? con->ignorepats : NULL;
06238    else
06239       return ip->next;
06240 }

struct ast_include* ast_walk_context_includes ( struct ast_context con,
struct ast_include inc 
)

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

06226 {
06227    if (!inc)
06228       return con ? con->includes : NULL;
06229    else
06230       return inc->next;
06231 }

struct ast_sw* ast_walk_context_switches ( struct ast_context con,
struct ast_sw sw 
)

Definition at line 6209 of file pbx.c.

References AST_LIST_FIRST, and AST_LIST_NEXT.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06211 {
06212    if (!sw)
06213       return con ? AST_LIST_FIRST(&con->alts) : NULL;
06214    else
06215       return AST_LIST_NEXT(sw, list);
06216 }

struct ast_context* ast_walk_contexts ( struct ast_context con  ) 

Definition at line 6195 of file pbx.c.

References contexts, and ast_context::next.

Referenced by _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), pbx_find_extension(), pbx_load_module(), and show_dialplan_helper().

06196 {
06197    return con ? con->next : contexts;
06198 }

struct ast_exten* ast_walk_extension_priorities ( struct ast_exten exten,
struct ast_exten priority 
)

Definition at line 6218 of file pbx.c.

References exten, and ast_exten::priority.

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

06220 {
06221    return priority ? priority->peer : exten;
06222 }

void pbx_builtin_clear_globals ( void   ) 

Definition at line 5949 of file pbx.c.

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

Referenced by handle_reload_extensions(), and reload().

05950 {
05951    struct ast_var_t *vardata;
05952 
05953    ast_mutex_lock(&globalslock);
05954    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
05955       ast_var_delete(vardata);
05956    ast_mutex_unlock(&globalslock);
05957 }

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

Definition at line 5749 of file pbx.c.

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

Referenced by __login_exec(), _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), ast_bridge_call(), ast_channel_bridge(), ast_feature_interpret(), ast_monitor_stop(), ast_park_call(), 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(), pickup_by_mark(), pop_exec(), queue_exec(), real_ctx(), retrydial_exec(), return_exec(), run_agi(), rxfax_exec(), set_config_flags(), sip_addheader(), sla_trunk_exec(), speech_background(), try_calling(), try_suggested_sip_codec(), txfax_exec(), wait_for_answer(), zt_call(), and zt_hangup().

05750 {
05751    struct ast_var_t *variables;
05752    const char *ret = NULL;
05753    int i;
05754    struct varshead *places[2] = { NULL, &globals };
05755 
05756    if (!name)
05757       return NULL;
05758    if (chan)
05759       places[0] = &chan->varshead;
05760 
05761    for (i = 0; i < 2; i++) {
05762       if (!places[i])
05763          continue;
05764       if (places[i] == &globals)
05765          ast_mutex_lock(&globalslock);
05766       AST_LIST_TRAVERSE(places[i], variables, entries) {
05767          if (!strcmp(name, ast_var_name(variables))) {
05768             ret = ast_var_value(variables);
05769             break;
05770          }
05771       }
05772       if (places[i] == &globals)
05773          ast_mutex_unlock(&globalslock);
05774       if (ret)
05775          break;
05776    }
05777 
05778    return ret;
05779 }

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

Definition at line 5781 of file pbx.c.

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

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

05782 {
05783    struct ast_var_t *newvariable;
05784    struct varshead *headp;
05785 
05786    if (name[strlen(name)-1] == ')') {
05787       char *function = ast_strdupa(name);
05788 
05789       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
05790       ast_func_write(chan, function, value);
05791       return;
05792    }
05793 
05794    headp = (chan) ? &chan->varshead : &globals;
05795 
05796    if (value) {
05797       if ((option_verbose > 1) && (headp == &globals))
05798          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05799       newvariable = ast_var_assign(name, value);
05800       if (headp == &globals)
05801          ast_mutex_lock(&globalslock);
05802       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05803       if (headp == &globals)
05804          ast_mutex_unlock(&globalslock);
05805    }
05806 }

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

Definition at line 5722 of file pbx.c.

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

05723 {
05724    struct ast_var_t *variables;
05725    const char *var, *val;
05726    int total = 0;
05727 
05728    if (!chan)
05729       return 0;
05730 
05731    memset(buf, 0, size);
05732 
05733    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
05734       if ((var=ast_var_name(variables)) && (val=ast_var_value(variables))
05735          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
05736          ) {
05737          if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) {
05738             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
05739             break;
05740          } else
05741             total++;
05742       } else
05743          break;
05744    }
05745 
05746    return total;
05747 }

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 
)

Definition at line 5808 of file pbx.c.

References 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(), option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2.

Referenced by __oh323_new(), _macro_exec(), _while_exec(), acf_odbc_read(), acf_odbc_write(), action_setvar(), agi_exec_full(), aji_status_exec(), aMYSQL_fetch(), app_exec(), aqm_exec(), array(), ast_bridge_call(), ast_channel_bridge(), ast_feature_request_and_dial(), ast_iax2_new(), ast_monitor_start(), ast_set_variables(), background_detect_exec(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), 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(), mwanalyze_exec(), MYSQL_exec(), nv_background_detect_exec(), nv_detectfax_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_exec(), parse_moved_contact(), pbx_builtin_importvar(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_extension_helper(), pbx_load_config(), phase_e_handler(), 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_asterisk_int(), 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().

05809 {
05810    struct ast_var_t *newvariable;
05811    struct varshead *headp;
05812    const char *nametail = name;
05813 
05814    /* XXX may need locking on the channel ? */
05815    if (name[strlen(name)-1] == ')') {
05816       char *function = ast_strdupa(name);
05817 
05818       ast_func_write(chan, function, value);
05819       return;
05820    }
05821 
05822    headp = (chan) ? &chan->varshead : &globals;
05823 
05824    /* For comparison purposes, we have to strip leading underscores */
05825    if (*nametail == '_') {
05826       nametail++;
05827       if (*nametail == '_')
05828          nametail++;
05829    }
05830 
05831    if (headp == &globals)
05832       ast_mutex_lock(&globalslock);
05833    AST_LIST_TRAVERSE (headp, newvariable, entries) {
05834       if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
05835          /* there is already such a variable, delete it */
05836          AST_LIST_REMOVE(headp, newvariable, entries);
05837          ast_var_delete(newvariable);
05838          break;
05839       }
05840    }
05841 
05842    if (value) {
05843       if ((option_verbose > 1) && (headp == &globals))
05844          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05845       newvariable = ast_var_assign(name, value);
05846       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05847    }
05848 
05849    if (headp == &globals)
05850       ast_mutex_unlock(&globalslock);
05851 }

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

05960 {
05961    if (ast_strlen_zero(condition))  /* NULL or empty strings are false */
05962       return 0;
05963    else if (*condition >= '0' && *condition <= '9')   /* Numbers are evaluated for truth */
05964       return atoi(condition);
05965    else  /* Strings are true */
05966       return 1;
05967 }

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

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

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

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

struct ast_app* pbx_findapp ( const char *  app  ) 

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

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

void pbx_retrieve_variable ( struct ast_channel c,
const char *  var,
char **  ret,
char *  workspace,
int  workspacelen,
struct varshead *  headp 
)

Support for Asterisk built-in variables and functions in the dialplan.

Note:
See also

Definition at line 1134 of file pbx.c.

References 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, ast_channel::hangupcause, offset, parse_variable_name(), ast_channel::priority, s, substring(), and ast_channel::varshead.

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

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

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

References autofallthrough.

Referenced by pbx_load_module().

02662 {
02663    int oldval = autofallthrough;
02664    autofallthrough = newval;
02665    return oldval;
02666 }

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

Definition at line 1745 of file pbx.c.

References pbx_substitute_variables_helper_full(), and ast_channel::varshead.

Referenced by _macro_exec(), acf_odbc_read(), acf_odbc_write(), add_extensions(), custom_log(), cut_internal(), exec_exec(), function_eval(), handle_getvariablefull(), launch_monitor_thread(), make_email_file(), pbx_builtin_importvar(), pbx_load_config(), pbx_substitute_variables(), realtime_exec(), rpt_do_lstats(), sendpage(), try_calling(), and tryexec_exec().

01746 {
01747    pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
01748 }

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

Definition at line 1750 of file pbx.c.

References pbx_substitute_variables_helper_full().

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

01751 {
01752    pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
01753 }


Generated on Fri Aug 24 02:27:07 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1