diff --git a/lib/installer-exclude/ice4j.jar b/lib/installer-exclude/ice4j.jar
index 8806069d1..8c4922e49 100644
Binary files a/lib/installer-exclude/ice4j.jar and b/lib/installer-exclude/ice4j.jar differ
diff --git a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPInputStream.java b/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPInputStream.java
index 31556a2b6..7b4750f3f 100644
--- a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPInputStream.java
+++ b/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPInputStream.java
@@ -11,6 +11,7 @@
import net.java.sip.communicator.service.packetlogging.*;
import net.java.sip.communicator.util.*;
+import org.ice4j.socket.*;
/**
* RTPConnectorInputStream implementation for TCP protocol.
@@ -86,6 +87,11 @@ protected void doLogPacket(DatagramPacket p)
if(socket.getLocalAddress() == null)
return;
+ // Do not log the packet if this one has been processed (and already
+ // logged) by the ice4j stack.
+ if(socket instanceof MultiplexingSocket)
+ return;
+
PacketLoggingService packetLogging
= NeomediaActivator.getPacketLogging();
diff --git a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPOutputStream.java b/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPOutputStream.java
index 590da6ff4..c4e2819dc 100644
--- a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPOutputStream.java
+++ b/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPOutputStream.java
@@ -10,6 +10,7 @@
import java.net.*;
import net.java.sip.communicator.service.packetlogging.*;
+import org.ice4j.socket.*;
/**
* RTPConnectorOutputStream implementation for TCP protocol.
@@ -62,6 +63,11 @@ protected void sendToTarget(RawPacket packet, InetSocketAddress target)
*/
protected void doLogPacket(RawPacket packet, InetSocketAddress target)
{
+ // Do not log the packet if this one has been processed (and already
+ // logged) by the ice4j stack.
+ if(socket instanceof MultiplexingSocket)
+ return;
+
PacketLoggingService packetLogging
= NeomediaActivator.getPacketLogging();
diff --git a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPInputStream.java b/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPInputStream.java
index 3ca3888f2..4cef9e3b0 100644
--- a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPInputStream.java
+++ b/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPInputStream.java
@@ -10,6 +10,7 @@
import java.net.*;
import net.java.sip.communicator.service.packetlogging.*;
+import org.ice4j.socket.*;
/**
* RTPConnectorInputStream implementation for UDP protocol.
@@ -70,6 +71,11 @@ protected void doLogPacket(DatagramPacket p)
if(socket.getLocalAddress() == null)
return;
+ // Do not log the packet if this one has been processed (and already
+ // logged) by the ice4j stack.
+ if(socket instanceof MultiplexingDatagramSocket)
+ return;
+
PacketLoggingService packetLogging
= NeomediaActivator.getPacketLogging();
diff --git a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPOutputStream.java b/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPOutputStream.java
index 6192f3f96..de2b00e2e 100644
--- a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPOutputStream.java
+++ b/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPOutputStream.java
@@ -10,6 +10,7 @@
import java.net.*;
import net.java.sip.communicator.service.packetlogging.*;
+import org.ice4j.socket.*;
/**
* RTPConnectorOutputStream implementation for UDP protocol.
@@ -65,6 +66,11 @@ protected void sendToTarget(RawPacket packet, InetSocketAddress target)
*/
protected void doLogPacket(RawPacket packet, InetSocketAddress target)
{
+ // Do not log the packet if this one has been processed (and already
+ // logged) by the ice4j stack.
+ if(socket instanceof MultiplexingDatagramSocket)
+ return;
+
PacketLoggingService packetLogging
= NeomediaActivator.getPacketLogging();
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesCandidateDatagramSocket.java b/src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesCandidateDatagramSocket.java
index 54b6ba699..4d88ecaa3 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesCandidateDatagramSocket.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesCandidateDatagramSocket.java
@@ -11,6 +11,7 @@
import org.ice4j.*;
import org.ice4j.stack.*;
+import org.ice4j.socket.*;
/**
* Represents an application-purposed (as opposed to an ICE-specific)
@@ -31,6 +32,31 @@ public class JingleNodesCandidateDatagramSocket extends DatagramSocket
*/
private JingleNodesCandidate jingleNodesCandidate;
+ /**
+ * The number of RTP packets received for this socket.
+ */
+ private long nbReceivedRtpPackets = 0;
+
+ /**
+ * The number of RTP packets sent for this socket.
+ */
+ private long nbSentRtpPackets = 0;
+
+ /**
+ * The number of RTP packets lost (not received) for this socket.
+ */
+ private long nbLostRtpPackets = 0;
+
+ /**
+ * The last RTP sequence number received for this socket.
+ */
+ private long lastRtpSequenceNumber = -1;
+
+ /**
+ * The last time an information about packet lost has been logged.
+ */
+ private long lastLostPacketLogTime = 0;
+
/**
* Initializes a new JingleNodesdCandidateDatagramSocket instance
* which is to be the socket of a specific
@@ -82,19 +108,15 @@ public void send(DatagramPacket p)
//XXX reuse an existing DatagramPacket ?
super.send(packet);
- // no exception packet is successfully sent, log it
- if(StunStack.isPacketLoggerEnabled())
- {
- StunStack.getPacketLogger().logPacket(
- super.getLocalAddress().getAddress(),
- super.getLocalPort(),
- packet.getAddress().getAddress(),
- packet.getPort(),
- packet.getData(),
- true);
- }
+ // no exception packet is successfully sent, log it.
+ ++nbSentRtpPackets;
+ DelegatingDatagramSocket.logPacketToPcap(
+ packet,
+ this.nbSentRtpPackets,
+ true,
+ super.getLocalAddress(),
+ super.getLocalPort());
}
-
/**
* Receives a DatagramPacket from this socket. The DatagramSocket
@@ -110,17 +132,16 @@ public void receive(DatagramPacket p)
{
super.receive(p);
- // no exception packet is successfully received, log it
- if(StunStack.isPacketLoggerEnabled())
- {
- StunStack.getPacketLogger().logPacket(
- p.getAddress().getAddress(),
- p.getPort(),
- super.getLocalAddress().getAddress(),
- super.getLocalPort(),
- p.getData(),
- false);
- }
+ // no exception packet is successfully received, log it.
+ ++nbReceivedRtpPackets;
+ DelegatingDatagramSocket.logPacketToPcap(
+ p,
+ this.nbReceivedRtpPackets,
+ false,
+ super.getLocalAddress(),
+ super.getLocalPort());
+ // Log RTP losses if > 5%.
+ updateRtpLosses(p);
}
/**
@@ -178,4 +199,30 @@ public InetSocketAddress getLocalSocketAddress()
{
return jingleNodesCandidate.getTransportAddress();
}
+
+ /**
+ * Updates and Logs information about RTP losses if there is more then 5% of
+ * RTP packet lost (at most every 5 seconds).
+ *
+ * @param p The last packet received.
+ */
+ public void updateRtpLosses(DatagramPacket p)
+ {
+ // If this is not a STUN/TURN packet, then this is a RTP packet.
+ if(!StunDatagramPacketFilter.isStunPacket(p))
+ {
+ long newSeq = DelegatingDatagramSocket.getRtpSequenceNumber(p);
+ if(this.lastRtpSequenceNumber != -1)
+ {
+ nbLostRtpPackets += DelegatingDatagramSocket
+ .getNbLost(this.lastRtpSequenceNumber, newSeq);
+ }
+ this.lastRtpSequenceNumber = newSeq;
+
+ this.lastLostPacketLogTime = DelegatingDatagramSocket.logRtpLosses(
+ this.nbLostRtpPackets,
+ this.nbReceivedRtpPackets,
+ this.lastLostPacketLogTime);
+ }
+ }
}