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