diff options
author | Kevin P. Fleming <kpfleming@digium.com> | 2005-05-15 05:42:51 +0000 |
---|---|---|
committer | Kevin P. Fleming <kpfleming@digium.com> | 2005-05-15 05:42:51 +0000 |
commit | 131ace2d703bdf5150d0e8f1a866f52e48520aad (patch) | |
tree | ba5958409483bc33e370a5d5c8a1713b4669b2ff /apps | |
parent | ed223f7f905653a3c569b09a15d46639227d87a5 (diff) |
allow caller to exit during position announcement by pressing valid exit key (bug #3821, with mods)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5673 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps')
-rwxr-xr-x | apps/app_queue.c | 218 |
1 files changed, 125 insertions, 93 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c index 0b94257e7..e5cba679b 100755 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -516,9 +516,9 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result * /* No luck, join at the end of the queue */ if (!inserted) insert_entry(q, prev, qe, &pos); - strncpy(qe->moh, q->moh, sizeof(qe->moh) - 1); - strncpy(qe->announce, q->announce, sizeof(qe->announce) - 1); - strncpy(qe->context, q->context, sizeof(qe->context) - 1); + ast_copy_string(qe->moh, q->moh, sizeof(qe->moh)); + ast_copy_string(qe->announce, q->announce, sizeof(qe->announce)); + ast_copy_string(qe->context, q->context, sizeof(qe->context)); q->count++; res = 0; manager_event(EVENT_FLAG_CALL, "Join", @@ -589,19 +589,32 @@ static int play_file(struct ast_channel *chan, char *filename) res = ast_streamfile(chan, filename, chan->language); if (!res) - res = ast_waitstream(chan, ""); + res = ast_waitstream(chan, AST_DIGIT_ANY); else res = 0; - if (res) { - ast_log(LOG_WARNING, "ast_streamfile failed on %s \n", chan->name); - res = 0; - } ast_stopstream(chan); return res; } +static int valid_exit(struct queue_ent *qe, char digit) +{ + char tmp[2]; + + if (ast_strlen_zero(qe->context)) + return 0; + tmp[0] = digit; + tmp[1] = '\0'; + if (ast_exists_extension(qe->chan, qe->context, tmp, 1, qe->chan->cid.cid_num)) { + ast_copy_string(qe->chan->context, qe->context, sizeof(qe->chan->context)); + ast_copy_string(qe->chan->exten, tmp, sizeof(qe->chan->exten)); + qe->chan->priority = 0; + return 1; + } + return 0; +} + static int say_position(struct queue_ent *qe) { int res = 0, avgholdmins, avgholdsecs; @@ -610,21 +623,29 @@ static int say_position(struct queue_ent *qe) /* Check to see if this is ludicrous -- if we just announced position, don't do it again*/ time(&now); if ( (now - qe->last_pos) < 15 ) - return -1; + return 0; /* If either our position has changed, or we are over the freq timer, say position */ if ( (qe->last_pos_said == qe->pos) && ((now - qe->last_pos) < qe->parent->announcefrequency) ) - return -1; + return 0; ast_moh_stop(qe->chan); /* Say we're next, if we are */ if (qe->pos == 1) { - res += play_file(qe->chan, qe->parent->sound_next); - goto posout; + res = play_file(qe->chan, qe->parent->sound_next); + if (res && valid_exit(qe, res)) + goto playout; + else + goto posout; } else { - res += play_file(qe->chan, qe->parent->sound_thereare); - res += ast_say_number(qe->chan, qe->pos, AST_DIGIT_ANY, qe->chan->language, (char *) NULL); /* Needs gender */ - res += play_file(qe->chan, qe->parent->sound_calls); + res = play_file(qe->chan, qe->parent->sound_thereare); + 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)) + goto playout; + res = play_file(qe->chan, qe->parent->sound_calls); + if (res && valid_exit(qe, res)) + goto playout; } /* Round hold time to nearest minute */ avgholdmins = abs(( (qe->parent->holdtime + 30) - (now - qe->start) ) / 60); @@ -644,33 +665,54 @@ static int say_position(struct queue_ent *qe) supposed to be only once and we have already said it, say it */ 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(avgholdmins>0) { + res = play_file(qe->chan, qe->parent->sound_holdtime); + if (res && valid_exit(qe, res)) + goto playout; + + if (avgholdmins>0) { if (avgholdmins < 2) { - res += play_file(qe->chan, qe->parent->sound_lessthan); - res += ast_say_number(qe->chan, 2, AST_DIGIT_ANY, qe->chan->language, (char *)NULL); - } else - res += ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, (char*) NULL); - res += play_file(qe->chan, qe->parent->sound_minutes); + res = play_file(qe->chan, qe->parent->sound_lessthan); + if (res && valid_exit(qe, res)) + goto playout; + + res = ast_say_number(qe->chan, 2, AST_DIGIT_ANY, qe->chan->language, (char *)NULL); + if (res && valid_exit(qe, res)) + goto playout; + } else { + res = ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, (char*) NULL); + if (res && valid_exit(qe, res)) + goto playout; + } + + res = play_file(qe->chan, qe->parent->sound_minutes); + if (res && valid_exit(qe, res)) + goto playout; } - if(avgholdsecs>0) { - res += ast_say_number(qe->chan, avgholdsecs, AST_DIGIT_ANY, qe->chan->language, (char*) NULL); - res += play_file(qe->chan, qe->parent->sound_seconds); + if (avgholdsecs>0) { + res = ast_say_number(qe->chan, avgholdsecs, AST_DIGIT_ANY, qe->chan->language, (char*) NULL); + if (res && valid_exit(qe, res)) + goto playout; + + res = play_file(qe->chan, qe->parent->sound_seconds); + if (res && valid_exit(qe, res)) + goto playout; } } - posout: + posout: + if (option_verbose > 2) + 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); + + playout: /* Set our last_pos indicators */ qe->last_pos = now; qe->last_pos_said = qe->pos; - - if (option_verbose > 2) - 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); ast_moh_start(qe->chan, qe->moh); - return (res>0); + return res; } static void record_abandoned(struct queue_ent *qe) @@ -871,7 +913,7 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp, int *busies) return 0; } - strncpy(tech, tmp->interface, sizeof(tech) - 1); + ast_copy_string(tech, tmp->interface, sizeof(tech)); if ((location = strchr(tech, '/'))) *location++ = '\0'; else @@ -1033,23 +1075,6 @@ static int store_next(struct queue_ent *qe, struct localuser *outgoing) return 0; } -static int valid_exit(struct queue_ent *qe, char digit) -{ - char tmp[2]; - - if (ast_strlen_zero(qe->context)) - return 0; - tmp[0] = digit; - tmp[1] = '\0'; - if (ast_exists_extension(qe->chan, qe->context, tmp, 1, qe->chan->cid.cid_num)) { - strncpy(qe->chan->context, qe->context, sizeof(qe->chan->context) - 1); - strncpy(qe->chan->exten, tmp, sizeof(qe->chan->exten) - 1); - qe->chan->priority = 0; - return 1; - } - return 0; -} - #define AST_MAX_WATCHERS 256 #define BUILD_WATCHERS do { \ @@ -1122,7 +1147,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser char tmpchan[256]=""; char *stuff; char *tech; - strncpy(tmpchan, o->chan->call_forward, sizeof(tmpchan) - 1); + ast_copy_string(tmpchan, o->chan->call_forward, sizeof(tmpchan)); if ((stuff = strchr(tmpchan, '/'))) { *stuff = '\0'; stuff++; @@ -1161,7 +1186,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser if (!o->chan->cid.cid_name) ast_log(LOG_WARNING, "Out of memory\n"); } - strncpy(o->chan->accountcode, in->accountcode, sizeof(o->chan->accountcode) - 1); + ast_copy_string(o->chan->accountcode, in->accountcode, sizeof(o->chan->accountcode)); o->chan->cdrflags = in->cdrflags; if (in->cid.cid_ani) { @@ -1354,7 +1379,9 @@ static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *r /* Make a position announcement, if enabled */ if (qe->parent->announcefrequency && !ringing) - say_position(qe); + res = say_position(qe); + if (res) + break; /* Wait a second before checking again */ res = ast_waitfordigit(qe->chan, RECHECK * 1000); @@ -1494,7 +1521,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce if (option_debug) ast_log(LOG_DEBUG, "%s is trying to call a queue member.\n", qe->chan->name); - strncpy(queuename, qe->parent->name, sizeof(queuename) - 1); + ast_copy_string(queuename, qe->parent->name, sizeof(queuename)); time(&now); cur = qe->parent->members; if (!ast_strlen_zero(qe->announce)) @@ -1523,7 +1550,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce tmp->member = cur; /* Never directly dereference! Could change on reload */ tmp->oldstatus = cur->status; tmp->lastcall = cur->lastcall; - strncpy(tmp->interface, cur->interface, sizeof(tmp->interface)-1); + ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface)-1); /* If we're dialing by extension, look at the extension to know what to dial */ if ((newnum = strstr(tmp->interface, "/BYEXTENSION"))) { newnum++; @@ -1690,8 +1717,8 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce "Holdtime: %ld\r\n", queuename, qe->chan->uniqueid, peer->name, member->interface, (long)time(NULL) - qe->start); - strncpy(oldcontext, qe->chan->context, sizeof(oldcontext) - 1); - strncpy(oldexten, qe->chan->exten, sizeof(oldexten) - 1); + ast_copy_string(oldcontext, qe->chan->context, sizeof(oldcontext)); + ast_copy_string(oldexten, qe->chan->exten, sizeof(oldexten)); time(&callstart); bridge = ast_bridge_call(qe->chan,peer, &bridge_config); @@ -1772,7 +1799,7 @@ static struct member *create_queue_node(char *interface, int penalty, int paused memset(cur, 0, sizeof(struct member)); cur->penalty = penalty; cur->paused = paused; - strncpy(cur->interface, interface, sizeof(cur->interface) - 1); + ast_copy_string(cur->interface, interface, sizeof(cur->interface)); if (!strchr(cur->interface, '/')) ast_log(LOG_WARNING, "No location at interface '%s'\n", interface); cur->status = ast_device_state(interface); @@ -2159,7 +2186,7 @@ static int rqm_exec(struct ast_channel *chan, void *data) interface++; } else { - strncpy(tmpchan, chan->name, sizeof(tmpchan) - 1); + ast_copy_string(tmpchan, chan->name, sizeof(tmpchan)); interface = strrchr(tmpchan, '-'); if (interface) *interface = '\0'; @@ -2230,7 +2257,7 @@ static int aqm_exec(struct ast_channel *chan, void *data) } } if (!interface || ast_strlen_zero(interface)) { - strncpy(tmpchan, chan->name, sizeof(tmpchan) - 1); + ast_copy_string(tmpchan, chan->name, sizeof(tmpchan)); interface = strrchr(tmpchan, '-'); if (interface) *interface = '\0'; @@ -2303,7 +2330,7 @@ static int queue_exec(struct ast_channel *chan, void *data) qe.start = time(NULL); /* Parse our arguments XXX Check for failure XXX */ - strncpy(info, (char *) data, sizeof(info) - 1); + ast_copy_string(info, (char *) data, sizeof(info)); queuename = strsep(&info_ptr, "|"); options = strsep(&info_ptr, "|"); url = strsep(&info_ptr, "|"); @@ -2396,7 +2423,12 @@ check_turns: if (makeannouncement) { /* Make a position announcement, if enabled */ if (qe.parent->announcefrequency && !ringing) - say_position(&qe); + res = say_position(&qe); + if (res && valid_exit(&qe, res)) { + ast_queue_log(queuename, chan->uniqueid, "NONE", "EXITWITHKEY", "%c|%d", res, qe.pos); + break; + } + } makeannouncement = 1; @@ -2534,7 +2566,7 @@ static void reload_queues(void) /* Initialize it */ memset(q, 0, sizeof(struct ast_call_queue)); ast_mutex_init(&q->lock); - strncpy(q->name, cat, sizeof(q->name) - 1); + ast_copy_string(q->name, cat, sizeof(q->name)); new = 1; } else new = 0; } else @@ -2561,15 +2593,15 @@ static void reload_queues(void) q->announce[0] = '\0'; q->context[0] = '\0'; q->monfmt[0] = '\0'; - strncpy(q->sound_next, "queue-youarenext", sizeof(q->sound_next) - 1); - strncpy(q->sound_thereare, "queue-thereare", sizeof(q->sound_thereare) - 1); - strncpy(q->sound_calls, "queue-callswaiting", sizeof(q->sound_calls) - 1); - strncpy(q->sound_holdtime, "queue-holdtime", sizeof(q->sound_holdtime) - 1); - strncpy(q->sound_minutes, "queue-minutes", sizeof(q->sound_minutes) - 1); - 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_reporthold, "queue-reporthold", sizeof(q->sound_reporthold) - 1); + 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)); + ast_copy_string(q->sound_holdtime, "queue-holdtime", sizeof(q->sound_holdtime)); + ast_copy_string(q->sound_minutes, "queue-minutes", sizeof(q->sound_minutes)); + ast_copy_string(q->sound_seconds, "queue-seconds", sizeof(q->sound_seconds)); + 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)); prev = q->members; if (prev) { /* find the end of any dynamic members */ @@ -2583,7 +2615,7 @@ static void reload_queues(void) cur = malloc(sizeof(struct member)); if (cur) { memset(cur, 0, sizeof(struct member)); - strncpy(cur->interface, var->value, sizeof(cur->interface) - 1); + ast_copy_string(cur->interface, var->value, sizeof(cur->interface)); if ((tmp = strchr(cur->interface, ','))) { *tmp = '\0'; tmp++; @@ -2600,35 +2632,35 @@ static void reload_queues(void) prev = cur; } } else if (!strcasecmp(var->name, "music") || !strcasecmp(var->name, "musiconhold")) { - strncpy(q->moh, var->value, sizeof(q->moh) - 1); + ast_copy_string(q->moh, var->value, sizeof(q->moh)); } else if (!strcasecmp(var->name, "announce")) { - strncpy(q->announce, var->value, sizeof(q->announce) - 1); + ast_copy_string(q->announce, var->value, sizeof(q->announce)); } else if (!strcasecmp(var->name, "context")) { - strncpy(q->context, var->value, sizeof(q->context) - 1); + ast_copy_string(q->context, var->value, sizeof(q->context)); } else if (!strcasecmp(var->name, "timeout")) { q->timeout = atoi(var->value); } else if (!strcasecmp(var->name, "monitor-join")) { q->monjoin = ast_true(var->value); } else if (!strcasecmp(var->name, "monitor-format")) { - strncpy(q->monfmt, var->value, sizeof(q->monfmt) - 1); + ast_copy_string(q->monfmt, var->value, sizeof(q->monfmt)); } else if (!strcasecmp(var->name, "queue-youarenext")) { - strncpy(q->sound_next, var->value, sizeof(q->sound_next) - 1); + ast_copy_string(q->sound_next, var->value, sizeof(q->sound_next)); } else if (!strcasecmp(var->name, "queue-thereare")) { - strncpy(q->sound_thereare, var->value, sizeof(q->sound_thereare) - 1); + ast_copy_string(q->sound_thereare, var->value, sizeof(q->sound_thereare)); } else if (!strcasecmp(var->name, "queue-callswaiting")) { - strncpy(q->sound_calls, var->value, sizeof(q->sound_calls) - 1); + ast_copy_string(q->sound_calls, var->value, sizeof(q->sound_calls)); } else if (!strcasecmp(var->name, "queue-holdtime")) { - strncpy(q->sound_holdtime, var->value, sizeof(q->sound_holdtime) - 1); + ast_copy_string(q->sound_holdtime, var->value, sizeof(q->sound_holdtime)); } else if (!strcasecmp(var->name, "queue-minutes")) { - strncpy(q->sound_minutes, var->value, sizeof(q->sound_minutes) - 1); + ast_copy_string(q->sound_minutes, var->value, sizeof(q->sound_minutes)); } else if (!strcasecmp(var->name, "queue-seconds")) { - strncpy(q->sound_seconds, var->value, sizeof(q->sound_seconds) - 1); + ast_copy_string(q->sound_seconds, var->value, sizeof(q->sound_seconds)); } else if (!strcasecmp(var->name, "queue-lessthan")) { - strncpy(q->sound_lessthan, var->value, sizeof(q->sound_lessthan) - 1); + ast_copy_string(q->sound_lessthan, var->value, sizeof(q->sound_lessthan)); } else if (!strcasecmp(var->name, "queue-thankyou")) { - strncpy(q->sound_thanks, var->value, sizeof(q->sound_thanks) - 1); + ast_copy_string(q->sound_thanks, var->value, sizeof(q->sound_thanks)); } else if (!strcasecmp(var->name, "queue-reporthold")) { - strncpy(q->sound_reporthold, var->value, sizeof(q->sound_reporthold) - 1); + ast_copy_string(q->sound_reporthold, var->value, sizeof(q->sound_reporthold)); } else if (!strcasecmp(var->name, "announce-frequency")) { q->announcefrequency = atoi(var->value); } else if (!strcasecmp(var->name, "announce-round-seconds")) { @@ -2740,22 +2772,22 @@ static char *status2str(int status, char *buf, int buflen) { switch(status) { case AST_DEVICE_UNKNOWN: - strncpy(buf, "unknown", buflen - 1); + ast_copy_string(buf, "unknown", buflen); break; case AST_DEVICE_NOT_INUSE: - strncpy(buf, "notinuse", buflen - 1); + ast_copy_string(buf, "notinuse", buflen); break; case AST_DEVICE_INUSE: - strncpy(buf, "inuse", buflen - 1); + ast_copy_string(buf, "inuse", buflen); break; case AST_DEVICE_BUSY: - strncpy(buf, "busy", buflen - 1); + ast_copy_string(buf, "busy", buflen); break; case AST_DEVICE_INVALID: - strncpy(buf, "invalid", buflen - 1); + ast_copy_string(buf, "invalid", buflen); break; case AST_DEVICE_UNAVAILABLE: - strncpy(buf, "unavailable", buflen - 1); + ast_copy_string(buf, "unavailable", buflen); break; default: snprintf(buf, buflen, "unknown status %d", status); @@ -2804,7 +2836,7 @@ static int __queues_show(int fd, int argc, char **argv, int queue_show) if (q->maxlen) snprintf(max, sizeof(max), "%d", q->maxlen); else - strncpy(max, "unlimited", sizeof(max) - 1); + ast_copy_string(max, "unlimited", sizeof(max)); sl = 0; if(q->callscompleted > 0) sl = 100*((float)q->callscompletedinsl/(float)q->callscompleted); @@ -2827,7 +2859,7 @@ static int __queues_show(int fd, int argc, char **argv, int queue_show) snprintf(calls, sizeof(calls), " has taken %d calls (last was %ld secs ago)", mem->calls, (long)(time(NULL) - mem->lastcall)); } else - strncpy(calls, " has taken no calls yet", sizeof(calls) - 1); + ast_copy_string(calls, " has taken no calls yet", sizeof(calls)); ast_cli(fd, " %s%s%s\n", mem->interface, max, calls); } } else |