OrderlyQ integrates with Asterisk over the Manager and FastAGI protocols (full details in the Asterisk Queues Tutorial). There is a known weakness in Asterisk in that if a FastAGI connection cannot be made for any reason, the call is dropped by default.

As OrderlyQ is delivered over the internet, connections cannot be guaranteed, so it is important that when a connection to our servers cannot be made, the call goes through to your Asterisk queue directly.

Note: If you're using or considering using OrderlyQ, we'd be happy to apply this patch for you.

1. Apply Asterisk Patch

The first step in building this contingency plan is to patch Asterisk. Digium have released an unofficial patch to allow Asterisk to continue handling the call at priority N+101, where N is the priority at which the AGI call failed. To apply the patch, find your Asterisk source directory (usually /usr/src/asterisk-1.X.x where X and x are the major and minor versions), and open res/res_agi.c with your favourite editor. Find the part at the end of the agi_exec_full() function that looks like this:

if (!res) {
        agi.fd = fds[1];
        agi.ctrl = fds[0];
        agi.audio = efd;
        res = run_agi(chan, argv[0], &agi, pid, dead);
        close(fds[1]);
        if (efd > -1)
                close(efd);
}
LOCAL_USER_REMOVE(u);
return res;

The changes you need to make depend on which version of Asterisk you're using, and are highlighted in bold below.

Asterisk 1.0.10 and below: Change res_agi.c to look like this:
if (!res) {
        agi.fd = fds[1];
	agi.ctrl = fds[0];
	agi.audio = efd;
	res = run_agi(chan, argv[0], &agi, pid, dead);
	close(fds[1]);
	if (efd > -1)
	        close(efd);
} else if (ast_exists_extension(chan, 
		chan->context, 
		chan->exten, 
		chan->priority + 101, 
		chan->callerid)) {
        chan->priority+=100;
        res = 0;
}
LOCAL_USER_REMOVE(u);
return res;
 
Asterisk 1.2.0 and above: Change res_agi.c to look like this:
if (!res) {
        agi.fd = fds[1];
        agi.ctrl = fds[0];
        agi.audio = efd;
        res = run_agi(chan, argv[0], &agi, pid, dead);
        close(fds[1]);
        if (efd > -1)
                close(efd);
} else if (ast_exists_extension(chan, 
		chan->context, 
		chan->exten, 
		chan->priority + 101, 
		chan->cid.cid_num)) {
	chan->priority+=100;
	res = 0;
}
LOCAL_USER_REOVE(u)
return res;

Next, recompile and reinstall Asterisk.

> cd /path/to/src/asterisk-1.X.x
> make
> make install

Restart asterisk, and the contingency patch will be in place. Next we'll build contingency into the OrderlyQ dial plan.



2. Add Contingency to Dial Plan

The last step is to modify /etc/asterisk/extensions.conf to tell Asterisk what to do if a FastAGI call fails. The following example assumes you have already set up a queue as outlined in the tutorial.

exten=> 2020,1,Answer
exten=> 2020,2,Ringing
exten=> 2020,3,Wait(2)

;Set music for callers in OrderlyQ
exten=> 2020,4,SetMusicOnHold(default)

;Send callers to OrderlyQ.
exten=> 2020,5,agi(agi://qqq.orderlyq.com/orderlyq?queueCode=QUEUE_CODE&username
=MyUsername&password=MyPassword&asteriskQueueName=MyQueue)   ;All one line.

exten=> 2020,6,Queue(MyQueue|r)
exten=> 2020,7,Hangup

;Contingency
exten => 2020,106,Goto(2020,6)

The first FastAGI call is at priority N = 5, so if it fails the dial plan will continue at N + 101 = 106. The call is then sent to the Asterisk queue at priorty 6 with a Goto(), and will be queued in the normal way.

Make sure you do an Asterisk reload so your changes can take effect.