Pjsip多次呼叫使用少数出局线路失败

时间:2015-12-25 04:47:17

标签: c++ line call sip pjsip

我使用pjsip高级api PJSUA一次拨打多个电话。我的sip操作员最多支持3个拨出线路,所以从理论上讲,一次可以呼叫3个人。问题是,在我看到的操作员日志中,消息"线路限制超出"在pjsip中,调用失败。我是这样做的:

这是我的类,其中包含调用方法:

 void Sip::InitLibrary()
{
    pj::EpConfig ep_cfg;

    ep_cfg.logConfig.level = 4;
    ep_cfg.logConfig.consoleLevel = 4;
    ep_cfg.logConfig.filename = this->log_;
    ep_cfg.uaConfig.userAgent = "Ekiga";
    this->ep_.libCreate();
    this->ep_.libInit(ep_cfg);
}
void Sip::SetSipTransport(Sip::SipTransport transport, unsigned port)
{
    TransportConfig tcfg;

    tcfg.port = port;

    pjsip_transport_type_e type;

    switch (transport)
    {
    case SipTransport::TCP:
        type = PJSIP_TRANSPORT_TCP;
        break;
    case SipTransport::UDP:
        type = PJSIP_TRANSPORT_UDP;
        break;
    }

    try {
        this->transportId_ = this->ep_.transportCreate(type, tcfg);
    }
    catch (Error &err) {
        //to log
        return;
    }

}
void Sip::StartLibrary()
{
    this->ep_.libStart();
}
AccountInfo Sip::ConnectSipServer(string serv, string login, string pass,SipTransport transport,int port)
{
    this->InitLibrary();
    this->SetSipTransport(transport, port);
    this->StartLibrary();
    this->server_ = serv;

    AccountConfig accConfig;
    string uri = "<sip:" + login + "@" + serv +">";
    accConfig.idUri = uri;
    string regUri = "sip:" + serv;
    accConfig.regConfig.registrarUri = regUri;

    accConfig.sipConfig.authCreds.push_back(AuthCredInfo("digest", "*", login, 0, pass));

    this->acc_ = new SipAccount();

    acc_->create(accConfig, true);
    {
        unique_lock<mutex> locker(acc_->regLock_);
        while (!acc_->regEnd_)
            acc_->regDone_.wait(locker);
    }
    return acc_->info_;


}
bool Sip::CallNumber(string phone)
{
    Call *call = new SipCall(*this->acc_);
    CallOpParam prm(true);
    prm.opt.audioCount = 1; 
    prm.opt.videoCount = 0; 
    call->makeCall("sip:" + phone + "@" + this->server_, prm);

    SipCall *myCall = (SipCall*)call;
    {
        unique_lock<mutex> locker(myCall->callLock);
        while (!myCall->callEnd)
            myCall->callDone.wait(locker);
    }
    if (myCall->validPhone)
    {

        delete myCall;
        return true;

    }
    delete myCall;

    return false;



}

SipCall.h

SipCall(Account &acc, int call_id = PJSUA_INVALID_ID)
        : Call(acc, call_id)
    {
        Acc = (SipAccount *)&acc;
        this->callEnd = false;
        this->validPhone = false;
    }
    ~SipCall();

    virtual void onCallState(OnCallStateParam &prm);
    condition_variable callDone;
    mutex callLock;
    bool callEnd;
    bool validPhone;

SipCall.cpp

   void SipCall::onCallState(OnCallStateParam &prm)
    {
        PJ_UNUSED_ARG(prm);

        CallInfo ci = getInfo();

        std::cout << "*** Call: " << ci.remoteUri << " [" << ci.stateText
            << "]" << std::endl;

        if (ci.state == PJSIP_INV_STATE_DISCONNECTED) {

            {
                unique_lock<mutex> locker(this->callLock);          
                this->callEnd = true;
                this->callDone.notify_one();
            }
        }

        if (ci.state == PJSIP_INV_STATE_CONFIRMED && ci.lastStatusCode == PJSIP_SC_OK)
        {    //here i check that phone is valid, and just hang up the call
            CallOpParam p;      
            this->validPhone = true;
            this->hangup(p);

        }

    }

    SipCall::~SipCall()
    {
    }

由于有3行可用,我创建了三个任务来调用相应的数字,如下所示:

 QStringList testCalls; // initialized with numbers 
   struct call_result{
    QString phone;
    bool valid;
   };
 //....
 QList<QFuture<call_result>> futureTestList;

        while(counter < testCalls.count()) {
            for(int i= 0; i < 3; i++,counter++) {
                if(counter >= testCalls.count())
                    break;
                QString number = testCalls.at(counter);
                QFuture<call_result> futureResult = QtConcurrent::run(this,&sipQtThread::callNumber,number);
                futureTestList.append(futureResult);
            }
            foreach(QFuture<call_result> future,futureTestList) {
                future.waitForFinished();
                call_result call = future.result();
                emit phonePassed(call.phone,call.valid);
            }
            futureTestList.clear();


        }

对应任务sipQtThread::callNumber如下:

sipQtThread::call_result sipQtThread::callNumber(QString phone)
{
   call_result call;
   pj_thread_desc initdec;
   pj_thread_t* thread = 0;
   pj_status_t status;


            status = pj_thread_register(NULL, initdec, &thread);
            if (status != PJ_SUCCESS) {
                qDebug()<<"pj_thread_register faild:"<<status;
                return call;
            }
    bool result = sip_->CallNumber(phone.toStdString());

    call.phone = phone;
    call.valid = result;  
    return call;

}

正如你在这里看到的那样

if (ci.state == PJSIP_INV_STATE_CONFIRMED && ci.lastStatusCode == PJSIP_SC_OK)
            {    //here i check that phone is valid, and just hang up the call
                CallOpParam p;      
                this->validPhone = true;
                this->hangup(p);

            }

我只是检查手机是否有效,并且正在通话,然后放弃它。 pjsua2可以处理多个线路呼叫吗?或者甚至是pjsip支持多个外拨线路呼叫? pj_thread_register注册的线程是否需要以某种方式取消注册?

0 个答案:

没有答案