pcap: Fix unused caching field
[deliverable/tracecompass.git] / pcap / org.eclipse.tracecompass.tmf.pcap.core / src / org / eclipse / tracecompass / internal / tmf / pcap / core / trace / PcapTrace.java
1 /*******************************************************************************
2 * Copyright (c) 2014, 2015 Ericsson
3 *
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
8 *
9 * Contributors:
10 * Vincent Perot - Initial API and implementation
11 * Alexandre Montplaisir - Update to new ITmfEventAspect API
12 * Patrick Tasse - Make pcap aspects singletons
13 *******************************************************************************/
14
15 package org.eclipse.tracecompass.internal.tmf.pcap.core.trace;
16
17 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
18 import static org.eclipse.tracecompass.common.core.NonNullUtils.nullToEmptyString;
19
20 import java.io.IOException;
21 import java.nio.channels.ClosedChannelException;
22 import java.nio.file.Path;
23 import java.nio.file.Paths;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.Map;
27
28 import org.eclipse.core.resources.IProject;
29 import org.eclipse.core.resources.IResource;
30 import org.eclipse.core.runtime.IStatus;
31 import org.eclipse.core.runtime.Status;
32 import org.eclipse.jdt.annotation.Nullable;
33 import org.eclipse.tracecompass.internal.pcap.core.packet.BadPacketException;
34 import org.eclipse.tracecompass.internal.pcap.core.protocol.pcap.PcapPacket;
35 import org.eclipse.tracecompass.internal.pcap.core.trace.BadPcapFileException;
36 import org.eclipse.tracecompass.internal.pcap.core.trace.PcapFile;
37 import org.eclipse.tracecompass.internal.pcap.core.util.LinkTypeHelper;
38 import org.eclipse.tracecompass.internal.tmf.pcap.core.Activator;
39 import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapEvent;
40 import org.eclipse.tracecompass.internal.tmf.pcap.core.event.aspect.PcapDestinationAspect;
41 import org.eclipse.tracecompass.internal.tmf.pcap.core.event.aspect.PcapProtocolAspect;
42 import org.eclipse.tracecompass.internal.tmf.pcap.core.event.aspect.PcapReferenceAspect;
43 import org.eclipse.tracecompass.internal.tmf.pcap.core.event.aspect.PcapSourceAspect;
44 import org.eclipse.tracecompass.internal.tmf.pcap.core.util.PcapEventFactory;
45 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
46 import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
47 import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
48 import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
49 import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceProperties;
50 import org.eclipse.tracecompass.tmf.core.trace.TmfContext;
51 import org.eclipse.tracecompass.tmf.core.trace.TmfTrace;
52 import org.eclipse.tracecompass.tmf.core.trace.TraceValidationStatus;
53 import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
54 import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation;
55
56 import com.google.common.collect.ImmutableList;
57 import com.google.common.collect.ImmutableMap;
58
59 /**
60 * Class that represents a TMF Pcap Trace. It is used to make the glue between
61 * the Pcap parser and TMF.
62 *
63 * TODO handle fields in TmfEventType for the filter view.
64 *
65 * @author Vincent Perot
66 */
67 public class PcapTrace extends TmfTrace implements ITmfTraceProperties {
68
69 /** pcap trace type id as defined in plugin.xml */
70 public static final String TRACE_TYPE_ID = "org.eclipse.linuxtools.tmf.pcap.core.pcaptrace"; //$NON-NLS-1$
71
72 private static final Collection<ITmfEventAspect> PCAP_ASPECTS =
73 checkNotNull(ImmutableList.of(
74 ITmfEventAspect.BaseAspects.TIMESTAMP,
75 PcapSourceAspect.INSTANCE,
76 PcapDestinationAspect.INSTANCE,
77 PcapReferenceAspect.INSTANCE,
78 PcapProtocolAspect.INSTANCE,
79 ITmfEventAspect.BaseAspects.CONTENTS
80 ));
81
82 private static final String EMPTY_STRING = ""; //$NON-NLS-1$
83 private static final int CONFIDENCE = 50;
84 private @Nullable PcapFile fPcapFile;
85 private @Nullable Map<String, String> fTraceProperties = null;
86
87 @Override
88 public synchronized ITmfLocation getCurrentLocation() {
89 PcapFile pcap = fPcapFile;
90 if (pcap == null) {
91 return new TmfLongLocation(0);
92 }
93 return new TmfLongLocation(pcap.getCurrentRank());
94 }
95
96 @Override
97 public synchronized double getLocationRatio(@Nullable ITmfLocation location) {
98 TmfLongLocation loc = (TmfLongLocation) location;
99 PcapFile pcap = fPcapFile;
100 if (loc == null || pcap == null) {
101 return 0;
102 }
103 try {
104 return (pcap.getTotalNbPackets() == 0 ? 0 : ((double) loc.getLocationInfo()) / pcap.getTotalNbPackets());
105 } catch (IOException | BadPcapFileException e) {
106 String message = e.getMessage();
107 if (message == null) {
108 message = EMPTY_STRING;
109 }
110 Activator.logError(message, e);
111 return 0;
112 }
113
114 }
115
116 @Override
117 public synchronized void initTrace(@Nullable IResource resource, @Nullable String path, @Nullable Class<? extends ITmfEvent> type) throws TmfTraceException {
118 super.initTrace(resource, path, type);
119 if (path == null) {
120 throw new TmfTraceException("No path has been specified."); //$NON-NLS-1$
121 }
122 Path filePath = checkNotNull(Paths.get(path));
123 try {
124 fPcapFile = new PcapFile(filePath);
125 } catch (IOException | BadPcapFileException e) {
126 throw new TmfTraceException(e.getMessage(), e);
127 }
128 }
129
130 @Override
131 public Iterable<ITmfEventAspect> getEventAspects() {
132 return PCAP_ASPECTS;
133 }
134
135 @Override
136 public synchronized @Nullable PcapEvent parseEvent(@Nullable ITmfContext context) {
137 if (context == null) {
138 return null;
139 }
140
141 long rank = context.getRank();
142 PcapPacket packet = null;
143 PcapFile pcap = fPcapFile;
144 if (pcap == null) {
145 return null;
146 }
147 try {
148 pcap.seekPacket(rank);
149 packet = pcap.parseNextPacket();
150 } catch (ClosedChannelException e) {
151 /*
152 * This is handled independently and happens when the user closes
153 * the trace while it is being parsed. It simply stops the parsing.
154 * No need to log a error.
155 */
156 return null;
157 } catch (IOException | BadPcapFileException | BadPacketException e) {
158 String message = e.getMessage();
159 if (message == null) {
160 message = EMPTY_STRING;
161 }
162 Activator.logError(message, e);
163 return null;
164 }
165
166 if (packet == null) {
167 return null;
168 }
169
170 // Generate an event from this packet and return it.
171 return PcapEventFactory.createEvent(packet, pcap, this);
172
173 }
174
175 @Override
176 public synchronized ITmfContext seekEvent(double ratio) {
177 long position;
178 PcapFile pcap = fPcapFile;
179 if (pcap == null) {
180 return new TmfContext(new TmfLongLocation(0), 0);
181 }
182
183 try {
184 /*
185 * The ratio is between 0 and 1. We multiply it by the total number
186 * of packets to get the position.
187 */
188 position = (long) (ratio * pcap.getTotalNbPackets());
189 } catch (IOException | BadPcapFileException e) {
190 String message = e.getMessage();
191 if (message == null) {
192 message = EMPTY_STRING;
193 }
194 Activator.logError(message, e);
195 return new TmfContext(new TmfLongLocation(0), 0);
196 }
197 TmfLongLocation loc = new TmfLongLocation(position);
198 return new TmfContext(loc, loc.getLocationInfo());
199 }
200
201 @Override
202 public synchronized ITmfContext seekEvent(@Nullable ITmfLocation location) {
203 TmfLongLocation loc = (TmfLongLocation) location;
204 if (loc == null) {
205 return new TmfContext(new TmfLongLocation(0));
206 }
207
208 return new TmfContext(loc, loc.getLocationInfo());
209 }
210
211 @Override
212 public IStatus validate(@Nullable IProject project, @Nullable String path) {
213
214 // All validations are made when making a new pcap file.
215 if (path == null) {
216 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, EMPTY_STRING);
217 }
218 Path filePath = checkNotNull(Paths.get(path));
219 try (PcapFile file = new PcapFile(filePath)) {
220 } catch (IOException | BadPcapFileException e) {
221 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.toString());
222 }
223 return new TraceValidationStatus(CONFIDENCE, Activator.PLUGIN_ID);
224 }
225
226 @Override
227 public synchronized void dispose() {
228 super.dispose();
229 PcapFile pcap = fPcapFile;
230 if (pcap == null) {
231 return;
232 }
233 try {
234 pcap.close();
235 fPcapFile = null;
236 } catch (IOException e) {
237 String message = e.getMessage();
238 if (message == null) {
239 message = EMPTY_STRING;
240 }
241 Activator.logError(message, e);
242 return;
243 }
244 }
245
246 @Override
247 public synchronized Map<String, String> getTraceProperties() {
248 PcapFile pcap = fPcapFile;
249 if (pcap == null) {
250 return Collections.emptyMap();
251 }
252
253 if (fTraceProperties != null) {
254 return fTraceProperties;
255 }
256
257 ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
258 builder.put(nullToEmptyString(Messages.PcapTrace_Version), String.format("%d%c%d", pcap.getMajorVersion(), '.', pcap.getMinorVersion())); //$NON-NLS-1$
259 builder.put(nullToEmptyString(Messages.PcapTrace_TimeZoneCorrection), pcap.getTimeZoneCorrection() + " s"); //$NON-NLS-1$
260 builder.put(nullToEmptyString(Messages.PcapTrace_TimestampAccuracy), String.valueOf(pcap.getTimeAccuracy()));
261 builder.put(nullToEmptyString(Messages.PcapTrace_MaxSnapLength), pcap.getSnapLength() + " bytes"); //$NON-NLS-1$
262 builder.put(nullToEmptyString(Messages.PcapTrace_LinkLayerHeaderType), LinkTypeHelper.toString((int) pcap.getDataLinkType()) + " (" + pcap.getDataLinkType() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
263 builder.put(nullToEmptyString(Messages.PcapTrace_FileEndianness), nullToEmptyString(pcap.getByteOrder().toString()));
264
265 fTraceProperties = builder.build();
266
267 return fTraceProperties;
268 }
269 }
This page took 0.036109 seconds and 5 git commands to generate.