Ringinuse not respecting device_state_busy_at

Using realtime configuration as below:

Queue:

name timeout ringinuse retry autopause strategy joinempty timeoutrestart
Support 20 yes 10 no ringall yes yes

Endpoint:

id transport aors auth context disallow allow send_pai callerid inband_progress device_state_busy_at dtls_auto_generate_cert webrtc
1004 transport-wss 1004 1004 internal all opus,alaw yes Flamur Dervishi <1004> yes 2 yes yes

In the Queue configuration we are using the option ringinuse=yes and in the endpoint configuration device_state_busy_at=2.

Reading queues.conf option descriptions:
; If you want the queue to avoid sending calls to members whose devices are
; known to be ‘in use’ (via the channel driver supporting that device state)
; uncomment this option. This can be controlled on a per member basis by
; setting ‘ringinuse’ on that member. This can be done in the member definition,
; in the ‘ringinuse’ field on a realtime member, via the QUEUE_MEMBER dialplan
; function, or with CLI/AMI. By default, the per member value will be the same
; as the queue’s ringinuse value if it isn’t set on the member deliberately.
; (Note: only the SIP channel driver currently is able to report ‘in use’.)
; ringinuse = no

We noticed that the Busy device state seems to be considered as ‘In use’ device state.
So we would expect that ‘ringinuse’ option would respect the ‘device_state_busy_at’ when deciding to pass a call through or not.

As workaround, we used Local channels as interface in the queue to manage the call from the dialplan by checking the device state.

Is this the normal behaviour of these 2 options or are we missing something ?

Have you confirmed the state of the underlying endpoint is what you expect at the time? What is the output of “queue show”? If you don’t use realtime does that alter things?

The state of Endpoint is reflected correctly to ‘Busy’ after ‘device_state_busy_at’ is reached:

Proof Fr has 0 calls (max unlimited) in ‘ringall’ strategy (17s holdtime, 18s talktime), W:0, C:4, A:13, SL:0.0%, SL2:0.0% within 0s
Members:
Flamur Dervishi (PJSIP/1004) (ringinuse enabled) (dynamic) (Busy) has taken 1 calls (last was 131 secs ago)
No Callers

The situation is the same by using dynamic or static members.

Actually, reading back you haven’t actually stated what “not respecting” means with your given configuration. What is actually happening?

Is it not ringing and you expect it to? If so you may find that turning on core debug and looking at the debug messages output by app_queue may provide insight.

With the ‘ringinuse’ option set to ‘yes’ and the ‘device_state_busy_at’ set to ‘2’, we would expect that after the endpoint will have received the 2nd call, it’s state should be ‘Busy’ and it is indeed.

We expect that if a 3rd call is in place, it should only be queued and not distributed to this endpoint as it’s busy limit is reached and the device state is ‘Busy’ but the call goes through.

The “ringinuse” option when set to “yes” will still distribute calls even when busy[1].

[1] https://github.com/asterisk/asterisk/blob/master/apps/app_queue.c#L2476

1 Like

I’d agree with the OP that that is not the behaviour that I would have expected.

1 Like

Alas, I can only state how it is and has been. It’s also not something that I would see changing without an option to enable it. A behavior change like that for people who have relied on it and used it for years would be… unacceptable.

Meanwhile the solution we tried:

static int is_member_available(struct call_queue *q, struct member *mem)
{
   int available = 0;
   int wrapuptime;

switch (mem->status) {
    case AST_DEVICE_INVALID:
    case AST_DEVICE_UNAVAILABLE:
        break;
    case AST_DEVICE_BUSY:
        if (mem->ringinuse) {
            break;
        }
    case AST_DEVICE_INUSE:
    case AST_DEVICE_RINGING:
    case AST_DEVICE_RINGINUSE:
    case AST_DEVICE_ONHOLD:
        if (!mem->ringinuse) {
            break;
        }

        /* else fall through */

    case AST_DEVICE_NOT_INUSE:
    case AST_DEVICE_UNKNOWN:
        if (!mem->paused) {
            available = 1;
        }
        break;
}

/* Let wrapuptimes override device state availability */
wrapuptime = get_wrapuptime(q, mem);

if (mem->lastcall && wrapuptime && (time(NULL) - wrapuptime < mem->lastcall)) {
    available = 0;
}
return available;

}

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.