[asterisk-app-dev] Asterisk AMI/ARI call origination complexity

Maxim Litnitskiy litnimaxster at gmail.com
Thu Jun 5 03:35:18 CDT 2014


Hi guys.
I'd like to discuss a wierd issue related to call origination from 3-rd
party apps.
IMHO call origination is the most important thing when embedding telephony
somewhere.
The problem is in one important place.
When call origination fails we need to know it and reflect accordingly.
Let's review a few examples with AMI and ARI where it fails.

1. AMI.
Let originate a call:

Action: Originate
> Channel: SIP/eltex/65010000
> Application: Echo
> ActionID: 12341234
> Async: true


Response: Success
> ActionID: 12341234
> Message: Originate successfully queued


Great. We have ActionID to track it.
Everything is fine when call is connected.
But often it fails to connect and we must know the reason - cause code and
message.
And here we are - it's not as simple as it could be.
Let see events:

Event: Hangup
> Privilege: call,all
> Channel: SIP/eltex-00000002
> Uniqueid: 1396800231.4
> CallerIDNum: <unknown>
> CallerIDName: <unknown>
> ConnectedLineNum: <unknown>
> ConnectedLineName: <unknown>
> AccountCode:
>
> *Cause: 19 **Cause-txt: User alerting, no answer*



>
> Event: OriginateResponse
> Privilege: call,all
>
> *ActionID: 12341234*
> *Response: Failure*Channel: SIP/eltex/65010000
> Context:
> Exten:
> Reason: 3
> Uniqueid: <null>
> CallerIDNum: <unknown>
> CallerIDName: <unknown>


We do have ActionID in OriginateResponse message. But how can we know cause
code and cause message?
Only from Hangup event.
But Hangup event does not have our ActionID it has Uniqueid.
But OriginateResponse does not have Uniqueid.
So it's impossible to properly track failed AMI originated calls without
inventing some hacks to solve the situation.
One solution is to use CallerID to track call path as this field is in all
messages.
But it does not help when we have to keep real caller id and name.
I tested this situation on all Asterisk versions from  1.4 to 11. All as
described above.

2. ARI. Now let see how we originate calls with ARI.
We use POST /channels API. Something like that:

data = {
>                 'endpoint': 'SIP/%s@%s' % (phone, provider),
>                 'extension': '1',
>                 'context': 'test',
>                 'priority': '1',
>                 'channelId': channel_id,
>                 'timeout': '60',

            }
>
>             ret = ari_post('channels', data=data)


Again everyhing is fine if call is answered and put into Statis app:

[test]
> exten => 1,1,Noop()
> same => n,Wait(1.5)
> same => n,Stasis(dialer)
> same => n,Wait(2)
> same => n,Hangup()



We do have channelId. And when ChannelHangupRequest event comes into our
 dialer websocket we already know it is ANSWERED and can distinguish it by
channel id. Fine.
But again what if call was not connected? CONGESTION, FAILED, NO ANSWER,
BUSY?
ChannelHangupRequest does not come into our websocket!
So for this time I created the following hack.
I used cdr_pgsql and created  AFTER INSERT TRIGGER on cdr table.
This trigger function takes disconnect cause by uniqueid and updates my
table we this cause:

CREATE OR REPLACE FUNCTION update_channel_status() RETURNS trigger AS $$
>     BEGIN
>         UPDATE dialer_subscriber SET status = NEW."disposition"
>             WHERE channel_id = NEW."uniqueid";
>         RETURN NEW;
>     END; $$ LANGUAGE 'plpgsql';
>
>
> CREATE TRIGGER update_channel_status AFTER INSERT on asterisk_cdr
>     FOR EACH ROW EXECUTE PROCEDURE update_channel_status();


Why at all I post all this here?
If ARI is just started to evolve may be developers can implement some
direct "inhouse" feature to track not connected calls in ARI app?

Thanks for reading.

Regars,
Max.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-app-dev/attachments/20140605/9da938b1/attachment.html>


More information about the asterisk-app-dev mailing list