1 /*******************************************************************************
2 * Copyright (c) 2014 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Vincent Perot - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.internal
.pcap
.core
.stream
;
15 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
17 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.endpoint
.ProtocolEndpointPair
;
18 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.packet
.Packet
;
19 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.protocol
.PcapProtocol
;
20 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.protocol
.pcap
.PcapPacket
;
22 import com
.google
.common
.math
.DoubleMath
;
24 // TODO decide if default modifier a good idea. This allows only the
25 // stream builder to call that method (and any class that is added to this
26 // package). This effectively makes the stream read-only.
29 * Class that represents a packet stream, which is a collection of packets that
30 * share the same endpoints. The endpoints of a packet are protocol-dependent.
31 * For example, a TCP stream is a collection of packets that share the same MAC
32 * address, IP address, and Port couple.
34 * @author Vincent Perot
36 public class PacketStream
{
38 private static final double SECOND_TO_NANOSECOND
= 1000000000.0;
39 private static final double DELTA
= 0.000000001;
40 private final PcapProtocol fProtocol
;
41 private final int fId
;
42 private final ProtocolEndpointPair fEndpointPair
;
44 private long fNbPacketsAtoB
;
45 private long fNbPacketsBtoA
;
46 private long fNbBytesAtoB
;
47 private long fNbBytesBtoA
;
48 private long fStartTime
;
49 private long fEndTime
;
52 * Constructor of a packet stream.
55 * The protocol of the packets of the stream. This is needed
56 * because the definition of a stream is protocol-dependent.
58 * The id of this stream.
60 * The common endpoints of the packets in this stream.
62 PacketStream(PcapProtocol protocol
, int id
, ProtocolEndpointPair endpointPair
) {
65 fEndpointPair
= endpointPair
;
70 fStartTime
= Long
.MAX_VALUE
;
71 fEndTime
= Long
.MIN_VALUE
;
75 * Add a packet to the stream.
78 * The packet that must be added.
80 synchronized void add(PcapPacket packet
) {
82 Packet newPacket
= packet
.getPacket(fProtocol
);
83 if (newPacket
== null) {
87 // Update packet and byte number
88 if (fEndpointPair
.getFirstEndpoint().equals(newPacket
.getSourceEndpoint()) &&
89 fEndpointPair
.getSecondEndpoint().equals(newPacket
.getDestinationEndpoint())) {
91 fNbBytesAtoB
+= packet
.getOriginalLength();
92 } else if (fEndpointPair
.getFirstEndpoint().equals(newPacket
.getDestinationEndpoint()) &&
93 fEndpointPair
.getSecondEndpoint().equals(newPacket
.getSourceEndpoint())) {
95 fNbBytesBtoA
+= packet
.getOriginalLength();
97 throw new IllegalStateException();
100 // Update start and stop time
101 // Stream timestamp is ALWAYS in nanoseconds.
103 switch (packet
.getTimestampScale()) {
105 timestamp
= packet
.getTimestamp() * 1000;
108 timestamp
= packet
.getTimestamp();
111 throw new IllegalArgumentException("The timestamp precision is not valid!"); //$NON-NLS-1$
113 fStartTime
= Math
.min(fStartTime
, timestamp
);
114 fEndTime
= Math
.max(fEndTime
, timestamp
);
118 * Get the Protocol of this stream.
120 * @return The protocol of this stream.
122 public PcapProtocol
getProtocol() {
127 * Method that returns the non-unique ID of this stream.
129 * @return the non-unique ID of this stream.
136 * Method that returns the unique ID of this stream.
138 * @return the unique ID of this stream.
140 public String
getUniqueID() {
141 return fProtocol
.getShortName() + '.' + fId
;
145 * Method that returns the endpoint pair of the stream.
147 * @return The endpoint pair of the stream.
149 public ProtocolEndpointPair
getEndpointPair() {
150 return fEndpointPair
;
153 // TODO return also the endpoint set.
155 public synchronized String
toString() {
156 StringBuilder sb
= new StringBuilder();
157 sb
.append("Stream " + getUniqueID() + ", Number of Packets: " + getNbPackets() + "\n"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
159 return checkNotNull(sb
.toString());
164 * Get the number of packets going from the first endpoint to the second.
166 * @return The number of packets from A to B.
168 public synchronized long getNbPacketsAtoB() {
169 return fNbPacketsAtoB
;
173 * Get the number of packets going from the second endpoint to the first.
175 * @return The number of packets from B to A.
177 public synchronized long getNbPacketsBtoA() {
178 return fNbPacketsBtoA
;
182 * Get the total number of packets in this stream.
184 * @return The total number of packets.
186 public synchronized long getNbPackets() {
187 return fNbPacketsAtoB
+ fNbPacketsBtoA
;
191 * Get the number of bytes going from the first endpoint to the second.
193 * @return The number of bytes from A to B.
195 public synchronized long getNbBytesAtoB() {
200 * Get the number of bytes going from the second endpoint to the first.
202 * @return The number of bytes from B to A.
204 public synchronized long getNbBytesBtoA() {
209 * Get the total number of bytes in this stream.
211 * @return The total number of bytes.
213 public synchronized long getNbBytes() {
214 return fNbBytesAtoB
+ fNbBytesBtoA
;
218 * Get the start time of this stream, in nanoseconds relative to epoch.
220 * @return The start time.
222 public synchronized long getStartTime() {
227 * Get the stop time of this stream, in nanoseconds relative to epoch.
229 * @return The stop time.
231 public synchronized long getStopTime() {
236 * Get the duration of this stream, in seconds
238 * @return The duration of this stream.
240 public synchronized double getDuration() {
241 return (fEndTime
- fStartTime
) / SECOND_TO_NANOSECOND
;
245 * Get the the average byte per second from A to B.
247 * @return the average byte per second from A to B.
249 public synchronized double getBPSAtoB() {
250 if (DoubleMath
.fuzzyEquals(getDuration(), 0, DELTA
)) {
253 return fNbBytesAtoB
/ getDuration();
257 * Get the the average byte per second from B to A.
259 * @return the average byte per second from B to A.
261 public synchronized double getBPSBtoA() {
262 if (DoubleMath
.fuzzyEquals(getDuration(), 0, DELTA
)) {
265 return fNbBytesBtoA
/ getDuration();