PJSIP客户端没有ACK邀请响应。

问题描述 投票:0回答:1

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

  • 发送给服务器的INVITE消息
  • 服务器回复180---------------------铃声
  • 服务器回复200 - OK

我的客户端从来没有ACK过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:[email protected]";
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:[email protected]", prm)

time.sleep(5)
ep.libDestroy()
del ep
pjsip pjsua2
1个回答
1
投票

难道你不需要一个回调的账户吗?我有一个helper文件,在那里我对来电进行回调。我不知道是不是这个问题,我也是来这里寻求智慧的... ...

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"

0
投票

我终于想明白了。 我把它贴在这里,以防别人遇到同样的问题。 我需要告诉端点处理事件。

while True:
    ep.libHandleEvents(10)

从... https:/www.pjsip.orgdocsbook-latesthtmlendpoint.html#starting-the-library

int libHandleEvents(unsigned msec_timeout)轮询pjsua是否有事件发生,如果有必要,会在指定的最大时间间隔(以毫秒为单位)内阻塞调用者线程。

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

如果EpConfig::UaConfig::mainThreadOnly被启用,并且这个函数被主线程调用(默认情况下,主线程是调用libCreate()的线程),那么这个函数也会扫描并运行列表中的任何待处理作业。

© www.soinside.com 2019 - 2024. All rights reserved.