#include <asterisk/sched.h>#include <asterisk/channel.h>Go to the source code of this file.
Data Structures | |
| struct | ast_pbx |
| struct | ast_switch |
| Data structure associated with an asterisk switch. More... | |
Defines | |
| #define | AST_PBX_KEEP 0 |
| #define | AST_PBX_REPLACE 1 |
| #define | AST_MAX_APP 32 |
| Max length of an application. | |
| #define | AST_PBX_KEEPALIVE 10 |
| Special return values from applications to the PBX. | |
| #define | AST_PBX_NO_HANGUP_PEER 11 |
| #define | PRIORITY_HINT -1 |
| Special Priority for an hint. | |
| #define | AST_EXTENSION_NOT_INUSE 0 |
| #define | AST_EXTENSION_INUSE 1 |
| One or more devices INUSE. | |
| #define | AST_EXTENSION_BUSY 2 |
| All devices BUSY. | |
| #define | AST_EXTENSION_UNAVAILABLE 3 |
| All devices UNAVAILABLE/UNREGISTERED. | |
Typedefs | |
| typedef int(* | ast_state_cb_type )(char *context, char *id, int state, void *data) |
Functions | |
| int | ast_register_switch (struct ast_switch *sw) |
| Register an alternative switch. | |
| void | ast_unregister_switch (struct ast_switch *sw) |
| Unregister an alternative switch. | |
| ast_app * | pbx_findapp (char *app) |
| Look up an application. | |
| int | pbx_exec (struct ast_channel *c, struct ast_app *app, void *data, int newstack) |
| executes an application | |
| ast_context * | ast_context_create (struct ast_context **extcontexts, char *name, char *registrar) |
| Register a new context. | |
| void | ast_merge_contexts_and_delete (struct ast_context **extcontexts, char *registrar) |
| Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added. | |
| void | ast_context_destroy (struct ast_context *con, char *registrar) |
| Destroy a context (matches the specified context (or ANY context if NULL). | |
| ast_context * | ast_context_find (char *name) |
| Find a context. | |
| int | ast_pbx_start (struct ast_channel *c) |
| Create a new thread and start the PBX (or whatever). | |
| int | ast_pbx_run (struct ast_channel *c) |
| Execute the PBX in the current thread. | |
| int | ast_add_extension (char *context, int replace, char *extension, int priority, char *callerid, char *application, void *data, void(*datad)(void *), char *registrar) |
| int | ast_add_extension2 (struct ast_context *con, int replace, char *extension, int priority, char *callerid, char *application, void *data, void(*datad)(void *), 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. | |
| int | ast_register_application (char *app, int(*execute)(struct ast_channel *, void *), char *synopsis, char *description) |
| Add an application. The function 'execute' should return non-zero if the line needs to be hung up. | |
| int | ast_unregister_application (char *app) |
| Remove an application. | |
| int | ast_extension_state (struct ast_channel *c, char *context, char *exten) |
| Uses hint and devicestate callback to get the state of an extension. | |
| int | ast_device_state_changed (const char *fmt,...) __attribute__((format(printf |
| Tells Asterisk the State for Device is changed. | |
| int | ast_extension_state_add (char *context, 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_get_hint (char *hint, int maxlen, struct ast_channel *c, char *context, char *exten) |
| If an extension exists, return non-zero. | |
| int | ast_exists_extension (struct ast_channel *c, char *context, char *exten, int priority, char *callerid) |
| If an extension exists, return non-zero. | |
| int | ast_canmatch_extension (struct ast_channel *c, char *context, char *exten, int priority, char *callerid) |
| Looks for a valid matching extension. | |
| int | ast_matchmore_extension (struct ast_channel *c, char *context, char *exten, int priority, char *callerid) |
| Looks to see if adding anything to this extension might match something. (exists ^ canmatch). | |
| int | ast_extension_match (char *pattern, char *extension) |
| Determine if a given extension matches a given pattern (in NXX format). | |
| int | ast_spawn_extension (struct ast_channel *c, char *context, char *exten, int priority, char *callerid) |
| Launch a new extension (i.e. new stack). | |
| int | ast_exec_extension (struct ast_channel *c, char *context, char *exten, int priority, char *callerid) |
| Execute an extension. | |
| int | ast_context_add_include (char *context, char *include, char *registrar) |
| Add an include. | |
| int | ast_context_add_include2 (struct ast_context *con, char *include, char *registrar) |
| Add an include. | |
| int | ast_context_remove_include (char *context, char *include, char *registrar) |
| Removes an include. | |
| int | ast_context_remove_include2 (struct ast_context *con, char *include, char *registrar) |
| Removes an include by an ast_context structure. | |
| int | ast_context_verify_includes (struct ast_context *con) |
| Verifies includes in an ast_contect structure. | |
| int | ast_context_add_switch (char *context, char *sw, char *data, char *registrar) |
| Add a switch. | |
| int | ast_context_add_switch2 (struct ast_context *con, char *sw, char *data, char *registrar) |
| Adds a switch (first param is a ast_context). | |
| int | ast_context_remove_switch (char *context, char *sw, char *data, char *registrar) |
| Remove a switch. | |
| int | ast_context_remove_switch2 (struct ast_context *con, char *sw, char *data, char *registrar) |
| int | ast_context_remove_extension (char *context, char *extension, int priority, char *registrar) |
| Simply remove extension from context. | |
| int | ast_context_remove_extension2 (struct ast_context *con, char *extension, int priority, char *registrar) |
| int | ast_context_add_ignorepat (char *context, char *ignorepat, char *registrar) |
| Add an ignorepat. | |
| int | ast_context_add_ignorepat2 (struct ast_context *con, char *ignorepat, char *registrar) |
| int | ast_context_remove_ignorepat (char *context, char *ignorepat, char *registrar) |
| int | ast_context_remove_ignorepat2 (struct ast_context *con, char *ignorepat, char *registrar) |
| int | ast_ignore_pattern (char *context, char *pattern) |
| Checks to see if a number should be ignored. | |
| int | ast_lock_contexts (void) |
| Locks the contexts. | |
| int | ast_unlock_contexts (void) |
| Unlocks contexts. | |
| int | ast_lock_context (struct ast_context *con) |
| Locks a given context. | |
| int | ast_unlock_context (struct ast_context *con) |
| Unlocks the given context. | |
| int | ast_async_goto (struct ast_channel *chan, char *context, char *exten, int priority, int needlock) |
| int | ast_async_goto_by_name (char *chan, char *context, char *exten, int priority) |
| int | ast_pbx_outgoing_exten (char *type, int format, void *data, int timeout, char *context, char *exten, int priority, int *reason, int sync, char *callerid, char *variable, char *account) |
| int | ast_pbx_outgoing_app (char *type, int format, void *data, int timeout, char *app, char *appdata, int *reason, int sync, char *callerid, char *variable, char *account) |
| char * | ast_get_context_name (struct ast_context *con) |
| char * | ast_get_extension_name (struct ast_exten *exten) |
| char * | ast_get_include_name (struct ast_include *include) |
| char * | ast_get_ignorepat_name (struct ast_ignorepat *ip) |
| char * | ast_get_switch_name (struct ast_sw *sw) |
| char * | ast_get_switch_data (struct ast_sw *sw) |
| int | ast_get_extension_priority (struct ast_exten *exten) |
| char * | ast_get_extension_app (struct ast_exten *e) |
| void * | ast_get_extension_app_data (struct ast_exten *e) |
| char * | ast_get_context_registrar (struct ast_context *c) |
| char * | ast_get_extension_registrar (struct ast_exten *e) |
| char * | ast_get_include_registrar (struct ast_include *i) |
| char * | ast_get_ignorepat_registrar (struct ast_ignorepat *ip) |
| char * | ast_get_switch_registrar (struct ast_sw *sw) |
| ast_context * | ast_walk_contexts (struct ast_context *con) |
| ast_exten * | ast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority) |
| ast_exten * | ast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority) |
| ast_include * | ast_walk_context_includes (struct ast_context *con, struct ast_include *inc) |
| ast_ignorepat * | ast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip) |
| ast_sw * | ast_walk_context_switches (struct ast_context *con, struct ast_sw *sw) |
| char * | pbx_builtin_getvar_helper (struct ast_channel *chan, char *name) |
| void | pbx_builtin_setvar_helper (struct ast_channel *chan, char *name, char *value) |
| void | pbx_builtin_clear_globals (void) |
| int | pbx_builtin_setvar (struct ast_channel *chan, void *data) |
| void | pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count) |
| int | ast_extension_patmatch (const char *pattern, const char *data) |
|
|
All devices BUSY.
|
|
|
One or more devices INUSE.
|
|
|
Extension states No device INUSE or BUSY |
|
|
All devices UNAVAILABLE/UNREGISTERED.
|
|
|
Max length of an application.
|
|
|
|
|
|
Special return values from applications to the PBX.
Definition at line 30 of file pbx.h. Referenced by ast_pbx_run(). |
|
|
|
|
|
|
|
|
Special Priority for an hint.
Definition at line 34 of file pbx.h. Referenced by ast_context_remove_extension2(). |
|
|
Definition at line 52 of file pbx.h. Referenced by ast_extension_state_add(), and ast_extension_state_del(). |
|
||||||||||||||||||||||||||||||||||||||||
|
Definition at line 3470 of file pbx.c.
03472 {
03473 struct ast_context *c;
03474
03475 if (ast_lock_contexts()) {
03476 errno = EBUSY;
03477 return -1;
03478 }
03479
03480 c = ast_walk_contexts(NULL);
03481 while (c) {
03482 if (!strcmp(context, ast_get_context_name(c))) {
03483 int ret = ast_add_extension2(c, replace, extension, priority, callerid,
03484 application, data, datad, registrar);
03485 ast_unlock_contexts();
03486 return ret;
03487 }
03488 c = ast_walk_contexts(c);
03489 }
03490
03491 ast_unlock_contexts();
03492 errno = ENOENT;
03493 return -1;
03494 }
|
|
||||||||||||||||||||||||||||||||||||||||
|
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 3602 of file pbx.c. Referenced by ast_ignore_pattern().
03606 {
03607
03608 #define LOG do { if (option_debug) {\
03609 if (tmp->matchcid) { \
03610 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \
03611 } else { \
03612 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \
03613 } \
03614 } else if (option_verbose > 2) { \
03615 if (tmp->matchcid) { \
03616 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \
03617 } else { \
03618 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \
03619 } \
03620 } } while(0)
03621
03622 /*
03623 * This is a fairly complex routine. Different extensions are kept
03624 * in order by the extension number. Then, extensions of different
03625 * priorities (same extension) are kept in a list, according to the
03626 * peer pointer.
03627 */
03628 struct ast_exten *tmp, *e, *el = NULL, *ep = NULL;
03629 int res;
03630 /* Be optimistic: Build the extension structure first */
03631 tmp = malloc(sizeof(struct ast_exten));
03632 if (tmp) {
03633 memset(tmp, 0, sizeof(struct ast_exten));
03634 ext_strncpy(tmp->exten, extension, sizeof(tmp->exten));
03635 tmp->priority = priority;
03636 if (callerid) {
03637 ext_strncpy(tmp->cidmatch, callerid, sizeof(tmp->cidmatch));
03638 tmp->matchcid = 1;
03639 } else {
03640 strcpy(tmp->cidmatch, "");
03641 tmp->matchcid = 0;
03642 }
03643 strncpy(tmp->app, application, sizeof(tmp->app)-1);
03644 tmp->parent = con;
03645 tmp->data = data;
03646 tmp->datad = datad;
03647 tmp->registrar = registrar;
03648 tmp->peer = NULL;
03649 tmp->next = NULL;
03650 } else {
03651 ast_log(LOG_ERROR, "Out of memory\n");
03652 errno = ENOMEM;
03653 return -1;
03654 }
03655 if (ast_mutex_lock(&con->lock)) {
03656 free(tmp);
03657 /* And properly destroy the data */
03658 datad(data);
03659 ast_log(LOG_WARNING, "Failed to lock context '%s'\n", con->name);
03660 errno = EBUSY;
03661 return -1;
03662 }
03663 e = con->root;
03664 while(e) {
03665 res= strcasecmp(e->exten, extension);
03666 if (!res) {
03667 if (!e->matchcid && !tmp->matchcid)
03668 res = 0;
03669 else if (tmp->matchcid && !e->matchcid)
03670 res = 1;
03671 else if (e->matchcid && !tmp->matchcid)
03672 res = -1;
03673 else
03674 res = strcasecmp(e->cidmatch, tmp->cidmatch);
03675 }
03676 if (res == 0) {
03677 /* We have an exact match, now we find where we are
03678 and be sure there's no duplicates */
03679 while(e) {
03680 if (e->priority == tmp->priority) {
03681 /* Can't have something exactly the same. Is this a
03682 replacement? If so, replace, otherwise, bonk. */
03683 if (replace) {
03684 if (ep) {
03685 /* We're in the peer list, insert ourselves */
03686 ep->peer = tmp;
03687 tmp->peer = e->peer;
03688 } else if (el) {
03689 /* We're the first extension. Take over e's functions */
03690 el->next = tmp;
03691 tmp->next = e->next;
03692 tmp->peer = e->peer;
03693 } else {
03694 /* We're the very first extension. */
03695 con->root = tmp;
03696 tmp->next = e->next;
03697 tmp->peer = e->peer;
03698 }
03699 if (tmp->priority == PRIORITY_HINT)
03700 ast_change_hint(e,tmp);
03701 /* Destroy the old one */
03702 e->datad(e->data);
03703 free(e);
03704 ast_mutex_unlock(&con->lock);
03705 if (tmp->priority == PRIORITY_HINT)
03706 ast_change_hint(e, tmp);
03707 /* And immediately return success. */
03708 LOG;
03709 return 0;
03710 } else {
03711 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name);
03712 tmp->datad(tmp->data);
03713 free(tmp);
03714 ast_mutex_unlock(&con->lock);
03715 errno = EEXIST;
03716 return -1;
03717 }
03718 } else if (e->priority > tmp->priority) {
03719 /* Slip ourselves in just before e */
03720 if (ep) {
03721 /* Easy enough, we're just in the peer list */
03722 ep->peer = tmp;
03723 tmp->peer = e;
03724 } else if (el) {
03725 /* We're the first extension in this peer list */
03726 el->next = tmp;
03727 tmp->next = e->next;
03728 e->next = NULL;
03729 tmp->peer = e;
03730 } else {
03731 /* We're the very first extension altogether */
03732 tmp->next = con->root;
03733 /* Con->root must always exist or we couldn't get here */
03734 tmp->peer = con->root->peer;
03735 con->root = tmp;
03736 }
03737 ast_mutex_unlock(&con->lock);
03738 /* And immediately return success. */
03739 if (tmp->priority == PRIORITY_HINT)
03740 ast_add_hint(tmp);
03741
03742 LOG;
03743 return 0;
03744 }
03745 ep = e;
03746 e = e->peer;
03747 }
03748 /* If we make it here, then it's time for us to go at the very end.
03749 ep *must* be defined or we couldn't have gotten here. */
03750 ep->peer = tmp;
03751 ast_mutex_unlock(&con->lock);
03752 if (tmp->priority == PRIORITY_HINT)
03753 ast_add_hint(tmp);
03754
03755 /* And immediately return success. */
03756 LOG;
03757 return 0;
03758
03759 } else if (res > 0) {
03760 /* Insert ourselves just before 'e'. We're the first extension of
03761 this kind */
03762 tmp->next = e;
03763 if (el) {
03764 /* We're in the list somewhere */
03765 el->next = tmp;
03766 } else {
03767 /* We're at the top of the list */
03768 con->root = tmp;
03769 }
03770 ast_mutex_unlock(&con->lock);
03771 if (tmp->priority == PRIORITY_HINT)
03772 ast_add_hint(tmp);
03773
03774 /* And immediately return success. */
03775 LOG;
03776 return 0;
03777 }
03778
03779 el = e;
03780 e = e->next;
03781 }
03782 /* If we fall all the way through to here, then we need to be on the end. */
03783 if (el)
03784 el->next = tmp;
03785 else
03786 con->root = tmp;
03787 ast_mutex_unlock(&con->lock);
03788 if (tmp->priority == PRIORITY_HINT)
03789 ast_add_hint(tmp);
03790 LOG;
03791 return 0;
03792 }
|
|
||||||||||||||||||||||||
|
Definition at line 3496 of file pbx.c.
03497 {
03498 int res = 0;
03499 if (needlock)
03500 ast_mutex_lock(&chan->lock);
03501 if (chan->pbx) {
03502 /* This channel is currently in the PBX */
03503 if (context && strlen(context))
03504 strncpy(chan->context, context, sizeof(chan->context) - 1);
03505 if (exten && strlen(exten))
03506 strncpy(chan->exten, exten, sizeof(chan->context) - 1);
03507 if (priority)
03508 chan->priority = priority - 1;
03509 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
03510 if (needlock)
03511 ast_mutex_unlock(&chan->lock);
03512 } else {
03513 /* In order to do it when the channel doesn't really exist within
03514 the PBX, we have to make a new channel, masquerade, and start the PBX
03515 at the new location */
03516 struct ast_channel *tmpchan;
03517 struct ast_frame *f;
03518 tmpchan = ast_channel_alloc(0);
03519 if (tmpchan) {
03520 snprintf(tmpchan->name, sizeof(tmpchan->name), "AsyncGoto/%s", chan->name);
03521 ast_setstate(tmpchan, chan->_state);
03522 /* Make formats okay */
03523 tmpchan->readformat = chan->readformat;
03524 tmpchan->writeformat = chan->writeformat;
03525 /* Setup proper location */
03526 if (context && strlen(context))
03527 strncpy(tmpchan->context, context, sizeof(tmpchan->context) - 1);
03528 else
03529 strncpy(tmpchan->context, chan->context, sizeof(tmpchan->context) - 1);
03530 if (exten && strlen(exten))
03531 strncpy(tmpchan->exten, exten, sizeof(tmpchan->exten) - 1);
03532 else
03533 strncpy(tmpchan->exten, chan->exten, sizeof(tmpchan->exten) - 1);
03534 if (priority)
03535 tmpchan->priority = priority;
03536 else
03537 tmpchan->priority = chan->priority;
03538 if (needlock)
03539 ast_mutex_unlock(&chan->lock);
03540
03541 /* Masquerade into temp channel */
03542 ast_channel_masquerade(tmpchan, chan);
03543
03544 /* Make the masquerade happen by reading a frame from the tmp channel */
03545 f = ast_read(tmpchan);
03546 if (f)
03547 ast_frfree(f);
03548 /* Start the PBX going on our stolen channel */
03549 if (ast_pbx_start(tmpchan)) {
03550 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
03551 ast_hangup(tmpchan);
03552 res = -1;
03553 }
03554 } else {
03555 res = -1;
03556 if (needlock)
03557 ast_mutex_unlock(&chan->lock);
03558 }
03559 }
03560 return res;
03561 }
|
|
||||||||||||||||||||
|
Definition at line 3563 of file pbx.c.
03564 {
03565 struct ast_channel *chan;
03566 chan = ast_channel_walk(NULL);
03567 while(chan) {
03568 if (!strcasecmp(channame, chan->name))
03569 break;
03570 chan = ast_channel_walk(chan);
03571 }
03572 if (chan)
03573 return ast_async_goto(chan, context, exten, priority, 1);
03574 return -1;
03575 }
|
|
||||||||||||||||||||||||
|
Looks for a valid matching extension.
Definition at line 1643 of file pbx.c. References HELPER_CANMATCH.
01644 {
01645 return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_CANMATCH);
01646 }
|
|
||||||||||||||||
|
Add an ignorepat.
Definition at line 3391 of file pbx.c.
03392 {
03393 struct ast_context *c;
03394
03395 if (ast_lock_contexts()) {
03396 errno = EBUSY;
03397 return -1;
03398 }
03399
03400 c = ast_walk_contexts(NULL);
03401 while (c) {
03402 if (!strcmp(ast_get_context_name(c), con)) {
03403 int ret = ast_context_add_ignorepat2(c, value, registrar);
03404 ast_unlock_contexts();
03405 return ret;
03406 }
03407 c = ast_walk_contexts(c);
03408 }
03409
03410 ast_unlock_contexts();
03411 errno = ENOENT;
03412 return -1;
03413 }
|
|
||||||||||||||||
|
Definition at line 3415 of file pbx.c. References ast_mutex_unlock, and ast_context::lock.
03416 {
03417 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
03418 ignorepat = malloc(sizeof(struct ast_ignorepat));
03419 if (!ignorepat) {
03420 ast_log(LOG_ERROR, "Out of memory\n");
03421 errno = ENOMEM;
03422 return -1;
03423 }
03424 memset(ignorepat, 0, sizeof(struct ast_ignorepat));
03425 strncpy(ignorepat->pattern, value, sizeof(ignorepat->pattern)-1);
03426 ignorepat->next = NULL;
03427 ignorepat->registrar = registrar;
03428 ast_mutex_lock(&con->lock);
03429 ignorepatc = con->ignorepats;
03430 while(ignorepatc) {
03431 ignorepatl = ignorepatc;
03432 if (!strcasecmp(ignorepatc->pattern, value)) {
03433 /* Already there */
03434 ast_mutex_unlock(&con->lock);
03435 errno = EEXIST;
03436 return -1;
03437 }
03438 ignorepatc = ignorepatc->next;
03439 }
03440 if (ignorepatl)
03441 ignorepatl->next = ignorepat;
03442 else
03443 con->ignorepats = ignorepat;
03444 ast_mutex_unlock(&con->lock);
03445 return 0;
03446
03447 }
|
|
||||||||||||||||
|
Add an include.
Definition at line 2855 of file pbx.c.
02856 {
02857 struct ast_context *c;
02858
02859 if (ast_lock_contexts()) {
02860 errno = EBUSY;
02861 return -1;
02862 }
02863
02864 /* walk contexts ... */
02865 c = ast_walk_contexts(NULL);
02866 while (c) {
02867 /* ... search for the right one ... */
02868 if (!strcmp(ast_get_context_name(c), context)) {
02869 int ret = ast_context_add_include2(c, include, registrar);
02870 /* ... unlock contexts list and return */
02871 ast_unlock_contexts();
02872 return ret;
02873 }
02874 c = ast_walk_contexts(c);
02875 }
02876
02877 /* we can't find the right context */
02878 ast_unlock_contexts();
02879 errno = ENOENT;
02880 return -1;
02881 }
|
|
||||||||||||||||
|
Add an include.
Definition at line 3172 of file pbx.c.
03174 {
03175 struct ast_include *new_include;
03176 char *c;
03177 struct ast_include *i, *il = NULL; /* include, include_last */
03178
03179 /* allocate new include structure ... */
03180 if (!(new_include = malloc(sizeof(struct ast_include)))) {
03181 ast_log(LOG_ERROR, "Out of memory\n");
03182 errno = ENOMEM;
03183 return -1;
03184 }
03185
03186 /* ... fill in this structure ... */
03187 memset(new_include, 0, sizeof(struct ast_include));
03188 strncpy(new_include->name, value, sizeof(new_include->name)-1);
03189 strncpy(new_include->rname, value, sizeof(new_include->rname)-1);
03190 c = new_include->rname;
03191 /* Strip off timing info */
03192 while(*c && (*c != '|')) c++;
03193 /* Process if it's there */
03194 if (*c) {
03195 build_timing(new_include, c+1);
03196 *c = '\0';
03197 }
03198 new_include->next = NULL;
03199 new_include->registrar = registrar;
03200
03201 /* ... try to lock this context ... */
03202 if (ast_mutex_lock(&con->lock)) {
03203 free(new_include);
03204 errno = EBUSY;
03205 return -1;
03206 }
03207
03208 /* ... go to last include and check if context is already included too... */
03209 i = con->includes;
03210 while (i) {
03211 if (!strcasecmp(i->name, new_include->name)) {
03212 free(new_include);
03213 ast_mutex_unlock(&con->lock);
03214 errno = EEXIST;
03215 return -1;
03216 }
03217 il = i;
03218 i = i->next;
03219 }
03220
03221 /* ... include new context into context list, unlock, return */
03222 if (il)
03223 il->next = new_include;
03224 else
03225 con->includes = new_include;
03226 if (option_verbose > 2)
03227 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
03228 ast_mutex_unlock(&con->lock);
03229
03230 return 0;
03231 }
|
|
||||||||||||||||||||
|
Add a switch.
Definition at line 3238 of file pbx.c.
03239 {
03240 struct ast_context *c;
03241
03242 if (ast_lock_contexts()) {
03243 errno = EBUSY;
03244 return -1;
03245 }
03246
03247 /* walk contexts ... */
03248 c = ast_walk_contexts(NULL);
03249 while (c) {
03250 /* ... search for the right one ... */
03251 if (!strcmp(ast_get_context_name(c), context)) {
03252 int ret = ast_context_add_switch2(c, sw, data, registrar);
03253 /* ... unlock contexts list and return */
03254 ast_unlock_contexts();
03255 return ret;
03256 }
03257 c = ast_walk_contexts(c);
03258 }
03259
03260 /* we can't find the right context */
03261 ast_unlock_contexts();
03262 errno = ENOENT;
03263 return -1;
03264 }
|
|
||||||||||||||||||||
|
Adds a switch (first param is a ast_context). Definition at line 3273 of file pbx.c.
03275 {
03276 struct ast_sw *new_sw;
03277 struct ast_sw *i, *il = NULL; /* sw, sw_last */
03278
03279 /* allocate new sw structure ... */
03280 if (!(new_sw = malloc(sizeof(struct ast_sw)))) {
03281 ast_log(LOG_ERROR, "Out of memory\n");
03282 errno = ENOMEM;
03283 return -1;
03284 }
03285
03286 /* ... fill in this structure ... */
03287 memset(new_sw, 0, sizeof(struct ast_sw));
03288 strncpy(new_sw->name, value, sizeof(new_sw->name)-1);
03289 if (data)
03290 strncpy(new_sw->data, data, sizeof(new_sw->data)-1);
03291 else
03292 strncpy(new_sw->data, "", sizeof(new_sw->data)-1);
03293 new_sw->next = NULL;
03294 new_sw->registrar = registrar;
03295
03296 /* ... try to lock this context ... */
03297 if (ast_mutex_lock(&con->lock)) {
03298 free(new_sw);
03299 errno = EBUSY;
03300 return -1;
03301 }
03302
03303 /* ... go to last sw and check if context is already swd too... */
03304 i = con->alts;
03305 while (i) {
03306 if (!strcasecmp(i->name, new_sw->name)) {
03307 free(new_sw);
03308 ast_mutex_unlock(&con->lock);
03309 errno = EEXIST;
03310 return -1;
03311 }
03312 il = i;
03313 i = i->next;
03314 }
03315
03316 /* ... sw new context into context list, unlock, return */
03317 if (il)
03318 il->next = new_sw;
03319 else
03320 con->alts = new_sw;
03321 if (option_verbose > 2)
03322 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
03323 ast_mutex_unlock(&con->lock);
03324
03325 return 0;
03326 }
|
|
||||||||||||||||
|
Register a new context.
Definition at line 2778 of file pbx.c.
02779 {
02780 struct ast_context *tmp, **local_contexts;
02781 if (!extcontexts) {
02782 local_contexts = &contexts;
02783 ast_mutex_lock(&conlock);
02784 } else
02785 local_contexts = extcontexts;
02786
02787 tmp = *local_contexts;
02788 while(tmp) {
02789 if (!strcasecmp(tmp->name, name)) {
02790 ast_mutex_unlock(&conlock);
02791 ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name);
02792 if (!extcontexts)
02793 ast_mutex_unlock(&conlock);
02794 return NULL;
02795 }
02796 tmp = tmp->next;
02797 }
02798 tmp = malloc(sizeof(struct ast_context));
02799 if (tmp) {
02800 memset(tmp, 0, sizeof(struct ast_context));
02801 ast_mutex_init(&tmp->lock);
02802 strncpy(tmp->name, name, sizeof(tmp->name)-1);
02803 tmp->root = NULL;
02804 tmp->registrar = registrar;
02805 tmp->next = *local_contexts;
02806 tmp->includes = NULL;
02807 tmp->ignorepats = NULL;
02808 *local_contexts = tmp;
02809 if (option_debug)
02810 ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name);
02811 else if (option_verbose > 2)
02812 ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name);
02813 } else
02814 ast_log(LOG_ERROR, "Out of memory\n");
02815
02816 if (!extcontexts)
02817 ast_mutex_unlock(&conlock);
02818 return tmp;
02819 }
|
|
||||||||||||
|
Destroy a context (matches the specified context (or ANY context if NULL).
Definition at line 4130 of file pbx.c.
04131 {
04132 __ast_context_destroy(con,registrar,1);
04133 }
|
|
|
Find a context.
Definition at line 597 of file pbx.c. References ast_mutex_lock, ast_mutex_unlock, and ast_context::next.
00598 {
00599 struct ast_context *tmp;
00600 ast_mutex_lock(&conlock);
00601 if (name) {
00602 tmp = contexts;
00603 while(tmp) {
00604 if (!strcasecmp(name, tmp->name))
00605 break;
00606 tmp = tmp->next;
00607 }
00608 } else
00609 tmp = contexts;
00610 ast_mutex_unlock(&conlock);
00611 return tmp;
00612 }
|
|
||||||||||||||||||||
|
Simply remove extension from context.
Definition at line 2053 of file pbx.c. References ast_context_remove_extension2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
02054 {
02055 struct ast_context *c;
02056
02057 if (ast_lock_contexts()) return -1;
02058
02059 /* walk contexts ... */
02060 c = ast_walk_contexts(NULL);
02061 while (c) {
02062 /* ... search for the right one ... */
02063 if (!strcmp(ast_get_context_name(c), context)) {
02064 /* ... remove extension ... */
02065 int ret = ast_context_remove_extension2(c, extension, priority,
02066 registrar);
02067 /* ... unlock contexts list and return */
02068 ast_unlock_contexts();
02069 return ret;
02070 }
02071 c = ast_walk_contexts(c);
02072 }
02073
02074 /* we can't find the right context */
02075 ast_unlock_contexts();
02076 return -1;
02077 }
|
|
||||||||||||||||||||
|
Definition at line 2089 of file pbx.c. References ast_mutex_lock, ast_mutex_unlock, free, ast_context::lock, ast_exten::next, ast_exten::peer, PRIORITY_HINT, and ast_context::root. Referenced by ast_context_remove_extension().
02090 {
02091 struct ast_exten *exten, *prev_exten = NULL;
02092
02093 if (ast_mutex_lock(&con->lock)) return -1;
02094
02095 /* go through all extensions in context and search the right one ... */
02096 exten = con->root;
02097 while (exten) {
02098
02099 /* look for right extension */
02100 if (!strcmp(exten->exten, extension) &&
02101 (!strcmp(exten->registrar, registrar) || !registrar)) {
02102 struct ast_exten *peer;
02103
02104 /* should we free all peers in this extension? (priority == 0)? */
02105 if (priority == 0) {
02106 /* remove this extension from context list */
02107 if (prev_exten)
02108 prev_exten->next = exten->next;
02109 else
02110 con->root = exten->next;
02111
02112 /* fire out all peers */
02113 peer = exten;
02114 while (peer) {
02115 exten = peer->peer;
02116
02117 if (!peer->priority==PRIORITY_HINT)
02118 ast_remove_hint(peer);
02119
02120 peer->datad(peer->data);
02121 free(peer);
02122
02123 peer = exten;
02124 }
02125
02126 ast_mutex_unlock(&con->lock);
02127 return 0;
02128 } else {
02129 /* remove only extension with exten->priority == priority */
02130 struct ast_exten *previous_peer = NULL;
02131
02132 peer = exten;
02133 while (peer) {
02134 /* is this our extension? */
02135 if (peer->priority == priority &&
02136 (!strcmp(peer->registrar, registrar) || !registrar)) {
02137 /* we are first priority extension? */
02138 if (!previous_peer) {
02139 /* exists previous extension here? */
02140 if (prev_exten) {
02141 /* yes, so we must change next pointer in
02142 * previous connection to next peer
02143 */
02144 if (peer->peer) {
02145 prev_exten->next = peer->peer;
02146 peer->peer->next = exten->next;
02147 } else
02148 prev_exten->next = exten->next;
02149 } else {
02150 /* no previous extension, we are first
02151 * extension, so change con->root ...
02152 */
02153 if (peer->peer)
02154 con->root = peer->peer;
02155 else
02156 con->root = exten->next;
02157 }
02158 } else {
02159 /* we are not first priority in extension */
02160 previous_peer->peer = peer->peer;
02161 }
02162
02163 /* now, free whole priority extension */
02164 if (peer->priority==PRIORITY_HINT)
02165 ast_remove_hint(peer);
02166 peer->datad(peer->data);
02167 free(peer);
02168
02169 ast_mutex_unlock(&con->lock);
02170 return 0;
02171 } else {
02172 /* this is not right extension, skip to next peer */
02173 previous_peer = peer;
02174 peer = peer->peer;
02175 }
02176 }
02177
02178 ast_mutex_unlock(&con->lock);
02179 return -1;
02180 }
02181 }
02182
02183 prev_exten = exten;
02184 exten = exten->next;
02185 }
02186
02187 /* we can't find right extension */
02188 ast_mutex_unlock(&con->lock);
02189 return -1;
02190 }
|
|
||||||||||||||||
|
Definition at line 3332 of file pbx.c.
03333 {
03334 struct ast_context *c;
03335
03336 if (ast_lock_contexts()) {
03337 errno = EBUSY;
03338 return -1;
03339 }
03340
03341 c = ast_walk_contexts(NULL);
03342 while (c) {
03343 if (!strcmp(ast_get_context_name(c), context)) {
03344 int ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
03345 ast_unlock_contexts();
03346 return ret;
03347 }
03348 c = ast_walk_contexts(c);
03349 }
03350
03351 ast_unlock_contexts();
03352 errno = ENOENT;
03353 return -1;
03354 }
|
|
||||||||||||||||
|
Definition at line 3356 of file pbx.c.
03357 {
03358 struct ast_ignorepat *ip, *ipl = NULL;
03359
03360 if (ast_mutex_lock(&con->lock)) {
03361 errno = EBUSY;
03362 return -1;
03363 }
03364
03365 ip = con->ignorepats;
03366 while (ip) {
03367 if (!strcmp(ip->pattern, ignorepat) &&
03368 (registrar == ip->registrar || !registrar)) {
03369 if (ipl) {
03370 ipl->next = ip->next;
03371 free(ip);
03372 } else {
03373 con->ignorepats = ip->next;
03374 free(ip);
03375 }
03376 ast_mutex_unlock(&con->lock);
03377 return 0;
03378 }
03379 ipl = ip; ip = ip->next;
03380 }
03381
03382 ast_mutex_unlock(&con->lock);
03383 errno = EINVAL;
03384 return -1;
03385 }
|
|
||||||||||||||||
|
Removes an include. See add_include Definition at line 1909 of file pbx.c. References ast_context_remove_include2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
01910 {
01911 struct ast_context *c;
01912
01913 if (ast_lock_contexts()) return -1;
01914
01915 /* walk contexts and search for the right one ...*/
01916 c = ast_walk_contexts(NULL);
01917 while (c) {
01918 /* we found one ... */
01919 if (!strcmp(ast_get_context_name(c), context)) {
01920 int ret;
01921 /* remove include from this context ... */
01922 ret = ast_context_remove_include2(c, include, registrar);
01923
01924 ast_unlock_contexts();
01925
01926 /* ... return results */
01927 return ret;
01928 }
01929 c = ast_walk_contexts(c);
01930 }
01931
01932 /* we can't find the right one context */
01933 ast_unlock_contexts();
01934 return -1;
01935 }
|
|
||||||||||||||||
|
Removes an include by an ast_context structure. See add_include2 Definition at line 1945 of file pbx.c. References ast_mutex_lock, ast_mutex_unlock, free, ast_context::includes, ast_context::lock, and ast_include::next. Referenced by ast_context_remove_include().
01946 {
01947 struct ast_include *i, *pi = NULL;
01948
01949 if (ast_mutex_lock(&con->lock)) return -1;
01950
01951 /* walk includes */
01952 i = con->includes;
01953 while (i) {
01954 /* find our include */
01955 if (!strcmp(i->name, include) &&
01956 (!strcmp(i->registrar, registrar) || !registrar)) {
01957 /* remove from list */
01958 if (pi)
01959 pi->next = i->next;
01960 else
01961 con->includes = i->next;
01962 /* free include and return */
01963 free(i);
01964 ast_mutex_unlock(&con->lock);
01965 return 0;
01966 }
01967 pi = i;
01968 i = i->next;
01969 }
01970
01971 /* we can't find the right include */
01972 ast_mutex_unlock(&con->lock);
01973 return -1;
01974 }
|
|
||||||||||||||||||||
|
Remove a switch. Removes a switch with the given parameters Returns 0 on success, -1 on failure Definition at line 1981 of file pbx.c. References ast_context_remove_switch2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
01982 {
01983 struct ast_context *c;
01984
01985 if (ast_lock_contexts()) return -1;
01986
01987 /* walk contexts and search for the right one ...*/
01988 c = ast_walk_contexts(NULL);
01989 while (c) {
01990 /* we found one ... */
01991 if (!strcmp(ast_get_context_name(c), context)) {
01992 int ret;
01993 /* remove switch from this context ... */
01994 ret = ast_context_remove_switch2(c, sw, data, registrar);
01995
01996 ast_unlock_contexts();
01997
01998 /* ... return results */
01999 return ret;
02000 }
02001 c = ast_walk_contexts(c);
02002 }
02003
02004 /* we can't find the right one context */
02005 ast_unlock_contexts();
02006 return -1;
02007 }
|
|
||||||||||||||||||||
|
Definition at line 2017 of file pbx.c. References ast_context::alts, ast_mutex_lock, ast_mutex_unlock, free, ast_context::lock, and ast_sw::next. Referenced by ast_context_remove_switch().
02018 {
02019 struct ast_sw *i, *pi = NULL;
02020
02021 if (ast_mutex_lock(&con->lock)) return -1;
02022
02023 /* walk switchs */
02024 i = con->alts;
02025 while (i) {
02026 /* find our switch */
02027 if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
02028 (!strcmp(i->registrar, registrar) || !registrar)) {
02029 /* remove from list */
02030 if (pi)
02031 pi->next = i->next;
02032 else
02033 con->alts = i->next;
02034 /* free switch and return */
02035 free(i);
02036 ast_mutex_unlock(&con->lock);
02037 return 0;
02038 }
02039 pi = i;
02040 i = i->next;
02041 }
02042
02043 /* we can't find the right switch */
02044 ast_mutex_unlock(&con->lock);
02045 return -1;
02046 }
|
|
|
Verifies includes in an ast_contect structure.
Definition at line 4731 of file pbx.c.
04732 {
04733 struct ast_include *inc;
04734 int res = 0;
04735
04736 for (inc = ast_walk_context_includes(con, NULL); inc; inc = ast_walk_context_includes(con, inc))
04737 if (!ast_context_find(inc->rname)) {
04738 res = -1;
04739 ast_log(LOG_WARNING, "Context '%s' tries includes non-existant context '%s'\n",
04740 ast_get_context_name(con), inc->rname);
04741 }
04742 return res;
04743 }
|
|
||||||||||||
|
Tells Asterisk the State for Device is changed.
Referenced by ast_channel_free(), and ast_setstate(). |
|
||||||||||||||||||||||||
|
Execute an extension.
|
|
||||||||||||||||||||||||
|
If an extension exists, return non-zero.
Definition at line 1638 of file pbx.c. References HELPER_EXISTS. Referenced by ast_pbx_run().
01639 {
01640 return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_EXISTS);
01641 }
|
|
||||||||||||
|
Determine if a given extension matches a given pattern (in NXX format).
Definition at line 564 of file pbx.c. References EXTENSION_MATCH_CORE.
00565 {
00566 int match;
00567 /* If they're the same return */
00568 if (!strcmp(pattern, data))
00569 return 1;
00570 EXTENSION_MATCH_CORE(data,pattern,match);
00571 /* Must be at the end of both */
00572 if (*data || (*pattern && (*pattern != '/')))
00573 match = 0;
00574 return match;
00575 }
|
|
||||||||||||
|
|
|
||||||||||||||||
|
Uses hint and devicestate callback to get the state of an extension.
Definition at line 1308 of file pbx.c.
01309 {
01310 struct ast_exten *e;
01311
01312 e = ast_hint_extension(c, context, exten);
01313 if (!e)
01314 return -1;
01315
01316 return ast_extension_state2(e);
01317 }
|
|
||||||||||||||||||||
|
Registers a state change callback.
Definition at line 1386 of file pbx.c. References ast_mutex_lock, ast_mutex_unlock, ast_state_cb_type, ast_state_cb::data, hints, malloc, ast_hint::next, and statecbs. Referenced by init_manager().
01388 {
01389 struct ast_hint *list;
01390 struct ast_state_cb *cblist;
01391 struct ast_exten *e;
01392
01393 /* No context and extension add callback to statecbs list */
01394 if (!context && !exten) {
01395 ast_mutex_lock(&hintlock);
01396
01397 cblist = statecbs;
01398 while (cblist) {
01399 if (cblist->callback == callback) {
01400 cblist->data = data;
01401 ast_mutex_unlock(&hintlock);
01402 }
01403
01404 cblist = cblist->next;
01405 }
01406
01407 /* Now inserts the callback */
01408 cblist = malloc(sizeof(struct ast_state_cb));
01409 if (!cblist) {
01410 ast_mutex_unlock(&hintlock);
01411 return -1;
01412 }
01413 memset(cblist, 0, sizeof(struct ast_state_cb));
01414 cblist->id = 0;
01415 cblist->callback = callback;
01416 cblist->data = data;
01417
01418 cblist->next = statecbs;
01419 statecbs = cblist;
01420
01421 ast_mutex_unlock(&hintlock);
01422 return 0;
01423 }
01424
01425 if (!context || !exten)
01426 return -1;
01427
01428 /* This callback type is for only one hint */
01429 e = ast_hint_extension(NULL, context, exten);
01430 if (!e) {
01431 return -1;
01432 }
01433
01434 ast_mutex_lock(&hintlock);
01435 list = hints;
01436
01437 while (list) {
01438 if (list->exten == e)
01439 break;
01440 list = list->next;
01441 }
01442
01443 if (!list) {
01444 ast_mutex_unlock(&hintlock);
01445 return -1;
01446 }
01447
01448 /* Now inserts the callback */
01449 cblist = malloc(sizeof(struct ast_state_cb));
01450 if (!cblist) {
01451 ast_mutex_unlock(&hintlock);
01452 return -1;
01453 }
01454 memset(cblist, 0, sizeof(struct ast_state_cb));
01455 cblist->id = stateid++;
01456 cblist->callback = callback;
01457 cblist->data = data;
01458
01459 cblist->next = list->callbacks;
01460 list->callbacks = cblist;
01461
01462 ast_mutex_unlock(&hintlock);
01463 return cblist->id;
01464 }
|
|
||||||||||||
|
Deletes a registered state change callback by ID.
Definition at line 1466 of file pbx.c. References ast_mutex_lock, ast_mutex_unlock, ast_state_cb_type, ast_hint::callbacks, free, hints, ast_state_cb::next, and statecbs.
01467 {
01468 struct ast_hint *list;
01469 struct ast_state_cb *cblist, *cbprev;
01470
01471 if (!id && !callback)
01472 return -1;
01473
01474 ast_mutex_lock(&hintlock);
01475
01476 /* id is zero is a callback without extension */
01477 if (!id) {
01478 cbprev = NULL;
01479 cblist = statecbs;
01480 while (cblist) {
01481 if (cblist->callback == callback) {
01482 if (!cbprev)
01483 statecbs = cblist->next;
01484 else
01485 cbprev->next = cblist->next;
01486
01487 free(cblist);
01488
01489 ast_mutex_unlock(&hintlock);
01490 return 0;
01491 }
01492 cbprev = cblist;
01493 cblist = cblist->next;
01494 }
01495
01496 ast_mutex_lock(&hintlock);
01497 return -1;
01498 }
01499
01500 /* id greater zero is a callback with extension */
01501 list = hints;
01502 while (list) {
01503 cblist = list->callbacks;
01504 cbprev = NULL;
01505 while (cblist) {
01506 if (cblist->id==id) {
01507 if (!cbprev)
01508 list->callbacks = cblist->next;
01509 else
01510 cbprev->next = cblist->next;
01511
01512 free(cblist);
01513
01514 ast_mutex_unlock(&hintlock);
01515 return 0;
01516 }
01517 cbprev = cblist;
01518 cblist = cblist->next;
01519 }
01520 list = list->next;
01521 }
01522
01523 ast_mutex_unlock(&hintlock);
01524 return -1;
01525 }
|
|
|
Definition at line 4602 of file pbx.c. References ast_ignorepat::pattern. Referenced by ast_context_remove_extension(), ast_context_remove_include(), ast_context_remove_switch(), and ast_ignore_pattern().
04603 {
04604 return con ? con->name : NULL;
04605 }
|
|
|
Definition at line 4630 of file pbx.c. References ast_ignorepat::registrar.
04631 {
04632 return c ? c->registrar : NULL;
04633 }
|
|
|
Definition at line 4650 of file pbx.c. References ast_sw::data. Referenced by ast_device_state_changed(), and ast_get_hint().
04651 {
04652 return e ? e->app : NULL;
04653 }
|
|
|
Definition at line 4655 of file pbx.c. References ast_sw::registrar.
04656 {
04657 return e ? e->data : NULL;
04658 }
|
|
|
Definition at line 4607 of file pbx.c. References ast_exten::priority.
04608 {
04609 return exten ? exten->exten : NULL;
04610 }
|
|
|
Definition at line 4622 of file pbx.c.
04623 {
04624 return exten ? exten->priority : -1;
04625 }
|
|
|
Definition at line 4635 of file pbx.c. References ast_exten::app.
04636 {
04637 return e ? e->registrar : NULL;
04638 }
|
|
||||||||||||||||||||||||
|
If an extension exists, return non-zero.
Definition at line 1627 of file pbx.c. References ast_get_extension_app().
01628 {
01629 struct ast_exten *e;
01630 e = ast_hint_extension(c, context, exten);
01631 if (e) {
01632 strncpy(hint, ast_get_extension_app(e), maxlen);
01633 return -1;
01634 }
01635 return 0;
01636 }
|
|
|
Definition at line 4617 of file pbx.c.
04618 {
04619 return ip ? ip->pattern : NULL;
04620 }
|
|
|
Definition at line 4645 of file pbx.c. References ast_sw::name.
04646 {
04647 return ip ? ip->registrar : NULL;
04648 }
|
|
|
Definition at line 4612 of file pbx.c. References ast_context::registrar.
04613 {
04614 return inc ? inc->name : NULL;
04615 }
|
|
|
Definition at line 4640 of file pbx.c. References ast_exten::data.
04641 {
04642 return i ? i->registrar : NULL;
04643 }
|
|
|
Definition at line 4665 of file pbx.c.
04666 {
04667 return sw ? sw->data : NULL;
04668 }
|
|
|
Definition at line 4660 of file pbx.c.
04661 {
04662 return sw ? sw->name : NULL;
04663 }
|
|
|
Definition at line 4670 of file pbx.c. References ast_exten::next, and ast_context::root.
04671 {
04672 return sw ? sw->registrar : NULL;
04673 }
|
|
||||||||||||
|
Checks to see if a number should be ignored.
Definition at line 3449 of file pbx.c. References ast_add_extension2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
03450 {
03451 struct ast_context *con;
03452 struct ast_ignorepat *pat;
03453 con = ast_context_find(context);
03454 if (con) {
03455 pat = con->ignorepats;
03456 while (pat) {
03457 if (ast_extension_match(pat->pattern, pattern))
03458 return 1;
03459 pat = pat->next;
03460 }
03461 }
03462 return 0;
03463 }
|
|
|
Locks a given context.
Definition at line 4589 of file pbx.c.
04590 {
04591 return ast_mutex_lock(&con->lock);
04592 }
|
|
|
Locks the contexts. Locks the context list Returns 0 on success, -1 on error Definition at line 4576 of file pbx.c. Referenced by ast_context_remove_extension(), ast_context_remove_include(), ast_context_remove_switch(), and ast_ignore_pattern().
04577 {
04578 return ast_mutex_lock(&conlock);
04579 }
|
|
||||||||||||||||||||||||
|
Looks to see if adding anything to this extension might match something. (exists ^ canmatch).
Definition at line 1648 of file pbx.c. References HELPER_MATCHMORE. Referenced by ast_pbx_run().
01649 {
01650 return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_MATCHMORE);
01651 }
|
|
||||||||||||
|
Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added.
Definition at line 2823 of file pbx.c.
02823 {
02824 struct ast_context *tmp, *lasttmp = NULL;
02825 tmp = *extcontexts;
02826 ast_mutex_lock(&conlock);
02827 if (registrar) {
02828 __ast_context_destroy(NULL,registrar,0);
02829 while (tmp) {
02830 lasttmp = tmp;
02831 tmp = tmp->next;
02832 }
02833 } else {
02834 while (tmp) {
02835 __ast_context_destroy(tmp,tmp->registrar,0);
02836 lasttmp = tmp;
02837 tmp = tmp->next;
02838 }
02839 }
02840 if (lasttmp) {
02841 lasttmp->next = contexts;
02842 contexts = *extcontexts;
02843 *extcontexts = NULL;
02844 } else
02845 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n");
02846 ast_mutex_unlock(&conlock);
02847 return;
02848 }
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 3973 of file pbx.c.
03974 {
03975 struct ast_channel *chan;
03976 struct async_stat *as;
03977 struct app_tmp *tmp;
03978 char *var, *vartmp;
03979 int res = -1;
03980 pthread_attr_t attr;
03981
03982 if (!app || !strlen(app))
03983 return -1;
03984 if (sync) {
03985 chan = ast_request_and_dial(type, format, data, timeout, reason, callerid);
03986 if (chan) {
03987 pbx_builtin_setaccount(chan, account);
03988 if (variable) {
03989 vartmp = ast_strdupa(variable);
03990 for (var = strtok_r(vartmp, "|", &vartmp); var; var = strtok_r(NULL, "|", &vartmp)) {
03991 pbx_builtin_setvar( chan, var );
03992 }
03993 }
03994 if (chan->_state == AST_STATE_UP) {
03995 res = 0;
03996 if (option_verbose > 3)
03997 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
03998 tmp = malloc(sizeof(struct app_tmp));
03999 if (tmp) {
04000 memset(tmp, 0, sizeof(struct app_tmp));
04001 strncpy(tmp->app, app, sizeof(tmp->app) - 1);
04002 strncpy(tmp->data, appdata, sizeof(tmp->data) - 1);
04003 tmp->chan = chan;
04004 if (sync > 1) {
04005 ast_pbx_run_app(tmp);
04006 } else {
04007 pthread_attr_init(&attr);
04008 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
04009 if (pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) {
04010 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
04011 free(tmp);
04012 ast_hangup(chan);
04013 res = -1;
04014 }
04015 }
04016 } else {
04017 ast_log(LOG_ERROR, "Out of memory :(\n");
04018 res = -1;
04019 }
04020 } else {
04021 if (option_verbose > 3)
04022 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
04023 ast_hangup(chan);
04024 }
04025 }
04026 } else {
04027 as = malloc(sizeof(struct async_stat));
04028 if (!as)
04029 return -1;
04030 memset(as, 0, sizeof(struct async_stat));
04031 chan = ast_request_and_dial(type, format, data, timeout, reason, callerid);
04032 if (!chan) {
04033 free(as);
04034 return -1;
04035 }
04036 pbx_builtin_setaccount(chan, account);
04037 as->chan = chan;
04038 strncpy(as->app, app, sizeof(as->app) - 1);
04039 if (appdata)
04040 strncpy(as->appdata, appdata, sizeof(as->appdata) - 1);
04041 as->timeout = timeout;
04042 if (pthread_create(&as->p, NULL, async_wait, as)) {
04043 ast_log(LOG_WARNING, "Failed to start async wait\n");
04044 free(as);
04045 ast_hangup(chan);
04046 return -1;
04047 }
04048 res = 0;
04049 }
04050 return res;
04051 }
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 3862 of file pbx.c. References option_verbose.
03863 {
03864 struct ast_channel *chan;
03865 struct async_stat *as;
03866 int res = -1;
03867 char *var, *tmp;
03868 struct outgoing_helper oh;
03869 pthread_attr_t attr;
03870
03871 if (sync) {
03872 LOAD_OH(oh);
03873 chan = __ast_request_and_dial(type, format, data, timeout, reason, callerid, &oh);
03874 if (chan) {
03875 pbx_builtin_setaccount(chan, account);
03876 if (chan->_state == AST_STATE_UP) {
03877 res = 0;
03878 if (option_verbose > 3)
03879 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
03880
03881 if (sync > 1) {
03882 if (ast_pbx_run(chan)) {
03883 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
03884 ast_hangup(chan);
03885 res = -1;
03886 }
03887 } else {
03888 if (ast_pbx_start(chan)) {
03889 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name);
03890 ast_hangup(chan);
03891 res = -1;
03892 }
03893 }
03894 } else {
03895 if (option_verbose > 3)
03896 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
03897 ast_hangup(chan);
03898 }
03899 } else {
03900 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */
03901 /* check if "failed" exists */
03902 if (ast_exists_extension(chan, context, "failed", 1, NULL)) {
03903 chan = ast_channel_alloc(0);
03904 if (chan) {
03905 strncpy(chan->name, "OutgoingSpoolFailed", sizeof(chan->name) - 1);
03906 if (context && strlen(context))
03907 strncpy(chan->context, context, sizeof(chan->context) - 1);
03908 strncpy(chan->exten, "failed", sizeof(chan->exten) - 1);
03909 chan->priority = 1;
03910 if (variable) {
03911 tmp = ast_strdupa(variable);
03912 for (var = strtok_r(tmp, "|", &tmp); var; var = strtok_r(NULL, "|", &tmp)) {
03913 pbx_builtin_setvar( chan, var );
03914 }
03915 }
03916 ast_pbx_run(chan);
03917 } else
03918 ast_log(LOG_WARNING, "Can't allocate the channel structure, skipping execution of extension 'failed'\n");
03919 }
03920 }
03921 } else {
03922 as = malloc(sizeof(struct async_stat));
03923 if (!as)
03924 return -1;
03925 memset(as, 0, sizeof(struct async_stat));
03926 chan = ast_request_and_dial(type, format, data, timeout, reason, callerid);
03927 if (!chan) {
03928 free(as);
03929 return -1;
03930 }
03931 pbx_builtin_setaccount(chan, account);
03932 as->chan = chan;
03933 strncpy(as->context, context, sizeof(as->context) - 1);
03934 strncpy(as->exten, exten, sizeof(as->exten) - 1);
03935 as->priority = priority;
03936 as->timeout = timeout;
03937 pthread_attr_init(&attr);
03938 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
03939 if (pthread_create(&as->p, &attr, async_wait, as)) {
03940 ast_log(LOG_WARNING, "Failed to start async wait\n");
03941 free(as);
03942 ast_hangup(chan);
03943 return -1;
03944 }
03945 res = 0;
03946 }
03947 return res;
03948 }
|
|
|
Execute the PBX in the current thread.
Definition at line 1658 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_hangup(), ast_log(), ast_matchmore_extension(), AST_PBX_KEEPALIVE, AST_SOFTHANGUP_ASYNCGOTO, AST_SOFTHANGUP_TIMEOUT, ast_spawn_extension(), ast_verbose(), ast_waitfordigit(), ast_channel::callerid, ast_channel::cdr, ast_channel::context, ast_pbx::dtimeout, EVENT_FLAG_CALL, ast_channel::exten, free, LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, manager_event(), ast_channel::name, option_debug, option_verbose, ast_channel::pbx, pbx_builtin_setvar_helper(), ast_channel::priority, ast_pbx::rtimeout, ast_channel::uniqueid, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, and ast_channel::whentohangup.
01659 {
01660 int firstpass = 1;
01661 char digit;
01662 char exten[256];
01663 int pos;
01664 int waittime;
01665 int res=0;
01666
01667 /* A little initial setup here */
01668 if (c->pbx)
01669 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name);
01670 c->pbx = malloc(sizeof(struct ast_pbx));
01671 if (!c->pbx) {
01672 ast_log(LOG_ERROR, "Out of memory\n");
01673 return -1;
01674 }
01675 if (c->amaflags) {
01676 if (c->cdr) {
01677 ast_log(LOG_WARNING, "%s already has a call record??\n", c->name);
01678 } else {
01679 c->cdr = ast_cdr_alloc();
01680 if (!c->cdr) {
01681 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
01682 free(c->pbx);
01683 return -1;
01684 }
01685 ast_cdr_init(c->cdr, c);
01686 }
01687 }
01688 memset(c->pbx, 0, sizeof(struct ast_pbx));
01689 /* Set reasonable defaults */
01690 c->pbx->rtimeout = 10;
01691 c->pbx->dtimeout = 5;
01692
01693 /* Start by trying whatever the channel is set to */
01694 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->callerid)) {
01695 /* JK02: If not successfull fall back to 's' */
01696 strncpy(c->exten, "s", sizeof(c->exten)-1);
01697 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->callerid)) {
01698 /* JK02: And finally back to default if everything else failed */
01699 strncpy(c->context, "default", sizeof(c->context)-1);
01700 }
01701 c->priority = 1;
01702 }
01703 if (c->cdr)
01704 ast_cdr_start(c->cdr);
01705 for(;;) {
01706 pos = 0;
01707 digit = 0;
01708 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->callerid)) {
01709 memset(exten, 0, sizeof(exten));
01710 manager_event(EVENT_FLAG_CALL, "Newexten",
01711 "Channel: %s\r\n"
01712 "Context: %s\r\n"
01713 "Extension: %s\r\n"
01714 "Priority: %d\r\n"
01715 "Uniqueid: %s\r\n",
01716 c->name, c->context, c->exten, c->priority, c->uniqueid);
01717 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->callerid))) {
01718 /* Something bad happened, or a hangup has been requested. */
01719 if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) ||
01720 (res == '*') || (res == '#')) {
01721 ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res);
01722 memset(exten, 0, sizeof(exten));
01723 pos = 0;
01724 exten[pos++] = digit = res;
01725 break;
01726 }
01727 switch(res) {
01728 case AST_PBX_KEEPALIVE:
01729 if (option_debug)
01730 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
01731 else if (option_verbose > 1)
01732 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
01733 goto out;
01734 break;
01735 default:
01736 if (option_debug)
01737 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
01738 else if (option_verbose > 1)
01739 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
01740 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
01741 c->_softhangup =0;
01742 break;
01743 }
01744 /* atimeout */
01745 if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
01746 break;
01747 }
01748
01749 if (c->cdr) {
01750 ast_cdr_update(c);
01751 }
01752 goto out;
01753 }
01754 }
01755 if ((c->_softhangup == AST_SOFTHANGUP_TIMEOUT) && (ast_exists_extension(c,c->context,"T",1,c->callerid))) {
01756 strncpy(c->exten,"T",sizeof(c->exten) - 1);
01757 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
01758 c->whentohangup = 0;
01759 c->priority = 0;
01760 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
01761 } else if (c->_softhangup) {
01762 ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n",
01763 c->exten, c->priority);
01764 goto out;
01765 }
01766 firstpass = 0;
01767 c->priority++;
01768 }
01769 if (!ast_exists_extension(c, c->context, c->exten, 1, c->callerid)) {
01770 /* It's not a valid extension anymore */
01771 if (ast_exists_extension(c, c->context, "i", 1, c->callerid)) {
01772 if (option_verbose > 2)
01773 ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name);
01774 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten);
01775 strncpy(c->exten, "i", sizeof(c->exten)-1);
01776 c->priority = 1;
01777 } else {
01778 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n",
01779 c->name, c->exten, c->context);
01780 goto out;
01781 }
01782 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
01783 /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */
01784 c->_softhangup = 0;
01785 } else {
01786 /* Done, wait for an extension */
01787 if (digit)
01788 waittime = c->pbx->dtimeout;
01789 else
01790 waittime = c->pbx->rtimeout;
01791 while (ast_matchmore_extension(c, c->context, exten, 1, c->callerid)) {
01792 /* As long as we're willing to wait, and as long as it's not defined,
01793 keep reading digits until we can't possibly get a right answer anymore. */
01794 digit = ast_waitfordigit(c, waittime * 1000);
01795 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
01796 c->_softhangup = 0;
01797 } else {
01798 if (!digit)
01799 /* No entry */
01800 break;
01801 if (digit < 0)
01802 /* Error, maybe a hangup */
01803 goto out;
01804 exten[pos++] = digit;
01805 waittime = c->pbx->dtimeout;
01806 }
01807 }
01808 if (ast_exists_extension(c, c->context, exten, 1, c->callerid)) {
01809 /* Prepare the next cycle */
01810 strncpy(c->exten, exten, sizeof(c->exten)-1);
01811 c->priority = 1;
01812 } else {
01813 /* No such extension */
01814 if (strlen(exten)) {
01815 /* An invalid extension */
01816 if (ast_exists_extension(c, c->context, "i", 1, c->callerid)) {
01817 if (option_verbose > 2)
01818 ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", exten, c->context, c->name);
01819 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", exten);
01820 strncpy(c->exten, "i", sizeof(c->exten)-1);
01821 c->priority = 1;
01822 } else {
01823 ast_log(LOG_WARNING, "Invalid extension, but no rule 'i' in context '%s'\n", c->context);
01824 goto out;
01825 }
01826 } else {
01827 /* A simple timeout */
01828 if (ast_exists_extension(c, c->context, "t", 1, c->callerid)) {
01829 if (option_verbose > 2)
01830 ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name);
01831 strncpy(c->exten, "t", sizeof(c->exten)-1);
01832 c->priority = 1;
01833 } else {
01834 ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context);
01835 goto out;
01836 }
01837 }
01838 }
01839 if (c->cdr) {
01840 if (option_verbose > 2)
01841 ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name);
01842 ast_cdr_update(c);
01843 }
01844 }
01845 }
01846 if (firstpass)
01847 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
01848 out:
01849 if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->callerid)) {
01850 strcpy(c->exten, "h");
01851 c->priority = 1;
01852 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->callerid)) {
01853 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->callerid))) {
01854 /* Something bad happened, or a hangup has been requested. */
01855 if (option_debug)
01856 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
01857 else if (option_verbose > 1)
01858 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
01859 break;
01860 }
01861 c->priority++;
01862 }
01863 }
01864
01865 pbx_destroy(c->pbx);
01866 c->pbx = NULL;
01867 if (res != AST_PBX_KEEPALIVE)
01868 ast_hangup(c);
01869 return 0;
01870 }
|
|
|
Create a new thread and start the PBX (or whatever).
Definition at line 1885 of file pbx.c. References ast_log(), and LOG_WARNING.
01886 {
01887 pthread_t t;
01888 pthread_attr_t attr;
01889 if (!c) {
01890 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
01891 return -1;
01892 }
01893
01894 /* Start a new thread, and get something handling this channel. */
01895 pthread_attr_init(&attr);
01896 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
01897 if (pthread_create(&t, &attr, pbx_thread, c)) {
01898 ast_log(LOG_WARNING, "Failed to create new channel thread\n");
01899 return -1;
01900 }
01901 return 0;
01902 }
|
|
||||||||||||||||||||
|
Add an application. The function 'execute' should return non-zero if the line needs to be hung up.
Definition at line 2193 of file pbx.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), COLOR_BRCYAN, description(), LOG_ERROR, LOG_WARNING, malloc, ast_app::next, option_verbose, term_color(), and VERBOSE_PREFIX_2.
02194 {
02195 struct ast_app *tmp, *prev, *cur;
02196 char tmps[80];
02197 if (ast_mutex_lock(&applock)) {
02198 ast_log(LOG_ERROR, "Unable to lock application list\n");
02199 return -1;
02200 }
02201 tmp = apps;
02202 while(tmp) {
02203 if (!strcasecmp(app, tmp->name)) {
02204 ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
02205 ast_mutex_unlock(&applock);
02206 return -1;
02207 }
02208 tmp = tmp->next;
02209 }
02210 tmp = malloc(sizeof(struct ast_app));
02211 if (tmp) {
02212 memset(tmp, 0, sizeof(struct ast_app));
02213 strncpy(tmp->name, app, sizeof(tmp->name)-1);
02214 tmp->execute = execute;
02215 tmp->synopsis = synopsis;
02216 tmp->description = description;
02217 /* Store in alphabetical order */
02218 cur = apps;
02219 prev = NULL;
02220 while(cur) {
02221 if (strcasecmp(tmp->name, cur->name) < 0)
02222 break;
02223 prev = cur;
02224 cur = cur->next;
02225 }
02226 if (prev) {
02227 tmp->next = prev->next;
02228 prev->next = tmp;
02229 } else {
02230 tmp->next = apps;
02231 apps = tmp;
02232 }
02233 } else {
02234 ast_log(LOG_ERROR, "Out of memory\n");
02235 ast_mutex_unlock(&applock);
02236 return -1;
02237 }
02238 if (option_verbose > 1)
02239 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
02240 ast_mutex_unlock(&applock);
02241 return 0;
02242 }
|
|
|
Register an alternative switch.
Definition at line 2244 of file pbx.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, LOG_ERROR, LOG_WARNING, ast_switch::name, ast_switch::next, and switches.
02245 {
02246 struct ast_switch *tmp, *prev=NULL;
02247 if (ast_mutex_lock(&switchlock)) {
02248 ast_log(LOG_ERROR, "Unable to lock switch lock\n");
02249 return -1;
02250 }
02251 tmp = switches;
02252 while(tmp) {
02253 if (!strcasecmp(tmp->name, sw->name))
02254 break;
02255 prev = tmp;
02256 tmp = tmp->next;
02257 }
02258 if (tmp) {
02259 ast_mutex_unlock(&switchlock);
02260 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
02261 return -1;
02262 }
02263 sw->next = NULL;
02264 if (prev)
02265 prev->next = sw;
02266 else
02267 switches = sw;
02268 ast_mutex_unlock(&switchlock);
02269 return 0;
02270 }
|
|
||||||||||||||||||||||||
|
Launch a new extension (i.e. new stack).
Definition at line 1653 of file pbx.c. References HELPER_SPAWN. Referenced by ast_pbx_run().
01654 {
01655 return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_SPAWN);
01656 }
|
|
|
Unlocks the given context.
Definition at line 4594 of file pbx.c.
04595 {
04596 return ast_mutex_unlock(&con->lock);
04597 }
|
|
|
Unlocks contexts. Returns 0 on success, -1 on failure Definition at line 4581 of file pbx.c. Referenced by ast_context_remove_extension(), ast_context_remove_include(), ast_context_remove_switch(), and ast_ignore_pattern().
04582 {
04583 return ast_mutex_unlock(&conlock);
04584 }
|
|
|
Remove an application.
Definition at line 2753 of file pbx.c.
02753 {
02754 struct ast_app *tmp, *tmpl = NULL;
02755 if (ast_mutex_lock(&applock)) {
02756 ast_log(LOG_ERROR, "Unable to lock application list\n");
02757 return -1;
02758 }
02759 tmp = apps;
02760 while(tmp) {
02761 if (!strcasecmp(app, tmp->name)) {
02762 if (tmpl)
02763 tmpl->next = tmp->next;
02764 else
02765 apps = tmp->next;
02766 if (option_verbose > 1)
02767 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
02768 ast_mutex_unlock(&applock);
02769 return 0;
02770 }
02771 tmpl = tmp;
02772 tmp = tmp->next;
02773 }
02774 ast_mutex_unlock(&applock);
02775 return -1;
02776 }
|
|
|
Unregister an alternative switch.
Definition at line 2272 of file pbx.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, LOG_ERROR, ast_switch::next, and switches.
02273 {
02274 struct ast_switch *tmp, *prev=NULL;
02275 if (ast_mutex_lock(&switchlock)) {
02276 ast_log(LOG_ERROR, "Unable to lock switch lock\n");
02277 return;
02278 }
02279 tmp = switches;
02280 while(tmp) {
02281 if (tmp == sw) {
02282 if (prev)
02283 prev->next = tmp->next;
02284 else
02285 switches = tmp->next;
02286 tmp->next = NULL;
02287 break;
02288 }
02289 prev = tmp;
02290 tmp = tmp->next;
02291 }
02292 ast_mutex_unlock(&switchlock);
02293 }
|
|
||||||||||||
|
Definition at line 4686 of file pbx.c.
|
|
||||||||||||
|
Definition at line 4722 of file pbx.c.
04724 {
04725 if (!ip)
04726 return con ? con->ignorepats : NULL;
04727 else
04728 return ip->next;
04729 }
|
|
||||||||||||
|
Definition at line 4713 of file pbx.c.
|
|
||||||||||||
|
Definition at line 4695 of file pbx.c.
|
|
|
Definition at line 4678 of file pbx.c. References ast_context::alts, and ast_sw::next. Referenced by ast_context_remove_extension(), ast_context_remove_include(), ast_context_remove_switch(), and ast_ignore_pattern().
04679 {
04680 if (!con)
04681 return contexts;
04682 else
04683 return con->next;
04684 }
|
|
||||||||||||
|
Definition at line 4704 of file pbx.c.
04706 {
04707 if (!priority)
04708 return exten;
04709 else
04710 return priority->peer;
04711 }
|
|
|
Definition at line 4474 of file pbx.c.
04475 {
04476 struct ast_var_t *vardata;
04477 while (!AST_LIST_EMPTY(&globals)) {
04478 vardata = AST_LIST_FIRST(&globals);
04479 AST_LIST_REMOVE_HEAD(&globals, entries);
04480 ast_var_delete(vardata);
04481 }
04482 }
|
|
||||||||||||
|
|
|
||||||||||||
|
Referenced by __ast_request_and_dial(). |
|
||||||||||||||||
|
Referenced by ast_pbx_run(). |
|
||||||||||||||||||||
|
executes an application
Definition at line 362 of file pbx.c. References ast_channel::app, ast_channel::appl, ast_cdr_setapp(), AST_CHANNEL_MAX_STACK, ast_log(), ast_channel::cdr, ast_channel::data, ast_app::execute, ast_channel::jmp, LOG_WARNING, ast_app::name, and ast_channel::stack.
00366 {
00367 /* This function is special. It saves the stack so that no matter
00368 how many times it is called, it returns to the same place */
00369 int res;
00370 int stack = c->stack;
00371 int (*execute)(struct ast_channel *chan, void *data) = app->execute;
00372 if (newstack && stack > AST_CHANNEL_MAX_STACK - 2) {
00373 /* Don't allow us to go over the max number of stacks we
00374 permit saving. */
00375 ast_log(LOG_WARNING, "Stack overflow, cannot create another stack\n");
00376 return -1;
00377 }
00378 if (newstack && (res = setjmp(c->jmp[++c->stack]))) {
00379 /* Okay, here's where it gets weird. If newstack is non-zero,
00380 then we increase the stack increment, but setjmp is not going
00381 to return until longjmp is called -- when the application
00382 exec'd is finished running. */
00383 if (res == 1)
00384 res = 0;
00385 if (c->stack != stack + 1)
00386 ast_log(LOG_WARNING, "Stack returned to an unexpected place!\n");
00387 else if (c->app[c->stack])
00388 ast_log(LOG_WARNING, "Application may have forgotten to free its memory\n");
00389 c->stack = stack;
00390 return res;
00391 } else {
00392 if (c->cdr)
00393 ast_cdr_setapp(c->cdr, app->name, data);
00394 c->appl = app->name;
00395 c->data = data;
00396 res = execute(c, data);
00397 c->appl = NULL;
00398 c->data = NULL;
00399 /* Any application that returns, we longjmp back, just in case. */
00400 if (c->stack != stack + 1)
00401 ast_log(LOG_WARNING, "Stack is not at expected value\n");
00402 longjmp(c->jmp[stack+1], res);
00403 /* Never returns */
00404 }
00405 }
|
|
|
Look up an application.
Definition at line 417 of file pbx.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, LOG_WARNING, and ast_app::next.
00418 {
00419 struct ast_app *tmp;
00420 if (ast_mutex_lock(&applock)) {
00421 ast_log(LOG_WARNING, "Unable to obtain application lock\n");
00422 return NULL;
00423 }
00424 tmp = apps;
00425 while(tmp) {
00426 if (!strcasecmp(tmp->name, app))
00427 break;
00428 tmp = tmp->next;
00429 }
00430 ast_mutex_unlock(&applock);
00431 return tmp;
00432 }
|
|
||||||||||||||||||||
|
Definition at line 943 of file pbx.c. References ast_expr(), ast_log(), free, LOG_DEBUG, and LOG_NOTICE.
00944 {
00945 char *cp4;
00946 const char *tmp, *whereweare;
00947 int length;
00948 char workspace[256];
00949 char ltmp[256], var[256];
00950 char *nextvar, *nextexp;
00951 char *vars, *vare;
00952 int pos, brackets, needsub, len;
00953
00954 /* Substitutes variables into cp2, based on string cp1, and assuming cp2 to be
00955 zero-filled */
00956 whereweare=tmp=cp1;
00957 while(strlen(whereweare) && count) {
00958 /* Assume we're copying the whole remaining string */
00959 pos = strlen(whereweare);
00960
00961 /* Look for a variable */
00962 nextvar = strstr(whereweare, "${");
00963
00964 nextexp = strstr(whereweare, "$[");
00965
00966 if (nextvar && nextexp) {
00967 if (nextvar < nextexp)
00968 nextexp = NULL;
00969 else
00970 nextvar = NULL;
00971 }
00972
00973 /* If there is one, we only go that far */
00974 if (nextvar)
00975 pos = nextvar - whereweare;
00976 else if (nextexp)
00977 pos = nextexp - whereweare;
00978
00979 /* Can't copy more than 'count' bytes */
00980 if (pos > count)
00981 pos = count;
00982
00983 /* Copy that many bytes */
00984 memcpy(cp2, whereweare, pos);
00985
00986 count -= pos;
00987 cp2 += pos;
00988 whereweare += pos;
00989
00990 if (nextvar) {
00991 /* We have a variable. Find the start and end, and determine
00992 if we are going to have to recursively call ourselves on the
00993 contents */
00994 vars = vare = nextvar + 2;
00995 brackets = 1;
00996 needsub = 0;
00997
00998 /* Find the end of it */
00999 while(brackets && *vare) {
01000 if ((vare[0] == '$') && (vare[1] == '{')) {
01001 needsub++;
01002 brackets++;
01003 } else if (vare[0] == '}') {
01004 brackets--;
01005 } else if ((vare[0] == '$') && (vare[1] == '['))
01006 needsub++;
01007 vare++;
01008 }
01009 if (brackets)
01010 ast_log(LOG_NOTICE, "Error in extension logic (missing '}')\n");
01011 len = vare - vars - 1;
01012
01013 /* Skip totally over variable name */
01014 whereweare += ( len + 3);
01015
01016 /* Store variable name (and truncate) */
01017 memset(var, 0, sizeof(var));
01018 strncpy(var, vars, sizeof(var) - 1);
01019 var[len] = '\0';
01020
01021 /* Substitute if necessary */
01022 if (needsub) {
01023 memset(ltmp, 0, sizeof(ltmp));
01024 pbx_substitute_variables_helper(c, var, ltmp, sizeof(ltmp) - 1);
01025 vars = ltmp;
01026 } else {
01027 vars = var;
01028 }
01029
01030 /* Retrieve variable value */
01031 strcpy(workspace, "");
01032 pbx_substitute_variables_temp(c,vars,&cp4, workspace, sizeof(workspace));
01033 if (cp4) {
01034 length = strlen(cp4);
01035 if (length > count)
01036 length = count;
01037 memcpy(cp2, cp4, length);
01038 count -= length;
01039 cp2 += length;
01040 }
01041
01042 } else if (nextexp) {
01043 /* We have an expression. Find the start and end, and determine
01044 if we are going to have to recursively call ourselves on the
01045 contents */
01046 vars = vare = nextexp + 2;
01047 brackets = 1;
01048 needsub = 0;
01049
01050 /* Find the end of it */
01051 while(brackets && *vare) {
01052 if ((vare[0] == '$') && (vare[1] == '[')) {
01053 needsub++;
01054 brackets++;
01055 } else if (vare[0] == ']') {
01056 brackets--;
01057 } else if ((vare[0] == '$') && (vare[1] == '{'))
01058 needsub++;
01059 vare++;
01060 }
01061 if (brackets)
01062 ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n");
01063 len = vare - vars - 1;
01064
01065 /* Skip totally over variable name */
01066 whereweare += ( len + 3);
01067
01068 /* Store variable name (and truncate) */
01069 memset(var, 0, sizeof(var));
01070 strncpy(var, vars, sizeof(var) - 1);
01071 var[len] = '\0';
01072
01073 /* Substitute if necessary */
01074 if (needsub) {
01075 memset(ltmp, 0, sizeof(ltmp));
01076 pbx_substitute_variables_helper(c, var, ltmp, sizeof(ltmp) - 1);
01077 vars = ltmp;
01078 } else {
01079 vars = var;
01080 }
01081
01082 /* Evaluate expression */
01083 cp4 = ast_expr(vars);
01084
01085 ast_log(LOG_DEBUG, "Expression is '%s'\n", cp4);
01086
01087 if (cp4) {
01088 length = strlen(cp4);
01089 if (length > count)
01090 length = count;
01091 memcpy(cp2, cp4, length);
01092 count -= length;
01093 cp2 += length;
01094 free(cp4);
01095 }
01096
01097 } else
01098 break;
01099 }
01100 }
|
1.3.5