I use PJSUA2 to establish a full-fledged SIP call with an application which is supposed to:
Even though the call is connected to the server (I can see the call, its ID, some logs etc), media session cannot be established for some reason.
Here's the code I run (python 3.11)
import pjsua2 as pj
import time
import random
endpoint_config = pj.EpConfig()
endpoint_config.logConfig.level = 9
endpoint_config.medConfig.sndClockRate = 8000
endpoint = pj.Endpoint()
endpoint.libCreate()
endpoint.libInit(endpoint_config)
print("Endpoint initialized..")
# Create SIP transport
sip_transport_config = pj.TransportConfig()
transport_type = pj.PJSIP_TRANSPORT_TCP
sip_transport_config.port = 5060
endpoint.transportCreate(transport_type, sip_transport_config)
print("Transport created..")
# Start the library
endpoint.libStart()
print("Endpoint started..")
endpoint.libHandleEvents(10)
# Subclass to extend the Account and get notifications etc.
class MyAccount(pj.Account):
def __init__(self):
super().__init__()
def onRegState(self, prm):
ai = self.getInfo()
print("*** Register: code=" if ai.regIsActive else "*** Unregister: code=", prm.code)
class MyCall(pj.Call):
def __init__(self, account, call_id):
super().__init__(account, call_id)
self.acc = account
self.connected = False
def onCallState(self, prm):
time.sleep(5)
print(f"THE STATE OF THE CALL HAS CHANGED: {prm}")
call_info = self.getInfo()
self.connected = call_info.state == pj.PJSIP_INV_STATE_CONFIRMED
print("CONNECTED:", self.connected)
print("current state is " + str(call_info.state) + " " + call_info.stateText)
print("GET ID:", self.getId())
print("HAS MEDIA:", self.hasMedia())
def onMediaState(self):
print("ON MEDIA STATE")
# pjsua2 test function
def pj_test():
account_config.idUri = "sip:111@111.111.1.1"
account = MyAccount()
try:
account.create(account_config)
print("ACCOUNT?", account)
print("\nAccount created/registered..\n")
except pj.Error as err:
print("ERR acc:",err)
call = MyCall(account, pj.PJSUA_INVALID_ID)
prm = pj.CallOpParam(True)
try:
print("Attempting to make a call...")
# USE prm.txOption – Optional headers etc to be added to outgoing INVITE request.
call.makeCall("sip:+12011124111@sip.address:5060;transport=tcp", prm) ## Dev
print("CALLINFO",callinfo := call.getInfo())
print("STATE:", callinfo.state)
print("CALLID:", callinfo.id)
print("GET ID:", call.getId())
print("HAS MEDIA:", call.hasMedia())
except Exception as err:
print("ERR:",err)
# call.dump()
endpoint.libDestroy()
if __name__ == "__main__":
pj_test()
and here're the logs:
11:13:56.697 os_core_unix.c !pjlib 2.13 for POSIX initialized
11:13:56.698 sip_endpoint.c .Creating endpoint instance...
11:13:56.699 pjlib .select() I/O Queue created (0x7f7eb4836ed8)
11:13:56.699 sip_endpoint.c .Module "mod-msg-print" registered
11:13:56.699 sip_transport.c .Transport manager created.
11:13:56.699 pjsua_core.c .PJSUA state changed: NULL --> CREATED
11:13:56.699 sip_endpoint.c .Module "mod-pjsua-log" registered
11:13:56.699 sip_endpoint.c .Module "mod-tsx-layer" registered
11:13:56.699 sip_endpoint.c .Module "mod-stateful-util" registered
11:13:56.699 sip_endpoint.c .Module "mod-ua" registered
11:13:56.699 sip_endpoint.c .Module "mod-100rel" registered
11:13:56.699 sip_endpoint.c .Module "mod-pjsua" registered
11:13:56.700 sip_endpoint.c .Module "mod-invite" registered
11:13:56.773 coreaudio_dev.c ..core audio detected 5 devices
11:13:56.777 coreaudio_dev.c .. dev_id 73: Soundcore Life Note (in=1, out=0) 16000Hz
11:13:56.777 coreaudio_dev.c .. dev_id 67: Soundcore Life Note (in=0, out=2) 44100Hz
11:13:56.785 coreaudio_dev.c .. dev_id 53: Built-in Microphone (in=2, out=0) 44100Hz
11:13:56.786 coreaudio_dev.c .. dev_id 43: Built-in Output (in=0, out=2) 44100Hz
11:13:56.795 coreaudio_dev.c .. dev_id 60: ZoomAudioDevice (in=2, out=2) 48000Hz
11:13:56.795 coreaudio_dev.c ..core audio initialized
11:13:56.796 pjlib ..select() I/O Queue created (0x7f7eb4841828)
11:13:56.801 sip_endpoint.c .Module "mod-evsub" registered
11:13:56.801 sip_endpoint.c .Module "mod-presence" registered
11:13:56.801 sip_endpoint.c .Module "mod-mwi" registered
11:13:56.801 sip_endpoint.c .Module "mod-refer" registered
11:13:56.801 sip_endpoint.c .Module "mod-pjsua-pres" registered
11:13:56.801 sip_endpoint.c .Module "mod-pjsua-im" registered
11:13:56.801 sip_endpoint.c .Module "mod-pjsua-options" registered
11:13:56.801 pjsua_core.c .1 SIP worker threads created
11:13:56.801 pjsua_core.c .pjsua version 2.13 for Darwin-21.6/x86_64 initialized
11:13:56.801 pjsua_core.c .PJSUA state changed: CREATED --> INIT
Endpoint initialized..
11:13:56.802 tcptp:5060 SIP TCP listener ready for incoming connections at 192.111.111.11:5060
Transport created..
11:13:56.802 pjsua_core.c PJSUA state changed: INIT --> STARTING
11:13:56.802 sip_endpoint.c .Module "mod-unsolicited-mwi" registered
11:13:56.802 pjsua_core.c .PJSUA state changed: STARTING --> RUNNING
Endpoint started..
11:13:56.813 pjsua_acc.c Adding account: id=sip:111@111.111.1.1
11:13:56.813 pjsua_acc.c .Account sip:111@111.111.1.1 added with id 0
ACCOUNT? <__main__.MyAccount; proxy of <Swig Object of type 'pj::Account *' at 0x10261a820> >
Account created/registered..
Attempting to make a call...
11:13:56.816 pjsua_call.c Making call with acc #0 to sip:+12011124111@sip.address:5060;transport=tcp
11:13:56.816 pjsua_aud.c .Set sound device: capture=-1, playback=-2, mode=0, use_default_settings=0
11:13:56.816 pjsua_aud.c ..Opening sound device (speaker + mic) PCM@8000/1/20ms
11:13:56.833 coreaudio_dev.c ...Using VoiceProcessingIO audio unit
11:13:56.833 coreaudio_dev.c ...Warning: audio device id settings are ignored when using VPIO
11:13:58.514 coreaudio_dev.c ...core audio stream started
11:13:58.556 os_core_unix.c Info: possibly re-registering existing thread
11:13:58.677 tcpc0x7f7eb5856428 !.TCP client transport created
11:13:58.677 tcpc0x7f7eb5856428 .TCP transport 192.111.111.11:12121 is connecting to 12.115.110.139:5060...
11:13:58.677 pjsua_media.c .Call 0: initializing media..
11:13:58.702 pjsua_media.c ..RTCP socket bind() at 0.0.0.0:4001 error: Address already in use
11:13:58.702 pjsua_media.c ..RTP socket reachable at 192.111.111.11:4002
11:13:58.702 pjsua_media.c ..RTCP socket reachable at 192.111.111.11:4003
11:13:58.702 pjsua_media.c ..Media index 0 selected for audio call 0
11:13:58.702 udp0x7f7eb44500a0 ..UDP media transport created
11:13:58.703 pjsua_core.c ....TX 1432 bytes Request msg INVITE/cseq=5438 (tdta0x7f7eb48536a8) to TCP 12.115.110.139:5060:
INVITE sip:+12011124111@sip.address.ai:5060;transport=tcp SIP/2.0
Via: SIP/2.0/TCP 192.111.111.11:12121;rport;branch=z9hG4bKPj94DC87A8-F6E8-484A-8666-DA6FDF806591;alias
Max-Forwards: 70
From: sip:111@111.111.1.1;tag=DF19B94B-5324-4EA6-93FC-E85CCB4E3083
To: sip:+12011124111@sip.address
Contact: <sip:111@111.111.1.1:12121;transport=TCP;ob>
Call-ID: 53AF310B-070D-4F00-9AC9-5373F04A7C66
CSeq: 5438 INVITE
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Supported: replaces, 100rel, timer, norefersub
Session-Expires: 1800
Min-SE: 90
Content-Type: application/sdp
Content-Length: 777
v=0
o=- 3897447238 3897447238 IN IP4 192.111.111.11
s=pjmedia
b=AS:117
t=0 0
a=X-nat:0
m=audio 4002 RTP/AVP 96 97 98 99 3 0 8 9 100 101 120 121 122 123
c=IN IP4 192.111.111.11
b=TIAS:96000
a=rtcp:4003 IN IP4 192.111.111.11
a=sendrecv
a=rtpmap:96 speex/16000
a=rtpmap:97 speex/8000
a=rtpmap:98 speex/32000
a=rtpmap:99 iLBC/8000
a=fmtp:99 mode=30
a=rtpmap:3 GSM/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:9 G722/8000
a=rtpmap:100 AMR/8000
a=rtpmap:101 opus/48000/2
a=fmtp:101 useinbandfec=1
a=rtpmap:120 telephone-event/16000
a=fmtp:120 0-16
a=rtpmap:121 telephone-event/8000
a=fmtp:121 0-16
a=rtpmap:122 telephone-event/32000
a=fmtp:122 0-16
a=rtpmap:123 telephone-event/48000
a=fmtp:123 0-16
a=ssrc:809471301 cname:51c99fb30c13cab8
--end msg--
11:13:58.810 tcpc0x7f7eb5856428 !TCP transport 192.111.111.11:12121 is connected to 12.115.110.139:5060
THE STATE OF THE CALL HAS CHANGED: <pjsua2.OnCallStateParam; proxy of <Swig Object of type 'pj::OnCallStateParam *' at 0x10261a610> >
CONNECTED: False
current state is 1 CALLING
GET ID: 0
HAS MEDIA: False
CALLINFO <pjsua2.CallInfo; proxy of <Swig Object of type 'pj::CallInfo *' at 0x10261a640> >
STATE: 1
CALLID: 0
GET ID: 0
HAS MEDIA: False
11:14:03.712 pjsua_core.c !Shutting down, flags=0...
11:14:03.712 pjsua_core.c PJSUA state changed: RUNNING --> CLOSING
11:14:03.712 pjsua_core.c .RX 393 bytes Response msg 100/INVITE/cseq=5438 (rdata0x7f7eb5856708) from TCP 12.115.110.139:5060:
SIP/2.0 100 trying -- your call is important to us
Via: SIP/2.0/TCP 192.111.111.11:12121;rport=12121;branch=z9hG4bKPj94DC87A8-F6E8-484A-8666-DA6FDF806591;alias;received=62.103.179.193
From: sip:111@111.111.1.1;tag=DF19B94B-5324-4EA6-93FC-E85CCB4E3083
To: sip:+12011124111@sip.address.ai
Call-ID: 53AF310B-070D-4F00-9AC9-5373F04A7C66
CSeq: 5438 INVITE
Server: OmSBC
Content-Length: 0
--end msg--
11:14:03.712 pjsua_core.c .RX 1060 bytes Response msg 200/INVITE/cseq=5438 (rdata0x7f7eb5856708) from TCP 12.115.110.139:5060:
SIP/2.0 200 OK
Via: SIP/2.0/TCP 192.111.111.11:12121;rport=12121;received=62.103.179.193;branch=z9hG4bKPj94DC87A8-F6E8-484A-8666-DA6FDF806591;alias
Record-Route: <sip:10.163.28.132:5080;transport=tcp;lr;r2=on;did=b31.63b2;nat=yes>
Record-Route: <sip:12.115.110.139;transport=tcp;lr;r2=on;did=b31.63b2;nat=yes>
Call-ID: 53AF310B-070D-4F00-9AC9-5373F04A7C66
From: <sip:111@111.111.1.1>;tag=DF19B94B-5324-4EA6-93FC-E85CCB4E3083
To: <sip:+12011124111@sip.address>;tag=a1c3099f-9f54-48b9-affc-019adc7f44bc
CSeq: 5438 INVITE
Server: Asterisk PBX 18.7.1
Contact: <sip:10.163.29.13:5060;transport=TCP>
Allow: OPTIONS, SUBSCRIBE, NOTIFY, PUBLISH, INVITE, ACK, BYE, CANCEL, UPDATE, PRACK, MESSAGE, REFER
Supported: 100rel, timer, replaces, norefersub
Session-Expires: 1800;refresher=uac
Require: timer
Content-Type: application/sdp
Content-Length: 195
v=0
o=- 3897447238 3897447240 IN IP4 63.35.69.252
s=Asterisk
c=IN IP4 63.35.69.252
t=0 0
m=audio 34112 RTP/AVP 0
a=maxptime:150
a=rtpmap:0 PCMU/8000
a=sendrecv
a=rtcp:34113
a=ptime:20
--end msg--
THE STATE OF THE CALL HAS CHANGED: <pjsua2.OnCallStateParam; proxy of <Swig Object of type 'pj::OnCallStateParam *' at 0x10261a580> >
CONNECTED: False
current state is 4 CONNECTING
GET ID: 0
HAS MEDIA: False
11:14:08.715 inv0x7f7eb5025ea8 ....SDP negotiation done: Success
11:14:08.715 pjsua_call.c .....Unable to create media session: Object is busy (PJ_EBUSY) [status=70011]
11:14:08.715 pjsua_core.c ........TX 552 bytes Request msg BYE/cseq=5439 (tdta0x7f7eb38562a8) to TCP 12.115.110.139:5060:
BYE sip:10.163.29.13:5060;transport=TCP SIP/2.0
Via: SIP/2.0/TCP 192.111.111.11:12121;rport;branch=z9hG4bKPj9F2572CC-3E19-4857-8D61-86F294CB0FA9;alias
Max-Forwards: 70
From: sip:111@111.111.1.1;tag=DF19B94B-5324-4EA6-93FC-E85CCB4E3083
To: sip:+12011124111@sip.address;tag=a1c3099f-9f54-48b9-affc-019adc7f44bc
Call-ID: 53AF310B-070D-4F00-9AC9-5373F04A7C66
CSeq: 5439 BYE
Route: <sip:12.115.110.139;transport=tcp;lr;r2=on;did=b31.63b2;nat=yes>
Route: <sip:10.163.28.132:5080;transport=tcp;lr;r2=on;did=b31.63b2;nat=yes>
Content-Length: 0
As can be seen from the logs:
Unable to create media session: Object is busy (PJ_EBUSY) [status=70011]
I saw similar answers here, but those are for some android apps, and this is not something I'm working on. The solutions didn't have any effect either.
I'd be really grateful for any info or ideas!
endpoint.audDevManager().setNullDev()
was the solution. Without it, the library is trying to use the detected devices.