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
.linuxtools
.tmf
.pcap
.core
.trace
;
15 import java
.io
.IOException
;
16 import java
.nio
.channels
.ClosedChannelException
;
19 import org
.eclipse
.core
.resources
.IProject
;
20 import org
.eclipse
.core
.resources
.IResource
;
21 import org
.eclipse
.core
.runtime
.IStatus
;
22 import org
.eclipse
.core
.runtime
.Status
;
23 import org
.eclipse
.jdt
.annotation
.NonNull
;
24 import org
.eclipse
.jdt
.annotation
.Nullable
;
25 import org
.eclipse
.linuxtools
.internal
.tmf
.pcap
.core
.Activator
;
26 import org
.eclipse
.linuxtools
.internal
.tmf
.pcap
.core
.util
.PcapEventFactory
;
27 import org
.eclipse
.linuxtools
.pcap
.core
.packet
.BadPacketException
;
28 import org
.eclipse
.linuxtools
.pcap
.core
.protocol
.pcap
.PcapPacket
;
29 import org
.eclipse
.linuxtools
.pcap
.core
.trace
.BadPcapFileException
;
30 import org
.eclipse
.linuxtools
.pcap
.core
.trace
.PcapFile
;
31 import org
.eclipse
.linuxtools
.pcap
.core
.util
.LinkTypeHelper
;
32 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
33 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.TmfTraceException
;
34 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfContext
;
35 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfEventParser
;
36 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTraceProperties
;
37 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfContext
;
38 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfTrace
;
39 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TraceValidationStatus
;
40 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.location
.ITmfLocation
;
41 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.location
.TmfLongLocation
;
42 import org
.eclipse
.linuxtools
.tmf
.pcap
.core
.event
.PcapEvent
;
44 import com
.google
.common
.collect
.ImmutableMap
;
47 * Class that represents a TMF Pcap Trace. It is used to make the glue between
48 * the Pcap parser and TMF.
50 * TODO handle fields in TmfEventType for the filter view.
52 * @author Vincent Perot
54 public class PcapTrace
extends TmfTrace
implements ITmfEventParser
, ITmfTraceProperties
, AutoCloseable
{
56 @SuppressWarnings("null")
57 private static final @NonNull Map
<String
, String
> EMPTY_MAP
= ImmutableMap
.of();
58 private static final String EMPTY_STRING
= ""; //$NON-NLS-1$
59 private static final int CONFIDENCE
= 50;
60 private @Nullable PcapFile fPcapFile
;
61 private @Nullable ImmutableMap
<String
, String
> fTraceProperties
= null;
64 public synchronized ITmfLocation
getCurrentLocation() {
65 PcapFile pcap
= fPcapFile
;
67 return new TmfLongLocation(0);
69 return new TmfLongLocation(pcap
.getCurrentRank());
73 public synchronized double getLocationRatio(@Nullable ITmfLocation location
) {
74 TmfLongLocation loc
= (TmfLongLocation
) location
;
75 PcapFile pcap
= fPcapFile
;
76 if (loc
== null || pcap
== null) {
80 return (pcap
.getTotalNbPackets() == 0 ?
0 : ((double) loc
.getLocationInfo()) / pcap
.getTotalNbPackets());
81 } catch (IOException
| BadPcapFileException e
) {
82 String message
= e
.getMessage();
83 if (message
== null) {
84 message
= EMPTY_STRING
;
86 Activator
.logError(message
, e
);
93 public synchronized void initTrace(@Nullable IResource resource
, @Nullable String path
, @Nullable Class
<?
extends ITmfEvent
> type
) throws TmfTraceException
{
94 super.initTrace(resource
, path
, type
);
96 throw new TmfTraceException("No path has been specified."); //$NON-NLS-1$
99 fPcapFile
= new PcapFile(path
);
100 } catch (IOException
| BadPcapFileException e
) {
101 throw new TmfTraceException(e
.getMessage(), e
);
106 public synchronized @Nullable PcapEvent
parseEvent(@Nullable ITmfContext context
) {
107 if (context
== null) {
111 long rank
= context
.getRank();
112 PcapPacket packet
= null;
113 PcapFile pcap
= fPcapFile
;
118 pcap
.seekPacket(rank
);
119 packet
= pcap
.parseNextPacket();
120 } catch (ClosedChannelException e
) {
122 * This is handled independently and happens when the user closes
123 * the trace while it is being parsed. It simply stops the parsing.
124 * No need to log a error.
127 } catch (IOException
| BadPcapFileException
| BadPacketException e
) {
128 String message
= e
.getMessage();
129 if (message
== null) {
130 message
= EMPTY_STRING
;
132 Activator
.logError(message
, e
);
136 if (packet
== null) {
140 // Generate an event from this packet and return it.
141 return PcapEventFactory
.createEvent(packet
, pcap
, this);
146 public synchronized ITmfContext
seekEvent(double ratio
) {
148 PcapFile pcap
= fPcapFile
;
150 return new TmfContext(new TmfLongLocation(0), 0);
155 * The ratio is between 0 and 1. We multiply it by the total number
156 * of packets to get the position.
158 position
= (long) (ratio
* pcap
.getTotalNbPackets());
159 } catch (IOException
| BadPcapFileException e
) {
160 String message
= e
.getMessage();
161 if (message
== null) {
162 message
= EMPTY_STRING
;
164 Activator
.logError(message
, e
);
165 return new TmfContext(new TmfLongLocation(0), 0);
167 TmfLongLocation loc
= new TmfLongLocation(position
);
168 return new TmfContext(loc
, loc
.getLocationInfo());
172 public synchronized ITmfContext
seekEvent(@Nullable ITmfLocation location
) {
173 TmfLongLocation loc
= (TmfLongLocation
) location
;
175 return new TmfContext(new TmfLongLocation(0));
178 return new TmfContext(loc
, loc
.getLocationInfo());
182 public IStatus
validate(@Nullable IProject project
, @Nullable String path
) {
184 // All validations are made when making a new pcap file.
186 return new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, EMPTY_STRING
);
188 try (PcapFile file
= new PcapFile(path
)) {
189 } catch (IOException
| BadPcapFileException e
) {
190 return new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, e
.toString());
192 return new TraceValidationStatus(CONFIDENCE
, Activator
.PLUGIN_ID
);
196 public synchronized void dispose() {
198 PcapFile pcap
= fPcapFile
;
205 } catch (IOException e
) {
206 String message
= e
.getMessage();
207 if (message
== null) {
208 message
= EMPTY_STRING
;
210 Activator
.logError(message
, e
);
216 public synchronized Map
<String
, String
> getTraceProperties() {
217 PcapFile pcap
= fPcapFile
;
222 ImmutableMap
<String
, String
> properties
= fTraceProperties
;
223 if (properties
== null) {
224 @SuppressWarnings("null")
225 @NonNull ImmutableMap
<String
, String
> newProperties
= ImmutableMap
.<String
, String
> builder()
226 .put(Messages
.PcapTrace_Version
, String
.format("%d%c%d", pcap
.getMajorVersion(), '.', pcap
.getMinorVersion())) //$NON-NLS-1$
227 .put(Messages
.PcapTrace_TimeZoneCorrection
, pcap
.getTimeZoneCorrection() + " s") //$NON-NLS-1$
228 .put(Messages
.PcapTrace_TimestampAccuracy
, String
.valueOf(pcap
.getTimeAccuracy()))
229 .put(Messages
.PcapTrace_MaxSnapLength
, pcap
.getSnapLength() + " bytes") //$NON-NLS-1$
230 .put(Messages
.PcapTrace_LinkLayerHeaderType
, LinkTypeHelper
.toString((int) pcap
.getDataLinkType()) + " (" + pcap
.getDataLinkType() + ")") //$NON-NLS-1$ //$NON-NLS-2$
231 .put(Messages
.PcapTrace_FileEndianness
, pcap
.getByteOrder().toString())
233 fTraceProperties
= newProperties
;
234 return newProperties
;
242 public void close() {