mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-13 16:21:01 +00:00
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/branches/1.4@75969 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
162
apps/app_queue.c
162
apps/app_queue.c
@@ -296,6 +296,7 @@ struct queue_ent {
|
|||||||
char announce[80]; /*!< Announcement to play for member when call is answered */
|
char announce[80]; /*!< Announcement to play for member when call is answered */
|
||||||
char context[AST_MAX_CONTEXT]; /*!< Context when user exits queue */
|
char context[AST_MAX_CONTEXT]; /*!< Context when user exits queue */
|
||||||
char digits[AST_MAX_EXTENSION]; /*!< Digits entered while in 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 pos; /*!< Where we are in the queue */
|
||||||
int prio; /*!< Our priority */
|
int prio; /*!< Our priority */
|
||||||
int last_pos_said; /*!< Last position we told the user */
|
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;
|
int res;
|
||||||
|
|
||||||
ast_stopstream(chan);
|
ast_stopstream(chan);
|
||||||
|
|
||||||
res = ast_streamfile(chan, filename, chan->language);
|
res = ast_streamfile(chan, filename, chan->language);
|
||||||
if (!res)
|
if (!res)
|
||||||
res = ast_waitstream(chan, AST_DIGIT_ANY);
|
res = ast_waitstream(chan, AST_DIGIT_ANY);
|
||||||
|
|
||||||
ast_stopstream(chan);
|
ast_stopstream(chan);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@@ -1263,6 +1266,7 @@ static int valid_exit(struct queue_ent *qe, char digit)
|
|||||||
|
|
||||||
/* We have an exact match */
|
/* We have an exact match */
|
||||||
if (!ast_goto_if_exists(qe->chan, qe->context, qe->digits, 1)) {
|
if (!ast_goto_if_exists(qe->chan, qe->context, qe->digits, 1)) {
|
||||||
|
qe->valid_digits = 1;
|
||||||
/* Return 1 on a successful goto */
|
/* Return 1 on a successful goto */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1288,19 +1292,19 @@ static int say_position(struct queue_ent *qe)
|
|||||||
/* Say we're next, if we are */
|
/* Say we're next, if we are */
|
||||||
if (qe->pos == 1) {
|
if (qe->pos == 1) {
|
||||||
res = play_file(qe->chan, qe->parent->sound_next);
|
res = play_file(qe->chan, qe->parent->sound_next);
|
||||||
if (res && valid_exit(qe, res))
|
if (res)
|
||||||
goto playout;
|
goto playout;
|
||||||
else
|
else
|
||||||
goto posout;
|
goto posout;
|
||||||
} else {
|
} else {
|
||||||
res = play_file(qe->chan, qe->parent->sound_thereare);
|
res = play_file(qe->chan, qe->parent->sound_thereare);
|
||||||
if (res && valid_exit(qe, res))
|
if (res)
|
||||||
goto playout;
|
goto playout;
|
||||||
res = ast_say_number(qe->chan, qe->pos, AST_DIGIT_ANY, qe->chan->language, (char *) NULL); /* Needs gender */
|
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;
|
goto playout;
|
||||||
res = play_file(qe->chan, qe->parent->sound_calls);
|
res = play_file(qe->chan, qe->parent->sound_calls);
|
||||||
if (res && valid_exit(qe, res))
|
if (res)
|
||||||
goto playout;
|
goto playout;
|
||||||
}
|
}
|
||||||
/* Round hold time to nearest minute */
|
/* 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) &&
|
if ((avgholdmins+avgholdsecs) > 0 && (qe->parent->announceholdtime) &&
|
||||||
(!(qe->parent->announceholdtime == ANNOUNCEHOLDTIME_ONCE) && qe->last_pos)) {
|
(!(qe->parent->announceholdtime == ANNOUNCEHOLDTIME_ONCE) && qe->last_pos)) {
|
||||||
res = play_file(qe->chan, qe->parent->sound_holdtime);
|
res = play_file(qe->chan, qe->parent->sound_holdtime);
|
||||||
if (res && valid_exit(qe, res))
|
if (res)
|
||||||
goto playout;
|
goto playout;
|
||||||
|
|
||||||
if (avgholdmins > 0) {
|
if (avgholdmins > 0) {
|
||||||
if (avgholdmins < 2) {
|
if (avgholdmins < 2) {
|
||||||
res = play_file(qe->chan, qe->parent->sound_lessthan);
|
res = play_file(qe->chan, qe->parent->sound_lessthan);
|
||||||
if (res && valid_exit(qe, res))
|
if (res)
|
||||||
goto playout;
|
goto playout;
|
||||||
|
|
||||||
res = ast_say_number(qe->chan, 2, AST_DIGIT_ANY, qe->chan->language, NULL);
|
res = ast_say_number(qe->chan, 2, AST_DIGIT_ANY, qe->chan->language, NULL);
|
||||||
if (res && valid_exit(qe, res))
|
if (res)
|
||||||
goto playout;
|
goto playout;
|
||||||
} else {
|
} else {
|
||||||
res = ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, NULL);
|
res = ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, NULL);
|
||||||
if (res && valid_exit(qe, res))
|
if (res)
|
||||||
goto playout;
|
goto playout;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = play_file(qe->chan, qe->parent->sound_minutes);
|
res = play_file(qe->chan, qe->parent->sound_minutes);
|
||||||
if (res && valid_exit(qe, res))
|
if (res)
|
||||||
goto playout;
|
goto playout;
|
||||||
}
|
}
|
||||||
if (avgholdsecs>0) {
|
if (avgholdsecs>0) {
|
||||||
res = ast_say_number(qe->chan, avgholdsecs, AST_DIGIT_ANY, qe->chan->language, NULL);
|
res = ast_say_number(qe->chan, avgholdsecs, AST_DIGIT_ANY, qe->chan->language, NULL);
|
||||||
if (res && valid_exit(qe, res))
|
if (res)
|
||||||
goto playout;
|
goto playout;
|
||||||
|
|
||||||
res = play_file(qe->chan, qe->parent->sound_seconds);
|
res = play_file(qe->chan, qe->parent->sound_seconds);
|
||||||
if (res && valid_exit(qe, res))
|
if (res)
|
||||||
goto playout;
|
goto playout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1361,10 +1365,11 @@ posout:
|
|||||||
ast_verbose(VERBOSE_PREFIX_3 "Told %s in %s their queue position (which was %d)\n",
|
ast_verbose(VERBOSE_PREFIX_3 "Told %s in %s their queue position (which was %d)\n",
|
||||||
qe->chan->name, qe->parent->name, qe->pos);
|
qe->chan->name, qe->parent->name, qe->pos);
|
||||||
res = play_file(qe->chan, qe->parent->sound_thanks);
|
res = play_file(qe->chan, qe->parent->sound_thanks);
|
||||||
if (res && !valid_exit(qe, res))
|
|
||||||
res = 0;
|
|
||||||
|
|
||||||
playout:
|
playout:
|
||||||
|
if (res > 0 && !valid_exit(qe, res))
|
||||||
|
res = 0;
|
||||||
|
|
||||||
/* Set our last_pos indicators */
|
/* Set our last_pos indicators */
|
||||||
qe->last_pos = now;
|
qe->last_pos = now;
|
||||||
qe->last_pos_said = qe->pos;
|
qe->last_pos_said = qe->pos;
|
||||||
@@ -1764,26 +1769,6 @@ static int store_next(struct queue_ent *qe, struct callattempt *outgoing)
|
|||||||
return 0;
|
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)
|
static int say_periodic_announcement(struct queue_ent *qe)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
@@ -1808,7 +1793,10 @@ static int say_periodic_announcement(struct queue_ent *qe)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* play the announcement */
|
/* 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 */
|
/* Resume Music on Hold if the caller is going to stay in the queue */
|
||||||
if (!res)
|
if (!res)
|
||||||
@@ -2208,9 +2196,13 @@ static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *r
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* Wait a second before checking again */
|
/* Wait a second before checking again */
|
||||||
if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000)))
|
if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000))) {
|
||||||
|
if (res > 0 && !valid_exit(qe, res))
|
||||||
|
res = 0;
|
||||||
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -2427,6 +2419,8 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
|
|||||||
res = -1;
|
res = -1;
|
||||||
} else {
|
} else {
|
||||||
res = digit;
|
res = digit;
|
||||||
|
if (res > 0 && !valid_exit(qe, res))
|
||||||
|
res = 0;
|
||||||
}
|
}
|
||||||
if (option_debug)
|
if (option_debug)
|
||||||
ast_log(LOG_DEBUG, "%s: Nobody answered.\n", qe->chan->name);
|
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 */
|
/* Don't need to hold the lock while we setup the outgoing calls */
|
||||||
int retrywait = qe->parent->retry * 1000;
|
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)
|
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_pos = 0;
|
||||||
qe.last_periodic_announce_time = time(NULL);
|
qe.last_periodic_announce_time = time(NULL);
|
||||||
qe.last_periodic_announce_sound = 0;
|
qe.last_periodic_announce_sound = 0;
|
||||||
|
qe.valid_digits = 0;
|
||||||
if (!join_queue(args.queuename, &qe, &reason)) {
|
if (!join_queue(args.queuename, &qe, &reason)) {
|
||||||
ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ENTERQUEUE", "%s|%s", S_OR(args.url, ""),
|
ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ENTERQUEUE", "%s|%s", S_OR(args.url, ""),
|
||||||
S_OR(chan->cid.cid_num, ""));
|
S_OR(chan->cid.cid_num, ""));
|
||||||
@@ -3390,29 +3389,13 @@ check_turns:
|
|||||||
} else {
|
} else {
|
||||||
ast_moh_start(chan, qe.moh, NULL);
|
ast_moh_start(chan, qe.moh, NULL);
|
||||||
}
|
}
|
||||||
for (;;) {
|
|
||||||
/* This is the wait loop for callers 2 through maxlen */
|
|
||||||
|
|
||||||
|
/* This is the wait loop for callers 2 through maxlen */
|
||||||
res = wait_our_turn(&qe, ringing, &reason);
|
res = wait_our_turn(&qe, ringing, &reason);
|
||||||
/* If they hungup, return immediately */
|
if (res)
|
||||||
if (res < 0) {
|
goto stop;
|
||||||
/* Record this abandoned call */
|
|
||||||
record_abandoned(&qe);
|
/* always true... */
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
int makeannouncement = 0;
|
int makeannouncement = 0;
|
||||||
|
|
||||||
@@ -3435,38 +3418,22 @@ check_turns:
|
|||||||
|
|
||||||
if (makeannouncement) {
|
if (makeannouncement) {
|
||||||
/* Make a position announcement, if enabled */
|
/* Make a position announcement, if enabled */
|
||||||
if (qe.parent->announcefrequency && !ringing &&
|
if (qe.parent->announcefrequency && !ringing)
|
||||||
(res = say_position(&qe))) {
|
if ((res = say_position(&qe)))
|
||||||
ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHKEY", "%s|%d", qe.digits, qe.pos);
|
goto stop;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
makeannouncement = 1;
|
makeannouncement = 1;
|
||||||
|
|
||||||
/* Make a periodic announcement, if enabled */
|
/* Make a periodic announcement, if enabled */
|
||||||
if (qe.parent->periodicannouncefrequency && !ringing &&
|
if (qe.parent->periodicannouncefrequency && !ringing)
|
||||||
(res = say_periodic_announcement(&qe))) {
|
if ((res = say_periodic_announcement(&qe)))
|
||||||
ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHKEY", "%c|%d", res, qe.pos);
|
goto stop;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try calling all queue members for 'timeout' seconds */
|
/* Try calling all queue members for 'timeout' seconds */
|
||||||
res = try_calling(&qe, args.options, args.announceoverride, args.url, &go_on, args.agi);
|
res = try_calling(&qe, args.options, args.announceoverride, args.url, &go_on, args.agi);
|
||||||
if (res) {
|
if (res)
|
||||||
if (res < 0) {
|
goto stop;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
stat = get_member_status(qe.parent, qe.max_penalty);
|
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 */
|
/* OK, we didn't get anybody; wait for 'retry' seconds; may get a digit to exit with */
|
||||||
res = wait_a_bit(&qe);
|
res = wait_a_bit(&qe);
|
||||||
if (res < 0) {
|
if (res)
|
||||||
record_abandoned(&qe);
|
goto stop;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Since this is a priority queue and
|
/* Since this is a priority queue and
|
||||||
* it is not sure that we are still at the head
|
* 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 */
|
/* Don't allow return code > 0 */
|
||||||
if (res >= 0 && res != AST_PBX_KEEPALIVE) {
|
if (res >= 0 && res != AST_PBX_KEEPALIVE) {
|
||||||
res = 0;
|
res = 0;
|
||||||
|
Reference in New Issue
Block a user