From 3dcce46f698d630ecba1bc29c74a43e0d4f59ac5 Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Thu, 19 Jul 2007 16:29:51 +0000 Subject: [PATCH] Merged revisions 75969 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r75969 | mmichelson | 2007-07-19 11:26:10 -0500 (Thu, 19 Jul 2007) | 10 lines Changes in handling return values of several functions in app_queue. This all started as a fix for issue #10008 but now includes all of the following changes: 1. Simplifying the code to handle positive return values from ast API calls. 2. Removing the background_file function. 3. The fix for issue #10008 (closes issue #10008, reported and patched by dimas) ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@75977 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_queue.c | 172 +++++++++++++++++++---------------------------- 1 file changed, 69 insertions(+), 103 deletions(-) diff --git a/apps/app_queue.c b/apps/app_queue.c index 56f1f35948..5cc931bbf3 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -296,6 +296,7 @@ struct queue_ent { 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 */ @@ -1322,9 +1323,11 @@ static int play_file(struct ast_channel *chan, char *filename) 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; @@ -1355,6 +1358,7 @@ static int valid_exit(struct queue_ent *qe, char digit) /* 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; } @@ -1380,19 +1384,19 @@ static int say_position(struct queue_ent *qe) /* 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 */ @@ -1414,35 +1418,35 @@ static int say_position(struct queue_ent *qe) 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; } @@ -1453,10 +1457,11 @@ posout: 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; @@ -1851,26 +1856,6 @@ static int store_next(struct queue_ent *qe, struct callattempt *outgoing) 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; @@ -1895,7 +1880,10 @@ static int say_periodic_announcement(struct queue_ent *qe) } /* 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) @@ -2296,8 +2284,12 @@ static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *r 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; @@ -2547,6 +2539,8 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce res = -1; } else { res = digit; + if (res > 0 && !valid_exit(qe, res)) + res = 0; } ast_debug(1, "%s: Nobody answered.\n", qe->chan->name); } else { /* peer is valid */ @@ -2911,7 +2905,11 @@ static int wait_a_bit(struct queue_ent *qe) /* 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) @@ -3514,6 +3512,7 @@ static int queue_exec(struct ast_channel *chan, void *data) 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, "")); @@ -3523,30 +3522,13 @@ check_turns: } 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|%d|%ld", - qe.digits, qe.pos, qe.opos, (long) time(NULL) - qe.start); - 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; @@ -3570,43 +3552,22 @@ check_turns: 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|%d|%ld", - qe.digits, qe.pos, qe.opos, (long) time(NULL) - qe.start); - 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", "%s|%d|%d|%ld", - qe.digits, qe.pos, qe.opos, (long) time(NULL) - qe.start); - 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, args.macro, args.gosub); - 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 (qcontinue) { - reason = QUEUE_CONTINUE; - res = 0; - } - } else if (valid_exit(&qe, res)) { - ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHKEY", "%s|%d|%d|%ld", - qe.digits, qe.pos, qe.opos, (long) time(NULL) - qe.start); - } - break; - } + if (res) + goto stop; stat = get_member_status(qe.parent, qe.max_penalty); @@ -3656,20 +3617,8 @@ check_turns: /* 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|%d|%ld", - qe.digits, qe.pos, qe.opos, (long) time(NULL) - qe.start); - break; - } + if (res) + goto stop; /* Since this is a priority queue and * it is not sure that we are still at the head @@ -3681,6 +3630,23 @@ check_turns: } } } + +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;