tmf: Remove the ITmfEventTableColumns extension point
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.pcap.core / src / org / eclipse / tracecompass / internal / tmf / pcap / core / trace / PcapTrace.java
CommitLineData
b6eb4dce
VP
1/*******************************************************************************
2 * Copyright (c) 2014 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 *******************************************************************************/
12
2bdf0193 13package org.eclipse.tracecompass.internal.tmf.pcap.core.trace;
b6eb4dce
VP
14
15import java.io.IOException;
16import java.nio.channels.ClosedChannelException;
333a2acb
AM
17import java.nio.file.FileSystems;
18import java.nio.file.Path;
b04903a2 19import java.util.Collection;
b6eb4dce
VP
20import java.util.Map;
21
22import org.eclipse.core.resources.IProject;
23import org.eclipse.core.resources.IResource;
24import org.eclipse.core.runtime.IStatus;
25import org.eclipse.core.runtime.Status;
26import org.eclipse.jdt.annotation.NonNull;
27import org.eclipse.jdt.annotation.Nullable;
71f2817f
AM
28import org.eclipse.tracecompass.internal.pcap.core.packet.BadPacketException;
29import org.eclipse.tracecompass.internal.pcap.core.protocol.pcap.PcapPacket;
30import org.eclipse.tracecompass.internal.pcap.core.trace.BadPcapFileException;
31import org.eclipse.tracecompass.internal.pcap.core.trace.PcapFile;
32import org.eclipse.tracecompass.internal.pcap.core.util.LinkTypeHelper;
2bdf0193
AM
33import org.eclipse.tracecompass.internal.tmf.pcap.core.Activator;
34import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapEvent;
b04903a2
AM
35import org.eclipse.tracecompass.internal.tmf.pcap.core.event.aspect.PcapDestinationAspect;
36import org.eclipse.tracecompass.internal.tmf.pcap.core.event.aspect.PcapProtocolAspect;
37import org.eclipse.tracecompass.internal.tmf.pcap.core.event.aspect.PcapReferenceAspect;
38import org.eclipse.tracecompass.internal.tmf.pcap.core.event.aspect.PcapSourceAspect;
2bdf0193
AM
39import org.eclipse.tracecompass.internal.tmf.pcap.core.util.PcapEventFactory;
40import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
b04903a2 41import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
2bdf0193
AM
42import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
43import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
44import org.eclipse.tracecompass.tmf.core.trace.ITmfEventParser;
45import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceProperties;
46import org.eclipse.tracecompass.tmf.core.trace.TmfContext;
47import org.eclipse.tracecompass.tmf.core.trace.TmfTrace;
48import org.eclipse.tracecompass.tmf.core.trace.TraceValidationStatus;
49import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
50import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation;
b6eb4dce 51
b04903a2 52import com.google.common.collect.ImmutableList;
b6eb4dce
VP
53import com.google.common.collect.ImmutableMap;
54
55/**
56 * Class that represents a TMF Pcap Trace. It is used to make the glue between
57 * the Pcap parser and TMF.
58 *
59 * TODO handle fields in TmfEventType for the filter view.
60 *
61 * @author Vincent Perot
62 */
63public class PcapTrace extends TmfTrace implements ITmfEventParser, ITmfTraceProperties, AutoCloseable {
64
b04903a2
AM
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
73 );
74
b6eb4dce
VP
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;
81
82 @Override
83 public synchronized ITmfLocation getCurrentLocation() {
84 PcapFile pcap = fPcapFile;
85 if (pcap == null) {
86 return new TmfLongLocation(0);
87 }
88 return new TmfLongLocation(pcap.getCurrentRank());
89 }
90
91 @Override
92 public synchronized double getLocationRatio(@Nullable ITmfLocation location) {
93 TmfLongLocation loc = (TmfLongLocation) location;
94 PcapFile pcap = fPcapFile;
95 if (loc == null || pcap == null) {
96 return 0;
97 }
98 try {
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;
104 }
105 Activator.logError(message, e);
106 return 0;
107 }
108
109 }
110
111 @Override
112 public synchronized void initTrace(@Nullable IResource resource, @Nullable String path, @Nullable Class<? extends ITmfEvent> type) throws TmfTraceException {
113 super.initTrace(resource, path, type);
114 if (path == null) {
115 throw new TmfTraceException("No path has been specified."); //$NON-NLS-1$
116 }
333a2acb
AM
117 @SuppressWarnings("null")
118 @NonNull Path filePath = FileSystems.getDefault().getPath(path);
b6eb4dce 119 try {
333a2acb 120 fPcapFile = new PcapFile(filePath);
b6eb4dce
VP
121 } catch (IOException | BadPcapFileException e) {
122 throw new TmfTraceException(e.getMessage(), e);
123 }
124 }
125
b04903a2
AM
126 @Override
127 public Iterable<ITmfEventAspect> getEventAspects() {
128 return PCAP_ASPECTS;
129 }
130
b6eb4dce
VP
131 @Override
132 public synchronized @Nullable PcapEvent parseEvent(@Nullable ITmfContext context) {
133 if (context == null) {
134 return null;
135 }
136
137 long rank = context.getRank();
138 PcapPacket packet = null;
139 PcapFile pcap = fPcapFile;
140 if (pcap == null) {
141 return null;
142 }
143 try {
144 pcap.seekPacket(rank);
145 packet = pcap.parseNextPacket();
146 } catch (ClosedChannelException e) {
147 /*
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.
151 */
152 return null;
153 } catch (IOException | BadPcapFileException | BadPacketException e) {
154 String message = e.getMessage();
155 if (message == null) {
156 message = EMPTY_STRING;
157 }
158 Activator.logError(message, e);
159 return null;
160 }
161
162 if (packet == null) {
163 return null;
164 }
165
166 // Generate an event from this packet and return it.
167 return PcapEventFactory.createEvent(packet, pcap, this);
168
169 }
170
171 @Override
172 public synchronized ITmfContext seekEvent(double ratio) {
173 long position;
174 PcapFile pcap = fPcapFile;
175 if (pcap == null) {
176 return new TmfContext(new TmfLongLocation(0), 0);
177 }
178
179 try {
180 /*
181 * The ratio is between 0 and 1. We multiply it by the total number
182 * of packets to get the position.
183 */
184 position = (long) (ratio * pcap.getTotalNbPackets());
185 } catch (IOException | BadPcapFileException e) {
186 String message = e.getMessage();
187 if (message == null) {
188 message = EMPTY_STRING;
189 }
190 Activator.logError(message, e);
191 return new TmfContext(new TmfLongLocation(0), 0);
192 }
193 TmfLongLocation loc = new TmfLongLocation(position);
194 return new TmfContext(loc, loc.getLocationInfo());
195 }
196
197 @Override
198 public synchronized ITmfContext seekEvent(@Nullable ITmfLocation location) {
199 TmfLongLocation loc = (TmfLongLocation) location;
200 if (loc == null) {
201 return new TmfContext(new TmfLongLocation(0));
202 }
203
204 return new TmfContext(loc, loc.getLocationInfo());
205 }
206
207 @Override
208 public IStatus validate(@Nullable IProject project, @Nullable String path) {
209
210 // All validations are made when making a new pcap file.
211 if (path == null) {
212 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, EMPTY_STRING);
213 }
333a2acb
AM
214 @SuppressWarnings("null")
215 @NonNull Path filePath = FileSystems.getDefault().getPath(path);
216 try (PcapFile file = new PcapFile(filePath)) {
b6eb4dce
VP
217 } catch (IOException | BadPcapFileException e) {
218 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.toString());
219 }
220 return new TraceValidationStatus(CONFIDENCE, Activator.PLUGIN_ID);
221 }
222
223 @Override
224 public synchronized void dispose() {
225 super.dispose();
226 PcapFile pcap = fPcapFile;
227 if (pcap == null) {
228 return;
229 }
230 try {
231 pcap.close();
232 fPcapFile = null;
233 } catch (IOException e) {
234 String message = e.getMessage();
235 if (message == null) {
236 message = EMPTY_STRING;
237 }
238 Activator.logError(message, e);
239 return;
240 }
241 }
242
243 @Override
244 public synchronized Map<String, String> getTraceProperties() {
245 PcapFile pcap = fPcapFile;
246 if (pcap == null) {
247 return EMPTY_MAP;
248 }
249
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())
260 .build();
261 fTraceProperties = newProperties;
262 return newProperties;
263
264 }
265
266 return properties;
267 }
268
269 @Override
270 public void close() {
271 dispose();
272 }
273}
This page took 0.049282 seconds and 5 git commands to generate.