package de.tu_darmstadt.tk.SmartHomeNetworkSim.core;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.function.Predicate;
/**
* A packet collector allows collection of {@link Packet}s from one or multiple {@link Link}s or {@link SmartDevice}s.
* The Packets are stored per Link.
* All packets which are sent from/to one of the devices can be filtered by the
* {@link #getFilter() getFilter()}.
* Packets should be collected by adding them via the
* {@link #addPackets(Link, Collection)} method.
*
* @author Andreas T. Meyer-Berg
*/
public class PacketCollector {
/**
* Devices which packets should be collected. Just devices from/to the
* device will be collected.
*/
private LinkedList devices = new LinkedList();
/**
* All packets which are sent via this link are collected.
*/
private LinkedList links = new LinkedList();
/**
* Packets which were collected by this packet collector
*/
private HashMap> collectedPackets = new HashMap>();
/**
* Packet Sniffing Algorithm, which
*/
private PacketSniffer packetAlgorithm = null;
/**
* Mode of the Collector, whether it should train or test the packetSniffer algorithm
*/
private boolean mode = false;
/**
* True if it should collect packages
*/
private boolean active = true;
/**
* Creates a PacketCollector without assigning and algorithm to process the packets
*/
public PacketCollector() {
packetAlgorithm = null;
}
/**
* Creates a PacketCollector and assigns an algorithm to process the packets
* @param sniffer PacketSniffer to process the packets collected by this collector
*/
public PacketCollector(PacketSniffer sniffer) {
packetAlgorithm = sniffer;
}
/**
* Adds a new Link, which packets should be collected. All packets send via
* the link will be collected from now on.
*
* @param link
* link, which packets should be collected.
*/
public void addLink(Link link) {
if(!links.contains(link)){
links.add(link);
collectedPackets.put(link, new LinkedList());
}
}
/**
* Remove link from Links that should be collected. Packets sent via this
* Link will no longer be collected. Just if a separate Device which
* contains the link should be collected.
*
* @param link link which packets should no longer be collected
*/
public void removeLink(Link link) {
links.remove(link);
collectedPackets.remove(link).clear();
}
/**
* Returns all links, which should be collected by this PacketCollector
* @return links, which packets should be collected
*/
public Collection getLinks() {
return links;
}
/**
* Adds device, which packets should be collected. All packets sent to or received from this device will be collected.
* @param device device, which packets should be collected
*/
public void addDevice(SmartDevice device) {
if(!devices.contains(device))
devices.add(device);
}
/**
* Remove device. Packets sent to or from this device will no longer be collected. Unless it participates in one of the links.
* @param device device to be removed
*/
public void removeDevice(SmartDevice device) {
devices.remove(device);
}
/**
* Returns all devices which packets are being collected by this Packet Collector.
* @return devices, which packets are being collected
*/
public Collection getDevices() {
return devices;
}
/**
* Predicate which is true if the given packet was sent from or to one of
* the devices, stored in this PacketCollector
*
* @return true if it was sent from or to one of the devices stored in this
* packet collector
*/
public Predicate super Packet> getFilter() {
return p -> /* filter devices where source or destination is null */
(p.getSource() != null && p.getDestination() != null && p.getSource().getOwner() != null
&& p.getDestination().getOwner() != null)
/* return true if */
/*&& (devices.contains(p.getSource().getOwner())||devices.contains(p.getDestination().getOwner()))*/
&& devices.stream().anyMatch(d -> d == p.getSource().getOwner() || d == p.getDestination().getOwner());
}
/**
* Adds packets which should be collected by this PacketCollector.
* @param link link, which the packets were sent on
* @param packets packets which were sent
*/
public void addPackets(Link link, Collection packets) {
if(link == null)
return;
LinkedList packetsOfLink = collectedPackets.get(link);
if(packetsOfLink !=null)
packetsOfLink.addAll(packets);
collectedPackets.put(link, new LinkedList<>(packets));
}
/**
* Returns the packets which were collected
* @return collected packets
*/
public HashMap> getPackets(){
return collectedPackets;
}
/**
* Return the collected Packets of the link
* @param link Link, which packets should be returned
* @return packets, collected on the given link
*/
public LinkedList getPacketsOfLink(Link link){
return collectedPackets.get(link);
}
/**
* Resets the collected Packets list, by clearing the list.
*/
public void resetPackets(){
collectedPackets.clear();
}
/**
* @return the packetSnifferAlgorithm
*/
public PacketSniffer getPacketAlgorithm() {
return packetAlgorithm;
}
/**
* @param packetAlgorithm the packetSnifferAlgorithm to set
*/
public void setPacketAlgorithm(PacketSniffer packetAlgorithm) {
this.packetAlgorithm = packetAlgorithm;
}
/**
* Returns training or testing mode of the algorithm.
* @return true if testing or false if training the algorithm.
*/
public boolean getMode() {
if(packetAlgorithm!=null)
mode = packetAlgorithm.getMode();
return mode;
}
/**
* Sets the training or testing mode
* @param mode true if testing or false if training the algorithm.
*/
public void setMode(boolean mode) {
this.mode = mode;
if(packetAlgorithm != null)
packetAlgorithm.setMode(mode);
}
/**
* Whether the algorithm should run
* @return true if algorithm will be executed
*/
public boolean isActive() {
return active;
}
/**
* Set to true, if it should run
* @param active true if it should be active
*/
public void setActive(boolean active) {
this.active = active;
}
}