#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_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) |
| 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 * | 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) |
| void | pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count) |
|
|
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_add_extension2(), and 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 3390 of file pbx.c. References ast_add_extension2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
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(context, ast_get_context_name(c))) {
03403 int ret = ast_add_extension2(c, replace, extension, priority, callerid,
03404 application, data, datad, registrar);
03405 ast_unlock_contexts();
03406 return ret;
03407 }
03408 c = ast_walk_contexts(c);
03409 }
03410
03411 ast_unlock_contexts();
03412 errno = ENOENT;
03413 return -1;
03414 }
|
|
||||||||||||||||||||||||||||||||||||||||
|
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 3522 of file pbx.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, free, ast_context::lock, LOG_WARNING, malloc, ast_context::name, ast_exten::next, ast_exten::peer, PRIORITY_HINT, ast_context::registrar, and ast_context::root. Referenced by ast_add_extension().
03526 {
03527
03528 #define LOG do { if (option_debug) {\
03529 if (tmp->matchcid) { \
03530 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \
03531 } else { \
03532 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \
03533 } \
03534 } else if (option_verbose > 2) { \
03535 if (tmp->matchcid) { \
03536 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \
03537 } else { \
03538 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \
03539 } \
03540 } } while(0)
03541
03542 /*
03543 * This is a fairly complex routine. Different extensions are kept
03544 * in order by the extension number. Then, extensions of different
03545 * priorities (same extension) are kept in a list, according to the
03546 * peer pointer.
03547 */
03548 struct ast_exten *tmp, *e, *el = NULL, *ep = NULL;
03549 int res;
03550 /* Be optimistic: Build the extension structure first */
03551 tmp = malloc(sizeof(struct ast_exten));
03552 if (tmp) {
03553 memset(tmp, 0, sizeof(struct ast_exten));
03554 ext_strncpy(tmp->exten, extension, sizeof(tmp->exten));
03555 tmp->priority = priority;
03556 if (callerid) {
03557 ext_strncpy(tmp->cidmatch, callerid, sizeof(tmp->cidmatch));
03558 tmp->matchcid = 1;
03559 } else {
03560 strcpy(tmp->cidmatch, "");
03561 tmp->matchcid = 0;
03562 }
03563 strncpy(tmp->app, application, sizeof(tmp->app)-1);
03564 tmp->parent = con;
03565 tmp->data = data;
03566 tmp->datad = datad;
03567 tmp->registrar = registrar;
03568 tmp->peer = NULL;
03569 tmp->next = NULL;
03570 } else {
03571 ast_log(LOG_WARNING, "Out of memory\n");
03572 errno = ENOMEM;
03573 return -1;
03574 }
03575 if (ast_mutex_lock(&con->lock)) {
03576 free(tmp);
03577 /* And properly destroy the data */
03578 datad(data);
03579 ast_log(LOG_WARNING, "Failed to lock context '%s'\n", con->name);
03580 errno = EBUSY;
03581 return -1;
03582 }
03583 e = con->root;
03584 while(e) {
03585 res= strcasecmp(e->exten, extension);
03586 if (!res) {
03587 if (!e->matchcid && !tmp->matchcid)
03588 res = 0;
03589 else if (tmp->matchcid && !e->matchcid)
03590 res = 1;
03591 else if (e->matchcid && !tmp->matchcid)
03592 res = -1;
03593 else
03594 res = strcasecmp(e->cidmatch, tmp->cidmatch);
03595 }
03596 if (res == 0) {
03597 /* We have an exact match, now we find where we are
03598 and be sure there's no duplicates */
03599 while(e) {
03600 if (e->priority == tmp->priority) {
03601 /* Can't have something exactly the same. Is this a
03602 replacement? If so, replace, otherwise, bonk. */
03603 if (replace) {
03604 if (ep) {
03605 /* We're in the peer list, insert ourselves */
03606 ep->peer = tmp;
03607 tmp->peer = e->peer;
03608 } else if (el) {
03609 /* We're the first extension. Take over e's functions */
03610 el->next = tmp;
03611 tmp->next = e->next;
03612 tmp->peer = e->peer;
03613 } else {
03614 /* We're the very first extension. */
03615 con->root = tmp;
03616 tmp->next = e->next;
03617 tmp->peer = e->peer;
03618 }
03619 if (tmp->priority == PRIORITY_HINT)
03620 ast_change_hint(e,tmp);
03621 /* Destroy the old one */
03622 e->datad(e->data);
03623 free(e);
03624 ast_mutex_unlock(&con->lock);
03625 if (tmp->priority == PRIORITY_HINT)
03626 ast_change_hint(e, tmp);
03627 /* And immediately return success. */
03628 LOG;
03629 return 0;
03630 } else {
03631 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name);
03632 tmp->datad(tmp->data);
03633 free(tmp);
03634 ast_mutex_unlock(&con->lock);
03635 errno = EEXIST;
03636 return -1;
03637 }
03638 } else if (e->priority > tmp->priority) {
03639 /* Slip ourselves in just before e */
03640 if (ep) {
03641 /* Easy enough, we're just in the peer list */
03642 ep->peer = tmp;
03643 tmp->peer = e;
03644 } else if (el) {
03645 /* We're the first extension in this peer list */
03646 el->next = tmp;
03647 tmp->next = e->next;
03648 e->next = NULL;
03649 tmp->peer = e;
03650 } else {
03651 /* We're the very first extension altogether */
03652 tmp->next = con->root;
03653 /* Con->root must always exist or we couldn't get here */
03654 tmp->peer = con->root->peer;
03655 con->root = tmp;
03656 }
03657 ast_mutex_unlock(&con->lock);
03658 /* And immediately return success. */
03659 if (tmp->priority == PRIORITY_HINT)
03660 ast_add_hint(tmp);
03661
03662 LOG;
03663 return 0;
03664 }
03665 ep = e;
03666 e = e->peer;
03667 }
03668 /* If we make it here, then it's time for us to go at the very end.
03669 ep *must* be defined or we couldn't have gotten here. */
03670 ep->peer = tmp;
03671 ast_mutex_unlock(&con->lock);
03672 if (tmp->priority == PRIORITY_HINT)
03673 ast_add_hint(tmp);
03674
03675 /* And immediately return success. */
03676 LOG;
03677 return 0;
03678
03679 } else if (res > 0) {
03680 /* Insert ourselves just before 'e'. We're the first extension of
03681 this kind */
03682 tmp->next = e;
03683 if (el) {
03684 /* We're in the list somewhere */
03685 el->next = tmp;
03686 } else {
03687 /* We're at the top of the list */
03688 con->root = tmp;
03689 }
03690 ast_mutex_unlock(&con->lock);
03691 if (tmp->priority == PRIORITY_HINT)
03692 ast_add_hint(tmp);
03693
03694 /* And immediately return success. */
03695 LOG;
03696 return 0;
03697 }
03698
03699 el = e;
03700 e = e->next;
03701 }
03702 /* If we fall all the way through to here, then we need to be on the end. */
03703 if (el)
03704 el->next = tmp;
03705 else
03706 con->root = tmp;
03707 ast_mutex_unlock(&con->lock);
03708 if (tmp->priority == PRIORITY_HINT)
03709 ast_add_hint(tmp);
03710 LOG;
03711 return 0;
03712 }
|
|
||||||||||||||||||||||||
|
Definition at line 3416 of file pbx.c. References ast_channel::_state, ast_channel_alloc(), ast_channel_masquerade(), ast_frfree(), ast_hangup(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pbx_start(), ast_read(), ast_setstate(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_channel::context, ast_channel::exten, ast_channel::lock, LOG_WARNING, ast_channel::name, ast_channel::pbx, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat. Referenced by ast_async_goto_by_name().
03417 {
03418 int res = 0;
03419 if (needlock)
03420 ast_mutex_lock(&chan->lock);
03421 if (chan->pbx) {
03422 /* This channel is currently in the PBX */
03423 if (context && strlen(context))
03424 strncpy(chan->context, context, sizeof(chan->context) - 1);
03425 if (exten && strlen(exten))
03426 strncpy(chan->exten, exten, sizeof(chan->context) - 1);
03427 if (priority)
03428 chan->priority = priority - 1;
03429 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
03430 if (needlock)
03431 ast_mutex_unlock(&chan->lock);
03432 } else {
03433 /* In order to do it when the channel doesn't really exist within
03434 the PBX, we have to make a new channel, masquerade, and start the PBX
03435 at the new location */
03436 struct ast_channel *tmpchan;
03437 struct ast_frame *f;
03438 tmpchan = ast_channel_alloc(0);
03439 if (tmpchan) {
03440 snprintf(tmpchan->name, sizeof(tmpchan->name), "AsyncGoto/%s", chan->name);
03441 ast_setstate(tmpchan, chan->_state);
03442 /* Make formats okay */
03443 tmpchan->readformat = chan->readformat;
03444 tmpchan->writeformat = chan->writeformat;
03445 /* Setup proper location */
03446 if (context && strlen(context))
03447 strncpy(tmpchan->context, context, sizeof(tmpchan->context) - 1);
03448 else
03449 strncpy(tmpchan->context, chan->context, sizeof(tmpchan->context) - 1);
03450 if (exten && strlen(exten))
03451 strncpy(tmpchan->exten, exten, sizeof(tmpchan->exten) - 1);
03452 else
03453 strncpy(tmpchan->exten, chan->exten, sizeof(tmpchan->exten) - 1);
03454 if (priority)
03455 tmpchan->priority = priority;
03456 else
03457 tmpchan->priority = chan->priority;
03458 if (needlock)
03459 ast_mutex_unlock(&chan->lock);
03460
03461 /* Masquerade into temp channel */
03462 ast_channel_masquerade(tmpchan, chan);
03463
03464 /* Make the masquerade happen by reading a frame from the tmp channel */
03465 f = ast_read(tmpchan);
03466 if (f)
03467 ast_frfree(f);
03468 /* Start the PBX going on our stolen channel */
03469 if (ast_pbx_start(tmpchan)) {
03470 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
03471 ast_hangup(tmpchan);
03472 res = -1;
03473 }
03474 } else {
03475 res = -1;
03476 if (needlock)
03477 ast_mutex_unlock(&chan->lock);
03478 }
03479 }
03480 return res;
03481 }
|
|
||||||||||||||||||||
|
Definition at line 3483 of file pbx.c. References ast_async_goto(), ast_channel_walk(), and ast_channel::name.
03484 {
03485 struct ast_channel *chan;
03486 chan = ast_channel_walk(NULL);
03487 while(chan) {
03488 if (!strcasecmp(channame, chan->name))
03489 break;
03490 chan = ast_channel_walk(chan);
03491 }
03492 if (chan)
03493 return ast_async_goto(chan, context, exten, priority, 1);
03494 return -1;
03495 }
|
|
||||||||||||||||||||||||
|
Looks for a valid matching extension.
Definition at line 1622 of file pbx.c. References HELPER_CANMATCH.
01623 {
01624 return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_CANMATCH);
01625 }
|
|
||||||||||||||||
|
Add an ignorepat.
Definition at line 3311 of file pbx.c. References ast_context_add_ignorepat2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
03312 {
03313 struct ast_context *c;
03314
03315 if (ast_lock_contexts()) {
03316 errno = EBUSY;
03317 return -1;
03318 }
03319
03320 c = ast_walk_contexts(NULL);
03321 while (c) {
03322 if (!strcmp(ast_get_context_name(c), con)) {
03323 int ret = ast_context_add_ignorepat2(c, value, registrar);
03324 ast_unlock_contexts();
03325 return ret;
03326 }
03327 c = ast_walk_contexts(c);
03328 }
03329
03330 ast_unlock_contexts();
03331 errno = ENOENT;
03332 return -1;
03333 }
|
|
||||||||||||||||
|
Definition at line 3335 of file pbx.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_context::ignorepats, ast_context::lock, LOG_WARNING, and malloc. Referenced by ast_context_add_ignorepat().
03336 {
03337 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
03338 ignorepat = malloc(sizeof(struct ast_ignorepat));
03339 if (!ignorepat) {
03340 ast_log(LOG_WARNING, "Out of memory\n");
03341 errno = ENOMEM;
03342 return -1;
03343 }
03344 memset(ignorepat, 0, sizeof(struct ast_ignorepat));
03345 strncpy(ignorepat->pattern, value, sizeof(ignorepat->pattern)-1);
03346 ignorepat->next = NULL;
03347 ignorepat->registrar = registrar;
03348 ast_mutex_lock(&con->lock);
03349 ignorepatc = con->ignorepats;
03350 while(ignorepatc) {
03351 ignorepatl = ignorepatc;
03352 if (!strcasecmp(ignorepatc->pattern, value)) {
03353 /* Already there */
03354 ast_mutex_unlock(&con->lock);
03355 errno = EEXIST;
03356 return -1;
03357 }
03358 ignorepatc = ignorepatc->next;
03359 }
03360 if (ignorepatl)
03361 ignorepatl->next = ignorepat;
03362 else
03363 con->ignorepats = ignorepat;
03364 ast_mutex_unlock(&con->lock);
03365 return 0;
03366
03367 }
|
|
||||||||||||||||
|
Add an include.
Definition at line 2801 of file pbx.c. References ast_context_add_include2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
02802 {
02803 struct ast_context *c;
02804
02805 if (ast_lock_contexts()) {
02806 errno = EBUSY;
02807 return -1;
02808 }
02809
02810 /* walk contexts ... */
02811 c = ast_walk_contexts(NULL);
02812 while (c) {
02813 /* ... search for the right one ... */
02814 if (!strcmp(ast_get_context_name(c), context)) {
02815 int ret = ast_context_add_include2(c, include, registrar);
02816 /* ... unlock contexts list and return */
02817 ast_unlock_contexts();
02818 return ret;
02819 }
02820 c = ast_walk_contexts(c);
02821 }
02822
02823 /* we can't find the right context */
02824 ast_unlock_contexts();
02825 errno = ENOENT;
02826 return -1;
02827 }
|
|
||||||||||||||||
|
Add an include.
Definition at line 3092 of file pbx.c. References ast_get_context_name(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), free, ast_context::includes, ast_context::lock, LOG_WARNING, malloc, option_verbose, and VERBOSE_PREFIX_3. Referenced by ast_context_add_include().
03094 {
03095 struct ast_include *new_include;
03096 char *c;
03097 struct ast_include *i, *il = NULL; /* include, include_last */
03098
03099 /* allocate new include structure ... */
03100 if (!(new_include = malloc(sizeof(struct ast_include)))) {
03101 ast_log(LOG_WARNING, "Out of memory\n");
03102 errno = ENOMEM;
03103 return -1;
03104 }
03105
03106 /* ... fill in this structure ... */
03107 memset(new_include, 0, sizeof(struct ast_include));
03108 strncpy(new_include->name, value, sizeof(new_include->name)-1);
03109 strncpy(new_include->rname, value, sizeof(new_include->rname)-1);
03110 c = new_include->rname;
03111 /* Strip off timing info */
03112 while(*c && (*c != '|')) c++;
03113 /* Process if it's there */
03114 if (*c) {
03115 build_timing(new_include, c+1);
03116 *c = '\0';
03117 }
03118 new_include->next = NULL;
03119 new_include->registrar = registrar;
03120
03121 /* ... try to lock this context ... */
03122 if (ast_mutex_lock(&con->lock)) {
03123 free(new_include);
03124 errno = EBUSY;
03125 return -1;
03126 }
03127
03128 /* ... go to last include and check if context is already included too... */
03129 i = con->includes;
03130 while (i) {
03131 if (!strcasecmp(i->name, new_include->name)) {
03132 free(new_include);
03133 ast_mutex_unlock(&con->lock);
03134 errno = EEXIST;
03135 return -1;
03136 }
03137 il = i;
03138 i = i->next;
03139 }
03140
03141 /* ... include new context into context list, unlock, return */
03142 if (il)
03143 il->next = new_include;
03144 else
03145 con->includes = new_include;
03146 if (option_verbose > 2)
03147 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
03148 ast_mutex_unlock(&con->lock);
03149
03150 return 0;
03151 }
|
|
||||||||||||||||||||
|
Add a switch.
Definition at line 3158 of file pbx.c. References ast_context_add_switch2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
03159 {
03160 struct ast_context *c;
03161
03162 if (ast_lock_contexts()) {
03163 errno = EBUSY;
03164 return -1;
03165 }
03166
03167 /* walk contexts ... */
03168 c = ast_walk_contexts(NULL);
03169 while (c) {
03170 /* ... search for the right one ... */
03171 if (!strcmp(ast_get_context_name(c), context)) {
03172 int ret = ast_context_add_switch2(c, sw, data, registrar);
03173 /* ... unlock contexts list and return */
03174 ast_unlock_contexts();
03175 return ret;
03176 }
03177 c = ast_walk_contexts(c);
03178 }
03179
03180 /* we can't find the right context */
03181 ast_unlock_contexts();
03182 errno = ENOENT;
03183 return -1;
03184 }
|
|
||||||||||||||||||||
|
Adds a switch (first param is a ast_context). Definition at line 3193 of file pbx.c. References ast_context::alts, ast_get_context_name(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), free, ast_context::lock, LOG_WARNING, malloc, option_verbose, and VERBOSE_PREFIX_3. Referenced by ast_context_add_switch().
03195 {
03196 struct ast_sw *new_sw;
03197 struct ast_sw *i, *il = NULL; /* sw, sw_last */
03198
03199 /* allocate new sw structure ... */
03200 if (!(new_sw = malloc(sizeof(struct ast_sw)))) {
03201 ast_log(LOG_WARNING, "Out of memory\n");
03202 errno = ENOMEM;
03203 return -1;
03204 }
03205
03206 /* ... fill in this structure ... */
03207 memset(new_sw, 0, sizeof(struct ast_sw));
03208 strncpy(new_sw->name, value, sizeof(new_sw->name)-1);
03209 if (data)
03210 strncpy(new_sw->data, data, sizeof(new_sw->data)-1);
03211 else
03212 strncpy(new_sw->data, "", sizeof(new_sw->data)-1);
03213 new_sw->next = NULL;
03214 new_sw->registrar = registrar;
03215
03216 /* ... try to lock this context ... */
03217 if (ast_mutex_lock(&con->lock)) {
03218 free(new_sw);
03219 errno = EBUSY;
03220 return -1;
03221 }
03222
03223 /* ... go to last sw and check if context is already swd too... */
03224 i = con->alts;
03225 while (i) {
03226 if (!strcasecmp(i->name, new_sw->name)) {
03227 free(new_sw);
03228 ast_mutex_unlock(&con->lock);
03229 errno = EEXIST;
03230 return -1;
03231 }
03232 il = i;
03233 i = i->next;
03234 }
03235
03236 /* ... sw new context into context list, unlock, return */
03237 if (il)
03238 il->next = new_sw;
03239 else
03240 con->alts = new_sw;
03241 if (option_verbose > 2)
03242 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
03243 ast_mutex_unlock(&con->lock);
03244
03245 return 0;
03246 }
|
|
||||||||||||||||
|
Register a new context.
Definition at line 2724 of file pbx.c. References ast_log(), ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_verbose(), LOG_DEBUG, LOG_WARNING, malloc, option_debug, option_verbose, and VERBOSE_PREFIX_3.
02725 {
02726 struct ast_context *tmp, **local_contexts;
02727 if (!extcontexts) {
02728 local_contexts = &contexts;
02729 ast_mutex_lock(&conlock);
02730 } else
02731 local_contexts = extcontexts;
02732
02733 tmp = *local_contexts;
02734 while(tmp) {
02735 if (!strcasecmp(tmp->name, name)) {
02736 ast_mutex_unlock(&conlock);
02737 ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name);
02738 if (!extcontexts)
02739 ast_mutex_unlock(&conlock);
02740 return NULL;
02741 }
02742 tmp = tmp->next;
02743 }
02744 tmp = malloc(sizeof(struct ast_context));
02745 if (tmp) {
02746 memset(tmp, 0, sizeof(struct ast_context));
02747 ast_mutex_init(&tmp->lock);
02748 strncpy(tmp->name, name, sizeof(tmp->name)-1);
02749 tmp->root = NULL;
02750 tmp->registrar = registrar;
02751 tmp->next = *local_contexts;
02752 tmp->includes = NULL;
02753 tmp->ignorepats = NULL;
02754 *local_contexts = tmp;
02755 if (option_debug)
02756 ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name);
02757 else if (option_verbose > 2)
02758 ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name);
02759 } else
02760 ast_log(LOG_WARNING, "Out of memory\n");
02761
02762 if (!extcontexts)
02763 ast_mutex_unlock(&conlock);
02764 return tmp;
02765 }
|
|
||||||||||||
|
Destroy a context (matches the specified context (or ANY context if NULL).
Definition at line 4026 of file pbx.c. References __ast_context_destroy().
04027 {
04028 __ast_context_destroy(con,registrar,1);
04029 }
|
|
|
Find a context.
Definition at line 597 of file pbx.c. References ast_mutex_lock, ast_mutex_unlock, and ast_context::next. Referenced by ast_ignore_pattern().
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 2028 of file pbx.c. References ast_context_remove_extension2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
02029 {
02030 struct ast_context *c;
02031
02032 if (ast_lock_contexts()) return -1;
02033
02034 /* walk contexts ... */
02035 c = ast_walk_contexts(NULL);
02036 while (c) {
02037 /* ... search for the right one ... */
02038 if (!strcmp(ast_get_context_name(c), context)) {
02039 /* ... remove extension ... */
02040 int ret = ast_context_remove_extension2(c, extension, priority,
02041 registrar);
02042 /* ... unlock contexts list and return */
02043 ast_unlock_contexts();
02044 return ret;
02045 }
02046 c = ast_walk_contexts(c);
02047 }
02048
02049 /* we can't find the right context */
02050 ast_unlock_contexts();
02051 return -1;
02052 }
|
|
||||||||||||||||||||
|
Definition at line 2064 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().
02065 {
02066 struct ast_exten *exten, *prev_exten = NULL;
02067
02068 if (ast_mutex_lock(&con->lock)) return -1;
02069
02070 /* go through all extensions in context and search the right one ... */
02071 exten = con->root;
02072 while (exten) {
02073
02074 /* look for right extension */
02075 if (!strcmp(exten->exten, extension) &&
02076 (!strcmp(exten->registrar, registrar) || !registrar)) {
02077 struct ast_exten *peer;
02078
02079 /* should we free all peers in this extension? (priority == 0)? */
02080 if (priority == 0) {
02081 /* remove this extension from context list */
02082 if (prev_exten)
02083 prev_exten->next = exten->next;
02084 else
02085 con->root = exten->next;
02086
02087 /* fire out all peers */
02088 peer = exten;
02089 while (peer) {
02090 exten = peer->peer;
02091
02092 if (!peer->priority==PRIORITY_HINT)
02093 ast_remove_hint(peer);
02094
02095 peer->datad(peer->data);
02096 free(peer);
02097
02098 peer = exten;
02099 }
02100
02101 ast_mutex_unlock(&con->lock);
02102 return 0;
02103 } else {
02104 /* remove only extension with exten->priority == priority */
02105 struct ast_exten *previous_peer = NULL;
02106
02107 peer = exten;
02108 while (peer) {
02109 /* is this our extension? */
02110 if (peer->priority == priority &&
02111 (!strcmp(peer->registrar, registrar) || !registrar)) {
02112 /* we are first priority extension? */
02113 if (!previous_peer) {
02114 /* exists previous extension here? */
02115 if (prev_exten) {
02116 /* yes, so we must change next pointer in
02117 * previous connection to next peer
02118 */
02119 if (peer->peer) {
02120 prev_exten->next = peer->peer;
02121 peer->peer->next = exten->next;
02122 } else
02123 prev_exten->next = exten->next;
02124 } else {
02125 /* no previous extension, we are first
02126 * extension, so change con->root ...
02127 */
02128 if (peer->peer)
02129 con->root = peer->peer;
02130 else
02131 con->root = exten->next;
02132 }
02133 } else {
02134 /* we are not first priority in extension */
02135 previous_peer->peer = peer->peer;
02136 }
02137
02138 /* now, free whole priority extension */
02139 if (peer->priority==PRIORITY_HINT)
02140 ast_remove_hint(peer);
02141 peer->datad(peer->data);
02142 free(peer);
02143
02144 ast_mutex_unlock(&con->lock);
02145 return 0;
02146 } else {
02147 /* this is not right extension, skip to next peer */
02148 previous_peer = peer;
02149 peer = peer->peer;
02150 }
02151 }
02152
02153 ast_mutex_unlock(&con->lock);
02154 return -1;
02155 }
02156 }
02157
02158 prev_exten = exten;
02159 exten = exten->next;
02160 }
02161
02162 /* we can't find right extension */
02163 ast_mutex_unlock(&con->lock);
02164 return -1;
02165 }
|
|
||||||||||||||||
|
Definition at line 3252 of file pbx.c. References ast_context_remove_ignorepat2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
03253 {
03254 struct ast_context *c;
03255
03256 if (ast_lock_contexts()) {
03257 errno = EBUSY;
03258 return -1;
03259 }
03260
03261 c = ast_walk_contexts(NULL);
03262 while (c) {
03263 if (!strcmp(ast_get_context_name(c), context)) {
03264 int ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
03265 ast_unlock_contexts();
03266 return ret;
03267 }
03268 c = ast_walk_contexts(c);
03269 }
03270
03271 ast_unlock_contexts();
03272 errno = ENOENT;
03273 return -1;
03274 }
|
|
||||||||||||||||
|
Definition at line 3276 of file pbx.c. References ast_mutex_lock, ast_mutex_unlock, free, ast_context::ignorepats, ast_context::lock, and ast_ignorepat::next. Referenced by ast_context_remove_ignorepat().
03277 {
03278 struct ast_ignorepat *ip, *ipl = NULL;
03279
03280 if (ast_mutex_lock(&con->lock)) {
03281 errno = EBUSY;
03282 return -1;
03283 }
03284
03285 ip = con->ignorepats;
03286 while (ip) {
03287 if (!strcmp(ip->pattern, ignorepat) &&
03288 (registrar == ip->registrar || !registrar)) {
03289 if (ipl) {
03290 ipl->next = ip->next;
03291 free(ip);
03292 } else {
03293 con->ignorepats = ip->next;
03294 free(ip);
03295 }
03296 ast_mutex_unlock(&con->lock);
03297 return 0;
03298 }
03299 ipl = ip; ip = ip->next;
03300 }
03301
03302 ast_mutex_unlock(&con->lock);
03303 errno = EINVAL;
03304 return -1;
03305 }
|
|
||||||||||||||||
|
Removes an include. See add_include Definition at line 1884 of file pbx.c. References ast_context_remove_include2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
01885 {
01886 struct ast_context *c;
01887
01888 if (ast_lock_contexts()) return -1;
01889
01890 /* walk contexts and search for the right one ...*/
01891 c = ast_walk_contexts(NULL);
01892 while (c) {
01893 /* we found one ... */
01894 if (!strcmp(ast_get_context_name(c), context)) {
01895 int ret;
01896 /* remove include from this context ... */
01897 ret = ast_context_remove_include2(c, include, registrar);
01898
01899 ast_unlock_contexts();
01900
01901 /* ... return results */
01902 return ret;
01903 }
01904 c = ast_walk_contexts(c);
01905 }
01906
01907 /* we can't find the right one context */
01908 ast_unlock_contexts();
01909 return -1;
01910 }
|
|
||||||||||||||||
|
Removes an include by an ast_context structure. See add_include2 Definition at line 1920 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().
01921 {
01922 struct ast_include *i, *pi = NULL;
01923
01924 if (ast_mutex_lock(&con->lock)) return -1;
01925
01926 /* walk includes */
01927 i = con->includes;
01928 while (i) {
01929 /* find our include */
01930 if (!strcmp(i->name, include) &&
01931 (!strcmp(i->registrar, registrar) || !registrar)) {
01932 /* remove from list */
01933 if (pi)
01934 pi->next = i->next;
01935 else
01936 con->includes = i->next;
01937 /* free include and return */
01938 free(i);
01939 ast_mutex_unlock(&con->lock);
01940 return 0;
01941 }
01942 pi = i;
01943 i = i->next;
01944 }
01945
01946 /* we can't find the right include */
01947 ast_mutex_unlock(&con->lock);
01948 return -1;
01949 }
|
|
||||||||||||||||||||
|
Remove a switch. Removes a switch with the given parameters Returns 0 on success, -1 on failure Definition at line 1956 of file pbx.c. References ast_context_remove_switch2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
01957 {
01958 struct ast_context *c;
01959
01960 if (ast_lock_contexts()) return -1;
01961
01962 /* walk contexts and search for the right one ...*/
01963 c = ast_walk_contexts(NULL);
01964 while (c) {
01965 /* we found one ... */
01966 if (!strcmp(ast_get_context_name(c), context)) {
01967 int ret;
01968 /* remove switch from this context ... */
01969 ret = ast_context_remove_switch2(c, sw, data, registrar);
01970
01971 ast_unlock_contexts();
01972
01973 /* ... return results */
01974 return ret;
01975 }
01976 c = ast_walk_contexts(c);
01977 }
01978
01979 /* we can't find the right one context */
01980 ast_unlock_contexts();
01981 return -1;
01982 }
|
|
||||||||||||||||||||
|
Definition at line 1992 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().
01993 {
01994 struct ast_sw *i, *pi = NULL;
01995
01996 if (ast_mutex_lock(&con->lock)) return -1;
01997
01998 /* walk switchs */
01999 i = con->alts;
02000 while (i) {
02001 /* find our switch */
02002 if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
02003 (!strcmp(i->registrar, registrar) || !registrar)) {
02004 /* remove from list */
02005 if (pi)
02006 pi->next = i->next;
02007 else
02008 con->alts = i->next;
02009 /* free switch and return */
02010 free(i);
02011 ast_mutex_unlock(&con->lock);
02012 return 0;
02013 }
02014 pi = i;
02015 i = i->next;
02016 }
02017
02018 /* we can't find the right switch */
02019 ast_mutex_unlock(&con->lock);
02020 return -1;
02021 }
|
|
||||||||||||
|
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 1617 of file pbx.c. References HELPER_EXISTS. Referenced by ast_pbx_run().
01618 {
01619 return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_EXISTS);
01620 }
|
|
||||||||||||
|
Determine if a given extension matches a given pattern (in NXX format).
Definition at line 564 of file pbx.c. References EXTENSION_MATCH_CORE. Referenced by ast_ignore_pattern().
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 1287 of file pbx.c.
01288 {
01289 struct ast_exten *e;
01290
01291 e = ast_hint_extension(c, context, exten);
01292 if (!e)
01293 return -1;
01294
01295 return ast_extension_state2(e);
01296 }
|
|
||||||||||||||||||||
|
Registers a state change callback.
Definition at line 1365 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().
01367 {
01368 struct ast_hint *list;
01369 struct ast_state_cb *cblist;
01370 struct ast_exten *e;
01371
01372 /* No context and extension add callback to statecbs list */
01373 if (!context && !exten) {
01374 ast_mutex_lock(&hintlock);
01375
01376 cblist = statecbs;
01377 while (cblist) {
01378 if (cblist->callback == callback) {
01379 cblist->data = data;
01380 ast_mutex_unlock(&hintlock);
01381 }
01382
01383 cblist = cblist->next;
01384 }
01385
01386 /* Now inserts the callback */
01387 cblist = malloc(sizeof(struct ast_state_cb));
01388 if (!cblist) {
01389 ast_mutex_unlock(&hintlock);
01390 return -1;
01391 }
01392 memset(cblist, 0, sizeof(struct ast_state_cb));
01393 cblist->id = 0;
01394 cblist->callback = callback;
01395 cblist->data = data;
01396
01397 cblist->next = statecbs;
01398 statecbs = cblist;
01399
01400 ast_mutex_unlock(&hintlock);
01401 return 0;
01402 }
01403
01404 if (!context || !exten)
01405 return -1;
01406
01407 /* This callback type is for only one hint */
01408 e = ast_hint_extension(NULL, context, exten);
01409 if (!e) {
01410 return -1;
01411 }
01412
01413 ast_mutex_lock(&hintlock);
01414 list = hints;
01415
01416 while (list) {
01417 if (list->exten == e)
01418 break;
01419 list = list->next;
01420 }
01421
01422 if (!list) {
01423 ast_mutex_unlock(&hintlock);
01424 return -1;
01425 }
01426
01427 /* Now inserts the callback */
01428 cblist = malloc(sizeof(struct ast_state_cb));
01429 if (!cblist) {
01430 ast_mutex_unlock(&hintlock);
01431 return -1;
01432 }
01433 memset(cblist, 0, sizeof(struct ast_state_cb));
01434 cblist->id = stateid++;
01435 cblist->callback = callback;
01436 cblist->data = data;
01437
01438 cblist->next = list->callbacks;
01439 list->callbacks = cblist;
01440
01441 ast_mutex_unlock(&hintlock);
01442 return cblist->id;
01443 }
|
|
||||||||||||
|
Deletes a registered state change callback by ID.
Definition at line 1445 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.
01446 {
01447 struct ast_hint *list;
01448 struct ast_state_cb *cblist, *cbprev;
01449
01450 if (!id && !callback)
01451 return -1;
01452
01453 ast_mutex_lock(&hintlock);
01454
01455 /* id is zero is a callback without extension */
01456 if (!id) {
01457 cbprev = NULL;
01458 cblist = statecbs;
01459 while (cblist) {
01460 if (cblist->callback == callback) {
01461 if (!cbprev)
01462 statecbs = cblist->next;
01463 else
01464 cbprev->next = cblist->next;
01465
01466 free(cblist);
01467
01468 ast_mutex_unlock(&hintlock);
01469 return 0;
01470 }
01471 cbprev = cblist;
01472 cblist = cblist->next;
01473 }
01474
01475 ast_mutex_lock(&hintlock);
01476 return -1;
01477 }
01478
01479 /* id greater zero is a callback with extension */
01480 list = hints;
01481 while (list) {
01482 cblist = list->callbacks;
01483 cbprev = NULL;
01484 while (cblist) {
01485 if (cblist->id==id) {
01486 if (!cbprev)
01487 list->callbacks = cblist->next;
01488 else
01489 cbprev->next = cblist->next;
01490
01491 free(cblist);
01492
01493 ast_mutex_unlock(&hintlock);
01494 return 0;
01495 }
01496 cbprev = cblist;
01497 cblist = cblist->next;
01498 }
01499 list = list->next;
01500 }
01501
01502 ast_mutex_unlock(&hintlock);
01503 return -1;
01504 }
|
|
|
Definition at line 4497 of file pbx.c. References ast_context::name. Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_include2(), ast_context_add_switch(), ast_context_add_switch2(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), and ast_context_remove_switch().
04498 {
04499 return con ? con->name : NULL;
04500 }
|
|
|
Definition at line 4525 of file pbx.c. References ast_context::registrar.
04526 {
04527 return c ? c->registrar : NULL;
04528 }
|
|
|
Definition at line 4545 of file pbx.c. References ast_exten::app. Referenced by ast_device_state_changed(), and ast_get_hint().
04546 {
04547 return e ? e->app : NULL;
04548 }
|
|
|
Definition at line 4550 of file pbx.c. References ast_exten::data.
04551 {
04552 return e ? e->data : NULL;
04553 }
|
|
|
Definition at line 4502 of file pbx.c. References ast_exten::exten.
04503 {
04504 return exten ? exten->exten : NULL;
04505 }
|
|
|
Definition at line 4517 of file pbx.c. References ast_exten::priority.
04518 {
04519 return exten ? exten->priority : -1;
04520 }
|
|
|
Definition at line 4530 of file pbx.c. References ast_exten::registrar.
04531 {
04532 return e ? e->registrar : NULL;
04533 }
|
|
||||||||||||||||||||||||
|
If an extension exists, return non-zero.
Definition at line 1606 of file pbx.c. References ast_get_extension_app().
01607 {
01608 struct ast_exten *e;
01609 e = ast_hint_extension(c, context, exten);
01610 if (e) {
01611 strncpy(hint, ast_get_extension_app(e), maxlen);
01612 return -1;
01613 }
01614 return 0;
01615 }
|
|
|
Definition at line 4512 of file pbx.c. References ast_ignorepat::pattern.
04513 {
04514 return ip ? ip->pattern : NULL;
04515 }
|
|
|
Definition at line 4540 of file pbx.c. References ast_ignorepat::registrar.
04541 {
04542 return ip ? ip->registrar : NULL;
04543 }
|
|
|
Definition at line 4507 of file pbx.c. References ast_include::name.
04508 {
04509 return inc ? inc->name : NULL;
04510 }
|
|
|
Definition at line 4535 of file pbx.c. References ast_include::registrar.
04536 {
04537 return i ? i->registrar : NULL;
04538 }
|
|
|
Definition at line 4560 of file pbx.c. References ast_sw::data.
04561 {
04562 return sw ? sw->data : NULL;
04563 }
|
|
|
Definition at line 4555 of file pbx.c. References ast_sw::name.
04556 {
04557 return sw ? sw->name : NULL;
04558 }
|
|
|
Definition at line 4565 of file pbx.c. References ast_sw::registrar.
04566 {
04567 return sw ? sw->registrar : NULL;
04568 }
|
|
||||||||||||
|
Checks to see if a number should be ignored.
Definition at line 3369 of file pbx.c. References ast_context_find(), and ast_extension_match().
03370 {
03371 struct ast_context *con;
03372 struct ast_ignorepat *pat;
03373 con = ast_context_find(context);
03374 if (con) {
03375 pat = con->ignorepats;
03376 while (pat) {
03377 if (ast_extension_match(pat->pattern, pattern))
03378 return 1;
03379 pat = pat->next;
03380 }
03381 }
03382 return 0;
03383 }
|
|
|
Locks a given context.
Definition at line 4484 of file pbx.c. References ast_mutex_lock, and ast_context::lock.
04485 {
04486 return ast_mutex_lock(&con->lock);
04487 }
|
|
|
Locks the contexts. Locks the context list Returns 0 on success, -1 on error Definition at line 4471 of file pbx.c. References ast_mutex_lock. Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), and ast_context_remove_switch().
04472 {
04473 return ast_mutex_lock(&conlock);
04474 }
|
|
||||||||||||||||||||||||
|
Looks to see if adding anything to this extension might match something. (exists ^ canmatch).
Definition at line 1627 of file pbx.c. References HELPER_MATCHMORE. Referenced by ast_pbx_run().
01628 {
01629 return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_MATCHMORE);
01630 }
|
|
||||||||||||
|
Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added.
Definition at line 2769 of file pbx.c. References __ast_context_destroy(), ast_log(), ast_mutex_lock, ast_mutex_unlock, and LOG_WARNING.
02769 {
02770 struct ast_context *tmp, *lasttmp = NULL;
02771 tmp = *extcontexts;
02772 ast_mutex_lock(&conlock);
02773 if (registrar) {
02774 __ast_context_destroy(NULL,registrar,0);
02775 while (tmp) {
02776 lasttmp = tmp;
02777 tmp = tmp->next;
02778 }
02779 } else {
02780 while (tmp) {
02781 __ast_context_destroy(tmp,tmp->registrar,0);
02782 lasttmp = tmp;
02783 tmp = tmp->next;
02784 }
02785 }
02786 if (lasttmp) {
02787 lasttmp->next = contexts;
02788 contexts = *extcontexts;
02789 *extcontexts = NULL;
02790 } else
02791 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n");
02792 ast_mutex_unlock(&conlock);
02793 return;
02794 }
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 3877 of file pbx.c. References ast_channel::_state, ast_hangup(), ast_log(), ast_request_and_dial(), AST_STATE_UP, ast_verbose(), free, LOG_WARNING, malloc, ast_channel::name, option_verbose, type, and VERBOSE_PREFIX_4.
03878 {
03879 struct ast_channel *chan;
03880 struct async_stat *as;
03881 struct app_tmp *tmp;
03882 char *var, *vartmp;
03883 int res = -1;
03884 if (!app || !strlen(app))
03885 return -1;
03886 if (sync) {
03887 chan = ast_request_and_dial(type, format, data, timeout, reason, callerid);
03888 if (chan) {
03889 vartmp = variable;
03890 while( (var = strtok_r(NULL, "|", &vartmp)) ) {
03891 pbx_builtin_setvar( chan, var );
03892 }
03893 if (chan->_state == AST_STATE_UP) {
03894 res = 0;
03895 if (option_verbose > 3)
03896 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
03897 tmp = malloc(sizeof(struct app_tmp));
03898 if (tmp) {
03899 memset(tmp, 0, sizeof(struct app_tmp));
03900 strncpy(tmp->app, app, sizeof(tmp->app) - 1);
03901 strncpy(tmp->data, appdata, sizeof(tmp->data) - 1);
03902 tmp->chan = chan;
03903 if (sync > 1) {
03904 ast_pbx_run_app(tmp);
03905 } else {
03906 if (pthread_create(&tmp->t, NULL, ast_pbx_run_app, tmp)) {
03907 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
03908 free(tmp);
03909 ast_hangup(chan);
03910 res = -1;
03911 }
03912 }
03913 } else {
03914 ast_log(LOG_WARNING, "Out of memory :(\n");
03915 res = -1;
03916 }
03917 } else {
03918 if (option_verbose > 3)
03919 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
03920 ast_hangup(chan);
03921 }
03922 }
03923 } else {
03924 as = malloc(sizeof(struct async_stat));
03925 if (!as)
03926 return -1;
03927 memset(as, 0, sizeof(struct async_stat));
03928 chan = ast_request_and_dial(type, format, data, 0, reason, callerid);
03929 if (!chan) {
03930 free(as);
03931 return -1;
03932 }
03933 as->chan = chan;
03934 strncpy(as->app, app, sizeof(as->app) - 1);
03935 if (appdata)
03936 strncpy(as->appdata, appdata, sizeof(as->appdata) - 1);
03937 as->timeout = timeout;
03938 if (pthread_create(&as->p, NULL, async_wait, as)) {
03939 ast_log(LOG_WARNING, "Failed to start async wait\n");
03940 free(as);
03941 ast_hangup(chan);
03942 return -1;
03943 }
03944 res = 0;
03945 }
03946 return res;
03947 }
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 3782 of file pbx.c. References ast_channel::_state, ast_hangup(), ast_log(), ast_pbx_run(), ast_pbx_start(), ast_request_and_dial(), AST_STATE_UP, ast_verbose(), ast_channel::callerid, ast_channel::context, ast_channel::exten, free, LOG_WARNING, malloc, ast_channel::name, option_verbose, ast_channel::priority, type, and VERBOSE_PREFIX_4.
03783 {
03784 struct ast_channel *chan;
03785 struct async_stat *as;
03786 int res = -1;
03787 char *var, *tmp;
03788 if (sync) {
03789 chan = ast_request_and_dial(type, format, data, timeout, reason, callerid);
03790 if (chan) {
03791 /* JDG chanvar */
03792 tmp = variable;
03793 /* FIXME replace this call with strsep NOT*/
03794 while( (var = strtok_r(NULL, "|", &tmp)) ) {
03795 pbx_builtin_setvar( chan, var );
03796 } /* /JDG */
03797 if (chan->_state == AST_STATE_UP) {
03798 res = 0;
03799 if (option_verbose > 3)
03800 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
03801 if (context && strlen(context))
03802 strncpy(chan->context, context, sizeof(chan->context) - 1);
03803 if (exten && strlen(exten))
03804 strncpy(chan->exten, exten, sizeof(chan->exten) - 1);
03805 if (callerid && strlen(callerid))
03806 strncpy(chan->callerid, callerid, sizeof(chan->callerid) - 1);
03807 if (priority > 0)
03808 chan->priority = priority;
03809 if (sync > 1) {
03810 if (ast_pbx_run(chan)) {
03811 ast_log(LOG_WARNING, "Unable to run PBX on %s\n", chan->name);
03812 ast_hangup(chan);
03813 res = -1;
03814 }
03815 } else {
03816 if (ast_pbx_start(chan)) {
03817 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", chan->name);
03818 ast_hangup(chan);
03819 res = -1;
03820 }
03821 }
03822 } else {
03823 if (option_verbose > 3)
03824 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
03825 ast_hangup(chan);
03826 }
03827 }
03828 } else {
03829 as = malloc(sizeof(struct async_stat));
03830 if (!as)
03831 return -1;
03832 memset(as, 0, sizeof(struct async_stat));
03833 chan = ast_request_and_dial(type, format, data, 0, reason, callerid);
03834 if (!chan) {
03835 free(as);
03836 return -1;
03837 }
03838 as->chan = chan;
03839 strncpy(as->context, context, sizeof(as->context) - 1);
03840 strncpy(as->exten, exten, sizeof(as->exten) - 1);
03841 as->priority = priority;
03842 as->timeout = timeout;
03843 if (pthread_create(&as->p, NULL, async_wait, as)) {
03844 ast_log(LOG_WARNING, "Failed to start async wait\n");
03845 free(as);
03846 ast_hangup(chan);
03847 return -1;
03848 }
03849 res = 0;
03850 }
03851 return res;
03852 }
|
|
|
Execute the PBX in the current thread.
Definition at line 1637 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_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. Referenced by ast_pbx_outgoing_exten().
01638 {
01639 int firstpass = 1;
01640 char digit;
01641 char exten[256];
01642 int pos;
01643 int waittime;
01644 int res=0;
01645
01646 /* A little initial setup here */
01647 if (c->pbx)
01648 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name);
01649 c->pbx = malloc(sizeof(struct ast_pbx));
01650 if (!c->pbx) {
01651 ast_log(LOG_WARNING, "Out of memory\n");
01652 return -1;
01653 }
01654 if (c->amaflags) {
01655 if (c->cdr) {
01656 ast_log(LOG_WARNING, "%s already has a call record??\n", c->name);
01657 } else {
01658 c->cdr = ast_cdr_alloc();
01659 if (!c->cdr) {
01660 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
01661 free(c->pbx);
01662 return -1;
01663 }
01664 ast_cdr_init(c->cdr, c);
01665 }
01666 }
01667 memset(c->pbx, 0, sizeof(struct ast_pbx));
01668 /* Set reasonable defaults */
01669 c->pbx->rtimeout = 10;
01670 c->pbx->dtimeout = 5;
01671
01672 /* Start by trying whatever the channel is set to */
01673 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->callerid)) {
01674 /* JK02: If not successfull fall back to 's' */
01675 strncpy(c->exten, "s", sizeof(c->exten)-1);
01676 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->callerid)) {
01677 /* JK02: And finally back to default if everything else failed */
01678 strncpy(c->context, "default", sizeof(c->context)-1);
01679 }
01680 c->priority = 1;
01681 }
01682 if (c->cdr)
01683 ast_cdr_start(c->cdr);
01684 for(;;) {
01685 pos = 0;
01686 digit = 0;
01687 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->callerid)) {
01688 memset(exten, 0, sizeof(exten));
01689 manager_event(EVENT_FLAG_CALL, "Newexten",
01690 "Channel: %s\r\n"
01691 "Context: %s\r\n"
01692 "Extension: %s\r\n"
01693 "Priority: %d\r\n"
01694 "Uniqueid: %s\r\n",
01695 c->name, c->context, c->exten, c->priority, c->uniqueid);
01696 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->callerid))) {
01697 /* Something bad happened, or a hangup has been requested. */
01698 if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) ||
01699 (res == '*') || (res == '#')) {
01700 ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res);
01701 memset(exten, 0, sizeof(exten));
01702 pos = 0;
01703 exten[pos++] = digit = res;
01704 break;
01705 }
01706 switch(res) {
01707 case AST_PBX_KEEPALIVE:
01708 if (option_debug)
01709 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
01710 else if (option_verbose > 1)
01711 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
01712 goto out;
01713 break;
01714 default:
01715 if (option_debug)
01716 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
01717 else if (option_verbose > 1)
01718 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
01719 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
01720 c->_softhangup =0;
01721 break;
01722 }
01723 /* atimeout */
01724 if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
01725 break;
01726 }
01727 goto out;
01728 }
01729 }
01730 if ((c->_softhangup == AST_SOFTHANGUP_TIMEOUT) && (ast_exists_extension(c,c->context,"T",1,c->callerid))) {
01731 strncpy(c->exten,"T",sizeof(c->exten) - 1);
01732 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
01733 c->whentohangup = 0;
01734 c->priority = 0;
01735 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
01736 } else if (c->_softhangup) {
01737 ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n",
01738 c->exten, c->priority);
01739 goto out;
01740 }
01741 firstpass = 0;
01742 c->priority++;
01743 }
01744 if (!ast_exists_extension(c, c->context, c->exten, 1, c->callerid)) {
01745 /* It's not a valid extension anymore */
01746 if (ast_exists_extension(c, c->context, "i", 1, c->callerid)) {
01747 if (option_verbose > 2)
01748 ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name);
01749 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten);
01750 strncpy(c->exten, "i", sizeof(c->exten)-1);
01751 c->priority = 1;
01752 } else {
01753 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n",
01754 c->name, c->exten, c->context);
01755 goto out;
01756 }
01757 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
01758 /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */
01759 c->_softhangup = 0;
01760 } else {
01761 /* Done, wait for an extension */
01762 if (digit)
01763 waittime = c->pbx->dtimeout;
01764 else
01765 waittime = c->pbx->rtimeout;
01766 while (ast_matchmore_extension(c, c->context, exten, 1, c->callerid)) {
01767 /* As long as we're willing to wait, and as long as it's not defined,
01768 keep reading digits until we can't possibly get a right answer anymore. */
01769 digit = ast_waitfordigit(c, waittime * 1000);
01770 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
01771 c->_softhangup = 0;
01772 } else {
01773 if (!digit)
01774 /* No entry */
01775 break;
01776 if (digit < 0)
01777 /* Error, maybe a hangup */
01778 goto out;
01779 exten[pos++] = digit;
01780 waittime = c->pbx->dtimeout;
01781 }
01782 }
01783 if (ast_exists_extension(c, c->context, exten, 1, c->callerid)) {
01784 /* Prepare the next cycle */
01785 strncpy(c->exten, exten, sizeof(c->exten)-1);
01786 c->priority = 1;
01787 } else {
01788 /* No such extension */
01789 if (strlen(exten)) {
01790 /* An invalid extension */
01791 if (ast_exists_extension(c, c->context, "i", 1, c->callerid)) {
01792 if (option_verbose > 2)
01793 ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", exten, c->context, c->name);
01794 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", exten);
01795 strncpy(c->exten, "i", sizeof(c->exten)-1);
01796 c->priority = 1;
01797 } else {
01798 ast_log(LOG_WARNING, "Invalid extension, but no rule 'i' in context '%s'\n", c->context);
01799 goto out;
01800 }
01801 } else {
01802 /* A simple timeout */
01803 if (ast_exists_extension(c, c->context, "t", 1, c->callerid)) {
01804 if (option_verbose > 2)
01805 ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name);
01806 strncpy(c->exten, "t", sizeof(c->exten)-1);
01807 c->priority = 1;
01808 } else {
01809 ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context);
01810 goto out;
01811 }
01812 }
01813 }
01814 if (c->cdr) {
01815 if (option_verbose > 2)
01816 ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name);
01817 ast_cdr_update(c);
01818 }
01819 }
01820 }
01821 if (firstpass)
01822 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
01823 out:
01824 if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->callerid)) {
01825 strcpy(c->exten, "h");
01826 c->priority = 1;
01827 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->callerid)) {
01828 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->callerid))) {
01829 /* Something bad happened, or a hangup has been requested. */
01830 if (option_debug)
01831 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
01832 else if (option_verbose > 1)
01833 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
01834 break;
01835 }
01836 c->priority++;
01837 }
01838 }
01839
01840 pbx_destroy(c->pbx);
01841 c->pbx = NULL;
01842 if (res != AST_PBX_KEEPALIVE)
01843 ast_hangup(c);
01844 return 0;
01845 }
|
|
|
Create a new thread and start the PBX (or whatever).
Definition at line 1860 of file pbx.c. References ast_log(), and LOG_WARNING. Referenced by ast_async_goto(), and ast_pbx_outgoing_exten().
01861 {
01862 pthread_t t;
01863 pthread_attr_t attr;
01864 if (!c) {
01865 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
01866 return -1;
01867 }
01868
01869 /* Start a new thread, and get something handling this channel. */
01870 pthread_attr_init(&attr);
01871 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
01872 if (pthread_create(&t, &attr, pbx_thread, c)) {
01873 ast_log(LOG_WARNING, "Failed to create new channel thread\n");
01874 return -1;
01875 }
01876 return 0;
01877 }
|
|
||||||||||||||||||||
|
Add an application. The function 'execute' should return non-zero if the line needs to be hung up.
Definition at line 2168 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. Referenced by load_pbx().
02169 {
02170 struct ast_app *tmp, *prev, *cur;
02171 char tmps[80];
02172 if (ast_mutex_lock(&applock)) {
02173 ast_log(LOG_ERROR, "Unable to lock application list\n");
02174 return -1;
02175 }
02176 tmp = apps;
02177 while(tmp) {
02178 if (!strcasecmp(app, tmp->name)) {
02179 ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
02180 ast_mutex_unlock(&applock);
02181 return -1;
02182 }
02183 tmp = tmp->next;
02184 }
02185 tmp = malloc(sizeof(struct ast_app));
02186 if (tmp) {
02187 memset(tmp, 0, sizeof(struct ast_app));
02188 strncpy(tmp->name, app, sizeof(tmp->name)-1);
02189 tmp->execute = execute;
02190 tmp->synopsis = synopsis;
02191 tmp->description = description;
02192 /* Store in alphabetical order */
02193 cur = apps;
02194 prev = NULL;
02195 while(cur) {
02196 if (strcasecmp(tmp->name, cur->name) < 0)
02197 break;
02198 prev = cur;
02199 cur = cur->next;
02200 }
02201 if (prev) {
02202 tmp->next = prev->next;
02203 prev->next = tmp;
02204 } else {
02205 tmp->next = apps;
02206 apps = tmp;
02207 }
02208 } else {
02209 ast_log(LOG_WARNING, "Out of memory\n");
02210 ast_mutex_unlock(&applock);
02211 return -1;
02212 }
02213 if (option_verbose > 1)
02214 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
02215 ast_mutex_unlock(&applock);
02216 return 0;
02217 }
|
|
|
Register an alternative switch.
Definition at line 2219 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.
02220 {
02221 struct ast_switch *tmp, *prev=NULL;
02222 if (ast_mutex_lock(&switchlock)) {
02223 ast_log(LOG_ERROR, "Unable to lock switch lock\n");
02224 return -1;
02225 }
02226 tmp = switches;
02227 while(tmp) {
02228 if (!strcasecmp(tmp->name, sw->name))
02229 break;
02230 prev = tmp;
02231 tmp = tmp->next;
02232 }
02233 if (tmp) {
02234 ast_mutex_unlock(&switchlock);
02235 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
02236 return -1;
02237 }
02238 sw->next = NULL;
02239 if (prev)
02240 prev->next = sw;
02241 else
02242 switches = sw;
02243 ast_mutex_unlock(&switchlock);
02244 return 0;
02245 }
|
|
||||||||||||||||||||||||
|
Launch a new extension (i.e. new stack).
Definition at line 1632 of file pbx.c. References HELPER_SPAWN. Referenced by ast_pbx_run().
01633 {
01634 return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_SPAWN);
01635 }
|
|
|
Unlocks the given context.
Definition at line 4489 of file pbx.c. References ast_mutex_unlock, and ast_context::lock.
04490 {
04491 return ast_mutex_unlock(&con->lock);
04492 }
|
|
|
Unlocks contexts. Returns 0 on success, -1 on failure Definition at line 4476 of file pbx.c. References ast_mutex_unlock. Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), and ast_context_remove_switch().
04477 {
04478 return ast_mutex_unlock(&conlock);
04479 }
|
|
|
Remove an application.
Definition at line 2699 of file pbx.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), LOG_ERROR, ast_app::next, option_verbose, and VERBOSE_PREFIX_2.
02699 {
02700 struct ast_app *tmp, *tmpl = NULL;
02701 if (ast_mutex_lock(&applock)) {
02702 ast_log(LOG_ERROR, "Unable to lock application list\n");
02703 return -1;
02704 }
02705 tmp = apps;
02706 while(tmp) {
02707 if (!strcasecmp(app, tmp->name)) {
02708 if (tmpl)
02709 tmpl->next = tmp->next;
02710 else
02711 apps = tmp->next;
02712 if (option_verbose > 1)
02713 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
02714 ast_mutex_unlock(&applock);
02715 return 0;
02716 }
02717 tmpl = tmp;
02718 tmp = tmp->next;
02719 }
02720 ast_mutex_unlock(&applock);
02721 return -1;
02722 }
|
|
|
Unregister an alternative switch.
Definition at line 2247 of file pbx.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, LOG_ERROR, ast_switch::next, and switches.
02248 {
02249 struct ast_switch *tmp, *prev=NULL;
02250 if (ast_mutex_lock(&switchlock)) {
02251 ast_log(LOG_ERROR, "Unable to lock switch lock\n");
02252 return;
02253 }
02254 tmp = switches;
02255 while(tmp) {
02256 if (tmp == sw) {
02257 if (prev)
02258 prev->next = tmp->next;
02259 else
02260 switches = tmp->next;
02261 tmp->next = NULL;
02262 break;
02263 }
02264 prev = tmp;
02265 tmp = tmp->next;
02266 }
02267 ast_mutex_unlock(&switchlock);
02268 }
|
|
||||||||||||
|
Definition at line 4581 of file pbx.c. References ast_exten::next, and ast_context::root.
|
|
||||||||||||
|
Definition at line 4617 of file pbx.c. References ast_context::ignorepats, and ast_ignorepat::next.
04619 {
04620 if (!ip)
04621 return con ? con->ignorepats : NULL;
04622 else
04623 return ip->next;
04624 }
|
|
||||||||||||
|
Definition at line 4608 of file pbx.c. References ast_context::includes, and ast_include::next.
|
|
||||||||||||
|
Definition at line 4590 of file pbx.c. References ast_context::alts, and ast_sw::next.
|
|
|
Definition at line 4573 of file pbx.c. References ast_context::next. Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), and ast_context_remove_switch().
04574 {
04575 if (!con)
04576 return contexts;
04577 else
04578 return con->next;
04579 }
|
|
||||||||||||
|
Definition at line 4599 of file pbx.c. References ast_exten::peer.
04601 {
04602 if (!priority)
04603 return exten;
04604 else
04605 return priority->peer;
04606 }
|
|
|
Definition at line 4369 of file pbx.c. References AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_REMOVE_HEAD, and ast_var_delete().
04370 {
04371 struct ast_var_t *vardata;
04372 while (!AST_LIST_EMPTY(&globals)) {
04373 vardata = AST_LIST_FIRST(&globals);
04374 AST_LIST_REMOVE_HEAD(&globals, entries);
04375 ast_var_delete(vardata);
04376 }
04377 }
|
|
||||||||||||
|
|
|
||||||||||||||||
|
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 922 of file pbx.c. References ast_expr(), ast_log(), free, LOG_DEBUG, and LOG_NOTICE.
00923 {
00924 char *cp4;
00925 const char *tmp, *whereweare;
00926 int length;
00927 char workspace[256];
00928 char ltmp[256], var[256];
00929 char *nextvar, *nextexp;
00930 char *vars, *vare;
00931 int pos, brackets, needsub, len;
00932
00933 /* Substitutes variables into cp2, based on string cp1, and assuming cp2 to be
00934 zero-filled */
00935 whereweare=tmp=cp1;
00936 while(strlen(whereweare) && count) {
00937 /* Assume we're copying the whole remaining string */
00938 pos = strlen(whereweare);
00939
00940 /* Look for a variable */
00941 nextvar = strstr(whereweare, "${");
00942
00943 nextexp = strstr(whereweare, "$[");
00944
00945 if (nextvar && nextexp) {
00946 if (nextvar < nextexp)
00947 nextexp = NULL;
00948 else
00949 nextvar = NULL;
00950 }
00951
00952 /* If there is one, we only go that far */
00953 if (nextvar)
00954 pos = nextvar - whereweare;
00955 else if (nextexp)
00956 pos = nextexp - whereweare;
00957
00958 /* Can't copy more than 'count' bytes */
00959 if (pos > count)
00960 pos = count;
00961
00962 /* Copy that many bytes */
00963 memcpy(cp2, whereweare, pos);
00964
00965 count -= pos;
00966 cp2 += pos;
00967 whereweare += pos;
00968
00969 if (nextvar) {
00970 /* We have a variable. Find the start and end, and determine
00971 if we are going to have to recursively call ourselves on the
00972 contents */
00973 vars = vare = nextvar + 2;
00974 brackets = 1;
00975 needsub = 0;
00976
00977 /* Find the end of it */
00978 while(brackets && *vare) {
00979 if ((vare[0] == '$') && (vare[1] == '{')) {
00980 needsub++;
00981 brackets++;
00982 } else if (vare[0] == '}') {
00983 brackets--;
00984 } else if ((vare[0] == '$') && (vare[1] == '['))
00985 needsub++;
00986 vare++;
00987 }
00988 if (brackets)
00989 ast_log(LOG_NOTICE, "Error in extension logic (missing '}')\n");
00990 len = vare - vars - 1;
00991
00992 /* Skip totally over variable name */
00993 whereweare += ( len + 3);
00994
00995 /* Store variable name (and truncate) */
00996 memset(var, 0, sizeof(var));
00997 strncpy(var, vars, sizeof(var) - 1);
00998 var[len] = '\0';
00999
01000 /* Substitute if necessary */
01001 if (needsub) {
01002 memset(ltmp, 0, sizeof(ltmp));
01003 pbx_substitute_variables_helper(c, var, ltmp, sizeof(ltmp) - 1);
01004 vars = ltmp;
01005 } else {
01006 vars = var;
01007 }
01008
01009 /* Retrieve variable value */
01010 strcpy(workspace, "");
01011 pbx_substitute_variables_temp(c,vars,&cp4, workspace, sizeof(workspace));
01012 if (cp4) {
01013 length = strlen(cp4);
01014 if (length > count)
01015 length = count;
01016 memcpy(cp2, cp4, length);
01017 count -= length;
01018 cp2 += length;
01019 }
01020
01021 } else if (nextexp) {
01022 /* We have an expression. Find the start and end, and determine
01023 if we are going to have to recursively call ourselves on the
01024 contents */
01025 vars = vare = nextexp + 2;
01026 brackets = 1;
01027 needsub = 0;
01028
01029 /* Find the end of it */
01030 while(brackets && *vare) {
01031 if ((vare[0] == '$') && (vare[1] == '[')) {
01032 needsub++;
01033 brackets++;
01034 } else if (vare[0] == ']') {
01035 brackets--;
01036 } else if ((vare[0] == '$') && (vare[1] == '{'))
01037 needsub++;
01038 vare++;
01039 }
01040 if (brackets)
01041 ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n");
01042 len = vare - vars - 1;
01043
01044 /* Skip totally over variable name */
01045 whereweare += ( len + 3);
01046
01047 /* Store variable name (and truncate) */
01048 memset(var, 0, sizeof(var));
01049 strncpy(var, vars, sizeof(var) - 1);
01050 var[len] = '\0';
01051
01052 /* Substitute if necessary */
01053 if (needsub) {
01054 memset(ltmp, 0, sizeof(ltmp));
01055 pbx_substitute_variables_helper(c, var, ltmp, sizeof(ltmp) - 1);
01056 vars = ltmp;
01057 } else {
01058 vars = var;
01059 }
01060
01061 /* Evaluate expression */
01062 cp4 = ast_expr(vars);
01063
01064 ast_log(LOG_DEBUG, "Expression is '%s'\n", cp4);
01065
01066 if (cp4) {
01067 length = strlen(cp4);
01068 if (length > count)
01069 length = count;
01070 memcpy(cp2, cp4, length);
01071 count -= length;
01072 cp2 += length;
01073 free(cp4);
01074 }
01075
01076 } else
01077 break;
01078 }
01079 }
|
1.3.4