How to get Agent's number in queue who will be next answer?

Hello!
Asterisk 1.6.2.11, FreeBSD 7.2/amd64
I have a simple configured queue in queue.conf. I have 5 Agents (for example). All of them are logged in and are answering calls.
I can see a call’s process in CLI and can “in-mind calculate” who of them will answer when next call will be.
How can I get Agent’s number of the my queue who will answer next call? Or, by other words, Who (Agent’s number) is next of logged Agents will be connected to the call when the call will be connected to queue?
I have read a lot of tutorials and docs and never seen any function or variable which allows me to do that.

PS. Of course, I can fully rewrite Queue application by Dialplan’s commands and set my own variable QUEUE_NEXT_MEMBER_ANSWER (for example), but I want to know if any variables or functions have already been built-in and work with standard Queue application.

Thanks, Ildar

I don’t believe this information is exposed. Even if it were exposed, it would only be true to the extent that there is always at least one agent free, and agents never log off.

I think Asterisk have to “know” the next agent’s number who will be answer on next call placed in queue. In other case, how Asterisk do ring policy? I’ve just want to find the way how make this “internal” variable accessible in userland.
May be developers of Asterisk can comment this situation?

As it happens, Asterisk may evaluate the first choice next member on handling the last call, however, there is no fundamental need to do this. Moreover, that decision can be invalidated if the member becomes unavailable, in which case it will have re-evaluate at the point where it is able to handle the call. Really it only needs to know historic information.

However, my main point is that this information is not exposed through AMI, so you would have to modify the source code to be able to access it (q->rrpos).

Asterisk “has to know in advance” which agent will receive the next call? How far in advance? A nano second? A microsecond? An hour? The call distribution, for starters, depends on logged in and who is on calls. Since the agent alone controls whether they are logged in or not, for asterisk to know in advance, it would have to know agent intent i.e. be psychic. In addition, the agent’s phone may also be co-opted by calls from outside of the queue [agent on other queues, agent takes a direct call from a non-queue source etc] … in other words, it is logically impossible to forecast with certainty where the next call will be directed except in a trivial case where there is a single queue with very low call volume. I do not see anything in the code that asterisk attempts to know this in advance. It simply takes what it knows, computes what to do based on current states and dials. I guess to be accurate, it does know where it is going to dial a few CPU cycles before it dials…but if you watch a busy real world system, you will see that even doing all this, conditions do change between the computation and dial and you will still see it dial busy agents who have become unavailable for one reason or another.

For round robin and linear, it does seem to select the next candidate after allocating a call, but the general algorithm seems to be:

[code]/*! \brief A large function which calls members, updates statistics, and bridges the caller and a member
*

  • Here is the process of this function
    1. Process any options passed to the Queue() application. Options here mean the third argument to Queue()
    1. Iterate trough the members of the queue, creating a callattempt corresponding to each member. During this
  • iteration, we also check the dialed_interfaces datastore to see if we have already attempted calling this
  • member. If we have, we do not create a callattempt. This is in place to prevent call forwarding loops. Also
  • during each iteration, we call calc_metric to determine which members should be rung when.
    1. Call ring_one to place a call to the appropriate member(s)
    1. Call wait_for_answer to wait for an answer. If no one answers, return.
    1. Take care of any holdtime announcements, member delays, or other options which occur after a call has been answered.
    1. Start the monitor or mixmonitor if the option is set
    1. Remove the caller from the queue to allow other callers to advance
    1. Bridge the call.
    1. Do any post processing after the call has disconnected.[/code]

(From try_calling() in app_queue.c for 1.6.1.0.)

with this being the bit that does the general case choose next function:

Although we’ve had a similar request (still in the queue) you can only predict on very simple systems, and the information is not exposed. The decisions, for the non-trivial cases, are based on information, like last call time, held against the individual queue members.

I am understanding all of us. I need the “next Agent’s number” in the case when new call is coming and it is not connected to Agent yet.
In this time Asterisk must do some check operation after that it must know the number of Agents who will be ringing now.

So, I can write my own dialplan with Queue-alternative with roundrobin. How it must work:
For example, I have 3 logged agents: 200, 201, 202 (all of them save in AstDB). All of them are in group called 500.
I created a variable (in AstDB) with “Next Agent Number” (call it “NAN”) and set NAN=200 (for example)
Then Asterisk (with my dialplan) do:

  1. Waiting for Call comes to 500.
  2. Get from AstDB value of NAN.
  3. Do checking State of Agent with NAN.
  4. IF (the Agent with current NAN CAN accept the Call) DO DIAL (…),
  5. IF (the Agent with current NAN CANNOT accept the Call) DO set the NAN number to next logged Agent number and go to 6. …

It is very simple example of algorithm. I just mark that NAN CAN be acceptable from API at any time for developer. Through dialplan I can get the value of this variable and manually control CALLING PROCESS’es behavior by checking NAN’s value after Call is connected to the group 500, but it is not connected to the Agent yet.

So, In what problem is with built-in Asterisk? AgentCallBackLogin is deprecated, So, If developer needs a simple queue with CallBack, he must write his own AgentCallBackLogin-application using Local interface and he can check in this case CAN Local/… Agent accepts a call or not BEFORE DIAL(). So why I have no any way to get “next Agent’s number” right before DIAL() with standard Asterisk API?

[quote=“david55”]For round robin and linear, it does seem to select the next candidate after allocating a call, but the general algorithm seems to be:

[code]/*! \brief A large function which calls members, updates statistics, and bridges the caller and a member
*

  • Here is the process of this function
    1. Process any options passed to the Queue() application. Options here mean the third argument to Queue()
    1. Iterate trough the members of the queue, creating a callattempt corresponding to each member. During this
  • iteration, we also check the dialed_interfaces datastore to see if we have already attempted calling this
  • member. If we have, we do not create a callattempt. This is in place to prevent call forwarding loops. Also
  • during each iteration, we call calc_metric to determine which members should be rung when.
    1. Call ring_one to place a call to the appropriate member(s)
    1. Call wait_for_answer to wait for an answer. If no one answers, return.
    1. Take care of any holdtime announcements, member delays, or other options which occur after a call has been answered.
    1. Start the monitor or mixmonitor if the option is set
    1. Remove the caller from the queue to allow other callers to advance
    1. Bridge the call.
    1. Do any post processing after the call has disconnected.[/code]

(From try_calling() in app_queue.c for 1.6.1.0.)

with this being the bit that does the general case choose next function:

Although we’ve had a similar request (still in the queue) you can only predict on very simple systems, and the information is not exposed. The decisions, for the non-trivial cases, are based on information, like last call time, held against the individual queue members.[/quote]

I have read it. The problem is “call_metric to determine which members should be rung when… and information is not exposed”. Ok. I understand it. I think I will write my own Queue function.