Episode 02 placed extensions 7101 and 7102 in training@default, reached through 7190 from a third registered test phone. This episode adds rotating offers, an agent break, a 20-second after-call interval and a pause after unanswered offers.
Use the same single FreeSWITCH instance and internal network. The module and 7190 dialplan already exist. The examples were checked against v1.10.12 source, the official template and current documentation; they have not been run on a live FS instance. CONF means the directory returned by eval {conf_dir}; confirm the domain with eval {domain}.
Separate registration, status and dispatch state
SIP registration describes the phone's login. Agent status expresses whether queue work is accepted; state tracks waiting, ringing and an active queue call. A registered 7101 can receive direct calls while agent7101 is On Break and skipped by the queue.
The queue strategy chooses among eligible agents. Agent timers determine when a person is eligible again. If the same agent belongs to several queues, its status and wrap-up interval affect those queues too.
Save the baseline and update the configuration
Back up CONF/autoload_configs/callcenter.conf.xml and record queue list, agent list, tier data and each agent's status. Pause test calls to 7190 and wait for the test queue and calls to clear. This complete file is for the isolated test setup. Merge only the relevant objects into an existing installation, preserving its settings and other queues.
<configuration name="callcenter.conf" description="Training dispatch">
<!-- 单机测试沿用默认状态库;保留现有生产settings -->
<settings/>
<queues>
<!-- 7190路由继续使用这个完整队列名 -->
<queue name="training@default">
<!-- 本期比较轮询,换策略只改这一项 -->
<param name="strategy" value="round-robin"/>
<!-- 沿用实例已有的等待音乐资源 -->
<param name="moh-sound" value="$${hold_music}"/>
<!-- 计分起点沿用上一期 -->
<param name="time-base-score" value="system"/>
<!-- 测试等待上限180秒,方便观察两次未接听 -->
<param name="max-wait-time" value="180"/>
<!-- 本期两名座席同层,不启用逐层等待 -->
<param name="tier-rules-apply" value="false"/>
<!-- 达到未接听上限后,将座席转为休息 -->
<param name="agent-no-answer-status" value="On Break"/>
</queue>
</queues>
<agents>
<!-- 7101的振铃上限15秒;整理20秒;两次未接后休息 -->
<agent name="agent7101" type="callback"
contact="[leg_timeout=15]user/7101@$${domain}"
status="Available" max-no-answer="2" wrap-up-time="20"
reject-delay-time="10" busy-delay-time="30"
no-answer-delay-time="20"/>
<!-- 7102使用相同时间规则,分机目标独立 -->
<agent name="agent7102" type="callback"
contact="[leg_timeout=15]user/7102@$${domain}"
status="Available" max-no-answer="2" wrap-up-time="20"
reject-delay-time="10" busy-delay-time="30"
no-answer-delay-time="20"/>
</agents>
<tiers>
<!-- 两名座席在同一层,便于比较轮询效果 -->
<tier agent="agent7101" queue="training@default" level="1" position="1"/>
<!-- position提供队列位置,不保证严格平均接通数 -->
<tier agent="agent7102" queue="training@default" level="1" position="2"/>
</tiers>
</configuration>
Compared with episode 02, this changes the strategy, total wait limit, wrap-up and unanswered threshold, and adds no-answer-delay-time and agent-no-answer-status. XML uses hyphenated names; some API keys use underscores.
Pick a strategy for the intended behavior
round-robin continues from the previous offered position and selects eligible agents in rotation. Breaks, busy conditions and wrap-up can skip someone. Strict alternation or equal answered totals are not acceptance criteria.
longest-idle-agent favors an eligible agent whose previous queue bridge ended earlier; position is only part of its ordering. top-down starts with tier order for each caller and continues when someone is unavailable. These describe routing preferences, not an unconditional guarantee of which phone rings.
ring-all offers a call to eligible agents concurrently and consumes multiple agent call legs. To compare it, change only strategy to ring-all and use the reload procedure below. Keep the timing settings unchanged during the comparison.
Both agents remain at level 1 with tier-rules-apply=false. Tiered routing also needs the tier-rule-wait-second family of settings. Setting level 2 alone does not promise escalation after a particular interval: tier eligibility, tier waits and the caller's overall wait limit interact.
Understand each timer and counter
The contact variable leg_timeout=15 limits the agent call attempt in seconds. It is not the lifetime of the customer call. max-wait-time=180 is the queue wait limit in seconds, about three minutes. The episode 02 dialplan ends the call after the application returns; this example adds no overflow destination.
wrap-up-time=20 is checked against the end of the queue bridge. An agent may still show Available and return to Waiting while the timer makes it ineligible. No literal Wrap Up state is required, and an offer is not guaranteed at precisely the twentieth second.
reject-delay-time=10, busy-delay-time=30 and no-answer-delay-time=20 delay another offer to that agent after the corresponding failure. They do not freeze the whole queue. A handset's reject button may produce busy or decline behavior; correlate the SIP response with the FS hangup cause.
max-no-answer=2 is an unanswered-attempt threshold, not a duration or a limit of two agents per caller. The relevant failure branch increments the counter; reaching the threshold changes status to the queue's agent-no-answer-status, here On Break. Busy, rejection and unregistered destinations have separate handling. Zero disables the count threshold rather than providing automatic recovery.
Apply the changes to running objects
Enter these commands individually in fs_cli while the test queue has no waiting callers or calls. queue reload rebuilds the queue object, so schedule it accordingly. Restarting the entire FS instance is unnecessary for this test.
reloadxml
callcenter_config queue reload training@default
callcenter_config agent reload agent7101
callcenter_config agent reload agent7102
callcenter_config tier reload training@default agent7101
callcenter_config tier reload training@default agent7102
callcenter_config queue list
callcenter_config queue list agents training@default
callcenter_config queue list tiers training@default
reloadxml refreshes XML; the remaining commands synchronize queue, agents and tiers. Inspect every response and the resulting lists. agent reload reapplies the XML status and parameters; tier reload can restore XML level and position. Establish ownership before mixing configuration files with a business application's runtime updates.
To change 7101's wrap-up temporarily through the API, use the following commands. The value is seconds. Inspect wrap_up_time in agent list and verify using test calls. Also persist wrap-up-time in XML if the change should survive later configuration loading.
callcenter_config agent set wrap_up_time agent7101 20
callcenter_config agent list
Put an agent on break and restore availability
Type the complete status directly into fs_cli without shell quotes. get status reports willingness to take work; get state reports dispatch progress.
callcenter_config agent set status agent7101 On Break
callcenter_config agent get status agent7101
callcenter_config agent set status agent7101 Available
callcenter_config agent get state agent7101
Logged Out also stops subsequent offers. Changing status is not an instruction to hang up an existing conversation. An offer already sent needs separate observation; change status with no ringing or active test call for this exercise. Let the module maintain state rather than forcing a database value that contradicts the live call.
Verify with three test sequences
With both agents Available, call 7190 sequentially and record offers, answers and end times. Observe rotation when both are eligible. Skipping an agent still in wrap-up is expected. Empty the queue before changing just the strategy for comparison.
For wrap-up, place 7102 On Break and let 7101 answer a queue call. End it and immediately call 7190 again. The caller should wait until 7101 is eligible after wrap-up. If 7102 remains Available, offering that second call to 7102 is valid and does not disprove 7101's timer.
For unanswered handling, keep 7102 on break and leave registered 7101 ringing without answering. Observe the attempt timeout, retry delay and counter. One waiting caller may generate several offers. Once the threshold is reached, verify On Break. After fixing the phone problem, moving from On Break to Available resets the relevant unanswered count in this version. Repeatedly setting an already Available agent to Available is not a general counter-reset procedure.
Diagnose common mismatches and roll back
If callers wait while agents show Available, inspect Waiting state, last bridge end, wrap_up_time, ready_time, tier membership and registration. Eligibility timers still matter.
If pressing reject does not reach the unanswered threshold, inspect the failure cause. Busy or rejection handling can apply its own delay instead of incrementing the unanswered counter. SIP response semantics
If XML says 20 seconds but the list says 10, confirm conf_dir, successful agent reload and possible business-API changes. If the list is correct but a phone rings immediately, identify the agent and whether the preceding call was actually a queue bridge.
If the same phone always rings first, inspect the running strategy, tiers and the other agent's break, wrap-up or retry conditions. A file alone does not show runtime eligibility.
Finish the test calls, restore the XML backup and run reloadxml plus the same targeted reload sequence. Restore each agent's recorded status, check parameters and tiers, then place one verification call. An XML backup does not automatically restore every runtime value.
Episode 04 will connect incoming numbers to extensions or queues through number matching, context and routing destinations.