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
.tmf
.pcap
.core
.trace
;
15 import java
.io
.IOException
;
16 import java
.nio
.channels
.ClosedChannelException
;
17 import java
.nio
.file
.FileSystems
;
18 import java
.nio
.file
.Path
;
19 import java
.util
.Collection
;
22 import org
.eclipse
.core
.resources
.IProject
;
23 import org
.eclipse
.core
.resources
.IResource
;
24 import org
.eclipse
.core
.runtime
.IStatus
;
25 import org
.eclipse
.core
.runtime
.Status
;
26 import org
.eclipse
.jdt
.annotation
.NonNull
;
27 import org
.eclipse
.jdt
.annotation
.Nullable
;
28 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.packet
.BadPacketException
;
29 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.protocol
.pcap
.PcapPacket
;
30 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.trace
.BadPcapFileException
;
31 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.trace
.PcapFile
;
32 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.util
.LinkTypeHelper
;
33 import org
.eclipse
.tracecompass
.internal
.tmf
.pcap
.core
.Activator
;
34 import org
.eclipse
.tracecompass
.internal
.tmf
.pcap
.core
.event
.PcapEvent
;
35 import org
.eclipse
.tracecompass
.internal
.tmf
.pcap
.core
.event
.aspect
.PcapDestinationAspect
;
36 import org
.eclipse
.tracecompass
.internal
.tmf
.pcap
.core
.event
.aspect
.PcapProtocolAspect
;
37 import org
.eclipse
.tracecompass
.internal
.tmf
.pcap
.core
.event
.aspect
.PcapReferenceAspect
;
38 import org
.eclipse
.tracecompass
.internal
.tmf
.pcap
.core
.event
.aspect
.PcapSourceAspect
;
39 import org
.eclipse
.tracecompass
.internal
.tmf
.pcap
.core
.util
.PcapEventFactory
;
40 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
41 import org
.eclipse
.tracecompass
.tmf
.core
.event
.aspect
.ITmfEventAspect
;
42 import org
.eclipse
.tracecompass
.tmf
.core
.exceptions
.TmfTraceException
;
43 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfContext
;
44 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfEventParser
;
45 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTraceProperties
;
46 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfContext
;
47 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTrace
;
48 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TraceValidationStatus
;
49 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.location
.ITmfLocation
;
50 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.location
.TmfLongLocation
;
52 import com
.google
.common
.collect
.ImmutableList
;
53 import com
.google
.common
.collect
.ImmutableMap
;
56 * Class that represents a TMF Pcap Trace. It is used to make the glue between
57 * the Pcap parser and TMF.
59 * TODO handle fields in TmfEventType for the filter view.
61 * @author Vincent Perot
63 public class PcapTrace
extends TmfTrace
implements ITmfEventParser
, ITmfTraceProperties
, AutoCloseable
{
65 @SuppressWarnings("null")
66 private static final @NonNull Collection
<ITmfEventAspect
> PCAP_ASPECTS
= ImmutableList
.of(
67 ITmfEventAspect
.BaseAspects
.TIMESTAMP
,
68 new PcapSourceAspect(),
69 new PcapDestinationAspect(),
70 new PcapReferenceAspect(),
71 new PcapProtocolAspect(),
72 ITmfEventAspect
.BaseAspects
.CONTENTS
75 @SuppressWarnings("null")
76 private static final @NonNull Map
<String
, String
> EMPTY_MAP
= ImmutableMap
.of();
77 private static final String EMPTY_STRING
= ""; //$NON-NLS-1$
78 private static final int CONFIDENCE
= 50;
79 private @Nullable PcapFile fPcapFile
;
80 private @Nullable ImmutableMap
<String
, String
> fTraceProperties
= null;
83 public synchronized ITmfLocation
getCurrentLocation() {
84 PcapFile pcap
= fPcapFile
;
86 return new TmfLongLocation(0);
88 return new TmfLongLocation(pcap
.getCurrentRank());
92 public synchronized double getLocationRatio(@Nullable ITmfLocation location
) {
93 TmfLongLocation loc
= (TmfLongLocation
) location
;
94 PcapFile pcap
= fPcapFile
;
95 if (loc
== null || pcap
== null) {
99 return (pcap
.getTotalNbPackets() == 0 ?
0 : ((double) loc
.getLocationInfo()) / pcap
.getTotalNbPackets());
100 } catch (IOException
| BadPcapFileException e
) {
101 String message
= e
.getMessage();
102 if (message
== null) {
103 message
= EMPTY_STRING
;
105 Activator
.logError(message
, e
);
112 public synchronized void initTrace(@Nullable IResource resource
, @Nullable String path
, @Nullable Class
<?
extends ITmfEvent
> type
) throws TmfTraceException
{
113 super.initTrace(resource
, path
, type
);
115 throw new TmfTraceException("No path has been specified."); //$NON-NLS-1$
117 @SuppressWarnings("null")
118 @NonNull Path filePath
= FileSystems
.getDefault().getPath(path
);
120 fPcapFile
= new PcapFile(filePath
);
121 } catch (IOException
| BadPcapFileException e
) {
122 throw new TmfTraceException(e
.getMessage(), e
);
127 public Iterable
<ITmfEventAspect
> getEventAspects() {
132 public synchronized @Nullable PcapEvent
parseEvent(@Nullable ITmfContext context
) {
133 if (context
== null) {
137 long rank
= context
.getRank();
138 PcapPacket packet
= null;
139 PcapFile pcap
= fPcapFile
;
144 pcap
.seekPacket(rank
);
145 packet
= pcap
.parseNextPacket();
146 } catch (ClosedChannelException e
) {
148 * This is handled independently and happens when the user closes
149 * the trace while it is being parsed. It simply stops the parsing.
150 * No need to log a error.
153 } catch (IOException
| BadPcapFileException
| BadPacketException e
) {
154 String message
= e
.getMessage();
155 if (message
== null) {
156 message
= EMPTY_STRING
;
158 Activator
.logError(message
, e
);
162 if (packet
== null) {
166 // Generate an event from this packet and return it.
167 return PcapEventFactory
.createEvent(packet
, pcap
, this);
172 public synchronized ITmfContext
seekEvent(double ratio
) {
174 PcapFile pcap
= fPcapFile
;
176 return new TmfContext(new TmfLongLocation(0), 0);
181 * The ratio is between 0 and 1. We multiply it by the total number
182 * of packets to get the position.
184 position
= (long) (ratio
* pcap
.getTotalNbPackets());
185 } catch (IOException
| BadPcapFileException e
) {
186 String message
= e
.getMessage();
187 if (message
== null) {
188 message
= EMPTY_STRING
;
190 Activator
.logError(message
, e
);
191 return new TmfContext(new TmfLongLocation(0), 0);
193 TmfLongLocation loc
= new TmfLongLocation(position
);
194 return new TmfContext(loc
, loc
.getLocationInfo());
198 public synchronized ITmfContext
seekEvent(@Nullable ITmfLocation location
) {
199 TmfLongLocation loc
= (TmfLongLocation
) location
;
201 return new TmfContext(new TmfLongLocation(0));
204 return new TmfContext(loc
, loc
.getLocationInfo());
208 public IStatus
validate(@Nullable IProject project
, @Nullable String path
) {
210 // All validations are made when making a new pcap file.
212 return new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, EMPTY_STRING
);
214 @SuppressWarnings("null")
215 @NonNull Path filePath
= FileSystems
.getDefault().getPath(path
);
216 try (PcapFile file
= new PcapFile(filePath
)) {
217 } catch (IOException
| BadPcapFileException e
) {
218 return new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, e
.toString());
220 return new TraceValidationStatus(CONFIDENCE
, Activator
.PLUGIN_ID
);
224 public synchronized void dispose() {
226 PcapFile pcap
= fPcapFile
;
233 } catch (IOException e
) {
234 String message
= e
.getMessage();
235 if (message
== null) {
236 message
= EMPTY_STRING
;
238 Activator
.logError(message
, e
);
244 public synchronized Map
<String
, String
> getTraceProperties() {
245 PcapFile pcap
= fPcapFile
;
250 ImmutableMap
<String
, String
> properties
= fTraceProperties
;
251 if (properties
== null) {
252 @SuppressWarnings("null")
253 @NonNull ImmutableMap
<String
, String
> newProperties
= ImmutableMap
.<String
, String
> builder()
254 .put(Messages
.PcapTrace_Version
, String
.format("%d%c%d", pcap
.getMajorVersion(), '.', pcap
.getMinorVersion())) //$NON-NLS-1$
255 .put(Messages
.PcapTrace_TimeZoneCorrection
, pcap
.getTimeZoneCorrection() + " s") //$NON-NLS-1$
256 .put(Messages
.PcapTrace_TimestampAccuracy
, String
.valueOf(pcap
.getTimeAccuracy()))
257 .put(Messages
.PcapTrace_MaxSnapLength
, pcap
.getSnapLength() + " bytes") //$NON-NLS-1$
258 .put(Messages
.PcapTrace_LinkLayerHeaderType
, LinkTypeHelper
.toString((int) pcap
.getDataLinkType()) + " (" + pcap
.getDataLinkType() + ")") //$NON-NLS-1$ //$NON-NLS-2$
259 .put(Messages
.PcapTrace_FileEndianness
, pcap
.getByteOrder().toString())
261 fTraceProperties
= newProperties
;
262 return newProperties
;
270 public void close() {