Lines 301-306
Link Here
|
301 |
static int pbx_builtin_background(struct ast_channel *, void *); |
301 |
static int pbx_builtin_background(struct ast_channel *, void *); |
302 |
static int pbx_builtin_wait(struct ast_channel *, void *); |
302 |
static int pbx_builtin_wait(struct ast_channel *, void *); |
303 |
static int pbx_builtin_waitexten(struct ast_channel *, void *); |
303 |
static int pbx_builtin_waitexten(struct ast_channel *, void *); |
|
|
304 |
static int pbx_builtin_incomplete(struct ast_channel *, void *); |
304 |
static int pbx_builtin_keepalive(struct ast_channel *, void *); |
305 |
static int pbx_builtin_keepalive(struct ast_channel *, void *); |
305 |
static int pbx_builtin_resetcdr(struct ast_channel *, void *); |
306 |
static int pbx_builtin_resetcdr(struct ast_channel *, void *); |
306 |
static int pbx_builtin_setamaflags(struct ast_channel *, void *); |
307 |
static int pbx_builtin_setamaflags(struct ast_channel *, void *); |
Lines 563-568
Link Here
|
563 |
"value.\n" |
564 |
"value.\n" |
564 |
}, |
565 |
}, |
565 |
|
566 |
|
|
|
567 |
{ "Incomplete", pbx_builtin_incomplete, |
568 |
"returns AST_PBX_INCOMPLETE value", |
569 |
" Incomplete([n]): Signals the PBX routines that the previous matched extension\n" |
570 |
"is incomplete and that further input should be allowed before matching can\n" |
571 |
"be considered to be complete. Can be used within a pattern match when\n" |
572 |
"certain criteria warrants a longer match.\n" |
573 |
" If the 'n' option is specified, then Incomplete will not attempt to answer\n" |
574 |
"the channel first. Note that most channel types need to be in Answer state\n" |
575 |
"in order to receive DTMF.\n" |
576 |
}, |
577 |
|
578 |
{ "KeepAlive", pbx_builtin_keepalive, |
579 |
"returns AST_PBX_KEEPALIVE value", |
580 |
" KeepAlive(): This application is chiefly meant for internal use with Gosubs.\n" |
581 |
"Please do not run it alone from the dialplan!\n" |
582 |
}, |
583 |
|
566 |
{ "NoOp", pbx_builtin_noop, |
584 |
{ "NoOp", pbx_builtin_noop, |
567 |
"Do Nothing (No Operation)", |
585 |
"Do Nothing (No Operation)", |
568 |
" NoOp(): This application does nothing. However, it is useful for debugging\n" |
586 |
" NoOp(): This application does nothing. However, it is useful for debugging\n" |
Lines 680-691
Link Here
|
680 |
"See Also: Playback(application), Background(application).\n" |
698 |
"See Also: Playback(application), Background(application).\n" |
681 |
}, |
699 |
}, |
682 |
|
700 |
|
683 |
{ "KeepAlive", pbx_builtin_keepalive, |
|
|
684 |
"returns AST_PBX_KEEPALIVE value", |
685 |
" KeepAlive(): This application is chiefly meant for internal use with Gosubs.\n" |
686 |
"Please do not run it alone from the dialplan!\n" |
687 |
}, |
688 |
|
689 |
}; |
701 |
}; |
690 |
|
702 |
|
691 |
static struct ast_context *contexts; |
703 |
static struct ast_context *contexts; |
Lines 3297-3302
Link Here
|
3297 |
char dst_exten[256]; /* buffer to accumulate digits */ |
3309 |
char dst_exten[256]; /* buffer to accumulate digits */ |
3298 |
int pos = 0; /* XXX should check bounds */ |
3310 |
int pos = 0; /* XXX should check bounds */ |
3299 |
int digit = 0; |
3311 |
int digit = 0; |
|
|
3312 |
int invalid = 0; |
3313 |
int timeout = 0; |
3300 |
|
3314 |
|
3301 |
/* loop on priorities in this context/exten */ |
3315 |
/* loop on priorities in this context/exten */ |
3302 |
while ( !(res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num, &found,1))) { |
3316 |
while ( !(res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num, &found,1))) { |
Lines 3332-3337
Link Here
|
3332 |
ast_debug(1, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); |
3346 |
ast_debug(1, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); |
3333 |
ast_verb(2, "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); |
3347 |
ast_verb(2, "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); |
3334 |
error = 1; |
3348 |
error = 1; |
|
|
3349 |
} else if (res == AST_PBX_INCOMPLETE) { |
3350 |
ast_debug(1, "Spawn extension (%s,%s,%d) exited INCOMPLETE on '%s'\n", c->context, c->exten, c->priority, c->name); |
3351 |
ast_verb(2, "Spawn extension (%s, %s, %d) exited INCOMPLETE on '%s'\n", c->context, c->exten, c->priority, c->name); |
3352 |
|
3353 |
/* Don't cycle on incomplete - this will happen if the only extension that matches is our "incomplete" extension */ |
3354 |
if (!ast_matchmore_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { |
3355 |
invalid = 1; |
3356 |
} else { |
3357 |
ast_copy_string(dst_exten, c->exten, sizeof(dst_exten)); |
3358 |
digit = 1; |
3359 |
pos = strlen(dst_exten); |
3360 |
} |
3335 |
} else { |
3361 |
} else { |
3336 |
ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); |
3362 |
ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); |
3337 |
ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); |
3363 |
ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); |
Lines 3368-3374
Link Here
|
3368 |
* hangup. We have options, here. We can either catch the failure |
3394 |
* hangup. We have options, here. We can either catch the failure |
3369 |
* and continue, or we can drop out entirely. */ |
3395 |
* and continue, or we can drop out entirely. */ |
3370 |
|
3396 |
|
3371 |
if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) { |
3397 |
if (invalid || !ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) { |
3372 |
/*!\note |
3398 |
/*!\note |
3373 |
* If there is no match at priority 1, it is not a valid extension anymore. |
3399 |
* If there is no match at priority 1, it is not a valid extension anymore. |
3374 |
* Try to continue at "i" (for invalid) or "e" (for exception) or exit if |
3400 |
* Try to continue at "i" (for invalid) or "e" (for exception) or exit if |
Lines 3412-3422
Link Here
|
3412 |
|
3438 |
|
3413 |
if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos)) |
3439 |
if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos)) |
3414 |
break; |
3440 |
break; |
3415 |
if (ast_exists_extension(c, c->context, dst_exten, 1, c->cid.cid_num)) /* Prepare the next cycle */ |
3441 |
if (res == AST_PBX_INCOMPLETE && ast_strlen_zero(&dst_exten[pos])) |
|
|
3442 |
timeout = 1; |
3443 |
if (!timeout && ast_exists_extension(c, c->context, dst_exten, 1, c->cid.cid_num)) /* Prepare the next cycle */ |
3416 |
set_ext_pri(c, dst_exten, 1); |
3444 |
set_ext_pri(c, dst_exten, 1); |
3417 |
else { |
3445 |
else { |
3418 |
/* No such extension */ |
3446 |
/* No such extension */ |
3419 |
if (!ast_strlen_zero(dst_exten)) { |
3447 |
if (!timeout && !ast_strlen_zero(dst_exten)) { |
3420 |
/* An invalid extension */ |
3448 |
/* An invalid extension */ |
3421 |
if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { |
3449 |
if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { |
3422 |
ast_verb(3, "Invalid extension '%s' in context '%s' on %s\n", dst_exten, c->context, c->name); |
3450 |
ast_verb(3, "Invalid extension '%s' in context '%s' on %s\n", dst_exten, c->context, c->name); |
Lines 6857-6862
Link Here
|
6857 |
return AST_PBX_KEEPALIVE; |
6885 |
return AST_PBX_KEEPALIVE; |
6858 |
} |
6886 |
} |
6859 |
|
6887 |
|
|
|
6888 |
static int pbx_builtin_incomplete(struct ast_channel *chan, void *data) |
6889 |
{ |
6890 |
char *options = data; |
6891 |
int answer = 1; |
6892 |
|
6893 |
/* Some channels can receive DTMF in unanswered state; some cannot */ |
6894 |
if (!ast_strlen_zero(options) && strchr(options, 'n')) { |
6895 |
answer = 0; |
6896 |
} |
6897 |
|
6898 |
/* If the channel is hungup, stop waiting */ |
6899 |
if (ast_check_hangup(chan)) { |
6900 |
return -1; |
6901 |
} else if (chan->_state != AST_STATE_UP && answer) { |
6902 |
__ast_answer(chan, 0); |
6903 |
} |
6904 |
|
6905 |
return AST_PBX_INCOMPLETE; |
6906 |
} |
6907 |
|
6860 |
AST_APP_OPTIONS(resetcdr_opts, { |
6908 |
AST_APP_OPTIONS(resetcdr_opts, { |
6861 |
AST_APP_OPTION('w', AST_CDR_FLAG_POSTED), |
6909 |
AST_APP_OPTION('w', AST_CDR_FLAG_POSTED), |
6862 |
AST_APP_OPTION('a', AST_CDR_FLAG_LOCKED), |
6910 |
AST_APP_OPTION('a', AST_CDR_FLAG_LOCKED), |