Mon May 14 04:52:00 2007

Asterisk developer's documentation


pbx.h File Reference

Core PBX routines and definitions. More...

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

Include dependency graph for pbx.h:

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

Go to the source code of this file.

Data Structures

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

Defines

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

Typedefs

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

Enumerations

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

Functions

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

const char * ast_get_context_name (struct ast_context *con)
ast_contextast_get_extension_context (struct ast_exten *exten)
const char * ast_get_extension_name (struct ast_exten *exten)
const char * ast_get_ignorepat_name (struct ast_ignorepat *ip)
const char * ast_get_include_name (struct ast_include *include)
const char * ast_get_switch_data (struct ast_sw *sw)
const char * ast_get_switch_name (struct ast_sw *sw)
Registrar info functions ...
const char * ast_get_context_registrar (struct ast_context *c)
const char * ast_get_extension_registrar (struct ast_exten *e)
const char * ast_get_ignorepat_registrar (struct ast_ignorepat *ip)
const char * ast_get_include_registrar (struct ast_include *i)
const char * ast_get_switch_registrar (struct ast_sw *sw)
Other Extension stuff
const char * ast_get_extension_app (struct ast_exten *e)
void * ast_get_extension_app_data (struct ast_exten *e)
const char * ast_get_extension_cidmatch (struct ast_exten *e)
const char * ast_get_extension_label (struct ast_exten *e)
int ast_get_extension_matchcid (struct ast_exten *e)
int ast_get_extension_priority (struct ast_exten *exten)


Detailed Description

Core PBX routines and definitions.

Definition in file pbx.h.


Define Documentation

#define AST_MAX_APP   32

Max length of an application

Definition at line 34 of file pbx.h.

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

#define AST_PBX_KEEP   0

Definition at line 36 of file pbx.h.

#define AST_PBX_KEEPALIVE   10

Special return values from applications to the PBX {.

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

Definition at line 40 of file pbx.h.

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

#define AST_PBX_NO_HANGUP_PEER   11

Definition at line 41 of file pbx.h.

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

#define AST_PBX_REPLACE   1

Definition at line 37 of file pbx.h.

#define PRIORITY_HINT   -1

} Special Priority for a hint

Definition at line 44 of file pbx.h.

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


Typedef Documentation

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

Typedef for devicestate and hint callbacks.

Definition at line 69 of file pbx.h.

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

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

Data structure associated with an Asterisk switch

Definition at line 83 of file pbx.h.


Enumeration Type Documentation

enum ast_extension_states

Extension states.

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

Definition at line 50 of file pbx.h.

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

enum ast_pbx_result

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

AST_PBX_CALL_LIMIT refers to the maxcalls call limit in asterisk.conf

Enumerator:
AST_PBX_SUCCESS 
AST_PBX_FAILED 
AST_PBX_CALL_LIMIT 

Definition at line 236 of file pbx.h.

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


Function Documentation

int ast_active_calls ( void   ) 

Retrieve the number of active calls.

Definition at line 2654 of file pbx.c.

References countcalls.

Referenced by handle_chanlist(), and handle_chanlist_deprecated().

02655 {
02656    return countcalls;
02657 }

int ast_add_extension ( const char *  context,
int  replace,
const char *  extension,
int  priority,
const char *  label,
const char *  callerid,
const char *  application,
void *  data,
void(*)(void *)  datad,
const char *  registrar 
)

Add and extension to an extension context.

Parameters:
context context to add the extension to
replace 
extension extension to add
priority priority level of extension addition
label extension label
callerid pattern to match CallerID, or NULL to match any CallerID
application application to run on the extension with that priority level
data data to pass to the application
datad 
registrar who registered the extension
Return values:
0 success
-1 failure

Definition at line 4534 of file pbx.c.

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

Referenced by handle_context_add_extension(), handle_context_add_extension_deprecated(), park_add_hints(), and register_peer_exten().

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

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

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

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

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

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

Definition at line 4738 of file pbx.c.

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

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

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

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

Definition at line 4568 of file pbx.c.

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

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

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

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

Definition at line 4614 of file pbx.c.

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

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

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

Definition at line 6293 of file pbx.c.

References __ast_goto_if_exists().

Referenced by asyncgoto_exec().

06294 {
06295    return __ast_goto_if_exists(chan, context, exten, priority, 1);
06296 }

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

Definition at line 4210 of file pbx.c.

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

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

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

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

Looks for a valid matching extension.

Parameters:
c not really important
context context to serach within
exten extension to check
priority priority of extension path
callerid callerid of extension being searched for
Returns:
If "exten" *could be* a valid extension in this context with or without some more digits, return non-zero. Basically, when this returns 0, no matter what you add to exten, it's not going to be a valid extension anymore

Definition at line 2282 of file pbx.c.

References E_CANMATCH, and pbx_extension_helper().

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

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

int ast_check_timing ( const struct ast_timing i  ) 

Definition at line 4236 of file pbx.c.

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

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

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

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

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

Definition at line 4482 of file pbx.c.

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

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

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

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

Add a context include.

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

Return values:
0 on success
-1 on error

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

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

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

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

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

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

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

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

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

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

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

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

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

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

References __ast_context_create().

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

03888 {
03889    return __ast_context_create(extcontexts, name, registrar, 0);
03890 }

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

References __ast_context_destroy().

Referenced by cleanup_stale_contexts(), and unload_module().

05339 {
05340    __ast_context_destroy(con,registrar);
05341 }

struct ast_context* ast_context_find ( const char *  name  ) 

Find a context.

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

Returns:
the ast_context on success, NULL on failure.

Definition at line 892 of file pbx.c.

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

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

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

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

Register a new context or find an existing one.

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

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

Definition at line 3892 of file pbx.c.

References __ast_context_create().

Referenced by pbx_load_config(), and pbx_load_users().

03893 {
03894    return __ast_context_create(extcontexts, name, registrar, 1);
03895 }

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

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

Referenced by _macro_exec().

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

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

Simply remove extension from context.

Parameters:
context context to remove extension from
extension which extension to remove
priority priority of extension to remove
registrar registrar of the extension
This function removes an extension from a given context.

Return values:
0 on success
-1 on failure

Definition at line 2792 of file pbx.c.

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

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

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

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

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

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

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

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

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

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

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

Definition at line 4439 of file pbx.c.

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

Referenced by ast_context_remove_ignorepat().

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

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

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

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

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

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

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

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

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

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

Referenced by ast_context_remove_switch().

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

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

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

Referenced by _macro_exec().

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

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

06255 {
06256    struct ast_include *inc = NULL;
06257    int res = 0;
06258 
06259    while ( (inc = ast_walk_context_includes(con, inc)) )
06260       if (!ast_context_find(inc->rname)) {
06261          res = -1;
06262          ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n",
06263                ast_get_context_name(con), inc->rname);
06264       }
06265    return res;
06266 }

struct ast_custom_function* ast_custom_function_find ( const char *  name  ) 

Definition at line 1433 of file pbx.c.

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

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

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

int ast_custom_function_register ( struct ast_custom_function acf  ) 

Reigster a custom function.

Definition at line 1469 of file pbx.c.

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

Referenced by load_module(), and reload().

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

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

Definition at line 1447 of file pbx.c.

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

Referenced by reload(), and unload_module().

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

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

Determine whether an extension exists.

Parameters:
c this is not important
context which context to look in
exten which extension to search for
priority priority of the action within the extension
callerid callerid to search for
Returns:
If an extension within the given context(or callerid) with the given priority is found a non zero value will be returned. Otherwise, 0 is returned.

Definition at line 2267 of file pbx.c.

References E_MATCH, and pbx_extension_helper().

Referenced by __ast_goto_if_exists(), __ast_pbx_run(), __login_exec(), _macro_exec(), agentmonitoroutgoing_exec(), answer_call(), ast_app_dtget(), ast_park_call(), ast_pbx_outgoing_exten(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), disa_exec(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), handle_stimulus_message(), leave_voicemail(), local_alloc(), local_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), misdn_overlap_dial_task(), nv_background_detect_exec(), nv_detectfax_exec(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), process_ast_dsp(), register_peer_exten(), rpt_exec(), skinny_ss(), socket_process(), ss_thread(), waitstream_core(), and zt_handle_dtmfup().

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

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

Definition at line 4549 of file pbx.c.

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

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

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

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

Definition at line 885 of file pbx.c.

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

Referenced by realtime_switch_common().

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

int ast_extension_match ( const char *  pattern,
const char *  extension 
)

Determine if a given extension matches a given pattern (in NXX format).

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

Return values:
1 on match
0 on failure

Definition at line 880 of file pbx.c.

References E_MATCH, and extension_match_core().

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

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

int ast_extension_patmatch ( const char *  pattern,
const char *  data 
)

int ast_extension_state ( struct ast_channel c,
const char *  context,
const char *  exten 
)

Uses hint and devicestate callback to get the state of an extension.

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

Definition at line 1991 of file pbx.c.

References ast_extension_state2(), and ast_hint_extension().

Referenced by action_extensionstate(), and handle_request_subscribe().

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

const char* ast_extension_state2str ( int  extension_state  ) 

Return string representation of the state of an extension.

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

Definition at line 1979 of file pbx.c.

References extension_states.

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

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

int ast_extension_state_add ( const char *  context,
const char *  exten,
ast_state_cb_type  callback,
void *  data 
)

Registers a state change callback.

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

Return values:
-1 on failure
ID on success

Definition at line 2046 of file pbx.c.

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

Referenced by handle_request_subscribe(), and init_manager().

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

int ast_extension_state_del ( int  id,
ast_state_cb_type  callback 
)

Deletes a registered state change callback by ID.

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

Return values:
0 success
-1 failure

Definition at line 2121 of file pbx.c.

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

Referenced by __sip_destroy().

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

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

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

Parameters:
c this is not important
context which context to look in
exten which extension to search for
label label of the action within the extension to match to priority
callerid callerid to search for
Returns:
the priority which matches the given label in the extension or -1 if not found.

Definition at line 2272 of file pbx.c.

References E_FINDLABEL, and pbx_extension_helper().

Referenced by action_originate(), action_redirect(), ast_parseable_goto(), asyncgoto_exec(), and handle_setpriority().

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

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

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

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

Definition at line 2277 of file pbx.c.

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

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

int ast_func_read ( struct ast_channel chan,
char *  function,
char *  workspace,
size_t  len 
)

executes a read operation on a function

Parameters:
chan Channel to execute on
function Data containing the function call string (will be modified)
workspace A pointer to safe memory to use for a return value
len the number of bytes in workspace
This application executes a function in read mode on a given channel.

Returns:
zero on success, non-zero on failure

Definition at line 1523 of file pbx.c.

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

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

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

int ast_func_write ( struct ast_channel chan,
char *  function,
const char *  value 
)

executes a write operation on a function

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

Returns:
zero on success, non-zero on failure

Definition at line 1537 of file pbx.c.

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

Referenced by pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().

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

const char* ast_get_context_name ( struct ast_context con  ) 

Definition at line 6111 of file pbx.c.

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

06112 {
06113    return con ? con->name : NULL;
06114 }

const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 6149 of file pbx.c.

References ast_context::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06150 {
06151    return c ? c->registrar : NULL;
06152 }

const char* ast_get_extension_app ( struct ast_exten e  ) 

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

06180 {
06181    return e ? e->app : NULL;
06182 }

void* ast_get_extension_app_data ( struct ast_exten e  ) 

Definition at line 6184 of file pbx.c.

References ast_exten::data.

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

06185 {
06186    return e ? e->data : NULL;
06187 }

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 6174 of file pbx.c.

References ast_exten::cidmatch.

Referenced by find_matching_priority(), and handle_save_dialplan().

06175 {
06176    return e ? e->cidmatch : NULL;
06177 }

struct ast_context* ast_get_extension_context ( struct ast_exten exten  ) 

Definition at line 6116 of file pbx.c.

References exten.

Referenced by handle_show_hints().

06117 {
06118    return exten ? exten->parent : NULL;
06119 }

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 6126 of file pbx.c.

References exten.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06127 {
06128    return exten ? exten->label : NULL;
06129 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 6169 of file pbx.c.

References ast_exten::matchcid.

Referenced by find_matching_priority(), and handle_save_dialplan().

06170 {
06171    return e ? e->matchcid : 0;
06172 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 

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

06122 {
06123    return exten ? exten->exten : NULL;
06124 }

int ast_get_extension_priority ( struct ast_exten exten  ) 

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

06142 {
06143    return exten ? exten->priority : -1;
06144 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 6154 of file pbx.c.

References ast_exten::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06155 {
06156    return e ? e->registrar : NULL;
06157 }

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

If an extension hint exists, return non-zero.

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

Definition at line 2250 of file pbx.c.

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

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

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

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 

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

06137 {
06138    return ip ? ip->pattern : NULL;
06139 }

const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

Definition at line 6164 of file pbx.c.

References ast_ignorepat::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06165 {
06166    return ip ? ip->registrar : NULL;
06167 }

const char* ast_get_include_name ( struct ast_include include  ) 

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

06132 {
06133    return inc ? inc->name : NULL;
06134 }

const char* ast_get_include_registrar ( struct ast_include i  ) 

Definition at line 6159 of file pbx.c.

References ast_include::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06160 {
06161    return i ? i->registrar : NULL;
06162 }

const char* ast_get_switch_data ( struct ast_sw sw  ) 

Definition at line 6194 of file pbx.c.

References ast_sw::data.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06195 {
06196    return sw ? sw->data : NULL;
06197 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

Definition at line 6189 of file pbx.c.

References ast_sw::name.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06190 {
06191    return sw ? sw->name : NULL;
06192 }

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

Definition at line 6199 of file pbx.c.

References ast_sw::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06200 {
06201    return sw ? sw->registrar : NULL;
06202 }

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

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

06289 {
06290    return __ast_goto_if_exists(chan, context, exten, priority, 0);
06291 }

void ast_hint_state_changed ( const char *  device  ) 

Definition at line 2002 of file pbx.c.

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

Referenced by do_state_change().

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

int ast_ignore_pattern ( const char *  context,
const char *  pattern 
)

Checks to see if a number should be ignored.

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

Return values:
0 if the pattern should not be ignored
non-zero if the pattern should be ignored

Definition at line 4515 of file pbx.c.

References ast_context_find(), ast_extension_match(), ast_context::ignorepats, ast_ignorepat::next, and ast_ignorepat::pattern.

Referenced by ast_app_dtget(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_soft_key_event_message(), handle_stimulus_message(), mgcp_ss(), skinny_ss(), and ss_thread().

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

int ast_lock_context ( struct ast_context con  ) 

Locks a given context.

Parameters:
con context to lock
Return values:
0 on success
-1 on failure

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

06099 {
06100    return ast_mutex_lock(&con->lock);
06101 }

int ast_lock_contexts ( void   ) 

Locks the context list.

Return values:
0 on success
-1 on error

Definition at line 6085 of file pbx.c.

References ast_mutex_lock().

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

06086 {
06087    return ast_mutex_lock(&conlock);
06088 }

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

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

Parameters:
c not really important XXX
context context to serach within
exten extension to check
priority priority of extension path
callerid callerid of extension being searched for
Returns:
If "exten" *could match* a valid extension in this context with some more digits, return non-zero. Does NOT return non-zero if this is an exact-match only. Basically, when this returns 0, no matter what you add to exten, it's not going to be a valid extension anymore

Definition at line 2287 of file pbx.c.

References E_MATCHMORE, and pbx_extension_helper().

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

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

void ast_merge_contexts_and_delete ( struct ast_context **  extcontexts,
const char *  registrar 
)

Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added.

Parameters:
extcontexts pointer to the ast_context structure pointer
registrar of the context; if it's set the routine will delete all contexts that belong to that registrar; if NULL only the contexts that are specified in extcontexts

Definition at line 3910 of file pbx.c.

References __ast_context_destroy(), ast_calloc, AST_EXTENSION_REMOVED, ast_hint_extension(), AST_LIST_HEAD_INIT_VALUE, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, store_hint::callbacks, ast_hint::callbacks, store_hint::context, contexts, ast_state_cb::data, ast_exten::exten, ast_hint::exten, store_hint::exten, free, ast_hint::laststate, store_hint::laststate, LOG_WARNING, ast_state_cb::next, ast_context::next, ast_exten::parent, and ast_context::registrar.

Referenced by pbx_load_module().

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

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

Definition at line 6298 of file pbx.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Referenced by load_module(), and load_pbx().

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

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

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

Referenced by load_module().

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

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

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

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

Return values:
0 on success
-1 on failure.

Definition at line 2292 of file pbx.c.

References E_SPAWN, and pbx_extension_helper().

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

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

int ast_unlock_context ( struct ast_context con  ) 

Return values:
Unlocks the given context
Parameters:
con context to unlock
Return values:
0 on success
-1 on failure

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

06104 {
06105    return ast_mutex_unlock(&con->lock);
06106 }

int ast_unlock_contexts ( void   ) 

Unlocks contexts.

Return values:
0 on success
-1 on failure

Definition at line 6090 of file pbx.c.

References ast_mutex_unlock().

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

06091 {
06092    return ast_mutex_unlock(&conlock);
06093 }

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

References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), free, option_verbose, and VERBOSE_PREFIX_2.

Referenced by __unload_module(), and unload_module().

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

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

References AST_LIST_LOCK, AST_LIST_REMOVE, and AST_LIST_UNLOCK.

Referenced by __unload_module(), and unload_module().

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

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

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

06214 {
06215    if (!exten)
06216       return con ? con->root : NULL;
06217    else
06218       return exten->next;
06219 }

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

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

06247 {
06248    if (!ip)
06249       return con ? con->ignorepats : NULL;
06250    else
06251       return ip->next;
06252 }

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

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

06238 {
06239    if (!inc)
06240       return con ? con->includes : NULL;
06241    else
06242       return inc->next;
06243 }

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

Definition at line 6221 of file pbx.c.

References AST_LIST_FIRST, and AST_LIST_NEXT.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06223 {
06224    if (!sw)
06225       return con ? AST_LIST_FIRST(&con->alts) : NULL;
06226    else
06227       return AST_LIST_NEXT(sw, list);
06228 }

struct ast_context* ast_walk_contexts ( struct ast_context con  ) 

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

06208 {
06209    return con ? con->next : contexts;
06210 }

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

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

06232 {
06233    return priority ? priority->peer : exten;
06234 }

void pbx_builtin_clear_globals ( void   ) 

Definition at line 5961 of file pbx.c.

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

Referenced by handle_reload_extensions(), and reload().

05962 {
05963    struct ast_var_t *vardata;
05964 
05965    ast_mutex_lock(&globalslock);
05966    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
05967       ast_var_delete(vardata);
05968    ast_mutex_unlock(&globalslock);
05969 }

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

Definition at line 5761 of file pbx.c.

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

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

05762 {
05763    struct ast_var_t *variables;
05764    const char *ret = NULL;
05765    int i;
05766    struct varshead *places[2] = { NULL, &globals };
05767 
05768    if (!name)
05769       return NULL;
05770    if (chan)
05771       places[0] = &chan->varshead;
05772 
05773    for (i = 0; i < 2; i++) {
05774       if (!places[i])
05775          continue;
05776       if (places[i] == &globals)
05777          ast_mutex_lock(&globalslock);
05778       AST_LIST_TRAVERSE(places[i], variables, entries) {
05779          if (!strcmp(name, ast_var_name(variables))) {
05780             ret = ast_var_value(variables);
05781             break;
05782          }
05783       }
05784       if (places[i] == &globals)
05785          ast_mutex_unlock(&globalslock);
05786       if (ret)
05787          break;
05788    }
05789 
05790    return ret;
05791 }

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

Definition at line 5793 of file pbx.c.

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

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

05794 {
05795    struct ast_var_t *newvariable;
05796    struct varshead *headp;
05797 
05798    if (name[strlen(name)-1] == ')') {
05799       char *function = ast_strdupa(name);
05800 
05801       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
05802       ast_func_write(chan, function, value);
05803       return;
05804    }
05805 
05806    headp = (chan) ? &chan->varshead : &globals;
05807 
05808    if (value) {
05809       if ((option_verbose > 1) && (headp == &globals))
05810          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05811       newvariable = ast_var_assign(name, value);
05812       if (headp == &globals)
05813          ast_mutex_lock(&globalslock);
05814       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05815       if (headp == &globals)
05816          ast_mutex_unlock(&globalslock);
05817    }
05818 }

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

Definition at line 5734 of file pbx.c.

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

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

05735 {
05736    struct ast_var_t *variables;
05737    const char *var, *val;
05738    int total = 0;
05739 
05740    if (!chan)
05741       return 0;
05742 
05743    memset(buf, 0, size);
05744 
05745    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
05746       if ((var=ast_var_name(variables)) && (val=ast_var_value(variables))
05747          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
05748          ) {
05749          if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) {
05750             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
05751             break;
05752          } else
05753             total++;
05754       } else
05755          break;
05756    }
05757 
05758    return total;
05759 }

int pbx_builtin_setvar ( struct ast_channel chan,
void *  data 
)

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

Definition at line 5820 of file pbx.c.

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

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

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

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

05972 {
05973    if (ast_strlen_zero(condition))  /* NULL or empty strings are false */
05974       return 0;
05975    else if (*condition >= '0' && *condition <= '9')   /* Numbers are evaluated for truth */
05976       return atoi(condition);
05977    else  /* Strings are true */
05978       return 1;
05979 }

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

Execute an application.

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

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

Definition at line 512 of file pbx.c.

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

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

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

struct ast_app* pbx_findapp ( const char *  app  ) 

Look up an application.

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

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

Definition at line 550 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.

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

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

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

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

Note:
See also

Definition at line 1134 of file pbx.c.

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

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

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

int pbx_set_autofallthrough ( int  newval  ) 

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

Definition at line 2659 of file pbx.c.

References autofallthrough.

Referenced by pbx_load_module().

02660 {
02661    int oldval = autofallthrough;
02662    autofallthrough = newval;
02663    return oldval;
02664 }

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

Definition at line 1745 of file pbx.c.

References pbx_substitute_variables_helper_full(), and ast_channel::varshead.

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

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

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

Definition at line 1750 of file pbx.c.

References pbx_substitute_variables_helper_full().

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

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


Generated on Mon May 14 04:52:03 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1