#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 } |