import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map.Entry;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PacketSniffer;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.packets.MQTT_packet;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.packets.Ping_packet;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.simpleImplementation.SimplePacket;
/**
* Metric which can be used as PacketSniffer. Will count the number of packets sent per Link.
* Furthermore statistics like number of packets sent between different devices, number of packets
* per type etc. will be printed to the console.
*
* @author Andreas T. Meyer-Berg
*/
public class CountingMetric implements PacketSniffer {
/**
* Mode of the algorithm, True = testing
*/
private boolean mode = false;
@Override
public void processPackets(HashMap> packets) {
System.out.println("Counting Metric: ");
System.out.println("Mode: "+(mode?"Testing":"Training"));
if(packets==null)return;
/**
* Print all links and their number of packets sent
*/
for(Entry> e:packets.entrySet()){
if(e == null || e.getKey() == null || e.getValue() == null)continue;
//System.out.println(e.getKey().getName()+": "+e.getValue().size()+" Packets");
printStatistics(e.getValue());
}
System.out.println("");
}
/**
* Calculates and prints statistics for the given packets
* @param packets Packets which should be evaluated
*/
private void printStatistics(LinkedList packets){
//Calculate first and last packet time
/**
* Timestep the first packet was sent
*/
long minTime = Long.MAX_VALUE;
/**
* Timestep the last pacekt was sent
*/
long maxTime = Long.MIN_VALUE;
/**
* Number of ping packets
*/
int pingPackets = 0;
/**
* Number of ping packets
*/
int mqttPackets = 0;
/**
* Number of MQTT packets
*/
int simplePackets = 0;
/**
* Number of unknown packets
*/
int unknownPackets = 0;
//HashMap for packets per collection
HashMap> connections = new HashMap>();
for(Packet p: packets){
minTime = Math.min(minTime, p.getTimestamp());
maxTime = Math.max(maxTime, p.getTimestamp());
if(p instanceof MQTT_packet)
mqttPackets++;
else if(p instanceof Ping_packet)
pingPackets++;
else if(p instanceof SimplePacket)
simplePackets++;
else
unknownPackets++;
HashMap map = connections.get(p.getSource().getOwner());
if(map == null)
map = new HashMap();
//Increment counter for each packet by on. Add HashMap/Numbers if number non existent
Integer lastVal = map.get(p.getDestination().getOwner());
int i = lastVal == null?0:lastVal;
map.put(p.getDestination().getOwner(), i+1);
connections.put(p.getSource().getOwner(), map);
}
// Print number of packets per Protocol Type
System.out.println("In Total "+packets.size()+" Packets were sent.");
if(mqttPackets != 0){
if(mqttPackets==packets.size()){
System.out.println("All of them were MQTT packets");
}else{
System.out.println(mqttPackets+ "("+Math.round(mqttPackets*100.0/packets.size())+"%) of them were MQTT packets");
}
}
if(pingPackets != 0){
if(pingPackets==packets.size()){
System.out.println("All of them were ping packets");
}else{
System.out.println(pingPackets+ "("+Math.round(pingPackets*100.0/packets.size())+"%) of them were ping packets");
}
}
if(simplePackets != 0){
if(simplePackets==packets.size()){
System.out.println("All of them were simple packets");
}else{
System.out.println(simplePackets+ "("+Math.round(simplePackets*100.0/packets.size())+"%) of them were simple packets");
}
}
if(unknownPackets != 0){
if(unknownPackets==packets.size()){
System.out.println("All of them were unknown packets");
}else{
System.out.println(unknownPackets+ "("+Math.round(unknownPackets*100.0/packets.size())+"%) of them were unknwon packets");
}
}
if(minTime<=maxTime)
System.out.println("First packet was captured at "+minTime+" ms, and the last at "+maxTime+" ms.");
else
System.out.println("No packets were captured.");
//Print the number of packets per connection
for (Entry> e: connections.entrySet()) {
String src = e.getKey() == null || e.getKey().getName()==null ? "null":e.getKey().getName();
System.out.println(src + " sent:");
for (Entry f: e.getValue().entrySet()) {
String dest = f.getKey() == null || f.getKey().getName()==null ? "null":f.getKey().getName();
System.out.println(f.getValue() + " packets to "+dest);
}
}
}
@Override
public void setMode(boolean testing) {
mode = testing;
}
@Override
public boolean getMode() {
return mode;
}
}