#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <time.h>
#include <sys/time.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/cli.h"
#include "asterisk/pbx.h"
#include "asterisk/channel.h"
#include "asterisk/options.h"
#include "asterisk/logger.h"
#include "asterisk/file.h"
#include "asterisk/callerid.h"
#include "asterisk/cdr.h"
#include "asterisk/config.h"
#include "asterisk/term.h"
#include "asterisk/manager.h"
#include "asterisk/ast_expr.h"
#include "asterisk/linkedlists.h"
#include "asterisk/say.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/musiconhold.h"
#include "asterisk/app.h"
#include "asterisk/devicestate.h"
#include "asterisk/compat.h"

Go to the source code of this file.
Data Structures | |
| struct | app_tmp |
| struct | ast_app |
| ast_app: A registered application More... | |
| struct | ast_context |
| ast_context: An extension context More... | |
| struct | ast_exten |
| ast_exten: An extension The dialplan is saved as a linked list with each context having it's own linked list of extensions - one item per priority. More... | |
| struct | ast_hint |
| Structure for dial plan hints. More... | |
| struct | ast_ignorepat |
| ast_ignorepat: Ignore patterns in dial plan More... | |
| struct | ast_include |
| ast_include: include= support in extensions.conf More... | |
| struct | ast_state_cb |
| ast_state_cb: An extension state notify register item More... | |
| struct | ast_sw |
| ast_sw: Switch statement in extensions.conf More... | |
| struct | async_stat |
| struct | dialplan_counters |
| struct | pbx_builtin |
| Declaration of builtin applications. More... | |
| struct | store_hint |
Defines | |
| #define | AST_PBX_MAX_STACK 128 |
| #define | BACKGROUND_MATCHEXTEN (1 << 2) |
| #define | BACKGROUND_NOANSWER (1 << 1) |
| #define | BACKGROUND_PLAYBACK (1 << 3) |
| #define | BACKGROUND_SKIP (1 << 0) |
| #define | DONT_HAVE_LENGTH 0x80000000 |
| #define | EXT_DATA_SIZE 8192 |
| #define | EXTENSION_MATCH_CORE(data, pattern, match) |
| #define | FIND_NEXT |
| #define | HELPER_CANMATCH 3 |
| #define | HELPER_EXEC 2 |
| #define | HELPER_EXISTS 0 |
| #define | HELPER_FINDLABEL 5 |
| #define | HELPER_MATCHMORE 4 |
| #define | HELPER_SPAWN 1 |
| #define | LOG |
| #define | STATUS_NO_CONTEXT 1 |
| #define | STATUS_NO_EXTENSION 2 |
| #define | STATUS_NO_LABEL 4 |
| #define | STATUS_NO_PRIORITY 3 |
| #define | STATUS_SUCCESS 5 |
| #define | SWITCH_DATA_LENGTH 256 |
| #define | VAR_BUF_SIZE 4096 |
| #define | VAR_HARDTRAN 3 |
| #define | VAR_NORMAL 1 |
| #define | VAR_SOFTTRAN 2 |
| #define | WAITEXTEN_MOH (1 << 0) |
Functions | |
| void | __ast_context_destroy (struct ast_context *con, const char *registrar) |
| static int | __ast_goto_if_exists (struct ast_channel *chan, char *context, char *exten, int priority, int async) |
| static int | __ast_pbx_run (struct ast_channel *c) |
| int | ast_active_calls (void) |
| 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) |
| 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) |
| static int | ast_add_hint (struct ast_exten *e) |
| ast_add_hint: Add hint to hint list, check initial extension state | |
| AST_APP_OPTIONS (resetcdr_opts,{AST_APP_OPTION('w', AST_CDR_FLAG_POSTED), AST_APP_OPTION('a', AST_CDR_FLAG_LOCKED), AST_APP_OPTION('v', AST_CDR_FLAG_KEEP_VARS),}) | |
| AST_APP_OPTIONS (waitexten_opts,{AST_APP_OPTION_ARG('m', WAITEXTEN_MOH, 1),}) | |
| AST_APP_OPTIONS (background_opts,{AST_APP_OPTION('s', BACKGROUND_SKIP), AST_APP_OPTION('n', BACKGROUND_NOANSWER), AST_APP_OPTION('m', BACKGROUND_MATCHEXTEN), AST_APP_OPTION('p', BACKGROUND_PLAYBACK),}) | |
| int | ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority) |
| int | ast_async_goto_by_name (const char *channame, const char *context, const char *exten, int priority) |
| int | ast_async_goto_if_exists (struct ast_channel *chan, char *context, char *exten, int priority) |
| int | ast_build_timing (struct ast_timing *i, char *info_in) |
| int | ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| static int | ast_change_hint (struct ast_exten *oe, struct ast_exten *ne) |
| ast_change_hint: Change hint for an extension | |
| int | ast_check_timing (struct ast_timing *i) |
| int | ast_context_add_ignorepat (const char *con, const char *value, const char *registrar) |
| int | ast_context_add_ignorepat2 (struct ast_context *con, const char *value, const char *registrar) |
| int | ast_context_add_include (const char *context, const char *include, const char *registrar) |
| int | ast_context_add_include2 (struct ast_context *con, const char *value, const char *registrar) |
| int | ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar) |
| int | ast_context_add_switch2 (struct ast_context *con, const char *value, const char *data, int eval, const char *registrar) |
| struct ast_context * | ast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar) |
| void | ast_context_destroy (struct ast_context *con, const char *registrar) |
| struct ast_context * | ast_context_find (const char *name) |
| int | ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar) |
| 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) |
| int | ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar) |
| int | ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar) |
| 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_verify_includes (struct ast_context *con) |
| struct ast_custom_function * | ast_custom_function_find (char *name) |
| int | ast_custom_function_register (struct ast_custom_function *acf) |
| int | ast_custom_function_unregister (struct ast_custom_function *acf) |
| int | ast_exec_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| int | ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| 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 *data) |
| int | ast_extension_state (struct ast_channel *c, char *context, char *exten) |
| ast_extension_state: Check extension state for an extension by using hint | |
| static int | ast_extension_state2 (struct ast_exten *e) |
| ast_extensions_state2: Check state of extension by using hints | |
| const char * | ast_extension_state2str (int extension_state) |
| ast_extension_state2str: Return extension_state as string | |
| int | ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data) |
| ast_extension_state_add: Add watcher for extension states | |
| int | ast_extension_state_del (int id, ast_state_cb_type callback) |
| ast_extension_state_del: Remove a watcher from the callback list | |
| int | ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid) |
| int | ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid) |
| char * | ast_func_read (struct ast_channel *chan, const char *in, char *workspace, size_t len) |
| void | ast_func_write (struct ast_channel *chan, const char *in, const char *value) |
| const char * | ast_get_context_name (struct ast_context *con) |
| const char * | ast_get_context_registrar (struct ast_context *c) |
| const char * | ast_get_extension_app (struct ast_exten *e) |
| void * | ast_get_extension_app_data (struct ast_exten *e) |
| const char * | ast_get_extension_cidmatch (struct ast_exten *e) |
| const char * | ast_get_extension_label (struct ast_exten *exten) |
| int | ast_get_extension_matchcid (struct ast_exten *e) |
| const char * | ast_get_extension_name (struct ast_exten *exten) |
| int | ast_get_extension_priority (struct ast_exten *exten) |
| const char * | ast_get_extension_registrar (struct ast_exten *e) |
| int | ast_get_hint (char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten) |
| ast_get_hint: Get hint for channel | |
| const char * | ast_get_ignorepat_name (struct ast_ignorepat *ip) |
| const char * | ast_get_ignorepat_registrar (struct ast_ignorepat *ip) |
| const char * | ast_get_include_name (struct ast_include *inc) |
| const char * | ast_get_include_registrar (struct ast_include *i) |
| const char * | ast_get_switch_data (struct ast_sw *sw) |
| const char * | ast_get_switch_name (struct ast_sw *sw) |
| const char * | ast_get_switch_registrar (struct ast_sw *sw) |
| int | ast_goto_if_exists (struct ast_channel *chan, char *context, char *exten, int priority) |
| static struct ast_exten * | ast_hint_extension (struct ast_channel *c, const char *context, const char *exten) |
| ast_hint_extension: Find hint for given extension in context | |
| void | ast_hint_state_changed (const char *device) |
| int | ast_ignore_pattern (const char *context, const char *pattern) |
| AST_LIST_HEAD (store_hints, store_hint) | |
| int | ast_lock_context (struct ast_context *con) |
| int | ast_lock_contexts () |
| int | ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| void | ast_merge_contexts_and_delete (struct ast_context **extcontexts, const char *registrar) |
| AST_MUTEX_DEFINE_STATIC (hintlock) | |
| AST_MUTEX_DEFINE_STATIC (switchlock) | |
| AST_MUTEX_DEFINE_STATIC (applock) | |
| AST_MUTEX_DEFINE_STATIC (conlock) | |
| AST_MUTEX_DEFINE_STATIC (acflock) | |
| AST_MUTEX_DEFINE_STATIC (maxcalllock) | |
| AST_MUTEX_DEFINE_STATIC (globalslock) | |
| 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_cdr_failed (void) |
| 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 **channel) |
| enum ast_pbx_result | ast_pbx_run (struct ast_channel *c) |
| static void * | ast_pbx_run_app (void *data) |
| enum ast_pbx_result | ast_pbx_start (struct ast_channel *c) |
| int | ast_register_application (const char *app, int(*execute)(struct ast_channel *, void *), const char *synopsis, const char *description) |
| Dynamically register a new dial plan application. | |
| int | ast_register_switch (struct ast_switch *sw) |
| static int | ast_remove_hint (struct ast_exten *e) |
| ast_remove_hint: Remove hint from extension | |
| int | ast_spawn_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| int | ast_unlock_context (struct ast_context *con) |
| int | ast_unlock_contexts () |
| int | ast_unregister_application (const char *app) |
| void | ast_unregister_switch (struct ast_switch *sw) |
| struct ast_exten * | ast_walk_context_extensions (struct ast_context *con, struct ast_exten *exten) |
| struct ast_ignorepat * | ast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip) |
| struct ast_include * | ast_walk_context_includes (struct ast_context *con, struct ast_include *inc) |
| struct ast_sw * | ast_walk_context_switches (struct ast_context *con, struct ast_sw *sw) |
| struct ast_context * | ast_walk_contexts (struct ast_context *con) |
| struct ast_exten * | ast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority) |
| static void * | async_wait (void *data) |
| static char * | complete_show_application (char *line, char *word, int pos, int state) |
| static char * | complete_show_applications (char *line, char *word, int pos, int state) |
| static char * | complete_show_dialplan_context (char *line, char *word, int pos, int state) |
| static char * | complete_show_function (char *line, char *word, int pos, int state) |
| static void | decrease_call_count (void) |
| static void | destroy_exten (struct ast_exten *e) |
| static int | ext_strncpy (char *dst, const char *src, int len) |
| static unsigned int | get_day (char *day) |
| static unsigned int | get_dow (char *dow) |
| get_dow: Get day of week | |
| static unsigned int | get_month (char *mon) |
| static void | get_timerange (struct ast_timing *i, char *times) |
| static int | handle_show_application (int fd, int argc, char *argv[]) |
| static int | handle_show_applications (int fd, int argc, char *argv[]) |
| static int | handle_show_dialplan (int fd, int argc, char *argv[]) |
| static int | handle_show_function (int fd, int argc, char *argv[]) |
| static int | handle_show_functions (int fd, int argc, char *argv[]) |
| static int | handle_show_hints (int fd, int argc, char *argv[]) |
| handle_show_hints: CLI support for listing registred dial plan hints | |
| static int | handle_show_switches (int fd, int argc, char *argv[]) |
| handle_show_switches: CLI support for listing registred dial plan switches | |
| static int | include_valid (struct ast_include *i) |
| static int | increase_call_count (const struct ast_channel *c) |
| int | load_pbx (void) |
| static int | matchcid (const char *cidpattern, const char *callerid) |
| static void | null_datad (void *foo) |
| static int | parse_variable_name (char *var, int *offset, int *length, int *isfunc) |
| static int | pbx_builtin_answer (struct ast_channel *, void *) |
| static int | pbx_builtin_atimeout (struct ast_channel *, void *) |
| static int | pbx_builtin_background (struct ast_channel *, void *) |
| static int | pbx_builtin_busy (struct ast_channel *, void *) |
| void | pbx_builtin_clear_globals (void) |
| static int | pbx_builtin_congestion (struct ast_channel *, void *) |
| static int | pbx_builtin_dtimeout (struct ast_channel *, void *) |
| static int | pbx_builtin_execiftime (struct ast_channel *, void *) |
| char * | pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name) |
| static int | pbx_builtin_goto (struct ast_channel *, void *) |
| static int | pbx_builtin_gotoif (struct ast_channel *, void *) |
| static int | pbx_builtin_gotoiftime (struct ast_channel *, void *) |
| static int | pbx_builtin_hangup (struct ast_channel *, void *) |
| static int | pbx_builtin_importvar (struct ast_channel *, void *) |
| static int | pbx_builtin_noop (struct ast_channel *, void *) |
| static int | pbx_builtin_progress (struct ast_channel *, void *) |
| void | pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value) |
| static int | pbx_builtin_resetcdr (struct ast_channel *, void *) |
| static int | pbx_builtin_ringing (struct ast_channel *, void *) |
| static int | pbx_builtin_rtimeout (struct ast_channel *, void *) |
| static int | pbx_builtin_saycharacters (struct ast_channel *, void *) |
| static int | pbx_builtin_saydigits (struct ast_channel *, void *) |
| static int | pbx_builtin_saynumber (struct ast_channel *, void *) |
| static int | pbx_builtin_sayphonetic (struct ast_channel *, void *) |
| int | pbx_builtin_serialize_variables (struct ast_channel *chan, char *buf, size_t size) |
| static int | pbx_builtin_setaccount (struct ast_channel *, void *) |
| static int | pbx_builtin_setamaflags (struct ast_channel *, void *) |
| static int | pbx_builtin_setglobalvar (struct ast_channel *, void *) |
| static int | pbx_builtin_setlanguage (struct ast_channel *, void *) |
| int | pbx_builtin_setvar (struct ast_channel *, void *) |
| void | pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value) |
| static int | pbx_builtin_setvar_old (struct ast_channel *, void *) |
| static int | pbx_builtin_wait (struct ast_channel *, void *) |
| static int | pbx_builtin_waitexten (struct ast_channel *, void *) |
| int | pbx_checkcondition (char *condition) |
| static void | pbx_destroy (struct ast_pbx *p) |
| int | pbx_exec (struct ast_channel *c, struct ast_app *app, void *data, int newstack) |
| static int | pbx_extension_helper (struct ast_channel *c, struct ast_context *con, const char *context, const char *exten, int priority, const char *label, const char *callerid, int action) |
| static struct ast_exten * | pbx_find_extension (struct ast_channel *chan, struct ast_context *bypass, const char *context, const char *exten, int priority, const char *label, const char *callerid, int action, char *incstack[], int *stacklen, int *status, struct ast_switch **swo, char **data, const char **foundcontext) |
| struct ast_app * | pbx_findapp (const char *app) |
| Find application handle in linked list. | |
| static struct ast_switch * | pbx_findswitch (const char *sw) |
| void | pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp) |
| pbx_retrieve_variable: Support for Asterisk built-in variables --- | |
| int | pbx_set_autofallthrough (int newval) |
| static void | pbx_substitute_variables (char *passdata, int datalen, struct ast_channel *c, struct ast_exten *e) |
| void | pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count) |
| static void | pbx_substitute_variables_helper_full (struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count) |
| void | pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count) |
| static void * | pbx_thread (void *data) |
| static int | show_dialplan_helper (int fd, char *context, char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude, int includecount, char *includes[]) |
| static char * | substring (const char *value, int offset, int length, char *workspace, size_t workspace_len) |
| takes a substring. It is ok to call with value == workspace. | |
| static void | wait_for_hangup (struct ast_channel *chan, void *data) |
Variables | |
| static struct ast_custom_function * | acf_root = NULL |
| static struct ast_app * | apps = NULL |
| static int | autofallthrough = 0 |
| static struct pbx_builtin | builtins [] |
| Declaration of builtin applications. | |
| static struct ast_context * | contexts = NULL |
| static int | countcalls = 0 |
| static char * | days [] |
| static struct varshead | globals |
| struct ast_hint * | hints = NULL |
| static char * | months [] |
| static struct ast_cli_entry | pbx_cli [] |
| static char | show_application_help [] |
| static char | show_applications_help [] |
| static char | show_dialplan_help [] |
| static char | show_function_help [] |
| static char | show_functions_help [] |
| static char | show_hints_help [] |
| static char | show_switches_help [] |
| struct ast_state_cb * | statecbs = NULL |
| static int | stateid = 1 |
| struct ast_switch * | switches = NULL |
Definition in file pbx.c.
| #define AST_PBX_MAX_STACK 128 |
Go no deeper than this through includes (not counting loops)
Definition at line 586 of file pbx.c.
Referenced by ast_hint_extension(), handle_show_dialplan(), pbx_extension_helper(), pbx_find_extension(), and show_dialplan_helper().
| #define BACKGROUND_MATCHEXTEN (1 << 2) |
| #define BACKGROUND_NOANSWER (1 << 1) |
| #define BACKGROUND_PLAYBACK (1 << 3) |
| #define BACKGROUND_SKIP (1 << 0) |
| #define DONT_HAVE_LENGTH 0x80000000 |
| #define EXT_DATA_SIZE 8192 |
Definition at line 74 of file pbx.c.
Referenced by pbx_extension_helper(), and realtime_exec().
| #define EXTENSION_MATCH_CORE | ( | data, | |||
| pattern, | |||||
| match | ) |
Definition at line 646 of file pbx.c.
Referenced by ast_extension_close(), and ast_extension_match().
| #define FIND_NEXT |
Value:
do { \ c = info; \ while(*c && (*c != '|')) c++; \ if (*c) { *c = '\0'; c++; } else c = NULL; \ } while(0)
Definition at line 3855 of file pbx.c.
Referenced by ast_build_timing().
| #define HELPER_CANMATCH 3 |
Definition at line 591 of file pbx.c.
Referenced by ast_canmatch_extension(), pbx_extension_helper(), and pbx_find_extension().
| #define HELPER_EXEC 2 |
Definition at line 590 of file pbx.c.
Referenced by ast_exec_extension(), and pbx_extension_helper().
| #define HELPER_EXISTS 0 |
Definition at line 588 of file pbx.c.
Referenced by ast_exists_extension(), ast_hint_extension(), and pbx_extension_helper().
| #define HELPER_FINDLABEL 5 |
Definition at line 593 of file pbx.c.
Referenced by ast_findlabel_extension(), ast_findlabel_extension2(), pbx_extension_helper(), and pbx_find_extension().
| #define HELPER_MATCHMORE 4 |
Definition at line 592 of file pbx.c.
Referenced by ast_matchmore_extension(), pbx_extension_helper(), and pbx_find_extension().
| #define HELPER_SPAWN 1 |
Definition at line 589 of file pbx.c.
Referenced by ast_spawn_extension(), and pbx_extension_helper().
| #define LOG |
Referenced by ast_add_extension2().
| #define STATUS_NO_CONTEXT 1 |
Definition at line 774 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
| #define STATUS_NO_EXTENSION 2 |
Definition at line 775 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
| #define STATUS_NO_LABEL 4 |
Definition at line 777 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
| #define STATUS_NO_PRIORITY 3 |
Definition at line 776 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
| #define STATUS_SUCCESS 5 |
| #define SWITCH_DATA_LENGTH 256 |
Definition at line 77 of file pbx.c.
Referenced by ast_context_add_switch2(), and pbx_find_extension().
| #define VAR_BUF_SIZE 4096 |
Definition at line 79 of file pbx.c.
Referenced by ast_add_extension2(), pbx_builtin_importvar(), and pbx_substitute_variables_helper_full().
| #define WAITEXTEN_MOH (1 << 0) |
| void __ast_context_destroy | ( | struct ast_context * | con, | |
| const char * | registrar | |||
| ) |
Definition at line 5341 of file pbx.c.
References ast_context::alts, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), destroy_exten(), el, free, ast_context::ignorepats, ast_context::includes, ast_context::lock, LOG_WARNING, ast_context::name, ast_exten::next, ast_sw::next, ast_ignorepat::next, ast_include::next, ast_context::next, ast_exten::peer, ast_context::registrar, and ast_context::root.
Referenced by ast_context_destroy(), and ast_merge_contexts_and_delete().
05342 { 05343 struct ast_context *tmp, *tmpl=NULL; 05344 struct ast_include *tmpi, *tmpil= NULL; 05345 struct ast_sw *sw, *swl= NULL; 05346 struct ast_exten *e, *el, *en; 05347 struct ast_ignorepat *ipi, *ipl = NULL; 05348 05349 ast_mutex_lock(&conlock); 05350 tmp = contexts; 05351 while(tmp) { 05352 if (((tmp->name && con && con->name && !strcasecmp(tmp->name, con->name)) || !con) && 05353 (!registrar || !strcasecmp(registrar, tmp->registrar))) { 05354 /* Okay, let's lock the structure to be sure nobody else 05355 is searching through it. */ 05356 if (ast_mutex_lock(&tmp->lock)) { 05357 ast_log(LOG_WARNING, "Unable to lock context lock\n"); 05358 return; 05359 } 05360 if (tmpl) 05361 tmpl->next = tmp->next; 05362 else 05363 contexts = tmp->next; 05364 /* Okay, now we're safe to let it go -- in a sense, we were 05365 ready to let it go as soon as we locked it. */ 05366 ast_mutex_unlock(&tmp->lock); 05367 for (tmpi = tmp->includes; tmpi; ) { 05368 /* Free includes */ 05369 tmpil = tmpi; 05370 tmpi = tmpi->next; 05371 free(tmpil); 05372 } 05373 for (ipi = tmp->ignorepats; ipi; ) { 05374 /* Free ignorepats */ 05375 ipl = ipi; 05376 ipi = ipi->next; 05377 free(ipl); 05378 } 05379 for (sw = tmp->alts; sw; ) { 05380 /* Free switches */ 05381 swl = sw; 05382 sw = sw->next; 05383 free(swl); 05384 swl = sw; 05385 } 05386 for (e = tmp->root; e;) { 05387 for (en = e->peer; en;) { 05388 el = en; 05389 en = en->peer; 05390 destroy_exten(el); 05391 } 05392 el = e; 05393 e = e->next; 05394 destroy_exten(el); 05395 } 05396 ast_mutex_destroy(&tmp->lock); 05397 free(tmp); 05398 if (!con) { 05399 /* Might need to get another one -- restart */ 05400 tmp = contexts; 05401 tmpl = NULL; 05402 tmpil = NULL; 05403 continue; 05404 } 05405 ast_mutex_unlock(&conlock); 05406 return; 05407 } 05408 tmpl = tmp; 05409 tmp = tmp->next; 05410 } 05411 ast_mutex_unlock(&conlock); 05412 }
| static int __ast_goto_if_exists | ( | struct ast_channel * | chan, | |
| char * | context, | |||
| char * | exten, | |||
| int | priority, | |||
| int | async | |||
| ) | [static] |
Definition at line 6478 of file pbx.c.
References ast_async_goto(), ast_exists_extension(), ast_explicit_goto(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, and ast_channel::exten.
Referenced by ast_async_goto_if_exists(), and ast_goto_if_exists().
06479 { 06480 int (*goto_func)(struct ast_channel *chan, const char *context, const char *exten, int priority); 06481 06482 if (!chan) 06483 return -2; 06484 06485 goto_func = (async) ? ast_async_goto : ast_explicit_goto; 06486 if (ast_exists_extension(chan, context ? context : chan->context, 06487 exten ? exten : chan->exten, priority, 06488 chan->cid.cid_num)) 06489 return goto_func(chan, context ? context : chan->context, 06490 exten ? exten : chan->exten, priority); 06491 else 06492 return -3; 06493 }
| static int __ast_pbx_run | ( | struct ast_channel * | c | ) | [static] |
Definition at line 2258 of file pbx.c.
References ast_channel::_softhangup, ast_channel::amaflags, ast_cdr_alloc(), ast_cdr_init(), ast_cdr_start(), ast_cdr_update(), ast_exists_extension(), AST_FLAG_IN_AUTOLOOP, ast_hangup(), ast_log(), ast_matchmore_extension(), AST_PBX_KEEPALIVE, ast_set2_flag, ast_set_flag, AST_SOFTHANGUP_ASYNCGOTO, AST_SOFTHANGUP_TIMEOUT, ast_spawn_extension(), ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_waitfordigit(), ast_channel::cdr, ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_pbx::dtimeout, ast_channel::exten, exten, free, LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, ast_channel::name, option_debug, option_verbose, ast_channel::pbx, pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pbx_destroy(), ast_channel::priority, ast_pbx::rtimeout, ast_cdr::start, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, and ast_channel::whentohangup.
Referenced by ast_pbx_run(), and pbx_thread().
02259 { 02260 int firstpass = 1; 02261 int digit; 02262 char exten[256]; 02263 int pos; 02264 int waittime; 02265 int res=0; 02266 int autoloopflag; 02267 02268 /* A little initial setup here */ 02269 if (c->pbx) 02270 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name); 02271 c->pbx = malloc(sizeof(struct ast_pbx)); 02272 if (!c->pbx) { 02273 ast_log(LOG_ERROR, "Out of memory\n"); 02274 return -1; 02275 } 02276 if (c->amaflags) { 02277 if (!c->cdr) { 02278 c->cdr = ast_cdr_alloc(); 02279 if (!c->cdr) { 02280 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 02281 free(c->pbx); 02282 return -1; 02283 } 02284 ast_cdr_init(c->cdr, c); 02285 } 02286 } 02287 memset(c->pbx, 0, sizeof(struct ast_pbx)); 02288 /* Set reasonable defaults */ 02289 c->pbx->rtimeout = 10; 02290 c->pbx->dtimeout = 5; 02291 02292 autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP); 02293 ast_set_flag(c, AST_FLAG_IN_AUTOLOOP); 02294 02295 /* Start by trying whatever the channel is set to */ 02296 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02297 /* If not successful fall back to 's' */ 02298 if (option_verbose > 1) 02299 ast_verbose( VERBOSE_PREFIX_2 "Starting %s at %s,%s,%d failed so falling back to exten 's'\n", c->name, c->context, c->exten, c->priority); 02300 ast_copy_string(c->exten, "s", sizeof(c->exten)); 02301 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02302 /* JK02: And finally back to default if everything else failed */ 02303 if (option_verbose > 1) 02304 ast_verbose( VERBOSE_PREFIX_2 "Starting %s at %s,%s,%d still failed so falling back to context 'default'\n", c->name, c->context, c->exten, c->priority); 02305 ast_copy_string(c->context, "default", sizeof(c->context)); 02306 } 02307 c->priority = 1; 02308 } 02309 if (c->cdr && !c->cdr->start.tv_sec && !c->cdr->start.tv_usec) 02310 ast_cdr_start(c->cdr); 02311 for(;;) { 02312 pos = 0; 02313 digit = 0; 02314 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02315 memset(exten, 0, sizeof(exten)); 02316 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02317 /* Something bad happened, or a hangup has been requested. */ 02318 if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) || 02319 (res == '*') || (res == '#')) { 02320 ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res); 02321 memset(exten, 0, sizeof(exten)); 02322 pos = 0; 02323 exten[pos++] = digit = res; 02324 break; 02325 } 02326 switch(res) { 02327 case AST_PBX_KEEPALIVE: 02328 if (option_debug) 02329 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02330 if (option_verbose > 1) 02331 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02332 goto out; 02333 break; 02334 default: 02335 if (option_debug) 02336 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02337 if (option_verbose > 1) 02338 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02339 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02340 c->_softhangup =0; 02341 break; 02342 } 02343 /* atimeout */ 02344 if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02345 break; 02346 } 02347 02348 if (c->cdr) { 02349 ast_cdr_update(c); 02350 } 02351 goto out; 02352 } 02353 } 02354 if ((c->_softhangup == AST_SOFTHANGUP_TIMEOUT) && (ast_exists_extension(c,c->context,"T",1,c->cid.cid_num))) { 02355 ast_copy_string(c->exten, "T", sizeof(c->exten)); 02356 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */ 02357 c->whentohangup = 0; 02358 c->priority = 0; 02359 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT; 02360 } else if (c->_softhangup) { 02361 ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n", 02362 c->exten, c->priority); 02363 goto out; 02364 } 02365 firstpass = 0; 02366 c->priority++; 02367 } 02368 if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) { 02369 /* It's not a valid extension anymore */ 02370 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02371 if (option_verbose > 2) 02372 ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name); 02373 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten); 02374 ast_copy_string(c->exten, "i", sizeof(c->exten)); 02375 c->priority = 1; 02376 } else { 02377 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n", 02378 c->name, c->exten, c->context); 02379 goto out; 02380 } 02381 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02382 /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */ 02383 c->_softhangup = 0; 02384 } else { 02385 /* Done, wait for an extension */ 02386 waittime = 0; 02387 if (digit) 02388 waittime = c->pbx->dtimeout; 02389 else if (!autofallthrough) 02390 waittime = c->pbx->rtimeout; 02391 if (waittime) { 02392 while (ast_matchmore_extension(c, c->context, exten, 1, c->cid.cid_num)) { 02393 /* As long as we're willing to wait, and as long as it's not defined, 02394 keep reading digits until we can't possibly get a right answer anymore. */ 02395 digit = ast_waitfordigit(c, waittime * 1000); 02396 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02397 c->_softhangup = 0; 02398 } else { 02399 if (!digit) 02400 /* No entry */ 02401 break; 02402 if (digit < 0) 02403 /* Error, maybe a hangup */ 02404 goto out; 02405 exten[pos++] = digit; 02406 waittime = c->pbx->dtimeout; 02407 } 02408 } 02409 if (ast_exists_extension(c, c->context, exten, 1, c->cid.cid_num)) { 02410 /* Prepare the next cycle */ 02411 ast_copy_string(c->exten, exten, sizeof(c->exten)); 02412 c->priority = 1; 02413 } else { 02414 /* No such extension */ 02415 if (!ast_strlen_zero(exten)) { 02416 /* An invalid extension */ 02417 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02418 if (option_verbose > 2) 02419 ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", exten, c->context, c->name); 02420 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", exten); 02421 ast_copy_string(c->exten, "i", sizeof(c->exten)); 02422 c->priority = 1; 02423 } else { 02424 ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", exten, c->context); 02425 goto out; 02426 } 02427 } else { 02428 /* A simple timeout */ 02429 if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) { 02430 if (option_verbose > 2) 02431 ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name); 02432 ast_copy_string(c->exten, "t", sizeof(c->exten)); 02433 c->priority = 1; 02434 } else { 02435 ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context); 02436 goto out; 02437 } 02438 } 02439 } 02440 if (c->cdr) { 02441 if (option_verbose > 2) 02442 ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name); 02443 ast_cdr_update(c); 02444 } 02445 } else { 02446 char *status; 02447 02448 status = pbx_builtin_getvar_helper(c, "DIALSTATUS"); 02449 if (!status) 02450 status = "UNKNOWN"; 02451 if (option_verbose > 2) 02452 ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status); 02453 if (!strcasecmp(status, "CONGESTION")) 02454 res = pbx_builtin_congestion(c, "10"); 02455 else if (!strcasecmp(status, "CHANUNAVAIL")) 02456 res = pbx_builtin_congestion(c, "10"); 02457 else if (!strcasecmp(status, "BUSY")) 02458 res = pbx_builtin_busy(c, "10"); 02459 goto out; 02460 } 02461 } 02462 } 02463 if (firstpass) 02464 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name); 02465 out: 02466 if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) { 02467 c->exten[0] = 'h'; 02468 c->exten[1] = '\0'; 02469 c->priority = 1; 02470 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02471 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02472 /* Something bad happened, or a hangup has been requested. */ 02473 if (option_debug) 02474 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02475 if (option_verbose > 1) 02476 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02477 break; 02478 } 02479 c->priority++; 02480 } 02481 } 02482 ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP); 02483 02484 pbx_destroy(c->pbx); 02485 c->pbx = NULL; 02486 if (res != AST_PBX_KEEPALIVE) 02487 ast_hangup(c); 02488 return 0; 02489 }
| int ast_active_calls | ( | void | ) |
Definition at line 2584 of file pbx.c.
Referenced by handle_chanlist().
02585 { 02586 return countcalls; 02587 }
| 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 | |||
| ) |
| context | context to add the extension to | |
| replace | ||
| extension | extension to add | |
| priority | priority level of extension addition | |
| label | extension label | |
| callerid | callerid of extension | |
| application | application to run on the extension with that priority level | |
| data | data to pass to the application | |
| datad | ||
| registrar | who registered the extension Add and extension to an extension context. Callerid is a pattern to match CallerID, or NULL to match any callerid Returns 0 on success, -1 on failure |
Definition at line 4527 of file pbx.c.
References ast_add_extension2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by handle_context_add_extension(), and register_peer_exten().
04529 { 04530 struct ast_context *c; 04531 04532 if (ast_lock_contexts()) { 04533 errno = EBUSY; 04534 return -1; 04535 } 04536 04537 c = ast_walk_contexts(NULL); 04538 while (c) { 04539 if (!strcmp(context, ast_get_context_name(c))) { 04540 int ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04541 application, data, datad, registrar); 04542 ast_unlock_contexts(); 04543 return ret; 04544 } 04545 c = ast_walk_contexts(c); 04546 } 04547 04548 ast_unlock_contexts(); 04549 errno = ENOENT; 04550 return -1; 04551 }
| 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 *. CallerID is a pattern to match on callerid, or NULL to not care about callerid
For details about the arguements, check ast_add_extension()
Definition at line 4666 of file pbx.c.
References ast_exten::app, ast_add_hint(), ast_change_hint(), AST_LIST_FIRST, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_exten::cidmatch, ast_exten::data, ast_exten::datad, el, ext_strncpy(), ast_exten::exten, free, globals, ast_exten::label, ast_context::lock, LOG, LOG_ERROR, LOG_WARNING, malloc, ast_exten::matchcid, ast_context::name, ast_exten::next, null_datad(), ast_exten::parent, pbx_substitute_variables_varshead(), ast_exten::peer, ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, ast_context::root, ast_exten::stuff, and VAR_BUF_SIZE.
Referenced by __build_step(), ast_add_extension(), ast_park_call(), do_parking_thread(), fillin_process(), handle_macro(), load_config(), and pbx_load_module().
04670 { 04671 04672 #define LOG do { if (option_debug) {\ 04673 if (tmp->matchcid) { \ 04674 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \ 04675 } else { \ 04676 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \ 04677 } \ 04678 } \ 04679 if (option_verbose > 2) { \ 04680 if (tmp->matchcid) { \ 04681 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \ 04682 } else { \ 04683 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \ 04684 } \ 04685 } } while(0) 04686 04687 /* 04688 * This is a fairly complex routine. Different extensions are kept 04689 * in order by the extension number. Then, extensions of different 04690 * priorities (same extension) are kept in a list, according to the 04691 * peer pointer. 04692 */ 04693 struct ast_exten *tmp, *e, *el = NULL, *ep = NULL; 04694 int res; 04695 int length; 04696 char *p; 04697 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04698 04699 /* if we are adding a hint, and there are global variables, and the hint 04700 contains variable references, then expand them 04701 */ 04702 ast_mutex_lock(&globalslock); 04703 if ((priority == PRIORITY_HINT) && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04704 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04705 application = expand_buf; 04706 } 04707 ast_mutex_unlock(&globalslock); 04708 04709 length = sizeof(struct ast_exten); 04710 length += strlen(extension) + 1; 04711 length += strlen(application) + 1; 04712 if (label) 04713 length += strlen(label) + 1; 04714 if (callerid) 04715 length += strlen(callerid) + 1; 04716 else 04717 length ++; 04718 04719 /* Be optimistic: Build the extension structure first */ 04720 if (datad == NULL) 04721 datad = null_datad; 04722 tmp = malloc(length); 04723 if (tmp) { 04724 memset(tmp, 0, length); 04725 p = tmp->stuff; 04726 if (label) { 04727 tmp->label = p; 04728 strcpy(tmp->label, label); 04729 p += strlen(label) + 1; 04730 } 04731 tmp->exten = p; 04732 p += ext_strncpy(tmp->exten, extension, strlen(extension) + 1) + 1; 04733 tmp->priority = priority; 04734 tmp->cidmatch = p; 04735 if (callerid) { 04736 p += ext_strncpy(tmp->cidmatch, callerid, strlen(callerid) + 1) + 1; 04737 tmp->matchcid = 1; 04738 } else { 04739 tmp->cidmatch[0] = '\0'; 04740 tmp->matchcid = 0; 04741 p++; 04742 } 04743 tmp->app = p; 04744 strcpy(tmp->app, application); 04745 tmp->parent = con; 04746 tmp->data = data; 04747 tmp->datad = datad; 04748 tmp->registrar = registrar; 04749 tmp->peer = NULL; 04750 tmp->next = NULL; 04751 } else { 04752 ast_log(LOG_ERROR, "Out of memory\n"); 04753 errno = ENOMEM; 04754 return -1; 04755 } 04756 if (ast_mutex_lock(&con->lock)) { 04757 free(tmp); 04758 /* And properly destroy the data */ 04759 datad(data); 04760 ast_log(LOG_WARNING, "Failed to lock context '%s'\n", con->name); 04761 errno = EBUSY; 04762 return -1; 04763 } 04764 e = con->root; 04765 while(e) { 04766 /* Make sure patterns are always last! */ 04767 if ((e->exten[0] != '_') && (extension[0] == '_')) 04768 res = -1; 04769 else if ((e->exten[0] == '_') && (extension[0] != '_')) 04770 res = 1; 04771 else 04772 res= strcmp(e->exten, extension); 04773 if (!res) { 04774 if (!e->matchcid && !tmp->matchcid) 04775 res = 0; 04776 else if (tmp->matchcid && !e->matchcid) 04777 res = 1; 04778 else if (e->matchcid && !tmp->matchcid) 04779 res = -1; 04780 else 04781 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04782 } 04783 if (res == 0) { 04784 /* We have an exact match, now we find where we are 04785 and be sure there's no duplicates */ 04786 while(e) { 04787 if (e->priority == tmp->priority) { 04788 /* Can't have something exactly the same. Is this a 04789 replacement? If so, replace, otherwise, bonk. */ 04790 if (replace) { 04791 if (ep) { 04792 /* We're in the peer list, insert ourselves */ 04793 ep->peer = tmp; 04794 tmp->peer = e->peer; 04795 } else if (el) { 04796 /* We're the first extension. Take over e's functions */ 04797 el->next = tmp; 04798 tmp->next = e->next; 04799 tmp->peer = e->peer; 04800 } else { 04801 /* We're the very first extension. */ 04802 con->root = tmp; 04803 tmp->next = e->next; 04804 tmp->peer = e->peer; 04805 } 04806 if (tmp->priority == PRIORITY_HINT) 04807 ast_change_hint(e,tmp); 04808 /* Destroy the old one */ 04809 e->datad(e->data); 04810 free(e); 04811 ast_mutex_unlock(&con->lock); 04812 if (tmp->priority == PRIORITY_HINT) 04813 ast_change_hint(e, tmp); 04814 /* And immediately return success. */ 04815 LOG; 04816 return 0; 04817 } else { 04818 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name); 04819 tmp->datad(tmp->data); 04820 free(tmp); 04821 ast_mutex_unlock(&con->lock); 04822 errno = EEXIST; 04823 return -1; 04824 } 04825 } else if (e->priority > tmp->priority) { 04826 /* Slip ourselves in just before e */ 04827 if (ep) { 04828 /* Easy enough, we're just in the peer list */ 04829 ep->peer = tmp; 04830 tmp->peer = e; 04831 } else if (el) { 04832 /* We're the first extension in this peer list */ 04833 el->next = tmp; 04834 tmp->next = e->next; 04835 e->next = NULL; 04836 tmp->peer = e; 04837 } else { 04838 /* We're the very first extension altogether */ 04839 tmp->next = con->root->next; 04840 /* Con->root must always exist or we couldn't get here */ 04841 tmp->peer = con->root; 04842 con->root = tmp; 04843 } 04844 ast_mutex_unlock(&con->lock); 04845 04846 /* And immediately return success. */ 04847 if (tmp->priority == PRIORITY_HINT) 04848 ast_add_hint(tmp); 04849 04850 LOG; 04851 return 0; 04852 } 04853 ep = e; 04854 e = e->peer; 04855 } 04856 /* If we make it here, then it's time for us to go at the very end. 04857 ep *must* be defined or we couldn't have gotten here. */ 04858 ep->peer = tmp; 04859 ast_mutex_unlock(&con->lock); 04860 if (tmp->priority == PRIORITY_HINT) 04861 ast_add_hint(tmp); 04862 04863 /* And immediately return success. */ 04864 LOG; 04865 return 0; 04866 04867 } else if (res > 0) { 04868 /* Insert ourselves just before 'e'. We're the first extension of 04869 this kind */ 04870 tmp->next = e; 04871 if (el) { 04872 /* We're in the list somewhere */ 04873 el->next = tmp; 04874 } else { 04875 /* We're at the top of the list */ 04876 con->root = tmp; 04877 } 04878 ast_mutex_unlock(&con->lock); 04879 if (tmp->priority == PRIORITY_HINT) 04880 ast_add_hint(tmp); 04881 04882 /* And immediately return success. */ 04883 LOG; 04884 return 0; 04885 } 04886 04887 el = e; 04888 e = e->next; 04889 } 04890 /* If we fall all the way through to here, then we need to be on the end. */ 04891 if (el) 04892 el->next = tmp; 04893 else 04894 con->root = tmp; 04895 ast_mutex_unlock(&con->lock); 04896 if (tmp->priority == PRIORITY_HINT) 04897 ast_add_hint(tmp); 04898 LOG; 04899 return 0; 04900 }
| static int ast_add_hint | ( | struct ast_exten * | e | ) | [static] |
ast_add_hint: Add hint to hint list, check initial extension state
Definition at line 2095 of file pbx.c.
References ast_extension_state2(), ast_get_extension_app(), ast_get_extension_name(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_hint::exten, ast_hint::laststate, list, LOG_DEBUG, malloc, ast_hint::next, and option_debug.
Referenced by ast_add_extension2().
02096 { 02097 struct ast_hint *list; 02098 02099 if (!e) 02100 return -1; 02101 02102 ast_mutex_lock(&hintlock); 02103 list = hints; 02104 02105 /* Search if hint exists, do nothing */ 02106 while (list) { 02107 if (list->exten == e) { 02108 ast_mutex_unlock(&hintlock); 02109 if (option_debug > 1) 02110 ast_log(LOG_DEBUG, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02111 return -1; 02112 } 02113 list = list->next; 02114 } 02115 02116 if (option_debug > 1) 02117 ast_log(LOG_DEBUG, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02118 02119 list = malloc(sizeof(struct ast_hint)); 02120 if (!list) { 02121 ast_mutex_unlock(&hintlock); 02122 if (option_debug > 1) 02123 ast_log(LOG_DEBUG, "HINTS: Out of memory...\n"); 02124 return -1; 02125 } 02126 /* Initialize and insert new item at the top */ 02127 memset(list, 0, sizeof(struct ast_hint)); 02128 list->exten = e; 02129 list->laststate = ast_extension_state2(e); 02130 list->next = hints; 02131 hints = list; 02132 02133 ast_mutex_unlock(&hintlock); 02134 return 0; 02135 }
| AST_APP_OPTIONS | ( | resetcdr_opts | ) |
| AST_APP_OPTIONS | ( | waitexten_opts | ) |
| AST_APP_OPTIONS | ( | background_opts | ) |
| int ast_async_goto | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 4572 of file pbx.c.
References ast_channel::_state, ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_setstate(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_strlen_zero(), ast_channel::context, ast_channel::exten, ast_channel::lock, LOG_WARNING, ast_channel::name, ast_channel::pbx, ast_channel::readformat, and ast_channel::writeformat.
Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), handle_request_bye(), handle_request_refer(), i4l_read(), monitor_handle_owned(), process_ast_dsp(), socket_read(), and zt_handle_dtmfup().
04573 { 04574 int res = 0; 04575 04576 ast_mutex_lock(&chan->lock); 04577 04578 if (chan->pbx) { 04579 /* This channel is currently in the PBX */ 04580 ast_explicit_goto(chan, context, exten, priority); 04581 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04582 } else { 04583 /* In order to do it when the channel doesn't really exist within 04584 the PBX, we have to make a new channel, masquerade, and start the PBX 04585 at the new location */ 04586 struct ast_channel *tmpchan; 04587 tmpchan = ast_channel_alloc(0); 04588 if (tmpchan) { 04589 snprintf(tmpchan->name, sizeof(tmpchan->name), "AsyncGoto/%s", chan->name); 04590 ast_setstate(tmpchan, chan->_state); 04591 /* Make formats okay */ 04592 tmpchan->readformat = chan->readformat; 04593 tmpchan->writeformat = chan->writeformat; 04594 /* Setup proper location */ 04595 ast_explicit_goto(tmpchan, 04596 (!ast_strlen_zero(context)) ? context : chan->context, 04597 (!ast_strlen_zero(exten)) ? exten : chan->exten, 04598 priority); 04599 04600 /* Masquerade into temp channel */ 04601 ast_channel_masquerade(tmpchan, chan); 04602 04603 /* Grab the locks and get going */ 04604 ast_mutex_lock(&tmpchan->lock); 04605 ast_do_masquerade(tmpchan); 04606 ast_mutex_unlock(&tmpchan->lock); 04607 /* Start the PBX going on our stolen channel */ 04608 if (ast_pbx_start(tmpchan)) { 04609 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04610 ast_hangup(tmpchan); 04611 res = -1; 04612 } 04613 } else { 04614 res = -1; 04615 } 04616 } 04617 ast_mutex_unlock(&chan->lock); 04618 return res; 04619 }
| int ast_async_goto_by_name | ( | const char * | channame, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 4621 of file pbx.c.
References ast_async_goto(), ast_get_channel_by_name_locked(), ast_mutex_unlock(), and ast_channel::lock.
04622 { 04623 struct ast_channel *chan; 04624 int res = -1; 04625 04626 chan = ast_get_channel_by_name_locked(channame); 04627 if (chan) { 04628 res = ast_async_goto(chan, context, exten, priority); 04629 ast_mutex_unlock(&chan->lock); 04630 } 04631 return res; 04632 }
| int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
| char * | context, | |||
| char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 6499 of file pbx.c.
References __ast_goto_if_exists().
06499 { 06500 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06501 }
| int ast_build_timing | ( | struct ast_timing * | i, | |
| char * | info_in | |||
| ) |
Definition at line 4105 of file pbx.c.
References ast_strlen_zero(), ast_timing::daymask, ast_timing::dowmask, FIND_NEXT, get_day(), get_dow(), get_month(), get_timerange(), and ast_timing::monthmask.
Referenced by ast_context_add_include2(), builtin_function_iftime(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
04106 { 04107 char info_save[256]; 04108 char *info; 04109 char *c; 04110 04111 /* Check for empty just in case */ 04112 if (ast_strlen_zero(info_in)) 04113 return 0; 04114 /* make a copy just in case we were passed a static string */ 04115 ast_copy_string(info_save, info_in, sizeof(info_save)); 04116 info = info_save; 04117 /* Assume everything except time */ 04118 i->monthmask = (1 << 12) - 1; 04119 i->daymask = (1 << 30) - 1 + (1 << 30); 04120 i->dowmask = (1 << 7) - 1; 04121 /* Avoid using str tok */ 04122 FIND_NEXT; 04123 /* Info has the time range, start with that */ 04124 get_timerange(i, info); 04125 info = c; 04126 if (!info) 04127 return 1; 04128 FIND_NEXT; 04129 /* Now check for day of week */ 04130 i->dowmask = get_dow(info); 04131 04132 info = c; 04133 if (!info) 04134 return 1; 04135 FIND_NEXT; 04136 /* Now check for the day of the month */ 04137 i->daymask = get_day(info); 04138 info = c; 04139 if (!info) 04140 return 1; 04141 FIND_NEXT; 04142 /* And finally go for the month */ 04143 i->monthmask = get_month(info); 04144 04145 return 1; 04146 }
| 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
| 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 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 2238 of file pbx.c.
References HELPER_CANMATCH, and pbx_extension_helper().
Referenced by background_detect_exec(), cb_events(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), loopback_canmatch(), mgcp_ss(), monitor_handle_notowned(), phone_check_exception(), rpt(), skinny_ss(), ss_thread(), and valid_exit().
02239 { 02240 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_CANMATCH); 02241 }
ast_change_hint: Change hint for an extension
Definition at line 2138 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_hint::exten, list, and ast_hint::next.
Referenced by ast_add_extension2().
02139 { 02140 struct ast_hint *list; 02141 02142 ast_mutex_lock(&hintlock); 02143 list = hints; 02144 02145 while(list) { 02146 if (list->exten == oe) { 02147 list->exten = ne; 02148 ast_mutex_unlock(&hintlock); 02149 return 0; 02150 } 02151 list = list->next; 02152 } 02153 ast_mutex_unlock(&hintlock); 02154 02155 return -1; 02156 }
| int ast_check_timing | ( | struct ast_timing * | i | ) |
Definition at line 4148 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 builtin_function_iftime(), include_valid(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
04149 { 04150 struct tm tm; 04151 time_t t; 04152 04153 time(&t); 04154 localtime_r(&t,&tm); 04155 04156 /* If it's not the right month, return */ 04157 if (!(i->monthmask & (1 << tm.tm_mon))) { 04158 return 0; 04159 } 04160 04161 /* If it's not that time of the month.... */ 04162 /* Warning, tm_mday has range 1..31! */ 04163 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04164 return 0; 04165 04166 /* If it's not the right day of the week */ 04167 if (!(i->dowmask & (1 << tm.tm_wday))) 04168 return 0; 04169 04170 /* Sanity check the hour just to be safe */ 04171 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04172 ast_log(LOG_WARNING, "Insane time...\n"); 04173 return 0; 04174 } 04175 04176 /* Now the tough part, we calculate if it fits 04177 in the right time based on min/hour */ 04178 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04179 return 0; 04180 04181 /* If we got this far, then we're good */ 04182 return 1; 04183 }
| int ast_context_add_ignorepat | ( | const char * | context, | |
| const char * | ignorepat, | |||
| const char * | registrar | |||
| ) |
Add an ignorepat
| 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. Returns 0 on success, -1 on failure |
Definition at line 4444 of file pbx.c.
References ast_context_add_ignorepat2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by handle_context_add_ignorepat().
04445 { 04446 struct ast_context *c; 04447 04448 if (ast_lock_contexts()) { 04449 errno = EBUSY; 04450 return -1; 04451 } 04452 04453 c = ast_walk_contexts(NULL); 04454 while (c) { 04455 if (!strcmp(ast_get_context_name(c), con)) { 04456 int ret = ast_context_add_ignorepat2(c, value, registrar); 04457 ast_unlock_contexts(); 04458 return ret; 04459 } 04460 c = ast_walk_contexts(c); 04461 } 04462 04463 ast_unlock_contexts(); 04464 errno = ENOENT; 04465 return -1; 04466 }
| int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
| const char * | value, | |||
| const char * | registrar | |||
| ) |
Definition at line 4468 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_context::ignorepats, ast_context::lock, LOG_ERROR, malloc, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.
Referenced by ast_context_add_ignorepat(), handle_context(), and pbx_load_module().
04469 { 04470 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04471 int length; 04472 length = sizeof(struct ast_ignorepat); 04473 length += strlen(value) + 1; 04474 ignorepat = malloc(length); 04475 if (!ignorepat) { 04476 ast_log(LOG_ERROR, "Out of memory\n"); 04477 errno = ENOMEM; 04478 return -1; 04479 } 04480 memset(ignorepat, 0, length); 04481 strcpy(ignorepat->pattern, value); 04482 ignorepat->next = NULL; 04483 ignorepat->registrar = registrar; 04484 ast_mutex_lock(&con->lock); 04485 ignorepatc = con->ignorepats; 04486 while(ignorepatc) { 04487 ignorepatl = ignorepatc; 04488 if (!strcasecmp(ignorepatc->pattern, value)) { 04489 /* Already there */ 04490 ast_mutex_unlock(&con->lock); 04491 errno = EEXIST; 04492 return -1; 04493 } 04494 ignorepatc = ignorepatc->next; 04495 } 04496 if (ignorepatl) 04497 ignorepatl->next = ignorepat; 04498 else 04499 con->ignorepats = ignorepat; 04500 ast_mutex_unlock(&con->lock); 04501 return 0; 04502 04503 }
| int ast_context_add_include | ( | const char * | context, | |
| const char * | include, | |||
| const char * | registrar | |||
| ) |
Add an include
| 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 Returns 0 on success, -1 on error |
Definition at line 3827 of file pbx.c.
References ast_context_add_include2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by handle_context_add_include().
03828 { 03829 struct ast_context *c; 03830 03831 if (ast_lock_contexts()) { 03832 errno = EBUSY; 03833 return -1; 03834 } 03835 03836 /* walk contexts ... */ 03837 c = ast_walk_contexts(NULL); 03838 while (c) { 03839 /* ... search for the right one ... */ 03840 if (!strcmp(ast_get_context_name(c), context)) { 03841 int ret = ast_context_add_include2(c, include, registrar); 03842 /* ... unlock contexts list and return */ 03843 ast_unlock_contexts(); 03844 return ret; 03845 } 03846 c = ast_walk_contexts(c); 03847 } 03848 03849 /* we can't find the right context */ 03850 ast_unlock_contexts(); 03851 errno = ENOENT; 03852 return -1; 03853 }
| int ast_context_add_include2 | ( | struct ast_context * | con, | |
| const char * | include, | |||
| const char * | registrar | |||
| ) |
Add an include
| 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 Returns 0 on success, -1 on failure |
Definition at line 4192 of file pbx.c.
References ast_build_timing(), ast_get_context_name(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, ast_include::hastime, ast_context::includes, ast_context::lock, LOG_ERROR, malloc, ast_include::name, ast_include::next, option_verbose, ast_include::registrar, ast_include::rname, ast_include::stuff, ast_include::timing, and VERBOSE_PREFIX_3.
Referenced by ast_context_add_include(), handle_context(), and pbx_load_module().
04194 { 04195 struct ast_include *new_include; 04196 char *c; 04197 struct ast_include *i, *il = NULL; /* include, include_last */ 04198 int length; 04199 char *p; 04200 04201 length = sizeof(struct ast_include); 04202 length += 2 * (strlen(value) + 1); 04203 04204 /* allocate new include structure ... */ 04205 if (!(new_include = malloc(length))) { 04206 ast_log(LOG_ERROR, "Out of memory\n"); 04207 errno = ENOMEM; 04208 return -1; 04209 } 04210 04211 /* ... fill in this structure ... */ 04212 memset(new_include, 0, length); 04213 p = new_include->stuff; 04214 new_include->name = p; 04215 strcpy(new_include->name, value); 04216 p += strlen(value) + 1; 04217 new_include->rname = p; 04218 strcpy(new_include->rname, value); 04219 c = new_include->rname; 04220 /* Strip off timing info */ 04221 while(*c && (*c != '|')) 04222 c++; 04223 /* Process if it's there */ 04224 if (*c) { 04225 new_include->hastime = ast_build_timing(&(new_include->timing), c+1); 04226 *c = '\0'; 04227 } 04228 new_include->next = NULL; 04229 new_include->registrar = registrar; 04230 04231 /* ... try to lock this context ... */ 04232 if (ast_mutex_lock(&con->lock)) { 04233 free(new_include); 04234 errno = EBUSY; 04235 return -1; 04236 } 04237 04238 /* ... go to last include and check if context is already included too... */ 04239 i = con->includes; 04240 while (i) { 04241 if (!strcasecmp(i->name, new_include->name)) { 04242 free(new_include); 04243 ast_mutex_unlock(&con->lock); 04244 errno = EEXIST; 04245 return -1; 04246 } 04247 il = i; 04248 i = i->next; 04249 } 04250 04251 /* ... include new context into context list, unlock, return */ 04252 if (il) 04253 il->next = new_include; 04254 else 04255 con->includes = new_include; 04256 if (option_verbose > 2) 04257 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04258 ast_mutex_unlock(&con->lock); 04259 04260 return 0; 04261 }
| int ast_context_add_switch | ( | const char * | context, | |
| const char * | sw, | |||
| const char * | data, | |||
| int | eval, | |||
| const char * | registrar | |||
| ) |
Add a switch
| 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 It returns 0 on success, -1 on failure |
Definition at line 4268 of file pbx.c.
References ast_context_add_switch2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
04269 { 04270 struct ast_context *c; 04271 04272 if (ast_lock_contexts()) { 04273 errno = EBUSY; 04274 return -1; 04275 } 04276 04277 /* walk contexts ... */ 04278 c = ast_walk_contexts(NULL); 04279 while (c) { 04280 /* ... search for the right one ... */ 04281 if (!strcmp(ast_get_context_name(c), context)) { 04282 int ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04283 /* ... unlock contexts list and return */ 04284 ast_unlock_contexts(); 04285 return ret; 04286 } 04287 c = ast_walk_contexts(c); 04288 } 04289 04290 /* we can't find the right context */ 04291 ast_unlock_contexts(); 04292 errno = ENOENT; 04293 return -1; 04294 }
| 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)
Definition at line 4303 of file pbx.c.
References ast_context::alts, ast_get_context_name(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_sw::data, ast_sw::eval, free, ast_context::lock, LOG_ERROR, malloc, ast_sw::name, ast_sw::next, option_verbose, ast_sw::registrar, ast_sw::stuff, SWITCH_DATA_LENGTH, ast_sw::tmpdata, and VERBOSE_PREFIX_3.
Referenced by ast_context_add_switch(), handle_context(), and pbx_load_module().
04305 { 04306 struct ast_sw *new_sw; 04307 struct ast_sw *i, *il = NULL; /* sw, sw_last */ 04308 int length; 04309 char *p; 04310 04311 length = sizeof(struct ast_sw); 04312 length += strlen(value) + 1; 04313 if (data) 04314 length += strlen(data); 04315 length++; 04316 if (eval) { 04317 /* Create buffer for evaluation of variables */ 04318 length += SWITCH_DATA_LENGTH; 04319 length++; 04320 } 04321 04322 /* allocate new sw structure ... */ 04323 if (!(new_sw = malloc(length))) { 04324 ast_log(LOG_ERROR, "Out of memory\n"); 04325 errno = ENOMEM; 04326 return -1; 04327 } 04328 04329 /* ... fill in this structure ... */ 04330 memset(new_sw, 0, length); 04331 p = new_sw->stuff; 04332 new_sw->name = p; 04333 strcpy(new_sw->name, value); 04334 p += strlen(value) + 1; 04335 new_sw->data = p; 04336 if (data) { 04337 strcpy(new_sw->data, data); 04338 p += strlen(data) + 1; 04339 } else { 04340 strcpy(new_sw->data, ""); 04341 p++; 04342 } 04343 if (eval) 04344 new_sw->tmpdata = p; 04345 new_sw->next = NULL; 04346 new_sw->eval = eval; 04347 new_sw->registrar = registrar; 04348 04349 /* ... try to lock this context ... */ 04350 if (ast_mutex_lock(&con->lock)) { 04351 free(new_sw); 04352 errno = EBUSY; 04353 return -1; 04354 } 04355 04356 /* ... go to last sw and check if context is already swd too... */ 04357 i = con->alts; 04358 while (i) { 04359 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04360 free(new_sw); 04361 ast_mutex_unlock(&con->lock); 04362 errno = EEXIST; 04363 return -1; 04364 } 04365 il = i; 04366 i = i->next; 04367 } 04368 04369 /* ... sw new context into context list, unlock, return */ 04370 if (il) 04371 il->next = new_sw; 04372 else 04373 con->alts = new_sw; 04374 if (option_verbose > 2) 04375 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04376 ast_mutex_unlock(&con->lock); 04377 04378 return 0; 04379 }
| struct ast_context* ast_context_create | ( | struct ast_context ** | extcontexts, | |
| const char * | name, | |||
| const char * | registrar | |||
| ) | [read] |
Register a new context
| 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. It returns NULL on failure, and an ast_context structure on success |
Definition at line 3662 of file pbx.c.
References ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_context::ignorepats, ast_context::includes, local_contexts, ast_context::lock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, ast_context::name, ast_context::next, option_debug, option_verbose, ast_context::registrar, ast_context::root, and VERBOSE_PREFIX_3.
Referenced by ast_park_call(), do_parking_thread(), handle_context(), handle_macro(), load_config(), pbx_load_module(), reload_config(), and set_config().
03663 { 03664 struct ast_context *tmp, **local_contexts; 03665 int length; 03666 length = sizeof(struct ast_context); 03667 length += strlen(name) + 1; 03668 if (!extcontexts) { 03669 local_contexts = &contexts; 03670 ast_mutex_lock(&conlock); 03671 } else 03672 local_contexts = extcontexts; 03673 03674 tmp = *local_contexts; 03675 while(tmp) { 03676 if (!strcasecmp(tmp->name, name)) { 03677 ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name); 03678 if (!extcontexts) 03679 ast_mutex_unlock(&conlock); 03680 return NULL; 03681 } 03682 tmp = tmp->next; 03683 } 03684 tmp = malloc(length); 03685 if (tmp) { 03686 memset(tmp, 0, length); 03687 ast_mutex_init(&tmp->lock); 03688 strcpy(tmp->name, name); 03689 tmp->root = NULL; 03690 tmp->registrar = registrar; 03691 tmp->next = *local_contexts; 03692 tmp->includes = NULL; 03693 tmp->ignorepats = NULL; 03694 *local_contexts = tmp; 03695 if (option_debug) 03696 ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name); 03697 if (option_verbose > 2) 03698 ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name); 03699 } else 03700 ast_log(LOG_ERROR, "Out of memory\n"); 03701 03702 if (!extcontexts) 03703 ast_mutex_unlock(&conlock); 03704 return tmp; 03705 }
| void ast_context_destroy | ( | struct ast_context * | con, | |
| const char * | registrar | |||
| ) |
Destroy a context (matches the specified context (or ANY context if NULL)
| 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 5414 of file pbx.c.
References __ast_context_destroy().
Referenced by ael_reload(), reload(), and unload_module().
05415 { 05416 __ast_context_destroy(con,registrar); 05417 }
| struct ast_context* ast_context_find | ( | const char * | name | ) | [read] |
Find a context
| 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 757 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_context::name, and ast_context::next.
Referenced by ast_context_verify_includes(), ast_ignore_pattern(), ast_park_call(), do_parking_thread(), load_config(), macro_exec(), park_exec(), reload_config(), and set_config().
00758 { 00759 struct ast_context *tmp; 00760 ast_mutex_lock(&conlock); 00761 if (name) { 00762 tmp = contexts; 00763 while(tmp) { 00764 if (!strcasecmp(name, tmp->name)) 00765 break; 00766 tmp = tmp->next; 00767 } 00768 } else 00769 tmp = contexts; 00770 ast_mutex_unlock(&conlock); 00771 return tmp; 00772 }
| int ast_context_remove_extension | ( | const char * | context, | |
| const char * | extension, | |||
| int | priority, | |||
| const char * | registrar | |||
| ) |
Simply remove extension from context
| 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. Returns 0 on success, -1 on failure |
Definition at line 2747 of file pbx.c.
References ast_context_remove_extension2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by handle_context_remove_extension(), and register_peer_exten().
02748 { 02749 struct ast_context *c; 02750 02751 if (ast_lock_contexts()) return -1; 02752 02753 /* walk contexts ... */ 02754 c = ast_walk_contexts(NULL); 02755 while (c) { 02756 /* ... search for the right one ... */ 02757 if (!strcmp(ast_get_context_name(c), context)) { 02758 /* ... remove extension ... */ 02759 int ret = ast_context_remove_extension2(c, extension, priority, 02760 registrar); 02761 /* ... unlock contexts list and return */ 02762 ast_unlock_contexts(); 02763 return ret; 02764 } 02765 c = ast_walk_contexts(c); 02766 } 02767 02768 /* we can't find the right context */ 02769 ast_unlock_contexts(); 02770 return -1; 02771 }
| 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.
Definition at line 2783 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_remove_hint(), ast_exten::data, ast_exten::datad, ast_exten::exten, exten, free, ast_context::lock, ast_exten::next, ast_exten::peer, ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, and ast_context::root.
Referenced by ast_context_remove_extension(), do_parking_thread(), load_config(), and park_exec().
02784 { 02785 struct ast_exten *exten, *prev_exten = NULL; 02786 02787 if (ast_mutex_lock(&con->lock)) return -1; 02788 02789 /* go through all extensions in context and search the right one ... */ 02790 exten = con->root; 02791 while (exten) { 02792 02793 /* look for right extension */ 02794 if (!strcmp(exten->exten, extension) && 02795 (!registrar || !strcmp(exten->registrar, registrar))) { 02796 struct ast_exten *peer; 02797 02798 /* should we free all peers in this extension? (priority == 0)? */ 02799 if (priority == 0) { 02800 /* remove this extension from context list */ 02801 if (prev_exten) 02802 prev_exten->next = exten->next; 02803 else 02804 con->root = exten->next; 02805 02806 /* fire out all peers */ 02807 peer = exten; 02808 while (peer) { 02809 exten = peer->peer; 02810 02811 if (!peer->priority==PRIORITY_HINT) 02812 ast_remove_hint(peer); 02813 02814 peer->datad(peer->data); 02815 free(peer); 02816 02817 peer = exten; 02818 } 02819 02820 ast_mutex_unlock(&con->lock); 02821 return 0; 02822 } else { 02823 /* remove only extension with exten->priority == priority */ 02824 struct ast_exten *previous_peer = NULL; 02825 02826 peer = exten; 02827 while (peer) { 02828 /* is this our extension? */ 02829 if (peer->priority == priority && 02830 (!registrar || !strcmp(peer->registrar, registrar) )) { 02831 /* we are first priority extension? */ 02832 if (!previous_peer) { 02833 /* exists previous extension here? */ 02834 if (prev_exten) { 02835 /* yes, so we must change next pointer in 02836 * previous connection to next peer 02837 */ 02838 if (peer->peer) { 02839 prev_exten->next = peer->peer; 02840 peer->peer->next = exten->next; 02841 } else 02842 prev_exten->next = exten->next; 02843 } else { 02844 /* no previous extension, we are first 02845 * extension, so change con->root ... 02846 */ 02847 if (peer->peer) 02848 con->root = peer->peer; 02849 else 02850 con->root = exten->next; 02851 } 02852 } else { 02853 /* we are not first priority in extension */ 02854 previous_peer->peer = peer->peer; 02855 } 02856 02857 /* now, free whole priority extension */ 02858 if (peer->priority==PRIORITY_HINT) 02859 ast_remove_hint(peer); 02860 peer->datad(peer->data); 02861 free(peer); 02862 02863 ast_mutex_unlock(&con->lock); 02864 return 0; 02865 } else { 02866 /* this is not right extension, skip to next peer */ 02867 previous_peer = peer; 02868 peer = peer->peer; 02869 } 02870 } 02871 02872 ast_mutex_unlock(&con->lock); 02873 return -1; 02874 } 02875 } 02876 02877 prev_exten = exten; 02878 exten = exten->next; 02879 } 02880 02881 /* we can't find right extension */ 02882 ast_mutex_unlock(&con->lock); 02883 return -1; 02884 }
| int ast_context_remove_ignorepat | ( | const char * | context, | |
| const char * | ignorepat, | |||
| const char * | registrar | |||
| ) |
| context | context from which to remove the pattern | |
| ignorepat | the pattern to remove | |
| registrar | the registrar of the ignore pattern This removes the given ignorepattern Returns 0 on success, -1 on failure |
Definition at line 4385 of file pbx.c.
References ast_context_remove_ignorepat2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by handle_context_remove_ignorepat().
04386 { 04387 struct ast_context *c; 04388 04389 if (ast_lock_contexts()) { 04390 errno = EBUSY; 04391 return -1; 04392 } 04393 04394 c = ast_walk_contexts(NULL); 04395 while (c) { 04396 if (!strcmp(ast_get_context_name(c), context)) { 04397 int ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04398 ast_unlock_contexts(); 04399 return ret; 04400 } 04401 c = ast_walk_contexts(c); 04402 } 04403 04404 ast_unlock_contexts(); 04405 errno = ENOENT; 04406 return -1; 04407 }
| int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
| const char * | ignorepat, | |||
| const char * | registrar | |||
| ) |
Definition at line 4409 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().
04410 { 04411 struct ast_ignorepat *ip, *ipl = NULL; 04412 04413 if (ast_mutex_lock(&con->lock)) { 04414 errno = EBUSY; 04415 return -1; 04416 } 04417 04418 ip = con->ignorepats; 04419 while (ip) { 04420 if (!strcmp(ip->pattern, ignorepat) && 04421 (!registrar || (registrar == ip->registrar))) { 04422 if (ipl) { 04423 ipl->next = ip->next; 04424 free(ip); 04425 } else { 04426 con->ignorepats = ip->next; 04427 free(ip); 04428 } 04429 ast_mutex_unlock(&con->lock); 04430 return 0; 04431 } 04432 ipl = ip; ip = ip->next; 04433 } 04434 04435 ast_mutex_unlock(&con->lock); 04436 errno = EINVAL; 04437 return -1; 04438 }
| int ast_context_remove_include | ( | const char * | context, | |
| const char * | include, | |||
| const char * | registrar | |||
| ) |
Removes an include
See add_include
Definition at line 2603 of file pbx.c.
References ast_context_remove_include2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by handle_context_dont_include().
02604 { 02605 struct ast_context *c; 02606 02607 if (ast_lock_contexts()) return -1; 02608 02609 /* walk contexts and search for the right one ...*/ 02610 c = ast_walk_contexts(NULL); 02611 while (c) { 02612 /* we found one ... */ 02613 if (!strcmp(ast_get_context_name(c), context)) { 02614 int ret; 02615 /* remove include from this context ... */ 02616 ret = ast_context_remove_include2(c, include, registrar); 02617 02618 ast_unlock_contexts(); 02619 02620 /* ... return results */ 02621 return ret; 02622 } 02623 c = ast_walk_contexts(c); 02624 } 02625 02626 /* we can't find the right one context */ 02627 ast_unlock_contexts(); 02628 return -1; 02629 }
| int ast_context_remove_include2 | ( | struct ast_context * | con, | |
| const char * | include, | |||
| const char * | registrar | |||
| ) |
Removes an include by an ast_context structure
See add_include2
Definition at line 2639 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().
02640 { 02641 struct ast_include *i, *pi = NULL; 02642 02643 if (ast_mutex_lock(&con->lock)) return -1; 02644 02645 /* walk includes */ 02646 i = con->includes; 02647 while (i) { 02648 /* find our include */ 02649 if (!strcmp(i->name, include) && 02650 (!registrar || !strcmp(i->registrar, registrar))) { 02651 /* remove from list */ 02652 if (pi) 02653 pi->next = i->next; 02654 else 02655 con->includes = i->next; 02656 /* free include and return */ 02657 free(i); 02658 ast_mutex_unlock(&con->lock); 02659 return 0; 02660 } 02661 pi = i; 02662 i = i->next; 02663 } 02664 02665 /* we can't find the right include */ 02666 ast_mutex_unlock(&con->lock); 02667 return -1; 02668 }
| int ast_context_remove_switch | ( | const char * | context, | |
| const char * | sw, | |||
| const char * | data, | |||
| const char * | registrar | |||
| ) |
Definition at line 2675 of file pbx.c.
References ast_context_remove_switch2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
02676 { 02677 struct ast_context *c; 02678 02679 if (ast_lock_contexts()) return -1; 02680 02681 /* walk contexts and search for the right one ...*/ 02682 c = ast_walk_contexts(NULL); 02683 while (c) { 02684 /* we found one ... */ 02685 if (!strcmp(ast_get_context_name(c), context)) { 02686 int ret; 02687 /* remove switch from this context ... */ 02688 ret = ast_context_remove_switch2(c, sw, data, registrar); 02689 02690 ast_unlock_contexts(); 02691 02692 /* ... return results */ 02693 return ret; 02694 } 02695 c = ast_walk_contexts(c); 02696 } 02697 02698 /* we can't find the right one context */ 02699 ast_unlock_contexts(); 02700 return -1; 02701 }
| 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.
Definition at line 2711 of file pbx.c.
References ast_context::alts, ast_mutex_lock(), ast_mutex_unlock(), ast_sw::data, free, ast_context::lock, ast_sw::name, ast_sw::next, and ast_sw::registrar.
Referenced by ast_context_remove_switch().
02712 { 02713 struct ast_sw *i, *pi = NULL; 02714 02715 if (ast_mutex_lock(&con->lock)) return -1; 02716 02717 /* walk switchs */ 02718 i = con->alts; 02719 while (i) { 02720 /* find our switch */ 02721 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02722 (!registrar || !strcmp(i->registrar, registrar))) { 02723 /* remove from list */ 02724 if (pi) 02725 pi->next = i->next; 02726 else 02727 con->alts = i->next; 02728 /* free switch and return */ 02729 free(i); 02730 ast_mutex_unlock(&con->lock); 02731 return 0; 02732 } 02733 pi = i; 02734 i = i->next; 02735 } 02736 02737 /* we can't find the right switch */ 02738 ast_mutex_unlock(&con->lock); 02739 return -1; 02740 }
| int ast_context_verify_includes | ( | struct ast_context * | con | ) |
Verifies includes in an ast_contect structure
| con | context in which to verify the includes Returns 0 if no problems found, -1 if there were any missing context |
Definition at line 6463 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().
06464 { 06465 struct ast_include *inc; 06466 int res = 0; 06467 06468 for (inc = ast_walk_context_includes(con, NULL); inc; inc = ast_walk_context_includes(con, inc)) 06469 if (!ast_context_find(inc->rname)) { 06470 res = -1; 06471 ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n", 06472 ast_get_context_name(con), inc->rname); 06473 } 06474 return res; 06475 }
| struct ast_custom_function* ast_custom_function_find | ( | char * | name | ) | [read] |
Definition at line 1287 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, ast_custom_function::name, and ast_custom_function::next.
Referenced by ast_custom_function_register(), ast_func_read(), ast_func_write(), and handle_show_function().
01288 { 01289 struct ast_custom_function *acfptr; 01290 01291 /* try to lock functions list ... */ 01292 if (ast_mutex_lock(&acflock)) { 01293 ast_log(LOG_ERROR, "Unable to lock function list\n"); 01294 return NULL; 01295 } 01296 01297 for (acfptr = acf_root; acfptr; acfptr = acfptr->next) { 01298 if (!strcmp(name, acfptr->name)) { 01299 break; 01300 } 01301 } 01302 01303 ast_mutex_unlock(&acflock); 01304 01305 return acfptr; 01306 }
| int ast_custom_function_register | ( | struct ast_custom_function * | acf | ) |
Definition at line 1343 of file pbx.c.
References ast_custom_function_find(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), LOG_ERROR, ast_custom_function::name, ast_custom_function::next, option_verbose, and VERBOSE_PREFIX_2.
Referenced by load_module().
01344 { 01345 if (!acf) 01346 return -1; 01347 01348 /* try to lock functions list ... */ 01349 if (ast_mutex_lock(&acflock)) { 01350 ast_log(LOG_ERROR, "Unable to lock function list. Failed registering function %s\n", acf->name); 01351 return -1; 01352 } 01353 01354 if (ast_custom_function_find(acf->name)) { 01355 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01356 ast_mutex_unlock(&acflock); 01357 return -1; 01358 } 01359 01360 acf->next = acf_root; 01361 acf_root = acf; 01362 01363 ast_mutex_unlock(&acflock); 01364 01365 if (option_verbose > 1) 01366 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01367 01368 return 0; 01369 }
| int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Definition at line 1308 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), LOG_ERROR, ast_custom_function::name, ast_custom_function::next, option_verbose, and VERBOSE_PREFIX_2.
Referenced by unload_module().
01309 { 01310 struct ast_custom_function *acfptr, *lastacf = NULL; 01311 int res = -1; 01312 01313 if (!acf) 01314 return -1; 01315 01316 /* try to lock functions list ... */ 01317 if (ast_mutex_lock(&acflock)) { 01318 ast_log(LOG_ERROR, "Unable to lock function list\n"); 01319 return -1; 01320 } 01321 01322 for (acfptr = acf_root; acfptr; acfptr = acfptr->next) { 01323 if (acfptr == acf) { 01324 if (lastacf) { 01325 lastacf->next = acf->next; 01326 } else { 01327 acf_root = acf->next; 01328 } 01329 res = 0; 01330 break; 01331 } 01332 lastacf = acfptr; 01333 } 01334 01335 ast_mutex_unlock(&acflock); 01336 01337 if (!res && (option_verbose > 1)) 01338 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01339 01340 return res; 01341 }
| int ast_exec_extension | ( | struct ast_channel * | c, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| const char * | callerid | |||
| ) |
Execute an extension.
| c | channel to execute upon | |
| context | which context extension is in | |
| exten | extension to execute | |
| priority | priority to execute within the given extension | |
| callerid | Caller-ID If it's not available, do whatever you should do for default extensions and halt the thread if necessary. This function does not return, except on error. |
Definition at line 2253 of file pbx.c.
References HELPER_EXEC, and pbx_extension_helper().
Referenced by loopback_exec().
02254 { 02255 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_EXEC); 02256 }
| int ast_exists_extension | ( | struct ast_channel * | c, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| const char * | callerid | |||
| ) |
If an extension exists, return non-zero
| 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 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 2223 of file pbx.c.
References HELPER_EXISTS, and pbx_extension_helper().
Referenced by __ast_goto_if_exists(), __ast_pbx_run(), __login_exec(), agentmonitoroutgoing_exec(), ast_app_dtget(), ast_pbx_outgoing_exten(), ast_waitstream_exten(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), console_dial(), console_transfer(), disa_exec(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), i4l_read(), leave_voicemail(), local_alloc(), loopback_exists(), macro_exec(), mgcp_ss(), misdn_overlap_dial_task(), monitor_handle_notowned(), monitor_handle_owned(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), process_ast_dsp(), register_peer_exten(), rpt(), rpt_exec(), skinny_ss(), socket_read(), ss_thread(), and zt_handle_dtmfup().
02224 { 02225 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_EXISTS); 02226 }
| int ast_explicit_goto | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 4553 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().
04554 { 04555 if (!chan) 04556 return -1; 04557 04558 if (!ast_strlen_zero(context)) 04559 ast_copy_string(chan->context, context, sizeof(chan->context)); 04560 if (!ast_strlen_zero(exten)) 04561 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04562 if (priority > -1) { 04563 chan->priority = priority; 04564 /* see flag description in channel.h for explanation */ 04565 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04566 chan->priority--; 04567 } 04568 04569 return 0; 04570 }
| int ast_extension_close | ( | const char * | pattern, | |
| const char * | data, | |||
| int | needmore | |||
| ) |
Definition at line 736 of file pbx.c.
References ast_strlen_zero(), EXTENSION_MATCH_CORE, and match().
Referenced by pbx_find_extension(), and realtime_switch_common().
00737 { 00738 int match; 00739 /* If "data" is longer, it can'be a subset of pattern unless 00740 pattern is a pattern match */ 00741 if ((strlen(pattern) < strlen(data)) && (pattern[0] != '_')) 00742 return 0; 00743 00744 if ((ast_strlen_zero((char *)data) || !strncasecmp(pattern, data, strlen(data))) && 00745 (!needmore || (strlen(pattern) > strlen(data)))) { 00746 return 1; 00747 } 00748 EXTENSION_MATCH_CORE(data,pattern,match); 00749 /* If there's more or we don't care about more, or if it's a possible early match, 00750 return non-zero; otherwise it's a miss */ 00751 if (!needmore || *pattern || match == 2) { 00752 return match; 00753 } else 00754 return 0; 00755 }
| int ast_extension_match | ( | const char * | pattern, | |
| const char * | extension | |||
| ) |
Determine if a given extension matches a given pattern (in NXX format)
| pattern | pattern to match | |
| extension | extension to check against the pattern. Checks whether or not the given extension matches the given pattern. Returns 1 on match, 0 on failure |
Definition at line 723 of file pbx.c.
References EXTENSION_MATCH_CORE, and match().
Referenced by ast_ignore_pattern(), find_matching_priority(), loopback_canmatch(), loopback_exec(), loopback_exists(), loopback_matchmore(), matchcid(), misdn_cfg_is_msn_valid(), pbx_find_extension(), realtime_switch_common(), and show_dialplan_helper().
00724 { 00725 int match; 00726 /* If they're the same return */ 00727 if (!strcmp(pattern, data)) 00728 return 1; 00729 EXTENSION_MATCH_CORE(data,pattern,match); 00730 /* Must be at the end of both */ 00731 if (*data || (*pattern && (*pattern != '/'))) 00732 match = 0; 00733 return match; 00734 }
| int ast_extension_state | ( | struct ast_channel * | c, | |
| char * | context, | |||
| char * | exten | |||
| ) |
ast_extension_state: Check extension state for an extension by using hint
Uses hint and devicestate callback to get the state of an extension
| c | this is not important | |
| context | which context to look in | |
| exten | which extension to get state Returns extension state !! = AST_EXTENSION_??? |
Definition at line 1895 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), and handle_request_subscribe().
01896 { 01897 struct ast_exten *e; 01898 01899 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 01900 if (!e) 01901 return -1; /* No hint, return -1 */ 01902 01903 return ast_extension_state2(e); /* Check all devices in the hint */ 01904 }
| static int ast_extension_state2 | ( | struct ast_exten * | e | ) | [static] |
ast_extensions_state2: Check state of extension by using hints
Definition at line 1808 of file pbx.c.
References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_RINGING, ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_extension_app(), AST_MAX_EXTENSION, inuse, and ring().
Referenced by ast_add_hint(), ast_extension_state(), and ast_hint_state_changed().
01809 { 01810 char hint[AST_MAX_EXTENSION] = ""; 01811 char *cur, *rest; 01812 int res = -1; 01813 int allunavailable = 1, allbusy = 1, allfree = 1; 01814 int busy = 0, inuse = 0, ring = 0; 01815 01816 if (!e) 01817 return -1; 01818 01819 ast_copy_string(hint, ast_get_extension_app(e), sizeof(hint)); 01820 01821 cur = hint; /* On or more devices separated with a & character */ 01822 do { 01823 rest = strchr(cur, '&'); 01824 if (rest) { 01825 *rest = 0; 01826 rest++; 01827 } 01828 01829 res = ast_device_state(cur); 01830 switch (res) { 01831 case AST_DEVICE_NOT_INUSE: 01832 allunavailable = 0; 01833 allbusy = 0; 01834 break; 01835 case AST_DEVICE_INUSE: 01836 inuse = 1; 01837 allunavailable = 0; 01838 allfree = 0; 01839 break; 01840 case AST_DEVICE_RINGING: 01841 ring = 1; 01842 allunavailable = 0; 01843 allfree = 0; 01844 break; 01845 case AST_DEVICE_BUSY: 01846 allunavailable = 0; 01847 allfree = 0; 01848 busy = 1; 01849 break; 01850 case AST_DEVICE_UNAVAILABLE: 01851 case AST_DEVICE_INVALID: 01852 allbusy = 0; 01853 allfree = 0; 01854 break; 01855 default: 01856 allunavailable = 0; 01857 allbusy = 0; 01858 allfree = 0; 01859 } 01860 cur = rest; 01861 } while (cur); 01862 01863 if (!inuse && ring) 01864 return AST_EXTENSION_RINGING; 01865 if (inuse && ring) 01866 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING); 01867 if (inuse) 01868 return AST_EXTENSION_INUSE; 01869 if (allfree) 01870 return AST_EXTENSION_NOT_INUSE; 01871 if (allbusy) 01872 return AST_EXTENSION_BUSY; 01873 if (allunavailable) 01874 return AST_EXTENSION_UNAVAILABLE; 01875 if (busy) 01876 return AST_EXTENSION_INUSE; 01877 01878 return AST_EXTENSION_NOT_INUSE; 01879 }
| const char* ast_extension_state2str | ( | int | extension_state | ) |
ast_extension_state2str: Return extension_state as string
Return string of the state of an extension
| extension_state | is the numerical state delivered by ast_extension_state Returns the state of an extension as string |
Definition at line 1882 of file pbx.c.
References extension_states, and cfextension_states::text.
Referenced by __sip_show_channels(), cb_extensionstate(), handle_request_subscribe(), and handle_show_hints().
01883 { 01884 int i; 01885 01886 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 01887 if (extension_states[i].extension_state == extension_state) { 01888 return extension_states[i].text; 01889 } 01890 } 01891 return "Unknown"; 01892 }
| int ast_extension_state_add | ( | const char * | context, | |
| const char * | exten, | |||
| ast_state_cb_type | callback, | |||
| void * | data | |||
| ) |
ast_extension_state_add: Add watcher for extension states
Registers a state change callback
| 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 for extension is changed Return -1 on failure, ID on success |
Definition at line 1949 of file pbx.c.
References ast_hint_extension(), ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_hint::exten, ast_state_cb::id, list, malloc, ast_hint::next, and ast_state_cb::next.
Referenced by handle_request_subscribe(), and init_manager().
01951 { 01952 struct ast_hint *list; 01953 struct ast_state_cb *cblist; 01954 struct ast_exten *e; 01955 01956 /* If there's no context and extension: add callback to statecbs list */ 01957 if (!context && !exten) { 01958 ast_mutex_lock(&hintlock); 01959 01960 cblist = statecbs; 01961 while (cblist) { 01962 if (cblist->callback == callback) { 01963 cblist->data = data; 01964 ast_mutex_unlock(&hintlock); 01965 return 0; 01966 } 01967 cblist = cblist->next; 01968 } 01969 01970 /* Now insert the callback */ 01971 cblist = malloc(sizeof(struct ast_state_cb)); 01972 if (!cblist) { 01973 ast_mutex_unlock(&hintlock); 01974 return -1; 01975 } 01976 memset(cblist, 0, sizeof(struct ast_state_cb)); 01977 cblist->id = 0; 01978 cblist->callback = callback; 01979 cblist->data = data; 01980 01981 cblist->next = statecbs; 01982 statecbs = cblist; 01983 01984 ast_mutex_unlock(&hintlock); 01985 return 0; 01986 } 01987 01988 if (!context || !exten) 01989 return -1; 01990 01991 /* This callback type is for only one hint, so get the hint */ 01992 e = ast_hint_extension(NULL, context, exten); 01993 if (!e) { 01994 return -1; 01995 } 01996 01997 /* Find the hint in the list of hints */ 01998 ast_mutex_lock(&hintlock); 01999 list = hints; 02000 02001 while (list) { 02002 if (list->exten == e) 02003 break; 02004 list = list->next; 02005 } 02006 02007 if (!list) { 02008 /* We have no hint, sorry */ 02009 ast_mutex_unlock(&hintlock); 02010 return -1; 02011 } 02012 02013 /* Now insert the callback in the callback list */ 02014 cblist = malloc(sizeof(struct ast_state_cb)); 02015 if (!cblist) { 02016 ast_mutex_unlock(&hintlock); 02017 return -1; 02018 } 02019 memset(cblist, 0, sizeof(struct ast_state_cb)); 02020 cblist->id = stateid++; /* Unique ID for this callback */ 02021 cblist->callback = callback; /* Pointer to callback routine */ 02022 cblist->data = data; /* Data for the callback */ 02023 02024 cblist->next = list->callbacks; 02025 list->callbacks = cblist; 02026 02027 ast_mutex_unlock(&hintlock); 02028 return cblist->id; 02029 }
| int ast_extension_state_del | ( | int | id, | |
| ast_state_cb_type | callback | |||
| ) |
ast_extension_state_del: Remove a watcher from the callback list
Deletes a registered state change callback by ID
| id | of the callback to delete | |
| callback | callback Removes the callback from list of callbacks Return 0 on success, -1 on failure |
Definition at line 2032 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_hint::callbacks, free, ast_state_cb::id, list, ast_hint::next, and ast_state_cb::next.
Referenced by __sip_destroy(), and handle_request_subscribe().
02033 { 02034 struct ast_hint *list; 02035 struct ast_state_cb *cblist, *cbprev; 02036 02037 if (!id && !callback) 02038 return -1; 02039 02040 ast_mutex_lock(&hintlock); 02041 02042 /* id is zero is a callback without extension */ 02043 if (!id) { 02044 cbprev = NULL; 02045 cblist = statecbs; 02046 while (cblist) { 02047 if (cblist->callback == callback) { 02048 if (!cbprev) 02049 statecbs = cblist->next; 02050 else 02051 cbprev->next = cblist->next; 02052 02053 free(cblist); 02054 02055 ast_mutex_unlock(&hintlock); 02056 return 0; 02057 } 02058 cbprev = cblist; 02059 cblist = cblist->next; 02060 } 02061 02062 ast_mutex_unlock(&hintlock); 02063 return -1; 02064 } 02065 02066 /* id greater than zero is a callback with extension */ 02067 /* Find the callback based on ID */ 02068 list = hints; 02069 while (list) { 02070 cblist = list->callbacks; 02071 cbprev = NULL; 02072 while (cblist) { 02073 if (cblist->id==id) { 02074 if (!cbprev) 02075 list->callbacks = cblist->next; 02076 else 02077 cbprev->next = cblist->next; 02078 02079 free(cblist); 02080 02081 ast_mutex_unlock(&hintlock); 02082 return 0; 02083 } 02084 cbprev = cblist; 02085 cblist = cblist->next; 02086 } 02087 list = list->next; 02088 } 02089 02090 ast_mutex_unlock(&hintlock); 02091 return -1; 02092 }
| int ast_findlabel_extension | ( | struct ast_channel * | c, | |
| const char * | context, | |||
| const char * | exten, | |||
| const char * | label, | |||
| const char * | callerid | |||
| ) |
If an extension exists, return non-zero
| 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 If an priority which matches given label in extension or -1 if not found. \ |
Definition at line 2228 of file pbx.c.
References HELPER_FINDLABEL, and pbx_extension_helper().
Referenced by ast_parseable_goto(), and handle_setpriority().
02229 { 02230 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, HELPER_FINDLABEL); 02231 }
| int ast_findlabel_extension2 | ( | struct ast_channel * | c, | |
| struct ast_context * | con, | |||
| const char * | exten, | |||
| const char * | label, | |||
| const char * | callerid | |||
| ) |
Definition at line 2233 of file pbx.c.
References HELPER_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_module().
02234 { 02235 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, HELPER_FINDLABEL); 02236 }
| char* ast_func_read | ( | struct ast_channel * | chan, | |
| const char * | in, | |||
| char * | workspace, | |||
| size_t | len | |||
| ) |
executes a read operation on a function
| chan | Channel to execute on | |
| in | Data containing the function call string | |
| workspace | A pointer to safe memory to use for a return value | |
| len | the number of bytes in workspace This application executes an function in read mode on a given channel. It returns a pointer to workspace if the buffer contains any new data or NULL if there was a problem. |
Definition at line 1371 of file pbx.c.
References ast_custom_function_find(), ast_log(), ast_strdupa, LOG_ERROR, LOG_WARNING, and ast_custom_function::read.
Referenced by handle_getvariable(), and pbx_substitute_variables_helper_full().
01372 { 01373 char *args = NULL, *function, *p; 01374 char *ret = "0"; 01375 struct ast_custom_function *acfptr; 01376 01377 function = ast_strdupa(in); 01378 if (!function) { 01379 ast_log(LOG_ERROR, "Out of memory\n"); 01380 return ret; 01381 } 01382 if ((args = strchr(function, '('))) { 01383 *args = '\0'; 01384 args++; 01385 if ((p = strrchr(args, ')'))) { 01386 *p = '\0'; 01387 } else { 01388 ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n"); 01389 } 01390 } else { 01391 ast_log(LOG_WARNING, "Function doesn't contain parentheses. Assuming null argument.\n"); 01392 } 01393 01394 if ((acfptr = ast_custom_function_find(function))) { 01395 /* run the custom function */ 01396 if (acfptr->read) { 01397 return acfptr->read(chan, function, args, workspace, len); 01398 } else { 01399 ast_log(LOG_ERROR, "Function %s cannot be read\n", function); 01400 } 01401 } else { 01402 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01403 } 01404 return ret; 01405 }
| void ast_func_write | ( | struct ast_channel * | chan, | |
| const char * | in, | |||
| const char * | value | |||
| ) |
executes a write operation on a function
| chan | Channel to execute on | |
| in | Data containing the function call string | |
| value | A value parameter to pass for writing This application executes an function in write mode on a given channel. It has no return value. |
Definition at line 1407 of file pbx.c.
References ast_custom_function_find(), ast_log(), ast_strdupa, LOG_ERROR, LOG_WARNING, and ast_custom_function::write.
Referenced by pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().
01408 { 01409 char *args = NULL, *function, *p; 01410 struct ast_custom_function *acfptr; 01411 01412 function = ast_strdupa(in); 01413 if (!function) { 01414 ast_log(LOG_ERROR, "Out of memory\n"); 01415 return; 01416 } 01417 if ((args = strchr(function, '('))) { 01418 *args = '\0'; 01419 args++; 01420 if ((p = strrchr(args, ')'))) { 01421 *p = '\0'; 01422 } else { 01423 ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n"); 01424 } 01425 } else { 01426 ast_log(LOG_WARNING, "Function doesn't contain parentheses. Assuming null argument.\n"); 01427 } 01428 01429 if ((acfptr = ast_custom_function_find(function))) { 01430 /* run the custom function */ 01431 if (acfptr->write) { 01432 acfptr->write(chan, function, args, value); 01433 } else { 01434 ast_log(LOG_ERROR, "Function %s is read-only, it cannot be written to\n", function); 01435 } 01436 } else { 01437 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01438 } 01439 }
| const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 6319 of file pbx.c.
References ast_context::name.
Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_include2(), ast_context_add_switch(), ast_context_add_switch2(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_verify_includes(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_show_dialplan_context(), dundi_precache_full(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), macro_exec(), and show_dialplan_helper().
06320 { 06321 return con ? con->name : NULL; 06322 }
| const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 6352 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06353 { 06354 return c ? c->registrar : NULL; 06355 }
| const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6382 of file pbx.c.
References ast_exten::app.
Referenced by ast_add_hint(), ast_extension_state2(), ast_get_hint(), ast_hint_state_changed(), find_matching_endwhile(), handle_save_dialplan(), handle_show_hints(), macro_exec(), and show_dialplan_helper().
06383 { 06384 return e ? e->app : NULL; 06385 }
| void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6387 of file pbx.c.
References ast_exten::data.
Referenced by ast_get_hint(), handle_save_dialplan(), macro_exec(), and show_dialplan_helper().
06388 { 06389 return e ? e->data : NULL; 06390 }
| const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6377 of file pbx.c.
References ast_exten::cidmatch.
Referenced by find_matching_priority(), and handle_save_dialplan().
06378 { 06379 return e ? e->cidmatch : NULL; 06380 }
| const char* ast_get_extension_label | ( | struct ast_exten * | exten | ) |
Definition at line 6329 of file pbx.c.
References ast_exten::label.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06330 { 06331 return exten ? exten->label : NULL; 06332 }
| int ast_get_extension_matchcid | ( | struct ast_exten * | e | ) |
Definition at line 6372 of file pbx.c.
References ast_exten::matchcid.
Referenced by find_matching_priority(), and handle_save_dialplan().
06373 { 06374 return e ? e->matchcid : 0; 06375 }
| const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6324 of file pbx.c.
References ast_exten::exten.
Referenced by ast_add_hint(), complete_context_remove_extension(), dundi_precache_full(), find_matching_priority(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper().
06325 { 06326 return exten ? exten->exten : NULL; 06327 }
| int ast_get_extension_priority | ( | struct ast_exten * | exten | ) |
Definition at line 6344 of file pbx.c.
References ast_exten::priority.
Referenced by complete_context_remove_extension(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper().
06345 { 06346 return exten ? exten->priority : -1; 06347 }
| const char* ast_get_extension_registrar | ( | struct ast_exten * | e | ) |
Definition at line 6357 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06358 { 06359 return e ? e->registrar : NULL; 06360 }
| int ast_get_hint | ( | char * | hint, | |
| int | maxlen, | |||
| char * | name, | |||
| int | maxnamelen, | |||
| struct ast_channel * | c, | |||
| const char * | context, | |||
| const char * | exten | |||
| ) |
ast_get_hint: Get hint for channel
If an extension exists, return non-zero
| 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 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 2204 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().
02205 { 02206 struct ast_exten *e; 02207 void *tmp; 02208 02209 e = ast_hint_extension(c, context, exten); 02210 if (e) { 02211 if (hint) 02212 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02213 if (name) { 02214 tmp = ast_get_extension_app_data(e); 02215 if (tmp) 02216 ast_copy_string(name, (char *) tmp, namesize); 02217 } 02218 return -1; 02219 } 02220 return 0; 02221 }
| const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6339 of file pbx.c.
References ast_ignorepat::pattern.
Referenced by complete_context_add_ignorepat(), complete_context_remove_ignorepat(), handle_save_dialplan(), and show_dialplan_helper().
06340 { 06341 return ip ? ip->pattern : NULL; 06342 }
| const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6367 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06368 { 06369 return ip ? ip->registrar : NULL; 06370 }
| const char* ast_get_include_name | ( | struct ast_include * | inc | ) |
Definition at line 6334 of file pbx.c.
References ast_include::name.
Referenced by complete_context_add_include(), complete_context_dont_include(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper().
06335 { 06336 return inc ? inc->name : NULL; 06337 }
| const char* ast_get_include_registrar | ( | struct ast_include * | i | ) |
Definition at line 6362 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06363 { 06364 return i ? i->registrar : NULL; 06365 }
| const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6397 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06398 { 06399 return sw ? sw->data : NULL; 06400 }
| const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6392 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06393 { 06394 return sw ? sw->name : NULL; 06395 }
| const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6402 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06403 { 06404 return sw ? sw->registrar : NULL; 06405 }
| int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
| char * | context, | |||
| char * | exten, | |||
| int | priority | |||
| ) |
Definition at line 6495 of file pbx.c.
References __ast_goto_if_exists().
Referenced by aqm_exec(), auth_exec(), background_detect_exec(), chanavail_exec(), conf_run(), controlplayback_exec(), dial_exec_full(), do_directory(), dundi_lookup_exec(), enumlookup_exec(), get_exec(), group_check_exec(), hasvoicemail_exec(), leave_voicemail(), lookupblacklist_exec(), md5check_exec(), onedigit_goto(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), play_mailbox_owner(), playback_exec(), pqm_exec(), privacy_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), sip_getheader(), system_exec_helper(), transfer_exec(), txtcidname_exec(), upqm_exec(), valid_exit(), vm_box_exists(), vm_exec(), and wait_for_answer().
06495 { 06496 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06497 }
| static struct ast_exten* ast_hint_extension | ( | struct ast_channel * | c, | |
| const char * | context, | |||
| const char * | exten | |||
| ) | [static, read] |
ast_hint_extension: Find hint for given extension in context
Definition at line 1788 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PBX_MAX_STACK, HELPER_EXISTS, LOG_WARNING, pbx_find_extension(), and PRIORITY_HINT.
Referenced by ast_extension_state(), ast_extension_state_add(), ast_get_hint(), and ast_merge_contexts_and_delete().
01789 { 01790 struct ast_exten *e; 01791 struct ast_switch *sw; 01792 char *data; 01793 const char *foundcontext = NULL; 01794 int status = 0; 01795 char *incstack[AST_PBX_MAX_STACK]; 01796 int stacklen = 0; 01797 01798 if (ast_mutex_lock(&conlock)) { 01799 ast_log(LOG_WARNING, "Unable to obtain lock\n"); 01800 return NULL; 01801 } 01802 e = pbx_find_extension(c, NULL, context, exten, PRIORITY_HINT, NULL, "", HELPER_EXISTS, incstack, &stacklen, &status, &sw, &data, &foundcontext); 01803 ast_mutex_unlock(&conlock); 01804 return e; 01805 }
| void ast_hint_state_changed | ( | const char * | device | ) |
Definition at line 1906 of file pbx.c.
References ast_extension_state2(), ast_get_extension_app(), AST_MAX_EXTENSION, ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_exten::exten, ast_hint::exten, ast_hint::laststate, ast_context::name, ast_state_cb::next, ast_hint::next, ast_exten::parent, parse(), and strsep().
Referenced by do_state_change().
01907 { 01908 struct ast_hint *hint; 01909 struct ast_state_cb *cblist; 01910 char buf[AST_MAX_EXTENSION]; 01911 char *parse; 01912 char *cur; 01913 int state; 01914 01915 ast_mutex_lock(&hintlock); 01916 01917 for (hint = hints; hint; hint = hint->next) { 01918 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 01919 parse = buf; 01920 for (cur = strsep(&parse, "&"); cur; cur = strsep(&parse, "&")) { 01921 if (strcasecmp(cur, device)) 01922 continue; 01923 01924 /* Get device state for this hint */ 01925 state = ast_extension_state2(hint->exten); 01926 01927 if ((state == -1) || (state == hint->laststate)) 01928 continue; 01929 01930 /* Device state changed since last check - notify the watchers */ 01931 01932 /* For general callbacks */ 01933 for (cblist = statecbs; cblist; cblist = cblist->next) 01934 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 01935 01936 /* For extension callbacks */ 01937 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 01938 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 01939 01940 hint->laststate = state; 01941 break; 01942 } 01943 } 01944 01945 ast_mutex_unlock(&hintlock); 01946 }
| int ast_ignore_pattern | ( | const char * | context, | |
| const char * | pattern | |||
| ) |
Checks to see if a number should be ignored
| 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. Returns 0 if the pattern should not be ignored, or non-zero if the pattern should be ignored |
Definition at line 4505 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(), mgcp_ss(), skinny_ss(), and ss_thread().
04506 { 04507 struct ast_context *con; 04508 struct ast_ignorepat *pat; 04509 04510 con = ast_context_find(context); 04511 if (con) { 04512 pat = con->ignorepats; 04513 while (pat) { 04514 if (ast_extension_match(pat->pattern, pattern)) 04515 return 1; 04516 pat = pat->next; 04517 } 04518 } 04519 return 0; 04520 }
| AST_LIST_HEAD | ( | store_hints | , | |
| store_hint | ||||
| ) |
| int ast_lock_context | ( | struct ast_context * | con | ) |
Locks a given context
| con | context to lock Locks the context. Returns 0 on success, -1 on failure |
Definition at line 6306 of file pbx.c.
References ast_mutex_lock(), and ast_context::lock.
Referenced by complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_ignorepat(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), macro_exec(), and show_dialplan_helper().
06307 { 06308 return ast_mutex_lock(&con->lock); 06309 }
| int ast_lock_contexts | ( | void | ) |
Locks the contexts
Locks the context list Returns 0 on success, -1 on error
Definition at line 6293 of file pbx.c.
References ast_mutex_lock().
Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_show_dialplan_context(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), macro_exec(), and show_dialplan_helper().
06294 { 06295 return ast_mutex_lock(&conlock); 06296 }
| 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)
| 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 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 2243 of file pbx.c.
References HELPER_MATCHMORE, and pbx_extension_helper().
Referenced by __ast_pbx_run(), ast_app_dtget(), disa_exec(), dp_lookup(), dundi_lookup_local(), loopback_matchmore(), mgcp_ss(), skinny_ss(), and ss_thread().
02244 { 02245 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_MATCHMORE); 02246 }
| 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
| 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 3720 of file pbx.c.
References __ast_context_destroy(), AST_EXTENSION_REMOVED, ast_hint_extension(), AST_LIST_HEAD_INIT, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, store_hint::callbacks, ast_hint::callbacks, calloc, store_hint::context, ast_state_cb::data, ast_exten::exten, ast_hint::exten, store_hint::exten, free, ast_hint::laststate, store_hint::laststate, LOG_WARNING, ast_context::name, ast_state_cb::next, ast_context::next, ast_hint::next, ast_exten::parent, and ast_context::registrar.
Referenced by pbx_load_module().
03721 { 03722 struct ast_context *tmp, *lasttmp = NULL; 03723 struct store_hints store; 03724 struct store_hint *this; 03725 struct ast_hint *hint; 03726 struct ast_exten *exten; 03727 int length; 03728 struct ast_state_cb *thiscb, *prevcb; 03729 03730 memset(&store, 0, sizeof(store)); 03731 AST_LIST_HEAD_INIT(&store); 03732 03733 /* it is very important that this function hold the hintlock _and_ the conlock 03734 during its operation; not only do we need to ensure that the list of contexts 03735 and extensions does not change, but also that no hint callbacks (watchers) are 03736 added or removed during the merge/delete process 03737 03738 in addition, the locks _must_ be taken in this order, because there are already 03739 other code paths that use this order 03740 */ 03741 ast_mutex_lock(&conlock); 03742 ast_mutex_lock(&hintlock); 03743 03744 /* preserve all watchers for hints associated with this registrar */ 03745 for (hint = hints; hint; hint = hint->next) { 03746 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03747 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03748 this = calloc(1, length); 03749 if (!this) { 03750 ast_log(LOG_WARNING, "Could not allocate memory to preserve hint\n"); 03751 continue; 03752 } 03753 this->callbacks = hint->callbacks; 03754 hint->callbacks = NULL; 03755 this->laststate = hint->laststate; 03756 this->context = this->data; 03757 strcpy(this->data, hint->exten->parent->name); 03758 this->exten = this->data + strlen(this->context) + 1; 03759 strcpy(this->exten, hint->exten->exten); 03760 AST_LIST_INSERT_HEAD(&store, this, list); 03761 } 03762 } 03763 03764 tmp = *extcontexts; 03765 if (registrar) { 03766 __ast_context_destroy(NULL,registrar); 03767 while (tmp) { 03768 lasttmp = tmp; 03769 tmp = tmp->next; 03770 } 03771 } else { 03772 while (tmp) { 03773 __ast_context_destroy(tmp,tmp->registrar); 03774 lasttmp = tmp; 03775 tmp = tmp->next; 03776 } 03777 } 03778 if (lasttmp) { 03779 lasttmp->next = contexts; 03780 contexts = *extcontexts; 03781 *extcontexts = NULL; 03782 } else 03783 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 03784 03785 /* restore the watchers for hints that can be found; notify those that 03786 cannot be restored 03787 */ 03788 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 03789 exten = ast_hint_extension(NULL, this->context, this->exten); 03790 /* Find the hint in the list of hints */ 03791 for (hint = hints; hint; hint = hint->next) { 03792 if (hint->exten == exten) 03793 break; 03794 } 03795 if (!exten || !hint) { 03796 /* this hint has been removed, notify the watchers */ 03797 prevcb = NULL; 03798 thiscb = this->callbacks; 03799 while (thiscb) { 03800 prevcb = thiscb; 03801 thiscb = thiscb->next; 03802 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 03803 free(prevcb); 03804 } 03805 } else { 03806 thiscb = this->callbacks; 03807 while (thiscb->next) 03808 thiscb = thiscb->next; 03809 thiscb->next = hint->callbacks; 03810 hint->callbacks = this->callbacks; 03811 hint->laststate = this->laststate; 03812 } 03813 free(this); 03814 } 03815 03816 ast_mutex_unlock(&hintlock); 03817 ast_mutex_unlock(&conlock); 03818 03819 return; 03820 }
| AST_MUTEX_DEFINE_STATIC | ( | hintlock | ) |
| AST_MUTEX_DEFINE_STATIC | ( | switchlock | ) |
| AST_MUTEX_DEFINE_STATIC | ( | applock | ) |
| AST_MUTEX_DEFINE_STATIC | ( | conlock | ) |
| AST_MUTEX_DEFINE_STATIC | ( | acflock | ) |
Lock for the custom function list
| AST_MUTEX_DEFINE_STATIC | ( | maxcalllock | ) |
| AST_MUTEX_DEFINE_STATIC | ( | globalslock | ) |
| int ast_parseable_goto | ( | struct ast_channel * | chan, | |
| const char * | goto_string | |||
| ) |
Definition at line 6503 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, store_hint::exten, LOG_WARNING, ast_channel::priority, s, and strsep().
Referenced by _while_exec(), check_goto_on_transfer(), dial_exec_full(), gosub_exec(), ivr_dispatch(), pbx_builtin_goto(), random_exec(), and return_exec().
06504 { 06505 char *s; 06506 char *exten, *pri, *context; 06507 char *stringp=NULL; 06508 int ipri; 06509 int mode = 0; 06510 06511 if (ast_strlen_zero(goto_string)) { 06512 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06513 return -1; 06514 } 06515 s = ast_strdupa(goto_string); 06516 stringp=s; 06517 context = strsep(&stringp, "|"); 06518 exten = strsep(&stringp, "|"); 06519 if (!exten) { 06520 /* Only a priority in this one */ 06521 pri = context; 06522 exten = NULL; 06523 context = NULL; 06524 } else { 06525 pri = strsep(&stringp, "|"); 06526 if (!pri) { 06527 /* Only an extension and priority in this one */ 06528 pri = exten; 06529 exten = context; 06530 context = NULL; 06531 } 06532 } 06533 if (*pri == '+') { 06534 mode = 1; 06535 pri++; 06536 } else if (*pri == '-') { 06537 mode = -1; 06538 pri++; 06539 } 06540 if (sscanf(pri, "%30d", &ipri) != 1) { 06541 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, (exten && strcasecmp(exten, "BYEXTENSION")) ? exten : chan->exten, 06542 pri, chan->cid.cid_num)) < 1) { 06543 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06544 return -1; 06545 } else 06546 mode = 0; 06547 } 06548 /* At this point we have a priority and maybe an extension and a context */ 06549 06550 if (exten && !strcasecmp(exten, "BYEXTENSION")) 06551 exten = NULL; 06552 06553 if (mode) 06554 ipri = chan->priority + (ipri * mode); 06555 06556 ast_explicit_goto(chan, context, exten, ipri); 06557 ast_cdr_update(chan); 06558 return 0; 06559 06560 }
| 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 | |||
| ) |
Definition at line 5183 of file pbx.c.
References __ast_request_and_dial(), ast_channel::_state, outgoing_helper::account, async_stat::app, app_tmp::app, async_stat::appdata, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, async_stat::chan, app_tmp::chan, app_tmp::data, free, ast_channel::hangupcause, ast_channel::lock, LOG_ERROR, LOG_WARNING, malloc, ast_channel::name, option_verbose, async_stat::p, ast_channel::pbx, app_tmp::t, async_stat::timeout, outgoing_helper::vars, and VERBOSE_PREFIX_4.
Referenced by action_originate(), attempt_thread(), fast_originate(), and page_thread().
05184 { 05185 struct ast_channel *chan; 05186 struct async_stat *as; 05187 struct app_tmp *tmp; 05188 int res = -1, cdr_res = -1; 05189 struct outgoing_helper oh; 05190 pthread_attr_t attr; 05191 05192 memset(&oh, 0, sizeof(oh)); 05193 oh.vars = vars; 05194 oh.account = account; 05195 05196 if (locked_channel) 05197 *locked_channel = NULL; 05198 if (ast_strlen_zero(app)) { 05199 res = -1; 05200 goto outgoing_app_cleanup; 05201 } 05202 if (sync) { 05203 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05204 if (chan) { 05205 if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 05206 ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name); 05207 } else { 05208 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 05209 if(!chan->cdr) { 05210 /* allocation of the cdr failed */ 05211 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 05212 free(chan->pbx); 05213 res = -1; 05214 goto outgoing_app_cleanup; 05215 } 05216 /* allocation of the cdr was successful */ 05217 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05218 ast_cdr_start(chan->cdr); 05219 } 05220 ast_set_variables(chan, vars); 05221 if (account) 05222 ast_cdr_setaccount(chan, account); 05223 if (chan->_state == AST_STATE_UP) { 05224 res = 0; 05225 if (option_verbose > 3) 05226 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05227 tmp = malloc(sizeof(struct app_tmp)); 05228 if (tmp) { 05229 memset(tmp, 0, sizeof(struct app_tmp)); 05230 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05231 if (appdata) 05232 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05233 tmp->chan = chan; 05234 if (sync > 1) { 05235 if (locked_channel) 05236 ast_mutex_unlock(&chan->lock); 05237 ast_pbx_run_app(tmp); 05238 } else { 05239 pthread_attr_init(&attr); 05240 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05241 if (locked_channel) 05242 ast_mutex_lock(&chan->lock); 05243 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05244 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05245 free(tmp); 05246 if (locked_channel) 05247 ast_mutex_unlock(&chan->lock); 05248 ast_hangup(chan); 05249 res = -1; 05250 } else { 05251 if (locked_channel) 05252 *locked_channel = chan; 05253 } 05254 pthread_attr_destroy(&attr); 05255 } 05256 } else { 05257 ast_log(LOG_ERROR, "Out of memory :(\n"); 05258 res = -1; 05259 } 05260 } else { 05261 if (option_verbose > 3) 05262 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05263 if (chan->cdr) { /* update the cdr */ 05264 /* here we update the status of the call, which sould be busy. 05265 * if that fails then we set the status to failed */ 05266 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05267 ast_cdr_failed(chan->cdr); 05268 } 05269 ast_hangup(chan); 05270 } 05271 } 05272 05273 if (res < 0) { /* the call failed for some reason */ 05274 if (*reason == 0) { /* if the call failed (not busy or no answer) 05275 * update the cdr with the failed message */ 05276 cdr_res = ast_pbx_outgoing_cdr_failed(); 05277 if (cdr_res != 0) { 05278 res = cdr_res; 05279 goto outgoing_app_cleanup; 05280 } 05281 } 05282 } 05283 05284 } else { 05285 as = malloc(sizeof(struct async_stat)); 05286 if (!as) { 05287 res = -1; 05288 goto outgoing_app_cleanup; 05289 } 05290 memset(as, 0, sizeof(struct async_stat)); 05291 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05292 if (!chan) { 05293 free(as); 05294 res = -1; 05295 goto outgoing_app_cleanup; 05296 } 05297 as->chan = chan; 05298 ast_copy_string(as->app, app, sizeof(as->app)); 05299 if (appdata) 05300 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05301 as->timeout = timeout; 05302 ast_set_variables(chan, vars); 05303 if (account) 05304 ast_cdr_setaccount(chan, account); 05305 /* Start a new thread, and get something handling this channel. */ 05306 pthread_attr_init(&attr); 05307 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05308 if (locked_channel) 05309 ast_mutex_lock(&chan->lock); 05310 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05311 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05312 free(as); 05313 if (locked_channel) 05314 ast_mutex_unlock(&chan->lock); 05315 ast_hangup(chan); 05316 res = -1; 05317 pthread_attr_destroy(&attr); 05318 goto outgoing_app_cleanup; 05319 } else { 05320 if (locked_channel) 05321 *locked_channel = chan; 05322 } 05323 pthread_attr_destroy(&attr); 05324 res = 0; 05325 } 05326 outgoing_app_cleanup: 05327 ast_variables_destroy(vars); 05328 return res; 05329 }
| int ast_pbx_outgoing_cdr_failed | ( | void | ) |
Function to post an empty cdr after a spool call fails.
This function posts an empty cdr for a failed spool call
Definition at line 4977 of file pbx.c.
References ast_cdr_alloc(), ast_cdr_detach(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_start(), ast_channel_alloc(), ast_channel_free(), ast_log(), ast_channel::cdr, and LOG_WARNING.
Referenced by ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().
04978 { 04979 /* allocate a channel */ 04980 struct ast_channel *chan = ast_channel_alloc(0); 04981 if(!chan) { 04982 /* allocation of the channel failed, let some peeps know */ 04983 ast_log(LOG_WARNING, "Unable to allocate channel structure for CDR record\n"); 04984 return -1; /* failure */ 04985 } 04986 04987 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 04988 04989 if(!chan->cdr) { 04990 /* allocation of the cdr failed */ 04991 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 04992 ast_channel_free(chan); /* free the channel */ 04993 return -1; /* return failure */ 04994 } 04995 04996 /* allocation of the cdr was successful */ 04997 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 04998 ast_cdr_start(chan->cdr); /* record the start and stop time */ 04999 ast_cdr_end(chan->cdr); 05000 ast_cdr_failed(chan->cdr); /* set the status to failed */ 05001 ast_cdr_detach(chan->cdr); /* post and free the record */ 05002 ast_channel_free(chan); /* free the channel */ 05003 05004 return 0; /* success */ 05005 }
| 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 ** | channel | |||
| ) |
Definition at line 5007 of file pbx.c.
References __ast_request_and_dial(), ast_channel::_state, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), ast_channel_alloc(), ast_exists_extension(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create, ast_request_and_dial(), ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, async_stat::chan, async_stat::context, ast_channel::context, async_stat::exten, ast_channel::exten, free, ast_channel::hangupcause, LOAD_OH, ast_channel::lock, LOG_ERROR, LOG_WARNING, malloc, ast_channel::name, option_verbose, async_stat::p, ast_channel::pbx, async_stat::priority, ast_channel::priority, async_stat::timeout, and VERBOSE_PREFIX_4.
Referenced by action_originate(), attempt_thread(), and fast_originate().
05008 { 05009 struct ast_channel *chan; 05010 struct async_stat *as; 05011 int res = -1, cdr_res = -1; 05012 struct outgoing_helper oh; 05013 pthread_attr_t attr; 05014 05015 if (sync) { 05016 LOAD_OH(oh); 05017 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05018 if (channel) { 05019 *channel = chan; 05020 if (chan) 05021 ast_mutex_lock(&chan->lock); 05022 } 05023 if (chan) { 05024 if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 05025 ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name); 05026 } else { 05027 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 05028 if (!chan->cdr) { 05029 /* allocation of the cdr failed */ 05030 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 05031 free(chan->pbx); 05032 res = -1; 05033 goto outgoing_exten_cleanup; 05034 } 05035 /* allocation of the cdr was successful */ 05036 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05037 ast_cdr_start(chan->cdr); 05038 } 05039 if (chan->_state == AST_STATE_UP) { 05040 res = 0; 05041 if (option_verbose > 3) 05042 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05043 05044 if (sync > 1) { 05045 if (channel) 05046 ast_mutex_unlock(&chan->lock); 05047 if (ast_pbx_run(chan)) { 05048 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05049 if (channel) 05050 *channel = NULL; 05051 ast_hangup(chan); 05052 res = -1; 05053 } 05054 } else { 05055 if (ast_pbx_start(chan)) { 05056 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05057 if (channel) { 05058 *channel = NULL; 05059 ast_mutex_unlock(&chan->lock); 05060 } 05061 ast_hangup(chan); 05062 res = -1; 05063 } 05064 } 05065 } else { 05066 if (option_verbose > 3) 05067 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05068 05069 if(chan->cdr) { /* update the cdr */ 05070 /* here we update the status of the call, which sould be busy. 05071 * if that fails then we set the status to failed */ 05072 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05073 ast_cdr_failed(chan->cdr); 05074 } 05075 05076 if (channel) { 05077 *channel = NULL; 05078 ast_mutex_unlock(&chan->lock); 05079 } 05080 ast_hangup(chan); 05081 } 05082 } 05083 05084 if (res < 0) { /* the call failed for some reason */ 05085 if (*reason == 0) { /* if the call failed (not busy or no answer) 05086 * update the cdr with the failed message */ 05087 cdr_res = ast_pbx_outgoing_cdr_failed(); 05088 if (cdr_res != 0) { 05089 res = cdr_res; 05090 goto outgoing_exten_cleanup; 05091 } 05092 } 05093 05094 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05095 /* check if "failed" exists */ 05096 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05097 chan = ast_channel_alloc(0); 05098 if (chan) { 05099 ast_copy_string(chan->name, "OutgoingSpoolFailed", sizeof(chan->name)); 05100 if (!ast_strlen_zero(context)) 05101 ast_copy_string(chan->context, context, sizeof(chan->context)); 05102 ast_copy_string(chan->exten, "failed", sizeof(chan->exten)); 05103 chan->priority = 1; 05104 ast_set_variables(chan, vars); 05105 if (account) 05106 ast_cdr_setaccount(chan, account); 05107 ast_pbx_run(chan); 05108 } else 05109 ast_log(LOG_WARNING, "Can't allocate the channel structure, skipping execution of extension 'failed'\n"); 05110 } 05111 } 05112 } else { 05113 as = malloc(sizeof(struct async_stat)); 05114 if (!as) { 05115 res = -1; 05116 goto outgoing_exten_cleanup; 05117 } 05118 memset(as, 0, sizeof(struct async_stat)); 05119 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05120 if (channel) { 05121 *channel = chan; 05122 if (chan) 05123 ast_mutex_lock(&chan->lock); 05124 } 05125 if (!chan) { 05126 free(as); 05127 res = -1; 05128 goto outgoing_exten_cleanup; 05129 } 05130 as->chan = chan; 05131 ast_copy_string(as->context, context, sizeof(as->context)); 05132 ast_copy_string(as->exten, exten, sizeof(as->exten)); 05133 as->priority = priority; 05134 as->timeout = timeout; 05135 ast_set_variables(chan, vars); 05136 if (account) 05137 ast_cdr_setaccount(chan, account); 05138 pthread_attr_init(&attr); 05139 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05140 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05141 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05142 free(as); 05143 if (channel) { 05144 *channel = NULL; 05145 ast_mutex_unlock(&chan->lock); 05146 } 05147 ast_hangup(chan); 05148 res = -1; 05149 pthread_attr_destroy(&attr); 05150 goto outgoing_exten_cleanup; 05151 } 05152 pthread_attr_destroy(&attr); 05153 res = 0; 05154 } 05155 outgoing_exten_cleanup: 05156 ast_variables_destroy(vars); 05157 return res; 05158 }
| enum ast_pbx_result ast_pbx_run | ( | struct ast_channel * | c | ) |
Execute the PBX in the current thread
| c | channel to run the pbx on |
Definition at line 2571 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_ss(), and ss_thread().
02572 { 02573 enum ast_pbx_result res = AST_PBX_SUCCESS; 02574 02575 if (increase_call_count(c)) 02576 return AST_PBX_CALL_LIMIT; 02577 02578 res = __ast_pbx_run(c); 02579 decrease_call_count(); 02580 02581 return res; 02582 }
| static void* ast_pbx_run_app | ( | void * | data | ) | [static] |
Definition at line 5167 of file pbx.c.
References app_tmp::app, ast_hangup(), ast_log(), ast_verbose(), app_tmp::chan, app_tmp::data, free, LOG_WARNING, ast_channel::name, option_verbose, pbx_exec(), pbx_findapp(), and VERBOSE_PREFIX_4.
Referenced by ast_pbx_outgoing_app().
05168 { 05169 struct app_tmp *tmp = data; 05170 struct ast_app *app; 05171 app = pbx_findapp(tmp->app); 05172 if (app) { 05173 if (option_verbose > 3) 05174 ast_verbose(VERBOSE_PREFIX_4 "Launching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name); 05175 pbx_exec(tmp->chan, app, tmp->data, 1); 05176 } else 05177 ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app); 05178 ast_hangup(tmp->chan); 05179 free(tmp); 05180 return NULL; 05181 }
| enum ast_pbx_result ast_pbx_start | ( | struct ast_channel * | c | ) |
Create a new thread and start the PBX (or whatever)
| c | channel to start the pbx on |
Definition at line 2545 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_modem_new(), ast_pbx_outgoing_exten(), check_goto_on_transfer(), dial_exec_full(), do_parking_thread(), handle_request_invite(), local_call(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), skinny_new(), vpb_new(), and zt_new().
02546 { 02547 pthread_t t; 02548 pthread_attr_t attr; 02549 02550 if (!c) { 02551 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02552 return AST_PBX_FAILED; 02553 } 02554 02555 if (increase_call_count(c)) 02556 return AST_PBX_CALL_LIMIT; 02557 02558 /* Start a new thread, and get something handling this channel. */ 02559 pthread_attr_init(&attr); 02560 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02561 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02562 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02563 pthread_attr_destroy(&attr); 02564 return AST_PBX_FAILED; 02565 } 02566 pthread_attr_destroy(&attr); 02567 02568 return AST_PBX_SUCCESS; 02569 }
| int ast_register_application | ( | const char * | app, | |
| int(*)(struct ast_channel *, void *) | execute, | |||
| const char * | synopsis, | |||
| const char * | description | |||
| ) |
Dynamically register a new dial plan application.
Add an application. The function 'execute' should return non-zero if the line needs to be hung up.
| app | Short name of the application | |
| execute | a function callback to execute the application | |
| synopsis | a short description of the application | |
| description | long description of the application Include a one-line synopsis (e.g. 'hangs up a channel') and a more lengthy, multiline description with more detail, including under what conditions the application will return 0 or -1. This registers an application with asterisks internal application list. Please note: The individual applications themselves are responsible for registering and unregistering CLI commands. It returns 0 on success, -1 on failure. |
Definition at line 2888 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), COLOR_BRCYAN, ast_app::description, ast_app::execute, LOG_ERROR, LOG_WARNING, malloc, ast_app::name, ast_app::next, option_verbose, ast_app::synopsis, term_color(), and VERBOSE_PREFIX_2.
Referenced by load_module(), and load_pbx().
02889 { 02890 struct ast_app *tmp, *prev, *cur; 02891 char tmps[80]; 02892 int length; 02893 length = sizeof(struct ast_app); 02894 length += strlen(app) + 1; 02895 if (ast_mutex_lock(&applock)) { 02896 ast_log(LOG_ERROR, "Unable to lock application list\n"); 02897 return -1; 02898 } 02899 tmp = apps; 02900 while(tmp) { 02901 if (!strcasecmp(app, tmp->name)) { 02902 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02903 ast_mutex_unlock(&applock); 02904 return -1; 02905 } 02906 tmp = tmp->next; 02907 } 02908 tmp = malloc(length); 02909 if (tmp) { 02910 memset(tmp, 0, length); 02911 strcpy(tmp->name, app); 02912 tmp->execute = execute; 02913 tmp->synopsis = synopsis; 02914 tmp->description = description; 02915 /* Store in alphabetical order */ 02916 cur = apps; 02917 prev = NULL; 02918 while(cur) { 02919 if (strcasecmp(tmp->name, cur->name) < 0) 02920 break; 02921 prev = cur; 02922 cur = cur->next; 02923 } 02924 if (prev) { 02925 tmp->next = prev->next; 02926 prev->next = tmp; 02927 } else { 02928 tmp->next = apps; 02929 apps = tmp; 02930 } 02931 } else { 02932 ast_log(LOG_ERROR, "Out of memory\n"); 02933 ast_mutex_unlock(&applock); 02934 return -1; 02935 } 02936 if (option_verbose > 1) 02937 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 02938 ast_mutex_unlock(&applock); 02939 return 0; 02940 }
| int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative switch
| sw | switch to register This function registers a populated ast_switch structure with the asterisk switching architecture. It returns 0 on success, and other than 0 on failure |
Definition at line 2942 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, LOG_WARNING, ast_switch::name, and ast_switch::next.
Referenced by load_module().
02943 { 02944 struct ast_switch *tmp, *prev=NULL; 02945 if (ast_mutex_lock(&switchlock)) { 02946 ast_log(LOG_ERROR, "Unable to lock switch lock\n"); 02947 return -1; 02948 } 02949 tmp = switches; 02950 while(tmp) { 02951 if (!strcasecmp(tmp->name, sw->name)) 02952 break; 02953 prev = tmp; 02954 tmp = tmp->next; 02955 } 02956 if (tmp) { 02957 ast_mutex_unlock(&switchlock); 02958 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 02959 return -1; 02960 } 02961 sw->next = NULL; 02962 if (prev) 02963 prev->next = sw; 02964 else 02965 switches = sw; 02966 ast_mutex_unlock(&switchlock); 02967 return 0; 02968 }
| static int ast_remove_hint | ( | struct ast_exten * | e | ) | [static] |
ast_remove_hint: Remove hint from extension
Definition at line 2159 of file pbx.c.
References AST_EXTENSION_DEACTIVATED, ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_exten::exten, ast_hint::exten, free, list, ast_context::name, ast_hint::next, ast_state_cb::next, and ast_exten::parent.
Referenced by ast_context_remove_extension2(), and destroy_exten().
02160 { 02161 /* Cleanup the Notifys if hint is removed */ 02162 struct ast_hint *list, *prev = NULL; 02163 struct ast_state_cb *cblist, *cbprev; 02164 02165 if (!e) 02166 return -1; 02167 02168 ast_mutex_lock(&hintlock); 02169 02170 list = hints; 02171 while(list) { 02172 if (list->exten==e) { 02173 cbprev = NULL; 02174 cblist = list->callbacks; 02175 while (cblist) { 02176 /* Notify with -1 and remove all callbacks */ 02177 cbprev = cblist; 02178 cblist = cblist->next; 02179 cbprev->callback(list->exten->parent->name, list->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data); 02180 free(cbprev); 02181 } 02182 list->callbacks = NULL; 02183 02184 if (!prev) 02185 hints = list->next; 02186 else 02187 prev->next = list->next; 02188 free(list); 02189 02190 ast_mutex_unlock(&hintlock); 02191 return 0; 02192 } else { 02193 prev = list; 02194 list = list->next; 02195 } 02196 } 02197 02198 ast_mutex_unlock(&hintlock); 02199 return -1; 02200 }
| 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)
| 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. It returns 0 on success, -1 on failure. |
Definition at line 2248 of file pbx.c.
References HELPER_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), loopback_exec(), and macro_exec().
02249 { 02250 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_SPAWN); 02251 }
| int ast_unlock_context | ( | struct ast_context * | con | ) |
Unlocks the given context
| con | context to unlock Unlocks the given context Returns 0 on success, -1 on failure |
Definition at line 6311 of file pbx.c.
References ast_mutex_unlock(), and ast_context::lock.
Referenced by complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_ignorepat(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), macro_exec(), and show_dialplan_helper().
06312 { 06313 return ast_mutex_unlock(&con->lock); 06314 }
| int ast_unlock_contexts | ( | void | ) |
Unlocks contexts
Returns 0 on success, -1 on failure
Definition at line 6298 of file pbx.c.
References ast_mutex_unlock().
Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_show_dialplan_context(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), macro_exec(), and show_dialplan_helper().
06299 { 06300 return ast_mutex_unlock(&conlock); 06301 }
| int ast_unregister_application | ( | const char * | app | ) |
Remove an application
| 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 registration mechanisms. It returns 0 on success, and -1 on failure. |
Definition at line 3635 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, LOG_ERROR, ast_app::name, ast_app::next, option_verbose, and VERBOSE_PREFIX_2.
Referenced by __unload_module(), and unload_module().
03636 { 03637 struct ast_app *tmp, *tmpl = NULL; 03638 if (ast_mutex_lock(&applock)) { 03639 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03640 return -1; 03641 } 03642 tmp = apps; 03643 while(tmp) { 03644 if (!strcasecmp(app, tmp->name)) { 03645 if (tmpl) 03646 tmpl->next = tmp->next; 03647 else 03648 apps = tmp->next; 03649 if (option_verbose > 1) 03650 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03651 free(tmp); 03652 ast_mutex_unlock(&applock); 03653 return 0; 03654 } 03655 tmpl = tmp; 03656 tmp = tmp->next; 03657 } 03658 ast_mutex_unlock(&applock); 03659 return -1; 03660 }
| void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch
| sw | switch to unregister Unregisters a switch from asterisk. Returns nothing |
Definition at line 2970 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, and ast_switch::next.
Referenced by __unload_module(), and unload_module().
02971 { 02972 struct ast_switch *tmp, *prev=NULL; 02973 if (ast_mutex_lock(&switchlock)) { 02974 ast_log(LOG_ERROR, "Unable to lock switch lock\n"); 02975 return; 02976 } 02977 tmp = switches; 02978 while(tmp) { 02979 if (tmp == sw) { 02980 if (prev) 02981 prev->next = tmp->next; 02982 else 02983 switches = tmp->next; 02984 tmp->next = NULL; 02985 break; 02986 } 02987 prev = tmp; 02988 tmp = tmp->next; 02989 } 02990 ast_mutex_unlock(&switchlock); 02991 }
| struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
| struct ast_exten * | exten | |||
| ) | [read] |
Definition at line 6418 of file pbx.c.
References ast_exten::next, and ast_context::root.
Referenced by complete_context_remove_extension(), dundi_precache_full(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper().
06420 { 06421 if (!exten) 06422 return con ? con->root : NULL; 06423 else 06424 return exten->next; 06425 }
| struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
| struct ast_ignorepat * | ip | |||
| ) | [read] |
Definition at line 6454 of file pbx.c.
References ast_context::ignorepats, and ast_ignorepat::next.
Referenced by complete_context_add_ignorepat(), complete_context_remove_ignorepat(), handle_save_dialplan(), and show_dialplan_helper().
06456 { 06457 if (!ip) 06458 return con ? con->ignorepats : NULL; 06459 else 06460 return ip->next; 06461 }
| struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
| struct ast_include * | inc | |||
| ) | [read] |
Definition at line 6445 of file pbx.c.
References ast_context::includes, and ast_include::next.
Referenced by ast_context_verify_includes(), complete_context_add_include(), complete_context_dont_include(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper().
06447 { 06448 if (!inc) 06449 return con ? con->includes : NULL; 06450 else 06451 return inc->next; 06452 }
| struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
| struct ast_sw * | sw | |||
| ) | [read] |
Definition at line 6427 of file pbx.c.
References ast_context::alts, and ast_sw::next.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06429 { 06430 if (!sw) 06431 return con ? con->alts : NULL; 06432 else 06433 return sw->next; 06434 }
| struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) | [read] |
Definition at line 6410 of file pbx.c.
References ast_context::next.
Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_show_dialplan_context(), dundi_precache_full(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), macro_exec(), pbx_load_module(), and show_dialplan_helper().
| struct ast_exten* ast_walk_extension_priorities | ( | struct ast_exten * | exten, | |
| struct ast_exten * | priority | |||
| ) | [read] |
Definition at line 6436 of file pbx.c.
References ast_exten::peer.
Referenced by complete_context_remove_extension(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper().
06438 { 06439 if (!priority) 06440 return exten; 06441 else 06442 return priority->peer; 06443 }
| static void* async_wait | ( | void * | data | ) | [static] |
Definition at line 4913 of file pbx.c.
References ast_channel::_state, async_stat::app, async_stat::appdata, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_frfree(), ast_hangup(), ast_log(), ast_pbx_run(), ast_read(), AST_STATE_UP, ast_strlen_zero(), ast_verbose(), ast_waitfor(), async_stat::chan, ast_channel::context, async_stat::context, ast_channel::exten, async_stat::exten, ast_frame::frametype, free, LOG_ERROR, LOG_WARNING, ast_channel::name, option_verbose, pbx_exec(), pbx_findapp(), ast_channel::priority, async_stat::priority, ast_frame::subclass, async_stat::timeout, and VERBOSE_PREFIX_3.
Referenced by ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().
04914 { 04915 struct async_stat *as = data; 04916 struct ast_channel *chan = as->chan; 04917 int timeout = as->timeout; 04918 int res; 04919 struct ast_frame *f; 04920 struct ast_app *app; 04921 04922 while(timeout && (chan->_state != AST_STATE_UP)) { 04923 res = ast_waitfor(chan, timeout); 04924 if (res < 1) 04925 break; 04926 if (timeout > -1) 04927 timeout = res; 04928 f = ast_read(chan); 04929 if (!f) 04930 break; 04931 if (f->frametype == AST_FRAME_CONTROL) { 04932 if ((f->subclass == AST_CONTROL_BUSY) || 04933 (f->subclass == AST_CONTROL_CONGESTION) ) { 04934 ast_frfree(f); 04935 break; 04936 } 04937 } 04938 ast_frfree(f); 04939 } 04940 if (chan->_state == AST_STATE_UP) { 04941 if (!ast_strlen_zero(as->app)) { 04942 app = pbx_findapp(as->app); 04943 if (app) { 04944 if (option_verbose > 2) 04945 ast_verbose(VERBOSE_PREFIX_3 "Launching %s(%s) on %s\n", as->app, as->appdata, chan->name); 04946 pbx_exec(chan, app, as->appdata, 1); 04947 } else 04948 ast_log(LOG_WARNING, "No such application '%s'\n", as->app); 04949 } else { 04950 if (!ast_strlen_zero(as->context)) 04951 ast_copy_string(chan->context, as->context, sizeof(chan->context)); 04952 if (!ast_strlen_zero(as->exten)) 04953 ast_copy_string(chan->exten, as->exten, sizeof(chan->exten)); 04954 if (as->priority > 0) 04955 chan->priority = as->priority; 04956 /* Run the PBX */ 04957 if (ast_pbx_run(chan)) { 04958 ast_log(LOG_ERROR, "Failed to start PBX on %s\n", chan->name); 04959 } else { 04960 /* PBX will have taken care of this */ 04961 chan = NULL; 04962 } 04963 } 04964 04965 } 04966 free(as); 04967 if (chan) 04968 ast_hangup(chan); 04969 return NULL; 04970 }
| static char* complete_show_application | ( | char * | line, | |
| char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 3041 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, ast_app::name, ast_app::next, and strdup.
03043 { 03044 struct ast_app *a; 03045 int which = 0; 03046 03047 /* try to lock applications list ... */ 03048 if (ast_mutex_lock(&applock)) { 03049 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03050 return NULL; 03051 } 03052 03053 /* ... walk all applications ... */ 03054 a = apps; 03055 while (a) { 03056 /* ... check if word matches this application ... */ 03057 if (!strncasecmp(word, a->name, strlen(word))) { 03058 /* ... if this is right app serve it ... */ 03059 if (++which > state) { 03060 char *ret = strdup(a->name); 03061 ast_mutex_unlock(&applock); 03062 return ret; 03063 } 03064 } 03065 a = a->next; 03066 } 03067 03068 /* no application match */ 03069 ast_mutex_unlock(&applock); 03070 return NULL; 03071 }
| static char* complete_show_applications | ( | char * | line, | |
| char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 3288 of file pbx.c.
References ast_strlen_zero(), and strdup.
03289 { 03290 if (pos == 2) { 03291 if (ast_strlen_zero(word)) { 03292 switch (state) { 03293 case 0: 03294 return strdup("like"); 03295 case 1: 03296 return strdup("describing"); 03297 default: 03298 return NULL; 03299 } 03300 } else if (! strncasecmp(word, "like", strlen(word))) { 03301 if (state == 0) { 03302 return strdup("like"); 03303 } else { 03304 return NULL; 03305 } 03306 } else if (! strncasecmp(word, "describing", strlen(word))) { 03307 if (state == 0) { 03308 return strdup("describing"); 03309 } else { 03310 return NULL; 03311 } 03312 } 03313 } 03314 return NULL; 03315 }
| static char* complete_show_dialplan_context | ( | char * | line, | |
| char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 3320 of file pbx.c.
References ast_get_context_name(), ast_lock_contexts(), ast_log(), ast_unlock_contexts(), ast_walk_contexts(), LOG_ERROR, and strdup.
03322 { 03323 struct ast_context *c; 03324 int which = 0; 03325 03326 /* we are do completion of [exten@]context on second position only */ 03327 if (pos != 2) return NULL; 03328 03329 /* try to lock contexts list ... */ 03330 if (ast_lock_contexts()) { 03331 ast_log(LOG_ERROR, "Unable to lock context list\n"); 03332 return NULL; 03333 } 03334 03335 /* ... walk through all contexts ... */ 03336 c = ast_walk_contexts(NULL); 03337 while(c) { 03338 /* ... word matches context name? yes? ... */ 03339 if (!strncasecmp(word, ast_get_context_name(c), strlen(word))) { 03340 /* ... for serve? ... */ 03341 if (++which > state) { 03342 /* ... yes, serve this context name ... */ 03343 char *ret = strdup(ast_get_context_name(c)); 03344 ast_unlock_contexts(); 03345 return ret; 03346 } 03347 } 03348 c = ast_walk_contexts(c); 03349 } 03350 03351 /* ... unlock and return */ 03352 ast_unlock_contexts(); 03353 return NULL; 03354 }
| static char* complete_show_function | ( | char * | line, | |
| char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 1260 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, ast_custom_function::name, ast_custom_function::next, and strdup.
01261 { 01262 struct ast_custom_function *acf; 01263 int which = 0; 01264 01265 /* try to lock functions list ... */ 01266 if (ast_mutex_lock(&acflock)) { 01267 ast_log(LOG_ERROR, "Unable to lock function list\n"); 01268 return NULL; 01269 } 01270 01271 acf = acf_root; 01272 while (acf) { 01273 if (!strncasecmp(word, acf->name, strlen(word))) { 01274 if (++which > state) { 01275 char *ret = strdup(acf->name); 01276 ast_mutex_unlock(&acflock); 01277 return ret; 01278 } 01279 } 01280 acf = acf->next; 01281 } 01282 01283 ast_mutex_unlock(&acflock); 01284 return NULL; 01285 }
| static void decrease_call_count | ( | void | ) | [static] |
Definition at line 2517 of file pbx.c.
References ast_mutex_lock(), and ast_mutex_unlock().
Referenced by ast_pbx_run(), and pbx_thread().
02518 { 02519 ast_mutex_lock(&maxcalllock); 02520 if (countcalls > 0) 02521 countcalls--; 02522 ast_mutex_unlock(&maxcalllock); 02523 }
| static void destroy_exten | ( | struct ast_exten * | e | ) | [static] |
Definition at line 5331 of file pbx.c.
References ast_remove_hint(), ast_exten::data, ast_exten::datad, free, ast_exten::priority, and PRIORITY_HINT.
Referenced by __ast_context_destroy().
05332 { 05333 if (e->priority == PRIORITY_HINT) 05334 ast_remove_hint(e); 05335 05336 if (e->datad) 05337 e->datad(e->data); 05338 free(e); 05339 }
| static int ext_strncpy | ( | char * | dst, | |
| const char * | src, | |||
| int | len | |||
| ) | [static] |
Definition at line 4634 of file pbx.c.
Referenced by ast_add_extension2().
04635 { 04636 int count=0; 04637 04638 while(*src && (count < len - 1)) { 04639 switch(*src) { 04640 case ' ': 04641 /* otherwise exten => [a-b],1,... doesn't work */ 04642 /* case '-': */ 04643 /* Ignore */ 04644 break; 04645 default: 04646 *dst = *src; 04647 dst++; 04648 } 04649 src++; 04650 count++; 04651 } 04652 *dst = '\0'; 04653 04654 return count; 04655 }
| static unsigned int get_day | ( | char * | day | ) | [static] |
Definition at line 4000 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and s.
Referenced by ast_build_timing().
04001 { 04002 char *c; 04003 /* The following line is coincidence, really! */ 04004 int s, e, x; 04005 unsigned int mask; 04006 04007 /* Check for all days */ 04008 if (ast_strlen_zero(day) || !strcmp(day, "*")) { 04009 mask = (1 << 30) + ((1 << 30) - 1); 04010 return mask; 04011 } 04012 /* Get start and ending days */ 04013 c = strchr(day, '-'); 04014 if (c) { 04015 *c = '\0'; 04016 c++; 04017 } 04018 /* Find the start */ 04019 if (sscanf(day, "%2d", &s) != 1) { 04020 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", day); 04021 return 0; 04022 } 04023 if ((s < 1) || (s > 31)) { 04024 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", day); 04025 return 0; 04026 } 04027 s--; 04028 if (c) { 04029 if (sscanf(c, "%2d", &e) != 1) { 04030 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c); 04031 return 0; 04032 } 04033 if ((e < 1) || (e > 31)) { 04034 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c); 04035 return 0; 04036 } 04037 e--; 04038 } else 04039 e = s; 04040 mask = 0; 04041 for (x=s; x!=e; x = (x + 1) % 31) { 04042 mask |= (1 << x); 04043 } 04044 mask |= (1 << x); 04045 return mask; 04046 }
| static unsigned int get_dow | ( | char * | dow | ) | [static] |
get_dow: Get day of week
Definition at line 3958 of file pbx.c.
References ast_log(), ast_strlen_zero(), days, LOG_WARNING, and s.
Referenced by ast_build_timing().
03959 { 03960 char *c; 03961 /* The following line is coincidence, really! */ 03962 int s, e, x; 03963 unsigned int mask; 03964 03965 /* Check for all days */ 03966 if (ast_strlen_zero(dow) || !strcmp(dow, "*")) 03967 return (1 << 7) - 1; 03968 /* Get start and ending days */ 03969 c = strchr(dow, '-'); 03970 if (c) { 03971 *c = '\0'; 03972 c++; 03973 } else 03974 c = NULL; 03975 /* Find the start */ 03976 s = 0; 03977 while((s < 7) && strcasecmp(dow, days[s])) s++; 03978 if (s >= 7) { 03979 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", dow); 03980 return 0; 03981 } 03982 if (c) { 03983 e = 0; 03984 while((e < 7) && strcasecmp(c, days[e])) e++; 03985 if (e >= 7) { 03986 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c); 03987 return 0; 03988 } 03989 } else 03990 e = s; 03991 mask = 0; 03992 for (x=s; x != e; x = (x + 1) % 7) { 03993 mask |= (1 << x); 03994 } 03995 /* One last one */ 03996 mask |= (1 << x); 03997 return mask; 03998 }
| static unsigned int get_month | ( | char * | mon | ) | [static] |
Definition at line 4064 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, months, and s.
Referenced by ast_build_timing().
04065 { 04066 char *c; 04067 /* The following line is coincidence, really! */ 04068 int s, e, x; 04069 unsigned int mask; 04070 04071 /* Check for all days */ 04072 if (ast_strlen_zero(mon) || !strcmp(mon, "*")) 04073 return (1 << 12) - 1; 04074 /* Get start and ending days */ 04075 c = strchr(mon, '-'); 04076 if (c) { 04077 *c = '\0'; 04078 c++; 04079 } 04080 /* Find the start */ 04081 s = 0; 04082 while((s < 12) && strcasecmp(mon, months[s])) s++; 04083 if (s >= 12) { 04084 ast_log(LOG_WARNING, "Invalid month '%s', assuming none\n", mon); 04085 return 0; 04086 } 04087 if (c) { 04088 e = 0; 04089 while((e < 12) && strcasecmp(c, months[e])) e++; 04090 if (e >= 12) { 04091 ast_log(LOG_WARNING, "Invalid month '%s', assuming none\n", c); 04092 return 0; 04093 } 04094 } else 04095 e = s; 04096 mask = 0; 04097 for (x=s; x!=e; x = (x + 1) % 12) { 04098 mask |= (1 << x); 04099 } 04100 /* One last one */ 04101 mask |= (1 << x); 04102 return mask; 04103 }
| static void get_timerange | ( | struct ast_timing * | i, | |
| char * | times | |||
| ) | [static] |
Definition at line 3862 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and ast_timing::minmask.
Referenced by ast_build_timing().
03863 { 03864 char *e; 03865 int x; 03866 int s1, s2; 03867 int e1, e2; 03868 /* int cth, ctm; */ 03869 03870 /* start disabling all times, fill the fields with 0's, as they may contain garbage */ 03871 memset(i->minmask, 0, sizeof(i->minmask)); 03872 03873 /* Star is all times */ 03874 if (ast_strlen_zero(times) || !strcmp(times, "*")) { 03875 for (x=0; x<24; x++) 03876 i->minmask[x] = (1 << 30) - 1; 03877 return; 03878 } 03879 /* Otherwise expect a range */ 03880 e = strchr(times, '-'); 03881 if (!e) { 03882 ast_log(LOG_WARNING, "Time range is not valid. Assuming no restrictions based on time.\n"); 03883 return; 03884 } 03885 *e = '\0'; 03886 e++; 03887 while(*e && !isdigit(*e)) 03888 e++; 03889 if (!*e) { 03890 ast_log(LOG_WARNING, "Invalid time range. Assuming no restrictions based on time.\n"); 03891 return; 03892 } 03893 if (sscanf(times, "%2d:%2d", &s1, &s2) != 2) { 03894 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", times); 03895 return; 03896 } 03897 if (sscanf(e, "%2d:%2d", &e1, &e2) != 2) { 03898 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", e); 03899 return; 03900 } 03901 03902 #if 1 03903 s1 = s1 * 30 + s2/2; 03904 if ((s1 < 0) || (s1 >= 24*30)) { 03905 ast_log(LOG_WARNING, "%s isn't a valid start time. Assuming no time.\n", times); 03906 return; 03907 } 03908 e1 = e1 * 30 + e2/2; 03909 if ((e1 < 0) || (e1 >= 24*30)) { 03910 ast_log(LOG_WARNING, "%s isn't a valid end time. Assuming no time.\n", e); 03911 return; 03912 } 03913 /* Go through the time and enable each appropriate bit */ 03914 for (x=s1;x != e1;x = (x + 1) % (24 * 30)) { 03915 i->minmask[x/30] |= (1 << (x % 30)); 03916 } 03917 /* Do the last one */ 03918 i->minmask[x/30] |= (1 << (x % 30)); 03919 #else 03920 for (cth=0; cth<24; cth++) { 03921 /* Initialize masks to blank */ 03922 i->minmask[cth] = 0; 03923 for (ctm=0; ctm<30; ctm++) { 03924 if ( 03925 /* First hour with more than one hour */ 03926 (((cth == s1) && (ctm >= s2)) && 03927 ((cth < e1))) 03928 /* Only one hour */ 03929 || (((cth == s1) && (ctm >= s2)) && 03930 ((cth == e1) && (ctm <= e2))) 03931 /* In between first and last hours (more than 2 hours) */ 03932 || ((cth > s1) && 03933 (cth < e1)) 03934 /* Last hour with more than one hour */ 03935 || ((cth > s1) && 03936 ((cth == e1) && (ctm <= e2))) 03937 ) 03938 i->minmask[cth] |= (1 << (ctm / 2)); 03939 } 03940 } 03941 #endif 03942 /* All done */ 03943 return; 03944 }
| static int handle_show_application | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 3073 of file pbx.c.
References ast_cli(), ast_log(), AST_MAX_APP, ast_mutex_lock(), ast_mutex_unlock(), COLOR_CYAN, COLOR_MAGENTA, ast_app::description, description, LOG_ERROR, ast_app::name, ast_app::next, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_app::synopsis, synopsis, and term_color().
03074 { 03075 struct ast_app *a; 03076 int app, no_registered_app = 1; 03077 03078 if (argc < 3) return RESULT_SHOWUSAGE; 03079 03080 /* try to lock applications list ... */ 03081 if (ast_mutex_lock(&applock)) { 03082 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03083 return -1; 03084 } 03085 03086 /* ... go through all applications ... */ 03087 a = apps; 03088 while (a) { 03089 /* ... compare this application name with all arguments given 03090 * to 'show application' command ... */ 03091 for (app = 2; app < argc; app++) { 03092 if (!strcasecmp(a->name, argv[app])) { 03093 /* Maximum number of characters added by terminal coloring is 22 */ 03094 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 03095 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 03096 int synopsis_size, description_size; 03097 03098 no_registered_app = 0; 03099 03100 if (a->synopsis) 03101 synopsis_size = strlen(a->synopsis) + 23; 03102 else 03103 synopsis_size = strlen("Not available") + 23; 03104 synopsis = alloca(synopsis_size); 03105 03106 if (a->description) 03107 description_size = strlen(a->description) + 23; 03108 else 03109 description_size = strlen("Not available") + 23; 03110 description = alloca(description_size); 03111 03112 if (synopsis && description) { 03113 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name); 03114 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 03115 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 03116 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 03117 term_color(synopsis, 03118 a->synopsis ? a->synopsis : "Not available", 03119 COLOR_CYAN, 0, synopsis_size); 03120 term_color(description, 03121 a->description ? a->description : "Not available", 03122 COLOR_CYAN, 0, description_size); 03123 03124 ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); 03125 } else { 03126 /* ... one of our applications, show info ...*/ 03127 ast_cli(fd,"\n -= Info about application '%s' =- \n\n" 03128 "[Synopsis]\n %s\n\n" 03129 "[Description]\n%s\n", 03130 a->name, 03131 a->synopsis ? a->synopsis : "Not available", 03132 a->description ? a->description : "Not available"); 03133 } 03134 } 03135 } 03136 a = a->next; 03137 } 03138 03139 ast_mutex_unlock(&applock); 03140 03141 /* we found at least one app? no? */ 03142 if (no_registered_app) { 03143 ast_cli(fd, "Your application(s) is (are) not registered\n"); 03144 return RESULT_FAILURE; 03145 } 03146 03147 return RESULT_SUCCESS; 03148 }
| static int handle_show_applications | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 3211 of file pbx.c.
References ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_app::description, LOG_ERROR, ast_app::name, ast_app::next, RESULT_SUCCESS, strcasestr(), and ast_app::synopsis.
03212 { 03213 struct ast_app *a; 03214 int like=0, describing=0; 03215 int total_match = 0; /* Number of matches in like clause */ 03216 int total_apps = 0; /* Number of apps registered */ 03217 03218 /* try to lock applications list ... */ 03219 if (ast_mutex_lock(&applock)) { 03220 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03221 return -1; 03222 } 03223 03224 /* ... have we got at least one application (first)? no? */ 03225 if (!apps) { 03226 ast_cli(fd, "There are no registered applications\n"); 03227 ast_mutex_unlock(&applock); 03228 return -1; 03229 } 03230 03231 /* show applications like <keyword> */ 03232 if ((argc == 4) && (!strcmp(argv[2], "like"))) { 03233 like = 1; 03234 } else if ((argc > 3) && (!strcmp(argv[2], "describing"))) { 03235 describing = 1; 03236 } 03237 03238 /* show applications describing <keyword1> [<keyword2>] [...] */ 03239 if ((!like) && (!describing)) { 03240 ast_cli(fd, " -= Registered Asterisk Applications =-\n"); 03241 } else { 03242 ast_cli(fd, " -= Matching Asterisk Applications =-\n"); 03243 } 03244 03245 /* ... go through all applications ... */ 03246 for (a = apps; a; a = a->next) { 03247 /* ... show informations about applications ... */ 03248 int printapp=0; 03249 total_apps++; 03250 if (like) { 03251 if (strcasestr(a->name, argv[3])) { 03252 printapp = 1; 03253 total_match++; 03254 } 03255 } else if (describing) { 03256 if (a->description) { 03257 /* Match all words on command line */ 03258 int i; 03259 printapp = 1; 03260 for (i=3; i<argc; i++) { 03261 if (!strcasestr(a->description, argv[i])) { 03262 printapp = 0; 03263 } else { 03264 total_match++; 03265 } 03266 } 03267 } 03268 } else { 03269 printapp = 1; 03270 } 03271 03272 if (printapp) { 03273 ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); 03274 } 03275 } 03276 if ((!like) && (!describing)) { 03277 ast_cli(fd, " -= %d Applications Registered =-\n",total_apps); 03278 } else { 03279 ast_cli(fd, " -= %d Applications Matching =-\n",total_match); 03280 } 03281 03282 /* ... unlock and return */ 03283 ast_mutex_unlock(&applock); 03284 03285 return RESULT_SUCCESS; 03286 }
| static int handle_show_dialplan | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 3551 of file pbx.c.
References ast_cli(), AST_PBX_MAX_STACK, ast_strdupa, ast_strlen_zero(), context, dialplan_counters::context_existence, exten, dialplan_counters::extension_existence, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, show_dialplan_helper(), strsep(), dialplan_counters::total_context, dialplan_counters::total_exten, and dialplan_counters::total_prio.
03552 { 03553 char *exten = NULL, *context = NULL; 03554 /* Variables used for different counters */ 03555 struct dialplan_counters counters; 03556 char *incstack[AST_PBX_MAX_STACK]; 03557 memset(&counters, 0, sizeof(counters)); 03558 03559 if (argc != 2 && argc != 3) 03560 return RESULT_SHOWUSAGE; 03561 03562 /* we obtain [exten@]context? if yes, split them ... */ 03563 if (argc == 3) { 03564 char *splitter = ast_strdupa(argv[2]); 03565 /* is there a '@' character? */ 03566 if (splitter && strchr(argv[2], '@')) { 03567 /* yes, split into exten & context ... */ 03568 exten = strsep(&splitter, "@"); 03569 context = splitter; 03570 03571 /* check for length and change to NULL if ast_strlen_zero() */ 03572 if (ast_strlen_zero(exten)) 03573 exten = NULL; 03574 if (ast_strlen_zero(context)) 03575 context = NULL; 03576 show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack); 03577 } else { 03578 /* no '@' char, only context given */ 03579 context = argv[2]; 03580 if (ast_strlen_zero(context)) 03581 context = NULL; 03582 show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack); 03583 } 03584 } else { 03585 /* Show complete dial plan */ 03586 show_dialplan_helper(fd, NULL, NULL, &counters, NULL, 0, incstack); 03587 } 03588 03589 /* check for input failure and throw some error messages */ 03590 if (context && !counters.context_existence) { 03591 ast_cli(fd, "There is no existence of '%s' context\n", context); 03592 return RESULT_FAILURE; 03593 } 03594 03595 if (exten && !counters.extension_existence) { 03596 if (context) 03597 ast_cli(fd, "There is no existence of %s@%s extension\n", 03598 exten, context); 03599 else 03600 ast_cli(fd, 03601 "There is no existence of '%s' extension in all contexts\n", 03602 exten); 03603 return RESULT_FAILURE; 03604 } 03605 03606 ast_cli(fd,"-= %d %s (%d %s) in %d %s. =-\n", 03607 counters.total_exten, counters.total_exten == 1 ? "extension" : "extensions", 03608 counters.total_prio, counters.total_prio == 1 ? "priority" : "priorities", 03609 counters.total_context, counters.total_context == 1 ? "context" : "contexts"); 03610 03611 /* everything ok */ 03612 return RESULT_SUCCESS; 03613 }
| static int handle_show_function | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 1205 of file pbx.c.
References ast_cli(), ast_custom_function_find(), AST_MAX_APP, COLOR_CYAN, COLOR_MAGENTA, ast_custom_function::desc, description, ast_custom_function::name, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_custom_function::synopsis, synopsis, ast_custom_function::syntax, and term_color().
01206 { 01207 struct ast_custom_function *acf; 01208 /* Maximum number of characters added by terminal coloring is 22 */ 01209 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 01210 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 01211 char stxtitle[40], *syntax = NULL; 01212 int synopsis_size, description_size, syntax_size; 01213 01214 if (argc < 3) return RESULT_SHOWUSAGE; 01215 01216 if (!(acf = ast_custom_function_find(argv[2]))) { 01217 ast_cli(fd, "No function by that name registered.\n"); 01218 return RESULT_FAILURE; 01219 01220 } 01221 01222 if (acf->synopsis) 01223 synopsis_size = strlen(acf->synopsis) + 23; 01224 else 01225 synopsis_size = strlen("Not available") + 23; 01226 synopsis = alloca(synopsis_size); 01227 01228 if (acf->desc) 01229 description_size = strlen(acf->desc) + 23; 01230 else 01231 description_size = strlen("Not available") + 23; 01232 description = alloca(description_size); 01233 01234 if (acf->syntax) 01235 syntax_size = strlen(acf->syntax) + 23; 01236 else 01237 syntax_size = strlen("Not available") + 23; 01238 syntax = alloca(syntax_size); 01239 01240 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about function '%s' =- \n\n", acf->name); 01241 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 01242 term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40); 01243 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 01244 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 01245 term_color(syntax, 01246 acf->syntax ? acf->syntax : "Not available", 01247 COLOR_CYAN, 0, syntax_size); 01248 term_color(synopsis, 01249 acf->synopsis ? acf->synopsis : "Not available", 01250 COLOR_CYAN, 0, synopsis_size); 01251 term_color(description, 01252 acf->desc ? acf->desc : "Not available", 01253 COLOR_CYAN, 0, description_size); 01254 01255 ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description); 01256 01257 return RESULT_SUCCESS; 01258 }
| static int handle_show_functions | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 1189 of file pbx.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_custom_function::name, ast_custom_function::next, ast_custom_function::synopsis, and ast_custom_function::syntax.
01190 { 01191 struct ast_custom_function *acf; 01192 int count_acf = 0; 01193 01194 ast_cli(fd, "Installed Custom Functions:\n--------------------------------------------------------------------------------\n"); 01195 ast_mutex_lock(&acflock); 01196 for (acf = acf_root ; acf; acf = acf->next) { 01197 ast_cli(fd, "%-20.20s %-35.35s %s\n", acf->name, acf->syntax, acf->synopsis); 01198 count_acf++; 01199 } 01200 ast_mutex_unlock(&acflock); 01201 ast_cli(fd, "%d custom functions installed.\n", count_acf); 01202 return 0; 01203 }
| static int handle_show_hints | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
handle_show_hints: CLI support for listing registred dial plan hints
Definition at line 3151 of file pbx.c.
References ast_cli(), ast_extension_state2str(), ast_get_extension_app(), ast_get_extension_name(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_hint::callbacks, ast_hint::exten, ast_hint::laststate, LOG_ERROR, ast_hint::next, ast_state_cb::next, and RESULT_SUCCESS.
03152 { 03153 struct ast_hint *hint; 03154 int num = 0; 03155 int watchers; 03156 struct ast_state_cb *watcher; 03157 03158 if (!hints) { 03159 ast_cli(fd, "There are no registered dialplan hints\n"); 03160 return RESULT_SUCCESS; 03161 } 03162 /* ... we have hints ... */ 03163 ast_cli(fd, "\n -= Registered Asterisk Dial Plan Hints =-\n"); 03164 if (ast_mutex_lock(&hintlock)) { 03165 ast_log(LOG_ERROR, "Unable to lock hints\n"); 03166 return -1; 03167 } 03168 hint = hints; 03169 while (hint) { 03170 watchers = 0; 03171 for (watcher = hint->callbacks; watcher; watcher = watcher->next) 03172 watchers++; 03173 ast_cli(fd, " %-20.20s: %-20.20s State:%-15.15s Watchers %2d\n", 03174 ast_get_extension_name(hint->exten), ast_get_extension_app(hint->exten), 03175 ast_extension_state2str(hint->laststate), watchers); 03176 num++; 03177 hint = hint->next; 03178 } 03179 ast_cli(fd, "----------------\n"); 03180 ast_cli(fd, "- %d hints registered\n", num); 03181 ast_mutex_unlock(&hintlock); 03182 return RESULT_SUCCESS; 03183 }
| static int handle_show_switches | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
handle_show_switches: CLI support for listing registred dial plan switches
Definition at line 3186 of file pbx.c.
References ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_switch::description, LOG_ERROR, ast_switch::name, ast_switch::next, and RESULT_SUCCESS.
03187 { 03188 struct ast_switch *sw; 03189 if (!switches) { 03190 ast_cli(fd, "There are no registered alternative switches\n"); 03191 return RESULT_SUCCESS; 03192 } 03193 /* ... we have applications ... */ 03194 ast_cli(fd, "\n -= Registered Asterisk Alternative Switches =-\n"); 03195 if (ast_mutex_lock(&switchlock)) { 03196 ast_log(LOG_ERROR, "Unable to lock switches\n"); 03197 return -1; 03198 } 03199 sw = switches; 03200 while (sw) { 03201 ast_cli(fd, "%s: %s\n", sw->name, sw->description); 03202 sw = sw->next; 03203 } 03204 ast_mutex_unlock(&switchlock); 03205 return RESULT_SUCCESS; 03206 }
| static int include_valid | ( | struct ast_include * | i | ) | [inline, static] |
Definition at line 633 of file pbx.c.
References ast_check_timing(), ast_include::hastime, and ast_include::timing.
Referenced by pbx_find_extension().
00634 { 00635 if (!i->hastime) 00636 return 1; 00637 00638 return ast_check_timing(&(i->timing)); 00639 }
| static int increase_call_count | ( | const struct ast_channel * | c | ) | [static] |
Definition at line 2492 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), getloadavg(), LOG_NOTICE, ast_channel::name, option_maxcalls, and option_maxload.
Referenced by ast_pbx_run(), and ast_pbx_start().
02493 { 02494 int failed = 0; 02495 double curloadavg; 02496 ast_mutex_lock(&maxcalllock); 02497 if (option_maxcalls) { 02498 if (countcalls >= option_maxcalls) { 02499 ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name); 02500 failed = -1; 02501 } 02502 } 02503 if (option_maxload) { 02504 getloadavg(&curloadavg, 1); 02505 if (curloadavg >= option_maxload) { 02506 ast_log(LOG_NOTICE, "Maximum loadavg limit of %lf load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg); 02507 failed = -1; 02508 } 02509 } 02510 if (!failed) 02511 countcalls++; 02512 ast_mutex_unlock(&maxcalllock); 02513 02514 return failed; 02515 }
| int load_pbx | ( | void | ) |
Definition at line 6266 of file pbx.c.
References ast_cli_register_multiple(), AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_register_application(), ast_verbose(), builtins, description, globals, LOG_ERROR, name, option_verbose, synopsis, and VERBOSE_PREFIX_1.
Referenced by main().
06267 { 06268 int x; 06269 06270 /* Initialize the PBX */ 06271 if (option_verbose) { 06272 ast_verbose( "Asterisk PBX Core Initializing\n"); 06273 ast_verbose( "Registering builtin applications:\n"); 06274 } 06275 AST_LIST_HEAD_INIT_NOLOCK(&globals); 06276 ast_cli_register_multiple(pbx_cli, sizeof(pbx_cli) / sizeof(pbx_cli[0])); 06277 06278 /* Register builtin applications */ 06279 for (x=0; x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) { 06280 if (option_verbose) 06281 ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name); 06282 if (ast_register_application(builtins[x].name, builtins[x].execute, builtins[x].synopsis, builtins[x].description)) { 06283 ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name); 06284 return -1; 06285 } 06286 } 06287 return 0; 06288 }
| static int matchcid | ( | const char * | cidpattern, | |
| const char * | callerid | |||
| ) | [static] |
Definition at line 780 of file pbx.c.
References ast_extension_match(), and ast_strlen_zero().
Referenced by pbx_find_extension().
00781 { 00782 int failresult; 00783 00784 /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so 00785 failing to get a number should count as a match, otherwise not */ 00786 00787 if (!ast_strlen_zero(cidpattern)) 00788 failresult = 0; 00789 else 00790 failresult = 1; 00791 00792 if (!callerid) 00793 return failresult; 00794 00795 return ast_extension_match(cidpattern, callerid); 00796 }
| static void null_datad | ( | void * | foo | ) | [static] |
| static int parse_variable_name | ( | char * | var, | |
| int * | offset, | |||
| int * | length, | |||
| int * | isfunc | |||
| ) | [static] |
Definition at line 926 of file pbx.c.
References DONT_HAVE_LENGTH.
Referenced by pbx_retrieve_variable(), and pbx_substitute_variables_helper_full().
00927 { 00928 char *varchar, *offsetchar = NULL; 00929 int parens=0; 00930 00931 *offset = 0; 00932 *length = DONT_HAVE_LENGTH; 00933 *isfunc = 0; 00934 for (varchar=var; *varchar; varchar++) { 00935 switch (*varchar) { 00936 case '(': 00937 (*isfunc)++; 00938 parens++; 00939 break; 00940 case ')': 00941 parens--; 00942 break; 00943 case ':': 00944 if (parens == 0) { 00945 offsetchar = varchar + 1; 00946 *varchar = '\0'; 00947 goto pvn_endfor; 00948 } 00949 } 00950 } 00951 pvn_endfor: 00952 if (offsetchar) { 00953 sscanf(offsetchar, "%30d:%30d", offset, length); 00954 return 1; 00955 } else { 00956 return 0; 00957 } 00958 }
| void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 6155 of file pbx.c.
References AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), ast_var_delete(), and globals.
Referenced by handle_reload_extensions(), and reload().
06156 { 06157 struct ast_var_t *vardata; 06158 06159 ast_mutex_lock(&globalslock); 06160 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06161 ast_var_delete(vardata); 06162 ast_mutex_unlock(&globalslock); 06163 }
| char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
| const char * | name | |||
| ) |
Definition at line 5950 of file pbx.c.
References AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), globals, and ast_channel::varshead.
Referenced by __ast_pbx_run(), __login_exec(), _while_exec(), action_getvar(), agentmonitoroutgoing_exec(), ast_bridge_call(), ast_channel_bridge(), ast_feature_interpret(), ast_monitor_stop(), ast_osp_lookup(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), chanspy_exec(), check_goto_on_transfer(), conf_exec(), conf_run(), dial_exec_full(), do_chanreads(), dundi_exec(), dundi_helper(), get_index(), get_refer_info(), group_check_exec(), group_count_exec(), iax2_exec(), import_ch(), leave_voicemail(), macro_exec(), misdn_answer(), misdn_hangup(), oh323_hangup(), ospfinished_exec(), ospnext_exec(), queue_exec(), retrydial_exec(), return_exec(), set_config_flags(), sip_addheader(), try_calling(), try_suggested_sip_codec(), wait_for_answer(), zt_call(), and zt_hangup().
05951 { 05952 struct ast_var_t *variables; 05953 char *ret = NULL; 05954 int i; 05955 struct varshead *places[2] = { NULL, &globals }; 05956 05957 if (!name) 05958 return NULL; 05959 if (chan) 05960 places[0] = &chan->varshead; 05961 05962 for (i = 0; i < 2; i++) { 05963 if (!places[i]) 05964 continue; 05965 if (places[i] == &globals) 05966 ast_mutex_lock(&globalslock); 05967 AST_LIST_TRAVERSE(places[i], variables, entries) { 05968 if (!strcmp(name, ast_var_name(variables))) { 05969 ret = ast_var_value(variables); 05970 break; 05971 } 05972 } 05973 if (places[i] == &globals) 05974 ast_mutex_unlock(&globalslock); 05975 if (ret) 05976 break; 05977 } 05978 05979 return ret; 05980 }
| static int pbx_builtin_gotoif | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 6184 of file pbx.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_DEBUG, LOG_WARNING, pbx_builtin_goto(), pbx_checkcondition(), s, and strsep().
06185 { 06186 char *condition, *branch1, *branch2, *branch; 06187 char *s; 06188 int rc; 06189 char *stringp=NULL; 06190 06191 if (ast_strlen_zero(data)) { 06192 ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n"); 06193 return 0; 06194 } 06195 06196 s = ast_strdupa(data); 06197 stringp = s; 06198 condition = strsep(&stringp,"?"); 06199 branch1 = strsep(&stringp,":"); 06200 branch2 = strsep(&stringp,""); 06201 branch = pbx_checkcondition(condition) ? branch1 : branch2; 06202 06203 if (ast_strlen_zero(branch)) { 06204 ast_log(LOG_DEBUG, "Not taking any branch\n"); 06205 return 0; 06206 } 06207 06208 rc = pbx_builtin_goto(chan, branch); 06209 06210 return rc; 06211 }
| int pbx_builtin_importvar | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 6094 of file pbx.c.
References ast_get_channel_by_name_locked(), ast_log(), ast_mutex_unlock(), ast_strdupa, ast_strlen_zero(), ast_channel::lock, LOG_WARNING, name, pbx_builtin_setvar_helper(), pbx_substitute_variables_helper(), s, strsep(), and VAR_BUF_SIZE.
06095 { 06096 char *name; 06097 char *value; 06098 char *stringp=NULL; 06099 char *channel; 06100 struct ast_channel *chan2; 06101 char tmp[VAR_BUF_SIZE]=""; 06102 char *s; 06103 06104 if (ast_strlen_zero(data)) { 06105 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06106 return 0; 06107 } 06108 06109 stringp = ast_strdupa(data); 06110 name = strsep(&stringp,"="); 06111 channel = strsep(&stringp,"|"); 06112 value = strsep(&stringp,"\0"); 06113 if (channel && value && name) { 06114 chan2 = ast_get_channel_by_name_locked(channel); 06115 if (chan2) { 06116 s = alloca(strlen(value) + 4); 06117 if (s) { 06118 sprintf(s, "${%s}", value); 06119 pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1); 06120 } 06121 ast_mutex_unlock(&chan2->lock); 06122 } 06123 pbx_builtin_setvar_helper(chan, name, tmp); 06124 } 06125 06126 return(0); 06127 }
| static int pbx_builtin_noop | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
| void pbx_builtin_pushvar_helper | ( | struct ast_channel * | chan, | |
| const char * | name, | |||
| const char * | value | |||
| ) |
Definition at line 5982 of file pbx.c.
References ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_var_assign(), ast_verbose(), globals, LOG_WARNING, option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2.
Referenced by gosub_exec().
05983 { 05984 struct ast_var_t *newvariable; 05985 struct varshead *headp; 05986 05987 if (name[strlen(name)-1] == ')') { 05988 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05989 return ast_func_write(chan, name, value); 05990 } 05991 05992 headp = (chan) ? &chan->varshead : &globals; 05993 05994 if (value) { 05995 if ((option_verbose > 1) && (headp == &globals)) 05996 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05997 newvariable = ast_var_assign(name, value); 05998 if (headp == &globals) 05999 ast_mutex_lock(&globalslock); 06000 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 06001 if (headp == &globals) 06002 ast_mutex_unlock(&globalslock); 06003 } 06004 }
| static int pbx_builtin_saycharacters | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 6248 of file pbx.c.
References ast_say_character_str(), and ast_channel::language.
06249 { 06250 int res = 0; 06251 06252 if (data) 06253 res = ast_say_character_str(chan, (char *)data, "", chan->language); 06254 return res; 06255 }
| static int pbx_builtin_saydigits | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 6239 of file pbx.c.
References ast_say_digit_str(), and ast_channel::language.
06240 { 06241 int res = 0; 06242 06243 if (data) 06244 res = ast_say_digit_str(chan, (char *)data, "", chan->language); 06245 return res; 06246 }
| static int pbx_builtin_saynumber | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 6213 of file pbx.c.
References ast_log(), ast_say_number(), ast_strlen_zero(), ast_channel::language, LOG_WARNING, and strsep().
06214 { 06215 int res = 0; 06216 char tmp[256]; 06217 char *number = (char *) NULL; 06218 char *options = (char *) NULL; 06219 06220 06221 if (ast_strlen_zero(data)) { 06222 ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n"); 06223 return -1; 06224 } 06225 ast_copy_string(tmp, (char *) data, sizeof(tmp)); 06226 number=tmp; 06227 strsep(&number, "|"); 06228 options = strsep(&number, "|"); 06229 if (options) { 06230 if ( strcasecmp(options, "f") && strcasecmp(options,"m") && 06231 strcasecmp(options, "c") && strcasecmp(options, "n") ) { 06232 ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n"); 06233 return -1; 06234 } 06235 } 06236 return res = ast_say_number(chan, atoi((char *) tmp), "", chan->language, options); 06237 }
| static int pbx_builtin_sayphonetic | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 6257 of file pbx.c.
References ast_say_phonetic_str(), and ast_channel::language.
06258 { 06259 int res = 0; 06260 06261 if (data) 06262 res = ast_say_phonetic_str(chan, (char *)data, "", chan->language); 06263 return res; 06264 }
| int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
| char * | buf, | |||
| size_t | size | |||
| ) |
Definition at line 5925 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(), and handle_showchan().
05926 { 05927 struct ast_var_t *variables; 05928 char *var, *val; 05929 int total = 0; 05930 05931 if (!chan) 05932 return 0; 05933 05934 memset(buf, 0, size); 05935 05936 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05937 if ((var = ast_var_name(variables)) && (val = ast_var_value(variables))) { 05938 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05939 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05940 break; 05941 } else 05942 total++; 05943 } else 05944 break; 05945 } 05946 05947 return total; 05948 }
| static int pbx_builtin_setglobalvar | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 6129 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, name, pbx_builtin_setvar_helper(), and strsep().
06130 { 06131 char *name; 06132 char *value; 06133 char *stringp = NULL; 06134 06135 if (ast_strlen_zero(data)) { 06136 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06137 return 0; 06138 } 06139 06140 stringp = data; 06141 name = strsep(&stringp, "="); 06142 value = strsep(&stringp, "\0"); 06143 06144 pbx_builtin_setvar_helper(NULL, name, value); 06145 06146 return(0); 06147 }
| int pbx_builtin_setvar | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) |
Definition at line 6058 of file pbx.c.
References ast_app_separate_args(), ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, name, and pbx_builtin_setvar_helper().
Referenced by handle_globals(), and pbx_builtin_setvar_old().
06059 { 06060 char *name, *value, *mydata; 06061 int argc; 06062 char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */ 06063 int global = 0; 06064 int x; 06065 06066 if (ast_strlen_zero(data)) { 06067 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n"); 06068 return 0; 06069 } 06070 06071 mydata = ast_strdupa(data); 06072 argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0])); 06073 06074 /* check for a trailing flags argument */ 06075 if ((argc > 1) && !strchr(argv[argc-1], '=')) { 06076 argc--; 06077 if (strchr(argv[argc], 'g')) 06078 global = 1; 06079 } 06080 06081 for (x = 0; x < argc; x++) { 06082 name = argv[x]; 06083 if ((value = strchr(name, '='))) { 06084 *value = '\0'; 06085 value++; 06086 pbx_builtin_setvar_helper((global) ? NULL : chan, name, value); 06087 } else 06088 ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name); 06089 } 06090 06091 return(0); 06092 }
| void pbx_builtin_setvar_helper | ( | struct ast_channel * | chan, | |
| const char * | name, | |||
| const char * | value | |||
| ) |
Definition at line 6006 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_var_assign(), ast_var_delete(), ast_var_name(), ast_verbose(), globals, option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2.
Referenced by __ast_pbx_run(), __login_exec(), _while_exec(), action_setvar(), aPGSQL_connect(), aPGSQL_fetch(), aPGSQL_query(), aqm_exec(), ast_bridge_call(), ast_channel_bridge(), ast_iax2_new(), ast_monitor_start(), ast_set_variables(), background_detect_exec(), builtin_blindtransfer(), builtin_function_set(), cb_events(), chanavail_exec(), conf_run(), controlplayback_exec(), count_exec(), curl_exec(), cut_exec(), dial_exec_full(), disa_exec(), do_waiting(), dundi_lookup_exec(), enumlookup_exec(), eval_exec(), export_ch(), function_db_exists(), function_db_read(), get_exec(), get_refer_info(), group_check_exec(), group_count_exec(), group_match_count_exec(), handle_setvariable(), hasvoicemail_exec(), i4l_read(), leave_voicemail(), lookupblacklist_exec(), macro_exec(), math_exec(), md5_exec(), md5check_exec(), misdn_call(), mixmonitor_exec(), monitor_handle_owned(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), pbx_builtin_importvar(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_extension_helper(), pbx_load_module(), play_message_datetime(), playback_exec(), pop_exec(), pqm_exec(), prep_email_sub_vars(), privacy_exec(), process_ast_dsp(), read_exec(), readfile_exec(), realtime_exec(), record_exec(), return_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_getheader(), sip_new(), sort_exec(), start_monitor_exec(), system_exec_helper(), transfer_exec(), txtcidname_exec(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), zt_handle_dtmfup(), and zt_new().
06007 { 06008 struct ast_var_t *newvariable; 06009 struct varshead *headp; 06010 const char *nametail = name; 06011 06012 if (name[strlen(name)-1] == ')') 06013 return ast_func_write(chan, name, value); 06014 06015 headp = (chan) ? &chan->varshead : &globals; 06016 06017 /* For comparison purposes, we have to strip leading underscores */ 06018 if (*nametail == '_') { 06019 nametail++; 06020 if (*nametail == '_') 06021 nametail++; 06022 } 06023 06024 if (headp == &globals) 06025 ast_mutex_lock(&globalslock); 06026 AST_LIST_TRAVERSE (headp, newvariable, entries) { 06027 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 06028 /* there is already such a variable, delete it */ 06029 AST_LIST_REMOVE(headp, newvariable, entries); 06030 ast_var_delete(newvariable); 06031 break; 06032 } 06033 } 06034 06035 if (value) { 06036 if ((option_verbose > 1) && (headp == &globals)) 06037 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 06038 newvariable = ast_var_assign(name, value); 06039 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 06040 } 06041 06042 if (headp == &globals) 06043 ast_mutex_unlock(&globalslock); 06044 }
| int pbx_builtin_setvar_old | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 6046 of file pbx.c.
References ast_log(), LOG_WARNING, and pbx_builtin_setvar().
06047 { 06048 static int deprecation_warning = 0; 06049 06050 if (!deprecation_warning) { 06051 ast_log(LOG_WARNING, "SetVar is deprecated, please use Set instead.\n"); 06052 deprecation_warning = 1; 06053 } 06054 06055 return pbx_builtin_setvar(chan, data); 06056 }
| int pbx_checkcondition | ( | char * | condition | ) |
Definition at line 6165 of file pbx.c.
Referenced by _while_exec(), builtin_function_if(), execif_exec(), gosubif_exec(), macro_exec(), macroif_exec(), and pbx_builtin_gotoif().
06166 { 06167 if (condition) { 06168 if (*condition == '\0') { 06169 /* Empty strings are false */ 06170 return 0; 06171 } else if (*condition >= '0' && *condition <= '9') { 06172 /* Numbers are evaluated for truth */ 06173 return atoi(condition); 06174 } else { 06175 /* Strings are true */ 06176 return 1; 06177 } 06178 } else { 06179 /* NULL is also false */ 06180 return 0; 06181 } 06182 }
| static void pbx_destroy | ( | struct ast_pbx * | p | ) | [static] |
Definition at line 641 of file pbx.c.
References free.
Referenced by __ast_pbx_run().
00642 { 00643 free(p); 00644 }
| int pbx_exec | ( | struct ast_channel * | c, | |
| struct ast_app * | app, | |||
| void * | data, | |||
| int | newstack | |||
| ) |
executes an application
| c | channel to execute on | |
| app | which app to execute | |
| data | the data passed into the app | |
| newstack | stack pointer This application executes an application on a given channel. It saves the stack and executes the given appliation passing in the given data. It returns 0 on success, and -1 on failure |
| c | Channel |
| app | Application |
| data | Data for execution |
| newstack | Force stack increment |
Definition at line 552 of file pbx.c.
References ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_log(), ast_channel::cdr, ast_channel::data, ast_app::execute, LOG_WARNING, and ast_app::name.
Referenced by ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dial_exec_full(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), and realtime_exec().
00556 { 00557 int res; 00558 00559 char *saved_c_appl; 00560 char *saved_c_data; 00561 00562 int (*execute)(struct ast_channel *chan, void *data) = app->execute; 00563 00564 if (newstack) { 00565 if (c->cdr && !ast_check_hangup(c)) 00566 ast_cdr_setapp(c->cdr, app->name, data); 00567 00568 /* save channel values */ 00569 saved_c_appl= c->appl; 00570 saved_c_data= c->data; 00571 00572 c->appl = app->name; 00573 c->data = data; 00574 res = execute(c, data); 00575 /* restore channel values */ 00576 c->appl= saved_c_appl; 00577 c->data= saved_c_data; 00578 return res; 00579 } else 00580 ast_log(LOG_WARNING, "You really didn't want to call this function with newstack set to 0\n"); 00581 return -1; 00582 }
| static int pbx_extension_helper | ( | struct ast_channel * | c, | |
| struct ast_context * | con, | |||
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| const char * | label, | |||
| const char * | callerid, | |||
| int | action | |||
| ) | [static] |
Definition at line 1641 of file pbx.c.
References ast_exten::app, app, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PBX_MAX_STACK, ast_strlen_zero(), ast_verbose(), COLOR_BRCYAN, COLOR_BRMAGENTA, ast_channel::context, EVENT_FLAG_CALL, ast_switch::exec, EXT_DATA_SIZE, ast_channel::exten, HELPER_CANMATCH, HELPER_EXEC, HELPER_EXISTS, HELPER_FINDLABEL, HELPER_MATCHMORE, HELPER_SPAWN, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), ast_switch::name, ast_channel::name, ast_app::name, option_debug, option_verbose, pbx_builtin_setvar_helper(), pbx_exec(), pbx_find_extension(), pbx_findapp(), pbx_substitute_variables(), ast_channel::priority, ast_exten::priority, STATUS_NO_CONTEXT, STATUS_NO_EXTENSION, STATUS_NO_LABEL, STATUS_NO_PRIORITY, term_color(), ast_channel::uniqueid, and VERBOSE_PREFIX_3.
Referenced by ast_canmatch_extension(), ast_exec_extension(), ast_exists_extension(), ast_findlabel_extension(), ast_findlabel_extension2(), ast_matchmore_extension(), and ast_spawn_extension().
01642 { 01643 struct ast_exten *e; 01644 struct ast_app *app; 01645 struct ast_switch *sw; 01646 char *data; 01647 const char *foundcontext=NULL; 01648 int newstack = 0; 01649 int res; 01650 int status = 0; 01651 char *incstack[AST_PBX_MAX_STACK]; 01652 char passdata[EXT_DATA_SIZE]; 01653 int stacklen = 0; 01654 char tmp[80]; 01655 char tmp2[80]; 01656 char tmp3[EXT_DATA_SIZE]; 01657 char atmp[80]; 01658 char atmp2[EXT_DATA_SIZE+100]; 01659 01660 if (ast_mutex_lock(&conlock)) { 01661 ast_log(LOG_WARNING, "Unable to obtain lock\n"); 01662 if ((action == HELPER_EXISTS) || (action == HELPER_CANMATCH) || (action == HELPER_MATCHMORE)) 01663 return 0; 01664 else 01665 return -1; 01666 } 01667 e = pbx_find_extension(c, con, context, exten, priority, label, callerid, action, incstack, &stacklen, &status, &sw, &data, &foundcontext); 01668 if (e) { 01669 switch(action) { 01670 case HELPER_CANMATCH: 01671 ast_mutex_unlock(&conlock); 01672 return -1; 01673 case HELPER_EXISTS: 01674 ast_mutex_unlock(&conlock); 01675 return -1; 01676 case HELPER_FINDLABEL: 01677 res = e->priority; 01678 ast_mutex_unlock(&conlock); 01679 return res; 01680 case HELPER_MATCHMORE: 01681 ast_mutex_unlock(&conlock); 01682 return -1; 01683 case HELPER_SPAWN: 01684 newstack++; 01685 /* Fall through */ 01686 case HELPER_EXEC: 01687 app = pbx_findapp(e->app); 01688 ast_mutex_unlock(&conlock); 01689 if (app) { 01690 if (c->context != context) 01691 ast_copy_string(c->context, context, sizeof(c->context)); 01692 if (c->exten != exten) 01693 ast_copy_string(c->exten, exten, sizeof(c->exten)); 01694 c->priority = priority; 01695 pbx_substitute_variables(passdata, sizeof(passdata), c, e); 01696 if (option_debug) { 01697 ast_log(LOG_DEBUG, "Launching '%s'\n", app->name); 01698 snprintf(atmp, 80, "STACK-%s-%s-%d", context, exten, priority); 01699 snprintf(atmp2, EXT_DATA_SIZE+100, "%s(\"%s\", \"%s\") %s", app->name, c->name, (!ast_strlen_zero(passdata) ? (char *)passdata : ""), (newstack ? "in new stack" : "in same stack")); 01700 pbx_builtin_setvar_helper(c, atmp, atmp2); 01701 } 01702 if (option_verbose > 2) 01703 ast_verbose( VERBOSE_PREFIX_3 "Executing %s(\"%s\", \"%s\") %s\n", 01704 term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)), 01705 term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)), 01706 term_color(tmp3, (!ast_strlen_zero(passdata) ? (char *)passdata : ""), COLOR_BRMAGENTA, 0, sizeof(tmp3)), 01707 (newstack ? "in new stack" : "in same stack")); 01708 manager_event(EVENT_FLAG_CALL, "Newexten", 01709 "Channel: %s\r\n" 01710 "Context: %s\r\n" 01711 "Extension: %s\r\n" 01712 "Priority: %d\r\n" 01713 "Application: %s\r\n" 01714 "AppData: %s\r\n" 01715 "Uniqueid: %s\r\n", 01716 c->name, c->context, c->exten, c->priority, app->name, passdata ? passdata : "(NULL)", c->uniqueid); 01717 res = pbx_exec(c, app, passdata, newstack); 01718 return res; 01719 } else { 01720 ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority); 01721 return -1; 01722 } 01723 default: 01724 ast_log(LOG_WARNING, "Huh (%d)?\n", action); return -1; 01725 } 01726 } else if (sw) { 01727 switch(action) { 01728 case HELPER_CANMATCH: 01729 ast_mutex_unlock(&conlock); 01730 return -1; 01731 case HELPER_EXISTS: 01732 ast_mutex_unlock(&conlock); 01733 return -1; 01734 case HELPER_MATCHMORE: 01735 ast_mutex_unlock(&conlock); 01736 return -1; 01737 case HELPER_FINDLABEL: 01738 ast_mutex_unlock(&conlock); 01739 return -1; 01740 case HELPER_SPAWN: 01741 newstack++; 01742 /* Fall through */ 01743 case HELPER_EXEC: 01744 ast_mutex_unlock(&conlock); 01745 if (sw->exec) 01746 res = sw->exec(c, foundcontext ? foundcontext : context, exten, priority, callerid, newstack, data); 01747 else { 01748 ast_log(LOG_WARNING, "No execution engine for switch %s\n", sw->name); 01749 res = -1; 01750 } 01751 return res; 01752 default: 01753 ast_log(LOG_WARNING, "Huh (%d)?\n", action); 01754 return -1; 01755 } 01756 } else { 01757 ast_mutex_unlock(&conlock); 01758 switch(status) { 01759 case STATUS_NO_CONTEXT: 01760 if ((action != HELPER_EXISTS) && (action != HELPER_MATCHMORE)) 01761 ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context); 01762 break; 01763 case STATUS_NO_EXTENSION: 01764 if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH) && (action != HELPER_MATCHMORE)) 01765 ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context); 01766 break; 01767 case STATUS_NO_PRIORITY: 01768 if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH) && (action != HELPER_MATCHMORE)) 01769 ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context); 01770 break; 01771 case STATUS_NO_LABEL: 01772 if (context) 01773 ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, context); 01774 break; 01775 default: 01776 ast_log(LOG_DEBUG, "Shouldn't happen!\n"); 01777 } 01778 01779 if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH) && (action != HELPER_MATCHMORE)) 01780 return -1; 01781 else 01782 return 0; 01783 } 01784 01785 }
| static struct ast_exten* pbx_find_extension | ( | struct ast_channel * | chan, | |
| struct ast_context * | bypass, | |||
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| const char * | label, | |||
| const char * | callerid, | |||
| int | action, | |||
| char * | incstack[], | |||
| int * | stacklen, | |||
| int * | status, | |||
| struct ast_switch ** | swo, | |||
| char ** | data, | |||
| const char ** | foundcontext | |||
| ) | [static, read] |
Definition at line 798 of file pbx.c.
References ast_context::alts, ast_extension_close(), ast_extension_match(), ast_log(), AST_PBX_MAX_STACK, ast_switch::canmatch, ast_exten::cidmatch, ast_sw::data, ast_sw::eval, ast_switch::exists, ast_exten::exten, HELPER_CANMATCH, HELPER_FINDLABEL, HELPER_MATCHMORE, include_valid(), ast_context::includes, ast_exten::label, LOG_WARNING, match(), matchcid(), ast_exten::matchcid, ast_switch::matchmore, ast_sw::name, ast_context::name, ast_context::next, ast_include::next, ast_sw::next, ast_exten::next, pbx_findswitch(), pbx_substitute_variables_helper(), ast_exten::peer, ast_exten::priority, ast_include::rname, ast_context::root, STATUS_NO_CONTEXT, STATUS_NO_EXTENSION, STATUS_NO_LABEL, STATUS_NO_PRIORITY, STATUS_SUCCESS, SWITCH_DATA_LENGTH, and ast_sw::tmpdata.
Referenced by ast_hint_extension(), and pbx_extension_helper().
00799 { 00800 int x, res; 00801 struct ast_context *tmp; 00802 struct ast_exten *e, *eroot; 00803 struct ast_include *i; 00804 struct ast_sw *sw; 00805 struct ast_switch *asw; 00806 00807 /* Initialize status if appropriate */ 00808 if (!*stacklen) { 00809 *status = STATUS_NO_CONTEXT; 00810 *swo = NULL; 00811 *data = NULL; 00812 } 00813 /* Check for stack overflow */ 00814 if (*stacklen >= AST_PBX_MAX_STACK) { 00815 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n"); 00816 return NULL; 00817 } 00818 /* Check first to see if we've already been checked */ 00819 for (x=0; x<*stacklen; x++) { 00820 if (!strcasecmp(incstack[x], context)) 00821 return NULL; 00822 } 00823 if (bypass) 00824 tmp = bypass; 00825 else 00826 tmp = contexts; 00827 while(tmp) { 00828 /* Match context */ 00829 if (bypass || !strcmp(tmp->name, context)) { 00830 struct ast_exten *earlymatch = NULL; 00831 00832 if (*status < STATUS_NO_EXTENSION) 00833 *status = STATUS_NO_EXTENSION; 00834 for (eroot = tmp->root; eroot; eroot=eroot->next) { 00835 int match = 0; 00836 /* Match extension */ 00837 if ((((action != HELPER_MATCHMORE) && ast_extension_match(eroot->exten, exten)) || 00838 ((action == HELPER_CANMATCH) && (ast_extension_close(eroot->exten, exten, 0))) || 00839 ((action == HELPER_MATCHMORE) && (match = ast_extension_close(eroot->exten, exten, 1)))) && 00840 (!eroot->matchcid || matchcid(eroot->cidmatch, callerid))) { 00841 00842 if (action == HELPER_MATCHMORE && match == 2 && !earlymatch) { 00843 /* It matched an extension ending in a '!' wildcard 00844 So ignore it for now, unless there's a better match */ 00845 earlymatch = eroot; 00846 } else { 00847 e = eroot; 00848 if (*status < STATUS_NO_PRIORITY) 00849 *status = STATUS_NO_PRIORITY; 00850 while(e) { 00851 /* Match priority */ 00852 if (action == HELPER_FINDLABEL) { 00853 if (*status < STATUS_NO_LABEL) 00854 *status = STATUS_NO_LABEL; 00855 if (label && e->label && !strcmp(label, e->label)) { 00856 *status = STATUS_SUCCESS; 00857 *foundcontext = context; 00858 return e; 00859 } 00860 } else if (e->priority == priority) { 00861 *status = STATUS_SUCCESS; 00862 *foundcontext = context; 00863 return e; 00864 } 00865 e = e->peer; 00866 } 00867 } 00868 } 00869 } 00870 if (earlymatch) { 00871 /* Bizarre logic for HELPER_MATCHMORE. We return zero to break out 00872 of the loop waiting for more digits, and _then_ match (normally) 00873 the extension we ended up with. We got an early-matching wildcard 00874 pattern, so return NULL to break out of the loop. */ 00875 return NULL; 00876 } 00877 /* Check alternative switches */ 00878 sw = tmp->alts; 00879 while(sw) { 00880 if ((asw = pbx_findswitch(sw->name))) { 00881 /* Substitute variables now */ 00882 if (sw->eval) 00883 pbx_substitute_variables_helper(chan, sw->data, sw->tmpdata, SWITCH_DATA_LENGTH - 1); 00884 if (action == HELPER_CANMATCH) 00885 res = asw->canmatch ? asw->canmatch(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0; 00886 else if (action == HELPER_MATCHMORE) 00887 res = asw->matchmore ? asw->matchmore(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0; 00888 else 00889 res = asw->exists ? asw->exists(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0; 00890 if (res) { 00891 /* Got a match */ 00892 *swo = asw; 00893 *data = sw->eval ? sw->tmpdata : sw->data; 00894 *foundcontext = context; 00895 return NULL; 00896 } 00897 } else { 00898 ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name); 00899 } 00900 sw = sw->next; 00901 } 00902 /* Setup the stack */ 00903 incstack[*stacklen] = tmp->name; 00904 (*stacklen)++; 00905 /* Now try any includes we have in this context */ 00906 i = tmp->includes; 00907 while(i) { 00908 if (include_valid(i)) { 00909 if ((e = pbx_find_extension(chan, bypass, i->rname, exten, priority, label, callerid, action, incstack, stacklen, status, swo, data, foundcontext))) 00910 return e; 00911 if (*swo) 00912 return NULL; 00913 } 00914 i = i->next; 00915 } 00916 break; 00917 } 00918 tmp = tmp->next; 00919 } 00920 return NULL; 00921 }
| struct ast_app* pbx_findapp | ( | const char * | app | ) | [read] |
Find application handle in linked list.
Look up an application
| 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 597 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, ast_app::name, and ast_app::next.
Referenced by ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dial_exec_full(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), and realtime_exec().
00598 { 00599 struct ast_app *tmp; 00600 00601 if (ast_mutex_lock(&applock)) { 00602 ast_log(LOG_WARNING, "Unable to obtain application lock\n"); 00603 return NULL; 00604 } 00605 tmp = apps; 00606 while(tmp) { 00607 if (!strcasecmp(tmp->name, app)) 00608 break; 00609 tmp = tmp->next; 00610 } 00611 ast_mutex_unlock(&applock); 00612 return tmp; 00613 }
| static struct ast_switch* pbx_findswitch | ( | const char * | sw | ) | [static, read] |
Definition at line 615 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, ast_switch::name, and ast_switch::next.
Referenced by pbx_find_extension().
00616 { 00617 struct ast_switch *asw; 00618 00619 if (ast_mutex_lock(&switchlock)) { 00620 ast_log(LOG_WARNING, "Unable to obtain application lock\n"); 00621 return NULL; 00622 } 00623 asw = switches; 00624 while(asw) { 00625 if (!strcasecmp(asw->name, sw)) 00626 break; 00627 asw = asw->next; 00628 } 00629 ast_mutex_unlock(&switchlock); 00630 return asw; 00631 }
| void pbx_retrieve_variable | ( | struct ast_channel * | c, | |
| const char * | var, | |||
| char ** | ret, | |||
| char * | workspace, | |||
| int | workspacelen, | |||
| struct varshead * | headp | |||
| ) |
pbx_retrieve_variable: Support for Asterisk built-in variables ---
Definition at line 999 of file pbx.c.
References ast_channel::accountcode, ast_get_hint(), AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_ani2, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, globals, ast_channel::hangupcause, ast_channel::language, LOG_WARNING, ast_channel::name, offset, parse_variable_name(), pbx_retrieve_variable(), ast_channel::priority, substring(), ast_channel::uniqueid, and ast_channel::varshead.
Referenced by handle_getvariable(), pbx_retrieve_variable(), and pbx_substitute_variables_helper_full().
01000 { 01001 char tmpvar[80]; 01002 time_t thistime; 01003 struct tm brokentime; 01004 int offset, offset2, isfunc; 01005 struct ast_var_t *variables; 01006 01007 if (c) 01008 headp=&c->varshead; 01009 *ret=NULL; 01010 ast_copy_string(tmpvar, var, sizeof(tmpvar)); 01011 if (parse_variable_name(tmpvar, &offset, &offset2, &isfunc)) { 01012 pbx_retrieve_variable(c, tmpvar, ret, workspace, workspacelen, headp); 01013 if (!(*ret)) 01014 return; 01015 *ret = substring(*ret, offset, offset2, workspace, workspacelen); 01016 } else if (c && !strncmp(var, "CALL", 4)) { 01017 if (!strncmp(var + 4, "ER", 2)) { 01018 if (!strncmp(var + 6, "ID", 2)) { 01019 if (!var[8]) { /* CALLERID */ 01020 if (c->cid.cid_num) { 01021 if (c->cid.cid_name) { 01022 snprintf(workspace, workspacelen, "\"%s\" <%s>", c->cid.cid_name, c->cid.cid_num); 01023 } else { 01024 ast_copy_string(workspace, c->cid.cid_num, workspacelen); 01025 } 01026 *ret = workspace; 01027 } else if (c->cid.cid_name) { 01028 ast_copy_string(workspace, c->cid.cid_name, workspacelen); 01029 *ret = workspace; 01030 } else 01031 *ret = NULL; 01032 } else if (!strcmp(var + 8, "NUM")) { 01033 /* CALLERIDNUM */ 01034 if (c->cid.cid_num) { 01035 ast_copy_string(workspace, c->cid.cid_num, workspacelen); 01036 *ret = workspace; 01037 } else 01038 *ret = NULL; 01039 } else if (!strcmp(var + 8, "NAME")) { 01040 /* CALLERIDNAME */ 01041 if (c->cid.cid_name) { 01042 ast_copy_string(workspace, c->cid.cid_name, workspacelen); 01043 *ret = workspace; 01044 } else 01045 *ret = NULL; 01046 } else 01047 goto icky; 01048 } else if (!strcmp(var + 6, "ANI")) { 01049 /* CALLERANI */ 01050 if (c->cid.cid_ani) { 01051 ast_copy_string(workspace, c->cid.cid_ani, workspacelen); 01052 *ret = workspace; 01053 } else 01054 *ret = NULL; 01055 } else 01056 goto icky; 01057 } else if (!strncmp(var + 4, "ING", 3)) { 01058 if (!strcmp(var + 7, "PRES")) { 01059 /* CALLINGPRES */ 01060 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 01061 *ret = workspace; 01062 } else if (!strcmp(var + 7, "ANI2")) { 01063 /* CALLINGANI2 */ 01064 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 01065 *ret = workspace; 01066 } else if (!strcmp(var + 7, "TON")) { 01067 /* CALLINGTON */ 01068 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 01069 *ret = workspace; 01070 } else if (!strcmp(var + 7, "TNS")) { 01071 /* CALLINGTNS */ 01072 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 01073 *ret = workspace; 01074 } else 01075 goto icky; 01076 } else 01077 goto icky; 01078 } else if (c && !strcmp(var, "DNID")) { 01079 if (c->cid.cid_dnid) { 01080 ast_copy_string(workspace, c->cid.cid_dnid, workspacelen); 01081 *ret = workspace; 01082 } else 01083 *ret = NULL; 01084 } else if (c && !strcmp(var, "HINT")) { 01085 if (!ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten)) 01086 *ret = NULL; 01087 else 01088 *ret = workspace; 01089 } else if (c && !strcmp(var, "HINTNAME")) { 01090 if (!ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten)) 01091 *ret = NULL; 01092 else 01093 *ret = workspace; 01094 } else if (c && !strcmp(var, "EXTEN")) { 01095 ast_copy_string(workspace, c->exten, workspacelen); 01096 *ret = workspace; 01097 } else if (c && !strcmp(var, "RDNIS")) { 01098 if (c->cid.cid_rdnis) { 01099 ast_copy_string(workspace, c->cid.cid_rdnis, workspacelen); 01100 *ret = workspace; 01101 } else 01102 *ret = NULL; 01103 } else if (c && !strcmp(var, "CONTEXT")) { 01104 ast_copy_string(workspace, c->context, workspacelen); 01105 *ret = workspace; 01106 } else if (c && !strcmp(var, "PRIORITY")) { 01107 snprintf(workspace, workspacelen, "%d", c->priority); 01108 *ret = workspace; 01109 } else if (c && !strcmp(var, "CHANNEL")) { 01110 ast_copy_string(workspace, c->name, workspacelen); 01111 *ret = workspace; 01112 } else if (!strcmp(var, "EPOCH")) { 01113 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 01114 *ret = workspace; 01115 } else if (!strcmp(var, "DATETIME")) { 01116 thistime=time(NULL); 01117 localtime_r(&thistime, &brokentime); 01118 snprintf(workspace, workspacelen, "%02d%02d%04d-%02d:%02d:%02d", 01119 brokentime.tm_mday, 01120 brokentime.tm_mon+1, 01121 brokentime.tm_year+1900, 01122 brokentime.tm_hour, 01123 brokentime.tm_min, 01124 brokentime.tm_sec 01125 ); 01126 *ret = workspace; 01127 } else if (!strcmp(var, "TIMESTAMP")) { 01128 thistime=time(NULL); 01129 localtime_r(&thistime, &brokentime); 01130 /* 20031130-150612 */ 01131 snprintf(workspace, workspacelen, "%04d%02d%02d-%02d%02d%02d", 01132 brokentime.tm_year+1900, 01133 brokentime.tm_mon+1, 01134 brokentime.tm_mday, 01135 brokentime.tm_hour, 01136 brokentime.tm_min, 01137 brokentime.tm_sec 01138 ); 01139 *ret = workspace; 01140 } else if (c && !strcmp(var, "UNIQUEID")) { 01141 snprintf(workspace, workspacelen, "%s", c->uniqueid); 01142 *ret = workspace; 01143 } else if (c && !strcmp(var, "HANGUPCAUSE")) { 01144 snprintf(workspace, workspacelen, "%d", c->hangupcause); 01145 *ret = workspace; 01146 } else if (c && !strcmp(var, "ACCOUNTCODE")) { 01147 ast_copy_string(workspace, c->accountcode, workspacelen); 01148 *ret = workspace; 01149 } else if (c && !strcmp(var, "LANGUAGE")) { 01150 ast_copy_string(workspace, c->language, workspacelen); 01151 *ret = workspace; 01152 } else { 01153 icky: 01154 if (headp) { 01155 AST_LIST_TRAVERSE(headp,variables,entries) { 01156 #if 0 01157 ast_log(LOG_WARNING,"Comparing variable '%s' with '%s'\n",var,ast_var_name(variables)); 01158 #endif 01159 if (strcasecmp(ast_var_name(variables),var)==0) { 01160 *ret=ast_var_value(variables); 01161 if (*ret) { 01162 ast_copy_string(workspace, *ret, workspacelen); 01163 *ret = workspace; 01164 } 01165 break; 01166 } 01167 } 01168 } 01169 if (!(*ret)) { 01170 /* Try globals */ 01171 ast_mutex_lock(&globalslock); 01172 AST_LIST_TRAVERSE(&globals,variables,entries) { 01173 if (strcasecmp(ast_var_name(variables),var)==0) { 01174 *ret = ast_var_value(variables); 01175 if (*ret) { 01176 ast_copy_string(workspace, *ret, workspacelen); 01177 *ret = workspace; 01178 } 01179 } 01180 } 01181 ast_mutex_unlock(&globalslock); 01182 } 01183 } 01184 }
| int pbx_set_autofallthrough | ( | int | newval | ) |
Definition at line 2589 of file pbx.c.
Referenced by pbx_load_module().
02590 { 02591 int oldval; 02592 oldval = autofallthrough; 02593 if (oldval != newval) 02594 autofallthrough = newval; 02595 return oldval; 02596 }
| static void pbx_substitute_variables | ( | char * | passdata, | |
| int | datalen, | |||
| struct ast_channel * | c, | |||
| struct ast_exten * | e | |||
| ) | [static] |
Definition at line 1628 of file pbx.c.
References ast_exten::data, and pbx_substitute_variables_helper().
Referenced by pbx_extension_helper().
01629 { 01630 memset(passdata, 0, datalen); 01631 01632 /* No variables or expressions in e->data, so why scan it? */ 01633 if (!strchr(e->data, '$') && !strstr(e->data,"${") && !strstr(e->data,"$[") && !strstr(e->data,"$(")) { 01634 ast_copy_string(passdata, e->data, datalen); 01635 return; 01636 } 01637 01638 pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1); 01639 }
| void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
| const char * | cp1, | |||
| char * | cp2, | |||
| int | count | |||
| ) |
Definition at line 1618 of file pbx.c.
References pbx_substitute_variables_helper_full(), and ast_channel::varshead.
Referenced by custom_log(), cut_internal(), eval_exec(), exec_exec(), function_eval(), function_fieldqty(), handle_getvariablefull(), launch_monitor_thread(), macro_exec(), pbx_builtin_importvar(), pbx_find_extension(), pbx_load_module(), pbx_substitute_variables(), realtime_exec(), rpt_exec(), sendmail(), and sendpage().
01619 { 01620 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 01621 }
| static void pbx_substitute_variables_helper_full | ( | struct ast_channel * | c, | |
| struct varshead * | headp, | |||
| const char * | cp1, | |||
| char * | cp2, | |||
| int | count | |||
| ) | [static] |
Definition at line 1441 of file pbx.c.
References ast_expr(), ast_func_read(), ast_log(), ast_strlen_zero(), LOG_DEBUG, LOG_NOTICE, offset, parse_variable_name(), pbx_retrieve_variable(), substring(), var, and VAR_BUF_SIZE.
Referenced by pbx_substitute_variables_helper(), and pbx_substitute_variables_varshead().
01442 { 01443 char *cp4; 01444 const char *tmp, *whereweare; 01445 int length, offset, offset2, isfunction; 01446 char *workspace = NULL; 01447 char *ltmp = NULL, *var = NULL; 01448 char *nextvar, *nextexp, *nextthing; 01449 char *vars, *vare; 01450 int pos, brackets, needsub, len; 01451 01452 /* Substitutes variables into cp2, based on string cp1, and assuming cp2 to be 01453 zero-filled */ 01454 whereweare=tmp=cp1; 01455 while(!ast_strlen_zero(whereweare) && count) { 01456 /* Assume we're copying the whole remaining string */ 01457 pos = strlen(whereweare); 01458 nextvar = NULL; 01459 nextexp = NULL; 01460 nextthing = strchr(whereweare, '$'); 01461 if (nextthing) { 01462 switch(nextthing[1]) { 01463 case '{': 01464 nextvar = nextthing; 01465 pos = nextvar - whereweare; 01466 break; 01467 case '[': 01468 nextexp = nextthing; 01469 pos = nextexp - whereweare; 01470 break; 01471 } 01472 } 01473 01474 if (pos) { 01475 /* Can't copy more than 'count' bytes */ 01476 if (pos > count) 01477 pos = count; 01478 01479 /* Copy that many bytes */ 01480 memcpy(cp2, whereweare, pos); 01481 01482 count -= pos; 01483 cp2 += pos; 01484 whereweare += pos; 01485 } 01486 01487 if (nextvar) { 01488 /* We have a variable. Find the start and end, and determine 01489 if we are going to have to recursively call ourselves on the 01490 contents */ 01491 vars = vare = nextvar + 2; 01492 brackets = 1; 01493 needsub = 0; 01494 01495 /* Find the end of it */ 01496 while (brackets && *vare) { 01497 if ((vare[0] == '$') && (vare[1] == '{')) { 01498 needsub++; 01499 } else if (vare[0] == '{') { 01500 brackets++; 01501 } else if (vare[0] == '}') { 01502 brackets--; 01503 } else if ((vare[0] == '$') && (vare[1] == '[')) 01504 needsub++; 01505 vare++; 01506 } 01507 if (brackets) 01508 ast_log(LOG_NOTICE, "Error in extension logic (missing '}')\n"); 01509 len = vare - vars - 1; 01510 01511 /* Skip totally over variable string */ 01512 whereweare += (len + 3); 01513 01514 if (!var) 01515 var = alloca(VAR_BUF_SIZE); 01516 01517 /* Store variable name (and truncate) */ 01518 ast_copy_string(var, vars, len + 1); 01519 01520 /* Substitute if necessary */ 01521 if (needsub) { 01522 if (!ltmp) 01523 ltmp = alloca(VAR_BUF_SIZE); 01524 01525 memset(ltmp, 0, VAR_BUF_SIZE); 01526 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1); 01527 vars = ltmp; 01528 } else { 01529 vars = var; 01530 } 01531 01532 if (!workspace) 01533 workspace = alloca(VAR_BUF_SIZE); 01534 01535 workspace[0] = '\0'; 01536 01537 parse_variable_name(vars, &offset, &offset2, &isfunction); 01538 if (isfunction) { 01539 /* Evaluate function */ 01540 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE); 01541 01542 ast_log(LOG_DEBUG, "Function result is '%s'\n", cp4 ? cp4 : "(null)"); 01543 } else { 01544 /* Retrieve variable value */ 01545 pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp); 01546