<div dir="ltr">Hi guys.<div>I'd like to discuss a wierd issue related to call origination from 3-rd party apps.</div><div>IMHO call origination is the most important thing when embedding telephony somewhere.</div><div>

The problem is in one important place. </div><div>When call origination fails we need to know it and reflect accordingly.</div><div>Let's review a few examples with AMI and ARI where it fails.</div><div><br></div><div>

1. AMI.</div><div>Let originate a call:</div><div><br></div><div><blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex" class="gmail_quote">

Action: Originate<br>Channel: SIP/eltex/65010000<br>Application: Echo<br><span class="" style="background:rgb(255,255,204)">ActionID</span>: 12341234<br>Async: true</blockquote></div><div><br></div><div><blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex" class="gmail_quote">

Response: Success<br><span class="" style="background:rgb(255,255,204)">ActionID</span>: 12341234<br>Message: Originate successfully queued</blockquote></div><div><br></div><div>Great. We have ActionID to track it. </div>

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

<div><br></div><div><blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex" class="gmail_quote">Event: Hangup<br>Privilege: call,all<br>

Channel: SIP/eltex-00000002<br>Uniqueid: 1396800231.4<br>CallerIDNum: <unknown><br>CallerIDName: <unknown><br>ConnectedLineNum: <unknown><br>ConnectedLineName: <unknown><br>AccountCode:<br><b>Cause: 19<br>

</b><b>Cause-txt: User alerting, no answer</b></blockquote><div> </div><blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex" class="gmail_quote">

<br>Event: OriginateResponse<br>Privilege: call,all<br><b><span class="" style="background:rgb(255,255,204)">ActionID</span>: 12341234<br></b><b>Response: Failure<br></b>Channel: SIP/eltex/65010000<br>Context:<br>Exten:<br>

Reason: 3<br>Uniqueid: <null><br>CallerIDNum: <unknown><br>CallerIDName: <unknown></blockquote></div><div><br></div><div>We do have ActionID in OriginateResponse message. But how can we know cause code and cause message? </div>

<div>Only from Hangup event.</div><div>But Hangup event does not have our ActionID it has Uniqueid.</div><div>But OriginateResponse does not have Uniqueid.</div><div>So it's impossible to properly track failed AMI originated calls without inventing some hacks to solve the situation.</div>

<div>One solution is to use CallerID to track call path as this field is in all messages.</div><div>But it does not help when we have to keep real caller id and name.</div><div>I tested this situation on all Asterisk versions from  1.4 to 11. All as described above.</div>

<div><br></div><div>2. ARI. Now let see how we originate calls with ARI.</div><div>We use POST /channels API. Something like that:</div><div><br></div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

data = {<br>                'endpoint': 'SIP/%s@%s' % (phone, provider),<br>                'extension': '1',<br>                'context': 'test',<br>                'priority': '1',<br>

                'channelId': channel_id,<br>                'timeout': '60', </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

            }<br>            <br>            ret = ari_post('channels', data=data)</blockquote></div><div><br></div><div>Again everyhing is fine if call is answered and put into Statis app:</div><div><br></div><div>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">[test]<br>exten => 1,1,Noop()<br>same => n,Wait(1.5)<br>

same => n,Stasis(dialer) <br>same => n,Wait(2)<br>same => n,Hangup()</blockquote></div><div><br></div><div><br></div><div>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.</div>

<div>But again what if call was not connected? CONGESTION, FAILED, NO ANSWER, BUSY?</div><div>ChannelHangupRequest does not come into our websocket!</div><div>So for this time I created the following hack.</div><div>I used cdr_pgsql and created  AFTER INSERT TRIGGER on cdr table.</div>

<div>This trigger function takes disconnect cause by uniqueid and updates my table we this cause: </div><div><br></div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

CREATE OR REPLACE FUNCTION update_channel_status() RETURNS trigger AS $$<br>    BEGIN<br>        UPDATE dialer_subscriber SET status = NEW."disposition"<br>            WHERE channel_id = NEW."uniqueid";<br>

        RETURN NEW;<br>    END; $$ LANGUAGE 'plpgsql';<br>    <br><br>CREATE TRIGGER update_channel_status AFTER INSERT on asterisk_cdr <br>    FOR EACH ROW EXECUTE PROCEDURE update_channel_status();</blockquote>
<div>
<br></div><div>Why at all I post all this here?</div></div><div>If ARI is just started to evolve may be developers can implement some direct "inhouse" feature to track not connected calls in ARI app?</div><div>
<br>
</div><div>Thanks for reading.</div><div><br></div><div>Regars,</div><div>Max.</div><div><br></div><div><br></div></div>