--- asterisk-old/apps/app_queue.c.orig 2004-09-29 10:06:59.000000000 -0400 +++ asterisk/apps/app_queue.c 2004-11-26 14:16:19.000000000 -0500 @@ -167,6 +167,7 @@ int pos; /* Where we are in the queue */ int prio; /* Our priority */ int last_pos_said; /* Last position we told the user */ + time_t last_periodic_announce_time; /* The last time we played a periodic anouncement */ time_t last_pos; /* Last time we told the user their position */ int opos; /* Where we started in the queue */ int handled; /* Whether our call was handled */ @@ -194,6 +195,7 @@ char context[80]; /* Context for this queue */ int strategy; /* Queueing strategy */ int announcefrequency; /* How often to announce their position */ + int periodicannouncefrequency; /* How often to play periodic announcement */ int roundingseconds; /* How many seconds do we round to? */ int announceholdtime; /* When to announce holdtime: 0 = never, -1 = every announcement, 1 = only once */ int holdtime; /* Current avg holdtime for this queue, based on recursive boxcar filter */ @@ -211,6 +213,7 @@ char sound_lessthan[80]; /* Sound file: "less-than" (def. queue-lessthan) */ char sound_seconds[80]; /* Sound file: "seconds." (def. queue-seconds) */ char sound_thanks[80]; /* Sound file: "Thank you for your patience." (def. queue-thankyou) */ + char sound_periodicannounce[80];/* Sound file: Custom, no default */ int count; /* How many entries are in the queue */ int maxlen; /* Max number of entries in queue */ @@ -463,13 +466,6 @@ return (res>0); } -static void record_abandoned(struct queue_ent *qe) -{ - ast_mutex_lock(&qe->parent->lock); - qe->parent->callsabandoned++; - ast_mutex_unlock(&qe->parent->lock); -} - static void recalc_holdtime(struct queue_ent *qe) { int oldvalue, newvalue; @@ -709,6 +705,71 @@ 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); + } else { + res = 0; + } + + /*if (res) { + ast_log(LOG_WARNING, "ast_streamfile failed on %s \n", chan->name); + res = 0; + }*/ + + return res; +} + +static int say_periodic_announcement(struct queue_ent *qe) +{ + int res = 0; + time_t now; + + /* Get the current time */ + time(&now); + + /* Check to see if it is time to announce */ + if ( (now - qe->last_periodic_announce_time) < qe->parent->periodicannouncefrequency ) + return -1; + + /* Stop the music on hold so we can play our own file */ + ast_moh_stop(qe->chan); + + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Playing periodic announcement\n"); + + /* play the announcement */ + res = background_file(qe, qe->chan, qe->parent->sound_periodicannounce); + + /* Resume Music on Hold */ + ast_moh_start(qe->chan, qe->moh); + + /* update last_periodic_announce_time */ + qe->last_periodic_announce_time = now; + + return(res); +} + +static void record_abandoned(struct queue_ent *qe) +{ + ast_mutex_lock(&qe->parent->lock); + qe->parent->callsabandoned++; + ast_mutex_unlock(&qe->parent->lock); +} + + #define AST_MAX_WATCHERS 256 static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect_in, int *allowdisconnect_out, char *digit) @@ -923,8 +984,12 @@ if (qe->parent->announcefrequency && !ringing) say_position(qe); + /* Make a periodic announcement, if enabled */ + if (qe->parent->periodicannouncefrequency && !ringing) + res = say_periodic_announcement(qe); + /* Wait a second before checking again */ - res = ast_waitfordigit(qe->chan, RECHECK * 1000); + if (!res) res = ast_waitfordigit(qe->chan, RECHECK * 1000); if (res) break; } @@ -1597,6 +1662,7 @@ qe.prio = (int)prio; qe.last_pos_said = 0; qe.last_pos = 0; + qe.last_periodic_announce_time = time(NULL); if (!join_queue(queuename, &qe)) { ast_queue_log(queuename, chan->uniqueid, "NONE", "ENTERQUEUE", "%s|%s", url ? url : "", chan->callerid ? chan->callerid : ""); /* Start music on hold */ @@ -1651,6 +1717,15 @@ if (qe.parent->announcefrequency && !ringing) say_position(&qe); + /* Make a periodic announcement, if enabled */ + if (qe.parent->periodicannouncefrequency && !ringing) + res = say_periodic_announcement(&qe); + + if (res && valid_exit(&qe, res)) { + ast_queue_log(queuename, chan->uniqueid, "NONE", "EXITWITHKEY", "%c|%d", res, qe.pos); + break; + } + /* Try calling all queue members for 'timeout' seconds */ res = try_calling(&qe, options, announceoverride, url, &go_on); if (res) { @@ -1782,6 +1857,7 @@ q->callscompletedinsl = 0; q->servicelevel = 0; q->wrapuptime = 0; + q->periodicannouncefrequency = 0; free_members(q, 0); q->moh[0] = '\0'; q->announce[0] = '\0'; @@ -1795,6 +1871,7 @@ strncpy(q->sound_seconds, "queue-seconds", sizeof(q->sound_seconds) - 1); strncpy(q->sound_thanks, "queue-thankyou", sizeof(q->sound_thanks) - 1); strncpy(q->sound_lessthan, "queue-less-than", sizeof(q->sound_lessthan) - 1); + strncpy(q->sound_periodicannounce, "queue-periodic-announce", sizeof(q->sound_periodicannounce) - 1); prev = q->members; if (prev) { /* find the end of any dynamic members */ @@ -1869,6 +1946,10 @@ } } else if (!strcasecmp(var->name, "announce-holdtime")) { q->announceholdtime = (!strcasecmp(var->value,"once")) ? 1 : ast_true(var->value); + } else if (!strcasecmp(var->name, "periodic-announce")) { + strncpy(q->sound_periodicannounce, var->value, sizeof(q->sound_periodicannounce) - 1); + } else if (!strcasecmp(var->name, "periodic-announce-frequency")) { + q->periodicannouncefrequency = atoi(var->value); } else if (!strcasecmp(var->name, "retry")) { q->retry = atoi(var->value); } else if (!strcasecmp(var->name, "wrapuptime")) {