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
.linuxtools
.internal
.tmf
.pcap
.core
.util
;
15 import java
.nio
.file
.Path
;
16 import java
.util
.ArrayList
;
17 import java
.util
.HashMap
;
18 import java
.util
.List
;
21 import org
.eclipse
.jdt
.annotation
.NonNull
;
22 import org
.eclipse
.jdt
.annotation
.Nullable
;
23 import org
.eclipse
.linuxtools
.internal
.pcap
.core
.packet
.Packet
;
24 import org
.eclipse
.linuxtools
.internal
.pcap
.core
.protocol
.Protocol
;
25 import org
.eclipse
.linuxtools
.internal
.pcap
.core
.protocol
.pcap
.PcapPacket
;
26 import org
.eclipse
.linuxtools
.internal
.pcap
.core
.trace
.PcapFile
;
27 import org
.eclipse
.linuxtools
.internal
.pcap
.core
.util
.LinkTypeHelper
;
28 import org
.eclipse
.linuxtools
.internal
.pcap
.core
.util
.PcapTimestampScale
;
29 import org
.eclipse
.linuxtools
.internal
.tmf
.pcap
.core
.event
.PcapEvent
;
30 import org
.eclipse
.linuxtools
.internal
.tmf
.pcap
.core
.event
.PcapEventField
;
31 import org
.eclipse
.linuxtools
.internal
.tmf
.pcap
.core
.event
.PcapEventType
;
32 import org
.eclipse
.linuxtools
.internal
.tmf
.pcap
.core
.event
.PcapRootEventField
;
33 import org
.eclipse
.linuxtools
.internal
.tmf
.pcap
.core
.trace
.PcapTrace
;
34 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEventField
;
35 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfEventField
;
36 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfEventType
;
37 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.ITmfTimestamp
;
38 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.TmfTimestamp
;
41 * Factory class that helps generating Pcap Events.
43 * @author Vincent Perot
45 public class PcapEventFactory
{
47 private static final ITmfEventField
[] EMPTY_FIELD_ARRAY
= new ITmfEventField
[0];
48 private static final String EMPTY_STRING
= ""; //$NON-NLS-1$
50 private static final Map
<Protocol
, TmfEventType
> fEventTypes
= new HashMap
<>();
52 private PcapEventFactory() {
56 * Method that create a PcapEvent from a packet.
59 * The packet to generate the event from.
61 * The pcap file to which the packet belongs.
63 * The trace to which this packet belongs.
64 * @return The generated PcapEvent.
66 public static @Nullable PcapEvent
createEvent(PcapPacket pcapPacket
, PcapFile pcap
, PcapTrace trace
) {
67 long rank
= pcapPacket
.getIndex();
68 long timestamp
= pcapPacket
.getTimestamp();
69 PcapTimestampScale scale
= pcapPacket
.getTimestampScale();
70 ITmfTimestamp tmfTimestamp
;
73 tmfTimestamp
= new TmfTimestamp(timestamp
, ITmfTimestamp
.MICROSECOND_SCALE
, (int) pcap
.getTimeAccuracy());
76 tmfTimestamp
= new TmfTimestamp(timestamp
, ITmfTimestamp
.NANOSECOND_SCALE
, (int) pcap
.getTimeAccuracy());
79 throw new IllegalArgumentException("The timestamp precision is not valid!"); //$NON-NLS-1$
81 Path filePath
= pcap
.getPath().getFileName();
82 @SuppressWarnings("null") // for .toString()
83 @NonNull String fileName
= (filePath
== null ? EMPTY_STRING
: filePath
.toString());
85 String dataLink
= Messages
.PcapEventFactory_LinkType
+ ':' + LinkTypeHelper
.toString((int) pcapPacket
.getPcapFile().getDataLinkType());
87 ITmfEventField
[] fields
= generatePacketFields(pcapPacket
);
88 ITmfEventField field
= new PcapRootEventField(EMPTY_STRING
, fields
, pcapPacket
);
89 Packet packet
= pcapPacket
.getMostEcapsulatedPacket();
90 if (!fEventTypes
.containsKey(packet
.getProtocol())) {
91 String typeIdString
= PcapEventType
.DEFAULT_PCAP_TYPE_ID
+ ':' + packet
.getProtocol().getShortName();
92 fEventTypes
.put(packet
.getProtocol(), new PcapEventType(typeIdString
, null));
94 TmfEventType eventType
= fEventTypes
.get(packet
.getProtocol());
95 if (eventType
== null) {
96 eventType
= new TmfEventType();
98 return new PcapEvent(trace
, rank
, tmfTimestamp
, dataLink
, eventType
, field
, fileName
, packet
);
102 private static ITmfEventField
[] generatePacketFields(Packet packet
) {
103 // TODO This is SOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO slow. Must find a
104 // way to use less intermediate data structures.
105 List
<ITmfEventField
> fieldList
= new ArrayList
<>();
106 List
<ITmfEventField
> subfieldList
= new ArrayList
<>();
107 Packet localPacket
= packet
.getPacket(Protocol
.PCAP
);
109 while (localPacket
!= null) {
110 subfieldList
.clear();
111 for (Map
.Entry
<String
, String
> entry
: localPacket
.getFields().entrySet()) {
113 @SuppressWarnings("null")
114 @NonNull String key
= entry
.getKey();
116 @SuppressWarnings("null")
117 @NonNull String value
= entry
.getValue();
118 subfieldList
.add(new TmfEventField(key
, value
, null));
120 ITmfEventField
[] subfieldArray
= subfieldList
.toArray(new ITmfEventField
[subfieldList
.size()]);
121 fieldList
.add(new PcapEventField(localPacket
.getProtocol().getName(), EMPTY_STRING
, subfieldArray
, localPacket
));
122 localPacket
= localPacket
.getChildPacket();
125 ITmfEventField
[] fieldArray
= fieldList
.toArray(new ITmfEventField
[fieldList
.size()]);
126 if (fieldArray
== null) {
127 return EMPTY_FIELD_ARRAY
;