pjsua2 crash on incoming call

GM
Gabriel Margiani
Sun, May 15, 2016 4:21 PM

Hello,

With libpjproject 2.5, my application crashes on every incoming
call with ../src/pjsip-ua/sip_inv.c:2321: pjsip_inv_answer: Assertion inv->last_answer' failed.`

For example the example pjsip-apps/src/samples/pjsua2_demo.cpp;
running mainProg1() from that file (adjusted to connect to my
server) and making a call gives me:


17:28:38.112 pjsua_core.c .RX 934 bytes Request msg
INVITE/cseq=19 (rdata0x7f5778009268) from UDP 192.168.1.1:5060:
INVITE sip:...:5060;ob SIP/2.0 Via: SIP/2.0/UDP
192.168.1.1:5060;branch=z9hG4bKF6C9406CE2B74353 From: "Telefon"
sip:...;tag=02C2A2303BAE5A8F To: sip:...:5060;ob Call-ID:
67633F78A1E5FE72@192.168.1.1 CSeq: 19 INVITE Contact:
sip:38CA76357F60C7729329E698EB24B@192.168.1.1 Max-Forwards: 70
Expires: 120 Supported: 100rel,replaces,timer Allow-Events:
telephone-event,refer Allow:
INVITE,ACK,OPTIONS,CANCEL,BYE,UPDATE,PRACK,INFO,SUBSCRIBE,NOTIFY,REFER,MESSAGE,PUBLISH
Content-Type: application/sdp Accept: application/sdp,
multipart/mixed Accept-Encoding: identity Content-Length: 218

v=0
o=user 13656679 13656679 IN IP4 192.168.1.1
s=call
c=IN IP4 192.168.1.1
t=0 0
m=audio 40012 RTP/AVP 8 18 101
a=sendrecv
a=fmtp:18 annexb=no
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=rtcp:40013

--end msg--
17:28:38.112 pjsua_call.c .Incoming Request msg INVITE/cseq=19
(rdata0x7f5778009268) 17:28:38.112 pjsua_media.c ..Call 0:
initializing media.. 17:28:38.113 pjsua_media.c ...RTP socket
reachable at 192.168.1.8:4000 17:28:38.113 pjsua_media.c ...RTCP
socket reachable at 192.168.1.8:4001 17:28:38.113 pjsua_media.c
...Media index 0 selected for audio call 0
*** Incoming Call: "Telefon" sip:... [NULL]
17:28:38.113 pjsua_call.c ...Answering call 0: code=200 a.out:
../src/pjsip-ua/sip_inv.c:2321: pjsip_inv_answer: Assertion
`inv->last_answer' failed. [1] 19792 abort (core dumped) ./a.out

The call handler ist:


virtual void onIncomingCall(OnIncomingCallParam &iprm)
{
Call *call = new MyCall(*this, iprm.callId);
CallInfo ci = call->getInfo();
CallOpParam prm;

    std::cout << "*** Incoming Call: " <<  ci.remoteUri << " ["
              << ci.stateText << "]" << std::endl;
    
    calls.push_back(call);
    prm.statusCode = (pjsip_status_code)200;
    call->answer(prm);
}

Any idea what to do here?

thank you
Gabriel

Hello, With libpjproject 2.5, my application crashes on every incoming call with `../src/pjsip-ua/sip_inv.c:2321: pjsip_inv_answer: Assertion `inv->last_answer' failed.` For example the example pjsip-apps/src/samples/pjsua2_demo.cpp; running mainProg1() from that file (adjusted to connect to my server) and making a call gives me: ------------------------------------------------------------------------------- 17:28:38.112 pjsua_core.c .RX 934 bytes Request msg INVITE/cseq=19 (rdata0x7f5778009268) from UDP 192.168.1.1:5060: INVITE sip:...:5060;ob SIP/2.0 Via: SIP/2.0/UDP 192.168.1.1:5060;branch=z9hG4bKF6C9406CE2B74353 From: "Telefon" <sip:...>;tag=02C2A2303BAE5A8F To: <sip:...:5060;ob> Call-ID: 67633F78A1E5FE72@192.168.1.1 CSeq: 19 INVITE Contact: <sip:38CA76357F60C7729329E698EB24B@192.168.1.1> Max-Forwards: 70 Expires: 120 Supported: 100rel,replaces,timer Allow-Events: telephone-event,refer Allow: INVITE,ACK,OPTIONS,CANCEL,BYE,UPDATE,PRACK,INFO,SUBSCRIBE,NOTIFY,REFER,MESSAGE,PUBLISH Content-Type: application/sdp Accept: application/sdp, multipart/mixed Accept-Encoding: identity Content-Length: 218 v=0 o=user 13656679 13656679 IN IP4 192.168.1.1 s=call c=IN IP4 192.168.1.1 t=0 0 m=audio 40012 RTP/AVP 8 18 101 a=sendrecv a=fmtp:18 annexb=no a=rtpmap:101 telephone-event/8000 a=fmtp:101 0-15 a=rtcp:40013 --end msg-- 17:28:38.112 pjsua_call.c .Incoming Request msg INVITE/cseq=19 (rdata0x7f5778009268) 17:28:38.112 pjsua_media.c ..Call 0: initializing media.. 17:28:38.113 pjsua_media.c ...RTP socket reachable at 192.168.1.8:4000 17:28:38.113 pjsua_media.c ...RTCP socket reachable at 192.168.1.8:4001 17:28:38.113 pjsua_media.c ...Media index 0 selected for audio call 0 *** Incoming Call: "Telefon" <sip:...> [NULL] 17:28:38.113 pjsua_call.c ...Answering call 0: code=200 a.out: ../src/pjsip-ua/sip_inv.c:2321: pjsip_inv_answer: Assertion `inv->last_answer' failed. [1] 19792 abort (core dumped) ./a.out ------------------------------------------------------------------------ The call handler ist: ------------------------------------------------------------------------- virtual void onIncomingCall(OnIncomingCallParam &iprm) { Call *call = new MyCall(*this, iprm.callId); CallInfo ci = call->getInfo(); CallOpParam prm; std::cout << "*** Incoming Call: " << ci.remoteUri << " [" << ci.stateText << "]" << std::endl; calls.push_back(call); prm.statusCode = (pjsip_status_code)200; call->answer(prm); } --------------------------------------------------------------------------- Any idea what to do here? thank you Gabriel
G
gabriel@margiani.ch
Mon, May 16, 2016 9:54 AM

17:28:38.112 pjsua_call.c .Incoming Request msg INVITE/cseq=19 (rdata0x7f5778009268)
17:28:38.112 pjsua_media.c ..Call 0: initializing media..
17:28:38.113 pjsua_media.c ...RTP socket reachable at 192.168.1.8:4000
17:28:38.113 pjsua_media.c ...RTCP socket reachable at 192.168.1.8:4001
17:28:38.113 pjsua_media.c ...Media index 0 selected for audio call 0
*** Incoming Call: "Telefon" sip:... [NULL]
17:28:38.113 pjsua_call.c ...Answering call 0: code=200 a.out:
../src/pjsip-ua/sip_inv.c:2321: pjsip_inv_answer: Assertion
`inv->last_answer' failed. [1] 19792 abort (core dumped) ./a.out

I managed to track it down a little more. It seems to be a bug in
pj::Endpoint. The first answer to a call has to be made by
'pjsip_inv_initial_answer()' function, which is done by pjsua
automatically before calling the 'on_incoming_call' callback of
pj::Endpoint. Before this happens, the media is being initialized (see
log above) by 'pj::Endpoint::on_create_media_transport()' (line 1233).
In version 2.5 this method calls on it's own 'on_incoming_call', but the
call isn't ready to be answered "normally" yet, so we get the crash.

Below the code of on_create_media_transport. Commenting out like shown
solves the problem for me, but I don't know why the code has been added,
so it might not the best solution:

-------------- pjsua2/Endpoint.cpp:1233+ -------------------------
pjmedia_transport*
Endpoint::on_create_media_transport(pjsua_call_id call_id,
unsigned media_idx,
pjmedia_transport *base_tp,
unsigned flags)
{
Call *call = Call::lookup(call_id);
if (!call) {
//pjsua_call in_call = &pjsua_var.calls[call_id];
//if (in_call->incoming_data) {
/
This can happen when there is an incoming call but the
* on_incoming_call() callback hasn't been called. So we need to

     * call the callback here.
     */
    //on_incoming_call(in_call->acc_id, call_id,

in_call->incoming_data);

    //[> New call should already be created by app. <]
    //call = Call::lookup(call_id);
    //if (!call) {
    //return base_tp;
    //}
//} else {
    return base_tp;
//}
}

----------- [...] -----------------------------------

regards
Gabriel

> 17:28:38.112 pjsua_call.c .Incoming Request msg INVITE/cseq=19 (rdata0x7f5778009268) > 17:28:38.112 pjsua_media.c ..Call 0: initializing media.. > 17:28:38.113 pjsua_media.c ...RTP socket reachable at 192.168.1.8:4000 > 17:28:38.113 pjsua_media.c ...RTCP socket reachable at 192.168.1.8:4001 > 17:28:38.113 pjsua_media.c ...Media index 0 selected for audio call 0 > *** Incoming Call: "Telefon" <sip:...> [NULL] > 17:28:38.113 pjsua_call.c ...Answering call 0: code=200 a.out: > ../src/pjsip-ua/sip_inv.c:2321: pjsip_inv_answer: Assertion > `inv->last_answer' failed. [1] 19792 abort (core dumped) ./a.out I managed to track it down a little more. It seems to be a bug in pj::Endpoint. The first answer to a call has to be made by 'pjsip_inv_initial_answer()' function, which is done by pjsua automatically before calling the 'on_incoming_call' callback of pj::Endpoint. Before this happens, the media is being initialized (see log above) by 'pj::Endpoint::on_create_media_transport()' (line 1233). In version 2.5 this method calls on it's own 'on_incoming_call', but the call isn't ready to be answered "normally" yet, so we get the crash. Below the code of on_create_media_transport. Commenting out like shown solves the problem for me, but I don't know why the code has been added, so it might not the best solution: -------------- pjsua2/Endpoint.cpp:1233+ ------------------------- pjmedia_transport* Endpoint::on_create_media_transport(pjsua_call_id call_id, unsigned media_idx, pjmedia_transport *base_tp, unsigned flags) { Call *call = Call::lookup(call_id); if (!call) { //pjsua_call *in_call = &pjsua_var.calls[call_id]; //if (in_call->incoming_data) { /* This can happen when there is an incoming call but the * on_incoming_call() callback hasn't been called. So we need to * call the callback here. */ //on_incoming_call(in_call->acc_id, call_id, in_call->incoming_data); //[> New call should already be created by app. <] //call = Call::lookup(call_id); //if (!call) { //return base_tp; //} //} else { return base_tp; //} } ----------- [...] ----------------------------------- regards Gabriel