我正在使用 jNetPcap 从 tcpdumps 解码 rtp。目前,我使用 SIP 邀请消息和源 IP(还通过源 ips 检查..)来检测呼叫的方向(正向、反向).. 这是有效的,但实际上并不是按照 rfc 标准的预期工作方式并解决所有可能的行为。
有什么方法可以从 SSRC 确定源在哪个方向进行 sip 呼叫?据我所见,ssrc 标识符首先出现在 rtp 流上,我无法说出它是哪个呼叫流向。
而且我不想保存两个方向并让用户决定它是哪个方向。
无法仅从 RTP 流中确定是哪一方发出了呼叫。您需要捕获 INVITE/200/ACK 交换以从 IP 地址/端口/传输三元组映射到呼叫的参与者。听起来你已经在这样做了。
我不确定您所说的“但不是真正打算如何按照 rfc 标准工作”的意思。似乎 RTP 和 SIP 标准都在做他们应该做的事情。SIP 使用 SDP 将自己与直接了解媒体平面隔离开来,这允许 SIP 与任意媒体协议一起工作。
我做了脏解析,但似乎 jnetpcap 没有更好的方法来做到这一点:
private class JPacketHandlerSSRCs implements JPacketHandler<String> {
@Override
public void nextPacket(JPacket packet, String user) {
// TODO Auto-generated method stub
Udp udp = new Udp();
Rtp rtp = new Rtp();
Sdp sdp = new Sdp();
Sip sip = new Sip();
// get the source ip of the caller from the invite message.
// seems to be a tricky and dirty workaround, poor jnetpcap framework!
if(packet.hasHeader(sip) && packet.hasHeader(sdp)) {
if( (sip.getUTF8String(0, '@')).startsWith("INVITE ") ) {
String sdptext = sdp.text();
int pos = sdptext.indexOf("m=audio ") + 8;
int end = pos;
if(pos != -1)
while(sdptext.charAt(end) != ' ') end++;
rtp_forward_channel_port = Integer.parseInt(sdptext.substring(pos, end));
}
}
if(packet.hasHeader(udp))
if(rtp_forward_channel_port == udp.source() && packet.hasHeader(rtp)) {
try {
dos = getOutputStream(rtp.ssrc());
dos.write(rtp.getPayload());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}