Index: apps/app_queue.c =================================================================== --- apps/app_queue.c (revision 75523) +++ apps/app_queue.c (working copy) @@ -296,6 +296,7 @@ char announce[80]; /*!< Announcement to play for member when call is answered */ char context[AST_MAX_CONTEXT]; /*!< Context when user exits queue */ char digits[AST_MAX_EXTENSION]; /*!< Digits entered while in queue */ + int valid_digits; /*!< Digits entered correspond to valid extension. Exited */ int pos; /*!< Where we are in the queue */ int prio; /*!< Our priority */ int last_pos_said; /*!< Last position we told the user */ @@ -1230,9 +1231,11 @@ int res; ast_stopstream(chan); + res = ast_streamfile(chan, filename, chan->language); if (!res) res = ast_waitstream(chan, AST_DIGIT_ANY); + ast_stopstream(chan); return res; @@ -1263,6 +1266,7 @@ /* We have an exact match */ if (!ast_goto_if_exists(qe->chan, qe->context, qe->digits, 1)) { + qe->valid_digits = 1; /* Return 1 on a successful goto */ return 1; } @@ -1288,19 +1292,19 @@ /* Say we're next, if we are */ if (qe->pos == 1) { res = play_file(qe->chan, qe->parent->sound_next); - if (res && valid_exit(qe, res)) + if (res) goto playout; else goto posout; } else { res = play_file(qe->chan, qe->parent->sound_thereare); - if (res && valid_exit(qe, res)) + if (res) goto playout; res = ast_say_number(qe->chan, qe->pos, AST_DIGIT_ANY, qe->chan->language, (char *) NULL); /* Needs gender */ - if (res && valid_exit(qe, res)) + if (res) goto playout; res = play_file(qe->chan, qe->parent->sound_calls); - if (res && valid_exit(qe, res)) + if (res) goto playout; } /* Round hold time to nearest minute */ @@ -1322,35 +1326,35 @@ if ((avgholdmins+avgholdsecs) > 0 && (qe->parent->announceholdtime) && (!(qe->parent->announceholdtime == ANNOUNCEHOLDTIME_ONCE) && qe->last_pos)) { res = play_file(qe->chan, qe->parent->sound_holdtime); - if (res && valid_exit(qe, res)) + if (res) goto playout; if (avgholdmins > 0) { if (avgholdmins < 2) { res = play_file(qe->chan, qe->parent->sound_lessthan); - if (res && valid_exit(qe, res)) + if (res) goto playout; res = ast_say_number(qe->chan, 2, AST_DIGIT_ANY, qe->chan->language, NULL); - if (res && valid_exit(qe, res)) + if (res) goto playout; } else { res = ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, NULL); - if (res && valid_exit(qe, res)) + if (res) goto playout; } res = play_file(qe->chan, qe->parent->sound_minutes); - if (res && valid_exit(qe, res)) + if (res) goto playout; } if (avgholdsecs>0) { res = ast_say_number(qe->chan, avgholdsecs, AST_DIGIT_ANY, qe->chan->language, NULL); - if (res && valid_exit(qe, res)) + if (res) goto playout; res = play_file(qe->chan, qe->parent->sound_seconds); - if (res && valid_exit(qe, res)) + if (res) goto playout; } @@ -1361,10 +1365,11 @@ ast_verbose(VERBOSE_PREFIX_3 "Told %s in %s their queue position (which was %d)\n", qe->chan->name, qe->parent->name, qe->pos); res = play_file(qe->chan, qe->parent->sound_thanks); - if (res && !valid_exit(qe, res)) - res = 0; playout: + if (res > 0 && !valid_exit(qe, res)) + res = 0; + /* Set our last_pos indicators */ qe->last_pos = now; qe->last_pos_said = qe->pos; @@ -1764,26 +1769,6 @@ return 0; } -static int background_file(struct queue_ent *qe, struct ast_channel *chan, char *filename) -{ - int res; - - ast_stopstream(chan); - res = ast_streamfile(chan, filename, chan->language); - - if (!res) { - /* Wait for a keypress */ - res = ast_waitstream(chan, AST_DIGIT_ANY); - if (res < 0 || !valid_exit(qe, res)) - res = 0; - - /* Stop playback */ - ast_stopstream(chan); - } - - return res; -} - static int say_periodic_announcement(struct queue_ent *qe) { int res = 0; @@ -1808,8 +1793,11 @@ } /* play the announcement */ - res = background_file(qe, qe->chan, qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]); + res = play_file(qe->chan, qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]); + if (res > 0 && !valid_exit(qe, res)) + res = 0; + /* Resume Music on Hold if the caller is going to stay in the queue */ if (!res) ast_moh_start(qe->chan, qe->moh, NULL); @@ -2208,8 +2196,12 @@ break; /* Wait a second before checking again */ - if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000))) - break; + if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000))) { + if (res > 0 && !valid_exit(qe, res)) + res = 0; + else + break; + } } return res; @@ -2427,6 +2419,8 @@ res = -1; } else { res = digit; + if (res > 0 && !valid_exit(qe, res)) + res = 0; } if (option_debug) ast_log(LOG_DEBUG, "%s: Nobody answered.\n", qe->chan->name); @@ -2705,7 +2699,11 @@ /* Don't need to hold the lock while we setup the outgoing calls */ int retrywait = qe->parent->retry * 1000; - return ast_waitfordigit(qe->chan, retrywait); + int res = ast_waitfordigit(qe->chan, retrywait); + if (res > 0 && !valid_exit(qe, res)) + res = 0; + + return res; } static struct member *interface_exists(struct call_queue *q, const char *interface) @@ -3381,6 +3379,7 @@ qe.last_pos = 0; qe.last_periodic_announce_time = time(NULL); qe.last_periodic_announce_sound = 0; + qe.valid_digits = 0; if (!join_queue(args.queuename, &qe, &reason)) { ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ENTERQUEUE", "%s|%s", S_OR(args.url, ""), S_OR(chan->cid.cid_num, "")); @@ -3390,29 +3389,13 @@ } else { ast_moh_start(chan, qe.moh, NULL); } - for (;;) { - /* This is the wait loop for callers 2 through maxlen */ - res = wait_our_turn(&qe, ringing, &reason); - /* If they hungup, return immediately */ - if (res < 0) { - /* Record this abandoned call */ - record_abandoned(&qe); - ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ABANDON", "%d|%d|%ld", - qe.pos, qe.opos, (long) time(NULL) - qe.start); - if (option_verbose > 2) { - ast_verbose(VERBOSE_PREFIX_3 "User disconnected from queue %s while waiting their turn\n", args.queuename); - } - res = -1; - break; - } - if (!res) - break; - if (valid_exit(&qe, res)) { - ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHKEY", "%s|%d", qe.digits, qe.pos); - break; - } - } + /* This is the wait loop for callers 2 through maxlen */ + res = wait_our_turn(&qe, ringing, &reason); + if (res) + goto stop; + + /* always true... */ if (!res) { int makeannouncement = 0; @@ -3435,38 +3418,22 @@ if (makeannouncement) { /* Make a position announcement, if enabled */ - if (qe.parent->announcefrequency && !ringing && - (res = say_position(&qe))) { - ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHKEY", "%s|%d", qe.digits, qe.pos); - break; - } + if (qe.parent->announcefrequency && !ringing) + if ((res = say_position(&qe))) + goto stop; } makeannouncement = 1; /* Make a periodic announcement, if enabled */ - if (qe.parent->periodicannouncefrequency && !ringing && - (res = say_periodic_announcement(&qe))) { - ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHKEY", "%c|%d", res, qe.pos); - break; - } + if (qe.parent->periodicannouncefrequency && !ringing) + if ((res = say_periodic_announcement(&qe))) + goto stop; /* Try calling all queue members for 'timeout' seconds */ res = try_calling(&qe, args.options, args.announceoverride, args.url, &go_on, args.agi); - if (res) { - if (res < 0) { - if (!qe.handled) { - record_abandoned(&qe); - ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ABANDON", - "%d|%d|%ld", qe.pos, qe.opos, - (long) time(NULL) - qe.start); - } - } else if (valid_exit(&qe, res)) { - ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHKEY", - "%s|%d", qe.digits, qe.pos); - } - break; - } + if (res) + goto stop; stat = get_member_status(qe.parent, qe.max_penalty); @@ -3510,20 +3477,10 @@ /* OK, we didn't get anybody; wait for 'retry' seconds; may get a digit to exit with */ res = wait_a_bit(&qe); - if (res < 0) { - record_abandoned(&qe); - ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ABANDON", "%d|%d|%ld", qe.pos, qe.opos, (long)time(NULL) - qe.start); - if (option_verbose > 2) { - ast_verbose(VERBOSE_PREFIX_3 "User disconnected from queue %s when they almost made it\n", args.queuename); - } - res = -1; - break; - } - if (res && valid_exit(&qe, res)) { - ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHKEY", "%s|%d", qe.digits, qe.pos); - break; - } + if (res) + goto stop; + /* Since this is a priority queue and * it is not sure that we are still at the head * of the queue, go and check for our turn again. @@ -3536,6 +3493,23 @@ } } } + +stop: + if (res) { + if (res < 0) { + if (!qe.handled) { + record_abandoned(&qe); + ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ABANDON", + "%d|%d|%ld", qe.pos, qe.opos, + (long) time(NULL) - qe.start); + } + res = -1; + } else if (qe.valid_digits) { + ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHKEY", + "%s|%d", qe.digits, qe.pos); + } + } + /* Don't allow return code > 0 */ if (res >= 0 && res != AST_PBX_KEEPALIVE) { res = 0;