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
.tracecompass
.internal
.tmf
.pcap
.core
.util
;
15 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
17 import java
.nio
.file
.Path
;
18 import java
.util
.ArrayList
;
19 import java
.util
.HashMap
;
20 import java
.util
.List
;
23 import org
.eclipse
.jdt
.annotation
.NonNull
;
24 import org
.eclipse
.jdt
.annotation
.Nullable
;
25 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.packet
.Packet
;
26 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.protocol
.PcapProtocol
;
27 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.protocol
.pcap
.PcapPacket
;
28 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.trace
.PcapFile
;
29 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.util
.LinkTypeHelper
;
30 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.util
.PcapTimestampScale
;
31 import org
.eclipse
.tracecompass
.internal
.tmf
.pcap
.core
.event
.PcapEvent
;
32 import org
.eclipse
.tracecompass
.internal
.tmf
.pcap
.core
.event
.PcapEventField
;
33 import org
.eclipse
.tracecompass
.internal
.tmf
.pcap
.core
.event
.PcapEventType
;
34 import org
.eclipse
.tracecompass
.internal
.tmf
.pcap
.core
.event
.PcapRootEventField
;
35 import org
.eclipse
.tracecompass
.internal
.tmf
.pcap
.core
.trace
.PcapTrace
;
36 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEventField
;
37 import org
.eclipse
.tracecompass
.tmf
.core
.event
.TmfEventField
;
38 import org
.eclipse
.tracecompass
.tmf
.core
.event
.TmfEventType
;
39 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.ITmfTimestamp
;
40 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimestamp
;
43 * Factory class that helps generating Pcap Events.
45 * @author Vincent Perot
47 public class PcapEventFactory
{
49 private static final String EMPTY_STRING
= ""; //$NON-NLS-1$
51 private static final Map
<PcapProtocol
, TmfEventType
> fEventTypes
= new HashMap
<>();
53 private PcapEventFactory() {
57 * Method that create a PcapEvent from a packet.
60 * The packet to generate the event from.
62 * The pcap file to which the packet belongs.
64 * The trace to which this packet belongs.
65 * @return The generated PcapEvent.
67 public static @Nullable PcapEvent
createEvent(PcapPacket pcapPacket
, PcapFile pcap
, PcapTrace trace
) {
68 long rank
= pcapPacket
.getIndex();
69 long timestamp
= pcapPacket
.getTimestamp();
70 PcapTimestampScale scale
= pcapPacket
.getTimestampScale();
71 ITmfTimestamp tmfTimestamp
;
74 long us
= trace
.getTimestampTransform().transform(timestamp
* 1000) / 1000;
75 tmfTimestamp
= new TmfTimestamp(us
, ITmfTimestamp
.MICROSECOND_SCALE
);
78 long ns
= trace
.getTimestampTransform().transform(timestamp
);
79 tmfTimestamp
= new TmfTimestamp(ns
, ITmfTimestamp
.NANOSECOND_SCALE
);
82 throw new IllegalArgumentException("The timestamp precision is not valid!"); //$NON-NLS-1$
84 Path filePath
= pcap
.getPath().getFileName();
85 @NonNull String fileName
= (filePath
== null ? EMPTY_STRING
: checkNotNull(filePath
.toString()));
87 String dataLink
= Messages
.PcapEventFactory_LinkType
+ ':' + LinkTypeHelper
.toString((int) pcapPacket
.getPcapFile().getDataLinkType());
89 ITmfEventField
[] fields
= generatePacketFields(pcapPacket
);
90 ITmfEventField field
= new PcapRootEventField(fields
, pcapPacket
);
91 Packet packet
= pcapPacket
.getMostEcapsulatedPacket();
92 if (!fEventTypes
.containsKey(packet
.getProtocol())) {
93 String typeIdString
= PcapEventType
.DEFAULT_PCAP_TYPE_ID
+ ':' + packet
.getProtocol().getShortName();
94 fEventTypes
.put(packet
.getProtocol(), new PcapEventType(typeIdString
, null));
96 TmfEventType eventType
= fEventTypes
.get(packet
.getProtocol());
97 if (eventType
== null) {
98 eventType
= new TmfEventType();
100 return new PcapEvent(trace
, rank
, tmfTimestamp
, dataLink
, eventType
, field
, fileName
, packet
);
104 private static ITmfEventField
[] generatePacketFields(Packet packet
) {
105 // TODO This is SOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO slow. Must find a
106 // way to use less intermediate data structures.
107 List
<ITmfEventField
> fieldList
= new ArrayList
<>();
108 List
<ITmfEventField
> subfieldList
= new ArrayList
<>();
109 Packet localPacket
= packet
.getPacket(PcapProtocol
.PCAP
);
111 while (localPacket
!= null) {
112 subfieldList
.clear();
113 for (Map
.Entry
<String
, String
> entry
: localPacket
.getFields().entrySet()) {
114 String key
= entry
.getKey();
115 String value
= entry
.getValue();
116 subfieldList
.add(new TmfEventField(key
, value
, null));
118 ITmfEventField
[] subfieldArray
= subfieldList
.toArray(new ITmfEventField
[subfieldList
.size()]);
119 fieldList
.add(new PcapEventField(localPacket
.getProtocol().getName(), EMPTY_STRING
, subfieldArray
, localPacket
));
120 localPacket
= localPacket
.getChildPacket();
123 return fieldList
.toArray(new ITmfEventField
[fieldList
.size()]);