Search code examples
pjsua2

How to properly forward/redirect calls with pjsua2


I can't find info on the net how to forward a call with pjsua2. Currently Im trying with the xfer method but Im getting:

../src/pjsip-ua/sip_inv.c:3942: inv_on_state_null: Assertion `!"Unexpected transaction type"' failed.

There is no information about this error.

This is my code Im trying:

void MyAccount::onIncomingCall(OnIncomingCallParam &iprm)
{
    MyCall *call = new MyCall(*this, iprm.callId);

    ...

    calls.push_back(call);
    ...

    QString fwd_to = fwd(QString::fromStdString(ci.remoteUri));

    if(fwd_to != "NO_FWD")
    {
        info+="*** Xfer Call: ";
        info+=QString::fromStdString(ci.remoteUri);
        info+=" [";
        info+=QString::fromStdString(ci.stateText);
        info+="]\n";
        infoChanged=true;

        CallOpParam prm1;
        prm1.statusCode = (pjsip_status_code)200;
        call->answer(prm1);

        pj_thread_sleep(2000);

        CallOpParam prm2(true);
        call->xfer(fwd_to.toStdString(), prm2);
    }
    else
    {
        // standart incoming
        ...
    }
}

fwd is my own function which search a database if it needs to forward the call


Solution

  • I did something like this and works, dont know if some other way exist:

    (answering with no media, setting flag and in other thread xfering call to fwd_to string)

    if(fwd_to != "NO_FWD")
        {
            CallOpParam prm1;
            prm1.statusCode = (pjsip_status_code)200;
            call->answer(prm1);
    
            call->fwd_to = fwd_to;
            call->fwd=true;
        }
    
    FwdThread *fwd_thread = new FwdThread();
    fwd_thread->start();
    
    void FwdThread::run()
    {
        static pj_thread_desc s_desc;
        static pj_thread_t *s_thread;
        pj_thread_register("FwdThread", s_desc, &s_thread);
        loop();
    }
    
    void FwdThread::loop()
    {
        while(1)
        {
            for(auto &call : pjt->v_calls)
            {
                if(call->fwd && call->answered)
                {
                    call->fwd=false;
                    CallOpParam prm2(true);
                    call->xfer(call->fwd_to.toStdString(), prm2);
                }
            }
    
            if(pjt->Stop)
                break;
    
            pj_thread_sleep(500);
        }
    }