Я занимаюсь разработкой SIP-контроллера на Java с использованием NIST-реализации JAIN SIP API.
У меня проблемы с вызовом с моего SIP-контроллера на программный телефон через Asterisk.
Если я звоню на софтфон напрямую (не через Asterisk), используя его IP-адрес и номер порта, все работает нормально. Вызов устанавливается, программный телефон слышит звук (данные RTP), который я отправляю, и я могу получить звук, который он мне отправляет.
Однако, когда я звоню на тот же программный телефон через Asterisk, вызов устанавливается, и я начинаю получать данные RTP с программного телефона (через Asterisk). Теперь мой поток отправки требует немного времени для настройки, но пока он настраивается, я получаю данные RTP с программного телефона. Проблема в том, что как только мой поток отправки инициализируется и начинает передавать данные RTP, я прекращаю получать данные RTP с программного телефона! В результате после установления вызова я слышу софтфон максимум полсекунды или секунды, а затем ничего. На этом этапе софтфон может слышать мои исходящие RTP-данные, но я не слышу их.
Если я не начинаю передавать какие-либо данные RTP, я продолжаю получать данные RTP с программного телефона. Но как только я начинаю передачу, он перестает приходить!
В случае, если это помогает, вот тип SIP-диалога, который устанавливает вызов (>> указывает на исходящее сообщение, а << указывает на входящее сообщение): </p>
>> INVITE sip:301@asterisk SIP/2.0
Call-ID: 8b92ba1ca9c922bcd266dce086596ce4@10.0.85.3
CSeq: 1 INVITE
From: <sip:null>;tag=JqbJKA
To: <sip:301@asterisk>
Via: SIP/2.0/UDP 10.0.85.3:5060;branch=z9hG4bK34d24b3f748ac08a5ca46f500f110d38353436
Max-Forwards: 70
Contact: <sip:10.0.85.3:5060>
Route: <sip:10.0.84.30;lr>
Content-Type: application/sdp
Content-Length: 106
v=0
o=- 3515232260 3515232260 IN IP4 10.0.85.3
s=-
c=IN IP4 10.0.85.3
t=0 0
m=audio 42138 RTP/AVP 0
a=rtpmap:0 PCMU/8000
<< SIP/2.0 407 Proxy Authentication Required
Via: SIP/2.0/UDP 10.0.85.3:5060;branch=z9hG4bK34d24b3f748ac08a5ca46f500f110d38353436;received=10.0.85.3
From: <sip:null>;tag=JqbJKA
To: <sip:301@asterisk>;tag=as7077f414
Call-ID: 8b92ba1ca9c922bcd266dce086596ce4@10.0.85.3
CSeq: 1 INVITE
User-Agent: Asterisk PBX (switchvox)
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY
Contact: <sip:301@10.0.84.30>
Proxy-Authenticate: Digest realm="asterisk",nonce="4a1cbda4"
Content-Length: 0
>> INVITE sip:301@asterisk SIP/2.0
CSeq: 2 INVITE
From: <sip:303@asterisk>;tag=JqbJKA
To: <sip:301@asterisk>
Via: SIP/2.0/UDP 10.0.85.3:5060;branch=z9hG4bKd1870f50e9fbf883b3e64fa3ef75dda9353436
Max-Forwards: 70
Contact: <sip:10.0.85.3:5060>
Route: <sip:10.0.84.30;lr>
Proxy-Authorization: Digest username="303",realm="asterisk",nonce="4a1cbda4",response="249b2b7d7c0e7b54499c632ba410365c",algorithm=MD5,uri="sip:301@asterisk",nc=00000001
Call-ID: 8b92ba1ca9c922bcd266dce086596ce4@10.0.85.3
Content-Type: application/sdp
Content-Length: 106
v=0
o=- 3515232260 3515232260 IN IP4 10.0.85.3
s=-
c=IN IP4 10.0.85.3
t=0 0
m=audio 42138 RTP/AVP 0
a=rtpmap:0 PCMU/8000`
`<< SIP/2.0 100 Trying
Via: SIP/2.0/UDP 10.0.85.3:5060;branch=z9hG4bKd1870f50e9fbf883b3e64fa3ef75dda9353436;received=10.0.85.3
From: <sip:303@asterisk>;tag=JqbJKA
To: <sip:301@asterisk>
Call-ID: 8b92ba1ca9c922bcd266dce086596ce4@10.0.85.3
CSeq: 2 INVITE
User-Agent: Asterisk PBX (switchvox)
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,R EFER,SUBSCRIBE,NOTIFY
Contact: <sip:301@10.0.84.30>
Content-Length: 0
`<< SIP/2.0 180 Ringing
Via: SIP/2.0/UDP 10.0.85.3:5060;branch=z9hG4bKd1870f50e9fbf883b3e64fa3ef75dda9353436;received=10.0.85.3
From: <sip:303@asterisk>;tag=JqbJKA
To: <sip:301@asterisk>;tag=as00faa25e
Call-ID: 8b92ba1ca9c922bcd266dce086596ce4@10.0.85.3
CSeq: 2 INVITE
User-Agent: Asterisk PBX (switchvox)
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY
Contact: <sip:301@10.0.84.30>
Content-Length: 0`
<< SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.0.85.3:5060;branch=z9hG4bKd1870f50e9fbf883b3e64fa3ef75dda9353436;received=10.0.85.3
From: <sip:303@asterisk>;tag=JqbJKA
To: <sip:301@asterisk>;tag=as00faa25e
Call-ID: 8b92ba1ca9c922bcd266dce086596ce4@10.0.85.3
CSeq: 2 INVITE
User-Agent: Asterisk PBX (switchvox)
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY
Contact: <sip:301@10.0.84.30>
Content-Type: application/sdp
Content-Length: 154
v=0
o=root 2593 2593 IN IP4 10.0.84.30
s=session
c=IN IP4 10.0.84.30
t=0 0
m=audio 10294 RTP/AVP 0
a=rtpmap:0 PCMU/8000
a=silenceSupp:off - - - -
>> ACK sip:301@10.0.84.30 SIP/2.0
Call-ID: 8b92ba1ca9c922bcd266dce086596ce4@10.0.85.3
CSeq: 2 ACK
Via: SIP/2.0/UDP 10.0.85.3:5060;branch=z9hG4bK7e16ebc0de9c6eaf901db0e2e58f495f353436
From: <sip:303@asterisk>;tag=JqbJKA
To: <sip:301@asterisk>;tag=as00faa25e
Max-Forwards: 70
Contact: <sip:10.0.85.3:5060>
Content-Length: 0
Вот код, который устанавливает RTP-сессию. Сначала несколько объявлений:
private RTPManager sessionManager = null;
private Processor processor = null;
private SendStream sendStream;`
Сначала вызывается следующий метод:
public void startMedia(String peerIp,int peerPort,int receivePort,String format) throws IOException,MediaException,InvalidSessionAddressException
{
stopMedia();
this.format = format;
RTPSessionMgr rtpSessionMgr = new RTPSessionMgr();
rtpSessionMgr.initSession(new SessionAddress(),null,0.05,0.25);
InetAddress localhost = InetAddress.getLocalHost();
SessionAddress localAddr = new SessionAddress(localhost,receivePort,localhost,receivePort + 1);
InetAddress destAddr = InetAddress.getByName(peerIp);
rtpSessionMgr.startSession(localAddr,localAddr,new SessionAddress(destAddr,peerPort,destAddr,peerPort + 1),null);
sessionManager = rtpSessionMgr;
for (ReceiveStreamListener nextListener : receiveStreamListeners)
sessionManager.addReceiveStreamListener(nextListener);
}
Затем, чтобы начать воспроизведение звука через RTP, этот метод называется:
public void transmitSound(DataSource ds) throws NoProcessorException,IOException,UnsupportedFormatException,NotRealizedError
{
stopTransmittingSound();
processor = Manager.createProcessor(ds);
for (ControllerListener nextListener : controllerListeners)
processor.addControllerListener(nextListener);
processor.addControllerListener(myControllerListener);
processor.configure();
}
Вот метод controllerUpdate () прослушивателя контроллера:
public void controllerUpdate(ControllerEvent event)
{
if (processor.getState()==Processor.Configured)
{
processor.setContentDescriptor(new ContentDescriptor(ContentDescriptor.RAW_RTP));
processor.getTrackControls()[0].setFormat(new AudioFormat(format,8000,8,1));
processor.realize();
}
else if (processor.getState()==Processor.Realized)
{
try
{
sendStream = sessionManager.createSendStream(processor.getDataOutput(),0);
sendStream.start();
processor.start();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (UnsupportedFormatException e)
{
e.printStackTrace();
}
catch (NotRealizedError e)
{
e.printStackTrace();
}
}
}
Это то, что в основном происходит после отправки ACK:
- Я создаю RTP-сеанс для передачи и прослушивания.
- Я начинаю инициализацию процессора для передачи RTP.
- Тем временем я получаю много RTP-данных.
- Процессор завершает инициализацию, и я начинаю отправлять RTP-данные.
- На этом этапе я прекращаю получать RTP-данные при переходе через Asterisk. При прямом вызове софтфона все работает нормально.
Есть идеи?