diff options
author | mmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-07-19 16:26:10 +0000 |
---|---|---|
committer | mmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-07-19 16:26:10 +0000 |
commit | c0affe8c5e62df5ed757dc8725c853ae4078a246 (patch) | |
tree | 027f6e2e93f2a97303517f1ff4184366342d7804 /apps/app_queue.c | |
parent | ff4d4acd9ca29349b55471369ecd6f6e08550086 (diff) |
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: http://svn.digium.com/svn/asterisk/branches/1.4@75969 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_queue.c')
-rw-r--r-- | apps/app_queue.c | 166 |
1 files changed, 70 insertions, 96 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c index c17c6026d..b4255a2a7 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 */ @@ -1230,9 +1231,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; @@ -1263,6 +1266,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; } @@ -1288,19 +1292,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 */ @@ -1322,35 +1326,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; } @@ -1361,10 +1365,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; @@ -1764,26 +1769,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; @@ -1808,7 +1793,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) @@ -2208,8 +2196,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; @@ -2427,6 +2419,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; } if (option_debug) ast_log(LOG_DEBUG, "%s: Nobody answered.\n", qe->chan->name); @@ -2705,7 +2699,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) @@ -3381,6 +3379,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, "")); @@ -3390,29 +3389,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", 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 @@ 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", 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,19 +3477,9 @@ 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", 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 @@ -3536,6 +3493,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; |