--- asterisk-orig/apps/app_queue.c.orig 2005-07-11 17:05:35.000000000 -0400 +++ asterisk/apps/app_queue.c 2005-07-12 15:41:14.000000000 -0400 @@ -237,6 +237,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 */ @@ -283,6 +284,7 @@ unsigned int maskmemberstatus:1; unsigned int realtime:1; 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 holdtime; /* Current avg holdtime, based on recursive boxcar filter */ int callscompleted; /* Number of queue calls completed */ @@ -299,6 +301,7 @@ 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_reporthold[80]; /* Sound file: "Hold time" (def. queue-reporthold) */ + char sound_periodicannounce[80];/* Sound file: Custom announce, no default */ int count; /* How many entries */ int maxlen; /* Max number of entries */ @@ -527,6 +530,7 @@ q->announce[0] = '\0'; q->context[0] = '\0'; q->monfmt[0] = '\0'; + q->periodicannouncefrequency = 0; ast_copy_string(q->sound_next, "queue-youarenext", sizeof(q->sound_next)); ast_copy_string(q->sound_thereare, "queue-thereare", sizeof(q->sound_thereare)); ast_copy_string(q->sound_calls, "queue-callswaiting", sizeof(q->sound_calls)); @@ -536,6 +540,7 @@ ast_copy_string(q->sound_thanks, "queue-thankyou", sizeof(q->sound_thanks)); ast_copy_string(q->sound_lessthan, "queue-less-than", sizeof(q->sound_lessthan)); ast_copy_string(q->sound_reporthold, "queue-reporthold", sizeof(q->sound_reporthold)); + ast_copy_string(q->sound_periodicannounce, "queue-periodic-announce", sizeof(q->sound_periodicannounce)); } static void clear_queue(struct ast_call_queue *q) @@ -609,6 +614,10 @@ q->announceholdtime = ANNOUNCEHOLDTIME_ALWAYS; else q->announceholdtime = 0; + } else if (!strcasecmp(param, "periodic-announce")) { + ast_copy_string(q->sound_periodicannounce, val, sizeof(q->sound_periodicannounce)); + } else if (!strcasecmp(param, "periodic-announce-frequency")) { + q->periodicannouncefrequency = atoi(val); } else if (!strcasecmp(param, "retry")) { q->retry = atoi(val); if (q->retry < 0) @@ -1093,13 +1102,6 @@ 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); -} - static void recalc_holdtime(struct queue_ent *qe) { int oldvalue, newvalue; @@ -1452,6 +1454,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 #define BUILD_WATCHERS do { \ @@ -1765,8 +1832,12 @@ if (res) break; + /* 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; } @@ -2735,6 +2806,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, &reason)) { ast_queue_log(queuename, chan->uniqueid, "NONE", "ENTERQUEUE", "%s|%s", url ? url : "", chan->cid.cid_num ? chan->cid.cid_num : ""); @@ -2796,6 +2868,15 @@ } makeannouncement = 1; + /* 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) {