Sat Aug 6 00:40:00 2011

Asterisk developer's documentation


pbx.h File Reference

Core PBX routines and definitions. More...

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

Go to the source code of this file.

Data Structures

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

Defines

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

Typedefs

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

Enumerations

enum  ast_extension_states {
  AST_EXTENSION_REMOVED = -2, AST_EXTENSION_DEACTIVATED = -1, AST_EXTENSION_NOT_INUSE = 0, AST_EXTENSION_INUSE = 1 << 0,
  AST_EXTENSION_BUSY = 1 << 1, AST_EXTENSION_UNAVAILABLE = 1 << 2, AST_EXTENSION_RINGING = 1 << 3, AST_EXTENSION_ONHOLD = 1 << 4
}
 Extension states. More...
enum  ast_pbx_result { AST_PBX_SUCCESS = 0, AST_PBX_FAILED = -1, AST_PBX_CALL_LIMIT = -2 }

Functions

int ast_active_calls (void)
 Retrieve the number of active calls.
int ast_add_extension (const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 Add and extension to an extension context.
int ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 Add an extension to an extension context, this time with an ast_context *.
int ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_async_goto_by_name (const char *chan, const char *context, const char *exten, int priority)
int ast_async_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_build_timing (struct ast_timing *i, const char *info)
int ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Looks for a valid matching extension.
int ast_check_timing (const struct ast_timing *i)
int ast_context_add_ignorepat (const char *context, const char *ignorepat, const char *registrar)
 Add an ignorepat.
int ast_context_add_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar)
int ast_context_add_include (const char *context, const char *include, const char *registrar)
 Add a context include.
int ast_context_add_include2 (struct ast_context *con, const char *include, const char *registrar)
 Add a context include.
int ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar)
 Add a switch.
int ast_context_add_switch2 (struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar)
 Adds a switch (first param is a ast_context).
ast_contextast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar)
 Register a new context.
void ast_context_destroy (struct ast_context *con, const char *registrar)
 Destroy a context (matches the specified context (or ANY context if NULL).
ast_contextast_context_find (const char *name)
 Find a context.
ast_contextast_context_find_or_create (struct ast_context **extcontexts, const char *name, const char *registrar)
int ast_context_lockmacro (const char *macrocontext)
 locks the macrolock in the given given context
int ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar)
 Simply remove extension from context.
int ast_context_remove_extension2 (struct ast_context *con, const char *extension, int priority, const char *registrar)
 This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return.
int ast_context_remove_extension_callerid (const char *context, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar)
int ast_context_remove_extension_callerid2 (struct ast_context *con, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar)
int ast_context_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar)
int ast_context_remove_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar)
int ast_context_remove_include (const char *context, const char *include, const char *registrar)
 Remove a context include.
int ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar)
 Removes an include by an ast_context structure.
int ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar)
 Remove a switch.
int ast_context_remove_switch2 (struct ast_context *con, const char *sw, const char *data, const char *registrar)
 This function locks given context, removes switch, unlock context and return.
int ast_context_unlockmacro (const char *macrocontext)
 Unlocks the macrolock in the given context.
int ast_context_verify_includes (struct ast_context *con)
 Verifies includes in an ast_contect structure.
ast_custom_functionast_custom_function_find (const char *name)
int ast_custom_function_register (struct ast_custom_function *acf)
 Reigster a custom function.
int ast_custom_function_unregister (struct ast_custom_function *acf)
 Unregister a custom function.
enum ast_extension_states ast_devstate_to_extenstate (enum ast_device_state devstate)
 Map devstate to an extension state.
int ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Determine whether an extension exists.
int ast_explicit_goto (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_extension_close (const char *pattern, const char *data, int needmore)
int ast_extension_match (const char *pattern, const char *extension)
 Determine if a given extension matches a given pattern (in NXX format).
int ast_extension_patmatch (const char *pattern, const char *data)
int ast_extension_state (struct ast_channel *c, const char *context, const char *exten)
 Uses hint and devicestate callback to get the state of an extension.
const char * ast_extension_state2str (int extension_state)
 Return string representation of the state of an extension.
int ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data)
 Registers a state change callback.
int ast_extension_state_del (int id, ast_state_cb_type callback)
 Deletes a registered state change callback by ID.
int ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
 Find the priority of an extension that has the specified label.
int ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
 Find the priority of an extension that has the specified label.
int ast_func_read (struct ast_channel *chan, char *function, char *workspace, size_t len)
 executes a read operation on a function
int ast_func_write (struct ast_channel *chan, char *function, const char *value)
 executes a write operation on a function
const char * ast_get_context_name (struct ast_context *con)
const char * ast_get_context_registrar (struct ast_context *c)
const char * ast_get_extension_app (struct ast_exten *e)
void * ast_get_extension_app_data (struct ast_exten *e)
const char * ast_get_extension_cidmatch (struct ast_exten *e)
ast_contextast_get_extension_context (struct ast_exten *exten)
const char * ast_get_extension_label (struct ast_exten *e)
int ast_get_extension_matchcid (struct ast_exten *e)
const char * ast_get_extension_name (struct ast_exten *exten)
int ast_get_extension_priority (struct ast_exten *exten)
const char * ast_get_extension_registrar (struct ast_exten *e)
int ast_get_hint (char *hint, int maxlen, char *name, int maxnamelen, struct ast_channel *c, const char *context, const char *exten)
 If an extension exists, return non-zero.
const char * ast_get_ignorepat_name (struct ast_ignorepat *ip)
const char * ast_get_ignorepat_registrar (struct ast_ignorepat *ip)
const char * ast_get_include_name (struct ast_include *include)
const char * ast_get_include_registrar (struct ast_include *i)
const char * ast_get_switch_data (struct ast_sw *sw)
const char * ast_get_switch_name (struct ast_sw *sw)
const char * ast_get_switch_registrar (struct ast_sw *sw)
int ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority)
void ast_hint_state_changed (const char *device)
int ast_ignore_pattern (const char *context, const char *pattern)
 Checks to see if a number should be ignored.
int ast_lock_context (struct ast_context *con)
 Locks a given context.
int ast_lock_contexts (void)
 Locks the context list.
int ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Looks to see if adding anything to this extension might match something. (exists ^ canmatch).
void ast_merge_contexts_and_delete (struct ast_context **extcontexts, const char *registrar)
 Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added.
int ast_parseable_goto (struct ast_channel *chan, const char *goto_string)
int ast_pbx_outgoing_app (const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
int ast_pbx_outgoing_exten (const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
enum ast_pbx_result ast_pbx_run (struct ast_channel *c)
 Execute the PBX in the current thread.
enum ast_pbx_result ast_pbx_start (struct ast_channel *c)
 Create a new thread and start the PBX.
int ast_processed_calls (void)
 Retrieve the total number of calls processed through the PBX since last restart.
int ast_rdlock_contexts (void)
int ast_register_application (const char *app, int(*execute)(struct ast_channel *, void *), const char *synopsis, const char *description)
 Register an application.
int ast_register_switch (struct ast_switch *sw)
 Register an alternative dialplan switch.
int ast_spawn_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Launch a new extension (i.e. new stack).
int ast_unlock_context (struct ast_context *con)
int ast_unlock_contexts (void)
 Unlocks contexts.
int ast_unregister_application (const char *app)
 Unregister an application.
void ast_unregister_switch (struct ast_switch *sw)
 Unregister an alternative switch.
ast_extenast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority)
ast_ignorepatast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip)
ast_includeast_walk_context_includes (struct ast_context *con, struct ast_include *inc)
ast_swast_walk_context_switches (struct ast_context *con, struct ast_sw *sw)
ast_contextast_walk_contexts (struct ast_context *con)
ast_extenast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority)
int ast_wrlock_contexts (void)
void pbx_builtin_clear_globals (void)
const char * pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name)
void pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value)
int pbx_builtin_serialize_variables (struct ast_channel *chan, char *buf, size_t size)
int pbx_builtin_setvar (struct ast_channel *chan, void *data)
void pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value)
int pbx_checkcondition (const char *condition)
 Evaluate a condition.
int pbx_exec (struct ast_channel *c, struct ast_app *app, void *data)
 Execute an application.
ast_apppbx_findapp (const char *app)
 Look up an application.
void pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
 pbx_retrieve_variable: Support for Asterisk built-in variables ---
int pbx_set_autofallthrough (int newval)
void pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count)
void pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count)


Detailed Description

Core PBX routines and definitions.

Definition in file pbx.h.


Define Documentation

#define AST_MAX_APP   32

Max length of an application

Definition at line 35 of file pbx.h.

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

#define AST_PBX_KEEP   0

Definition at line 37 of file pbx.h.

#define AST_PBX_KEEPALIVE   10

Special return values from applications to the PBX {.

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

Definition at line 41 of file pbx.h.

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

#define AST_PBX_REPLACE   1

Definition at line 38 of file pbx.h.

#define PRIORITY_HINT   -1

} Special Priority for a hint

Definition at line 44 of file pbx.h.

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


Typedef Documentation

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

Typedef for devicestate and hint callbacks.

Definition at line 66 of file pbx.h.

typedef int( ast_switch_f)(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)

All switch functions have the same interface, so define a type for them.

Data structure associated with an Asterisk switch

Definition at line 80 of file pbx.h.


Enumeration Type Documentation

enum ast_extension_states

Extension states.

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

Definition at line 47 of file pbx.h.

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

enum ast_pbx_result

Enumerator:
AST_PBX_SUCCESS 
AST_PBX_FAILED 
AST_PBX_CALL_LIMIT 

Definition at line 214 of file pbx.h.

00214                     {
00215    AST_PBX_SUCCESS = 0,
00216    AST_PBX_FAILED = -1,
00217    AST_PBX_CALL_LIMIT = -2,
00218 };


Function Documentation

int ast_active_calls ( void   ) 

Retrieve the number of active calls.

Definition at line 2764 of file pbx.c.

Referenced by handle_chanlist(), and handle_chanlist_deprecated().

02765 {
02766    return countcalls;
02767 }

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

04706 {
04707    int ret = -1;
04708    struct ast_context *c = find_context_locked(context);
04709 
04710    if (c) {
04711       ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
04712          application, data, datad, registrar);
04713       ast_unlock_contexts();
04714    }
04715    return ret;
04716 }

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

References add_pri(), ast_exten::app, ast_add_hint(), ast_calloc, AST_LIST_FIRST, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_exten::cidmatch, ast_exten::data, ast_exten::datad, el, errno, ext_cmp(), ext_strncpy(), ast_exten::exten, globals, globalslock, ast_exten::label, ast_context::lock, ast_exten::matchcid, ast_context::name, ast_exten::next, option_verbose, ast_exten::parent, pbx_substitute_variables_varshead(), ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, ast_context::root, ast_exten::stuff, VAR_BUF_SIZE, and VERBOSE_PREFIX_3.

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

04922 {
04923    /*
04924     * Sort extensions (or patterns) according to the rules indicated above.
04925     * These are implemented by the function ext_cmp()).
04926     * All priorities for the same ext/pattern/cid are kept in a list,
04927     * using the 'peer' field  as a link field..
04928     */
04929    struct ast_exten *tmp, *e, *el = NULL;
04930    int res;
04931    int length;
04932    char *p;
04933    char expand_buf[VAR_BUF_SIZE] = { 0, };
04934 
04935    /* if we are adding a hint, and there are global variables, and the hint
04936       contains variable references, then expand them
04937    */
04938    ast_mutex_lock(&globalslock);
04939    if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) {
04940       pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf));
04941       application = expand_buf;
04942    }
04943    ast_mutex_unlock(&globalslock);
04944 
04945    length = sizeof(struct ast_exten);
04946    length += strlen(extension) + 1;
04947    length += strlen(application) + 1;
04948    if (label)
04949       length += strlen(label) + 1;
04950    if (callerid)
04951       length += strlen(callerid) + 1;
04952    else
04953       length ++;  /* just the '\0' */
04954 
04955    /* Be optimistic:  Build the extension structure first */
04956    if (!(tmp = ast_calloc(1, length)))
04957       return -1;
04958 
04959    /* use p as dst in assignments, as the fields are const char * */
04960    p = tmp->stuff;
04961    if (label) {
04962       tmp->label = p;
04963       strcpy(p, label);
04964       p += strlen(label) + 1;
04965    }
04966    tmp->exten = p;
04967    p += ext_strncpy(p, extension, strlen(extension) + 1) + 1;
04968    tmp->priority = priority;
04969    tmp->cidmatch = p;   /* but use p for assignments below */
04970    if (callerid) {
04971       p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1;
04972       tmp->matchcid = 1;
04973    } else {
04974       *p++ = '\0';
04975       tmp->matchcid = 0;
04976    }
04977    tmp->app = p;
04978    strcpy(p, application);
04979    tmp->parent = con;
04980    tmp->data = data;
04981    tmp->datad = datad;
04982    tmp->registrar = registrar;
04983 
04984    ast_mutex_lock(&con->lock);
04985    res = 0; /* some compilers will think it is uninitialized otherwise */
04986    for (e = con->root; e; el = e, e = e->next) {   /* scan the extension list */
04987       res = ext_cmp(e->exten, tmp->exten);
04988       if (res == 0) { /* extension match, now look at cidmatch */
04989          if (!e->matchcid && !tmp->matchcid)
04990             res = 0;
04991          else if (tmp->matchcid && !e->matchcid)
04992             res = 1;
04993          else if (e->matchcid && !tmp->matchcid)
04994             res = -1;
04995          else
04996             res = ext_cmp(e->cidmatch, tmp->cidmatch);
04997       }
04998       if (res >= 0)
04999          break;
05000    }
05001    if (e && res == 0) { /* exact match, insert in the pri chain */
05002       res = add_pri(con, tmp, el, e, replace);
05003       ast_mutex_unlock(&con->lock);
05004       if (res < 0) {
05005          errno = EEXIST;   /* XXX do we care ? */
05006          return 0; /* XXX should we return -1 maybe ? */
05007       }
05008    } else {
05009       /*
05010        * not an exact match, this is the first entry with this pattern,
05011        * so insert in the main list right before 'e' (if any)
05012        */
05013       tmp->next = e;
05014       if (el)
05015          el->next = tmp;
05016       else
05017          con->root = tmp;
05018       ast_mutex_unlock(&con->lock);
05019       if (tmp->priority == PRIORITY_HINT)
05020          ast_add_hint(tmp);
05021    }
05022    if (option_debug) {
05023       if (tmp->matchcid) {
05024          if (option_debug)
05025             ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n",
05026                tmp->exten, tmp->priority, tmp->cidmatch, con->name);
05027       } else {
05028          if (option_debug)
05029             ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n",
05030                tmp->exten, tmp->priority, con->name);
05031       }
05032    }
05033    if (option_verbose > 2) {
05034       if (tmp->matchcid) {
05035          ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n",
05036             tmp->exten, tmp->priority, tmp->cidmatch, con->name);
05037       } else {
05038          ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n",
05039             tmp->exten, tmp->priority, con->name);
05040       }
05041    }
05042    return 0;
05043 }

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

Definition at line 4741 of file pbx.c.

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

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

04742 {
04743    int res = 0;
04744 
04745    ast_channel_lock(chan);
04746 
04747    if (chan->pbx) { /* This channel is currently in the PBX */
04748       ast_explicit_goto(chan, context, exten, priority);
04749       ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
04750    } else {
04751       /* In order to do it when the channel doesn't really exist within
04752          the PBX, we have to make a new channel, masquerade, and start the PBX
04753          at the new location */
04754       struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name);
04755       if (!tmpchan) {
04756          res = -1;
04757       } else {
04758          if (chan->cdr) {
04759             ast_cdr_discard(tmpchan->cdr);
04760             tmpchan->cdr = ast_cdr_dup(chan->cdr);  /* share the love */
04761          }
04762          /* Make formats okay */
04763          tmpchan->readformat = chan->readformat;
04764          tmpchan->writeformat = chan->writeformat;
04765          /* Setup proper location */
04766          ast_explicit_goto(tmpchan,
04767             S_OR(context, chan->context), S_OR(exten, chan->exten), priority);
04768 
04769          /* Masquerade into temp channel */
04770          if (ast_channel_masquerade(tmpchan, chan)) {
04771             /* Failed to set up the masquerade.  It's probably chan_local
04772              * in the middle of optimizing itself out.  Sad. :( */
04773             ast_hangup(tmpchan);
04774             tmpchan = NULL;
04775             res = -1;
04776          } else {
04777             /* Grab the locks and get going */
04778             ast_channel_lock(tmpchan);
04779             ast_do_masquerade(tmpchan);
04780             ast_channel_unlock(tmpchan);
04781             /* Start the PBX going on our stolen channel */
04782             if (ast_pbx_start(tmpchan)) {
04783                ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
04784                ast_hangup(tmpchan);
04785                res = -1;
04786             }
04787          }
04788       }
04789    }
04790    ast_channel_unlock(chan);
04791    return res;
04792 }

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

Definition at line 4794 of file pbx.c.

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

04795 {
04796    struct ast_channel *chan;
04797    int res = -1;
04798 
04799    chan = ast_get_channel_by_name_locked(channame);
04800    if (chan) {
04801       res = ast_async_goto(chan, context, exten, priority);
04802       ast_channel_unlock(chan);
04803    }
04804    return res;
04805 }

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

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

Definition at line 6637 of file pbx.c.

References __ast_goto_if_exists().

Referenced by asyncgoto_exec().

06638 {
06639    return __ast_goto_if_exists(chan, context, exten, priority, 1);
06640 }

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

Definition at line 4381 of file pbx.c.

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

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

04382 {
04383    char info_save[256];
04384    char *info;
04385 
04386    /* Check for empty just in case */
04387    if (ast_strlen_zero(info_in))
04388       return 0;
04389    /* make a copy just in case we were passed a static string */
04390    ast_copy_string(info_save, info_in, sizeof(info_save));
04391    info = info_save;
04392    /* Assume everything except time */
04393    i->monthmask = 0xfff;   /* 12 bits */
04394    i->daymask = 0x7fffffffU; /* 31 bits */
04395    i->dowmask = 0x7f; /* 7 bits */
04396    /* on each call, use strsep() to move info to the next argument */
04397    get_timerange(i, strsep(&info, "|"));
04398    if (info)
04399       i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week");
04400    if (info)
04401       i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day");
04402    if (info)
04403       i->monthmask = get_range(strsep(&info, "|"), 12, months, "month");
04404    return 1;
04405 }

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

Looks for a valid matching extension.

Parameters:
c not really important
context context to serach within
exten extension to check
priority priority of extension path
callerid callerid of extension being searched for
Note:
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
Returns:
If "exten" *could be* a valid extension in this context with or without some more digits, return non-zero. Basically, when this returns 0, no matter what you add to exten, it's not going to be a valid extension anymore

Definition at line 2381 of file pbx.c.

References E_CANMATCH, and pbx_extension_helper().

Referenced by background_detect_exec(), cb_events(), do_immediate_setup(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), handle_link_data(), handle_link_phone_dtmf(), local_dtmf_helper(), loopback_canmatch(), mgcp_ss(), pbx_builtin_background(), phone_check_exception(), skinny_ss(), ss_thread(), and valid_exit().

02382 {
02383    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH);
02384 }

int ast_check_timing ( const struct ast_timing i  ) 

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

04408 {
04409    struct tm tm;
04410    time_t t = time(NULL);
04411 
04412    ast_localtime(&t, &tm, NULL);
04413 
04414    /* If it's not the right month, return */
04415    if (!(i->monthmask & (1 << tm.tm_mon)))
04416       return 0;
04417 
04418    /* If it's not that time of the month.... */
04419    /* Warning, tm_mday has range 1..31! */
04420    if (!(i->daymask & (1 << (tm.tm_mday-1))))
04421       return 0;
04422 
04423    /* If it's not the right day of the week */
04424    if (!(i->dowmask & (1 << tm.tm_wday)))
04425       return 0;
04426 
04427    /* Sanity check the hour just to be safe */
04428    if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
04429       ast_log(LOG_WARNING, "Insane time...\n");
04430       return 0;
04431    }
04432 
04433    /* Now the tough part, we calculate if it fits
04434       in the right time based on min/hour */
04435    if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
04436       return 0;
04437 
04438    /* If we got this far, then we're good */
04439    return 1;
04440 }

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

04635 {
04636    int ret = -1;
04637    struct ast_context *c = find_context_locked(context);
04638 
04639    if (c) {
04640       ret = ast_context_add_ignorepat2(c, value, registrar);
04641       ast_unlock_contexts();
04642    }
04643    return ret;
04644 }

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

Definition at line 4646 of file pbx.c.

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

Referenced by ast_context_add_ignorepat(), and pbx_load_config().

04647 {
04648    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
04649    int length;
04650    char *pattern;
04651    length = sizeof(struct ast_ignorepat);
04652    length += strlen(value) + 1;
04653    if (!(ignorepat = ast_calloc(1, length)))
04654       return -1;
04655    /* The cast to char * is because we need to write the initial value.
04656     * The field is not supposed to be modified otherwise.  Also, gcc 4.2
04657     * sees the cast as dereferencing a type-punned pointer and warns about
04658     * it.  This is the workaround (we're telling gcc, yes, that's really
04659     * what we wanted to do).
04660     */
04661    pattern = (char *) ignorepat->pattern;
04662    strcpy(pattern, value);
04663    ignorepat->next = NULL;
04664    ignorepat->registrar = registrar;
04665    ast_mutex_lock(&con->lock);
04666    for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
04667       ignorepatl = ignorepatc;
04668       if (!strcasecmp(ignorepatc->pattern, value)) {
04669          /* Already there */
04670          ast_mutex_unlock(&con->lock);
04671          errno = EEXIST;
04672          return -1;
04673       }
04674    }
04675    if (ignorepatl)
04676       ignorepatl->next = ignorepat;
04677    else
04678       con->ignorepats = ignorepat;
04679    ast_mutex_unlock(&con->lock);
04680    return 0;
04681 
04682 }

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

04188 {
04189    int ret = -1;
04190    struct ast_context *c = find_context_locked(context);
04191 
04192    if (c) {
04193       ret = ast_context_add_include2(c, include, registrar);
04194       ast_unlock_contexts();
04195    }
04196    return ret;
04197 }

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

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

Referenced by ast_context_add_include(), and pbx_load_config().

04451 {
04452    struct ast_include *new_include;
04453    char *c;
04454    struct ast_include *i, *il = NULL; /* include, include_last */
04455    int length;
04456    char *p;
04457 
04458    length = sizeof(struct ast_include);
04459    length += 2 * (strlen(value) + 1);
04460 
04461    /* allocate new include structure ... */
04462    if (!(new_include = ast_calloc(1, length)))
04463       return -1;
04464    /* Fill in this structure. Use 'p' for assignments, as the fields
04465     * in the structure are 'const char *'
04466     */
04467    p = new_include->stuff;
04468    new_include->name = p;
04469    strcpy(p, value);
04470    p += strlen(value) + 1;
04471    new_include->rname = p;
04472    strcpy(p, value);
04473    /* Strip off timing info, and process if it is there */
04474    if ( (c = strchr(p, '|')) ) {
04475       *c++ = '\0';
04476            new_include->hastime = ast_build_timing(&(new_include->timing), c);
04477    }
04478    new_include->next      = NULL;
04479    new_include->registrar = registrar;
04480 
04481    ast_mutex_lock(&con->lock);
04482 
04483    /* ... go to last include and check if context is already included too... */
04484    for (i = con->includes; i; i = i->next) {
04485       if (!strcasecmp(i->name, new_include->name)) {
04486          free(new_include);
04487          ast_mutex_unlock(&con->lock);
04488          errno = EEXIST;
04489          return -1;
04490       }
04491       il = i;
04492    }
04493 
04494    /* ... include new context into context list, unlock, return */
04495    if (il)
04496       il->next = new_include;
04497    else
04498       con->includes = new_include;
04499    if (option_verbose > 2)
04500       ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
04501    ast_mutex_unlock(&con->lock);
04502 
04503    return 0;
04504 }

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

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

04512 {
04513    int ret = -1;
04514    struct ast_context *c = find_context_locked(context);
04515 
04516    if (c) { /* found, add switch to this context */
04517       ret = ast_context_add_switch2(c, sw, data, eval, registrar);
04518       ast_unlock_contexts();
04519    }
04520    return ret;
04521 }

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

References ast_context::alts, ast_calloc, ast_get_context_name(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_sw::data, errno, ast_sw::eval, free, store_hint::list, ast_context::lock, ast_sw::name, option_verbose, ast_sw::registrar, ast_sw::stuff, and VERBOSE_PREFIX_3.

Referenced by ast_context_add_switch(), and pbx_load_config().

04532 {
04533    struct ast_sw *new_sw;
04534    struct ast_sw *i;
04535    int length;
04536    char *p;
04537 
04538    length = sizeof(struct ast_sw);
04539    length += strlen(value) + 1;
04540    if (data)
04541       length += strlen(data);
04542    length++;
04543 
04544    /* allocate new sw structure ... */
04545    if (!(new_sw = ast_calloc(1, length)))
04546       return -1;
04547    /* ... fill in this structure ... */
04548    p = new_sw->stuff;
04549    new_sw->name = p;
04550    strcpy(new_sw->name, value);
04551    p += strlen(value) + 1;
04552    new_sw->data = p;
04553    if (data) {
04554       strcpy(new_sw->data, data);
04555       p += strlen(data) + 1;
04556    } else {
04557       strcpy(new_sw->data, "");
04558       p++;
04559    }
04560    new_sw->eval     = eval;
04561    new_sw->registrar = registrar;
04562 
04563    /* ... try to lock this context ... */
04564    ast_mutex_lock(&con->lock);
04565 
04566    /* ... go to last sw and check if context is already swd too... */
04567    AST_LIST_TRAVERSE(&con->alts, i, list) {
04568       if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
04569          free(new_sw);
04570          ast_mutex_unlock(&con->lock);
04571          errno = EEXIST;
04572          return -1;
04573       }
04574    }
04575 
04576    /* ... sw new context into context list, unlock, return */
04577    AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
04578 
04579    if (option_verbose > 2)
04580       ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
04581 
04582    ast_mutex_unlock(&con->lock);
04583 
04584    return 0;
04585 }

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

References __ast_context_create().

Referenced by park_call_full(), and set_config().

04045 {
04046    return __ast_context_create(extcontexts, name, registrar, 0);
04047 }

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

References __ast_context_destroy(), ast_unlock_contexts(), and ast_wrlock_contexts().

Referenced by cleanup_stale_contexts(), sla_destroy(), and unload_module().

05500 {
05501    ast_wrlock_contexts();
05502    __ast_context_destroy(con,registrar);
05503    ast_unlock_contexts();
05504 }

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

References ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::name.

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

00949 {
00950    struct ast_context *tmp = NULL;
00951 
00952    ast_rdlock_contexts();
00953 
00954    while ( (tmp = ast_walk_contexts(tmp)) ) {
00955       if (!name || !strcasecmp(name, tmp->name))
00956          break;
00957    }
00958 
00959    ast_unlock_contexts();
00960 
00961    return tmp;
00962 }

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

Definition at line 4049 of file pbx.c.

References __ast_context_create().

Referenced by do_parking_thread(), pbx_load_config(), and pbx_load_users().

04050 {
04051    return __ast_context_create(extcontexts, name, registrar, 1);
04052 }

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

References ast_get_context_name(), ast_mutex_lock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::macrolock.

Referenced by _macro_exec().

03007 {
03008    struct ast_context *c = NULL;
03009    int ret = -1;
03010 
03011    ast_rdlock_contexts();
03012 
03013    while ((c = ast_walk_contexts(c))) {
03014       if (!strcmp(ast_get_context_name(c), context)) {
03015          ret = 0;
03016          break;
03017       }
03018    }
03019 
03020    ast_unlock_contexts();
03021 
03022    /* if we found context, lock macrolock */
03023    if (ret == 0) 
03024       ret = ast_mutex_lock(&c->macrolock);
03025 
03026    return ret;
03027 }

int ast_context_remove_extension ( const char *  context,
const char *  extension,
int  priority,
const char *  registrar 
)

Simply remove extension from context.

Parameters:
context context to remove extension from
extension which extension to remove
priority priority of extension to remove (0 to remove all)
callerid NULL to remove all; non-NULL to match a single record per priority
matchcid non-zero to match callerid element (if non-NULL); 0 to match default case
registrar registrar of the extension
This function removes an extension from a given context.

Return values:
0 on success
-1 on failure

Definition at line 2907 of file pbx.c.

References ast_context_remove_extension_callerid().

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

02908 {
02909    return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar);
02910 }

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

References ast_context_remove_extension_callerid2().

Referenced by do_parking_thread(), and park_exec().

02935 {
02936    return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar);
02937 }

int ast_context_remove_extension_callerid ( const char *  context,
const char *  extension,
int  priority,
const char *  callerid,
int  matchcid,
const char *  registrar 
)

Definition at line 2912 of file pbx.c.

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

Referenced by ast_context_remove_extension(), handle_context_remove_extension(), and handle_context_remove_extension_deprecated().

02913 {
02914    int ret = -1; /* default error return */
02915    struct ast_context *c = find_context_locked(context);
02916 
02917    if (c) { /* ... remove extension ... */
02918       ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar);
02919       ast_unlock_contexts();
02920    }
02921    return ret;
02922 }

int ast_context_remove_extension_callerid2 ( struct ast_context con,
const char *  extension,
int  priority,
const char *  callerid,
int  matchcid,
const char *  registrar 
)

Definition at line 2939 of file pbx.c.

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

Referenced by ast_context_remove_extension2(), and ast_context_remove_extension_callerid().

02940 {
02941    struct ast_exten *exten, *prev_exten = NULL;
02942    struct ast_exten *peer;
02943    struct ast_exten *previous_peer = NULL;
02944    struct ast_exten *next_peer = NULL;
02945    int found = 0;
02946 
02947    ast_mutex_lock(&con->lock);
02948 
02949    /* scan the extension list to find first matching extension-registrar */
02950    for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
02951       if (!strcmp(exten->exten, extension) &&
02952          (!registrar || !strcmp(exten->registrar, registrar)))
02953          break;
02954    }
02955    if (!exten) {
02956       /* we can't find right extension */
02957       ast_mutex_unlock(&con->lock);
02958       return -1;
02959    }
02960 
02961    /* scan the priority list to remove extension with exten->priority == priority */
02962    for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next;
02963          peer && !strcmp(peer->exten, extension);
02964          peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) {
02965       if ((priority == 0 || peer->priority == priority) &&
02966             (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) &&
02967             (!registrar || !strcmp(peer->registrar, registrar) )) {
02968          found = 1;
02969 
02970          /* we are first priority extension? */
02971          if (!previous_peer) {
02972             /*
02973              * We are first in the priority chain, so must update the extension chain.
02974              * The next node is either the next priority or the next extension
02975              */
02976             struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
02977 
02978             if (!prev_exten) {   /* change the root... */
02979                con->root = next_node;
02980             } else {
02981                prev_exten->next = next_node; /* unlink */
02982             }
02983             if (peer->peer)   { /* update the new head of the pri list */
02984                peer->peer->next = peer->next;
02985             }
02986          } else { /* easy, we are not first priority in extension */
02987             previous_peer->peer = peer->peer;
02988          }
02989 
02990          /* now, free whole priority extension */
02991          destroy_exten(peer);
02992       } else {
02993          previous_peer = peer;
02994       }
02995    }
02996    ast_mutex_unlock(&con->lock);
02997    return found ? 0 : -1;
02998 }

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

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

04592 {
04593    int ret = -1;
04594    struct ast_context *c = find_context_locked(context);
04595 
04596    if (c) {
04597       ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
04598       ast_unlock_contexts();
04599    }
04600    return ret;
04601 }

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

Definition at line 4603 of file pbx.c.

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

Referenced by ast_context_remove_ignorepat().

04604 {
04605    struct ast_ignorepat *ip, *ipl = NULL;
04606 
04607    ast_mutex_lock(&con->lock);
04608 
04609    for (ip = con->ignorepats; ip; ip = ip->next) {
04610       if (!strcmp(ip->pattern, ignorepat) &&
04611          (!registrar || (registrar == ip->registrar))) {
04612          if (ipl) {
04613             ipl->next = ip->next;
04614             free(ip);
04615          } else {
04616             con->ignorepats = ip->next;
04617             free(ip);
04618          }
04619          ast_mutex_unlock(&con->lock);
04620          return 0;
04621       }
04622       ipl = ip;
04623    }
04624 
04625    ast_mutex_unlock(&con->lock);
04626    errno = EINVAL;
04627    return -1;
04628 }

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

02804 {
02805    int ret = -1;
02806    struct ast_context *c = find_context_locked(context);
02807 
02808    if (c) {
02809       /* found, remove include from this context ... */
02810       ret = ast_context_remove_include2(c, include, registrar);
02811       ast_unlock_contexts();
02812    }
02813    return ret;
02814 }

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

02825 {
02826    struct ast_include *i, *pi = NULL;
02827    int ret = -1;
02828 
02829    ast_mutex_lock(&con->lock);
02830 
02831    /* find our include */
02832    for (i = con->includes; i; pi = i, i = i->next) {
02833       if (!strcmp(i->name, include) &&
02834             (!registrar || !strcmp(i->registrar, registrar))) {
02835          /* remove from list */
02836          if (pi)
02837             pi->next = i->next;
02838          else
02839             con->includes = i->next;
02840          /* free include and return */
02841          free(i);
02842          ret = 0;
02843          break;
02844       }
02845    }
02846 
02847    ast_mutex_unlock(&con->lock);
02848    return ret;
02849 }

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

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

02857 {
02858    int ret = -1; /* default error return */
02859    struct ast_context *c = find_context_locked(context);
02860 
02861    if (c) {
02862       /* remove switch from this context ... */
02863       ret = ast_context_remove_switch2(c, sw, data, registrar);
02864       ast_unlock_contexts();
02865    }
02866    return ret;
02867 }

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

References ast_context::alts, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), ast_sw::data, free, ast_sw::list, ast_context::lock, ast_sw::name, and ast_sw::registrar.

Referenced by ast_context_remove_switch().

02878 {
02879    struct ast_sw *i;
02880    int ret = -1;
02881 
02882    ast_mutex_lock(&con->lock);
02883 
02884    /* walk switches */
02885    AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
02886       if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
02887          (!registrar || !strcmp(i->registrar, registrar))) {
02888          /* found, remove from list */
02889          AST_LIST_REMOVE_CURRENT(&con->alts, list);
02890          free(i); /* free switch and return */
02891          ret = 0;
02892          break;
02893       }
02894    }
02895    AST_LIST_TRAVERSE_SAFE_END
02896 
02897    ast_mutex_unlock(&con->lock);
02898 
02899    return ret;
02900 }

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

References ast_get_context_name(), ast_mutex_unlock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::macrolock.

Referenced by _macro_exec().

03035 {
03036    struct ast_context *c = NULL;
03037    int ret = -1;
03038 
03039    ast_rdlock_contexts();
03040 
03041    while ((c = ast_walk_contexts(c))) {
03042       if (!strcmp(ast_get_context_name(c), context)) {
03043          ret = 0;
03044          break;
03045       }
03046    }
03047 
03048    ast_unlock_contexts();
03049 
03050    /* if we found context, unlock macrolock */
03051    if (ret == 0) 
03052       ret = ast_mutex_unlock(&c->macrolock);
03053 
03054    return ret;
03055 }

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

06595 {
06596    struct ast_include *inc = NULL;
06597    int res = 0;
06598 
06599    while ( (inc = ast_walk_context_includes(con, inc)) ) {
06600       if (ast_context_find(inc->rname))
06601          continue;
06602 
06603       res = -1;
06604       ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n",
06605          ast_get_context_name(con), inc->rname);
06606       break;
06607    }
06608 
06609    return res;
06610 }

struct ast_custom_function* ast_custom_function_find ( const char *  name  ) 

Definition at line 1510 of file pbx.c.

References ast_custom_function::acflist, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_custom_function::name.

Referenced by ast_custom_function_register(), ast_func_read(), ast_func_write(), handle_show_function(), and handle_show_function_deprecated().

01511 {
01512    struct ast_custom_function *acf = NULL;
01513 
01514    AST_LIST_LOCK(&acf_root);
01515    AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
01516       if (!strcmp(name, acf->name))
01517          break;
01518    }
01519    AST_LIST_UNLOCK(&acf_root);
01520 
01521    return acf;
01522 }

int ast_custom_function_register ( struct ast_custom_function acf  ) 

Reigster a custom function.

Definition at line 1546 of file pbx.c.

References ast_custom_function::acflist, ast_custom_function_find(), AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), LOG_ERROR, ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.

Referenced by load_module(), odbc_load_module(), and reload().

01547 {
01548    struct ast_custom_function *cur;
01549 
01550    if (!acf)
01551       return -1;
01552 
01553    AST_LIST_LOCK(&acf_root);
01554 
01555    if (ast_custom_function_find(acf->name)) {
01556       ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
01557       AST_LIST_UNLOCK(&acf_root);
01558       return -1;
01559    }
01560 
01561    /* Store in alphabetical order */
01562    AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
01563       if (strcasecmp(acf->name, cur->name) < 0) {
01564          AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist);
01565          break;
01566       }
01567    }
01568    AST_LIST_TRAVERSE_SAFE_END
01569    if (!cur)
01570       AST_LIST_INSERT_TAIL(&acf_root, acf, acflist);
01571 
01572    AST_LIST_UNLOCK(&acf_root);
01573 
01574    if (option_verbose > 1)
01575       ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name);
01576 
01577    return 0;
01578 }

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

Definition at line 1524 of file pbx.c.

References ast_custom_function::acflist, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.

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

01525 {
01526    struct ast_custom_function *cur;
01527 
01528    if (!acf)
01529       return -1;
01530 
01531    AST_LIST_LOCK(&acf_root);
01532    AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
01533       if (cur == acf) {
01534          AST_LIST_REMOVE_CURRENT(&acf_root, acflist);
01535          if (option_verbose > 1)
01536             ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name);
01537          break;
01538       }
01539    }
01540    AST_LIST_TRAVERSE_SAFE_END
01541    AST_LIST_UNLOCK(&acf_root);
01542 
01543    return acf ? 0 : -1;
01544 }

enum ast_extension_states ast_devstate_to_extenstate ( enum ast_device_state  devstate  ) 

Map devstate to an extension state.

Parameters:
[in] device state
Returns:
the extension state mapping.

Definition at line 1974 of file pbx.c.

References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_TOTAL, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, AST_EXTENSION_BUSY, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_RINGING, and AST_EXTENSION_UNAVAILABLE.

Referenced by ast_extension_state2().

01975 {
01976    switch (devstate) {
01977    case AST_DEVICE_ONHOLD:
01978       return AST_EXTENSION_ONHOLD;
01979    case AST_DEVICE_BUSY:
01980       return AST_EXTENSION_BUSY;
01981    case AST_DEVICE_UNKNOWN:
01982       return AST_EXTENSION_NOT_INUSE;
01983    case AST_DEVICE_UNAVAILABLE:
01984    case AST_DEVICE_INVALID:
01985       return AST_EXTENSION_UNAVAILABLE;
01986    case AST_DEVICE_RINGINUSE:
01987       return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING);
01988    case AST_DEVICE_RINGING:
01989       return AST_EXTENSION_RINGING;
01990    case AST_DEVICE_INUSE:
01991       return AST_EXTENSION_INUSE;
01992    case AST_DEVICE_NOT_INUSE:
01993       return AST_EXTENSION_NOT_INUSE;
01994    case AST_DEVICE_TOTAL: /* not a device state, included for completeness */
01995       break;
01996    }
01997 
01998    return AST_EXTENSION_NOT_INUSE;
01999 }

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

Determine whether an extension exists.

Parameters:
c this is not important
context which context to look in
exten which extension to search for
priority priority of the action within the extension
callerid callerid to search for
Note:
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
Returns:
If an extension within the given context(or callerid) with the given priority is found a non zero value will be returned. Otherwise, 0 is returned.

Definition at line 2366 of file pbx.c.

References E_MATCH, and pbx_extension_helper().

Referenced by __ast_goto_if_exists(), __ast_pbx_run(), __login_exec(), _macro_exec(), agentmonitoroutgoing_exec(), answer_call(), ast_app_dtget(), ast_bridge_call(), ast_pbx_outgoing_exten(), cb_events(), conf_run(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), dahdi_handle_dtmf(), dahdi_r2_on_call_offered(), dahdi_r2_on_dnis_digit_received(), disa_exec(), dp_lookup(), dundi_lookup_local(), findmeexec(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), handle_stimulus_message(), leave_voicemail(), local_alloc(), local_call(), local_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), misdn_overlap_dial_task(), park_space_reserve(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), pri_dchannel(), process_ast_dsp(), register_peer_exten(), sip_new(), skinny_ss(), socket_process(), ss_thread(), and waitstream_core().

02367 {
02368    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH);
02369 }

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

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

Definition at line 4718 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_FLAG_IN_AUTOLOOP, ast_strlen_zero(), ast_test_flag, ast_channel::context, ast_channel::exten, and ast_channel::priority.

Referenced by __ast_goto_if_exists(), ast_async_goto(), ast_parseable_goto(), builtin_atxfer(), disa_exec(), and handle_setpriority().

04719 {
04720    if (!chan)
04721       return -1;
04722 
04723    ast_channel_lock(chan);
04724 
04725    if (!ast_strlen_zero(context))
04726       ast_copy_string(chan->context, context, sizeof(chan->context));
04727    if (!ast_strlen_zero(exten))
04728       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
04729    if (priority > -1) {
04730       chan->priority = priority;
04731       /* see flag description in channel.h for explanation */
04732       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
04733          chan->priority--;
04734    }
04735 
04736    ast_channel_unlock(chan);
04737 
04738    return 0;
04739 }

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

Definition at line 941 of file pbx.c.

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

Referenced by realtime_switch_common().

00942 {
00943    if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
00944       ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
00945    return extension_match_core(pattern, data, needmore);
00946 }

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

References E_MATCH, and extension_match_core().

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

00937 {
00938    return extension_match_core(pattern, data, E_MATCH);
00939 }

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

References ast_extension_state2(), and ast_hint_extension().

Referenced by action_extensionstate(), and handle_request_subscribe().

02037 {
02038    struct ast_exten *e;
02039 
02040    e = ast_hint_extension(c, context, exten);   /* Do we have a hint for this extension ? */
02041    if (!e)
02042       return -1;           /* No hint, return -1 */
02043 
02044    return ast_extension_state2(e);        /* Check all devices in the hint */
02045 }

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

References extension_states.

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

02025 {
02026    int i;
02027 
02028    for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) {
02029       if (extension_states[i].extension_state == extension_state)
02030          return extension_states[i].text;
02031    }
02032    return "Unknown";
02033 }

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

References ao2_lock(), ao2_unlock(), ast_calloc, ast_state_cb::callback, ast_state_cb::data, hints, ast_state_cb::next, and statecbs.

Referenced by handle_request_subscribe(), and init_manager().

02120 {
02121    struct ast_hint *hint;
02122    struct ast_state_cb *cblist;
02123    struct ast_exten *e;
02124 
02125    /* If there's no context and extension:  add callback to statecbs list */
02126    if (!context && !exten) {
02127       ao2_lock(hints);
02128 
02129       for (cblist = statecbs; cblist; cblist = cblist->next) {
02130          if (cblist->callback == callback) {
02131             cblist->data = data;
02132             ao2_unlock(hints);
02133             return 0;
02134          }
02135       }
02136 
02137       /* Now insert the callback */
02138       if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
02139          ao2_unlock(hints);
02140          return -1;
02141       }
02142       cblist->id = 0;
02143       cblist->callback = callback;
02144       cblist->data = data;
02145 
02146       cblist->next = statecbs;
02147       statecbs = cblist;
02148 
02149       ao2_unlock(hints);
02150       return 0;
02151    }
02152 
02153    if (!context || !exten)
02154       return -1;
02155 
02156    /* This callback type is for only one hint, so get the hint */
02157    e = ast_hint_extension(NULL, context, exten);
02158    if (!e) {
02159       return -1;
02160    }
02161 
02162    hint = ao2_find(hints, e, 0);
02163 
02164    if (!hint) {
02165       return -1;
02166    }
02167 
02168    /* Now insert the callback in the callback list  */
02169    if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
02170       ao2_ref(hint, -1);
02171       return -1;
02172    }
02173    cblist->id = stateid++;    /* Unique ID for this callback */
02174    cblist->callback = callback;  /* Pointer to callback routine */
02175    cblist->data = data;    /* Data for the callback */
02176 
02177    ao2_lock(hint);
02178    cblist->next = hint->callbacks;
02179    hint->callbacks = cblist;
02180    ao2_unlock(hint);
02181 
02182    ao2_ref(hint, -1);
02183 
02184    return cblist->id;
02185 }

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

References ao2_lock(), ao2_unlock(), free, hints, ast_state_cb::next, and statecbs.

Referenced by __sip_destroy(), and handle_request_subscribe().

02204 {
02205    struct ast_state_cb **p_cur = NULL; /* address of pointer to us */
02206    int ret = -1;
02207 
02208    if (!id && !callback) {
02209       return -1;
02210    }
02211 
02212    if (!id) {  /* id == 0 is a callback without extension */
02213       ao2_lock(hints);
02214       for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) {
02215          if ((*p_cur)->callback == callback) {
02216             break;
02217          }
02218       }
02219       if (p_cur && *p_cur) {
02220          struct ast_state_cb *cur = *p_cur;
02221          *p_cur = cur->next;
02222          free(cur);
02223          ret = 0;
02224       }
02225       ao2_unlock(hints);
02226    } else { /* callback with extension, find the callback based on ID */
02227       struct ast_hint *hint;
02228 
02229       hint = ao2_callback(hints, 0, find_hint_by_cb_id, &id);
02230 
02231       if (hint) {
02232          ao2_lock(hint);
02233          for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) {
02234             if ((*p_cur)->id == id) {
02235                break;
02236             }
02237          }
02238          if (p_cur && *p_cur) {
02239             struct ast_state_cb *cur = *p_cur;
02240             *p_cur = cur->next;
02241             free(cur);
02242             ret = 0;
02243          }
02244          ao2_unlock(hint);
02245          ao2_ref(hint, -1);
02246       }
02247    }
02248 
02249    return ret;
02250 }

int ast_findlabel_extension ( struct ast_channel c,
const char *  context,
const char *  exten,
const char *  label,
const char *  callerid 
)

Find the priority of an extension that has the specified label.

Parameters:
c this is not important
context which context to look in
exten which extension to search for
label label of the action within the extension to match to priority
callerid callerid to search for
Note:
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
Returns:
the priority which matches the given label in the extension or -1 if not found.

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

02372 {
02373    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL);
02374 }

int ast_findlabel_extension2 ( struct ast_channel c,
struct ast_context con,
const char *  exten,
const char *  label,
const char *  callerid 
)

Find the priority of an extension that has the specified label.

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

This function is the same as ast_findlabel_extension, except that it accepts a pointer to an ast_context structure to specify the context instead of the name of the context. Otherwise, the functions behave the same.

Definition at line 2376 of file pbx.c.

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

02377 {
02378    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL);
02379 }

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

01601 {
01602    char *args = func_args(function);
01603    struct ast_custom_function *acfptr = ast_custom_function_find(function);
01604 
01605    if (acfptr == NULL)
01606       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01607    else if (!acfptr->read)
01608       ast_log(LOG_ERROR, "Function %s cannot be read\n", function);
01609    else
01610       return acfptr->read(chan, function, args, workspace, len);
01611    return -1;
01612 }

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

References ast_custom_function_find(), ast_log(), func_args(), LOG_ERROR, and ast_custom_function::write.

Referenced by action_setvar(), pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().

01615 {
01616    char *args = func_args(function);
01617    struct ast_custom_function *acfptr = ast_custom_function_find(function);
01618 
01619    if (acfptr == NULL)
01620       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01621    else if (!acfptr->write)
01622       ast_log(LOG_ERROR, "Function %s cannot be written to\n", function);
01623    else
01624       return acfptr->write(chan, function, args, value);
01625 
01626    return -1;
01627 }

const char* ast_get_context_name ( struct ast_context con  ) 

Definition at line 6451 of file pbx.c.

References ast_context::name.

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

06452 {
06453    return con ? con->name : NULL;
06454 }

const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 6489 of file pbx.c.

References ast_context::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06490 {
06491    return c ? c->registrar : NULL;
06492 }

const char* ast_get_extension_app ( struct ast_exten e  ) 

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

06520 {
06521    return e ? e->app : NULL;
06522 }

void* ast_get_extension_app_data ( struct ast_exten e  ) 

Definition at line 6524 of file pbx.c.

References ast_exten::data.

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

06525 {
06526    return e ? e->data : NULL;
06527 }

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 6514 of file pbx.c.

References ast_exten::cidmatch.

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

06515 {
06516    return e ? e->cidmatch : NULL;
06517 }

struct ast_context* ast_get_extension_context ( struct ast_exten exten  ) 

Definition at line 6456 of file pbx.c.

References exten.

Referenced by handle_show_hints().

06457 {
06458    return exten ? exten->parent : NULL;
06459 }

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 6466 of file pbx.c.

References exten.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06467 {
06468    return exten ? exten->label : NULL;
06469 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 6509 of file pbx.c.

References ast_exten::matchcid.

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

06510 {
06511    return e ? e->matchcid : 0;
06512 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 

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

06462 {
06463    return exten ? exten->exten : NULL;
06464 }

int ast_get_extension_priority ( struct ast_exten exten  ) 

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

06482 {
06483    return exten ? exten->priority : -1;
06484 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 6494 of file pbx.c.

References ast_exten::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06495 {
06496    return e ? e->registrar : NULL;
06497 }

int ast_get_hint ( char *  hint,
int  maxlen,
char *  name,
int  maxnamelen,
struct ast_channel c,
const char *  context,
const char *  exten 
)

If an extension exists, return non-zero.

Parameters:
hint buffer for hint
maxlen size of hint buffer
name buffer for name portion of hint
maxnamelen size of name buffer
c this is not important
context which context to look in
exten which extension to search for
Returns:
If an extension within the given context with the priority PRIORITY_HINT is found a non zero value will be returned. Otherwise, 0 is returned.

Definition at line 2349 of file pbx.c.

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

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

02350 {
02351    struct ast_exten *e = ast_hint_extension(c, context, exten);
02352 
02353    if (e) {
02354       if (hint)
02355          ast_copy_string(hint, ast_get_extension_app(e), hintsize);
02356       if (name) {
02357          const char *tmp = ast_get_extension_app_data(e);
02358          if (tmp)
02359             ast_copy_string(name, tmp, namesize);
02360       }
02361       return -1;
02362    }
02363    return 0;
02364 }

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 

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

06477 {
06478    return ip ? ip->pattern : NULL;
06479 }

const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

Definition at line 6504 of file pbx.c.

References ast_ignorepat::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06505 {
06506    return ip ? ip->registrar : NULL;
06507 }

const char* ast_get_include_name ( struct ast_include include  ) 

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

06472 {
06473    return inc ? inc->name : NULL;
06474 }

const char* ast_get_include_registrar ( struct ast_include i  ) 

Definition at line 6499 of file pbx.c.

References ast_include::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06500 {
06501    return i ? i->registrar : NULL;
06502 }

const char* ast_get_switch_data ( struct ast_sw sw  ) 

Definition at line 6534 of file pbx.c.

References ast_sw::data.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06535 {
06536    return sw ? sw->data : NULL;
06537 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

Definition at line 6529 of file pbx.c.

References ast_sw::name.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06530 {
06531    return sw ? sw->name : NULL;
06532 }

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

Definition at line 6539 of file pbx.c.

References ast_sw::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06540 {
06541    return sw ? sw->registrar : NULL;
06542 }

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

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

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

06633 {
06634    return __ast_goto_if_exists(chan, context, exten, priority, 0);
06635 }

void ast_hint_state_changed ( const char *  device  ) 

Definition at line 2047 of file pbx.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next(), ao2_lock(), ao2_ref(), ao2_unlock(), ast_dynamic_str_create(), ast_dynamic_str_set(), ast_extension_state2(), ast_free, ast_get_extension_app(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_hint::callbacks, ast_exten::exten, ast_hint::exten, hints, ast_hint::laststate, ast_context::name, ast_state_cb::next, ast_exten::parent, parse(), statecbs, and ast_dynamic_str::str.

Referenced by do_state_change().

02048 {
02049    struct ast_hint *hint;
02050    struct ast_dynamic_str *str;
02051    struct ao2_iterator i;
02052 
02053    if (!(str = ast_dynamic_str_create(1024))) {
02054       return;
02055    }
02056 
02057    i = ao2_iterator_init(hints, 0);
02058    for (hint = ao2_iterator_next(&i); hint; ao2_ref(hint, -1), hint = ao2_iterator_next(&i)) {
02059       struct ast_state_cb *cblist;
02060       char *cur, *parse;
02061       int state;
02062 
02063       ast_dynamic_str_set(&str, 0, "%s", ast_get_extension_app(hint->exten));
02064       parse = str->str;
02065 
02066       while ( (cur = strsep(&parse, "&")) ) {
02067          if (!strcasecmp(cur, device)) {
02068             break;
02069          }
02070       }
02071 
02072       if (!cur) {
02073          continue;
02074       }
02075 
02076       /* Get device state for this hint */
02077       state = ast_extension_state2(hint->exten);
02078 
02079       if ((state == -1) || (state == hint->laststate)) {
02080          continue;
02081       }
02082 
02083       /* Device state changed since last check - notify the watchers */
02084 
02085       ast_rdlock_contexts();
02086       ao2_lock(hints);
02087       ao2_lock(hint);
02088 
02089       if (hint->exten == NULL) {
02090          /* the extension has been destroyed */
02091          ao2_unlock(hint);
02092          ao2_unlock(hints);
02093          ast_unlock_contexts();
02094          continue;
02095       }
02096 
02097       /* For general callbacks */
02098       for (cblist = statecbs; cblist; cblist = cblist->next) {
02099          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
02100       }
02101 
02102       /* For extension callbacks */
02103       for (cblist = hint->callbacks; cblist; cblist = cblist->next) {
02104          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
02105       }
02106 
02107       hint->laststate = state;   /* record we saw the change */
02108       ao2_unlock(hint);
02109       ao2_unlock(hints);
02110       ast_unlock_contexts();
02111    }
02112 
02113    ao2_iterator_destroy(&i);
02114    ast_free(str);
02115 }

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

04685 {
04686    struct ast_context *con = ast_context_find(context);
04687    if (con) {
04688       struct ast_ignorepat *pat;
04689       for (pat = con->ignorepats; pat; pat = pat->next) {
04690          if (ast_extension_match(pat->pattern, pattern))
04691             return 1;
04692       }
04693    }
04694 
04695    return 0;
04696 }

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

06439 {
06440    return ast_mutex_lock(&con->lock);
06441 }

int ast_lock_contexts ( void   ) 

Locks the context list.

Return values:
0 on success
-1 on error

Definition at line 6415 of file pbx.c.

References ast_mutex_lock(), and conlock.

Referenced by find_matching_endwhile().

06416 {
06417    return ast_mutex_lock(&conlock);
06418 }

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

Looks to see if adding anything to this extension might match something. (exists ^ canmatch).

Parameters:
c not really important XXX
context context to serach within
exten extension to check
priority priority of extension path
callerid callerid of extension being searched for
Note:
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
Returns:
If "exten" *could match* a valid extension in this context with some more digits, return non-zero. Does NOT return non-zero if this is an exact-match only. Basically, when this returns 0, no matter what you add to exten, it's not going to be a valid extension anymore

Definition at line 2386 of file pbx.c.

References E_MATCHMORE, and pbx_extension_helper().

Referenced by ast_app_dtget(), collect_digits(), dahdi_r2_on_dnis_digit_received(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_stimulus_message(), loopback_matchmore(), mgcp_ss(), pbx_builtin_background(), skinny_ss(), and ss_thread().

02387 {
02388    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE);
02389 }

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

References __ast_context_destroy(), ao2_find(), AO2_ITERATOR_DONTLOCK, ao2_iterator_init(), ao2_iterator_next(), ao2_lock(), ao2_ref(), ao2_unlock(), ast_calloc, AST_EXTENSION_REMOVED, AST_LIST_HEAD_INIT_VALUE, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_unlock_contexts(), ast_wrlock_contexts(), ast_state_cb::callback, store_hint::callbacks, ast_hint::callbacks, store_hint::context, contexts, ast_state_cb::data, E_MATCH, store_hint::exten, ast_exten::exten, ast_hint::exten, free, hints, ast_hint::laststate, store_hint::laststate, store_hint::list, LOG_WARNING, ast_context::name, ast_state_cb::next, ast_context::next, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_context::registrar, and pbx_find_info::stacklen.

Referenced by pbx_load_module().

04068 {
04069    struct ast_context *tmp, *lasttmp = NULL;
04070    struct store_hints store = AST_LIST_HEAD_INIT_VALUE;
04071    struct store_hint *this;
04072    struct ast_hint *hint;
04073    struct ast_exten *exten;
04074    int length;
04075    struct ast_state_cb *thiscb, *prevcb;
04076    struct ao2_iterator i;
04077 
04078    /* it is very important that this function hold the hint list lock _and_ the conlock
04079       during its operation; not only do we need to ensure that the list of contexts
04080       and extensions does not change, but also that no hint callbacks (watchers) are
04081       added or removed during the merge/delete process
04082 
04083       in addition, the locks _must_ be taken in this order, because there are already
04084       other code paths that use this order
04085    */
04086    ast_wrlock_contexts();
04087    ao2_lock(hints);
04088 
04089    /* preserve all watchers for hints associated with this registrar */
04090    i = ao2_iterator_init(hints, AO2_ITERATOR_DONTLOCK);
04091    for (hint = ao2_iterator_next(&i); hint; ao2_ref(hint, -1), hint = ao2_iterator_next(&i)) {
04092       if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) {
04093          length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this);
04094          if (!(this = ast_calloc(1, length))) {
04095             continue;
04096          }
04097          ao2_lock(hint);
04098 
04099          if (hint->exten == NULL) {
04100             ao2_unlock(hint);
04101             continue;
04102          }
04103 
04104          this->callbacks = hint->callbacks;
04105          hint->callbacks = NULL;
04106          this->laststate = hint->laststate;
04107          ao2_unlock(hint);
04108          this->context = this->data;
04109          strcpy(this->data, hint->exten->parent->name);
04110          this->exten = this->data + strlen(this->context) + 1;
04111          strcpy(this->exten, hint->exten->exten);
04112          AST_LIST_INSERT_HEAD(&store, this, list);
04113       }
04114    }
04115 
04116    tmp = *extcontexts;
04117    if (registrar) {
04118       /* XXX remove previous contexts from same registrar */
04119       if (option_debug)
04120          ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar);
04121       __ast_context_destroy(NULL,registrar);
04122       while (tmp) {
04123          lasttmp = tmp;
04124          tmp = tmp->next;
04125       }
04126    } else {
04127       /* XXX remove contexts with the same name */
04128       while (tmp) {
04129          ast_log(LOG_WARNING, "must remove %s  reg %s\n", tmp->name, tmp->registrar);
04130          __ast_context_destroy(tmp,tmp->registrar);
04131          lasttmp = tmp;
04132          tmp = tmp->next;
04133       }
04134    }
04135    if (lasttmp) {
04136       lasttmp->next = contexts;
04137       contexts = *extcontexts;
04138       *extcontexts = NULL;
04139    } else
04140       ast_log(LOG_WARNING, "Requested contexts didn't get merged\n");
04141 
04142    /* restore the watchers for hints that can be found; notify those that
04143       cannot be restored
04144    */
04145    while ((this = AST_LIST_REMOVE_HEAD(&store, list))) {
04146       struct pbx_find_info q = { .stacklen = 0 };
04147       exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH);
04148       hint = ao2_find(hints, exten, 0);
04149       if (!exten || !hint) {
04150          /* this hint has been removed, notify the watchers */
04151          prevcb = NULL;
04152          thiscb = this->callbacks;
04153          while (thiscb) {
04154             prevcb = thiscb;
04155             thiscb = thiscb->next;
04156             prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data);
04157             free(prevcb);
04158             }
04159       } else {
04160          thiscb = this->callbacks;
04161          while (thiscb->next) {
04162             thiscb = thiscb->next;
04163          }
04164          ao2_lock(hint);
04165          thiscb->next = hint->callbacks;
04166          hint->callbacks = this->callbacks;
04167          hint->laststate = this->laststate;
04168          ao2_unlock(hint);
04169       }
04170       if (hint) {
04171          ao2_ref(hint, -1);
04172       }
04173       free(this);
04174    }
04175 
04176    ao2_unlock(hints);
04177    ast_unlock_contexts();
04178 
04179    return;
04180 }

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

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

This function will handle locking the channel as needed.

Definition at line 6642 of file pbx.c.

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

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

06643 {
06644    char *exten, *pri, *context;
06645    char *stringp;
06646    int ipri;
06647    int mode = 0;
06648 
06649    if (ast_strlen_zero(goto_string)) {
06650       ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
06651       return -1;
06652    }
06653    stringp = ast_strdupa(goto_string);
06654    context = strsep(&stringp, "|"); /* guaranteed non-null */
06655    exten = strsep(&stringp, "|");
06656    pri = strsep(&stringp, "|");
06657    if (!exten) {  /* Only a priority in this one */
06658       pri = context;
06659       exten = NULL;
06660       context = NULL;
06661    } else if (!pri) {   /* Only an extension and priority in this one */
06662       pri = exten;
06663       exten = context;
06664       context = NULL;
06665    }
06666    if (*pri == '+') {
06667       mode = 1;
06668       pri++;
06669    } else if (*pri == '-') {
06670       mode = -1;
06671       pri++;
06672    }
06673    if (sscanf(pri, "%30d", &ipri) != 1) {
06674       if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten,
06675          pri, chan->cid.cid_num)) < 1) {
06676          ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);
06677          return -1;
06678       } else
06679          mode = 0;
06680    }
06681    /* At this point we have a priority and maybe an extension and a context */
06682 
06683    if (mode)
06684       ipri = chan->priority + (ipri * mode);
06685 
06686    ast_explicit_goto(chan, context, exten, ipri);
06687    return 0;
06688 
06689 }

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

References __ast_request_and_dial(), ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), async_stat::chan, errno, free, LOG_WARNING, option_verbose, outgoing_helper::vars, and VERBOSE_PREFIX_4.

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

05312 {
05313    struct ast_channel *chan;
05314    struct app_tmp *tmp;
05315    int res = -1, cdr_res = -1;
05316    struct outgoing_helper oh;
05317    pthread_attr_t attr;
05318 
05319    memset(&oh, 0, sizeof(oh));
05320    oh.vars = vars;
05321    oh.account = account;
05322 
05323    if (locked_channel)
05324       *locked_channel = NULL;
05325    if (ast_strlen_zero(app)) {
05326       res = -1;
05327       goto outgoing_app_cleanup;
05328    }
05329    if (sync) {
05330       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
05331       if (chan) {
05332          ast_set_variables(chan, vars);
05333          if (account)
05334             ast_cdr_setaccount(chan, account);
05335          if (chan->_state == AST_STATE_UP) {
05336             res = 0;
05337             if (option_verbose > 3)
05338                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
05339             tmp = ast_calloc(1, sizeof(*tmp));
05340             if (!tmp)
05341                res = -1;
05342             else {
05343                ast_copy_string(tmp->app, app, sizeof(tmp->app));
05344                if (appdata)
05345                   ast_copy_string(tmp->data, appdata, sizeof(tmp->data));
05346                tmp->chan = chan;
05347                if (sync > 1) {
05348                   if (locked_channel)
05349                      ast_channel_unlock(chan);
05350                   ast_pbx_run_app(tmp);
05351                } else {
05352                   pthread_attr_init(&attr);
05353                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05354                   if (locked_channel)
05355                      ast_channel_lock(chan);
05356                   if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) {
05357                      ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
05358                      free(tmp);
05359                      if (locked_channel)
05360                         ast_channel_unlock(chan);
05361                      ast_hangup(chan);
05362                      res = -1;
05363                   } else {
05364                      if (locked_channel)
05365                         *locked_channel = chan;
05366                   }
05367                   pthread_attr_destroy(&attr);
05368                }
05369             }
05370          } else {
05371             if (option_verbose > 3)
05372                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
05373             if (chan->cdr) { /* update the cdr */
05374                /* here we update the status of the call, which sould be busy.
05375                 * if that fails then we set the status to failed */
05376                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
05377                   ast_cdr_failed(chan->cdr);
05378             }
05379             ast_hangup(chan);
05380          }
05381       }
05382 
05383       if (res < 0) { /* the call failed for some reason */
05384          if (*reason == 0) { /* if the call failed (not busy or no answer)
05385                         * update the cdr with the failed message */
05386             cdr_res = ast_pbx_outgoing_cdr_failed();
05387             if (cdr_res != 0) {
05388                res = cdr_res;
05389                goto outgoing_app_cleanup;
05390             }
05391          }
05392       }
05393 
05394    } else {
05395       struct async_stat *as;
05396       if (!(as = ast_calloc(1, sizeof(*as)))) {
05397          res = -1;
05398          goto outgoing_app_cleanup;
05399       }
05400       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
05401       if (!chan) {
05402          free(as);
05403          res = -1;
05404          goto outgoing_app_cleanup;
05405       }
05406       as->chan = chan;
05407       ast_copy_string(as->app, app, sizeof(as->app));
05408       if (appdata)
05409          ast_copy_string(as->appdata,  appdata, sizeof(as->appdata));
05410       as->timeout = timeout;
05411       ast_set_variables(chan, vars);
05412       if (account)
05413          ast_cdr_setaccount(chan, account);
05414       /* Start a new thread, and get something handling this channel. */
05415       pthread_attr_init(&attr);
05416       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05417       if (locked_channel)
05418          ast_channel_lock(chan);
05419       if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
05420          ast_log(LOG_WARNING, "Failed to start async wait\n");
05421          free(as);
05422          if (locked_channel)
05423             ast_channel_unlock(chan);
05424          ast_hangup(chan);
05425          res = -1;
05426          pthread_attr_destroy(&attr);
05427          goto outgoing_app_cleanup;
05428       } else {
05429          if (locked_channel)
05430             *locked_channel = chan;
05431       }
05432       pthread_attr_destroy(&attr);
05433       res = 0;
05434    }
05435 outgoing_app_cleanup:
05436    ast_variables_destroy(vars);
05437    return res;
05438 }

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

References __ast_request_and_dial(), ast_channel::_state, ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_alloc(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_exists_extension(), ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create, ast_request_and_dial(), ast_set_variables(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, ast_channel::context, free, ast_channel::hangupcause, LOAD_OH, LOG_ERROR, LOG_WARNING, ast_channel::name, option_verbose, pbx_builtin_setvar_helper(), set_ext_pri(), outgoing_helper::vars, and VERBOSE_PREFIX_4.

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

05146 {
05147    struct ast_channel *chan;
05148    struct async_stat *as;
05149    int res = -1, cdr_res = -1;
05150    struct outgoing_helper oh;
05151    pthread_attr_t attr;
05152 
05153    if (sync) {
05154       LOAD_OH(oh);
05155       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
05156       if (channel) {
05157          *channel = chan;
05158          if (chan)
05159             ast_channel_lock(chan);
05160       }
05161       if (chan) {
05162          if (chan->_state == AST_STATE_UP) {
05163                res = 0;
05164             if (option_verbose > 3)
05165                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
05166 
05167             if (sync > 1) {
05168                if (channel)
05169                   ast_channel_unlock(chan);
05170                if (ast_pbx_run(chan)) {
05171                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
05172                   if (channel)
05173                      *channel = NULL;
05174                   ast_hangup(chan);
05175                   chan = NULL;
05176                   res = -1;
05177                }
05178             } else {
05179                if (ast_pbx_start(chan)) {
05180                   ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name);
05181                   if (channel) {
05182                      *channel = NULL;
05183                      ast_channel_unlock(chan);
05184                   }
05185                   ast_hangup(chan);
05186                   res = -1;
05187                }
05188                chan = NULL;
05189             }
05190          } else {
05191             if (option_verbose > 3)
05192                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
05193 
05194             if (chan->cdr) { /* update the cdr */
05195                /* here we update the status of the call, which sould be busy.
05196                 * if that fails then we set the status to failed */
05197                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
05198                   ast_cdr_failed(chan->cdr);
05199             }
05200 
05201             if (channel) {
05202                *channel = NULL;
05203                ast_channel_unlock(chan);
05204             }
05205             ast_hangup(chan);
05206             chan = NULL;
05207          }
05208       }
05209 
05210       if (res < 0) { /* the call failed for some reason */
05211          if (*reason == 0) { /* if the call failed (not busy or no answer)
05212                         * update the cdr with the failed message */
05213             cdr_res = ast_pbx_outgoing_cdr_failed();
05214             if (cdr_res != 0) {
05215                res = cdr_res;
05216                goto outgoing_exten_cleanup;
05217             }
05218          }
05219 
05220          /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */
05221          /* check if "failed" exists */
05222          if (ast_exists_extension(chan, context, "failed", 1, NULL)) {
05223             chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed");
05224             if (chan) {
05225                char failed_reason[4] = "";
05226                if (!ast_strlen_zero(context))
05227                   ast_copy_string(chan->context, context, sizeof(chan->context));
05228                set_ext_pri(chan, "failed", 1);
05229                ast_set_variables(chan, vars);
05230                snprintf(failed_reason, sizeof(failed_reason), "%d", *reason);
05231                pbx_builtin_setvar_helper(chan, "REASON", failed_reason);
05232                if (account)
05233                   ast_cdr_setaccount(chan, account);
05234                if (ast_pbx_run(chan)) {
05235                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
05236                   ast_hangup(chan);
05237                }
05238                chan = NULL;
05239             }
05240          }
05241       }
05242    } else {
05243       if (!(as = ast_calloc(1, sizeof(*as)))) {
05244          res = -1;
05245          goto outgoing_exten_cleanup;
05246       }
05247       chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
05248       if (channel) {
05249          *channel = chan;
05250          if (chan)
05251             ast_channel_lock(chan);
05252       }
05253       if (!chan) {
05254          free(as);
05255          res = -1;
05256          goto outgoing_exten_cleanup;
05257       }
05258       as->chan = chan;
05259       ast_copy_string(as->context, context, sizeof(as->context));
05260       set_ext_pri(as->chan,  exten, priority);
05261       as->timeout = timeout;
05262       ast_set_variables(chan, vars);
05263       if (account)
05264          ast_cdr_setaccount(chan, account);
05265       pthread_attr_init(&attr);
05266       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05267       if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
05268          ast_log(LOG_WARNING, "Failed to start async wait\n");
05269          free(as);
05270          if (channel) {
05271             *channel = NULL;
05272             ast_channel_unlock(chan);
05273          }
05274          ast_hangup(chan);
05275          res = -1;
05276          pthread_attr_destroy(&attr);
05277          goto outgoing_exten_cleanup;
05278       }
05279       pthread_attr_destroy(&attr);
05280       res = 0;
05281    }
05282 outgoing_exten_cleanup:
05283    ast_variables_destroy(vars);
05284    return res;
05285 }

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 2751 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(), do_idle_thread(), mgcp_ss(), skinny_newcall(), and ss_thread().

02752 {
02753    enum ast_pbx_result res = AST_PBX_SUCCESS;
02754 
02755    if (increase_call_count(c))
02756       return AST_PBX_CALL_LIMIT;
02757 
02758    res = __ast_pbx_run(c);
02759    decrease_call_count();
02760 
02761    return res;
02762 }

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

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

Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_exten(), check_goto_on_transfer(), dahdi_new(), do_parking_thread(), gtalk_new(), gtalk_newcall(), handle_request_invite(), local_call(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), and skinny_new().

02725 {
02726    pthread_t t;
02727    pthread_attr_t attr;
02728 
02729    if (!c) {
02730       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
02731       return AST_PBX_FAILED;
02732    }
02733 
02734    if (increase_call_count(c))
02735       return AST_PBX_CALL_LIMIT;
02736 
02737    /* Start a new thread, and get something handling this channel. */
02738    pthread_attr_init(&attr);
02739    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
02740    if (ast_pthread_create(&t, &attr, pbx_thread, c)) {
02741       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
02742       pthread_attr_destroy(&attr);
02743       decrease_call_count();
02744       return AST_PBX_FAILED;
02745    }
02746    pthread_attr_destroy(&attr);
02747 
02748    return AST_PBX_SUCCESS;
02749 }

int ast_processed_calls ( void   ) 

Retrieve the total number of calls processed through the PBX since last restart.

Definition at line 2769 of file pbx.c.

02770 {
02771    return totalcalls;
02772 }

int ast_rdlock_contexts ( void   ) 

Definition at line 6420 of file pbx.c.

References ast_mutex_lock(), and conlock.

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

06421 {
06422    return ast_mutex_lock(&conlock);
06423 }

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

References ast_calloc, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), COLOR_BRCYAN, ast_app::description, ast_app::execute, ast_app::list, LOG_WARNING, ast_app::name, option_verbose, ast_app::synopsis, term_color(), and VERBOSE_PREFIX_2.

Referenced by load_module(), and load_pbx().

03059 {
03060    struct ast_app *tmp, *cur = NULL;
03061    char tmps[80];
03062    int length;
03063 
03064    AST_LIST_LOCK(&apps);
03065    AST_LIST_TRAVERSE(&apps, tmp, list) {
03066       if (!strcasecmp(app, tmp->name)) {
03067          ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
03068          AST_LIST_UNLOCK(&apps);
03069          return -1;
03070       }
03071    }
03072 
03073    length = sizeof(*tmp) + strlen(app) + 1;
03074 
03075    if (!(tmp = ast_calloc(1, length))) {
03076       AST_LIST_UNLOCK(&apps);
03077       return -1;
03078    }
03079 
03080    strcpy(tmp->name, app);
03081    tmp->execute = execute;
03082    tmp->synopsis = synopsis;
03083    tmp->description = description;
03084 
03085    /* Store in alphabetical order */
03086    AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) {
03087       if (strcasecmp(tmp->name, cur->name) < 0) {
03088          AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list);
03089          break;
03090       }
03091    }
03092    AST_LIST_TRAVERSE_SAFE_END
03093    if (!cur)
03094       AST_LIST_INSERT_TAIL(&apps, tmp, list);
03095 
03096    if (option_verbose > 1)
03097       ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
03098 
03099    AST_LIST_UNLOCK(&apps);
03100 
03101    return 0;
03102 }

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

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

Referenced by load_module().

03109 {
03110    struct ast_switch *tmp;
03111 
03112    AST_LIST_LOCK(&switches);
03113    AST_LIST_TRAVERSE(&switches, tmp, list) {
03114       if (!strcasecmp(tmp->name, sw->name)) {
03115          AST_LIST_UNLOCK(&switches);
03116          ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
03117          return -1;
03118       }
03119    }
03120    AST_LIST_INSERT_TAIL(&switches, sw, list);
03121    AST_LIST_UNLOCK(&switches);
03122 
03123    return 0;
03124 }

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

Launch a new extension (i.e. new stack).

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

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

Definition at line 2391 of file pbx.c.

References E_SPAWN, and pbx_extension_helper().

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

02392 {
02393    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN);
02394 }

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

06444 {
06445    return ast_mutex_unlock(&con->lock);
06446 }

int ast_unlock_contexts ( void   ) 

Unlocks contexts.

Return values:
0 on success
-1 on failure

Definition at line 6430 of file pbx.c.

References ast_mutex_unlock(), and conlock.

Referenced by __ast_context_create(), _macro_exec(), ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_destroy(), ast_context_find(), ast_context_lockmacro(), ast_context_remove_extension_callerid(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_unlockmacro(), ast_hint_extension(), ast_hint_state_changed(), ast_merge_contexts_and_delete(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_save_dialplan(), pbx_extension_helper(), and show_dialplan_helper().

06431 {
06432    return ast_mutex_unlock(&conlock);
06433 }

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

References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), free, ast_app::list, ast_app::name, option_verbose, and VERBOSE_PREFIX_2.

Referenced by __unload_module(), and unload_module().

03979 {
03980    struct ast_app *tmp;
03981 
03982    AST_LIST_LOCK(&apps);
03983    AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) {
03984       if (!strcasecmp(app, tmp->name)) {
03985          AST_LIST_REMOVE_CURRENT(&apps, list);
03986          if (option_verbose > 1)
03987             ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
03988          free(tmp);
03989          break;
03990       }
03991    }
03992    AST_LIST_TRAVERSE_SAFE_END
03993    AST_LIST_UNLOCK(&apps);
03994 
03995    return tmp ? 0 : -1;
03996 }

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

References AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, and ast_switch::list.

Referenced by __unload_module(), and unload_module().

03127 {
03128    AST_LIST_LOCK(&switches);
03129    AST_LIST_REMOVE(&switches, sw, list);
03130    AST_LIST_UNLOCK(&switches);
03131 }

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

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

06554 {
06555    if (!exten)
06556       return con ? con->root : NULL;
06557    else
06558       return exten->next;
06559 }

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

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

06587 {
06588    if (!ip)
06589       return con ? con->ignorepats : NULL;
06590    else
06591       return ip->next;
06592 }

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

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

06578 {
06579    if (!inc)
06580       return con ? con->includes : NULL;
06581    else
06582       return inc->next;
06583 }

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

Definition at line 6561 of file pbx.c.

References ast_context::alts, AST_LIST_FIRST, AST_LIST_NEXT, and ast_sw::list.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06563 {
06564    if (!sw)
06565       return con ? AST_LIST_FIRST(&con->alts) : NULL;
06566    else
06567       return AST_LIST_NEXT(sw, list);
06568 }

struct ast_context* ast_walk_contexts ( struct ast_context con  ) 

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

06548 {
06549    return con ? con->next : contexts;
06550 }

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

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

06572 {
06573    return priority ? priority->peer : exten;
06574 }

int ast_wrlock_contexts ( void   ) 

Definition at line 6425 of file pbx.c.

References ast_mutex_lock(), and conlock.

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

06426 {
06427    return ast_mutex_lock(&conlock);
06428 }

void pbx_builtin_clear_globals ( void   ) 

Definition at line 6191 of file pbx.c.

References AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), ast_var_delete(), ast_var_t::entries, globals, and globalslock.

Referenced by handle_reload_extensions(), and reload().

06192 {
06193    struct ast_var_t *vardata;
06194 
06195    ast_mutex_lock(&globalslock);
06196    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
06197       ast_var_delete(vardata);
06198    ast_mutex_unlock(&globalslock);
06199 }

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

Note:
Will lock the channel.

Definition at line 5967 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), globals, and globalslock.

Referenced by __login_exec(), _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), ast_bridge_call(), ast_call_forward(), ast_monitor_stop(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dahdi_call(), dahdi_hangup(), dahdi_r2_answer(), dahdi_r2_get_channel_category(), dundi_exec(), dundi_helper(), feature_check(), feature_interpret(), get_also_info(), get_index(), get_refer_info(), global_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), macro_fixup(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_call_full(), park_space_reserve(), pbx_builtin_background(), pickup_by_mark(), queue_exec(), real_ctx(), retrydial_exec(), return_exec(), ring_entry(), run_agi(), set_config_flags(), sip_addheader(), sla_trunk_exec(), speech_background(), try_suggested_sip_codec(), update_bridgepeer(), and wait_for_answer().

05968 {
05969    struct ast_var_t *variables;
05970    const char *ret = NULL;
05971    int i;
05972    struct varshead *places[2] = { NULL, &globals };
05973 
05974    if (!name)
05975       return NULL;
05976 
05977    if (chan) {
05978       ast_channel_lock(chan);
05979       places[0] = &chan->varshead;
05980    }
05981 
05982    for (i = 0; i < 2; i++) {
05983       if (!places[i])
05984          continue;
05985       if (places[i] == &globals)
05986          ast_mutex_lock(&globalslock);
05987       AST_LIST_TRAVERSE(places[i], variables, entries) {
05988          if (!strcmp(name, ast_var_name(variables))) {
05989             ret = ast_var_value(variables);
05990             break;
05991          }
05992       }
05993       if (places[i] == &globals)
05994          ast_mutex_unlock(&globalslock);
05995       if (ret)
05996          break;
05997    }
05998 
05999    if (chan)
06000       ast_channel_unlock(chan);
06001 
06002    return ret;
06003 }

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

Note:
Will lock the channel.

Definition at line 6005 of file pbx.c.

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

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

06006 {
06007    struct ast_var_t *newvariable;
06008    struct varshead *headp;
06009 
06010    if (name[strlen(name)-1] == ')') {
06011       char *function = ast_strdupa(name);
06012 
06013       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
06014       ast_func_write(chan, function, value);
06015       return;
06016    }
06017 
06018    if (chan) {
06019       ast_channel_lock(chan);
06020       headp = &chan->varshead;
06021    } else {
06022       ast_mutex_lock(&globalslock);
06023       headp = &globals;
06024    }
06025 
06026    if (value) {
06027       if ((option_verbose > 1) && (headp == &globals))
06028          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
06029       newvariable = ast_var_assign(name, value);
06030       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
06031    }
06032 
06033    if (chan)
06034       ast_channel_unlock(chan);
06035    else
06036       ast_mutex_unlock(&globalslock);
06037 }

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

Note:
Will lock the channel.

Definition at line 5936 of file pbx.c.

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

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

05937 {
05938    struct ast_var_t *variables;
05939    const char *var, *val;
05940    int total = 0;
05941 
05942    if (!chan)
05943       return 0;
05944 
05945    memset(buf, 0, size);
05946 
05947    ast_channel_lock(chan);
05948 
05949    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
05950       if ((var=ast_var_name(variables)) && (val=ast_var_value(variables))
05951          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
05952          ) {
05953          if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) {
05954             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
05955             break;
05956          } else
05957             total++;
05958       } else
05959          break;
05960    }
05961 
05962    ast_channel_unlock(chan);
05963 
05964    return total;
05965 }

int pbx_builtin_setvar ( struct ast_channel chan,
void *  data 
)

Note:
Will lock the channel.

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

Note:
Will lock the channel.

Definition at line 6039 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verbose(), globals, globalslock, option_verbose, 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(), aqm_exec(), array(), ast_bridge_call(), ast_iax2_new(), ast_monitor_start(), ast_monitor_stop(), ast_pbx_outgoing_exten(), ast_set_variables(), background_detect_exec(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), controlplayback_exec(), count_exec(), dahdi_handle_dtmf(), dahdi_new(), disa_exec(), do_waiting(), end_bridge_callback(), export_aoc_vars(), export_ch(), feature_request_and_dial(), 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(), macro_fixup(), misdn_call(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_call_full(), park_exec(), parse_moved_contact(), pbx_builtin_importvar(), pbx_builtin_saydate(), pbx_builtin_saytime(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_load_config(), play_message_datetime(), playback_exec(), pop_exec(), pqm_exec(), prep_email_sub_vars(), privacy_exec(), process_ast_dsp(), read_exec(), readfile_exec(), realtime_exec(), realtime_update_exec(), record_exec(), return_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_hangup(), sip_new(), sla_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), ss_thread(), start_monitor_exec(), system_exec_helper(), transfer_exec(), tryexec_exec(), update_bridgepeer(), upqm_exec(), vm_box_exists(), vm_exec(), and vmauthenticate().

06040 {
06041    struct ast_var_t *newvariable;
06042    struct varshead *headp;
06043    const char *nametail = name;
06044 
06045    if (name[strlen(name)-1] == ')') {
06046       char *function = ast_strdupa(name);
06047 
06048       ast_func_write(chan, function, value);
06049       return;
06050    }
06051 
06052    if (chan) {
06053       ast_channel_lock(chan);
06054       headp = &chan->varshead;
06055    } else {
06056       ast_mutex_lock(&globalslock);
06057       headp = &globals;
06058    }
06059 
06060    /* For comparison purposes, we have to strip leading underscores */
06061    if (*nametail == '_') {
06062       nametail++;
06063       if (*nametail == '_')
06064          nametail++;
06065    }
06066 
06067    AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) {
06068       if (strcmp(ast_var_name(newvariable), nametail) == 0) {
06069          /* there is already such a variable, delete it */
06070          AST_LIST_REMOVE_CURRENT(headp, entries);
06071          ast_var_delete(newvariable);
06072          break;
06073       }
06074    }
06075    AST_LIST_TRAVERSE_SAFE_END;
06076 
06077    if (value) {
06078       if ((option_verbose > 1) && (headp == &globals))
06079          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
06080       newvariable = ast_var_assign(name, value);
06081       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
06082    }
06083 
06084    if (chan)
06085       ast_channel_unlock(chan);
06086    else
06087       ast_mutex_unlock(&globalslock);
06088 }

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

06202 {
06203    if (ast_strlen_zero(condition))  /* NULL or empty strings are false */
06204       return 0;
06205    else if (*condition >= '0' && *condition <= '9')   /* Numbers are evaluated for truth */
06206       return atoi(condition);
06207    else  /* Strings are true */
06208       return 1;
06209 }

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

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

Referenced by aelsub_exec(), 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(), and tryexec_exec().

00554 {
00555    int res;
00556 
00557    const char *saved_c_appl;
00558    const char *saved_c_data;
00559 
00560    if (c->cdr && !ast_check_hangup(c))
00561       ast_cdr_setapp(c->cdr, app->name, data);
00562 
00563    /* save channel values */
00564    saved_c_appl= c->appl;
00565    saved_c_data= c->data;
00566 
00567    c->appl = app->name;
00568    c->data = data;
00569    /* XXX remember what to to when we have linked apps to modules */
00570    if (app->module) {
00571       /* XXX LOCAL_USER_ADD(app->module) */
00572    }
00573    res = app->execute(c, S_OR(data, ""));
00574    if (app->module) {
00575       /* XXX LOCAL_USER_REMOVE(app->module) */
00576    }
00577    /* restore channel values */
00578    c->appl = saved_c_appl;
00579    c->data = saved_c_data;
00580    return res;
00581 }

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

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sw::list, and ast_app::name.

Referenced by aelsub_exec(), 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(), and tryexec_exec().

00590 {
00591    struct ast_app *tmp;
00592 
00593    AST_LIST_LOCK(&apps);
00594    AST_LIST_TRAVERSE(&apps, tmp, list) {
00595       if (!strcasecmp(tmp->name, app))
00596          break;
00597    }
00598    AST_LIST_UNLOCK(&apps);
00599 
00600    return tmp;
00601 }

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

pbx_retrieve_variable: Support for Asterisk built-in variables ---

Note:
Will lock the channel.

Definition at line 1204 of file pbx.c.

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

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

01205 {
01206    const char not_found = '\0';
01207    char *tmpvar;
01208    const char *s; /* the result */
01209    int offset, length;
01210    int i, need_substring;
01211    struct varshead *places[2] = { headp, &globals };  /* list of places where we may look */
01212 
01213    if (c) {
01214       ast_channel_lock(c);
01215       places[0] = &c->varshead;
01216    }
01217    /*
01218     * Make a copy of var because parse_variable_name() modifies the string.
01219     * Then if called directly, we might need to run substring() on the result;
01220     * remember this for later in 'need_substring', 'offset' and 'length'
01221     */
01222    tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */
01223    need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
01224 
01225    /*
01226     * Look first into predefined variables, then into variable lists.
01227     * Variable 's' points to the result, according to the following rules:
01228     * s == &not_found (set at the beginning) means that we did not find a
01229     * matching variable and need to look into more places.
01230     * If s != &not_found, s is a valid result string as follows:
01231     * s = NULL if the variable does not have a value;
01232     * you typically do this when looking for an unset predefined variable.
01233     * s = workspace if the result has been assembled there;
01234     * typically done when the result is built e.g. with an snprintf(),
01235     * so we don't need to do an additional copy.
01236     * s != workspace in case we have a string, that needs to be copied
01237     * (the ast_copy_string is done once for all at the end).
01238     * Typically done when the result is already available in some string.
01239     */
01240    s = &not_found;   /* default value */
01241    if (c) { /* This group requires a valid channel */
01242       /* Names with common parts are looked up a piece at a time using strncmp. */
01243       if (!strncmp(var, "CALL", 4)) {
01244          if (!strncmp(var + 4, "ING", 3)) {
01245             if (!strcmp(var + 7, "PRES")) {        /* CALLINGPRES */
01246                snprintf(workspace, workspacelen, "%d", c->cid.cid_pres);
01247                s = workspace;
01248             } else if (!strcmp(var + 7, "ANI2")) {    /* CALLINGANI2 */
01249                snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2);
01250                s = workspace;
01251             } else if (!strcmp(var + 7, "TON")) {     /* CALLINGTON */
01252                snprintf(workspace, workspacelen, "%d", c->cid.cid_ton);
01253                s = workspace;
01254             } else if (!strcmp(var + 7, "TNS")) {     /* CALLINGTNS */
01255                snprintf(workspace, workspacelen, "%d", c->cid.cid_tns);
01256                s = workspace;
01257             }
01258          }
01259       } else if (!strcmp(var, "HINT")) {
01260          s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL;
01261       } else if (!strcmp(var, "HINTNAME")) {
01262          s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL;
01263       } else if (!strcmp(var, "EXTEN")) {
01264          s = c->exten;
01265       } else if (!strcmp(var, "CONTEXT")) {
01266          s = c->context;
01267       } else if (!strcmp(var, "PRIORITY")) {
01268          snprintf(workspace, workspacelen, "%d", c->priority);
01269          s = workspace;
01270       } else if (!strcmp(var, "CHANNEL")) {
01271          s = c->name;
01272       } else if (!strcmp(var, "UNIQUEID")) {
01273          s = c->uniqueid;
01274       } else if (!strcmp(var, "HANGUPCAUSE")) {
01275          snprintf(workspace, workspacelen, "%d", c->hangupcause);
01276          s = workspace;
01277       } else if (c && !strcmp(var, "HANGUPCAUSESTR")) {
01278          ast_copy_string(workspace, ast_cause2str(c->hangupcause), workspacelen);
01279          *ret = workspace;
01280       }
01281    }
01282    if (s == &not_found) { /* look for more */
01283       if (!strcmp(var, "EPOCH")) {
01284          snprintf(workspace, workspacelen, "%u",(int)time(NULL));
01285          s = workspace;
01286       } else if (!strcmp(var, "SYSTEMNAME")) {
01287          s = ast_config_AST_SYSTEM_NAME;
01288       }
01289    }
01290    /* if not found, look into chanvars or global vars */
01291    for (i = 0; s == &not_found && i < (sizeof(places) / sizeof(places[0])); i++) {
01292       struct ast_var_t *variables;
01293       if (!places[i])
01294          continue;
01295       if (places[i] == &globals)
01296          ast_mutex_lock(&globalslock);
01297       AST_LIST_TRAVERSE(places[i], variables, entries) {
01298          if (strcasecmp(ast_var_name(variables), var)==0) {
01299             s = ast_var_value(variables);
01300             break;
01301          }
01302       }
01303       if (places[i] == &globals)
01304          ast_mutex_unlock(&globalslock);
01305    }
01306    if (s == &not_found || s == NULL)
01307       *ret = NULL;
01308    else {
01309       if (s != workspace)
01310          ast_copy_string(workspace, s, workspacelen);
01311       *ret = workspace;
01312       if (need_substring)
01313          *ret = substring(*ret, offset, length, workspace, workspacelen);
01314    }
01315 
01316    if (c)
01317       ast_channel_unlock(c);
01318 }

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

Referenced by pbx_load_module().

02775 {
02776    int oldval = autofallthrough;
02777    autofallthrough = newval;
02778    return oldval;
02779 }

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

Definition at line 1824 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(), function_fieldqty(), handle_getvariablefull(), launch_monitor_thread(), make_email_file(), pbx_builtin_importvar(), pbx_load_config(), pbx_substitute_variables(), realtime_exec(), rpt_do_lstats(), sendpage(), and tryexec_exec().

01825 {
01826    pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
01827 }

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

Definition at line 1829 of file pbx.c.

References pbx_substitute_variables_helper_full().

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

01830 {
01831    pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
01832 }


Generated on Sat Aug 6 00:40:01 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7