我正在使用Python和PJSUA2创建SIP客户端。我正在使用在同一主机上运行的SIP服务器进行测试。当我调用makeCall()时,Wireshark显示以下内容:
我的客户端从不确认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
答案 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()的线程),则此函数还将扫描并运行列表中的所有未决作业