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