/******************************************************************************* * Copyright (c) 2014 Ericsson * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License v1.0 which * accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Vincent Perot - Initial API and implementation *******************************************************************************/ package org.eclipse.tracecompass.internal.tmf.pcap.core.analysis; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapEvent; import org.eclipse.tracecompass.internal.tmf.pcap.core.event.TmfPacketStreamBuilder; import org.eclipse.tracecompass.internal.tmf.pcap.core.protocol.TmfPcapProtocol; import org.eclipse.tracecompass.internal.tmf.pcap.core.trace.PcapTrace; import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule; import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment; /** * A pcap-specific analysis that parse an entire trace to find all the streams. * * @author Vincent Perot */ public class StreamListAnalysis extends TmfAbstractAnalysisModule { /** * The Stream List analysis ID. */ public static final String ID = "org.eclipse.linuxtools.tmf.pcap.core.analysis.stream"; //$NON-NLS-1$ private @Nullable ITmfEventRequest fRequest; private final Map<TmfPcapProtocol, TmfPacketStreamBuilder> fBuilders; /** * The default constructor. It initializes all variables. */ public StreamListAnalysis() { super(); fBuilders = new HashMap<>(); for (TmfPcapProtocol protocol : TmfPcapProtocol.values()) { if (protocol.supportsStream()) { fBuilders.put(protocol, new TmfPacketStreamBuilder(protocol)); } } } @Override public boolean canExecute(ITmfTrace trace) { // Trace is Pcap if (trace instanceof PcapTrace) { return true; } // Trace is not a TmfExperiment if (!(trace instanceof TmfExperiment)) { return false; } // Trace is TmfExperiment. Check if it has a PcapTrace. TmfExperiment experiment = (TmfExperiment) trace; List<ITmfTrace> traces = experiment.getTraces(); for (ITmfTrace expTrace : traces) { if (expTrace instanceof PcapTrace) { return true; } } // No Pcap :( return false; } @Override protected boolean executeAnalysis(@Nullable IProgressMonitor monitor) throws TmfAnalysisException { IProgressMonitor mon = (monitor == null ? new NullProgressMonitor() : monitor); ITmfTrace trace = getTrace(); if (trace == null) { /* This analysis was cancelled in the meantime */ return false; } ITmfEventRequest request = fRequest; if ((request != null) && (!request.isCompleted())) { request.cancel(); } request = new TmfEventRequest(PcapEvent.class, TmfTimeRange.ETERNITY, 0L, ITmfEventRequest.ALL_DATA, ITmfEventRequest.ExecutionType.BACKGROUND) { @Override public void handleData(ITmfEvent data) { // Called for each event super.handleData(data); if (!(data instanceof PcapEvent)) { return; } PcapEvent event = (PcapEvent) data; for (Map.Entry<TmfPcapProtocol, TmfPacketStreamBuilder> entry : fBuilders.entrySet()) { entry.getValue().addEventToStream(event); } } }; trace.sendRequest(request); fRequest = request; try { request.waitForCompletion(); } catch (InterruptedException e) { // Request was canceled. return false; } return !mon.isCanceled() && !request.isCancelled() && !request.isFailed(); } @Override protected void canceling() { ITmfEventRequest req = fRequest; if ((req != null) && (!req.isCompleted())) { req.cancel(); } } /** * Getter method that returns the packet builder associated to a particular * protocol. * * @param protocol * The specified protocol. * @return The builder. */ public @Nullable TmfPacketStreamBuilder getBuilder(TmfPcapProtocol protocol) { return fBuilders.get(protocol); } /** * Method that indicates if the analysis is still running or has finished. * * @return Whether the analysis is finished or not. */ public boolean isFinished() { ITmfEventRequest req = fRequest; if (req == null) { return false; } return req.isCompleted(); } }