![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
pbx.h File Reference
Definition in file pbx.h.
#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/linkedlists.h"
Include dependency graph for pbx.h:

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

Go to the source code of this file.
Data Structures | |
| struct | ast_custom_function |
| Data structure associated with a custom dialplan function. More... | |
| struct | ast_pbx |
| struct | ast_switch |
| struct | ast_timing |
| Functions for returning values from structures | |
| const char * | ast_get_context_name (struct ast_context *con) |
| ast_context * | ast_get_extension_context (struct ast_exten *exten) |
| const char * | ast_get_extension_name (struct ast_exten *exten) |
| const char * | ast_get_ignorepat_name (struct ast_ignorepat *ip) |
| const char * | ast_get_include_name (struct ast_include *include) |
| const char * | ast_get_switch_data (struct ast_sw *sw) |
| const char * | ast_get_switch_name (struct ast_sw *sw) |
Registrar info functions ... | |
| const char * | ast_get_context_registrar (struct ast_context *c) |
| const char * | ast_get_extension_registrar (struct ast_exten *e) |
| const char * | ast_get_ignorepat_registrar (struct ast_ignorepat *ip) |
| const char * | ast_get_include_registrar (struct ast_include *i) |
| const char * | ast_get_switch_registrar (struct ast_sw *sw) |
Other Extension stuff | |
| const char * | ast_get_extension_app (struct ast_exten *e) |
| void * | ast_get_extension_app_data (struct ast_exten *e) |
| const char * | ast_get_extension_cidmatch (struct ast_exten *e) |
| const char * | ast_get_extension_label (struct ast_exten *e) |
| int | ast_get_extension_matchcid (struct ast_exten *e) |
| int | ast_get_extension_priority (struct ast_exten *exten) |
Defines | |
| #define | AST_MAX_APP 32 |
| #define | AST_PBX_KEEP 0 |
| #define | AST_PBX_KEEPALIVE 10 |
| Special return values from applications to the PBX {. | |
| #define | AST_PBX_NO_HANGUP_PEER 11 |
| #define | AST_PBX_REPLACE 1 |
| #define | PRIORITY_HINT -1 |
Typedefs | |
| typedef int(* | ast_state_cb_type )(char *context, char *id, enum ast_extension_states state, void *data) |
| Typedef for devicestate and hint callbacks. | |
| typedef int() | ast_switch_f (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| All switch functions have the same interface, so define a type for them. | |
Enumerations | |
| enum | ast_extension_states { AST_EXTENSION_REMOVED = -2, AST_EXTENSION_DEACTIVATED = -1, AST_EXTENSION_NOT_INUSE = 0, AST_EXTENSION_INUSE = 1 << 0, AST_EXTENSION_BUSY = 1 << 1, AST_EXTENSION_UNAVAILABLE = 1 << 2, AST_EXTENSION_RINGING = 1 << 3, AST_EXTENSION_ONHOLD = 1 << 4 } |
| Extension states. More... | |
| enum | ast_pbx_result { AST_PBX_SUCCESS = 0, AST_PBX_FAILED = -1, AST_PBX_CALL_LIMIT = -2 } |
| The result codes when starting the PBX on a channel with ast_pbx_start(). More... | |
Functions | |
| int | ast_active_calls (void) |
| Retrieve the number of active calls. | |
| int | ast_add_extension (const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar) |
| Add and extension to an extension context. | |
| int | ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar) |
| Add an extension to an extension context, this time with an ast_context *. | |
| int | ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority) |
| int | ast_async_goto_by_name (const char *chan, const char *context, const char *exten, int priority) |
| int | ast_async_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
| int | ast_build_timing (struct ast_timing *i, const char *info) |
| int | ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| Looks for a valid matching extension. | |
| int | ast_check_timing (const struct ast_timing *i) |
| int | ast_context_add_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
| Add an ignorepat. | |
| int | ast_context_add_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar) |
| int | ast_context_add_include (const char *context, const char *include, const char *registrar) |
| Add a context include. | |
| int | ast_context_add_include2 (struct ast_context *con, const char *include, const char *registrar) |
| Add a context include. | |
| int | ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar) |
| Add a switch. | |
| int | ast_context_add_switch2 (struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar) |
| Adds a switch (first param is a ast_context). | |
| ast_context * | ast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar) |
| Register a new context. | |
| void | ast_context_destroy (struct ast_context *con, const char *registrar) |
| Destroy a context (matches the specified context (or ANY context if NULL). | |
| ast_context * | ast_context_find (const char *name) |
| Find a context. | |
| ast_context * | ast_context_find_or_create (struct ast_context **extcontexts, const char *name, const char *registrar) |
| Register a new context or find an existing one. | |
| int | ast_context_lockmacro (const char *macrocontext) |
| locks the macrolock in the given given context | |
| int | ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar) |
| Simply remove extension from context. | |
| int | ast_context_remove_extension2 (struct ast_context *con, const char *extension, int priority, const char *registrar) |
| This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return. | |
| int | ast_context_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
| int | ast_context_remove_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar) |
| int | ast_context_remove_include (const char *context, const char *include, const char *registrar) |
| Remove a context include. | |
| int | ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar) |
| Removes an include by an ast_context structure. | |
| int | ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar) |
| Remove a switch. | |
| int | ast_context_remove_switch2 (struct ast_context *con, const char *sw, const char *data, const char *registrar) |
| This function locks given context, removes switch, unlock context and return. | |
| int | ast_context_unlockmacro (const char *macrocontext) |
| Unlocks the macrolock in the given context. | |
| int | ast_context_verify_includes (struct ast_context *con) |
| Verifies includes in an ast_contect structure. | |
| ast_custom_function * | ast_custom_function_find (const char *name) |
| int | ast_custom_function_register (struct ast_custom_function *acf) |
| Reigster a custom function. | |
| int | ast_custom_function_unregister (struct ast_custom_function *acf) |
| Unregister a custom function. | |
| int | ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| Determine whether an extension exists. | |
| int | ast_explicit_goto (struct ast_channel *chan, const char *context, const char *exten, int priority) |
| int | ast_extension_close (const char *pattern, const char *data, int needmore) |
| int | ast_extension_match (const char *pattern, const char *extension) |
| Determine if a given extension matches a given pattern (in NXX format). | |
| int | ast_extension_patmatch (const char *pattern, const char *data) |
| int | ast_extension_state (struct ast_channel *c, const char *context, const char *exten) |
| Uses hint and devicestate callback to get the state of an extension. | |
| const char * | ast_extension_state2str (int extension_state) |
| Return string representation of the state of an extension. | |
| int | ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data) |
| Registers a state change callback. | |
| int | ast_extension_state_del (int id, ast_state_cb_type callback) |
| Deletes a registered state change callback by ID. | |
| int | ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid) |
| Find the priority of an extension that has the specified label. | |
| int | ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid) |
| Find the priority of an extension that has the specified label. | |
| int | ast_func_read (struct ast_channel *chan, const char *function, char *workspace, size_t len) |
| executes a read operation on a function | |
| int | ast_func_write (struct ast_channel *chan, const char *function, const char *value) |
| executes a write operation on a function | |
| int | ast_get_hint (char *hint, int maxlen, char *name, int maxnamelen, struct ast_channel *c, const char *context, const char *exten) |
| If an extension hint exists, return non-zero. | |
| int | ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
| void | ast_hint_state_changed (const char *device) |
| int | ast_ignore_pattern (const char *context, const char *pattern) |
| Checks to see if a number should be ignored. | |
| int | ast_lock_context (struct ast_context *con) |
| Locks a given context. | |
| int | ast_lock_contexts (void) |
| Locks the context list. | |
| int | ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| Looks to see if adding anything to this extension might match something. (exists ^ canmatch). | |
| void | ast_merge_contexts_and_delete (struct ast_context **extcontexts, const char *registrar) |
| Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added. | |
| int | ast_parseable_goto (struct ast_channel *chan, const char *goto_string) |
| int | ast_pbx_outgoing_app (const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) |
| int | ast_pbx_outgoing_exten (const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) |
| enum ast_pbx_result | ast_pbx_run (struct ast_channel *c) |
| Execute the PBX in the current thread. | |
| enum ast_pbx_result | ast_pbx_start (struct ast_channel *c) |
| Create a new thread and start the PBX. | |
| int | ast_register_application (const char *app, int(*execute)(struct ast_channel *, void *), const char *synopsis, const char *description) |
| Register an application. | |
| int | ast_register_switch (struct ast_switch *sw) |
| Register an alternative dialplan switch. | |
| int | ast_spawn_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
| Launch a new extension (i.e. new stack). | |
| int | ast_unlock_context (struct ast_context *con) |
| int | ast_unlock_contexts (void) |
| Unlocks contexts. | |
| int | ast_unregister_application (const char *app) |
| Unregister an application. | |
| void | ast_unregister_switch (struct ast_switch *sw) |
| Unregister an alternative switch. | |
| ast_exten * | ast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority) |
| ast_ignorepat * | ast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip) |
| ast_include * | ast_walk_context_includes (struct ast_context *con, struct ast_include *inc) |
| ast_sw * | ast_walk_context_switches (struct ast_context *con, struct ast_sw *sw) |
| ast_context * | ast_walk_contexts (struct ast_context *con) |
| ast_exten * | ast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority) |
| void | pbx_builtin_clear_globals (void) |
| const char * | pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name) |
| void | pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value) |
| int | pbx_builtin_serialize_variables (struct ast_channel *chan, struct ast_str **buf) |
| int | pbx_builtin_setvar (struct ast_channel *chan, void *data) |
| void | pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value) |
| int | pbx_checkcondition (const char *condition) |
| Evaluate a condition. | |
| int | pbx_exec (struct ast_channel *c, struct ast_app *app, void *data) |
| Execute an application. | |
| ast_app * | pbx_findapp (const char *app) |
| Look up an application. | |
| void | pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp) |
| Support for Asterisk built-in variables in the dialplan. | |
| int | pbx_set_autofallthrough (int newval) |
| void | pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count) |
| void | pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count) |
|
|
Max length of an application Definition at line 34 of file pbx.h. Referenced by handle_show_application(), and handle_show_function(). |
|
|
|
|
|
Special return values from applications to the PBX {. Destroy the thread, but don't hang up the channel Definition at line 40 of file pbx.h. Referenced by agi_handle_command(), builtin_blindtransfer(), builtin_parkcall(), feature_exec_app(), park_call_exec(), and run_agi(). |
|
|
Definition at line 41 of file pbx.h. Referenced by builtin_blindtransfer(), builtin_parkcall(), feature_exec_app(), and park_exec(). |
|
|
|
|
|
} Special Priority for a hint Definition at line 44 of file pbx.h. Referenced by add_extensions(), ast_add_extension2(), ast_hint_extension(), destroy_exten(), handle_context_add_extension(), handle_context_remove_extension(), handle_save_dialplan(), manager_show_dialplan_helper(), park_add_hints(), and print_ext(). |
|
|
Typedef for devicestate and hint callbacks.
|
|
|
All switch functions have the same interface, so define a type for them. Data structure associated with an Asterisk switch |
|
|
Extension states.
Definition at line 50 of file pbx.h. 00050 { 00051 AST_EXTENSION_REMOVED = -2, /*!< Extension removed */ 00052 AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */ 00053 AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */ 00054 AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */ 00055 AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */ 00056 AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */ 00057 AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */ 00058 AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */ 00059 };
|
|
|
The result codes when starting the PBX on a channel with ast_pbx_start(). AST_PBX_CALL_LIMIT refers to the maxcalls call limit in asterisk.conf Definition at line 236 of file pbx.h. 00236 { 00237 AST_PBX_SUCCESS = 0, 00238 AST_PBX_FAILED = -1, 00239 AST_PBX_CALL_LIMIT = -2, 00240 };
|
|
|
Retrieve the number of active calls.
Definition at line 2530 of file pbx.c. References countcalls. Referenced by handle_chanlist(). 02531 { 02532 return countcalls; 02533 }
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
Add and extension to an extension context.
Definition at line 4448 of file pbx.c. References ast_add_extension2(), ast_unlock_contexts(), and find_context_locked(). Referenced by handle_context_add_extension(), park_add_hints(), and register_peer_exten(). 04451 { 04452 int ret = -1; 04453 struct ast_context *c = find_context_locked(context); 04454 04455 if (c) { 04456 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04457 application, data, datad, registrar); 04458 ast_unlock_contexts(); 04459 } 04460 return ret; 04461 }
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
Add an extension to an extension context, this time with an ast_context *. We sort extensions in order of matching preference, so that we can stop the search as soon as we find a suitable match. This ordering also takes care of wildcards such as '.' (meaning "one or more of any character") and '!' (which is 'earlymatch', meaning "zero or more of any character" but also impacts the return value from CANMATCH and EARLYMATCH. The extension match rules defined in the devmeeting 2006.05.05 are quite simple: WE SELECT THE LONGEST MATCH. In detail, "longest" means the number of matched characters in the extension. In case of ties (e.g. _XXX and 333) in the length of a pattern, we give priority to entries with the smallest cardinality (e.g, [5-9] comes before [2-8] before the former has only 5 elements, while the latter has 7, etc. In case of same cardinality, the first element in the range counts. If we still have a tie, any final '!' will make this as a possibly less specific pattern. EBUSY - can't lock EEXIST - extension with the same priority exist and no replace is set Definition at line 4649 of file pbx.c. References add_pri(), ast_exten::app, ast_add_hint(), ast_calloc, AST_LIST_FIRST, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_verbose(), ast_exten::cidmatch, ast_exten::data, ast_exten::datad, el, ext_cmp(), ext_strncpy(), ast_exten::exten, ast_exten::label, ast_context::lock, ast_exten::matchcid, ast_exten::next, option_verbose, ast_exten::parent, pbx_substitute_variables_varshead(), ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, ast_context::root, ast_exten::stuff, VAR_BUF_SIZE, and VERBOSE_PREFIX_3. Referenced by add_extensions(), ast_add_extension(), and do_parking_thread(). 04653 { 04654 /* 04655 * Sort extensions (or patterns) according to the rules indicated above. 04656 * These are implemented by the function ext_cmp()). 04657 * All priorities for the same ext/pattern/cid are kept in a list, 04658 * using the 'peer' field as a link field.. 04659 */ 04660 struct ast_exten *tmp, *e, *el = NULL; 04661 int res; 04662 int length; 04663 char *p; 04664 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04665 04666 /* if we are adding a hint, and there are global variables, and the hint 04667 contains variable references, then expand them 04668 */ 04669 ast_rwlock_rdlock(&globalslock); 04670 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04671 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04672 application = expand_buf; 04673 } 04674 ast_rwlock_unlock(&globalslock); 04675 04676 length = sizeof(struct ast_exten); 04677 length += strlen(extension) + 1; 04678 length += strlen(application) + 1; 04679 if (label) 04680 length += strlen(label) + 1; 04681 if (callerid) 04682 length += strlen(callerid) + 1; 04683 else 04684 length ++; /* just the '\0' */ 04685 04686 /* Be optimistic: Build the extension structure first */ 04687 if (!(tmp = ast_calloc(1, length))) 04688 return -1; 04689 04690 /* use p as dst in assignments, as the fields are const char * */ 04691 p = tmp->stuff; 04692 if (label) { 04693 tmp->label = p; 04694 strcpy(p, label); 04695 p += strlen(label) + 1; 04696 } 04697 tmp->exten = p; 04698 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04699 tmp->priority = priority; 04700 tmp->cidmatch = p; /* but use p for assignments below */ 04701 if (callerid) { 04702 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04703 tmp->matchcid = 1; 04704 } else { 04705 *p++ = '\0'; 04706 tmp->matchcid = 0; 04707 } 04708 tmp->app = p; 04709 strcpy(p, application); 04710 tmp->parent = con; 04711 tmp->data = data; 04712 tmp->datad = datad; 04713 tmp->registrar = registrar; 04714 04715 ast_mutex_lock(&con->lock); 04716 res = 0; /* some compilers will think it is uninitialized otherwise */ 04717 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04718 res = ext_cmp(e->exten, extension); 04719 if (res == 0) { /* extension match, now look at cidmatch */ 04720 if (!e->matchcid && !tmp->matchcid) 04721 res = 0; 04722 else if (tmp->matchcid && !e->matchcid) 04723 res = 1; 04724 else if (e->matchcid && !tmp->matchcid) 04725 res = -1; 04726 else 04727 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04728 } 04729 if (res >= 0) 04730 break; 04731 } 04732 if (e && res == 0) { /* exact match, insert in the pri chain */ 04733 res = add_pri(con, tmp, el, e, replace); 04734 ast_mutex_unlock(&con->lock); 04735 if (res < 0) { 04736 errno = EEXIST; /* XXX do we care ? */ 04737 return 0; /* XXX should we return -1 maybe ? */ 04738 } 04739 } else { 04740 /* 04741 * not an exact match, this is the first entry with this pattern, 04742 * so insert in the main list right before 'e' (if any) 04743 */ 04744 tmp->next = e; 04745 if (el) 04746 el->next = tmp; 04747 else 04748 con->root = tmp; 04749 ast_mutex_unlock(&con->lock); 04750 if (tmp->priority == PRIORITY_HINT) 04751 ast_add_hint(tmp); 04752 } 04753 if (option_debug) { 04754 if (tmp->matchcid) { 04755 if (option_debug) 04756 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04757 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04758 } else { 04759 if (option_debug) 04760 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04761 tmp->exten, tmp->priority, con->name); 04762 } 04763 } 04764 if (option_verbose > 2) { 04765 if (tmp->matchcid) { 04766 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04767 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04768 } else { 04769 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04770 tmp->exten, tmp->priority, con->name); 04771 } 04772 } 04773 return 0; 04774 }
|
|
||||||||||||||||||||
|
Definition at line 4482 of file pbx.c. References ast_channel::_state, ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_unlock, ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_pbx_start(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_channel::context, ast_channel::exten, LOG_WARNING, ast_channel::pbx, ast_channel::readformat, S_OR, and ast_channel::writeformat. Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), handle_request_bye(), handle_request_refer(), process_ast_dsp(), socket_process(), and zt_read(). 04483 { 04484 int res = 0; 04485 04486 ast_channel_lock(chan); 04487 04488 if (chan->pbx) { /* This channel is currently in the PBX */ 04489 ast_explicit_goto(chan, context, exten, priority); 04490 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04491 } else { 04492 /* In order to do it when the channel doesn't really exist within 04493 the PBX, we have to make a new channel, masquerade, and start the PBX 04494 at the new location */ 04495 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, "AsyncGoto/%s", chan->name); 04496 if (!tmpchan) 04497 res = -1; 04498 else { 04499 /* Make formats okay */ 04500 tmpchan->readformat = chan->readformat; 04501 tmpchan->writeformat = chan->writeformat; 04502 /* Setup proper location */ 04503 ast_explicit_goto(tmpchan, 04504 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04505 04506 /* Masquerade into temp channel */ 04507 ast_channel_masquerade(tmpchan, chan); 04508 04509 /* Grab the locks and get going */ 04510 ast_channel_lock(tmpchan); 04511 ast_do_masquerade(tmpchan); 04512 ast_channel_unlock(tmpchan); 04513 /* Start the PBX going on our stolen channel */ 04514 if (ast_pbx_start(tmpchan)) { 04515 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04516 ast_hangup(tmpchan); 04517 res = -1; 04518 } 04519 } 04520 } 04521 ast_channel_unlock(chan); 04522 return res; 04523 }
|
|
||||||||||||||||||||
|
Definition at line 4525 of file pbx.c. References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked(). 04526 { 04527 struct ast_channel *chan; 04528 int res = -1; 04529 04530 chan = ast_get_channel_by_name_locked(channame); 04531 if (chan) { 04532 res = ast_async_goto(chan, context, exten, priority); 04533 ast_channel_unlock(chan); 04534 } 04535 return res; 04536 }
|
|
||||||||||||||||||||
|
Definition at line 6185 of file pbx.c. References __ast_goto_if_exists(). 06186 { 06187 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06188 }
|
|
||||||||||||
|
Definition at line 4124 of file pbx.c. References ast_strlen_zero(), ast_timing::daymask, ast_timing::dowmask, get_range(), get_timerange(), ast_timing::monthmask, and strsep(). Referenced by ast_context_add_include2(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime(). 04125 { 04126 char info_save[256]; 04127 char *info; 04128 04129 /* Check for empty just in case */ 04130 if (ast_strlen_zero(info_in)) 04131 return 0; 04132 /* make a copy just in case we were passed a static string */ 04133 ast_copy_string(info_save, info_in, sizeof(info_save)); 04134 info = info_save; 04135 /* Assume everything except time */ 04136 i->monthmask = 0xfff; /* 12 bits */ 04137 i->daymask = 0x7fffffffU; /* 31 bits */ 04138 i->dowmask = 0x7f; /* 7 bits */ 04139 /* on each call, use strsep() to move info to the next argument */ 04140 get_timerange(i, strsep(&info, "|")); 04141 if (info) 04142 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04143 if (info) 04144 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04145 if (info) 04146 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04147 return 1; 04148 }
|
|
||||||||||||||||||||||||
|
Looks for a valid matching extension.
Definition at line 2158 of file pbx.c. References E_CANMATCH, and pbx_extension_helper(). Referenced by cb_events(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), loopback_canmatch(), mgcp_ss(), phone_check_exception(), skinny_ss(), and ss_thread(). 02159 { 02160 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH); 02161 }
|
|
|
Definition at line 4150 of file pbx.c. References ast_log(), ast_timing::daymask, ast_timing::dowmask, LOG_WARNING, ast_timing::minmask, and ast_timing::monthmask. Referenced by include_valid(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime(). 04151 { 04152 struct tm tm; 04153 time_t t = time(NULL); 04154 04155 localtime_r(&t,&tm); 04156 04157 /* If it's not the right month, return */ 04158 if (!(i->monthmask & (1 << tm.tm_mon))) 04159 return 0; 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 }
|
|
||||||||||||||||
|
Add an ignorepat.
Definition at line 4384 of file pbx.c. References ast_context_add_ignorepat2(), ast_unlock_contexts(), and find_context_locked(). Referenced by handle_context_add_ignorepat(). 04385 { 04386 int ret = -1; 04387 struct ast_context *c = find_context_locked(context); 04388 04389 if (c) { 04390 ret = ast_context_add_ignorepat2(c, value, registrar); 04391 ast_unlock_contexts(); 04392 } 04393 return ret; 04394 }
|
|
||||||||||||||||
|
Definition at line 4396 of file pbx.c. References ast_calloc, ast_mutex_lock(), ast_mutex_unlock(), ast_context::ignorepats, ast_context::lock, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar. Referenced by ast_compile_ael2(), and ast_context_add_ignorepat(). 04397 { 04398 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04399 int length; 04400 length = sizeof(struct ast_ignorepat); 04401 length += strlen(value) + 1; 04402 if (!(ignorepat = ast_calloc(1, length))) 04403 return -1; 04404 /* The cast to char * is because we need to write the initial value. 04405 * The field is not supposed to be modified otherwise 04406 */ 04407 strcpy((char *)ignorepat->pattern, value); 04408 ignorepat->next = NULL; 04409 ignorepat->registrar = registrar; 04410 ast_mutex_lock(&con->lock); 04411 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04412 ignorepatl = ignorepatc; 04413 if (!strcasecmp(ignorepatc->pattern, value)) { 04414 /* Already there */ 04415 ast_mutex_unlock(&con->lock); 04416 errno = EEXIST; 04417 return -1; 04418 } 04419 } 04420 if (ignorepatl) 04421 ignorepatl->next = ignorepat; 04422 else 04423 con->ignorepats = ignorepat; 04424 ast_mutex_unlock(&con->lock); 04425 return 0; 04426 04427 }
|
|
||||||||||||||||
|
Add a context include.
Definition at line 3930 of file pbx.c. References ast_context_add_include2(), ast_unlock_contexts(), and find_context_locked(). Referenced by handle_context_add_include(). 03931 { 03932 int ret = -1; 03933 struct ast_context *c = find_context_locked(context); 03934 03935 if (c) { 03936 ret = ast_context_add_include2(c, include, registrar); 03937 ast_unlock_contexts(); 03938 } 03939 return ret; 03940 }
|
|
||||||||||||||||
|
Add a context include.
Definition at line 4192 of file pbx.c. References ast_build_timing(), ast_calloc, ast_get_context_name(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, ast_include::hastime, ast_context::includes, ast_context::lock, ast_include::name, ast_include::next, option_verbose, ast_include::registrar, ast_include::rname, ast_include::stuff, ast_include::timing, and VERBOSE_PREFIX_3. Referenced by ast_compile_ael2(), and ast_context_add_include(). 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 = ast_calloc(1, length))) 04206 return -1; 04207 /* Fill in this structure. Use 'p' for assignments, as the fields 04208 * in the structure are 'const char *' 04209 */ 04210 p = new_include->stuff; 04211 new_include->name = p; 04212 strcpy(p, value); 04213 p += strlen(value) + 1; 04214 new_include->rname = p; 04215 strcpy(p, value); 04216 /* Strip off timing info, and process if it is there */ 04217 if ( (c = strchr(p, '|')) ) { 04218 *c++ = '\0'; 04219 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04220 } 04221 new_include->next = NULL; 04222 new_include->registrar = registrar; 04223 04224 ast_mutex_lock(&con->lock); 04225 04226 /* ... go to last include and check if context is already included too... */ 04227 for (i = con->includes; i; i = i->next) { 04228 if (!strcasecmp(i->name, new_include->name)) { 04229 free(new_include); 04230 ast_mutex_unlock(&con->lock); 04231 errno = EEXIST; 04232 return -1; 04233 } 04234 il = i; 04235 } 04236 04237 /* ... include new context into context list, unlock, return */ 04238 if (il) 04239 il->next = new_include; 04240 else 04241 con->includes = new_include; 04242 if (option_verbose > 2) 04243 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04244 ast_mutex_unlock(&con->lock); 04245 04246 return 0; 04247 }
|
|
||||||||||||||||||||||||
|
Add a switch.
Definition at line 4254 of file pbx.c. References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked(). 04255 { 04256 int ret = -1; 04257 struct ast_context *c = find_context_locked(context); 04258 04259 if (c) { /* found, add switch to this context */ 04260 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04261 ast_unlock_contexts(); 04262 } 04263 return ret; 04264 }
|
|
||||||||||||||||||||||||
|
Adds a switch (first param is a ast_context).
Definition at line 4273 of file pbx.c. References ast_calloc, ast_get_context_name(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_sw::data, ast_sw::eval, free, ast_context::lock, ast_sw::name, option_verbose, ast_sw::registrar, SWITCH_DATA_LENGTH, and VERBOSE_PREFIX_3. Referenced by ast_compile_ael2(), and ast_context_add_switch(). 04275 { 04276 struct ast_sw *new_sw; 04277 struct ast_sw *i; 04278 int length; 04279 char *p; 04280 04281 length = sizeof(struct ast_sw); 04282 length += strlen(value) + 1; 04283 if (data) 04284 length += strlen(data); 04285 length++; 04286 if (eval) { 04287 /* Create buffer for evaluation of variables */ 04288 length += SWITCH_DATA_LENGTH; 04289 length++; 04290 } 04291 04292 /* allocate new sw structure ... */ 04293 if (!(new_sw = ast_calloc(1, length))) 04294 return -1; 04295 /* ... fill in this structure ... */ 04296 p = new_sw->stuff; 04297 new_sw->name = p; 04298 strcpy(new_sw->name, value); 04299 p += strlen(value) + 1; 04300 new_sw->data = p; 04301 if (data) { 04302 strcpy(new_sw->data, data); 04303 p += strlen(data) + 1; 04304 } else { 04305 strcpy(new_sw->data, ""); 04306 p++; 04307 } 04308 if (eval) 04309 new_sw->tmpdata = p; 04310 new_sw->eval = eval; 04311 new_sw->registrar = registrar; 04312 04313 /* ... try to lock this context ... */ 04314 ast_mutex_lock(&con->lock); 04315 04316 /* ... go to last sw and check if context is already swd too... */ 04317 AST_LIST_TRAVERSE(&con->alts, i, list) { 04318 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04319 free(new_sw); 04320 ast_mutex_unlock(&con->lock); 04321 errno = EEXIST; 04322 return -1; 04323 } 04324 } 04325 04326 /* ... sw new context into context list, unlock, return */ 04327 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04328 04329 if (option_verbose > 2) 04330 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04331 04332 ast_mutex_unlock(&con->lock); 04333 04334 return 0; 04335 }
|
|
||||||||||||||||
|
Register a new context.
Definition at line 3801 of file pbx.c. References __ast_context_create(). Referenced by ast_compile_ael2(), do_parking_thread(), reload_config(), and set_config(). 03802 { 03803 return __ast_context_create(extcontexts, name, registrar, 0); 03804 }
|
|
||||||||||||
|
Destroy a context (matches the specified context (or ANY context if NULL).
Definition at line 5259 of file pbx.c. References __ast_context_destroy(). Referenced by cleanup_stale_contexts(), and unload_module(). 05260 { 05261 __ast_context_destroy(con,registrar); 05262 }
|
|
|
Find a context.
Definition at line 864 of file pbx.c. References ast_mutex_lock(), ast_mutex_unlock(), and ast_walk_contexts(). Referenced by ast_context_verify_includes(), ast_ignore_pattern(), cleanup_stale_contexts(), do_parking_thread(), park_exec(), register_peer_exten(), reload_config(), and set_config(). 00865 { 00866 struct ast_context *tmp = NULL; 00867 ast_mutex_lock(&conlock); 00868 while ( (tmp = ast_walk_contexts(tmp)) ) { 00869 if (!name || !strcasecmp(name, tmp->name)) 00870 break; 00871 } 00872 ast_mutex_unlock(&conlock); 00873 return tmp; 00874 }
|
|
||||||||||||||||
|
Register a new context or find an existing one.
Definition at line 3806 of file pbx.c. References __ast_context_create(). Referenced by pbx_load_users(). 03807 { 03808 return __ast_context_create(extcontexts, name, registrar, 1); 03809 }
|
|
|
locks the macrolock in the given given context
Definition at line 2767 of file pbx.c. References ast_get_context_name(), ast_lock_contexts(), ast_mutex_lock(), ast_unlock_contexts(), and ast_walk_contexts(). 02768 { 02769 struct ast_context *c = NULL; 02770 int ret = -1; 02771 02772 ast_lock_contexts(); 02773 02774 while ((c = ast_walk_contexts(c))) { 02775 if (!strcmp(ast_get_context_name(c), context)) { 02776 ret = 0; 02777 break; 02778 } 02779 } 02780 02781 ast_unlock_contexts(); 02782 02783 /* if we found context, lock macrolock */ 02784 if (ret == 0) 02785 ret = ast_mutex_lock(&c->macrolock); 02786 02787 return ret; 02788 }
|
|
||||||||||||||||||||
|
Simply remove extension from context.
Definition at line 2668 of file pbx.c. References ast_context_remove_extension2(), ast_unlock_contexts(), and find_context_locked(). Referenced by handle_context_remove_extension(), and register_peer_exten(). 02669 { 02670 int ret = -1; /* default error return */ 02671 struct ast_context *c = find_context_locked(context); 02672 02673 if (c) { /* ... remove extension ... */ 02674 ret = ast_context_remove_extension2(c, extension, priority, registrar); 02675 ast_unlock_contexts(); 02676 } 02677 return ret; 02678 }
|
|
||||||||||||||||||||
|
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 2690 of file pbx.c. References ast_mutex_lock(), ast_mutex_unlock(), destroy_exten(), exten, ast_context::lock, ast_exten::next, ast_exten::peer, and ast_context::root. Referenced by ast_context_remove_extension(), do_parking_thread(), and park_exec(). 02691 { 02692 struct ast_exten *exten, *prev_exten = NULL; 02693 struct ast_exten *peer; 02694 02695 ast_mutex_lock(&con->lock); 02696 02697 /* scan the extension list to find matching extension-registrar */ 02698 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02699 if (!strcmp(exten->exten, extension) && 02700 (!registrar || !strcmp(exten->registrar, registrar))) 02701 break; 02702 } 02703 if (!exten) { 02704 /* we can't find right extension */ 02705 ast_mutex_unlock(&con->lock); 02706 return -1; 02707 } 02708 02709 /* should we free all peers in this extension? (priority == 0)? */ 02710 if (priority == 0) { 02711 /* remove this extension from context list */ 02712 if (prev_exten) 02713 prev_exten->next = exten->next; 02714 else 02715 con->root = exten->next; 02716 02717 /* fire out all peers */ 02718 while ( (peer = exten) ) { 02719 exten = peer->peer; /* prepare for next entry */ 02720 destroy_exten(peer); 02721 } 02722 } else { 02723 /* scan the priority list to remove extension with exten->priority == priority */ 02724 struct ast_exten *previous_peer = NULL; 02725 02726 for (peer = exten; peer; previous_peer = peer, peer = peer->peer) { 02727 if (peer->priority == priority && 02728 (!registrar || !strcmp(peer->registrar, registrar) )) 02729 break; /* found our priority */ 02730 } 02731 if (!peer) { /* not found */ 02732 ast_mutex_unlock(&con->lock); 02733 return -1; 02734 } 02735 /* we are first priority extension? */ 02736 if (!previous_peer) { 02737 /* 02738 * We are first in the priority chain, so must update the extension chain. 02739 * The next node is either the next priority or the next extension 02740 */ 02741 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02742 02743 if (!prev_exten) /* change the root... */ 02744 con->root = next_node; 02745 else 02746 prev_exten->next = next_node; /* unlink */ 02747 if (peer->peer) /* XXX update the new head of the pri list */ 02748 peer->peer->next = peer->next; 02749 } else { /* easy, we are not first priority in extension */ 02750 previous_peer->peer = peer->peer; 02751 } 02752 02753 /* now, free whole priority extension */ 02754 destroy_exten(peer); 02755 /* XXX should we return -1 ? */ 02756 } 02757 ast_mutex_unlock(&con->lock); 02758 return 0; 02759 }
|
|
||||||||||||||||
|
Definition at line 4341 of file pbx.c. References ast_context_remove_ignorepat2(), ast_unlock_contexts(), and find_context_locked(). Referenced by handle_context_remove_ignorepat(). 04342 { 04343 int ret = -1; 04344 struct ast_context *c = find_context_locked(context); 04345 04346 if (c) { 04347 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04348 ast_unlock_contexts(); 04349 } 04350 return ret; 04351 }
|
|
||||||||||||||||
|
Definition at line 4353 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(). 04354 { 04355 struct ast_ignorepat *ip, *ipl = NULL; 04356 04357 ast_mutex_lock(&con->lock); 04358 04359 for (ip = con->ignorepats; ip; ip = ip->next) { 04360 if (!strcmp(ip->pattern, ignorepat) && 04361 (!registrar || (registrar == ip->registrar))) { 04362 if (ipl) { 04363 ipl->next = ip->next; 04364 free(ip); 04365 } else { 04366 con->ignorepats = ip->next; 04367 free(ip); 04368 } 04369 ast_mutex_unlock(&con->lock); 04370 return 0; 04371 } 04372 ipl = ip; 04373 } 04374 04375 ast_mutex_unlock(&con->lock); 04376 errno = EINVAL; 04377 return -1; 04378 }
|
|
||||||||||||||||
|
Remove a context include.
Definition at line 2564 of file pbx.c. References ast_context_remove_include2(), ast_unlock_contexts(), and find_context_locked(). Referenced by handle_context_remove_include(). 02565 { 02566 int ret = -1; 02567 struct ast_context *c = find_context_locked(context); 02568 02569 if (c) { 02570 /* found, remove include from this context ... */ 02571 ret = ast_context_remove_include2(c, include, registrar); 02572 ast_unlock_contexts(); 02573 } 02574 return ret; 02575 }
|
|
||||||||||||||||
|
Removes an include by an ast_context structure.
Definition at line 2585 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(). 02586 { 02587 struct ast_include *i, *pi = NULL; 02588 int ret = -1; 02589 02590 ast_mutex_lock(&con->lock); 02591 02592 /* find our include */ 02593 for (i = con->includes; i; pi = i, i = i->next) { 02594 if (!strcmp(i->name, include) && 02595 (!registrar || !strcmp(i->registrar, registrar))) { 02596 /* remove from list */ 02597 if (pi) 02598 pi->next = i->next; 02599 else 02600 con->includes = i->next; 02601 /* free include and return */ 02602 free(i); 02603 ret = 0; 02604 break; 02605 } 02606 } 02607 02608 ast_mutex_unlock(&con->lock); 02609 return ret; 02610 }
|
|
||||||||||||||||||||
|
Remove a switch.
Definition at line 2617 of file pbx.c. References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked(). 02618 { 02619 int ret = -1; /* default error return */ 02620 struct ast_context *c = find_context_locked(context); 02621 02622 if (c) { 02623 /* remove switch from this context ... */ 02624 ret = ast_context_remove_switch2(c, sw, data, registrar); 02625 ast_unlock_contexts(); 02626 } 02627 return ret; 02628 }
|
|
||||||||||||||||||||
|
This function locks given context, removes switch, unlock context and return.
Definition at line 2638 of file pbx.c. References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), ast_sw::data, free, ast_context::lock, ast_sw::name, and ast_sw::registrar. Referenced by ast_context_remove_switch(). 02639 { 02640 struct ast_sw *i; 02641 int ret = -1; 02642 02643 ast_mutex_lock(&con->lock); 02644 02645 /* walk switches */ 02646 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02647 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02648 (!registrar || !strcmp(i->registrar, registrar))) { 02649 /* found, remove from list */ 02650 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02651 free(i); /* free switch and return */ 02652 ret = 0; 02653 break; 02654 } 02655 } 02656 AST_LIST_TRAVERSE_SAFE_END 02657 02658 ast_mutex_unlock(&con->lock); 02659 02660 return ret; 02661 }
|
|
|
Unlocks the macrolock in the given context.
Definition at line 2795 of file pbx.c. References ast_get_context_name(), ast_lock_contexts(), ast_mutex_unlock(), ast_unlock_contexts(), and ast_walk_contexts(). 02796 { 02797 struct ast_context *c = NULL; 02798 int ret = -1; 02799 02800 ast_lock_contexts(); 02801 02802 while ((c = ast_walk_contexts(c))) { 02803 if (!strcmp(ast_get_context_name(c), context)) { 02804 ret = 0; 02805 break; 02806 } 02807 } 02808 02809 ast_unlock_contexts(); 02810 02811 /* if we found context, unlock macrolock */ 02812 if (ret == 0) 02813 ret = ast_mutex_unlock(&c->macrolock); 02814 02815 return ret; 02816 }
|
|
|
Verifies includes in an ast_contect structure.
Definition at line 6146 of file pbx.c. References ast_context_find(), ast_get_context_name(), ast_log(), ast_walk_context_includes(), and ast_include::rname. Referenced by pbx_load_module(). 06147 { 06148 struct ast_include *inc = NULL; 06149 int res = 0; 06150 06151 while ( (inc = ast_walk_context_includes(con, inc)) ) 06152 if (!ast_context_find(inc->rname)) { 06153 res = -1; 06154 ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n", 06155 ast_get_context_name(con), inc->rname); 06156 } 06157 return res; 06158 }
|
|
|
Definition at line 1319 of file pbx.c. References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, and ast_custom_function::name. Referenced by ast_func_read(), ast_func_write(), and handle_show_function(). 01320 { 01321 struct ast_custom_function *acf = NULL; 01322 01323 AST_RWLIST_RDLOCK(&acf_root); 01324 AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) { 01325 if (!strcmp(name, acf->name)) 01326 break; 01327 } 01328 AST_RWLIST_UNLOCK(&acf_root); 01329 01330 return acf; 01331 }
|
|
|
Reigster a custom function.
Definition at line 1355 of file pbx.c. References ast_log(), AST_RWLIST_INSERT_BEFORE_CURRENT, AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verbose(), LOG_ERROR, ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2. Referenced by load_module(). 01356 { 01357 struct ast_custom_function *cur; 01358 01359 if (!acf) 01360 return -1; 01361 01362 AST_RWLIST_WRLOCK(&acf_root); 01363 01364 AST_RWLIST_TRAVERSE(&acf_root, cur, acflist) { 01365 if (!strcmp(acf->name, cur->name)) { 01366 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01367 AST_RWLIST_UNLOCK(&acf_root); 01368 return -1; 01369 } 01370 } 01371 01372 /* Store in alphabetical order */ 01373 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01374 if (strcasecmp(acf->name, cur->name) < 0) { 01375 AST_RWLIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist); 01376 break; 01377 } 01378 } 01379 AST_RWLIST_TRAVERSE_SAFE_END 01380 if (!cur) 01381 AST_RWLIST_INSERT_TAIL(&acf_root, acf, acflist); 01382 01383 AST_RWLIST_UNLOCK(&acf_root); 01384 01385 if (option_verbose > 1) 01386 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01387 01388 return 0; 01389 }
|
|
|
Unregister a custom function.
Definition at line 1333 of file pbx.c. References AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verbose(), ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2. Referenced by unload_module(). 01334 { 01335 struct ast_custom_function *cur; 01336 01337 if (!acf) 01338 return -1; 01339 01340 AST_RWLIST_WRLOCK(&acf_root); 01341 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01342 if (cur == acf) { 01343 AST_RWLIST_REMOVE_CURRENT(&acf_root, acflist); 01344 if (option_verbose > 1) 01345 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01346 break; 01347 } 01348 } 01349 AST_RWLIST_TRAVERSE_SAFE_END 01350 AST_RWLIST_UNLOCK(&acf_root); 01351 01352 return acf ? 0 : -1; 01353 }
|
|
||||||||||||||||||||||||
|
||||||||||||||||||||
|
Definition at line 4463 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(), and handle_setpriority(). 04464 { 04465 if (!chan) 04466 return -1; 04467 04468 if (!ast_strlen_zero(context)) 04469 ast_copy_string(chan->context, context, sizeof(chan->context)); 04470 if (!ast_strlen_zero(exten)) 04471 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04472 if (priority > -1) { 04473 chan->priority = priority; 04474 /* see flag description in channel.h for explanation */ 04475 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04476 chan->priority--; 04477 } 04478 04479 return 0; 04480 }
|
|
||||||||||||||||
|
Definition at line 857 of file pbx.c. References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING. Referenced by realtime_switch_common(). 00858 { 00859 if (needmore != E_MATCHMORE && needmore != E_CANMATCH) 00860 ast_log(LOG_WARNING, "invalid argument %d\n", needmore); 00861 return extension_match_core(pattern, data, needmore); 00862 }
|
|
||||||||||||
|
Determine if a given extension matches a given pattern (in NXX format).
Definition at line 852 of file pbx.c. References E_MATCH, and extension_match_core(). Referenced by ast_ignore_pattern(), loopback_canmatch(), loopback_exec(), loopback_exists(), loopback_matchmore(), manager_show_dialplan_helper(), matchcid(), misdn_cfg_is_msn_valid(), realtime_switch_common(), and show_dialplan_helper(). 00853 { 00854 return extension_match_core(pattern, data, E_MATCH); 00855 }
|
|
||||||||||||
|
|
|
||||||||||||||||
|
Uses hint and devicestate callback to get the state of an extension.
Definition at line 1869 of file pbx.c. References ast_extension_state2(), and ast_hint_extension(). Referenced by action_extensionstate(), and handle_request_subscribe(). 01870 { 01871 struct ast_exten *e; 01872 01873 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 01874 if (!e) 01875 return -1; /* No hint, return -1 */ 01876 01877 return ast_extension_state2(e); /* Check all devices in the hint */ 01878 }
|
|
|
Return string representation of the state of an extension.
Definition at line 1857 of file pbx.c. References extension_states. Referenced by cb_extensionstate(), handle_request_subscribe(), and handle_show_hints(). 01858 { 01859 int i; 01860 01861 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 01862 if (extension_states[i].extension_state == extension_state) 01863 return extension_states[i].text; 01864 } 01865 return "Unknown"; 01866 }
|
|
||||||||||||||||||||
|
Registers a state change callback.
Definition at line 1924 of file pbx.c. References AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_state_cb::callback, ast_state_cb::data, ast_state_cb::next, and statecbs. Referenced by handle_request_subscribe(), and init_manager(). 01926 { 01927 struct ast_hint *hint; 01928 struct ast_state_cb *cblist; 01929 struct ast_exten *e; 01930 01931 /* If there's no context and extension: add callback to statecbs list */ 01932 if (!context && !exten) { 01933 AST_RWLIST_WRLOCK(&hints); 01934 01935 for (cblist = statecbs; cblist; cblist = cblist->next) { 01936 if (cblist->callback == callback) { 01937 cblist->data = data; 01938 AST_RWLIST_UNLOCK(&hints); 01939 return 0; 01940 } 01941 } 01942 01943 /* Now insert the callback */ 01944 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 01945 AST_RWLIST_UNLOCK(&hints); 01946 return -1; 01947 } 01948 cblist->id = 0; 01949 cblist->callback = callback; 01950 cblist->data = data; 01951 01952 cblist->next = statecbs; 01953 statecbs = cblist; 01954 01955 AST_RWLIST_UNLOCK(&hints); 01956 return 0; 01957 } 01958 01959 if (!context || !exten) 01960 return -1; 01961 01962 /* This callback type is for only one hint, so get the hint */ 01963 e = ast_hint_extension(NULL, context, exten); 01964 if (!e) { 01965 return -1; 01966 } 01967 01968 /* Find the hint in the list of hints */ 01969 AST_RWLIST_WRLOCK(&hints); 01970 01971 AST_RWLIST_TRAVERSE(&hints, hint, list) { 01972 if (hint->exten == e) 01973 break; 01974 } 01975 01976 if (!hint) { 01977 /* We have no hint, sorry */ 01978 AST_RWLIST_UNLOCK(&hints); 01979 return -1; 01980 } 01981 01982 /* Now insert the callback in the callback list */ 01983 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 01984 AST_RWLIST_UNLOCK(&hints); 01985 return -1; 01986 } 01987 cblist->id = stateid++; /* Unique ID for this callback */ 01988 cblist->callback = callback; /* Pointer to callback routine */ 01989 cblist->data = data; /* Data for the callback */ 01990 01991 cblist->next = hint->callbacks; 01992 hint->callbacks = cblist; 01993 01994 AST_RWLIST_UNLOCK(&hints); 01995 return cblist->id; 01996 }
|
|
||||||||||||
|
Deletes a registered state change callback by ID.
Definition at line 1999 of file pbx.c. References AST_RWLIST_WRLOCK, ast_state_cb::next, and statecbs. Referenced by __sip_destroy(). 02000 { 02001 struct ast_state_cb **p_cur = NULL; /* address of pointer to us */ 02002 int ret = -1; 02003 02004 if (!id && !callback) 02005 return -1; 02006 02007 AST_RWLIST_WRLOCK(&hints); 02008 02009 if (!id) { /* id == 0 is a callback without extension */ 02010 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) { 02011 if ((*p_cur)->callback == callback) 02012 break; 02013 } 02014 } else { /* callback with extension, find the callback based on ID */ 02015 struct ast_hint *hint; 02016 AST_RWLIST_TRAVERSE(&hints, hint, list) { 02017 for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) { 02018 if ((*p_cur)->id == id) 02019 break; 02020 } 02021 if (*p_cur) /* found in the inner loop */ 02022 break; 02023 } 02024 } 02025 if (p_cur && *p_cur) { 02026 struct ast_state_cb *cur = *p_cur; 02027 *p_cur = cur->next; 02028 free(cur); 02029 ret = 0; 02030 } 02031 AST_RWLIST_UNLOCK(&hints); 02032 return ret; 02033 }
|
|
||||||||||||||||||||||||
|
Find the priority of an extension that has the specified label.
Definition at line 2148 of file pbx.c. References E_FINDLABEL, and pbx_extension_helper(). Referenced by action_originate(), action_redirect(), ast_parseable_goto(), and handle_setpriority(). 02149 { 02150 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL); 02151 }
|
|
||||||||||||||||||||||||
|
Find the priority of an extension that has the specified label.
Definition at line 2153 of file pbx.c. References E_FINDLABEL, and pbx_extension_helper(). 02154 { 02155 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL); 02156 }
|
|
||||||||||||||||||||
|
executes a read operation on a function
Definition at line 1411 of file pbx.c. References ast_custom_function_find(), ast_log(), ast_strdupa, copy(), func_args(), LOG_ERROR, and ast_custom_function::read. Referenced by action_getvar(), handle_getvariable(), and pbx_substitute_variables_helper_full(). 01412 { 01413 char *copy = ast_strdupa(function); 01414 char *args = func_args(copy); 01415 struct ast_custom_function *acfptr = ast_custom_function_find(copy); 01416 01417 if (acfptr == NULL) 01418 ast_log(LOG_ERROR, "Function %s not registered\n", copy); 01419 else if (!acfptr->read) 01420 ast_log(LOG_ERROR, "Function %s cannot be read\n", copy); 01421 else 01422 return acfptr->read(chan, copy, args, workspace, len); 01423 return -1; 01424 }
|
|
||||||||||||||||
|
executes a write operation on a function
Definition at line 1426 of file pbx.c. References ast_custom_function_find(), ast_log(), ast_strdupa, copy(), func_args(), LOG_ERROR, and ast_custom_function::write. Referenced by pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper(). 01427 { 01428 char *copy = ast_strdupa(function); 01429 char *args = func_args(copy); 01430 struct ast_custom_function *acfptr = ast_custom_function_find(copy); 01431 01432 if (acfptr == NULL) 01433 ast_log(LOG_ERROR, "Function %s not registered\n", copy); 01434 else if (!acfptr->write) 01435 ast_log(LOG_ERROR, "Function %s cannot be written to\n", copy); 01436 else 01437 return acfptr->write(chan, copy, args, value); 01438 01439 return -1; 01440 }
|
|
|
Definition at line 6003 of file pbx.c. Referenced by ast_context_add_include2(), ast_context_add_switch2(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_context_verify_includes(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_remove_extension(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), handle_save_dialplan(), handle_show_hints(), manager_show_dialplan_helper(), and show_dialplan_helper().
|
|
|
Definition at line 6041 of file pbx.c. References ast_context::registrar. Referenced by handle_save_dialplan(), and show_dialplan_helper(). 06042 { 06043 return c ? c->registrar : NULL; 06044 }
|
|
|
Definition at line 6071 of file pbx.c. References ast_exten::app. Referenced by ast_add_hint(), ast_extension_state2(), ast_get_hint(), ast_hint_state_changed(), handle_save_dialplan(), handle_show_hints(), manager_show_dialplan_helper(), and print_ext(). 06072 { 06073 return e ? e->app : NULL; 06074 }
|
|
|
Definition at line 6076 of file pbx.c. References ast_exten::data. Referenced by ast_get_hint(), handle_save_dialplan(), manager_show_dialplan_helper(), and print_ext(). 06077 { 06078 return e ? e->data : NULL; 06079 }
|
|
|
Definition at line 6066 of file pbx.c. References ast_exten::cidmatch. Referenced by handle_save_dialplan(). 06067 { 06068 return e ? e->cidmatch : NULL; 06069 }
|
|
|
Definition at line 6008 of file pbx.c. References exten. Referenced by handle_show_hints().
|
|
|
Definition at line 6018 of file pbx.c. References exten. Referenced by handle_save_dialplan(), manager_show_dialplan_helper(), and show_dialplan_helper().
|
|
|
Definition at line 6061 of file pbx.c. References ast_exten::matchcid. Referenced by handle_save_dialplan(). 06062 { 06063 return e ? e->matchcid : 0; 06064 }
|
|
|
Definition at line 6013 of file pbx.c. References exten. Referenced by ast_add_hint(), complete_context_remove_extension(), dundi_precache_full(), handle_save_dialplan(), handle_show_hints(), manager_show_dialplan_helper(), and show_dialplan_helper().
|
|
|
Definition at line 6033 of file pbx.c. References exten. Referenced by complete_context_remove_extension(), handle_save_dialplan(), manager_show_dialplan_helper(), and print_ext().
|
|
|
Definition at line 6046 of file pbx.c. References ast_exten::registrar. Referenced by handle_save_dialplan(), manager_show_dialplan_helper(), and show_dialplan_helper(). 06047 { 06048 return e ? e->registrar : NULL; 06049 }
|
|
||||||||||||||||||||||||||||||||
|
If an extension hint exists, return non-zero.
Definition at line 2126 of file pbx.c. References ast_get_extension_app(), ast_get_extension_app_data(), and ast_hint_extension(). Referenced by action_extensionstate(), pbx_retrieve_variable(), and transmit_state_notify(). 02127 { 02128 struct ast_exten *e = ast_hint_extension(c, context, exten); 02129 02130 if (e) { 02131 if (hint) 02132 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02133 if (name) { 02134 const char *tmp = ast_get_extension_app_data(e); 02135 if (tmp) 02136 ast_copy_string(name, tmp, namesize); 02137 } 02138 return -1; 02139 } 02140 return 0; 02141 }
|
|
|
Definition at line 6028 of file pbx.c. References ast_ignorepat::pattern. Referenced by complete_context_remove_ignorepat(), lookup_c_ip(), and manager_show_dialplan_helper(). 06029 { 06030 return ip ? ip->pattern : NULL; 06031 }
|
|
|
Definition at line 6056 of file pbx.c. References ast_ignorepat::registrar. Referenced by manager_show_dialplan_helper(). 06057 { 06058 return ip ? ip->registrar : NULL; 06059 }
|
|
|
Definition at line 6023 of file pbx.c. References ast_include::name. Referenced by complete_context_remove_include(), lookup_ci(), manager_show_dialplan_helper(), and show_dialplan_helper().
|
|
|
Definition at line 6051 of file pbx.c. References ast_include::registrar. Referenced by manager_show_dialplan_helper(). 06052 { 06053 return i ? i->registrar : NULL; 06054 }
|
|
|
Definition at line 6086 of file pbx.c. References ast_sw::data. Referenced by manager_show_dialplan_helper(). 06087 { 06088 return sw ? sw->data : NULL; 06089 }
|
|
|
Definition at line 6081 of file pbx.c. References ast_sw::name. Referenced by manager_show_dialplan_helper(). 06082 { 06083 return sw ? sw->name : NULL; 06084 }
|
|
|
Definition at line 6091 of file pbx.c. References ast_sw::registrar. Referenced by manager_show_dialplan_helper(). 06092 { 06093 return sw ? sw->registrar : NULL; 06094 }
|
|
||||||||||||||||||||
|
Definition at line 6180 of file pbx.c. References __ast_goto_if_exists(). 06181 { 06182 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06183 }
|
|
|
Definition at line 1880 of file pbx.c. References ast_extension_state2(), ast_get_extension_app(), AST_MAX_EXTENSION, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_exten::exten, ast_hint::exten, ast_hint::laststate, ast_state_cb::next, ast_exten::parent, parse(), statecbs, and strsep(). Referenced by do_state_change(). 01881 { 01882 struct ast_hint *hint; 01883 01884 AST_RWLIST_RDLOCK(&hints); 01885 01886 AST_RWLIST_TRAVERSE(&hints, hint, list) { 01887 struct ast_state_cb *cblist; 01888 char buf[AST_MAX_EXTENSION]; 01889 char *parse = buf; 01890 char *cur; 01891 int state; 01892 01893 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 01894 while ( (cur = strsep(&parse, "&")) ) { 01895 if (!strcasecmp(cur, device)) 01896 break; 01897 } 01898 if (!cur) 01899 continue; 01900 01901 /* Get device state for this hint */ 01902 state = ast_extension_state2(hint->exten); 01903 01904 if ((state == -1) || (state == hint->laststate)) 01905 continue; 01906 01907 /* Device state changed since last check - notify the watchers */ 01908 01909 /* For general callbacks */ 01910 for (cblist = statecbs; cblist; cblist = cblist->next) 01911 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 01912 01913 /* For extension callbacks */ 01914 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 01915 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 01916 01917 hint->laststate = state; /* record we saw the change */ 01918 } 01919 01920 AST_RWLIST_UNLOCK(&hints); 01921 }
|
|
||||||||||||
|
Checks to see if a number should be ignored.
Definition at line 4429 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(), dp_lookup(), dundi_lookup_local(), handle_soft_key_event_message(), handle_stimulus_message(), mgcp_ss(), skinny_ss(), and ss_thread(). 04430 { 04431 struct ast_context *con = ast_context_find(context); 04432 if (con) { 04433 struct ast_ignorepat *pat; 04434 for (pat = con->ignorepats; pat; pat = pat->next) { 04435 if (ast_extension_match(pat->pattern, pattern)) 04436 return 1; 04437 } 04438 } 04439 04440 return 0; 04441 }
|
|
|
Locks a given context.
Definition at line 5990 of file pbx.c. References ast_mutex_lock(), and ast_context::lock. Referenced by complete_context_remove_ignorepat(), complete_context_remove_include(), dundi_precache_full(), handle_save_dialplan(), lookup_c_ip(), lookup_ci(), manager_show_dialplan_helper(), and show_dialplan_helper(). 05991 { 05992 return ast_mutex_lock(&con->lock); 05993 }
|
|
|
Locks the context list.
Definition at line 5977 of file pbx.c. References ast_mutex_lock(). Referenced by ast_context_lockmacro(), ast_context_unlockmacro(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), handle_save_dialplan(), manager_show_dialplan_helper(), show_dialplan_helper(), and unreference_cached_app(). 05978 { 05979 return ast_mutex_lock(&conlock); 05980 }
|
|
||||||||||||||||||||||||
|
Looks to see if adding anything to this extension might match something. (exists ^ canmatch).
Definition at line 2163 of file pbx.c. References E_MATCHMORE, and pbx_extension_helper(). Referenced by ast_app_dtget(), collect_digits(), dp_lookup(), dundi_lookup_local(), handle_stimulus_message(), loopback_matchmore(), mgcp_ss(), skinny_ss(), and ss_thread(). 02164 { 02165 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE); 02166 }
|
|
||||||||||||
|
Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added.
Definition at line 3824 of file pbx.c. References __ast_context_destroy(), ast_calloc, AST_EXTENSION_REMOVED, ast_hint_extension(), AST_LIST_HEAD_INIT_VALUE, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_state_cb::callback, store_hint::callbacks, ast_hint::callbacks, store_hint::context, contexts, ast_state_cb::data, ast_exten::exten, ast_hint::exten, store_hint::exten, free, ast_hint::laststate, store_hint::laststate, LOG_WARNING, ast_state_cb::next, ast_context::next, ast_exten::parent, and ast_context::registrar. Referenced by pbx_load_module(). 03825 { 03826 struct ast_context *tmp, *lasttmp = NULL; 03827 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 03828 struct store_hint *this; 03829 struct ast_hint *hint; 03830 struct ast_exten *exten; 03831 int length; 03832 struct ast_state_cb *thiscb, *prevcb; 03833 03834 /* it is very important that this function hold the hint list lock _and_ the conlock 03835 during its operation; not only do we need to ensure that the list of contexts 03836 and extensions does not change, but also that no hint callbacks (watchers) are 03837 added or removed during the merge/delete process 03838 03839 in addition, the locks _must_ be taken in this order, because there are already 03840 other code paths that use this order 03841 */ 03842 ast_mutex_lock(&conlock); 03843 AST_RWLIST_WRLOCK(&hints); 03844 03845 /* preserve all watchers for hints associated with this registrar */ 03846 AST_RWLIST_TRAVERSE(&hints, hint, list) { 03847 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03848 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03849 if (!(this = ast_calloc(1, length))) 03850 continue; 03851 this->callbacks = hint->callbacks; 03852 hint->callbacks = NULL; 03853 this->laststate = hint->laststate; 03854 this->context = this->data; 03855 strcpy(this->data, hint->exten->parent->name); 03856 this->exten = this->data + strlen(this->context) + 1; 03857 strcpy(this->exten, hint->exten->exten); 03858 AST_LIST_INSERT_HEAD(&store, this, list); 03859 } 03860 } 03861 03862 tmp = *extcontexts; 03863 if (registrar) { 03864 /* XXX remove previous contexts from same registrar */ 03865 if (option_debug) 03866 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 03867 __ast_context_destroy(NULL,registrar); 03868 while (tmp) { 03869 lasttmp = tmp; 03870 tmp = tmp->next; 03871 } 03872 } else { 03873 /* XXX remove contexts with the same name */ 03874 while (tmp) { 03875 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 03876 __ast_context_destroy(tmp,tmp->registrar); 03877 lasttmp = tmp; 03878 tmp = tmp->next; 03879 } 03880 } 03881 if (lasttmp) { 03882 lasttmp->next = contexts; 03883 contexts = *extcontexts; 03884 *extcontexts = NULL; 03885 } else 03886 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 03887 03888 /* restore the watchers for hints that can be found; notify those that 03889 cannot be restored 03890 */ 03891 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 03892 exten = ast_hint_extension(NULL, this->context, this->exten); 03893 /* Find the hint in the list of hints */ 03894 AST_RWLIST_TRAVERSE(&hints, hint, list) { 03895 if (hint->exten == exten) 03896 break; 03897 } 03898 if (!exten || !hint) { 03899 /* this hint has been removed, notify the watchers */ 03900 prevcb = NULL; 03901 thiscb = this->callbacks; 03902 while (thiscb) { 03903 prevcb = thiscb; 03904 thiscb = thiscb->next; 03905 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 03906 free(prevcb); 03907 } 03908 } else { 03909 thiscb = this->callbacks; 03910 while (thiscb->next) 03911 thiscb = thiscb->next; 03912 thiscb->next = hint->callbacks; 03913 hint->callbacks = this->callbacks; 03914 hint->laststate = this->laststate; 03915 } 03916 free(this); 03917 } 03918 03919 AST_RWLIST_UNLOCK(&hints); 03920 ast_mutex_unlock(&conlock); 03921 03922 return; 03923 }
|
|
||||||||||||
|
Definition at line 6190 of file pbx.c. References ast_cdr_update(), ast_explicit_goto(), ast_findlabel_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, exten, ast_channel::priority, and strsep(). Referenced by ivr_dispatch(), and pbx_builtin_goto(). 06191 { 06192 char *exten, *pri, *context; 06193 char *stringp; 06194 int ipri; 06195 int mode = 0; 06196 06197 if (ast_strlen_zero(goto_string)) { 06198 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06199 return -1; 06200 } 06201 stringp = ast_strdupa(goto_string); 06202 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06203 exten = strsep(&stringp, "|"); 06204 pri = strsep(&stringp, "|"); 06205 if (!exten) { /* Only a priority in this one */ 06206 pri = context; 06207 exten = NULL; 06208 context = NULL; 06209 } else if (!pri) { /* Only an extension and priority in this one */ 06210 pri = exten; 06211 exten = context; 06212 context = NULL; 06213 } 06214 if (*pri == '+') { 06215 mode = 1; 06216 pri++; 06217 } else if (*pri == '-') { 06218 mode = -1; 06219 pri++; 06220 } 06221 if (sscanf(pri, "%d", &ipri) != 1) { 06222 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06223 pri, chan->cid.cid_num)) < 1) { 06224 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06225 return -1; 06226 } else 06227 mode = 0; 06228 } 06229 /* At this point we have a priority and maybe an extension and a context */ 06230 06231 if (mode) 06232 ipri = chan->priority + (ipri * mode); 06233 06234 ast_explicit_goto(chan, context, exten, ipri); 06235 ast_cdr_update(chan); 06236 return 0; 06237 06238 }
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Synchronously or asynchronously make an outbound call and send it to a particular application with given extension Definition at line 5055 of file pbx.c. References __ast_request_and_dial(), ast_calloc, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), ast_channel_lock, ast_channel_unlock, ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, async_stat::chan, free, option_verbose, ast_channel::pbx, outgoing_helper::vars, and VERBOSE_PREFIX_4. Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_app(). 05056 { 05057 struct ast_channel *chan; 05058 struct app_tmp *tmp; 05059 int res = -1, cdr_res = -1; 05060 struct outgoing_helper oh; 05061 pthread_attr_t attr; 05062 05063 memset(&oh, 0, sizeof(oh)); 05064 oh.vars = vars; 05065 oh.account = account; 05066 05067 if (locked_channel) 05068 *locked_channel = NULL; 05069 if (ast_strlen_zero(app)) { 05070 res = -1; 05071 goto outgoing_app_cleanup; 05072 } 05073 if (sync) { 05074 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05075 if (chan) { 05076 if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 05077 ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name); 05078 } else { 05079 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 05080 if (!chan->cdr) { 05081 /* allocation of the cdr failed */ 05082 free(chan->pbx); 05083 res = -1; 05084 goto outgoing_app_cleanup; 05085 } 05086 /* allocation of the cdr was successful */ 05087 ast_cdr_init(chan->cdr, chan); /* initialize our channel's cdr */ 05088 ast_cdr_start(chan->cdr); 05089 } 05090 ast_set_variables(chan, vars); 05091 if (account) 05092 ast_cdr_setaccount(chan, account); 05093 if (chan->_state == AST_STATE_UP) { 05094 res = 0; 05095 if (option_verbose > 3) 05096 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05097 tmp = ast_calloc(1, sizeof(*tmp)); 05098 if (!tmp) 05099 res = -1; 05100 else { 05101 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05102 if (appdata) 05103 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05104 tmp->chan = chan; 05105 if (sync > 1) { 05106 if (locked_channel) 05107 ast_channel_unlock(chan); 05108 ast_pbx_run_app(tmp); 05109 } else { 05110 pthread_attr_init(&attr); 05111 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05112 if (locked_channel) 05113 ast_channel_lock(chan); 05114 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05115 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05116 free(tmp); 05117 if (locked_channel) 05118 ast_channel_unlock(chan); 05119 ast_hangup(chan); 05120 res = -1; 05121 } else { 05122 if (locked_channel) 05123 *locked_channel = chan; 05124 } 05125 pthread_attr_destroy(&attr); 05126 } 05127 } 05128 } else { 05129 if (option_verbose > 3) 05130 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05131 if (chan->cdr) { /* update the cdr */ 05132 /* here we update the status of the call, which sould be busy. 05133 * if that fails then we set the status to failed */ 05134 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05135 ast_cdr_failed(chan->cdr); 05136 } 05137 ast_hangup(chan); 05138 } 05139 } 05140 05141 if (res < 0) { /* the call failed for some reason */ 05142 if (*reason == 0) { /* if the call failed (not busy or no answer) 05143 * update the cdr with the failed message */ 05144 cdr_res = ast_pbx_outgoing_cdr_failed(); 05145 if (cdr_res != 0) { 05146 res = cdr_res; 05147 goto outgoing_app_cleanup; 05148 } 05149 } 05150 } 05151 05152 } else { 05153 struct async_stat *as; 05154 if (!(as = ast_calloc(1, sizeof(*as)))) { 05155 res = -1; 05156 goto outgoing_app_cleanup; 05157 } 05158 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05159 if (!chan) { 05160 free(as); 05161 res = -1; 05162 goto outgoing_app_cleanup; 05163 } 05164 as->chan = chan; 05165 ast_copy_string(as->app, app, sizeof(as->app)); 05166 if (appdata) 05167 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05168 as->timeout = timeout; 05169 ast_set_variables(chan, vars); 05170 if (account) 05171 ast_cdr_setaccount(chan, account); 05172 /* Start a new thread, and get something handling this channel. */ 05173 pthread_attr_init(&attr); 05174 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05175 if (locked_channel) 05176 ast_channel_lock(chan); 05177 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05178 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05179 free(as); 05180 if (locked_channel) 05181 ast_channel_unlock(chan); 05182 ast_hangup(chan); 05183 res = -1; 05184 pthread_attr_destroy(&attr); 05185 goto outgoing_app_cleanup; 05186 } else { 05187 if (locked_channel) 05188 *locked_channel = chan; 05189 } 05190 pthread_attr_destroy(&attr); 05191 res = 0; 05192 } 05193 outgoing_app_cleanup: 05194 ast_variables_destroy(vars); 05195 return res; 05196 }
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Synchronously or asynchronously make an outbound call and send it to a particular extension Definition at line 4877 of file pbx.c. References __ast_request_and_dial(), ast_channel::_state, outgoing_helper::account, ast_calloc, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), ast_channel_alloc(), ast_channel_lock, ast_channel_unlock, ast_exists_extension(), ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create, ast_request_and_dial(), ast_set_variables(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::context, outgoing_helper::context, outgoing_helper::exten, free, ast_channel::hangupcause, LOG_ERROR, option_verbose, outgoing_helper::parent_channel, ast_channel::pbx, outgoing_helper::priority, set_ext_pri(), outgoing_helper::vars, and VERBOSE_PREFIX_4. Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_exten(). 04878 { 04879 struct ast_channel *chan; 04880 struct async_stat *as; 04881 int res = -1, cdr_res = -1; 04882 struct outgoing_helper oh; 04883 pthread_attr_t attr; 04884 04885 if (sync) { 04886 oh.context = context; 04887 oh.exten = exten; 04888 oh.priority = priority; 04889 oh.cid_num = cid_num; 04890 oh.cid_name = cid_name; 04891 oh.account = account; 04892 oh.vars = vars; 04893 oh.parent_channel = NULL; 04894 04895 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 04896 if (channel) { 04897 *channel = chan; 04898 if (chan) 04899 ast_channel_lock(chan); 04900 } 04901 if (chan) { 04902 if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 04903 ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name); 04904 } else { 04905 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 04906 if (!chan->cdr) { 04907 /* allocation of the cdr failed */ 04908 free(chan->pbx); 04909 res = -1; 04910 goto outgoing_exten_cleanup; 04911 } 04912 /* allocation of the cdr was successful */ 04913 ast_cdr_init(chan->cdr, chan); /* initialize our channel's cdr */ 04914 ast_cdr_start(chan->cdr); 04915 } 04916 if (chan->_state == AST_STATE_UP) { 04917 res = 0; 04918 if (option_verbose > 3) 04919 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 04920 04921 if (sync > 1) { 04922 if (channel) 04923 ast_channel_unlock(chan); 04924 if (ast_pbx_run(chan)) { 04925 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 04926 if (channel) 04927 *channel = NULL; 04928 ast_hangup(chan); 04929 res = -1; 04930 } 04931 } else { 04932 if (ast_pbx_start(chan)) { 04933 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 04934 if (channel) { 04935 *channel = NULL; 04936 ast_channel_unlock(chan); 04937 } 04938 ast_hangup(chan); 04939 res = -1; 04940 } 04941 } 04942 } else { 04943 if (option_verbose > 3) 04944 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 04945 04946 if (chan->cdr) { /* update the cdr */ 04947 /* here we update the status of the call, which sould be busy. 04948 * if that fails then we set the status to failed */ 04949 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 04950 ast_cdr_failed(chan->cdr); 04951 } 04952 04953 if (channel) { 04954 *channel = NULL; 04955 ast_channel_unlock(chan); 04956 } 04957 ast_hangup(chan); 04958 } 04959 } 04960 04961 if (res < 0) { /* the call failed for some reason */ 04962 if (*reason == 0) { /* if the call failed (not busy or no answer) 04963 * update the cdr with the failed message */ 04964 cdr_res = ast_pbx_outgoing_cdr_failed(); 04965 if (cdr_res != 0) { 04966 res = cdr_res; 04967 goto outgoing_exten_cleanup; 04968 } 04969 } 04970 04971 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 04972 /* check if "failed" exists */ 04973 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 04974 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "OutgoingSpoolFailed"); 04975 if (chan) { 04976 if (!ast_strlen_zero(context)) 04977 ast_copy_string(chan->context, context, sizeof(chan->context)); 04978 set_ext_pri(chan, "failed", 1); 04979 ast_set_variables(chan, vars); 04980 if (account) 04981 ast_cdr_setaccount(chan, account); 04982 ast_pbx_run(chan); 04983 } 04984 } 04985 } 04986 } else { 04987 if (!(as = ast_calloc(1, sizeof(*as)))) { 04988 res = -1; 04989 goto outgoing_exten_cleanup; 04990 } 04991 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 04992 if (channel) { 04993 *channel = chan; 04994 if (chan) 04995 ast_channel_lock(chan); 04996 } 04997 if (!chan) { 04998 free(as); 04999 res = -1; 05000 goto outgoing_exten_cleanup; 05001 } 05002 as->chan = chan; 05003 ast_copy_string(as->context, context, sizeof(as->context)); 05004 set_ext_pri(as->chan, exten, priority); 05005 as->timeout = timeout; 05006 ast_set_variables(chan, vars); 05007 if (account) 05008 ast_cdr_setaccount(chan, account); 05009 pthread_attr_init(&attr); 05010 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05011 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05012 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05013 free(as); 05014 if (channel) { 05015 *channel = NULL; 05016 ast_channel_unlock(chan); 05017 } 05018 ast_hangup(chan); 05019 res = -1; 05020 pthread_attr_destroy(&attr); 05021 goto outgoing_exten_cleanup; 05022 } 05023 pthread_attr_destroy(&attr); 05024 res = 0; 05025 } 05026 outgoing_exten_cleanup: 05027 ast_variables_destroy(vars); 05028 return res; 05029 }
|
|
|
Execute the PBX in the current thread.
Definition at line 2517 of file pbx.c. References __ast_pbx_run(), AST_PBX_CALL_LIMIT, AST_PBX_SUCCESS, decrease_call_count(), and increase_call_count(). Referenced by ast_pbx_outgoing_exten(), async_wait(), mgcp_ss(), skinny_newcall(), and ss_thread(). 02518 { 02519 enum ast_pbx_result res = AST_PBX_SUCCESS; 02520 02521 if (increase_call_count(c)) 02522 return AST_PBX_CALL_LIMIT; 02523 02524 res = __ast_pbx_run(c); 02525 decrease_call_count(); 02526 02527 return res; 02528 }
|
|
|
Create a new thread and start the PBX.
Definition at line 2491 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, and pbx_thread(). Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_exten(), do_parking_thread(), gtalk_new(), gtalk_newcall(), handle_request_invite(), jingle_new(), jingle_newcall(), local_call(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), sip_new(), and skinny_new(). 02492 { 02493 pthread_t t; 02494 pthread_attr_t attr; 02495 02496 if (!c) { 02497 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02498 return AST_PBX_FAILED; 02499 } 02500 02501 if (increase_call_count(c)) 02502 return AST_PBX_CALL_LIMIT; 02503 02504 /* Start a new thread, and get something handling this channel. */ 02505 pthread_attr_init(&attr); 02506 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02507 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02508 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02509 pthread_attr_destroy(&attr); 02510 return AST_PBX_FAILED; 02511 } 02512 pthread_attr_destroy(&attr); 02513 02514 return AST_PBX_SUCCESS; 02515 }
|
|
||||||||||||||||||||
|
Register an application.
Definition at line 2819 of file pbx.c. References ast_calloc, ast_log(), AST_RWLIST_INSERT_BEFORE_CURRENT, AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verbose(), COLOR_BRCYAN, ast_app::description, ast_app::execute, LOG_WARNING, option_verbose, ast_app::synopsis, term_color(), and VERBOSE_PREFIX_2. Referenced by load_module(), and load_pbx(). 02820 { 02821 struct ast_app *tmp, *cur = NULL; 02822 char tmps[80]; 02823 int length; 02824 02825 AST_RWLIST_WRLOCK(&apps); 02826 AST_RWLIST_TRAVERSE(&apps, tmp, list) { 02827 if (!strcasecmp(app, tmp->name)) { 02828 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02829 AST_RWLIST_UNLOCK(&apps); 02830 return -1; 02831 } 02832 } 02833 02834 length = sizeof(*tmp) + strlen(app) + 1; 02835 02836 if (!(tmp = ast_calloc(1, length))) { 02837 AST_RWLIST_UNLOCK(&apps); 02838 return -1; 02839 } 02840 02841 strcpy(tmp->name, app); 02842 tmp->execute = execute; 02843 tmp->synopsis = synopsis; 02844 tmp->description = description; 02845 02846 /* Store in alphabetical order */ 02847 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 02848 if (strcasecmp(tmp->name, cur->name) < 0) { 02849 AST_RWLIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 02850 break; 02851 } 02852 } 02853 AST_RWLIST_TRAVERSE_SAFE_END 02854 if (!cur) 02855 AST_RWLIST_INSERT_TAIL(&apps, tmp, list); 02856 02857 if (option_verbose > 1) 02858 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 02859 02860 AST_RWLIST_UNLOCK(&apps); 02861 02862 return 0; 02863 }
|
|
|
Register an alternative dialplan switch.
Definition at line 2869 of file pbx.c. References ast_log(), AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, LOG_WARNING, and ast_switch::name. Referenced by load_module(). 02870 { 02871 struct ast_switch *tmp; 02872 02873 AST_RWLIST_WRLOCK(&switches); 02874 AST_RWLIST_TRAVERSE(&switches, tmp, list) { 02875 if (!strcasecmp(tmp->name, sw->name)) { 02876 AST_RWLIST_UNLOCK(&switches); 02877 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 02878 return -1; 02879 } 02880 } 02881 AST_RWLIST_INSERT_TAIL(&switches, sw, list); 02882 AST_RWLIST_UNLOCK(&switches); 02883 02884 return 0; 02885 }
|
|
||||||||||||||||||||||||
|
Launch a new extension (i.e. new stack).
Definition at line 2168 of file pbx.c. References E_SPAWN, and pbx_extension_helper(). Referenced by __ast_pbx_run(), and loopback_exec(). 02169 { 02170 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN); 02171 }
|
|
|
Definition at line 5995 of file pbx.c. References ast_mutex_unlock(), and ast_context::lock. Referenced by complete_context_remove_ignorepat(), complete_context_remove_include(), dundi_precache_full(), lookup_c_ip(), lookup_ci(), and manager_show_dialplan_helper(). 05996 { 05997 return ast_mutex_unlock(&con->lock); 05998 }
|
|
|
Unlocks contexts.
Definition at line 5982 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_lockmacro(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_unlockmacro(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_remove_extension(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), handle_save_dialplan(), manager_show_dialplan_helper(), and unreference_cached_app(). 05983 { 05984 return ast_mutex_unlock(&conlock); 05985 }
|
|
|
Unregister an application.
Definition at line 3737 of file pbx.c. References AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verbose(), free, option_verbose, unreference_cached_app(), and VERBOSE_PREFIX_2. Referenced by __unload_module(), and unload_module(). 03738 { 03739 struct ast_app *tmp; 03740 03741 AST_RWLIST_WRLOCK(&apps); 03742 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03743 if (!strcasecmp(app, tmp->name)) { 03744 unreference_cached_app(tmp); 03745 AST_RWLIST_REMOVE_CURRENT(&apps, list); 03746 if (option_verbose > 1) 03747 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03748 free(tmp); 03749 break; 03750 } 03751 } 03752 AST_RWLIST_TRAVERSE_SAFE_END 03753 AST_RWLIST_UNLOCK(&apps); 03754 03755 return tmp ? 0 : -1; 03756 }
|
|
|
Unregister an alternative switch.
Definition at line 2887 of file pbx.c. References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK. Referenced by __unload_module(), and unload_module(). 02888 { 02889 AST_RWLIST_WRLOCK(&switches); 02890 AST_RWLIST_REMOVE(&switches, sw, list); 02891 AST_RWLIST_UNLOCK(&switches); 02892 }
|
|
||||||||||||
|
Definition at line 6104 of file pbx.c. References exten, and ast_context::root. Referenced by complete_context_remove_extension(), dundi_precache_full(), handle_save_dialplan(), manager_show_dialplan_helper(), show_dialplan_helper(), and unreference_cached_app(). 06106 { 06107 if (!exten) 06108 return con ? con->root : NULL; 06109 else 06110 return exten->next; 06111 }
|
|
||||||||||||
|
Definition at line 6137 of file pbx.c. References ast_context::ignorepats, and ast_ignorepat::next. Referenced by complete_context_remove_ignorepat(), lookup_c_ip(), and manager_show_dialplan_helper(). 06139 { 06140 if (!ip) 06141 return con ? con->ignorepats : NULL; 06142 else 06143 return ip->next; 06144 }
|
|
||||||||||||
|
Definition at line 6128 of file pbx.c. References ast_context::includes, and ast_include::next. Referenced by ast_context_verify_includes(), complete_context_remove_include(), lookup_ci(), manager_show_dialplan_helper(), and show_dialplan_helper(). 06130 { 06131 if (!inc) 06132 return con ? con->includes : NULL; 06133 else 06134 return inc->next; 06135 }
|
|