PJSIP客户端不确认邀请响应

时间:2020-06-09 18:08:59

标签: pjsip pjsua2

我正在使用Python和PJSUA2创建SIP客户端。我正在使用在同一主机上运行的SIP服务器进行测试。当我调用makeCall()时,Wireshark显示以下内容:

  • 正在将邀请消息发送到服务器
  • 服务器回复180-振铃
  • 服务器回复200-确定

我的客户端从不确认200-OK消息。应该自动完成此操作还是需要对其进行配置以使其进入ACK?

import time
import pjsua2 as pj

class MyCall(pj.Call):
    def onCallState(self, prm):
        print("***OnCallState: ")

        call_info = self.getInfo()
        print("current state is " + str(call_info.state) + " " + call_info.stateText)
        print("last status code: " + str(call_info.lastStatusCode))

ep = pj.Endpoint()
ep_cfg = pj.EpConfig()
ep_cfg.uaConfig.threadCnt = 0
ep.libCreate()
ep.libInit(ep_cfg)

sipTpConfig = pj.TransportConfig()
ep.transportCreate(pj.PJSIP_TRANSPORT_UDP, sipTpConfig)
ep.libStart()

# Create the account information
acfg = pj.AccountConfig()
acfg.idUri = "sip:test@pjsip.org";
acfg.regConfig.registrarUri = "sip:pjsip.org";
cred = pj.AuthCredInfo("digest", "*", "test", 0, "pwtest");
acfg.sipConfig.authCreds.append( cred );

acc = pj.Account()
acc.create(acfg)

call = MyCall(acc, pj.PJSUA_INVALID_ID)
prm = pj.CallOpParam(True)

call.makeCall("sip:service@127.0.0.1", prm)

time.sleep(5)
ep.libDestroy()
del ep

2 个答案:

答案 0 :(得分:1)

您不需要该帐户的回叫吗?我有一个帮助文件,可以在接听来电时接听电话。我不知道这是否是问题,我也是来这里寻求智慧的...

import sys
import pjsua as pj
import threading
import time

current_call=None

# Callback to receive events from Account
class MyAccountCallback(pj.AccountCallback):
    sem = None

    def __init__(self, account):
        pj.AccountCallback.__init__(self, account)

    def wait(self):
        self.sem = threading.Semaphore(0)
        self.sem.acquire()

    #Notification when account registration state has changed
    def on_reg_state(self):
        if self.sem:
            if self.account.info().reg_status >= 200:
                self.sem.release()

    # Notification on incoming call
    def on_incoming_call(self, call):
        global current_call
        if current_call:
            call.answer(486, "Busy")
            return

        print "Incoming call from ", call.info().remote_uri

        current_call = call
        call_cb = MyCallCallback(current_call)
        current_call.set_callback(call_cb)

        current_call.answer(180)
        time.sleep(0.1)
        current_call.answer(200)


# Callback to receive events from Call
class MyCallCallback(pj.CallCallback):
    def __init__(self, call=None):
        pj.CallCallback.__init__(self, call)

    # Notification when call state has changed
    def on_state(self):
        global current_call
        print "Call is ", self.call.info().state_text,
        print "last code =", self.call.info().last_code,
        print "(" + self.call.info().last_reason + ")"
        if self.call.info().state == pj.CallState.DISCONNECTED:
            current_call = None
            print 'Current call is', current_call

    # Notification when call's media state has changed.
    def on_media_state(self):
        if (self.call.info().media_state == pj.MediaState.ACTIVE):
            # Connect the call to sound device
            call_slot = self.call.info().conf_slot
            pj.Lib.instance().conf_connect(call_slot, 0)
            pj.Lib.instance().conf_connect(0, call_slot)
            print "\nMEDIA IS ACTIVE\n"
        else:
            print "\n\MEDIA IS *NOT* ACTIVE\n"

答案 1 :(得分:1)

我终于明白了。如果有人遇到相同问题,我将在此发布。我需要告诉端点处理事件:

while True:
    ep.libHandleEvents(10)

来自https://www.pjsip.org/docs/book-latest/html/endpoint.html#starting-the-library

int libHandleEvents(未签名的msec_timeout) 轮询事件的pjsua,并在必要时阻止调用方线程达到指定的最大间隔(以毫秒为单位)。

如果应用程序已在pjsua_config结构中配置了工作线程(thread_cnt字段),则通常不需要调用此函数,因为轮询将改为由这些工作线程完成。

如果启用了EpConfig :: UaConfig :: mainThreadOnly并从主线程调用此函数(默认情况下,主线程是调用libCreate()的线程),则此函数还将扫描并运行列表中的所有未决作业

相关问题