Browse Source

Merge branch 'GlobalScheduler'

Andreas T. Meyer-Berg 3 years ago
parent
commit
69b7c0e71d
62 changed files with 4069 additions and 132 deletions
  1. 3 0
      .gitignore
  2. 1 0
      README.md
  3. 51 47
      build.gradle
  4. 16 0
      examples/CountingMetric.java
  5. 307 0
      examples/UnsupervisedAnomalyDetectionExample.java
  6. 343 0
      examples/UnsupervisedAnomalyDetectionExample2.java
  7. 426 0
      examples/classifier/BasicPacketClassifier.java
  8. 87 0
      examples/classifier/EMClustering.java
  9. 70 0
      examples/classifier/HierarchicalClustering.java
  10. 121 0
      examples/classifier/KMeansClustering.java
  11. 1 1
      gradle/wrapper/gradle-wrapper.properties
  12. BIN
      libs/weka.jar
  13. BIN
      libs_src/weka_src.jar
  14. 196 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/ExampleAnomalyController.java
  15. 61 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/ImportController.java
  16. 22 2
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/NetworkController.java
  17. 43 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/PacketCaptureController.java
  18. 20 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Connection.java
  19. 22 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/ConnectionPerformance.java
  20. 3 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/ConnectionPrecision.java
  21. 31 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Link.java
  22. 29 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Packet.java
  23. 2 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/PacketCollectionManager.java
  24. 46 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/PacketCollector.java
  25. 16 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/PacketSniffer.java
  26. 93 18
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Port.java
  27. 44 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/PrecisionLink.java
  28. 39 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/ProbabilityDistributionHandler.java
  29. 60 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/SimulationManager.java
  30. 21 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/SmartDevice.java
  31. 39 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/configuration/ImportConfiguration.java
  32. 25 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/devices/FloatSensorDevice.java
  33. 113 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/distributionHandler/ConstantValueDistributionHandler.java
  34. 167 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/distributionHandler/NormalDistributionHandler.java
  35. 168 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/distributionHandler/PoissonDistributionHandler.java
  36. 6 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/distributionHandler/package-info.java
  37. 73 11
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/MQTT_protocol.java
  38. 6 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/packets/MQTT_packet.java
  39. 81 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/packets/MQTTpublishPacket.java
  40. 6 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/packets/Ping_packet.java
  41. 31 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/scheduler/AbstractEvent.java
  42. 21 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/scheduler/Schedulable.java
  43. 23 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/scheduler/ScheduleComparator.java
  44. 125 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/scheduler/Scheduler.java
  45. 6 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/scheduler/package-info.java
  46. 15 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/CountingMetric.java
  47. 1 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/Manipulation_RandomMove.java
  48. 20 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/SimpleConnection.java
  49. 21 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/SimpleLink.java
  50. 34 4
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/SimplePacket.java
  51. 17 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/SimplePacketSniffer.java
  52. 11 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/MenuBar.java
  53. 152 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/menuBar/MenuBarInsertAnomalies.java
  54. 377 18
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/menuBar/MenuBarNetworkExamples.java
  55. 7 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/menuBar/package-info.java
  56. 52 6
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/ConnectionCreationPanel.java
  57. 56 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/EditPacketSniffer.java
  58. 195 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/PortDistributionConfigurationPopUp.java
  59. 44 11
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/PortEditorPanel.java
  60. 1 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/SmartDeviceCreationPopUp.java
  61. 1 1
      src/test/java/de/tu_darmstadt/tk/shNetSimTests/control/ConfigurationTest.java
  62. 1 1
      src/test/resources/control/testCompilation/project1/MQTT_protocolProject1.javaTest

+ 3 - 0
.gitignore

@@ -105,6 +105,9 @@ gradle-app.setting
 
 # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
 !gradle-wrapper.jar
+# Avoid if
+!/libs/*.jar
+!/libs_src/*.jar
 
 # Cache of project
 .gradletasknamecache

+ 1 - 0
README.md

@@ -27,6 +27,7 @@ Gradle downloads these during the build process
 
 * [JUnit4](https://junit.org/junit4/) - Java unit test framework
 * [Pcap4j](https://www.pcap4j.org/) - Java Library used for Pcap File creation (not yet implemented)
+* [Math3](https://commons.apache.org/proper/commons-math/) - Apache Common Maths (for Distribution function)
 
 <!-- PCAP file writing example (as part of the export manager - but probably required packet transformation): https://www.devdungeon.com/content/packet-capturing-java-pcap4j#writing_pcap_file -->
 

+ 51 - 47
build.gradle

@@ -1,47 +1,51 @@
-/*
- * This file was generated by the Gradle 'init' task.
- *
- * This is a general purpose Gradle build.
- * Learn how to create Gradle builds at https://guides.gradle.org/creating-new-gradle-builds/
- */
-
-apply plugin: 'java'
-apply plugin: 'eclipse'
-apply plugin: 'application'
-
-group = groupName
-version = versionNumber
-
-//application allows the Task 'run' which runs the main class
-mainClassName = "de.tu_darmstadt.tk.SmartHomeNetworkSim.Main"
-
-repositories {
-	jcenter()
-}
-
-//Creates the Jar
-jar {
-    manifest {
-        attributes 'Main-Class': 'de.tu_darmstadt.tk.SmartHomeNetworkSim.Main'
-    }
-}
-
-test {
-	ignoreFailures = true
-}
-
-//Runs the created Jar
-task runIt(dependsOn:jar) {
-    doLast {
-        javaexec { 
-            main="-jar"; args jar.archivePath
-        }
-    }
-}
-
-dependencies {
-	compile 'org.pcap4j:pcap4j-core:1.+'
-	compile 'org.pcap4j:pcap4j-packetfactory-static:1.+'
-
-	testCompile 'junit:junit:4.12'
-}
+/*
+ * This file was generated by the Gradle 'init' task.
+ *
+ * This is a general purpose Gradle build.
+ * Learn how to create Gradle builds at https://guides.gradle.org/creating-new-gradle-builds/
+ */
+
+apply plugin: 'java'
+apply plugin: 'eclipse'
+apply plugin: 'application'
+
+group = groupName
+version = versionNumber
+
+//application allows the Task 'run' which runs the main class
+mainClassName = "de.tu_darmstadt.tk.SmartHomeNetworkSim.Main"
+
+repositories {
+	jcenter()
+}
+
+//Creates the Jar
+jar {
+    manifest {
+        attributes 'Main-Class': 'de.tu_darmstadt.tk.SmartHomeNetworkSim.Main'
+    }
+}
+
+test {
+	ignoreFailures = true
+}
+
+//Runs the created Jar
+task runIt(dependsOn:jar) {
+    doLast {
+        javaexec { 
+            main="-jar"; args jar.archivePath
+        }
+    }
+}
+
+dependencies {
+	compile 'org.pcap4j:pcap4j-core:1.+'
+	compile 'org.pcap4j:pcap4j-packetfactory-static:1.+'
+	// https://mvnrepository.com/artifact/org.apache.commons/commons-math3
+	compile group: 'org.apache.commons', name: 'commons-math3', version: '3.6.1'
+	//compile group: 'nz.ac.waikato.cms.weka', name: 'weka-stable', version: '3.8.0'
+	compile fileTree(include: ['*.jar'], dir: 'libs')
+	
+	testCompile 'junit:junit:4.12'
+}

+ 16 - 0
examples/CountingMetric.java

@@ -20,9 +20,15 @@ import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.simpleImplementation.SimplePa
  */
 public class CountingMetric implements PacketSniffer {
 
+	/**
+	 * Mode of the algorithm, True = testing
+	 */
+	private boolean mode = false;
+	
 	@Override
 	public void processPackets(HashMap<Link, LinkedList<Packet>> 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
@@ -133,4 +139,14 @@ public class CountingMetric implements PacketSniffer {
 		
 		
 	}
+	
+	@Override
+	public void setMode(boolean testing) {
+		mode = testing;
+	}
+	
+	@Override
+	public boolean getMode() {
+		return mode;
+	}
 }

+ 307 - 0
examples/UnsupervisedAnomalyDetectionExample.java

@@ -0,0 +1,307 @@
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+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 weka.clusterers.SimpleKMeans;
+import weka.core.Attribute;
+import weka.core.DenseInstance;
+import weka.core.Instance;
+import weka.core.Instances;
+
+/**
+ * Unsupervised Example - maybe Clustering
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public class UnsupervisedAnomalyDetectionExample implements PacketSniffer {
+
+	/**
+	 * Clusterer
+	 */
+	private SimpleKMeans clusterer;
+	
+	/**
+	 * True, if instances should be used for training
+	 */
+	private boolean training = true;
+	
+	/**
+	 * Attributes which should be taken into account
+	 */
+	private ArrayList<Attribute> atts = new ArrayList<Attribute>();
+	
+	/**
+	 * Collected Packets
+	 */
+	private Instances dataset;
+	
+	/**
+	 * HashMap for calculating transmission delay
+	 */
+	private HashMap<Link, LinkedList<Packet>> lastPackets = new HashMap<Link, LinkedList<Packet>>();
+	
+	/**
+	 * Number of Clusters
+	 */
+	private int NUMBER_OF_CLUSTERS = 2;
+	
+	/**
+	 * Number of packets used for number of packets per second
+	 */
+	private int NUMBER_OF_PACKETS = 30;
+	
+	/**
+	 * 
+	 */
+	private HashMap<String,Integer> link_mappings = new HashMap<String, Integer>();
+
+	private HashMap<String,Integer> source_mappings = new HashMap<String, Integer>();
+	
+	private HashMap<String,Integer> destination_mappings = new HashMap<String, Integer>();
+	
+	private HashMap<String,Integer> protocol_mappings = new HashMap<String, Integer>();
+	/**
+	 * 
+	 */
+	public UnsupervisedAnomalyDetectionExample() {
+		// Initialize Attribute list
+		link_mappings.put("unknown", 0);
+		atts.add(new Attribute("Link-Name", false));//TODO:??
+		source_mappings.put("unknown", 0);
+		atts.add(new Attribute("Source-Device", false));
+		atts.add(new Attribute("Source-Port-number", false));
+		destination_mappings.put("unknown", 0);
+		atts.add(new Attribute("Destination-Device", false));
+		atts.add(new Attribute("Destination-Port-number", false));
+		protocol_mappings.put("unknown", 0);
+		atts.add(new Attribute("Protocol-name", false));
+		atts.add(new Attribute("Packets-per-second", false));
+		// Initialize data set
+		dataset = new Instances("Packets", atts, 100000);
+		// Initialize Clusterer
+		clusterer = new SimpleKMeans();
+		clusterer.setSeed(42);
+		try {
+			clusterer.setNumClusters(NUMBER_OF_CLUSTERS);
+		} catch (Exception e) {
+			System.out.println("Error while building cluster");
+			e.printStackTrace();
+		}
+	}
+	
+	@Override
+	public void processPackets(HashMap<Link, LinkedList<Packet>> packets) {
+		if(training)
+			try {
+				training(packets);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		else
+			classify(packets);
+	}
+	/**
+	 * Estimates the current Packets per second (depending on the last 100 packets of the link)
+	 * @param link Link which should be checked
+	 * @param packet Packet which should investigated
+	 * @return estimated number of packets per second
+	 */
+	private double getEstimatedPacketsPerSecond(Link link, Packet packet) {
+		/**
+		 * Packets used to calculated the packets per second
+		 */
+		LinkedList<Packet> list = lastPackets.get(link);
+		if(list == null) {
+			/**
+			 * Add list if not present
+			 */
+			list = new LinkedList<Packet>();
+			lastPackets.put(link, list);
+		}
+		if(list.isEmpty()) {
+			list.addLast(packet);
+			// Default 1 packet per second
+			return 1.0;
+		}
+		if(list.size() == NUMBER_OF_PACKETS){
+			list.removeFirst();	
+		}
+		list.addLast(packet);
+		/**
+		 * elapsed time in milliseconds since last packet
+		 */
+		long elapsed_time = packet.getTimestamp()-list.getFirst().getTimestamp()/list.size();
+		if(elapsed_time<=0)
+			return Double.POSITIVE_INFINITY;
+		/**
+		 * Return number of packets per second
+		 */
+		return 1000.0/elapsed_time;
+		
+	}
+	
+	/**
+	 * Returns the instance representation of the given packet and link
+	 * @param link link the packet was sent on
+	 * @param packet packet which should be transformed
+	 * @param dataset distribution the packet is part of
+	 * @return instance representation
+	 */
+	private Instance packet2Instance(Link link, Packet packet, Instances dataset) {
+		/**
+		 * Instance for the given Packet
+		 */
+		DenseInstance instance = new DenseInstance(dataset.numAttributes());
+		instance.setDataset(dataset);
+		
+		// link
+		instance.setValue(0, link == null ? 0 : stringToNumber(link_mappings, link.getName()));
+		
+		// source
+		if(packet.getSource()==null) {
+			instance.setValue(1, 0);
+			instance.setValue(2, Double.NEGATIVE_INFINITY);
+		}else if(packet.getSource().getOwner()==null){
+			instance.setValue(1, 0);
+			instance.setValue(2, packet.getSource().getPortNumber());
+		}else {
+			instance.setValue(1, stringToNumber(source_mappings, packet.getSource().getOwner().getName()));
+			instance.setValue(2, packet.getSource().getPortNumber());
+		}
+		
+		// Destination
+		if(packet.getDestination()==null) {
+			instance.setValue(3, 0);
+			instance.setValue(4, Double.NEGATIVE_INFINITY);
+		}else if(packet.getDestination().getOwner()==null){
+			instance.setValue(3, 0);
+			instance.setValue(4, packet.getDestination().getPortNumber());
+		}else {
+			instance.setValue(3, stringToNumber(destination_mappings, packet.getDestination().getOwner().getName()));
+			instance.setValue(4, packet.getDestination().getPortNumber());
+		}
+		
+		// Protocol name
+		instance.setValue(5, stringToNumber(protocol_mappings, packet.getProtocolName()));
+		
+		// Packets per second
+		instance.setValue(6, getEstimatedPacketsPerSecond(link, packet));
+		
+		return instance;
+	}
+	
+	/**
+	 * Transforms the String into an Number
+	 * @param map
+	 * @param s
+	 * @return
+	 */
+	double stringToNumber(HashMap<String, Integer> map, String s) {
+		Integer i = map.get(s);
+		if(i == null) {
+			int size = map.size();
+			map.put(s, size);
+			return size;
+		}else {
+			return i;
+		}
+	}
+	/**
+	 * Train the clusterer by collecting the packets
+	 * 
+	 * @param packets packets to be learned
+	 */
+	private void training(HashMap<Link, LinkedList<Packet>> packets) {
+		for (Iterator<Entry<Link, LinkedList<Packet>>> it = packets.entrySet().iterator(); it.hasNext();) {
+			Entry<Link, LinkedList<Packet>> entry = it.next();
+			/**
+			 * Link the packet was captured on
+			 */
+			Link l = entry.getKey();
+			for (Iterator<Packet> itPacket = entry.getValue().iterator(); itPacket.hasNext();) {
+				/**
+				 * Packets to be added to the dataset
+				 */
+				Packet packet = (Packet) itPacket.next();
+				dataset.add(packet2Instance(l, packet, dataset));
+			}
+		}
+	}
+	
+	/**
+	 * Finishes the collection and trains the clusterer on the collected packets
+	 * 
+	 * @throws Exception
+	 */
+	private void finishDataCollection() throws Exception{
+		/**
+		 * Build the clusterer for the given dataset
+		 */
+		clusterer.buildClusterer(dataset);
+	}
+	
+	/**
+	 * Try to classify the given packets and detect anomalies
+	 * @param packets packets to be classified
+	 */
+	private void classify(HashMap<Link, LinkedList<Packet>> packets) {
+		for (Iterator<Entry<Link, LinkedList<Packet>>> it = packets.entrySet().iterator(); it.hasNext();) {
+			/**
+			 * Link & its packets
+			 */
+			Entry<Link, LinkedList<Packet>> entry = it.next();
+			/**
+			 * Link the packets were captured on
+			 */
+			Link l = entry.getKey();
+			for (Iterator<Packet> itPacket = entry.getValue().iterator(); itPacket.hasNext();) {
+				/**
+				 * Packet which should be checked
+				 */
+				Packet packet = (Packet) itPacket.next();
+				/**
+				 * Instance Representation
+				 */
+				Instance packet_instance = packet2Instance(l, packet, dataset);
+				try {
+					/**
+					 * Try to classify (find appropriate cluster)
+					 */
+					clusterer.clusterInstance(packet_instance);
+				} catch (Exception e) {
+					/**
+					 * Anomaly found
+					 */
+					System.out.println("Anomaly: "+packet.getTextualRepresentation());
+					//e.printStackTrace();
+				}
+			}
+		}
+	}
+	
+
+	
+	@Override
+	public void setMode(boolean testing) {
+		training = !testing;
+		if(testing) {
+			// Build Clusterer
+			try {
+				finishDataCollection();
+			} catch (Exception e) {
+				System.out.println("Clustering failed");
+				e.printStackTrace();
+			}
+		}
+	}
+	
+	@Override
+	public boolean getMode() {
+		return !training;
+	}
+}

+ 343 - 0
examples/UnsupervisedAnomalyDetectionExample2.java

@@ -0,0 +1,343 @@
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+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 weka.clusterers.SimpleKMeans;
+import weka.core.Attribute;
+import weka.core.DenseInstance;
+import weka.core.Instance;
+import weka.core.Instances;
+
+/**
+ * Unsupervised Example - maybe Clustering
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public class UnsupervisedAnomalyDetectionExample2 implements PacketSniffer {
+
+	/**
+	 * Clusterer
+	 */
+	private SimpleKMeans clusterer;
+	
+	/**
+	 * True, if instances should be used for training
+	 */
+	private boolean training = true;
+	
+	/**
+	 * Attributes which should be taken into account
+	 */
+	private ArrayList<Attribute> atts = new ArrayList<Attribute>();
+	
+	/**
+	 * Collected Packets
+	 */
+	private Instances dataset;
+	
+	/**
+	 * CollectedPackets
+	 */
+	private HashMap<Link, LinkedList<Packet>> collectedPackets = new HashMap<Link, LinkedList<Packet>>();
+	
+	
+	/**
+	 * HashMap for calculating transmission delay
+	 */
+	private HashMap<Link, LinkedList<Packet>> lastPackets = new HashMap<Link, LinkedList<Packet>>();
+	
+	/**
+	 * Number of Clusters
+	 */
+	private int NUMBER_OF_CLUSTERS = 2;
+	
+	/**
+	 * Number of packets used for number of packets per second
+	 */
+	private int NUMBER_OF_PACKETS = 30;
+	
+	/**
+	 * 
+	 */
+	private HashSet<String> link_mappings = new HashSet<String>();
+
+	private HashSet<String> source_mappings = new HashSet<String>();
+	
+	private HashSet<String> destination_mappings = new HashSet<String>();
+	
+	private HashSet<String> protocol_mappings = new HashSet<String>();
+	
+	/**
+	 * 
+	 */
+	public UnsupervisedAnomalyDetectionExample2() {
+		// Initialize Attribute list
+		source_mappings.add("unknown");
+		link_mappings.add("unknown");
+		destination_mappings.add("unknown");
+		protocol_mappings.add("unknown");
+		// Initialize data set
+		// Initialize Clusterer
+
+		clusterer = new SimpleKMeans();
+		clusterer.setSeed(42);
+		try {
+			clusterer.setNumClusters(NUMBER_OF_CLUSTERS);
+		} catch (Exception e) {
+			System.out.println("Error while building cluster");
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public void processPackets(HashMap<Link, LinkedList<Packet>> packets) {
+		if(training)
+			try {
+				training(packets);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		else
+			classify(packets);
+	}
+	
+	/**
+	 * Estimates the current Packets per second (depending on the last 100 packets of the link)
+	 * @param link Link which should be checked
+	 * @param packet Packet which should investigated
+	 * @return estimated number of packets per second
+	 */
+	private double getEstimatedPacketsPerSecond(Link link, Packet packet) {
+		/**
+		 * Packets used to calculated the packets per second
+		 */
+		LinkedList<Packet> list = lastPackets.get(link);
+		if(list == null) {
+			/**
+			 * Add list if not present
+			 */
+			list = new LinkedList<Packet>();
+			lastPackets.put(link, list);
+		}
+		if(list.isEmpty()) {
+			list.addLast(packet);
+			// Default 1 packet per second
+			return 1.0;
+		}
+		if(list.size() == NUMBER_OF_PACKETS){
+			list.removeFirst();	
+		}
+		list.addLast(packet);
+		/**
+		 * elapsed time in milliseconds since last packet
+		 */
+		long elapsed_time = packet.getTimestamp()-list.getFirst().getTimestamp()/list.size();
+		if(elapsed_time<=0)
+			return Double.POSITIVE_INFINITY;
+		/**
+		 * Return number of packets per second
+		 */
+		return 1000.0/elapsed_time;
+		
+	}
+	
+	/**
+	 * Returns the instance representation of the given packet and link
+	 * @param link link the packet was sent on
+	 * @param packet packet which should be transformed
+	 * @param dataset distribution the packet is part of
+	 * @return instance representation
+	 */
+	private Instance packet2Instance(Link link, Packet packet, Instances dataset) {
+		/**
+		 * Instance for the given Packet
+		 */
+		DenseInstance instance = new DenseInstance(dataset.numAttributes());
+		instance.setDataset(dataset);
+		
+		// link
+		instance.setValue(0, stringToNominal(link_mappings, link.getName()));
+		
+		// source
+		if(packet.getSource()==null) {
+			instance.setValue(1, "unknown");
+			instance.setValue(2, Double.NEGATIVE_INFINITY);
+		}else if(packet.getSource().getOwner()==null){
+			instance.setValue(1, "unknown");
+			instance.setValue(2, packet.getSource().getPortNumber());
+		}else {
+			instance.setValue(1, stringToNominal(source_mappings, packet.getSource().getOwner().getName()));
+			instance.setValue(2, packet.getSource().getPortNumber());
+		}
+		
+		// Destination
+		if(packet.getDestination()==null) {
+			instance.setValue(3, "unknown");
+			instance.setValue(4, Double.NEGATIVE_INFINITY);
+		}else if(packet.getDestination().getOwner()==null){
+			instance.setValue(3, "unknown");
+			instance.setValue(4, packet.getDestination().getPortNumber());
+		}else {
+			instance.setValue(3, stringToNominal(destination_mappings, packet.getDestination().getOwner().getName()));
+			instance.setValue(4, packet.getDestination().getPortNumber());
+		}
+		
+		// Protocol name
+		instance.setValue(5, stringToNominal(protocol_mappings, packet.getProtocolName()));
+		
+		// Packets per second
+		instance.setValue(6, getEstimatedPacketsPerSecond(link, packet));
+		
+		return instance;
+	}
+	
+	/**
+	 * Transforms the String into an Number
+	 * @param map
+	 * @param s
+	 * @return
+	 */
+	String stringToNominal(HashSet<String> map, String s) {
+		return map.contains(s)?s:"unknown";
+	}
+	/**
+	 * Train the clusterer by collecting the packets
+	 * 
+	 * @param packets packets to be learned
+	 */
+	private void training(HashMap<Link, LinkedList<Packet>> packets) {
+		for(Entry<Link, LinkedList<Packet>> e:packets.entrySet()) {
+			Link l = e.getKey();
+			LinkedList<Packet> p = collectedPackets.get(l);
+			if(p == null)
+				collectedPackets.put(l, new LinkedList<Packet>(e.getValue()));
+			else
+				p.addAll(e.getValue());
+		}
+	}
+	
+	/**
+	 * Finishes the collection and trains the clusterer on the collected packets
+	 * 
+	 * @throws Exception
+	 */
+	private void finishDataCollection() throws Exception{
+		atts.add(new Attribute("Link-Name", new LinkedList<String>(link_mappings)));//TODO:??
+		atts.add(new Attribute("Source-Device", new LinkedList<String>(source_mappings)));
+		atts.add(new Attribute("Source-Port-number", false));
+		atts.add(new Attribute("Destination-Device", new LinkedList<String>(destination_mappings)));
+		atts.add(new Attribute("Destination-Port-number", false));
+		Attribute pn = new Attribute("Protocol-name", new LinkedList<String>(protocol_mappings));
+		//pn.setWeight(10);
+		atts.add(pn);
+		Attribute pps = new Attribute("Packets-per-second", false);
+		//pps.setWeight(20);
+		atts.add(pps);
+		//atts.add(new Attribute("Anomaly", false));
+
+		/*
+		atts = new ArrayList<Attribute>();
+		atts.add(new Attribute("LN", new LinkedList<String>(link_mappings)));//TODO:??
+		atts.add(new Attribute("SD", new LinkedList<String>(source_mappings)));
+		atts.add(new Attribute("SPN", false));
+		atts.add(new Attribute("DD", new LinkedList<String>(destination_mappings)));
+		atts.add(new Attribute("DPN", false));
+		atts.add(new Attribute("PN", new LinkedList<String>(protocol_mappings)));
+		atts.add(new Attribute("PPS", false));
+		atts.add(new Attribute("A", false));*/
+		dataset = new Instances("Packets", atts, 100000);
+		//dataset.setClassIndex(7);
+
+		/**
+		 * Add Instances to dataset
+		 */
+		for (Iterator<Entry<Link, LinkedList<Packet>>> it = collectedPackets.entrySet().iterator(); it.hasNext();) {
+			Entry<Link, LinkedList<Packet>> entry = it.next();
+			/**
+			 * Link the packet was captured on
+			 */
+			Link l = entry.getKey();
+			for (Iterator<Packet> itPacket = entry.getValue().iterator(); itPacket.hasNext();) {
+				/**
+				 * Packets to be added to the dataset
+				 */
+				Packet packet = (Packet) itPacket.next();
+				dataset.add(packet2Instance(l, packet, dataset));
+			}
+		}
+		
+		/**
+		 * Build the clusterer for the given dataset
+		 */
+		clusterer.buildClusterer(dataset);
+	}
+	
+	/**
+	 * Try to classify the given packets and detect anomalies
+	 * @param packets packets to be classified
+	 */
+	private void classify(HashMap<Link, LinkedList<Packet>> packets) {
+		for (Iterator<Entry<Link, LinkedList<Packet>>> it = packets.entrySet().iterator(); it.hasNext();) {
+			/**
+			 * Link & its packets
+			 */
+			Entry<Link, LinkedList<Packet>> entry = it.next();
+			/**
+			 * Link the packets were captured on
+			 */
+			Link l = entry.getKey();
+			for (Iterator<Packet> itPacket = entry.getValue().iterator(); itPacket.hasNext();) {
+				/**
+				 * Packet which should be checked
+				 */
+				Packet packet = (Packet) itPacket.next();
+				/**
+				 * Instance Representation
+				 */
+				Instance packet_instance = packet2Instance(l, packet, dataset);
+				
+				if(packet_instance == null)continue;
+				try {
+					/**
+					 * Try to classify (find appropriate cluster)
+					 */
+					int c = clusterer.clusterInstance(packet_instance);
+					System.out.println("Cluster "+c+": "+packet.getTextualRepresentation());
+				} catch (Exception e) {
+					/**
+					 * Anomaly found
+					 */
+					System.out.println("Anomaly: "+packet.getTextualRepresentation());
+					e.printStackTrace();
+				}
+			}
+		}
+	}
+	
+
+	
+	@Override
+	public void setMode(boolean testing) {
+		training = !testing;
+		if(testing) {
+			// Build Clusterer
+			try {
+				finishDataCollection();
+			} catch (Exception e) {
+				System.out.println("Clustering failed");
+				e.printStackTrace();
+			}
+		}
+	}
+	
+	@Override
+	public boolean getMode() {
+		return !training;
+	}
+}

+ 426 - 0
examples/classifier/BasicPacketClassifier.java

@@ -0,0 +1,426 @@
+package classifier;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+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.protocols.packets.MQTTpublishPacket;
+import weka.core.Attribute;
+import weka.core.DenseInstance;
+import weka.core.Instance;
+import weka.core.Instances;
+
+/**
+ * Unsupervised Classifier Basis, which contains methods for transforming {@link Packet}s into {@link Instance}s.
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public abstract class BasicPacketClassifier implements PacketSniffer {
+
+	/**
+	 * True, if instances should be used for training
+	 */
+	protected boolean training = true;
+	
+	/**
+	 * Attributes which should be taken into account
+	 */
+	protected ArrayList<Attribute> atts = new ArrayList<Attribute>();
+	
+	/**
+	 * Collected Packets
+	 */
+	protected Instances dataset;
+	
+	/**
+	 * CollectedPackets
+	 */
+	protected HashMap<Link, LinkedList<Packet>> collectedPackets = new HashMap<Link, LinkedList<Packet>>();
+	
+	/**
+	 * HashMap for calculating transmission delay
+	 */
+	protected HashMap<Link, LinkedList<Packet>> lastPackets = new HashMap<Link, LinkedList<Packet>>();
+	
+	/**
+	 * Map for the different Link names
+	 */
+	protected HashSet<String> link_mappings = new HashSet<String>();
+
+	/**
+	 * Map for the difference source device names
+	 */
+	protected HashSet<String> source_mappings = new HashSet<String>();
+	
+	/**
+	 * Map for the different destination device names
+	 */
+	protected HashSet<String> destination_mappings = new HashSet<String>();
+	
+	/**
+	 * Map for the protocol names
+	 */
+	protected HashSet<String> protocol_mappings = new HashSet<String>();
+
+	/**
+	 * Number of packets which are used to calculate the current transmission speed
+	 */
+	protected int NUMBER_OF_PACKETS = 200;
+	
+	/**
+	 * Initializes the different maps
+	 */
+	public BasicPacketClassifier() {
+		// Initialize Attribute list
+		source_mappings.add("unknown");
+		link_mappings.add("unknown");
+		destination_mappings.add("unknown");
+		protocol_mappings.add("unknown");
+	}
+	
+	@Override
+	public void processPackets(HashMap<Link, LinkedList<Packet>> packets) {
+		if(training)
+			try {
+				training(packets);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		else
+			classify(packets);
+	}
+	
+	/**
+	 * Estimates the current Packets per second (depending on the last 100 packets of the link)
+	 * @param link Link which should be checked
+	 * @param packet Packet which should investigated
+	 * @return estimated number of packets per second
+	 */
+	protected double getEstimatedPacketsPerSecond(Link link, Packet packet) {
+		/**
+		 * Packets used to calculated the packets per second
+		 */
+		LinkedList<Packet> list = lastPackets.get(link);
+		if(list == null) {
+			/**
+			 * Add list if not present
+			 */
+			list = new LinkedList<Packet>();
+			lastPackets.put(link, list);
+		}
+		if(list.isEmpty()) {
+			list.addLast(packet);
+			// Default 1 packet per second
+			return 1.0;
+		}
+		if(list.size() == NUMBER_OF_PACKETS){
+			list.removeFirst();	
+		}
+		list.addLast(packet);
+		/**
+		 * elapsed time in milliseconds since last packet
+		 */
+		long elapsed_time = packet.getTimestamp()-list.getFirst().getTimestamp()/list.size();
+		if(elapsed_time<=0)
+			return Double.POSITIVE_INFINITY;
+		/**
+		 * Return number of packets per second
+		 */
+		return 1000.0/elapsed_time;
+		
+	}
+	
+	/**
+	 * Returns the instance representation of the given packet and link
+	 * @param link link the packet was sent on
+	 * @param packet packet which should be transformed
+	 * @param dataset distribution the packet is part of
+	 * @return instance representation
+	 */
+	protected Instance packet2Instance(Link link, Packet packet, Instances dataset) {
+		/**
+		 * Instance for the given Packet
+		 */
+		DenseInstance instance = new DenseInstance(dataset.numAttributes());
+		instance.setDataset(dataset);
+		
+		// link
+		instance.setValue(0, stringToNominal(link_mappings, link.getName()));
+		
+		// source
+		if(packet.getSource()==null) {
+			instance.setValue(1, "unknown");
+			instance.setValue(2, Double.NEGATIVE_INFINITY);
+		}else if(packet.getSource().getOwner()==null){
+			instance.setValue(1, "unknown");
+			instance.setValue(2, packet.getSource().getPortNumber());
+		}else {
+			instance.setValue(1, stringToNominal(source_mappings, packet.getSource().getOwner().getName()));
+
+			instance.setValue(2, packet.getSource().getPortNumber());
+		}
+		
+		// Destination
+		if(packet.getDestination()==null) {
+			instance.setValue(3, "unknown");
+			instance.setValue(4, Double.NEGATIVE_INFINITY);
+		}else if(packet.getDestination().getOwner()==null){
+			instance.setValue(3, "unknown");
+
+			instance.setValue(4, packet.getDestination().getPortNumber());
+		}else {
+			instance.setValue(3, stringToNominal(destination_mappings, packet.getDestination().getOwner().getName()));
+			instance.setValue(4, packet.getDestination().getPortNumber());
+		}
+		
+		// Protocol name
+		instance.setValue(5, stringToNominal(protocol_mappings, packet.getProtocolName()));
+		
+		// Packets per second
+		instance.setValue(6, getEstimatedPacketsPerSecond(link, packet));
+		// MQTT Value
+		if(packet instanceof MQTTpublishPacket)
+			instance.setValue(7, ((MQTTpublishPacket)packet).getValue());
+		else
+			instance.setValue(7, -1);
+		
+		return instance;
+	}
+	
+	/**
+	 * Inserts the
+	 * @param map
+	 * @param nominal
+	 */
+	protected void insertNominalIntoMap(HashSet<String> map, String nominal) {
+		if(map == null || nominal == null)
+			return;
+		map.add(nominal);
+	}
+	/**
+	 * Transforms the String into an Number
+	 * @param map
+	 * @param s
+	 * @return
+	 */
+	protected String stringToNominal(HashSet<String> map, String s) {
+		return map.contains(s)?s:"unknown";
+	} 
+	
+	/**
+	 * Train the clusterer by collecting the packets
+	 * 
+	 * @param packets packets to be learned
+	 */
+	protected void training(HashMap<Link, LinkedList<Packet>> packets) {
+		for(Entry<Link, LinkedList<Packet>> e:packets.entrySet()) {
+			Link l = e.getKey();
+			// TODO: ERROR ????????
+			LinkedList<Packet> p = collectedPackets.get(l);
+			if(p == null) {
+				collectedPackets.put(l, new LinkedList<Packet>(e.getValue()));
+			} else
+				p.addAll(e.getValue());
+			insertNominalIntoMap(link_mappings, l.getName());
+			for(Packet pac: e.getValue()) {
+				if(pac == null || pac.getSource()==null ||pac.getDestination() == null || pac.getSource().getOwner() == null || pac.getDestination().getOwner() == null)
+					continue;
+				insertNominalIntoMap(destination_mappings, pac.getSource().getOwner().getName());
+				insertNominalIntoMap(destination_mappings, pac.getDestination().getOwner().getName());
+				insertNominalIntoMap(source_mappings, pac.getSource().getOwner().getName());
+				insertNominalIntoMap(source_mappings, pac.getDestination().getOwner().getName());
+				insertNominalIntoMap(protocol_mappings, pac.getProtocolName());
+			}
+			//TODO: Add packet/Link/Names etc. to mappings
+		}
+	}
+	
+	/**
+	 * Finishes the collection and trains the clusterer on the collected packets
+	 * 
+	 * @throws Exception
+	 */
+	protected void finishDataCollection() throws Exception{
+		/**
+		printHashSet("Link-Name", link_mappings);
+		printHashSet("Source-Device", source_mappings);
+		printHashSet("Destination-Port", destination_mappings);
+		printHashSet("Protocol-name", protocol_mappings);
+		*/
+		atts.add(new Attribute("Link-Name", new LinkedList<String>(link_mappings)));//TODO:??
+		atts.add(new Attribute("Source-Device", new LinkedList<String>(source_mappings)));
+		atts.add(new Attribute("Source-Port-number", false));
+		atts.add(new Attribute("Destination-Device", new LinkedList<String>(destination_mappings)));
+		atts.add(new Attribute("Destination-Port-number", false));
+		Attribute pn = new Attribute("Protocol-name", new LinkedList<String>(protocol_mappings));
+		//pn.setWeight(10);
+		atts.add(pn);
+		Attribute pps = new Attribute("Packets-per-second", false);
+		//pps.setWeight(20);
+		atts.add(pps);
+		atts.add(new Attribute("PacketValue", false));
+		//atts.add(new Attribute("Anomaly", false));
+
+		/*
+		atts = new ArrayList<Attribute>();
+		atts.add(new Attribute("LN", new LinkedList<String>(link_mappings)));//TODO:??
+		atts.add(new Attribute("SD", new LinkedList<String>(source_mappings)));
+		atts.add(new Attribute("SPN", false));
+		atts.add(new Attribute("DD", new LinkedList<String>(destination_mappings)));
+		atts.add(new Attribute("DPN", false));
+		atts.add(new Attribute("PN", new LinkedList<String>(protocol_mappings)));
+		atts.add(new Attribute("PPS", false));
+		atts.add(new Attribute("A", false));*/
+		dataset = new Instances("Packets", atts, 100000);
+		//dataset.setClassIndex(7);
+
+		/**
+		 * Add Instances to dataset
+		 */
+		for (Iterator<Entry<Link, LinkedList<Packet>>> it = collectedPackets.entrySet().iterator(); it.hasNext();) {
+			Entry<Link, LinkedList<Packet>> entry = it.next();
+			/**
+			 * Link the packet was captured on
+			 */
+			Link l = entry.getKey();
+			for (Iterator<Packet> itPacket = entry.getValue().iterator(); itPacket.hasNext();) {
+				/**
+				 * Packets to be added to the dataset
+				 */
+				Packet packet = (Packet) itPacket.next();
+				dataset.add(packet2Instance(l, packet, dataset));
+			}
+		}
+		
+		trainModel(dataset);
+	}
+	
+	private void printHashSet(String name, HashSet<String> toPrint) {
+		System.out.println(name+":");
+		for (Iterator<String> iterator = toPrint.iterator(); iterator.hasNext();) {
+			String string = (String) iterator.next();
+			System.out.print(string);
+			if(iterator.hasNext())
+				System.out.print(", ");
+		}
+		System.out.println();
+	}
+	/**
+	 * Try to classify the given packets and detect anomalies
+	 * @param packets packets to be classified
+	 */
+	protected void classify(HashMap<Link, LinkedList<Packet>> packets) {
+		int tp = 0;
+		int fp = 0;
+		int tn = 0;
+		int fn = 0;
+		long start = Long.MAX_VALUE;
+		long end = Long.MIN_VALUE;
+		for (Iterator<Entry<Link, LinkedList<Packet>>> it = packets.entrySet().iterator(); it.hasNext();) {
+			/**
+			 * Link & its packets
+			 */
+			Entry<Link, LinkedList<Packet>> entry = it.next();
+			/**
+			 * Link the packets were captured on
+			 */
+			Link l = entry.getKey();
+			for (Iterator<Packet> itPacket = entry.getValue().iterator(); itPacket.hasNext();) {
+				/**
+				 * Packet which should be checked
+				 */
+				Packet packet = (Packet) itPacket.next();
+
+				start = Math.min(start, packet.getTimestamp());
+				end = Math.max(end, packet.getTimestamp());
+				/**
+				 * Instance Representation
+				 */
+				Instance packet_instance = packet2Instance(l, packet, dataset);
+				
+				if(packet_instance == null)continue;
+				try {
+					double dist = classifyInstance(packet_instance, packet);	
+					if(dist<=1.0) {
+						if(packet.getLabel()==0)
+							tn++;
+						else
+							fn++;
+					}else {
+						if(packet.getLabel()==0)
+							fp++;
+						else
+							tp++;
+					}
+				} catch (Exception e) {
+					if(packet.getLabel()==0)
+						fp++;
+					else
+						tp++;
+				}
+			}	
+		}
+		int n = tp+tn+fp+fn;
+		if(n!=0) {
+			System.out.println(getAlgoName()+" Performance: ["+start+"ms, "+end+"ms]");
+			System.out.println("n: "+n);
+			System.out.println("TP: "+tp);
+			System.out.println("FP: "+fp);
+			System.out.println("TN: "+tn);
+			System.out.println("FN: "+fn);
+			System.out.println("TPR: "+(tp/(tp+fn+0.0)));
+			System.out.println("FPR: "+(fp/(fp+tn+0.0)));
+			System.out.println("");
+		}
+	}
+	
+	/**
+	 * Train the model using the given instances
+	 * @param instances training set, which should be learned
+	 */
+	public abstract void trainModel(Instances instances);
+	
+	/**
+	 * classifies the given instance
+	 * @param instance instance which should be classified
+	 * @param origin original packet, which was transformed into the instance
+	 * @return distance to next centroid
+	 * @throws Exception if anomaly was detected
+	 */
+	public abstract double classifyInstance(Instance instance, Packet origin) throws Exception;
+	
+	/**
+	 * Returns the timestep, after which the classifier should start classifying instead of training.
+	 * @return timestep of the testing begin.
+	 */
+	public abstract long getClassificationStart();
+	
+	@Override
+	public void setMode(boolean testing) {
+		training = !testing;
+		if(testing) {
+			try {
+				finishDataCollection();
+			} catch (Exception e) {
+				System.out.println("Clustering failed");
+				e.printStackTrace();
+			}	
+		}
+	}
+	
+	@Override
+	public boolean getMode() {
+		return !training;
+	}
+	
+	/**
+	 * Short String representation of the classifier
+	 * @return
+	 */
+	public abstract String getAlgoName();
+}

+ 87 - 0
examples/classifier/EMClustering.java

@@ -0,0 +1,87 @@
+package classifier;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
+import weka.clusterers.EM;
+import weka.core.Instance;
+import weka.core.Instances;
+
+/**
+ * Expectation Maximization Clustering Approach
+ * @author Andreas T. Meyer-Berg
+ */
+public class EMClustering extends BasicPacketClassifier {
+
+	/**
+	 * EM cluster which is used
+	 */
+	private EM clusterer;
+	
+	/**
+	 * Initialize the clusterer
+	 */
+	public EMClustering() {
+		clusterer = new EM();
+	}
+	
+	@Override
+	public void trainModel(Instances instances) {
+		try {
+			clusterer.buildClusterer(instances);
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+	}
+
+	@Override
+	public double classifyInstance(Instance instance, Packet origin) throws Exception {
+		/**
+		 * Id of the closest cluster
+		 */
+		int x = clusterer.clusterInstance(instance);
+
+		/*
+		System.out.println(origin.getTextualRepresentation()+": cluster: "+x+" Dens: "+clusterer.logDensityForInstance(instance)+" joined: ");
+		double[] joined = clusterer.logJointDensitiesForInstance(instance);
+		for(int i = 0;i<joined.length;) {
+			System.out.print(joined[i]);
+			if(++i<joined.length)
+				System.out.print(", ");
+			else
+				System.out.println("");
+		}
+		System.out.println("Distribution:");
+		double[] distribution = clusterer.distributionForInstance(instance);
+		for(int i = 0;i<distribution.length;) {
+			System.out.print(distribution[i]);
+			if(++i<distribution.length)
+				System.out.print(", ");
+			else
+				System.out.println("");
+		}
+		
+		double[] priors = clusterer.clusterPriors();
+		System.out.println("Priors: ");
+		for(int i = 0; i<priors.length; i++) {
+			System.out.println("i="+i+": "+priors[i]);
+		}
+		double[][][] rest = clusterer.getClusterModelsNumericAtts();
+		double[][] posteriori = rest[x];
+		for(int i = 0; i<posteriori.length; i++) {
+			System.out.println("Att "+i+": Mean: "+posteriori[i][0]+" Std: "+posteriori[i][1]+" ???: "+posteriori[i][2]+" Real: "+instance.value(i));
+		}*/
+		return (1-clusterer.distributionForInstance(instance)[x])*800;
+	}
+
+	@Override
+	public long getClassificationStart() {
+		return 3600000;
+	}
+
+	@Override
+	public String getAlgoName() {
+		return "EM";
+	}
+
+}

+ 70 - 0
examples/classifier/HierarchicalClustering.java

@@ -0,0 +1,70 @@
+package classifier;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
+import weka.clusterers.HierarchicalClusterer;
+import weka.core.EuclideanDistance;
+import weka.core.Instance;
+import weka.core.Instances;
+
+/**
+ * Hierarchical Clustering Approach
+ * @author Andreas T. Meyer-Berg
+ */
+public class HierarchicalClustering extends BasicPacketClassifier {
+
+	/**
+	 * Hierarchical cluster which is used
+	 */
+	private HierarchicalClusterer clusterer;
+	
+	/**
+	 * Initialize the clusterer
+	 */
+	public HierarchicalClustering() {
+		clusterer = new HierarchicalClusterer();
+		clusterer.setDistanceFunction(new EuclideanDistance());
+		clusterer.setNumClusters(16);
+	}
+	
+	@Override
+	public void trainModel(Instances instances) {
+		try {
+			clusterer.buildClusterer(instances);
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+	}
+
+	@Override
+	public double classifyInstance(Instance instance, Packet origin) throws Exception {
+		/**
+		 * Id of the closes cluster centroid
+		 */
+		int x = clusterer.clusterInstance(instance);
+		/**
+		 * centroid instance
+		 */
+		/*
+		System.out.print(origin.getTextualRepresentation()+": ");
+		double[] posteriori = clusterer.distributionForInstance(instance);
+		for(int i = 0; i<posteriori.length; i++) {
+			System.out.print(posteriori[i]);
+			if(i<posteriori.length-1)
+				System.out.print(", ");
+		}*/
+		return 1;
+	}
+
+	@Override
+	public long getClassificationStart() {
+		return 3600000;
+	}
+
+	@Override
+	public String getAlgoName() {
+		return "HC";
+	}
+
+}

+ 121 - 0
examples/classifier/KMeansClustering.java

@@ -0,0 +1,121 @@
+package classifier;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
+import weka.clusterers.SimpleKMeans;
+import weka.core.Instance;
+import weka.core.Instances;
+import weka.core.SelectedTag;
+
+/**
+ * Unsupervised Example: K Means Clustering
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public class KMeansClustering extends BasicPacketClassifier {
+
+	/**
+	 * Clusterer
+	 */
+	private SimpleKMeans clusterer;
+
+	/**
+	 * Number of Clusters
+	 */ 
+	//17 works fine
+	//34 found value anomalies
+	protected int NUMBER_OF_CLUSTERS = 34;
+	protected double[] stdv = new double[NUMBER_OF_CLUSTERS];
+	/**
+	 * Initializes the k means clusterer
+	 */
+	public KMeansClustering() {
+		super();
+		clusterer = new SimpleKMeans();
+		clusterer.setSeed(42);
+		//clusterer.setDisplayStdDevs(true);
+		clusterer.setInitializationMethod(new SelectedTag(SimpleKMeans.FARTHEST_FIRST,SimpleKMeans.TAGS_SELECTION));
+		//clusterer.setCanopyPeriodicPruningRate(100);
+		//clusterer.setCanopyT1(0.001);
+		//clusterer.setCanopyT2(0.1);
+		try {
+			clusterer.setNumClusters(this.NUMBER_OF_CLUSTERS);
+		} catch (Exception e) {
+			System.out.println("Error while building cluster");
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public void trainModel(Instances instances) {
+		try {
+			clusterer.buildClusterer(instances);
+			double[] sumOfSquares = new double[NUMBER_OF_CLUSTERS];
+			for(Instance i: instances) {
+				/**
+				 * Id of the closest cluster centroid
+				 */
+				int x = clusterer.clusterInstance(i);
+				/**
+				 * centroid instance
+				 */
+				Instance center = clusterer.getClusterCentroids().get(x);
+				/**
+				 * Distance
+				 */
+				double dist = clusterer.getDistanceFunction().distance(center, i);
+				sumOfSquares[x] += dist*dist;
+			}
+			/**
+			 * Calculate Standard Deviations
+			 */
+			for(int i = 0; i<NUMBER_OF_CLUSTERS; i++)
+				this.stdv[i] = Math.sqrt(sumOfSquares[i]);
+		} catch (Exception e) {
+			System.out.println("Failed while training the classifier");
+			e.printStackTrace();
+		}
+	}
+	private boolean test = true;
+	@Override
+	public double classifyInstance(Instance instance, Packet origin) throws Exception {
+		/**
+		 * Id of the closest cluster centroid
+		 */
+		int x = clusterer.clusterInstance(instance);
+		/**
+		 * centroid instance
+		 */
+		Instance center = clusterer.getClusterCentroids().get(x);
+		
+		double dist = clusterer.getDistanceFunction().distance(center, instance);
+		if(test && dist<stdv[x] && origin.getLabel()!=0) {
+			test = false;
+			System.out.println("Analysis of: "+origin.getTextualRepresentation());
+			System.out.println("Classified as: "+x+" Dist: "+dist+" Stdv: "+stdv[x]);
+			for(int i=0; i<NUMBER_OF_CLUSTERS; i++) {
+				Instance centroid = clusterer.getClusterCentroids().get(i);
+				if(centroid == null)continue;
+				double d = clusterer.getDistanceFunction().distance(centroid, instance);
+				
+				System.out.println("Cluster: "+i+" Dist: "+d+" Stdv: "+stdv[i]);
+			}
+			test = false;
+			System.out.println("");
+		}
+		if(dist < stdv[x])
+			return 0;
+		else
+			return Double.MAX_VALUE;
+		
+	}
+
+	@Override
+	public long getClassificationStart() {
+		return 3600000;
+	}
+
+	@Override
+	public String getAlgoName() {
+		return "KNN";
+	}
+}

+ 1 - 1
gradle/wrapper/gradle-wrapper.properties

@@ -1,5 +1,5 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists

BIN
libs/weka.jar


BIN
libs_src/weka_src.jar


+ 196 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/ExampleAnomalyController.java

@@ -0,0 +1,196 @@
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.control;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Connection;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ConnectionPrecision;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PrecisionLink;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler.NormalDistributionHandler;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.simpleImplementation.SimpleProtocol;
+
+/**
+ * Controller, which allows the user to create a few example anomalies
+ * @author Andreas T. Meyer-Berg
+ *
+ */
+public class ExampleAnomalyController {
+
+	/**
+	 * Controller which is used to manipulates the network parts
+	 */
+	private Controller controller;
+	
+	/**
+	 * Initializes the Anomaly Controller
+	 * @param controller controller to be used
+	 */
+	public ExampleAnomalyController(Controller controller) {
+		this.controller = controller;
+	}
+	
+	/**
+	 * Opens a DDosCreation Menu which targets the given Device
+	 * So far only a DDoS Attack is created
+	 * @param d Device which should be targeted
+	 * @return DDoS Connection, which was created 
+	 */
+	public Connection openDDosCreationMenu(SmartDevice d, List<SmartDevice> sources) {
+		/**
+		 * Port of the largest connected connection to disguise DDoS
+		 */
+		Port example = null;
+		for(Port p: d.getPorts()) {
+			if(example == null || example.getConnection() == null || example.getConnection().getProtocol()==null) {
+				example = p;
+			} else {
+				if(p.getConnection() == null || p.getConnection().getProtocol() == null) {
+					continue;
+				} else if(p.getConnection().getParticipants().size()>example.getConnection().getParticipants().size()){
+					example = p;
+				}
+			}
+		}
+		if(example == null || example.getConnection() == null || example.getConnection().getProtocol()==null)
+			example = null;
+		/**
+		 * Role of the target device
+		 */
+		int targetRole = 0;
+		if(example != null) {
+			targetRole = example.getConnection().getProtocol().getRoleOfDevice(example);
+			if(targetRole == -1)
+				targetRole = 0;
+		}
+		/**
+		 * Attack Interval per device
+		 */
+		long attackInterval = 1;
+		if(example!=null) {
+			int numDevices = 0;
+			for(Port exP:example.getConnection().getParticipants()) {
+				attackInterval+=exP.getTriggerInterval();
+				numDevices++;
+			}
+			attackInterval /= numDevices == 0 ? 1 : numDevices;
+			/**
+			 * Frequency Less or equal
+			 */
+			attackInterval /= 10.0;
+		}
+		
+		/**
+		 * Link of the DDoS attack
+		 */
+		Link link = null;
+		if(example !=null)
+			link = example.getConnection().getLink();
+		if(link == null) {
+			if(d.getLinks().isEmpty()) {
+				System.out.println("WARNING: Could not create DDos, as Device "+d.getName()+" is not connected to any Link");
+				return null;
+			}
+			link = d.getLinks().get(0);
+		}
+		NetworkController networkController = controller.getNetworkController();
+		Connection ddosConnection = new ConnectionPrecision();
+		ddosConnection.setLabel((short)1);
+		ddosConnection.setName("DDOS against "+d.getName());
+		networkController.addConnectionToLink(ddosConnection, link);
+		try {
+			@SuppressWarnings("unchecked")
+			Class<Protocol> exampleProtocol = (Class<Protocol>) example.getConnection().getProtocol().getClass();
+			ddosConnection.setProtocol(exampleProtocol.newInstance());	
+		} catch (Exception e) {
+			ddosConnection.setProtocol(new SimpleProtocol());			
+		}
+		LinkedList<SmartDevice> devices = new LinkedList<SmartDevice>(sources);
+		devices.retainAll(link.getDevices());
+		
+		
+		Port pTarget = new Port(d, (short)80, 1000L);
+		pTarget.setStatus(Port.OPEN);
+		if(!networkController.addDeviceToConnectionAndProtocol(pTarget, ddosConnection, targetRole)) {
+			System.out.println("WARNING: Could not add DDoS Target to role "+targetRole);
+		}
+			
+		for(SmartDevice src: devices) {
+			if(src==d)continue;
+			Port pSource = new Port(src, (short)80, 1L);
+			pSource.setTriggerHandler(new NormalDistributionHandler(attackInterval, attackInterval*0.05));
+			pSource.setStatus(Port.SENDING);
+			// Ten tries of assigning random role
+			for(int i=0; i<10;i++) {
+				int sourceRole = (int) Math.floor(Math.random()*ddosConnection.getProtocol().getNumberOfRoles());
+				if(sourceRole==targetRole)
+					continue;
+				if(networkController.addDeviceToConnectionAndProtocol(pSource, ddosConnection, sourceRole)) 
+					break;
+			}
+		}
+		networkController.addConnection(ddosConnection);
+		
+		controller.notifyObservers();
+		return ddosConnection;
+	}
+	
+	/**
+	 * Crash Device, which wont send packets any longer
+	 * @param d Device to be crashed
+	 */
+	public void crashDevice(SmartDevice d) {
+		for(Port p:d.getPorts()) {
+			p.setStatus(Port.CLOSED);
+		}
+		controller.notifyObservers();
+	}
+
+	/**
+	 * Inserts DOS attack into the network
+	 * @param source source of the attack
+	 * @param target destination of the attack
+	 * @return DDoS Connection, which was created
+	 */
+	public Connection runDosAttack(SmartDevice source, SmartDevice target) {
+		NetworkController networkController = controller.getNetworkController();
+		Connection dosConnection = new ConnectionPrecision();
+		dosConnection.setLabel((short)1);
+		dosConnection.setName("DOS: "+source.getName()+"-"+target.getName());
+		networkController.addConnectionToLink(dosConnection, getCommonLink(source, target));
+		dosConnection.setProtocol(new SimpleProtocol());
+		Port pSource = new Port(source, (short)80, 4L);
+		pSource.setStatus(Port.SENDING);
+		networkController.addDeviceToConnectionAndProtocol(pSource, dosConnection, 0);
+		Port pTarget = new Port(target, (short)80, 1000L);
+		pTarget.setStatus(Port.OPEN);
+		networkController.addDeviceToConnectionAndProtocol(pSource, dosConnection, 0);
+		networkController.addDeviceToConnectionAndProtocol(pTarget, dosConnection, 1);
+		networkController.addConnection(dosConnection);
+		controller.notifyObservers();
+		return dosConnection;
+	}
+	
+	/**
+	 * Returns a common Link of the given devices
+	 * @param a
+	 * @param b
+	 * @return Link, both devices are connected to
+	 */
+	private Link getCommonLink(SmartDevice a, SmartDevice b) {
+		LinkedList<Link> l = new LinkedList<Link>(a.getLinks());
+		l.addAll(b.getLinks());
+		if(l.isEmpty()) {
+			NetworkController net = controller.getNetworkController();
+			Link newLink = new PrecisionLink("Direct Link: " + a.getName()+"-"+b.getName());
+			net.addLinkToDevice(newLink, a);
+			net.addLinkToDevice(newLink, b);
+			net.addLink(newLink);
+			return newLink;
+		}else
+			return l.getFirst();
+	}
+}

+ 61 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/ImportController.java

@@ -15,6 +15,7 @@ import javax.tools.ToolProvider;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Model;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Connection;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ProbabilityDistributionHandler;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.configuration.ImportConfiguration;
@@ -293,6 +294,66 @@ public class ImportController {
 		return true;
 	}
 	
+	/**
+	 * Adds new DistributionHandler to the model
+	 * 
+	 * @param distributionHandler DistributionHandler to be added
+	 * @return true if it was added
+	 */
+	public boolean addDistributionHandler(Class<? extends ProbabilityDistributionHandler> distributionHandler) {
+		if (isValidDistributionHandler(distributionHandler))
+			importConf.addDistributionHandlerClass(distributionHandler);
+		else
+			return false;
+		return true;
+		
+	}
+	
+	/**
+	 * Removes DistributionHandler from the model
+	 * 
+	 * @param distributionHandler
+	 *            DistributionHandler to be removed
+	 */
+	public void removeDistributionHandler(Class<? extends ProbabilityDistributionHandler> distributionHandler) {
+		importConf.removeDistributionHandlerClass(distributionHandler);
+	}
+	
+	/**
+	 * Returns the available DistributionHandler of the model
+	 * 
+	 * @return available DistributionHandler
+	 */
+	public LinkedList<Class<? extends ProbabilityDistributionHandler>> getDistributionHandlers() {
+		return importConf.getDistributionHandlerClasses();
+	}
+	
+	/**
+	 * Returns true if it is a Valid DistributionHandler, false if not
+	 * 
+	 * @param distributionHandler
+	 *            DistributionHandler to be checked
+	 * @return true if it is a valid DistributionHandler
+	 */
+	public boolean isValidDistributionHandler(Class<? extends ProbabilityDistributionHandler> distributionHandler) {
+		try {
+			/**
+			 * SmartDevice to be tested
+			 */
+			ProbabilityDistributionHandler p = distributionHandler.newInstance();
+			// Empty constructor required, to create new instance
+			if (p == null)
+				throw new Exception("DistributionHandler required an empty constructor");
+			// Name shall not be null or empty string
+			if (p.getSimpleDescription() == null || p.getSimpleDescription() == "")
+				throw new Exception(
+						"DistributionHandler name shall not be null or empty string.");
+		} catch (Exception e) {
+			return false;
+		}
+		return true;
+	}
+	
 	/**
 	 * Imports the given .java File, compiles it and returns the compiled class
 	 * 

+ 22 - 2
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/NetworkController.java

@@ -38,6 +38,10 @@ public class NetworkController {
 	 * Packet Capture Controller
 	 */
 	private PacketCaptureController captureController;
+	/**
+	 * ExampleAnomalyController
+	 */
+	private ExampleAnomalyController anomalyController;
 	/**
 	 * Creates a new NetworkController, which may manipulate the given model and use the controller
 	 * @param model Model which can be manipulated
@@ -48,6 +52,7 @@ public class NetworkController {
 		this.controller = controller;
 		networkTreeSettings = controller.getSettingsController().getNetworkTreeSettingsController();
 		captureController = controller.getSimulationController().getPacketCaptureController();
+		anomalyController = new ExampleAnomalyController(controller);
 	}
 
 	/**
@@ -92,12 +97,13 @@ public class NetworkController {
 	 * @param z_pos
 	 *            position on the z-Axis
 	 */
-	public void createSmartDevice(String name, int x_pos, int y_pos, int z_pos) {
+	public SmartDevice createSmartDevice(String name, int x_pos, int y_pos, int z_pos) {
 		SmartDevice sd = new SmartDevice(name);
 		sd.setX(controller.getSettingsController().scalePos(x_pos, 1.0, controller.getSettingsController().getWidth()));
 		sd.setY(controller.getSettingsController().scalePos(y_pos, 1.0, controller.getSettingsController().getHeight()));
 		sd.setZ(controller.getSettingsController().scalePos(z_pos, 1.0, controller.getSettingsController().getDepth()));
 		model.addDevices(sd);
+		return sd;
 	}
 
 	/**
@@ -274,7 +280,7 @@ public class NetworkController {
 			link.addDevice(smartDevice);
 		}
 		
-		if(!smartDevice.getLinks().contains(smartDevice)){
+		if(!smartDevice.getLinks().contains(link)){
 			smartDevice.addLink(link);
 		}
 		
@@ -385,6 +391,8 @@ public class NetworkController {
 				connection.addSmartDevice(p);
 			if(p.getConnection()!=connection)
 				p.setConnection(connection);
+			if(!p.getOwner().getPorts().contains(p))
+				p.getOwner().addPort(p);
 			return true;
 		}else {
 			//Device could not be added -> Remove
@@ -552,6 +560,10 @@ public class NetworkController {
 			captureController.removePacketCollector(p);
 		}
 		
+		/**
+		 * Clear event queue
+		 */
+		
 		/**
 		 * Update the GUI
 		 */
@@ -764,4 +776,12 @@ public class NetworkController {
 			return newDevice;
 		}
 	}
+
+	/**
+	 * Returns the AnomalyController, which can be used to insert anomalies into the network model
+	 * @return Anomaly Controller
+	 */
+	public ExampleAnomalyController getAnomalyController() {
+		return anomalyController;
+	}
 }

+ 43 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/PacketCaptureController.java

@@ -163,7 +163,49 @@ public class PacketCaptureController {
 			notifyObservers();
 		}
 	}
-	
+	/**
+	 * Returns training or testing mode of the algorithm.
+	 * @param collector Collector which is used
+	 * @return true if testing or false if training the algorithm.
+	 */
+	public boolean getMode(PacketCollector collector) {
+		if(collector == null) 
+			return false;
+		return collector.getMode();
+	}
+
+	/**
+	 * Sets the training or testing mode
+	 * @param collector Collector which is used
+	 * @param mode true if testing or false if training the algorithm.
+	 */
+	public void setMode(PacketCollector collector, boolean mode) {
+		if(collector == null) return;
+		collector.setMode(mode);
+		notifyObservers();
+	}
+
+	/**
+	 * Whether the algorithm should run
+	 * @param collector Collector which is used
+	 * @return true if algorithm will be executed
+	 */
+	public boolean isActive(PacketCollector collector) {
+		if(collector == null) 
+			return false;
+		return collector.isActive();
+	}
+
+	/**
+	 * Set to true, if it should run
+	 * @param collector Collector which is used
+	 * @param active true if it should be active
+	 */
+	public void setActive(PacketCollector collector, boolean active) {
+		if(collector == null)return;
+		collector.setActive(active);
+		notifyObservers();
+	}
 	/**
 	 * Notify all observers of the packet collection managers
 	 */

+ 20 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Connection.java

@@ -95,6 +95,7 @@ public interface Connection {
 	 *            Duration of the simulation interval in milliseconds
 	 * @return packets that were sent in this interval
 	 */
+	@Deprecated
 	public Collection<Packet> simulateTimeInterval(long startTime, long duration);
 
 	/**
@@ -107,6 +108,13 @@ public interface Connection {
 	 */
 	public Collection<Packet> getTerminationPackages(long startTime);
 
+	/**
+	 * Encapsulates the given Packets
+	 * @param packets Packets which should be encapsulated
+	 * @return Encapsulated Packets
+	 */
+	public Collection<Packet> encapsulatePackages(Collection<Packet> packets);
+	
 	/**
 	 * Returns the Protocol which is used on this Connection
 	 * 
@@ -194,4 +202,16 @@ public interface Connection {
 			return "unknown";
 		}
 	}
+	
+	/**
+	 * Returns the default label for packets of this connection represented as a short
+	 * @return default label value
+	 */
+	public short getLabel();
+	
+	/**
+	 * Set the default label value for packets of this connection
+	 * @param label new default label value
+	 */
+	public void setLabel(short label);
 }

+ 22 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/ConnectionPerformance.java

@@ -26,7 +26,8 @@ public class ConnectionPerformance implements Connection {
 	protected boolean changed = false;
 	/** Link on which this connection runs */
 	protected String name;
-	
+	/** default label */
+	protected short label = 0;
 	/**
 	 * Initializes the connection, adds participants of the protocol
 	 * 
@@ -105,8 +106,19 @@ public class ConnectionPerformance implements Connection {
 				returnPackets.addAll(protocol.generateNextPackets(p, (long) Math.max((p.getLastTrigger()+p.getTriggerInterval()+p.getJitter()*(Math.random())),p.getLastTrigger()+p.getTriggerInterval()),Math.random()<packetLossRate));
 		}
 		returnPackets.sort((a,b)->(Long.compare(a.getTimestamp(),b.getTimestamp())));
+		if(label!=0)
+			returnPackets.forEach(p->p.setLabel(label));
 		return returnPackets;
 	}
+	
+	@Override
+	public Collection<Packet> encapsulatePackages(Collection<Packet> packets) {
+		packets.forEach(p->{
+			p.setLabel((short) Math.max(Math.max(label, p.getLabel()), p.getSource().getOwner().getLabel()));
+		});
+		return packets;
+	}
+
 
 	@Override
 	public Collection<Packet> getTerminationPackages(long startTime) {
@@ -162,4 +174,13 @@ public class ConnectionPerformance implements Connection {
 		this.name = name;
 	}
 
+	@Override
+	public short getLabel() {
+		return label;
+	}
+
+	@Override
+	public void setLabel(short label) {
+		this.label = label;
+	}
 }

+ 3 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/ConnectionPrecision.java

@@ -120,6 +120,9 @@ public class ConnectionPrecision extends ConnectionPerformance {
 				break;
 			last = returnPackets.getLast();
 		}
+		if(label!=0)
+			returnPackets.forEach(p->p.setLabel(label));
+		
 		return returnPackets;
 	}
 	

+ 31 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Link.java

@@ -63,8 +63,33 @@ public interface Link {
 	 * @param duration
 	 *            Duration of the simulation interval in milliseconds
 	 */
+	@Deprecated
 	public void simulateTimeInterval(long startTime, long duration);
+	
+	/**
+	 * Initializes the simulation interval, by clearing the previously generated 
+	 * packets and adds Packets of previous iterations, which are are part of this interval.
+	 * @param startTime startTime of the simulation interval
+	 * @param duration duration of the simulation interval
+	 */
+	public void initSimulationInterval(long startTime, long duration);
+	
+	/**
+	 * Encapsulates the given Packets
+	 * @param packets Packets which should be encapsulated
+	 * @return Encapsulated Packets
+	 */
+	public Collection<Packet> encapsulatePackages(Collection<Packet> packets);
 
+	/**
+	 * Time at the end of an simulation interval, to remove Packets, which are not in bound, sort the array
+	 * or manipulate the packets slightly.
+	 * 
+	 * @param startTime startTime of the simulation interval
+	 * @param duration duration of the interval
+	 */
+	public void finalizeSimulationInterval(long startTime, long duration);
+	
 	/**
 	 * Returns all packets which where sent during the last Simulation time step
 	 * 
@@ -85,4 +110,10 @@ public interface Link {
 	 * @return delay of the transmission, infinite if to is unreachable or the Packets is lost.
 	 */
 	public long getTransmissionDelayFrom(SmartDevice from, SmartDevice to);
+
+	/**
+	 * Adds Packets to the internal data structure
+	 * @param packets Packets, which should be added
+	 */
+	public void addPackets(Collection<Packet> packets);
 }

+ 29 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Packet.java

@@ -21,6 +21,12 @@ public abstract class Packet {
 	 * DestinationPort of the packet
 	 */
 	protected Port destination;
+	
+	/**
+	 * Number representing the label of the package
+	 */
+	protected short label = 0;
+	
 	/**
 	 * Creates a new packet with the given timestamp
 	 * @param timestamp time the packet was sent
@@ -87,4 +93,27 @@ public abstract class Packet {
 	public Port getDestination(){
 		return destination;
 	}
+	
+	/**
+	 * Return name of the protocol, the packets is part of
+	 * 
+	 * @return Protocol name
+	 */
+	public abstract String getProtocolName();
+	
+	/**
+	 * Returns the label represented as a short
+	 * @return label value
+	 */
+	public short getLabel() {
+		return label;
+	}
+	
+	/**
+	 * Set the label value
+	 * @param label new label value
+	 */
+	public void setLabel(short label) {
+		this.label = label;
+	}
 }

+ 2 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/PacketCollectionManager.java

@@ -38,6 +38,7 @@ public class PacketCollectionManager extends Observable {
 		 */
 		for(PacketCollector col: collectors){
 			col.resetPackets();
+			if(!col.isActive())continue;
 			/**
 			 * Add all links, which packets should be collected
 			 */
@@ -74,7 +75,7 @@ public class PacketCollectionManager extends Observable {
 	 */
 	public void runPacketAlgorithms(){
 		for(PacketCollector collector:collectors){
-			if(collector.getPacketAlgorithm()!=null){
+			if(collector.isActive() && collector.getPacketAlgorithm()!=null){
 				collector.getPacketAlgorithm().processPackets(collector.getPackets());
 			}
 		}

+ 46 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/PacketCollector.java

@@ -37,6 +37,16 @@ public class PacketCollector {
 	 */
 	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
 	 */
@@ -180,4 +190,40 @@ public class PacketCollector {
 	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;
+	}
 }

+ 16 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/PacketSniffer.java

@@ -22,5 +22,21 @@ public interface PacketSniffer {
 	 *            grouped by each link.
 	 */
 	public void processPackets(HashMap<Link, LinkedList<Packet>> packets);
+	
+	/**
+	 * Set the mode of the algorithm, whether it should be training or testing 
+	 * with the given packets
+	 * @param testing <code>false</code> if it should be training, <code>true</code> if
+	 * it should be testing
+	 */
+	public void setMode(boolean testing);
+	
+	/**
+	 * Returns the mode of the algorithm, whether it should be training or testing 
+	 * with the given packets.<br>
+	 * <code>false</code>: if it should be training<br> 
+	 * <code>true</code>:  if it should be testing
+	 */
+	public boolean getMode();
 
 }

+ 93 - 18
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Port.java

@@ -1,14 +1,21 @@
 package de.tu_darmstadt.tk.SmartHomeNetworkSim.core;
 
+import java.util.Collection;
 import java.util.Random;
 
+import org.apache.commons.math3.distribution.AbstractRealDistribution;
+import org.apache.commons.math3.distribution.LaplaceDistribution;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler.ConstantValueDistributionHandler;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler.Schedulable;
+
 /**
  * Representation of connection EndPoints, which allows configuration of timings
  * and if it reacts to incoming traffic or even triggers new connections.
  * 
  * @author Andreas T. Meyer-Berg
  */
-public class Port {
+public class Port implements Schedulable {
 
 	/**
 	 * A closed Port which does not react to incoming traffic
@@ -40,12 +47,6 @@ public class Port {
 	 * Connection this Port listens to
 	 */
 	private Connection connection;
-	
-	/**
-	 * Constant time interval, which triggers new traffic every
-	 * {@code triggerInterval} milliseconds.
-	 */
-	private long triggerInterval;
 
 	/**
 	 * Last timestep traffic was triggered
@@ -62,11 +63,27 @@ public class Port {
 	 */
 	private short jitter;
 	
+	/**
+	 * Current Jitter, updated after every simulation
+	 */
+	private short currentJitter;
+	
 	/**
 	 * Port number of this Port.
 	 */
 	private short portNumber;
 
+	/**
+	 * Constant time interval, which triggers new traffic every
+	 * {@code triggerInterval} milliseconds.
+	 */
+	private long triggerInterval;
+
+	/**
+	 * Probability Distribution for calculating the next Trigger
+	 */
+	private ProbabilityDistributionHandler triggerIntervalStat;
+	
 	/**
 	 * Creates a new Port for the given Device with the specified PortNumber
 	 * @param device SmartDevice this port listens on
@@ -76,9 +93,12 @@ public class Port {
 		status = SENDING;
 		owner = device;
 		connection = null;
-		setTriggerInterval(new Random().nextInt(1000)+1);
+		triggerIntervalStat = new ConstantValueDistributionHandler(new Random().nextInt(1000)+1);
+		triggerInterval = Math.max(1, triggerIntervalStat.sampleNextValue());
+		//setTriggerInterval(new Random().nextInt(1000)+1);
 		lastTrigger = 0;
-		setTriggerInterval(new Random().nextInt(5)+1);
+		jitter = (short)(new Random().nextInt(5)+1);
+		currentJitter = (short)Math.round(Math.random()*jitter);
 		responseTime = 0;
 		this.portNumber = portNumber;
 	}
@@ -93,9 +113,11 @@ public class Port {
 		status = SENDING;
 		owner = device;
 		connection = null;
-		this.triggerInterval = triggerInterval;
+		triggerIntervalStat = new ConstantValueDistributionHandler(triggerInterval);
+		this.triggerInterval = Math.max(1, triggerIntervalStat.sampleNextValue());
 		lastTrigger = 0;
 		jitter = 0;
+		currentJitter = (short)Math.round(Math.random()*jitter);
 		responseTime = 0;
 		this.portNumber = portNumber;
 	}
@@ -113,9 +135,11 @@ public class Port {
 		status = SENDING;
 		owner = device;
 		connection = null;
-		this.triggerInterval = triggerInterval;
+		triggerIntervalStat = new ConstantValueDistributionHandler(triggerInterval);
+		this.triggerInterval = Math.max(1, triggerIntervalStat.sampleNextValue());
 		this.lastTrigger = lastTrigger;
 		this.jitter = jitter;
+		currentJitter = (short)Math.round(Math.random()*jitter);
 		this.responseTime = responseTime;
 		this.portNumber = portNumber;
 	}
@@ -152,6 +176,7 @@ public class Port {
 	}
 
 	/**
+	 * TriggerInterval is sampled from distribution after previous simulation
 	 * @return the triggerInterval
 	 */
 	public long getTriggerInterval() {
@@ -159,14 +184,33 @@ public class Port {
 	}
 
 	/**
-	 * @param triggerInterval
-	 *            the triggerInterval to set
+	 * Returns the Probability Handler for the trigger interval, which allows configuration of the Distribution
+	 * @return Distribution Handler for configuration
 	 */
-	public void setTriggerInterval(long triggerInterval) {
-		if(triggerInterval<=0)
-			this.triggerInterval = (long)1;
-		else
-		    this.triggerInterval = triggerInterval;
+	public ProbabilityDistributionHandler getTriggerHandler(){
+		return triggerIntervalStat;
+	}
+	
+	/**
+	 * Set a new Probability Distribution Handler to sample the trigger interval
+	 * @param triggerHandler Sets the Probability Distribution to generate the trigger interval
+	 */
+	public void setTriggerHandler(ProbabilityDistributionHandler triggerHandler){
+		this.triggerIntervalStat = triggerHandler;
+		boolean removed = SimulationManager.removeEvent(this);
+		this.triggerInterval = Math.max(1, triggerHandler.sampleNextValue());
+		if(removed)
+			SimulationManager.scheduleEvent(this);
+	}
+	
+	/**
+	 * Samples a new Value for the TriggerInterval
+	 */
+	public void resampleTriggerInterval(){
+		boolean removed = SimulationManager.removeEvent(this);
+		this.triggerInterval = Math.max(triggerIntervalStat.sampleNextValue(),1);
+		if(removed)
+			SimulationManager.scheduleEvent(this);
 	}
 
 	/**
@@ -286,4 +330,35 @@ public class Port {
 					return connection.getLink().getTransmissionDelayFrom(owner, to.getOwner());
 		return Long.MAX_VALUE;
 	}
+
+	@Override
+	public long getEventTime() {
+		return lastTrigger+triggerInterval+currentJitter;
+	}
+
+	@Override
+	public void simulateEvent(long time) {
+		if(connection==null || connection.getProtocol()==null || connection.getLink()==null || owner == null)
+			return;
+		
+		/**
+		 * Packets of the transfer initiated by this port
+		 */
+		Collection<Packet> packets = connection.getProtocol().generateNextPackets(this, time, false);
+		
+		//Packets encapsulated by Connection
+		packets = connection.encapsulatePackages(packets);
+		
+		//Encapsulate packets in Links
+		packets = connection.getLink().encapsulatePackages(packets);
+		
+		connection.getLink().addPackets(packets);
+		
+		//TODO: Sample next game
+		triggerInterval = Math.max(1,triggerIntervalStat.sampleNextValue());
+		
+		if(status==Port.SENDING && connection.getStatus()==Connection.ACTIVE)
+			SimulationManager.scheduleEvent(this);
+		
+	}
 }

+ 44 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/PrecisionLink.java

@@ -48,6 +48,9 @@ public class PrecisionLink implements Link {
 	 */
 	private boolean statusChanged;
 
+	/**
+	 * Delay between two devices, fixed
+	 */
 	private long fixedDelay=3;
 
 	/**
@@ -155,6 +158,11 @@ public class PrecisionLink implements Link {
 			last = packets.getLast();
 		}
 	}
+	
+	@Override
+	public Collection<Packet> encapsulatePackages(Collection<Packet> packets){
+		return packets;
+	}
 
 	@Override
 	public Collection<Packet> getPackets() {
@@ -201,4 +209,40 @@ public class PrecisionLink implements Link {
 	public long  getFixedDelay(){
 		return this.fixedDelay;
 	}
+
+	@Override
+	public void addPackets(Collection<Packet> packets) {
+		this.packets.addAll(packets);
+	}
+
+	@Override
+	public void initSimulationInterval(long startTime, long duration) {
+		/**
+		 * Reset packets
+		 */
+		packets.clear();
+		/**
+		 * Add out of Bounds packets
+		 */
+		packets.addAll(outOfBoundsPackets);
+	}
+
+	@Override
+	public void finalizeSimulationInterval(long startTime, long duration) {
+		//Remove out of Bounds Packets
+		/**
+		 * Remove packets which are not being sent in this time interval
+		 */
+		outOfBoundsPackets.clear();
+		/**
+		 * Last package, which should be sent in the next time step
+		 */
+		Packet last = packets.isEmpty()? null : packets.getLast();
+		while (last != null&&last.getTimestamp()>startTime+duration) {
+			outOfBoundsPackets.addFirst(packets.removeLast());
+			if(packets.isEmpty())
+				break;
+			last = packets.getLast();
+		}
+	}
 }

+ 39 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/ProbabilityDistributionHandler.java

@@ -0,0 +1,39 @@
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.core;
+
+import javax.swing.JPanel;
+
+import org.apache.commons.math3.random.RandomGenerator;
+
+/**
+ * Allows selection and configuration of such a class in view. Also Import & visualization of the example panel.
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public interface ProbabilityDistributionHandler {
+
+	/**
+	 * Set the random generator which should be used
+	 * @param rng random generator
+	 */
+	public void setRandomGenerator(RandomGenerator rng);
+
+	/**
+	 * Next value from the distribution
+	 * @return next sample value
+	 */
+	public long sampleNextValue();
+	
+	/**
+	 * Returns a configuration panel for the distribution.
+	 * Should be set enabled, visible and embedded by the calling methods.
+	 * @return panel for configuration
+	 */
+	public JPanel getConfigurationPanel();
+	
+	/**
+	 * Returns a simple description/name/identifier of the Distribution.
+	 * For example: "Gaussian Distribution"
+	 * @return simple description
+	 */
+	public String getSimpleDescription();
+}

+ 60 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/SimulationManager.java

@@ -6,6 +6,8 @@ import java.util.Observable;
 import javax.swing.Timer;
 
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.Controller;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler.Schedulable;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler.Scheduler;
 
 /**
  * Manages the Simulation by calling the relevant methods.
@@ -74,6 +76,11 @@ public class SimulationManager extends Observable {
 	 */
 	//private long perfStart = 0;
 	
+	/**
+	 * Scheduler which stores the event queue and enables scheduling and running of further events
+	 */
+	private static Scheduler scheduler;
+	
 	/**
 	 * Creates a new Simulationmanager
 	 * 
@@ -86,6 +93,7 @@ public class SimulationManager extends Observable {
 		this.collectionMan = new PacketCollectionManager(model);
 		this.exportMan = new PacketExportManager(model);
 		timer = new Timer(0, t -> simulateTimeStep());
+		scheduler = new Scheduler();
 	}
 
 	/**
@@ -118,8 +126,33 @@ public class SimulationManager extends Observable {
 	 *            Duration of the simulation interval in milliseconds
 	 */
 	public void simulateTimeIntervall(long startTime, long duration) {
+		scheduler.setMinTime(startTime);
+		//TODO: Fill Queue
+		//TODO: Simulate Schedule
+		//TODO: Export
+		
 		//Simulates the network
-		simulateNetwork(startTime, duration);
+		boolean oldWay = false;
+		if(oldWay)
+			simulateNetwork(startTime, duration);
+		else{
+			long maxTime = startTime + duration;
+			scheduler.scheduleAll(model);
+			for(Connection con:model.getConnections()){
+				Link l = con.getLink();
+				if(l!=null){
+					l.getPackets().clear();
+					l.addPackets(con.getTerminationPackages(startTime));
+				}
+			}
+			while(scheduler.hasNext(maxTime)){
+				Schedulable currentEvent = scheduler.getAndRemoveFirst();
+				//System.out.println("Event time: "+currentEvent.getEventTime());
+				currentEvent.simulateEvent(currentEvent.getEventTime());
+			}
+			// Simulate SmartDevices - if they need some logic -> TODO: Insert as schedulable
+			model.getDevices().forEach(d -> d.simulateTimeStep(startTime, duration));
+		}
 		runAlgorithms(startTime+duration);
 		collectionMan.collectPackets();
 		//Run all 
@@ -138,6 +171,7 @@ public class SimulationManager extends Observable {
 	 *            Duration of the simulation interval in milliseconds
 	 */
 	private void simulateNetwork(long startTime, long duration){
+		//TODO: Implement Event Schedule
 		// Nothing changed so far
 		statusChanged = false;
 		// Simulate all Links, and their connections
@@ -204,6 +238,12 @@ public class SimulationManager extends Observable {
 			for (Port p : d.getPorts())
 				if (p.getLastTrigger() > timestep)
 					p.setLastTrigger(timestep);
+		scheduler.reset(timestep);
+		/**
+		for(Connection c: model.getConnections())
+			for(Port p: c.getParticipants())
+				if (p.getLastTrigger() > timestep)
+					System.out.println("P without owner: "+p.toString());*/
 	}
 
 	/**
@@ -327,6 +367,7 @@ public class SimulationManager extends Observable {
 		this.controller = controller;
 		if(algo!=null)
 			algos.add(algo);
+		
 	}
 	
 	/**
@@ -352,4 +393,22 @@ public class SimulationManager extends Observable {
 	public PacketExportManager getPacketExportManager(){
 		return exportMan;
 	}
+	
+	/**
+	 * Adds an event to the event queue, which will be simulated later. Returns falls, if it could not be added (e.g. timestep to low)
+	 * @param event event which should be scheduled
+	 * @return true if it was scheduled, false if not
+	 */
+	public static boolean scheduleEvent(Schedulable event){
+		return scheduler.scheduleEvent(event);
+	}
+	
+	/**
+	 * Removes an event from the global event queue
+	 * @param event Event which should be removed
+	 * @return true, if it was removed, false if not
+	 */
+	public static boolean removeEvent(Schedulable event){
+		return scheduler.removeEvent(event);
+	}
 }

+ 21 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/SmartDevice.java

@@ -10,7 +10,12 @@ import java.util.List;
  * @author Andreas T. Meyer-Berg
  */
 public class SmartDevice {
-
+	
+	/**
+	 * Label
+	 */
+	protected short label = 0;
+	
 	/**
 	 * Name of the Device
 	 */
@@ -204,5 +209,20 @@ public class SmartDevice {
 	public void removePort(Port port) {
 		this.ports.remove(port);
 	}
+	
+	/**
+	 * @return label
+	 */
+	public short getLabel() {
+		return label;
+	}
+	
+	/**
+	 * Sets the label
+	 * @param label label to set
+	 */
+	public void setLabel(Short label) {
+		this.label = label;
+	}
 
 }

+ 39 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/configuration/ImportConfiguration.java

@@ -2,17 +2,23 @@ package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.configuration;
 
 import java.util.LinkedList;
 
+import org.apache.commons.math3.distribution.PoissonDistribution;
+
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Connection;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ConnectionPerformance;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ConnectionPrecision;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PrecisionLink;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ProbabilityDistributionHandler;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.BoolCollectorDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.BoolSensorDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.FloatCollectorDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.FloatSensorDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler.ConstantValueDistributionHandler;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler.NormalDistributionHandler;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler.PoissonDistributionHandler;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.MQTT_protocol;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.Ping_protocol;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.simpleImplementation.SimpleLink;
@@ -42,6 +48,8 @@ public class ImportConfiguration {
 	private LinkedList<Class<? extends SmartDevice>> standardSmartDevices = new LinkedList<Class<? extends SmartDevice>>();
 	private LinkedList<Class<? extends SmartDevice>> importedSmartDevices = new LinkedList<Class<? extends SmartDevice>>();
 	
+	private LinkedList<Class<? extends ProbabilityDistributionHandler>> standardDistributions = new LinkedList<Class<? extends ProbabilityDistributionHandler>>();
+	private LinkedList<Class<? extends ProbabilityDistributionHandler>> importedDistribution = new LinkedList<Class<? extends ProbabilityDistributionHandler>>();
 	/**
 	 * Initializes the configuration and adds the standard classes
 	 */
@@ -63,6 +71,10 @@ public class ImportConfiguration {
 		
 		standardConnections.add(ConnectionPerformance.class);
 		standardConnections.add(ConnectionPrecision.class);
+		
+		standardDistributions.add(ConstantValueDistributionHandler.class);
+		standardDistributions.add(NormalDistributionHandler.class);
+		standardDistributions.add(PoissonDistributionHandler.class);
 	}
 	
 	
@@ -174,4 +186,31 @@ public class ImportConfiguration {
 		importedSmartDevices.remove(remove);
 	}
 
+	
+	/**
+	 * Returns DistributionHandler Classes of the Model
+	 * @return available DistributionHandler Classes
+	 */
+	public LinkedList<Class<? extends ProbabilityDistributionHandler>> getDistributionHandlerClasses(){
+		LinkedList<Class<? extends ProbabilityDistributionHandler>> export = new LinkedList<Class<? extends ProbabilityDistributionHandler>>();
+		export.addAll(standardDistributions);
+		export.addAll(importedDistribution);
+		return export;
+	}
+	
+	/**
+	 * Adds new DistributionHandler Class to the available DistributionHandler classes
+	 * @param newDistributionHandler new DistributionHandler Class to be added
+	 */
+	public void addDistributionHandlerClass(Class<? extends ProbabilityDistributionHandler> newDistributionHandler){
+		importedDistribution.add(newDistributionHandler);
+	}
+	
+	/**
+	 * Removes DistributionHandler Class from the available DistributionHandler Classes
+	 * @param remove DistributionHandler Class to be removed
+	 */
+	public void removeDistributionHandlerClass(Class<? extends ProbabilityDistributionHandler> remove){
+		importedDistribution.remove(remove);
+	}
 }

+ 25 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/devices/FloatSensorDevice.java

@@ -2,7 +2,9 @@ package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices;
 
 import java.util.Random;
 
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SimulationManager;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler.Schedulable;
 
 
 /**
@@ -10,7 +12,7 @@ import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
  *
  * @author Andreas T. Meyer-Berg
  */
-public class FloatSensorDevice extends SmartDevice implements FloatSensor {
+public class FloatSensorDevice extends SmartDevice implements FloatSensor, Schedulable {
 
 	/**
 	 * Minimum value
@@ -29,6 +31,11 @@ public class FloatSensorDevice extends SmartDevice implements FloatSensor {
 	 */
 	private float oldVal;
 	
+	/**
+	 * Timestep it will be udpated again
+	 */
+	long nextSimulationTime = 0;
+	
 	/**
 	 * Name of the sensor reading
 	 */
@@ -56,6 +63,7 @@ public class FloatSensorDevice extends SmartDevice implements FloatSensor {
 		val = 22;
 		oldVal = 22;
 		infoName = "temperature";
+		SimulationManager.scheduleEvent(this);
 	}
 	
 	@Override
@@ -101,6 +109,22 @@ public class FloatSensorDevice extends SmartDevice implements FloatSensor {
 	
 	@Override
 	public void simulateTimeStep(long startTime, long duration) {
+		
+	}
+	
+	@Override
+	public long getEventTime() {
+		return nextSimulationTime;
+	}
+	@Override
+	public void simulateEvent(long time) {
+		updateData();
+		//Update again in 10 seconds
+		nextSimulationTime=time *10000;
+		SimulationManager.scheduleEvent(this);
+	}
+	
+	private void updateData() {
 		float newVal = val + (val-oldVal)+new Random().nextFloat()/2.0f-0.25f;
 		newVal = Math.max(Math.min(newVal, max),min);
 		this.oldVal = val;

+ 113 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/distributionHandler/ConstantValueDistributionHandler.java

@@ -0,0 +1,113 @@
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler;
+
+import java.awt.Color;
+import java.awt.Dimension;
+
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import org.apache.commons.math3.random.RandomGenerator;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ProbabilityDistributionHandler;
+
+/**
+ * Example class representing a Distribution, with only one constant value
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public class ConstantValueDistributionHandler implements
+		ProbabilityDistributionHandler {
+
+	/**
+	 * Fixed value this distribution returns
+	 */
+	private long fixedValue;
+	
+	/**
+	 * Creates a new distribution which returns the given value
+	 * @param value value to be returned
+	 */
+	public ConstantValueDistributionHandler(long value) {
+		fixedValue = value;
+	}
+
+	/**
+	 * Creates a default distribution, which returns 50.
+	 */
+	public ConstantValueDistributionHandler() {
+		fixedValue = 50;
+	}
+	
+	@Override
+	public void setRandomGenerator(RandomGenerator rng) {
+		// Fixed Value requires no randomness
+	}
+
+	@Override
+	public long sampleNextValue() {
+		return fixedValue;
+	}
+
+	/**
+	 * Sets the sample value to the given one
+	 * @param value new fixed value
+	 */
+	public void setValue(long value){
+		this.fixedValue = value;
+	}
+	@Override
+	public JPanel getConfigurationPanel() {
+		/**
+		 * JPanel which allows configuration of this Distribution
+		 */
+		JPanel panel = new JPanel();
+		panel.setMinimumSize(new Dimension(90, 40));
+		panel.setLayout(null);
+		
+		/**
+		 * Label 
+		 */
+		JLabel label = new JLabel("Value: ");
+		panel.add(label);
+		label.setLocation(20, 20);
+		label.setSize(50,20);
+		label.setMinimumSize(new Dimension(50, 20));
+
+		/**
+		 * Textfield for changing the value
+		 */
+		JTextField valueConfig = new JTextField(""+fixedValue);
+		panel.add(valueConfig);
+		valueConfig.setLocation(80, 20);
+		valueConfig.setMinimumSize(new Dimension(32, 20));
+		valueConfig.setSize(32, 20);
+		valueConfig.addActionListener(a->{
+			try {
+				/**
+				 * Update the value
+				 */
+				fixedValue = Long.parseLong(valueConfig.getText());
+				valueConfig.setBackground(Color.WHITE);
+			} catch (Exception e) {
+				valueConfig.setBackground(Color.RED);
+			}
+		});
+		return panel;
+	}
+
+	public static void main(String[] args) {
+		ConstantValueDistributionHandler c = new ConstantValueDistributionHandler(12);
+		JFrame test = new JFrame("test");
+		test.setSize(400, 400);
+		test.add(c.getConfigurationPanel());
+		test.setEnabled(true);
+		test.setVisible(true);
+	}
+
+	@Override
+	public String getSimpleDescription() {
+		return "Constant Value";
+	}
+}

+ 167 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/distributionHandler/NormalDistributionHandler.java

@@ -0,0 +1,167 @@
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler;
+
+import java.awt.Color;
+import java.awt.Dimension;
+
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import org.apache.commons.math3.distribution.NormalDistribution;
+import org.apache.commons.math3.random.RandomGenerator;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ProbabilityDistributionHandler;
+
+/**
+ * Example class representing a Normal Distribution
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public class NormalDistributionHandler implements
+		ProbabilityDistributionHandler {
+
+	/**
+	 * Mean value
+	 */
+	private double mean;
+	
+	/**
+	 * Standard Deviation
+	 */
+	private double sd;
+	
+	/**
+	 * Normal Distribution
+	 */
+	private NormalDistribution dist;
+	
+	/**
+	 * 
+	 */
+	private RandomGenerator gen = null;
+	
+	/**
+	 * Creates a new distribution which returns the given value
+	 * @param value value to be returned
+	 */
+	public NormalDistributionHandler(double mean, double sd) {
+		this.mean = mean;
+		this.sd = sd;
+		dist = new NormalDistribution(mean, sd);
+	}
+
+	/**
+	 * Creates a default distribution, which returns 50.
+	 */
+	public NormalDistributionHandler() {
+		this.mean = 50.0;
+		this.sd = 12.0;
+		dist = new NormalDistribution(mean, sd);
+	}
+	
+	@Override
+	public void setRandomGenerator(RandomGenerator rng) {
+		gen = rng;
+		dist = new NormalDistribution(rng, mean, sd);
+	}
+
+	@Override
+	public long sampleNextValue() {
+		return (long)Math.round(dist.sample());
+	}
+
+	@Override
+	public JPanel getConfigurationPanel() {
+		/**
+		 * JPanel which allows configuration of this Distribution
+		 */
+		JPanel panel = new JPanel();
+		panel.setMinimumSize(new Dimension(90, 80));
+		panel.setLayout(null);
+		
+		/**
+		 * Label 
+		 */
+		JLabel label = new JLabel("Mean: ");
+		panel.add(label);
+		label.setLocation(20, 20);
+		label.setSize(50,20);
+		label.setMinimumSize(new Dimension(50, 20));
+
+		/**
+		 * Textfield for changing the value
+		 */
+		JTextField valueConfig = new JTextField(""+mean);
+		panel.add(valueConfig);
+		valueConfig.setLocation(80, 20);
+		valueConfig.setMinimumSize(new Dimension(70, 20));
+		valueConfig.setSize(70, 20);
+		valueConfig.addActionListener(a->{
+			try {
+				/**
+				 * Update the value
+				 */
+				mean = Double.parseDouble(valueConfig.getText());
+				initializeDistribution();
+				valueConfig.setBackground(Color.WHITE);
+			} catch (Exception e) {
+				valueConfig.setBackground(Color.RED);
+			}
+		});
+		
+		
+		
+		/**
+		 * Label 
+		 */
+		JLabel lbSD = new JLabel("SD: ");
+		panel.add(lbSD);
+		lbSD.setLocation(20, 50);
+		lbSD.setSize(50,20);
+		lbSD.setMinimumSize(new Dimension(50, 20));
+
+		/**
+		 * Textfield for changing the value
+		 */
+		JTextField tfSDvalue = new JTextField(""+sd);
+		panel.add(tfSDvalue);
+		tfSDvalue.setLocation(80, 50);
+		tfSDvalue.setMinimumSize(new Dimension(70, 20));
+		tfSDvalue.setSize(70, 20);
+		tfSDvalue.addActionListener(a->{
+			try {
+				/**
+				 * Update the value
+				 */
+				sd = Double.parseDouble(tfSDvalue.getText());
+				tfSDvalue.setBackground(Color.WHITE);
+			} catch (Exception e) {
+				tfSDvalue.setBackground(Color.RED);
+			}
+		});
+		return panel;
+	}
+
+	private void initializeDistribution() {
+		if(gen==null)
+			dist = new NormalDistribution(mean, sd);
+		else
+			dist = new NormalDistribution(gen, mean, sd);
+			
+	}
+
+	public static void main(String[] args) {
+		NormalDistributionHandler c = new NormalDistributionHandler(12.0, 5.0);
+		JFrame test = new JFrame("test");
+		test.setSize(400, 400);
+		test.add(c.getConfigurationPanel());
+		test.setEnabled(true);
+		test.setVisible(true);
+	}
+
+	@Override
+	public String getSimpleDescription() {
+		return "Normal Distribution";
+	}
+}

+ 168 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/distributionHandler/PoissonDistributionHandler.java

@@ -0,0 +1,168 @@
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler;
+
+import java.awt.Color;
+import java.awt.Dimension;
+
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import org.apache.commons.math3.distribution.NormalDistribution;
+import org.apache.commons.math3.distribution.PoissonDistribution;
+import org.apache.commons.math3.random.RandomGenerator;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ProbabilityDistributionHandler;
+
+/**
+ * Example class representing a Normal Distribution
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public class PoissonDistributionHandler implements
+		ProbabilityDistributionHandler {
+
+	/**
+	 * Poisson Mean value
+	 */
+	private double p;
+	
+	/**
+	 * Standard Deviation
+	 */
+	private double epsilon;
+	
+	/**
+	 * Normal Distribution
+	 */
+	private PoissonDistribution dist;
+	
+	/**
+	 * 
+	 */
+	private RandomGenerator gen = null;
+	
+	/**
+	 * Creates a new distribution which returns the given value
+	 * @param value value to be returned
+	 */
+	public PoissonDistributionHandler(double p, double epsilon) {
+		this.p = p;
+		this.epsilon = epsilon;
+		dist = new PoissonDistribution(p, epsilon);
+	}
+
+	/**
+	 * Creates a default distribution, which returns 50.
+	 */
+	public PoissonDistributionHandler() {
+		this.p = 50.0;
+		this.epsilon = 12.0;
+		dist = new PoissonDistribution(p, epsilon);
+	}
+	
+	@Override
+	public void setRandomGenerator(RandomGenerator rng) {
+		gen = rng;
+		dist = new PoissonDistribution(rng, p, epsilon, 100);
+	}
+
+	@Override
+	public long sampleNextValue() {
+		return (long)Math.round(dist.sample());
+	}
+
+	@Override
+	public JPanel getConfigurationPanel() {
+		/**
+		 * JPanel which allows configuration of this Distribution
+		 */
+		JPanel panel = new JPanel();
+		panel.setMinimumSize(new Dimension(90, 80));
+		panel.setLayout(null);
+		
+		/**
+		 * Label 
+		 */
+		JLabel label = new JLabel("p(Mean): ");
+		panel.add(label);
+		label.setLocation(20, 20);
+		label.setSize(100,20);
+		label.setMinimumSize(new Dimension(50, 20));
+
+		/**
+		 * Textfield for changing the value
+		 */
+		JTextField valueConfig = new JTextField(""+p);
+		panel.add(valueConfig);
+		valueConfig.setLocation(130, 20);
+		valueConfig.setMinimumSize(new Dimension(70, 20));
+		valueConfig.setSize(70, 20);
+		valueConfig.addActionListener(a->{
+			try {
+				/**
+				 * Update the value
+				 */
+				p = Double.parseDouble(valueConfig.getText());
+				initializeDistribution();
+				valueConfig.setBackground(Color.WHITE);
+			} catch (Exception e) {
+				valueConfig.setBackground(Color.RED);
+			}
+		});
+		
+		
+		
+		/**
+		 * Label 
+		 */
+		JLabel lbSD = new JLabel("epsilon: ");
+		panel.add(lbSD);
+		lbSD.setLocation(20, 50);
+		lbSD.setSize(100,20);
+		lbSD.setMinimumSize(new Dimension(50, 20));
+
+		/**
+		 * Textfield for changing the value
+		 */
+		JTextField tfSDvalue = new JTextField(""+epsilon);
+		panel.add(tfSDvalue);
+		tfSDvalue.setLocation(130, 50);
+		tfSDvalue.setMinimumSize(new Dimension(70, 20));
+		tfSDvalue.setSize(70, 20);
+		tfSDvalue.addActionListener(a->{
+			try {
+				/**
+				 * Update the value
+				 */
+				epsilon = Double.parseDouble(tfSDvalue.getText());
+				tfSDvalue.setBackground(Color.WHITE);
+			} catch (Exception e) {
+				tfSDvalue.setBackground(Color.RED);
+			}
+		});
+		return panel;
+	}
+
+	private void initializeDistribution() {
+		if(gen==null)
+			dist = new PoissonDistribution(p, epsilon);
+		else
+			dist = new PoissonDistribution(gen, p, epsilon, 100);
+			
+	}
+
+	public static void main(String[] args) {
+		PoissonDistributionHandler c = new PoissonDistributionHandler(12.0, 5.0);
+		JFrame test = new JFrame("test");
+		test.setSize(400, 400);
+		test.add(c.getConfigurationPanel());
+		test.setEnabled(true);
+		test.setVisible(true);
+	}
+
+	@Override
+	public String getSimpleDescription() {
+		return "Normal Distribution";
+	}
+}

+ 6 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/distributionHandler/package-info.java

@@ -0,0 +1,6 @@
+/**
+ * Packet for the different Distribution Handler, which allow configuration and storage of different Distributions Functions for Ports. 
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler;

+ 73 - 11
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/MQTT_protocol.java

@@ -7,15 +7,20 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Random;
 
+import org.hamcrest.core.IsAnything;
+
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SimulationManager;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.BoolCollector;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.BoolSensor;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.FloatCollector;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.FloatSensor;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.packets.MQTT_packet;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.packets.MQTTpublishPacket;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler.AbstractEvent;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.util.Pair;
 
 /**
@@ -165,7 +170,7 @@ public class MQTT_protocol implements Protocol {
 			 * Topic which should be subscribed to
 			 */
 			String newTopic = null;
-
+			
 			/**
 			 * Check if FloatCollector & not subscribed
 			 */
@@ -257,7 +262,11 @@ public class MQTT_protocol implements Protocol {
 			 * Value which should be published
 			 */
 			String newValue = null;
-
+			boolean isBoolean = false;
+			/**
+			 * True if value anomaly (value = -1)
+			 */
+			boolean valueAnomaly = (device.getLabel()==(short)-1);
 			/**
 			 * Check if FloatSensor
 			 */
@@ -276,18 +285,27 @@ public class MQTT_protocol implements Protocol {
 				if (newTopic == null || new Random().nextBoolean()) {
 					newTopic = bSensor.getBSinfoName();
 					newValue = "" + bSensor.getBSval();
+					isBoolean = true;
 				}
 			}
 
 			if (newTopic != null) {
 				/**
-				 * Message to be published
+				 * Packet for publishing the new value
 				 */
-				String msg = "Topic:" + newTopic + ":" + newValue;
+				Packet  pubPacket = null;
+				if(isBoolean) {
+					pubPacket = new MQTTpublishPacket(timestep, port, broker, newTopic, Boolean.parseBoolean(newValue));
+				}else {
+					pubPacket = new MQTTpublishPacket(timestep, port, broker, newTopic, Float.parseFloat(newValue));
+				}
+				if(valueAnomaly) {
+					pubPacket.setLabel((short) 1);
+				}
 				/**
 				 * Send Packet
 				 */
-				returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, port, broker, msg));
+				returnPackets.add(pubPacket);
 
 				/**
 				 * Delay to the broker
@@ -313,18 +331,54 @@ public class MQTT_protocol implements Protocol {
 						 */
 						long delayBrokerToSub = broker.getTransmissionDelayTo(p);
 						timestep += broker.getResponseTime();
-
-						returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, broker, p, msg));
+						/**
+						 * Packet Broker -> Subscriber
+						 */
+						if(isBoolean) {
+							pubPacket = new MQTTpublishPacket(timestep, broker, p, newTopic, Boolean.parseBoolean(newValue));
+						}else {
+							pubPacket = new MQTTpublishPacket(timestep, broker, p, newTopic, Float.parseFloat(newValue));
+						}
+						if(valueAnomaly) {
+							pubPacket.setLabel((short) 1);
+						}
+						returnPackets.add(pubPacket);
 						if (p.getStatus() != Port.CLOSED && delayBrokerToSub != Long.MAX_VALUE) {
 							returnPackets.add(
 									new MQTT_packet(MQTT_packet.PUBACK, timestep + p.getResponseTime(), p, broker));
 							// Update Collector
 							if (device instanceof FloatSensor && p.getOwner() instanceof FloatCollector
 									&& newTopic.equals(((FloatSensor) device).getFSinfoName())) {
-								((FloatCollector) p.getOwner()).setFCval(((FloatSensor) device).getFSval());
+								/**
+								 * original Float Value -> if it might change during the two events
+								 */
+								float oldValue = ((FloatSensor) device).getFSval();
+								/**
+								 * Schedule Event to update the sensor 
+								 * -> therefore multiple parallel interactions would be in the right order
+								 */
+								SimulationManager.scheduleEvent(new AbstractEvent(timestep + p.getResponseTime()) {	
+									@Override
+									public void simulateEvent(long time) {
+										((FloatCollector) p.getOwner()).setFCval(oldValue);
+									}
+								});
 							} else if (device instanceof BoolSensor && p.getOwner() instanceof BoolCollector
 									&& newTopic.equals(((BoolSensor) device).getBSinfoName())) {
-								((BoolCollector) p.getOwner()).setBCval(((BoolSensor) device).getBSval());
+								/**
+								 * Original sensor value
+								 */
+								boolean oldValue = ((BoolSensor) device).getBSval();
+								/**
+								 * Schedule Event to update the sensor 
+								 * -> therefore multiple parallel interactions would be in the right order
+								 */
+								SimulationManager.scheduleEvent(new AbstractEvent(timestep + p.getResponseTime()) {	
+									@Override
+									public void simulateEvent(long time) {
+										((BoolCollector) p.getOwner()).setBCval(oldValue);
+									}
+								});
 							}
 						}
 					}
@@ -340,8 +394,16 @@ public class MQTT_protocol implements Protocol {
 						 */
 						long delayBrokerToSub = broker.getTransmissionDelayTo(p);
 						timestep += broker.getResponseTime();
-
-						returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, broker, p, msg));
+						
+						if(isBoolean) {
+							pubPacket = new MQTTpublishPacket(timestep, broker, p, newTopic, Boolean.parseBoolean(newValue));
+						}else {
+							pubPacket = new MQTTpublishPacket(timestep, broker, p, newTopic, Float.parseFloat(newValue));
+						}
+						if(valueAnomaly) {
+							pubPacket.setLabel((short) 1);
+						}
+						returnPackets.add(pubPacket);
 						if (p.getStatus() != Port.CLOSED && delayBrokerToSub != Long.MAX_VALUE) {
 							returnPackets.add(
 									new MQTT_packet(MQTT_packet.PUBACK, timestep + p.getResponseTime(), p, broker));

+ 6 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/packets/MQTT_packet.java

@@ -195,11 +195,16 @@ public class MQTT_packet extends Packet {
 			packetType="RESERVED";
 			break;
 		}
-		return "[MQTT: "+packetType+"; time:"+timestamp+"; source:"+source.getOwner().getName()+"; destination:"+destination.getOwner().getName()+(message==""?"":"; "+message)+"]";
+		return "[MQTT: "+packetType+"; time:"+timestamp+"; source:"+source.getOwner().getName()+":"+source.getPortNumber()+"; destination:"+destination.getOwner().getName()+":"+destination.getPortNumber()+(message==""?"":"; "+message)+"]";
 	}
 
 	@Override
 	public String getPayload() {
 		return "null";
 	}
+
+	@Override
+	public String getProtocolName() {
+		return "MQTT";
+	}
 }

+ 81 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/packets/MQTTpublishPacket.java

@@ -0,0 +1,81 @@
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.packets;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port;
+
+/**
+ * MQTT Publish Packet
+ * 
+ * 
+ * @author Andreas T. Meyer-Berg
+ */
+public class MQTTpublishPacket extends MQTT_packet {
+	/**
+	 * Topic of the Publish Packet
+	 */
+	private String topic = "";
+	/**
+	 * Value of the packet
+	 */
+	private float value = 0;
+	/**
+	 * True if boolean
+	 */
+	private boolean isBoolean = false;
+	
+	/**
+	 * MQTT Publish Packet
+	 * @param timestamp time it is send
+	 * @param source source port
+	 * @param destination destination port
+	 * @param topic topic of the message
+	 * @param value value of the message
+	 */
+	public MQTTpublishPacket(long timestamp, Port source, Port destination, String topic, float value) {
+		super(MQTT_packet.PUBLISH, timestamp, source, destination);
+		this.setTopic(topic);
+		this.setValue(value);
+		setBoolean(false);
+		this.message = topic + ":"+ value;
+	}
+	
+	/**
+	 * MQTT Publish Packet
+	 * @param timestamp time it is send
+	 * @param source source port
+	 * @param destination destination port
+	 * @param topic topic of the message
+	 * @param value value of the message
+	 */
+	public MQTTpublishPacket(long timestamp, Port source, Port destination, String topic, boolean value) {
+		super(MQTT_packet.PUBLISH, timestamp, source, destination);
+		this.setTopic(topic);
+		this.setValue(value ? 1 : 0);
+		setBoolean(true);
+		this.message = "Topic:"+topic + ":"+ value;
+	}
+
+	public boolean isBoolean() {
+		return isBoolean;
+	}
+
+	public void setBoolean(boolean isBoolean) {
+		this.isBoolean = isBoolean;
+	}
+
+	public float getValue() {
+		return value;
+	}
+
+	public void setValue(float value) {
+		this.value = value;
+	}
+
+	public String getTopic() {
+		return topic;
+	}
+
+	public void setTopic(String topic) {
+		this.topic = topic;
+	}
+
+}

+ 6 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/packets/Ping_packet.java

@@ -138,7 +138,7 @@ public class Ping_packet extends Packet {
 
 	@Override
 	public String getTextualRepresentation() {
-		return "[Ping: "+getType()+"; time:"+timestamp+"; source:"+source.getOwner().getName()+"; destination:"+destination.getOwner().getName()+"; Payload: "+getPayload()+"]";
+		return "[Ping: "+getType()+"; time:"+timestamp+"; source:"+source.getOwner().getName()+":"+source.getPortNumber()+"; destination:"+destination.getOwner().getName()+":"+destination.getPortNumber()+"; Payload: "+getPayload()+"]";
 	}
 
 	@Override
@@ -169,4 +169,9 @@ public class Ping_packet extends Packet {
 		for(int i = 0; i<bytes.length; i++)
 			System.out.println(bytes[i]);
 	}
+
+	@Override
+	public String getProtocolName() {
+		return "ICMPv6 Ping";
+	}
 }

+ 31 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/scheduler/AbstractEvent.java

@@ -0,0 +1,31 @@
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler;
+
+/**
+ * Abstract Event can be used to schedule changes to the model. For example, updates of devices.
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public abstract class AbstractEvent implements Schedulable {
+
+	/**
+	 * Timestep the event takes place
+	 */
+	private long timestep;
+	
+	/**
+	 * Creates an Event at the given timestep, which can be scheduled.
+	 * @param timestep timestep, the event should be scheduled
+	 */
+	public AbstractEvent(long timestep){
+		this.timestep = timestep;
+	}
+	
+	@Override
+	public long getEventTime(){
+		return timestep;
+	}
+
+	@Override
+	public abstract void simulateEvent(long time);
+
+}

+ 21 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/scheduler/Schedulable.java

@@ -0,0 +1,21 @@
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler;
+
+/**
+ * Interface for events or objects, which can be scheduled during simulation of the network or world model.
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public interface Schedulable {
+	
+	/**
+	 * Returns the timestep, in which the event begins
+	 * @return timestep, in which the event begins
+	 */
+	public long getEventTime();
+	
+	/**
+	 * Simulates the given Event, might update states of model parts and schedule further events.
+	 * @param time minimum timestamp
+	 */
+	public void simulateEvent(long time);
+}

+ 23 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/scheduler/ScheduleComparator.java

@@ -0,0 +1,23 @@
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler;
+
+import java.util.Comparator;
+
+/**
+ * Comparator used for scheduling different events in the global event queue
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public class ScheduleComparator implements Comparator<Schedulable> {
+
+	
+	@Override
+	public int compare(Schedulable o1, Schedulable o2) {
+		int res = Long.compare(o1.getEventTime(), o2.getEventTime());
+		if(res==0)
+			//Advanced handling ? TODO: Maybe microtime ? Some random alternation or event priority
+			return Integer.compare(o1.hashCode(), o2.hashCode());
+
+		return res;
+	}
+
+}

+ 125 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/scheduler/Scheduler.java

@@ -0,0 +1,125 @@
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler;
+
+import java.util.TreeSet;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Connection;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Model;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port;
+
+/**
+ * The Scheduler manages the EventQueue of the framework and allows manipulating the queue.
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public class Scheduler {
+
+	/**
+	 * Event Queue, which stores the different events
+	 */
+	private TreeSet<Schedulable> eventQueue;
+	
+	/**
+	 * Minimum time step. No earlier events can be scheduled
+	 */
+	private long minimumTimeStep = Long.MIN_VALUE;
+	
+	/**
+	 * Initializes a new Scheduler with an empty event queue.
+	 */
+	public Scheduler() {
+		eventQueue  = new TreeSet<Schedulable>(new ScheduleComparator());
+	}
+	
+	
+	/**
+	 * Schedules the given {@link Schedulable}, by adding it to the event queue. 
+	 * @param event Event which should be scheduled
+	 * @return true if it was scheduled, false if otherwise
+	 */
+	public boolean scheduleEvent(Schedulable event){
+		if(event.getEventTime()<minimumTimeStep){
+			
+			System.out.println("Min: "+minimumTimeStep+"  Event: "+event.getEventTime());
+			System.out.println("Could not schedule: "+event.toString());
+			System.out.println("Simulate now ");
+			event.simulateEvent(minimumTimeStep);//TODO: Maybe other solution
+			//throw new Error("Fail");
+			
+			return false;
+		}else {
+			return eventQueue.add(event);
+		}
+	}
+	
+	/**
+	 * Schedules all network events of the given model
+	 * @param m Model which should be scheduled
+	 */
+	public void scheduleAll(Model m){
+		for(Connection c: m.getConnections())
+			for(Port p:c.getParticipants()){
+				if(p != null && p.getStatus() == Port.SENDING)
+				scheduleEvent(p);				
+			}
+	}
+	
+	/**
+	 * Return true, if the EventQueue contains another event before the given maximum time
+	 * @param maxTime exclusive maximum time events should have in this simulation interval
+	 * @return true, if 
+	 */
+	public boolean hasNext(long maxTime){
+		if(eventQueue.isEmpty()) 
+			return false;
+		return eventQueue.first().getEventTime()<maxTime;
+	}
+	
+	/**
+	 * Returns the next Event, which will be simulated
+	 * @return next event
+	 */
+	public Schedulable getNextEvent(){
+		return eventQueue.first();
+	}
+	
+	/**
+	 * Returns the first Element of the queue and removes it.
+	 * @return
+	 */
+	public Schedulable getAndRemoveFirst(){
+		return eventQueue.pollFirst();
+	}
+	
+	/**
+	 * Removes the event from the Event Queue, it will not be simulated
+	 * @param event Event to be removed
+	 * @return true if it was removed
+	 */
+	public boolean removeEvent(Schedulable event){
+		return eventQueue.remove(event);
+	}
+	
+	/**
+	 * Resets the EventQueue by removing all events and resetting the minimum timestep
+	 */
+	public void reset(long newMinTime){
+		minimumTimeStep = newMinTime;
+		eventQueue.clear();
+	}
+	
+	/**
+	 * Returns the minimum Time, events could be scheduled.
+	 * @return minimum time step
+	 */
+	public long getMinTime(){
+		return minimumTimeStep;
+	}
+	
+	/**
+	 * Sets the new minimum time. No events will be scheduled earlier.
+	 * @param newMinTime new minimum time
+	 */
+	public void setMinTime(long newMinTime){
+		this.minimumTimeStep = newMinTime;
+	}
+}

+ 6 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/scheduler/package-info.java

@@ -0,0 +1,6 @@
+/**
+ * Packet for the different classes and interfaces required for event scheduling 
+ * during the simulation of the network and world model. 
+ * @author Andreas T. Meyer-Berg
+ */
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler;

+ 15 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/CountingMetric.java

@@ -22,6 +22,11 @@ import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.simpleImplementation.SimplePa
  */
 public class CountingMetric implements PacketSniffer {
 
+	/**
+	 * Mode of the algorithm, True = testing
+	 */
+	private boolean mode = false;
+	
 	@Override
 	public void processPackets(HashMap<Link, LinkedList<Packet>> packets) {
 		System.out.println("Counting Metric: ");
@@ -135,4 +140,14 @@ public class CountingMetric implements PacketSniffer {
 		
 		
 	}
+	
+	@Override
+	public void setMode(boolean testing) {
+		mode = testing;
+	}
+	
+	@Override
+	public boolean getMode() {
+		return mode;
+	}
 }

+ 1 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/Manipulation_RandomMove.java

@@ -25,6 +25,7 @@ public class Manipulation_RandomMove implements NetworkManipulationAlgorithm {
 		 * Visible devices of the model, to select one which should be moved
 		 */
 		Collection<SmartDevice> devices = controller.getNetworkController().getVisibleSmartDevices();
+		if(devices.isEmpty())return;
 		/**
 		 * Iterator for the devices
 		 */

+ 20 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/SimpleConnection.java

@@ -60,6 +60,10 @@ public class SimpleConnection implements Connection {
 	 */
 	private double packetLossProbability = 0.0;
 
+	/**
+	 * Default label assigned to packets
+	 */
+	protected short label = 0;
 	
 	/**
 	 * Creates a new connection between two SmartDevice Ports on a given Link, which
@@ -118,6 +122,11 @@ public class SimpleConnection implements Connection {
 		return list;
 	}
 
+	@Override
+	public Collection<Packet> encapsulatePackages(Collection<Packet> packets) {
+		return packets;
+	}
+
 	@Override
 	public Collection<Port> getParticipants() {
 		return new LinkedList<Port>(Arrays.asList(source, destination));
@@ -145,7 +154,7 @@ public class SimpleConnection implements Connection {
 		status = DONE;
 		return new LinkedList<Packet>(Arrays.asList((Packet) new SimplePacket(
 				startTime, srcOfTermination,
-				srcOfTermination == source ? destination : source, "Terminated")));
+				srcOfTermination == source ? destination : source, "Terminated", label)));
 	}
 
 	@Override
@@ -200,4 +209,14 @@ public class SimpleConnection implements Connection {
 		this.name = name;
 	}
 
+	@Override
+	public short getLabel() {
+		return label;
+	}
+
+	@Override
+	public void setLabel(short label) {
+		this.label = label;
+	}
+
 }

+ 21 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/SimpleLink.java

@@ -138,6 +138,11 @@ public class SimpleLink implements Link {
 		 * Unsorted Packets from multiple sorted Connections
 		 */
 	}
+	
+	@Override
+	public Collection<Packet> encapsulatePackages(Collection<Packet> packets){
+		return packets;
+	}
 
 	@Override
 	public Collection<Packet> getPackets() {
@@ -184,4 +189,20 @@ public class SimpleLink implements Link {
 	public long  getFixedDelay(){
 		return this.fixedDelay;
 	}
+
+	@Override
+	public void addPackets(Collection<Packet> packets) {
+		this.packets.addAll(packets);
+	}
+
+	@Override
+	public void initSimulationInterval(long startTime, long duration) {
+		packets.clear();
+		
+	}
+
+	@Override
+	public void finalizeSimulationInterval(long startTime, long duration) {
+		
+	}
 }

+ 34 - 4
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/SimplePacket.java

@@ -41,6 +41,8 @@ public class SimplePacket extends Packet {
 	 * @param payload
 	 *            String which represents the payload which is encapsulated by
 	 *            this packet
+	 * @param label
+	 * 			  Label of this packet, represented as a short
 	 */
 	public SimplePacket(long time, Port source, Port destination, String payload) {
 		super(time, source, destination);
@@ -48,6 +50,29 @@ public class SimplePacket extends Packet {
 		this.destination = destination;
 		this.payload = payload;
 	}
+	
+	/**
+	 * Creates a new dummy packet with a String as payload
+	 * 
+	 * @param time
+	 *            time the package was created in System.currentTimeMillis
+	 * @param source
+	 *            SmartDevice which sent this packet
+	 * @param destination
+	 *            SmartDevice which should receive this packet
+	 * @param payload
+	 *            String which represents the payload which is encapsulated by
+	 *            this packet
+	 * @param label
+	 * 			  Label of this packet, represented as a short
+	 */
+	public SimplePacket(long time, Port source, Port destination, String payload, short label) {
+		super(time, source, destination);
+		this.source = source;
+		this.destination = destination;
+		this.payload = payload;
+		this.label = label;
+	}
 
 	@Override
 	public byte[] dumpBytes() {
@@ -61,10 +86,10 @@ public class SimplePacket extends Packet {
 	
 	@Override
 	public String toString() {
-		String destName = destination == null ? "null" : destination.getOwner().getName();
-		String srcName = source == null ? "null" : source.getOwner().getName();
-			
-		return "[SimplePacket:" + payload + " time-" + timestamp + ";source:" + srcName + ";dest:"
+		String destName = destination == null ? "null" : (destination.getOwner().getName()+":"+destination.getPortNumber());
+		String srcName = source == null ? "null" : (source.getOwner().getName()+":"+source.getPortNumber());
+
+		return "[SimplePacket:" + payload + " time:" + timestamp + ";source:" + srcName + ";dest:"
 				+ destName + "]";
 	}
 
@@ -72,4 +97,9 @@ public class SimplePacket extends Packet {
 	public String getPayload() {
 		return payload == null ? "" : payload;
 	}
+
+	@Override
+	public String getProtocolName() {
+		return "Simple";
+	}
 }

+ 17 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/SimplePacketSniffer.java

@@ -16,6 +16,11 @@ import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PacketSniffer;
  */
 public class SimplePacketSniffer implements PacketSniffer {
 
+	/**
+	 * True if in testing mode;
+	 */
+	private boolean testing = true;
+	
 	@Override
 	public void processPackets(HashMap<Link, LinkedList<Packet>> packets) {
 		System.out.println("PacketSniffer: ");
@@ -31,4 +36,16 @@ public class SimplePacketSniffer implements PacketSniffer {
 
 	}
 
+	@Override
+	public void setMode(boolean testing) {
+		this.testing = testing;
+	}
+
+	@Override
+	public boolean getMode() {
+		return this.testing;
+	}
+	
+	
+
 }

+ 11 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/MenuBar.java

@@ -12,12 +12,13 @@ import javax.swing.JOptionPane;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.Controller;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.SettingsController;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.menuBar.MenuBarInsertAnomalies;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.menuBar.MenuBarNetworkExamples;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.AboutPopUp;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.ConnectionCreationDialog;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.EditAlgorithmsPopUp;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.EditCollectorsPopUp;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.LinkCreationDialog;
-import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.MenuBarNetworkExamples;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.NetworkTreeWindow;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.SettingsPopUp;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.SimulationConfigurator;
@@ -74,6 +75,11 @@ public class MenuBar extends JMenuBar {
 	 * JMenu for examples
 	 */
 	private JMenu mnExamples;
+	
+	/**
+	 * JMenu for Examample Anomalies
+	 */
+	private JMenu mnInsertAnomaly;
 
 	/**
 	 * Serial Version
@@ -190,6 +196,10 @@ public class MenuBar extends JMenuBar {
 		mnExamples = new MenuBarNetworkExamples(controller);
 		mnCreate.add(mnExamples);
 		
+		// Create Anomaly Example
+		mnInsertAnomaly = new MenuBarInsertAnomalies(controller);
+		mnCreate.add(mnInsertAnomaly);
+		
 		
 	}
 

+ 152 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/menuBar/MenuBarInsertAnomalies.java

@@ -0,0 +1,152 @@
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.view.menuBar;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Observable;
+import java.util.Observer;
+
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.Controller;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.ExampleAnomalyController;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.NetworkController;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Connection;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ConnectionPrecision;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PrecisionLink;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.BoolSensor;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.FloatSensor;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler.NormalDistributionHandler;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.simpleImplementation.SimpleProtocol;
+
+/**
+ * Menu which allows simple insertion of anomalies into the network
+ * 
+ * @author Andreas T. Meyer-Berg
+ */
+public class MenuBarInsertAnomalies extends JMenu implements Observer {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 2522406981845530518L;
+	
+	/**
+	 * Controller for manipulating the network
+	 */
+	private Controller controller;
+	
+	/**
+	 * Menu for denial of service attacks
+	 */
+	private JMenu mnDos;
+	
+	/**
+	 * Menu for distributed denial of service attacks
+	 */
+	private JMenu mnDDos;
+	
+	/**
+	 * Menu for letting the device crash
+	 */
+	private JMenu mnCrash;
+	
+	/**
+	 * Menu for Value Anomalies
+	 */
+	private JMenu mnValueAnomaly;
+	
+	/**
+	 * Anomaly Controller
+	 */
+	private ExampleAnomalyController anomController;
+	
+	/**
+	 * Create a new MenuBar for anomaly insertion
+	 * @param controller main Controller of the framework
+	 */
+	public MenuBarInsertAnomalies(Controller controller) {
+		super("Insert Example Anomaly");
+		this.controller = controller;
+		this.anomController = controller.getNetworkController().getAnomalyController();
+		initialize();
+		this.update(null, null);
+		this.controller.addObserver(this);
+	}
+
+	private void initialize() {
+		mnDos = new JMenu("Denial of Service");
+		this.add(mnDos);
+		
+		mnDDos = new JMenu("Distributed Denial of Service");
+		this.add(mnDDos);
+		
+		mnCrash = new JMenu("Crash Device");
+		this.add(mnCrash);
+		
+		mnValueAnomaly = new JMenu("Value Anomaly");
+		this.add(mnValueAnomaly);	
+	}
+	
+	@Override
+	public void update(Observable o, Object arg) {
+		mnDos.removeAll();
+		mnDDos.removeAll();
+		mnCrash.removeAll();
+		mnValueAnomaly.removeAll();
+		
+		for(SmartDevice d : controller.getNetworkController().getVisibleSmartDevices()) {
+			/**
+			 * DDos Target Menu Item, which opens a DDosCreation Menu
+			 */
+			JMenuItem mntmDDosTarget = new JMenuItem("Destination: "+d.getName());
+			mntmDDosTarget.addActionListener(a->anomController.openDDosCreationMenu(d, (List<SmartDevice>)controller.getNetworkController().getVisibleSmartDevices()));
+			mnDDos.add(mntmDDosTarget);
+			/**
+			 * Dos creation menus
+			 */
+			JMenu mntmDosSource = new JMenu("Source: "+d.getName());
+			for(SmartDevice t: controller.getNetworkController().getVisibleSmartDevices()){
+				if(d==t)continue;
+				JMenuItem mntmDosTarget = new JMenuItem("Destination: " +t.getName());
+				mntmDosTarget.addActionListener(a->anomController.runDosAttack(d,t));
+				mntmDosSource.add(mntmDosTarget);
+			}
+			mnDos.add(mntmDosSource);
+			/**
+			 * Menus to crash a device
+			 */
+			JMenuItem crashDevice = new JMenuItem(d.getName());
+			crashDevice.addActionListener(a->anomController.crashDevice(d));
+			mnCrash.add(crashDevice);
+			/**
+			 * Value Anomalies menus
+			 */
+			if(d instanceof BoolSensor) {
+				BoolSensor sensor = (BoolSensor)d;
+				JMenuItem itm = new JMenuItem(d.getName());
+				itm.addActionListener(a->sensor.setBSval(!sensor.getBSval()));
+			}else if(d instanceof FloatSensor) {
+				FloatSensor sensor = (FloatSensor)d;
+				JMenuItem itm = new JMenuItem(d.getName());
+				itm.addActionListener(a->{
+					sensor.setFSmax(100);
+					sensor.setFSval(80);
+				});
+				mnValueAnomaly.add(itm);
+			}
+		}
+		/**
+		 * Only enable not empty menus
+		 */
+		mnCrash.setEnabled(mnCrash.getMenuComponentCount()!=0);
+		mnDos.setEnabled(mnDos.getMenuComponentCount()!=0);
+		mnDDos.setEnabled(mnDDos.getMenuComponentCount()!=0);
+		mnValueAnomaly.setEnabled(mnValueAnomaly.getMenuComponentCount()!=0);
+	}
+
+}

+ 377 - 18
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/MenuBarNetworkExamples.java → src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/menuBar/MenuBarNetworkExamples.java

@@ -1,5 +1,6 @@
-package de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups;
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.view.menuBar;
 
+import java.io.File;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -9,7 +10,10 @@ import javax.swing.JMenu;
 import javax.swing.JMenuItem;
 
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.Controller;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.ExampleAnomalyController;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.ImportController;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.NetworkController;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.PacketCaptureController;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.SettingsController;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.SimulationController;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Connection;
@@ -18,6 +22,7 @@ import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ConnectionPrecision;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PacketCollector;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PacketSniffer;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PrecisionLink;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
@@ -26,6 +31,7 @@ import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.BoolCollectorDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.BoolSensorDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.FloatCollectorDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.FloatSensorDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler.NormalDistributionHandler;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.MQTT_protocol;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.simpleImplementation.CountingMetric;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.simpleImplementation.Manipulation_RandomMove;
@@ -49,6 +55,11 @@ public class MenuBarNetworkExamples extends JMenu{
 	 */
 	private NetworkController networkController;
 	
+	/**
+	 * Controller to insert anomalies
+	 */
+	private ExampleAnomalyController anomalyController;
+	
 	/**
 	 * Controller for configuration of the program
 	 */
@@ -68,6 +79,7 @@ public class MenuBarNetworkExamples extends JMenu{
 		
 		this.controller = controller;
 		this.networkController = controller.getNetworkController();
+		this.anomalyController = networkController.getAnomalyController();
 		this.settingsController = controller.getSettingsController();
 		this.simulationController = controller.getSimulationController();
 		
@@ -105,8 +117,21 @@ public class MenuBarNetworkExamples extends JMenu{
 		JMenuItem mnPacketCollectionExmample = new JMenuItem("Packet Collection Example");
 		mnPacketCollectionExmample.addActionListener(a->testPackageCollection());
 		this.add(mnPacketCollectionExmample);
+		
+		/**
+		 * Paper example
+		 */
+		JMenuItem mnPaperExample = new JMenuItem("Paper Example");
+		mnPaperExample.addActionListener(a->createPaperExample(false));
+		this.add(mnPaperExample);
+		
+		/**
+		 * Paper example + run
+		 */
+		JMenuItem mnRunPaperExample = new JMenuItem("Run Paper Example");
+		mnRunPaperExample.addActionListener(a->createPaperExample(true));
+		this.add(mnRunPaperExample);
 	}
-	
 
 	private void initializePerformanceTest(){
 		SmartDevice tic = new SmartDevice("Tic");
@@ -164,6 +189,8 @@ public class MenuBarNetworkExamples extends JMenu{
 	 * Test package collectors
 	 */
 	private void testPackageCollection() {
+		if(networkController.getSmartDevices().size()<3)
+			return;
 		simulationController.addAlgorithm(new Manipulation_RandomMove(), controller);
 	    PacketCollector collector = new PacketCollector();
 	    simulationController.getSimulationManager().getPacketCollectionManager().addPacketCollector(collector);
@@ -241,13 +268,11 @@ public class MenuBarNetworkExamples extends JMenu{
 		B.addLink(link);
 		C.addLink(link);
 		
-		Port a = new Port(A, (short) 1);
+		Port a = new Port(A, (short) 1, 68);
 		a.setLastTrigger(0);
-		a.setTriggerInterval(68);
 		a.setStatus(Port.SENDING);
 		A.addPort(a);
-		Port b = new Port(B, (short) 2);
-		b.setTriggerInterval(102);
+		Port b = new Port(B, (short) 2, 102);
 		b.setStatus(Port.SENDING);
 		B.addPort(b);
 		
@@ -277,9 +302,8 @@ public class MenuBarNetworkExamples extends JMenu{
 		broker.setY((int)(Math.random()*settingsController.getWidth()-2*settingsController.getDeviceVisualizationRadius())+settingsController.getDeviceVisualizationRadius());
 		networkController.addSmartDevice(broker);
 		
-		Port brokerPort = new Port(broker, (short) 0);
+		Port brokerPort = new Port(broker, (short) 0, 987);
 		brokerPort.setLastTrigger(0);
-		brokerPort.setTriggerInterval(987);
 		brokerPort.setStatus(Port.OPEN);		
 		broker.addPort(brokerPort);
 		
@@ -308,9 +332,8 @@ public class MenuBarNetworkExamples extends JMenu{
 			link.addDevice(A);
 			A.addLink(link);
 			
-			aP = new Port(A,((short) (3*i+1)));
+			aP = new Port(A,((short) (3*i+1)),100+(int)(Math.random()*900));
 			aP.setLastTrigger(0);
-			aP.setTriggerInterval(100+(int)(Math.random()*900));
 			aP.setJitter((short) (Math.random()*50));
 			aP.setStatus(Port.SENDING);
 			aP.setConnection(con);
@@ -329,9 +352,8 @@ public class MenuBarNetworkExamples extends JMenu{
 			link.addDevice(A1);
 			A1.addLink(link);
 			
-			a1P = new Port(A1,((short) (3*i+1)));
+			a1P = new Port(A1,((short) (3*i+1)),100+(int)(Math.random()*900));
 			a1P.setLastTrigger(0);
-			a1P.setTriggerInterval(100+(int)(Math.random()*900));
 			a1P.setJitter((short) (Math.random()*50));
 			a1P.setStatus(Port.SENDING);
 			a1P.setConnection(con);
@@ -350,9 +372,8 @@ public class MenuBarNetworkExamples extends JMenu{
 			link.addDevice(A2);
 			A2.addLink(link);
 			
-			a2P = new Port(A2,((short) (3*i+1)));
+			a2P = new Port(A2,((short) (3*i+1)),100+(int)(Math.random()*900));
 			a2P.setLastTrigger(0);
-			a2P.setTriggerInterval(100+(int)(Math.random()*900));
 			a2P.setJitter((short) (Math.random()*50));
 			a2P.setStatus(Port.SENDING);
 			a2P.setConnection(con);
@@ -372,9 +393,8 @@ public class MenuBarNetworkExamples extends JMenu{
 			link.addDevice(B);
 			B.addLink(link);
 			
-			bP = new Port(B,((short) (3*i+2)));
+			bP = new Port(B,((short) (3*i+2)),10+(int)(Math.random()*190));
 			bP.setLastTrigger(0);
-			bP.setTriggerInterval(10+(int)(Math.random()*190));
 			bP.setJitter((short) (Math.random()*50));
 			bP.setStatus(Port.SENDING);
 			bP.setConnection(con);
@@ -391,9 +411,8 @@ public class MenuBarNetworkExamples extends JMenu{
 			link.addDevice(C);
 			C.addLink(link);
 			
-			cP = new Port(C,((short) (3*i+1)));
+			cP = new Port(C,((short) (3*i+1)), 50+(int)(Math.random()*450));
 			cP.setLastTrigger(0);
-			cP.setTriggerInterval(50+(int)(Math.random()*450));
 			cP.setJitter((short) (Math.random()*50));
 			cP.setStatus(Port.SENDING);
 			cP.setConnection(con);
@@ -405,4 +424,344 @@ public class MenuBarNetworkExamples extends JMenu{
 			controller.notifyObservers();
 		}
 	}
+	
+	/**
+	 * Creates the paper toy example, also simulates it, if run = true
+	 * @param run
+	 */
+	@SuppressWarnings("unchecked")
+	public void createPaperExample(boolean run){
+		/**
+		 * Reset network, etc.
+		 */
+		if(run) {
+			controller.getSimulationController().resetSimulation();
+			controller.getNetworkController().deleteNetworkModel();
+		}
+		/*
+		 * Main networking devices 
+		 */
+		SmartDevice router = networkController.createSmartDevice("Wifi-Router", 500, 100, 50);
+		SmartDevice zigBeeRouter = networkController.createSmartDevice("ZigBee-Router", 500, 300, 50);
+		SmartDevice broker = networkController.createSmartDevice("SmartHub", 500, 500, 50);
+		
+		/*
+		 * Links/Networks
+		 */
+		Link wifi = new PrecisionLink("Wifi");
+		networkController.addLink(wifi);
+		Link zigbee = new PrecisionLink("ZigBee");
+		networkController.addLink(zigbee);
+		
+		/*
+		 * Connect Devices to Links
+		 */
+		networkController.addLinkToDevice(wifi, router);
+		networkController.addLinkToDevice(wifi, zigBeeRouter);
+		networkController.addLinkToDevice(zigbee, zigBeeRouter);
+		networkController.addLinkToDevice(zigbee, broker);
+		
+		/*
+		 * Internet Access Connection 
+		 */
+		Connection inetAcces = new ConnectionPrecision();
+		inetAcces.setName("Cloud  Access");
+		networkController.addConnectionToLink(inetAcces, wifi);
+		inetAcces.setProtocol(new SimpleProtocol());
+		Port pRouter = new Port(router, (short)80, 500L);
+		pRouter.setTriggerHandler(new NormalDistributionHandler(500, 100));
+		networkController.addDeviceToConnectionAndProtocol(pRouter, inetAcces, 0);
+		Port pZigBee = new Port(zigBeeRouter, (short)80, 1000L);
+		pZigBee.setTriggerHandler(new NormalDistributionHandler(1000, 300));
+		networkController.addDeviceToConnectionAndProtocol(pRouter, inetAcces, 0);
+		networkController.addDeviceToConnectionAndProtocol(pZigBee, inetAcces, 1);
+		networkController.addConnection(inetAcces);
+		
+		/*
+		 * ZigbeeRouter -> Broker ? 
+		 */
+		Connection homeAutomationInternetAccess = new ConnectionPrecision();
+		homeAutomationInternetAccess.setName("Home Automation Webinterface");
+		networkController.addConnectionToLink(homeAutomationInternetAccess, zigbee);
+		homeAutomationInternetAccess.setProtocol(new SimpleProtocol());
+		Port pBrokerWebInterface = new Port(broker, (short)80);
+		pBrokerWebInterface.setTriggerHandler(new NormalDistributionHandler(2000, 500));
+		pBrokerWebInterface.setStatus(Port.SENDING);
+		pBrokerWebInterface.setResponseTime((short)2);
+		pBrokerWebInterface.setLastTrigger(-284L);
+		networkController.addDeviceToConnectionAndProtocol(pBrokerWebInterface, homeAutomationInternetAccess, 0);
+		networkController.addConnection(homeAutomationInternetAccess);
+		Port pRouterWebInterface = new Port(zigBeeRouter, (short)80);
+		pRouterWebInterface.setTriggerHandler(new NormalDistributionHandler(5000, 3000));
+		pRouterWebInterface.setStatus(Port.SENDING);
+		pRouterWebInterface.setResponseTime((short)2);
+		pRouterWebInterface.setLastTrigger(-142L);
+		networkController.addDeviceToConnectionAndProtocol(pRouterWebInterface, homeAutomationInternetAccess, 1);
+		networkController.addConnection(homeAutomationInternetAccess);
+		
+		
+		/*
+		 * Create MQTT Connection
+		 */
+		Connection mqtt = new ConnectionPrecision();
+		mqtt.setName("Automation (MQTT)");
+		networkController.addConnectionToLink(mqtt, zigbee);
+		mqtt.setProtocol(new MQTT_protocol());
+		Port pBroker = new Port(broker, (short)1883);
+		pBroker.setStatus(Port.OPEN);
+		pBroker.setResponseTime((short)2);
+		networkController.addDeviceToConnectionAndProtocol(pBroker, mqtt, 0);
+		networkController.addConnection(mqtt);
+		
+		/*
+		 * Add some MQTT Devices
+		 */
+		
+		/**
+		 * Kitchen Thermostat
+		 */
+		FloatSensorDevice floatSensor = new FloatSensorDevice("Kitchen Thermostat");
+		floatSensor.setFSinfoName("home/kitchen/temperature");
+		networkController.addLinkToDevice(zigbee, floatSensor);
+		networkController.moveSmartDevice(floatSensor, 300, 500, 50);
+		floatSensor.setFSmin(15.0f);
+		floatSensor.setFSmax(32.0f);
+		networkController.addSmartDevice(floatSensor);
+		Port pFloatSensor = new Port(floatSensor, (short)1883, 15000);
+		pFloatSensor.setTriggerHandler(new NormalDistributionHandler(15000, 500));
+		pFloatSensor.setStatus(Port.SENDING);
+		pFloatSensor.setLastTrigger(-357L);
+		networkController.addDeviceToConnectionAndProtocol(pFloatSensor, mqtt,1);
+		
+		/*
+		 * Add Fridge
+		 */
+		FloatSensorDevice kitchenFridge = new FloatSensorDevice("Smart Fridge");
+		kitchenFridge.setFSinfoName("home/kitchen/fridgeTemp");
+		networkController.addLinkToDevice(zigbee, kitchenFridge);
+		networkController.moveSmartDevice(kitchenFridge, 100, 600, 50);
+		kitchenFridge.setFSmin(-6.0f);
+		kitchenFridge.setFSmax(-4.0f);
+		networkController.addSmartDevice(kitchenFridge);
+		Port pKitchenFridge = new Port(kitchenFridge, (short)1883, 15000);
+		pKitchenFridge.setStatus(Port.SENDING);
+		pKitchenFridge.setTriggerHandler(new NormalDistributionHandler(15000, 500));
+		pKitchenFridge.setLastTrigger(-1231L);
+		networkController.addDeviceToConnectionAndProtocol(pKitchenFridge, mqtt,1);
+		
+		
+		/*
+		 * Add some kitchen lights
+		 */
+		BoolSensorDevice kitchenLight = new BoolSensorDevice("Kitchen Light");
+		kitchenLight.setBSinfoName("home/kitchen/light");
+		networkController.addLinkToDevice(zigbee, kitchenLight);
+		networkController.moveSmartDevice(kitchenLight, 250, 400, 50);
+		networkController.addSmartDevice(kitchenLight);
+		Port pKitchenLight = new Port(kitchenLight, (short)1883, 15000);
+		pKitchenLight.setTriggerHandler(new NormalDistributionHandler(15000, 500));
+		pKitchenLight.setStatus(Port.SENDING);
+		pKitchenLight.setLastTrigger(-1207L);
+		networkController.addDeviceToConnectionAndProtocol(pKitchenLight, mqtt,1);
+		
+		//TODO Further devices & Connections
+		
+		/*
+		 * Bedroom
+		 */
+		BoolSensorDevice sleepingRoomLight = new BoolSensorDevice("Bedroom Light");
+		sleepingRoomLight.setBSinfoName("home/bedroom/light");
+		networkController.addLinkToDevice(zigbee, sleepingRoomLight);
+		networkController.moveSmartDevice(sleepingRoomLight, 750, 400, 50);
+		networkController.addSmartDevice(sleepingRoomLight);
+		Port pBedroomLight = new Port(sleepingRoomLight, (short)1883, 15000);
+		pBedroomLight.setTriggerHandler(new NormalDistributionHandler(15000, 500));
+		pBedroomLight.setStatus(Port.SENDING);
+		pBedroomLight.setLastTrigger(-1337L);
+		networkController.addDeviceToConnectionAndProtocol(pBedroomLight, mqtt,1);
+		
+		/*
+		 * Bedroom Thermostat
+		 */
+		FloatSensorDevice bedroomThermostat = new FloatSensorDevice("Bedroom Thermostat");
+		bedroomThermostat.setFSinfoName("home/bedroom/temperature");
+		networkController.addLinkToDevice(zigbee, bedroomThermostat);
+		networkController.moveSmartDevice(bedroomThermostat, 700, 500, 50);
+		bedroomThermostat.setFSmin(15.0f);
+		bedroomThermostat.setFSmax(32.0f);
+		networkController.addSmartDevice(bedroomThermostat);
+		Port pBedroomThermostat = new Port(bedroomThermostat, (short)1883, 15000);
+		pBedroomThermostat.setTriggerHandler(new NormalDistributionHandler(15000, 500));
+		pBedroomThermostat.setStatus(Port.SENDING);
+		pBedroomThermostat.setLastTrigger(-820L);
+		networkController.addDeviceToConnectionAndProtocol(pBedroomThermostat, mqtt,1);
+		
+		
+		/*
+		 * Bedroom Info Screen
+		 */
+		FloatCollectorDevice bedroomInfoScreen = new FloatCollectorDevice("Information Panel");
+		bedroomInfoScreen.setFCinfoName("home/kitchen/fridgeTemp");
+		networkController.addLinkToDevice(zigbee, bedroomInfoScreen);
+		networkController.moveSmartDevice(bedroomInfoScreen, 900, 600, 50);
+		networkController.addSmartDevice(bedroomInfoScreen);
+		Port pBedroomInfo = new Port(bedroomInfoScreen, (short)1883, 15000);
+		pBedroomInfo.setStatus(Port.SENDING);
+		pBedroomInfo.setTriggerHandler(new NormalDistributionHandler(15000, 500));
+		pBedroomInfo.setLastTrigger(-666L);
+		networkController.addDeviceToConnectionAndProtocol(pBedroomInfo, mqtt,1);
+		/* 
+		 * Update visualization 
+		 */
+		controller.notifyObservers();
+		
+		/**
+		 * Run only if run == true
+		 */
+		if(!run)return;
+		try {
+			System.out.println("Check 1");//TODO
+			/**
+			 * Instances of the packet Sniffers
+			 */
+			PacketSniffer snifferEM = null, snifferKNN = null, snifferHC = null;
+			/*
+			 * Import Example PacketSniffer algorithms
+			 */
+			Class<? extends PacketSniffer> em = (Class<? extends PacketSniffer>) ImportController.importJavaClass(new File("examples/classifier/EMClustering.java"));
+			snifferEM = em.newInstance();
+			Class<? extends PacketSniffer> knn = (Class<? extends PacketSniffer>) ImportController.importJavaClass(new File("examples/classifier/KMeansClustering.java"));
+			snifferKNN = knn.newInstance();
+			Class<? extends PacketSniffer> hc = (Class<? extends PacketSniffer>) ImportController.importJavaClass(new File("examples/classifier/HierarchicalClustering.java"));
+			snifferHC = hc.newInstance();
+
+			System.out.println("Check 2: Imported");//TODO
+			/*
+			 * Create collectors
+			 */
+			PacketCollector collectorKNN = new PacketCollector(snifferKNN);
+			//PacketCollector collectorEM = new PacketCollector(snifferEM);
+			//PacketCollector collectorHC = new PacketCollector(snifferHC);
+			
+			/*
+			 * Capture both links on all collectors
+			 */
+			PacketCaptureController captureController = controller.getSimulationController().getPacketCaptureController();
+			//captureController.addLinkToCollector(collectorEM, zigbee);
+			//captureController.addLinkToCollector(collectorEM, wifi);
+			captureController.addLinkToCollector(collectorKNN, zigbee);
+			captureController.addLinkToCollector(collectorKNN, wifi);
+			//captureController.addLinkToCollector(collectorHC, zigbee);
+			//captureController.addLinkToCollector(collectorHC, wifi);
+			captureController.addPacketCollector(collectorKNN);
+			//captureController.addPacketCollector(collectorEM);
+			//captureController.addPacketCollector(collectorHC);
+
+			System.out.println("Check 3: created Controller");//TODO
+			
+			long currentTime = System.currentTimeMillis();
+			
+			long hour = 60 * 60 * 1000;
+			/*
+			 * Simulate 24 hours
+			 */
+			SimulationController sim = controller.getSimulationController();
+			sim.setStartTime(0);
+			sim.resetSimulation();
+			sim.setStepDuration(hour);
+			sim.setPrintPackets(false);
+			sim.setEndTime(24*hour);
+
+			kitchenFridge.setFSmin(-6f);
+			kitchenFridge.setFSmax(-4f);
+			kitchenFridge.setFSval(-5f);
+			System.out.println("Training:");//TODO
+			for(int i=0; i<24; i++)
+				sim.getSimulationManager().simulateTimeIntervall(i*hour, hour);
+			
+			long new_time = System.currentTimeMillis();
+			long elapsed_time = new_time-currentTime;
+			System.out.println("Training data generation: "+elapsed_time+"ms");
+			currentTime = new_time;
+			
+			collectorKNN.setMode(true);
+			//collectorEM.setMode(true);
+			//collectorHC.setMode(true);
+			new_time = System.currentTimeMillis();
+			elapsed_time = new_time-currentTime;
+			System.out.println("Training of algorithm: "+elapsed_time+"ms");
+			currentTime = new_time;
+			
+			
+			
+			/*
+			 * Simulate/Test 1 hour without anomalies
+			 */
+
+			System.out.println("Test w/0 anomalies:");//TODO
+			for(int i=24; i<25; i++)
+				sim.getSimulationManager().simulateTimeIntervall(hour*i, hour);
+			
+			new_time = System.currentTimeMillis();
+			elapsed_time = new_time-currentTime;
+			System.out.println("Training data generation: "+elapsed_time+"ms");
+			currentTime = new_time;
+			
+			System.out.println("DDoS:");
+			/**
+			 * 1 hour DDoS
+			 */
+			Connection ddos = anomalyController.openDDosCreationMenu(broker, new LinkedList<SmartDevice>(zigbee.getDevices()));	
+			for(int i=25; i<26; i++)
+				sim.getSimulationManager().simulateTimeIntervall(hour*i, hour);
+			networkController.deleteConnection(ddos);
+			
+			new_time = System.currentTimeMillis();
+			elapsed_time = new_time-currentTime;
+			System.out.println("DDoS generation & classification: "+elapsed_time+"ms");
+			currentTime = new_time;
+			
+			System.out.println("DoS:");
+			/**
+			 * 1 hour DoS
+			 */
+			Connection dos = anomalyController.runDosAttack(kitchenLight, kitchenFridge);
+			for(int i=26; i<27; i++)
+				sim.getSimulationManager().simulateTimeIntervall(hour*i, hour);
+			networkController.deleteConnection(dos);
+			
+			new_time = System.currentTimeMillis();
+			elapsed_time = new_time-currentTime;
+			System.out.println("DoS generation & classification: "+elapsed_time+"ms");
+			currentTime = new_time;
+			
+			/**
+			 * Value Anomaly 1h
+			 */
+			System.out.println("Value Anomalies:");
+			float min = kitchenFridge.getFSmin();
+			float max = kitchenFridge.getFSmax();
+			float val = kitchenFridge.getFSval();
+			kitchenFridge.setFSmin(18);
+			kitchenFridge.setFSval(18.5f);
+			kitchenFridge.setFSmax(24);
+			kitchenFridge.setLabel((short)-1);//-1 Value anomaly
+			for(int i=27; i<28; i++)
+				sim.getSimulationManager().simulateTimeIntervall(hour*i, hour);
+			kitchenFridge.setFSmin(min);
+			kitchenFridge.setFSmax(max);
+			kitchenFridge.setFSval(val);
+			kitchenFridge.setLabel((short)0);
+			
+			new_time = System.currentTimeMillis();
+			elapsed_time = new_time-currentTime;
+			System.out.println("Anomaly generation & classification: "+elapsed_time+"ms");
+			currentTime = new_time;
+			
+			System.out.println("Testing completed");
+		} catch(Exception e) {
+			System.out.println("WARNING: Testing failed: ");
+			e.printStackTrace();
+		}
+	}
 }

+ 7 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/menuBar/package-info.java

@@ -0,0 +1,7 @@
+/**
+ * 
+ * Different submenus of the MenuBar
+ * 
+ * @author Andreas T. Meyer-Berg
+ */
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.view.menuBar;

+ 52 - 6
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/ConnectionCreationPanel.java

@@ -158,6 +158,7 @@ public class ConnectionCreationPanel extends JScrollPane {
 	 * Should not update if mutex is true
 	 */
 	private boolean mutex = true;
+	private JTextField tfLabel;
 
 
 	/**
@@ -165,6 +166,7 @@ public class ConnectionCreationPanel extends JScrollPane {
 	 * @param connection connection which should be edited
 	 * @param controller controller for manipulation
 	 * @param frame parent frame
+	 * @wbp.parser.constructor
 	 */// @wbp.parser.constructor for Eclipse:WindowBuilder
 	public ConnectionCreationPanel(Connection connection, Controller controller, Window frame) {
 		this.controller = controller;
@@ -216,9 +218,9 @@ public class ConnectionCreationPanel extends JScrollPane {
 
 		// Sets up window
 		setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
-		this.setPreferredSize(new Dimension(600, 220 + ports.length * 20));
+		this.setPreferredSize(new Dimension(600, 250 + ports.length * 20));
 		content = new JPanel();
-		content.setPreferredSize(new Dimension(600, 200 + ports.length * 20));
+		content.setPreferredSize(new Dimension(600, 240 + ports.length * 20));
 		this.setViewportView(content);
 		content.setLayout(null);
 
@@ -484,6 +486,8 @@ public class ConnectionCreationPanel extends JScrollPane {
 			}
 
 			private void updateConnectionAndField() {
+				if(mutex)
+					return;
 				try {
 					double newRate = Double.parseDouble(tfPacketLossRate.getText());
 					if (newRate >= 0.0 && newRate <= 1.0) {
@@ -498,6 +502,46 @@ public class ConnectionCreationPanel extends JScrollPane {
 			}
 		});
 
+
+		JLabel lblLabel = new JLabel("Label:");
+		lblLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+		lblLabel.setBounds(10, 160, 140, 20);
+		content.add(lblLabel);
+		
+		tfLabel = new JTextField();
+		tfLabel.setColumns(10);
+		tfLabel.setBounds(155, 160, 90, 20);
+		content.add(tfLabel);
+		tfLabel.getDocument().addDocumentListener(new DocumentListener() {
+
+			@Override
+			public void removeUpdate(DocumentEvent e) {
+				updateConnectionAndField();
+			}
+
+			@Override
+			public void insertUpdate(DocumentEvent e) {
+				updateConnectionAndField();
+			}
+
+			@Override
+			public void changedUpdate(DocumentEvent e) {
+				updateConnectionAndField();
+			}
+
+			private void updateConnectionAndField() {
+				if(mutex)
+					return;
+				try {
+					short newLabel = Short.parseShort(tfLabel.getText());
+					connection.setLabel(newLabel);
+					tfLabel.setBackground(Color.WHITE);
+				} catch (Exception exception) {
+					tfLabel.setBackground(Color.RED);
+				}
+			}
+		});
+		
 		JLabel lblStatus = new JLabel("Status:");
 		lblStatus.setHorizontalAlignment(SwingConstants.RIGHT);
 		lblStatus.setBounds(250, 130, 60, 20);
@@ -524,7 +568,7 @@ public class ConnectionCreationPanel extends JScrollPane {
 		});
 
 		JButton btnCreate = new JButton("Verify and Create");
-		btnCreate.setBounds(125, 160, 206, 25);
+		btnCreate.setBounds(127, 186, 206, 25);
 		content.add(btnCreate);
 
 		btnCreate.addActionListener(new ActionListener() {
@@ -626,15 +670,14 @@ public class ConnectionCreationPanel extends JScrollPane {
 		 */
 		JLabel lblRole = new JLabel("Roles:");
 		lblRole.setHorizontalAlignment(SwingConstants.CENTER);
-		lblRole.setBounds(350, 165, 50, 18);
+		lblRole.setBounds(345, 189, 50, 18);
 		lblRole.setToolTipText("The roles each device plays in the connection, can be defined below. It defines how the device acts.");
 		content.add(lblRole);
 		
-		
 		/**
 		 * Height of the current Box which is being created
 		 */
-		int currentHeight = 190;
+		int currentHeight = 220;
 
 		cmbPortRoles = new JComboBox[ports.length];
 		for (int i = 0; i < ports.length; i++) {
@@ -750,6 +793,9 @@ public class ConnectionCreationPanel extends JScrollPane {
 		// Update packet loss field
 		tfPacketLossRate.setText("" + connection.getPacketLossProbability());
 
+		// Update Label
+		tfLabel.setText("" + connection.getLabel());
+		
 		// Update Status
 		cmbStatus.setSelectedIndex(connection.getStatus());
 

+ 56 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/EditPacketSniffer.java

@@ -17,9 +17,11 @@ import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PacketCollector;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PacketSniffer;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.util.Utility;
+import weka.classifiers.functions.supportVector.RBFKernel;
 
 import java.awt.Container;
 
+import javax.swing.ButtonGroup;
 import javax.swing.JButton;
 import javax.swing.JLabel;
 
@@ -30,6 +32,8 @@ import java.util.Iterator;
 import java.util.Observable;
 import java.util.Observer;
 import java.awt.event.ActionEvent;
+import javax.swing.JRadioButton;
+import javax.swing.JCheckBox;
 
 
 /**
@@ -95,6 +99,19 @@ public class EditPacketSniffer extends JDialog implements Observer {
 	 * True if the collector is being edited
 	 */
 	private boolean edit;
+	/**
+	 * RadioButton marked, if in testing mode
+	 */
+	private JRadioButton rdbtnTesting;
+	/**
+	 * RadioButton for training mode
+	 */
+	private JRadioButton rdbtnTraining;
+	/**
+	 * Checkbox, which is checked if enabled
+	 */
+	private JCheckBox chckbxEnabled;
+	
 	/**
 	 * Creates and shows a new EditAlgorithmPopUp
 	 * @param controller controller
@@ -230,6 +247,33 @@ public class EditPacketSniffer extends JDialog implements Observer {
 		
 		btnCreatePacketCollector.setBounds(180, 310, 210, 30);
 		getContentPane().add(btnCreatePacketCollector);
+		
+		chckbxEnabled = new JCheckBox("Enabled");
+		chckbxEnabled.setBounds(190, 50, 113, 25);
+		getContentPane().add(chckbxEnabled);
+		chckbxEnabled.addActionListener(a->{
+			if(mutex)return;
+			boolean active = chckbxEnabled.isSelected();
+			captureController.setActive(collector, active);
+		});
+		
+
+		rdbtnTraining = new JRadioButton("Training");
+		rdbtnTraining.setBounds(185, 82, 127, 25);
+		getContentPane().add(rdbtnTraining);
+		rdbtnTraining.addActionListener(a->{
+			if(mutex)return;
+			captureController.setMode(collector, !rdbtnTraining.isSelected());
+		});
+		
+		rdbtnTesting = new JRadioButton("Testing");
+		rdbtnTesting.setBounds(185, 112, 127, 25);
+		getContentPane().add(rdbtnTesting);
+		rdbtnTesting.addActionListener(a->{
+			if(mutex)return;
+			captureController.setMode(collector, rdbtnTesting.isSelected());
+		});
+		
 
 		this.addWindowListener(new WindowAdapter() {
 			//Remove Observer, if window is closing
@@ -242,7 +286,9 @@ public class EditPacketSniffer extends JDialog implements Observer {
 		update(null, null);
 		this.setLocationRelativeTo(parent);
 		
-		
+		ButtonGroup group = new ButtonGroup();
+		group.add(rdbtnTesting);
+		group.add(rdbtnTraining);
 	}
 	
 	@Override
@@ -332,6 +378,15 @@ public class EditPacketSniffer extends JDialog implements Observer {
 		scrollPaneDevices.getVerticalScrollBar().setValue(pos);
 		listDevices = newList;
 		
+		/**
+		 * Manage checkboxes
+		 */
+		chckbxEnabled.setSelected(collector.isActive());
+		rdbtnTesting.setEnabled(collector.isActive());
+		rdbtnTesting.setSelected(collector.getMode());
+		rdbtnTraining.setEnabled(collector.isActive());
+		rdbtnTraining.setSelected(!collector.getMode());		
+		
 		if(this.edit&&!captureController.getPacketCollectors().contains(collector)){
 			/**
 			 * If Collector was removed -> Close PopUp

+ 195 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/PortDistributionConfigurationPopUp.java

@@ -0,0 +1,195 @@
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.util.LinkedList;
+import java.util.Observable;
+import java.util.Observer;
+
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JButton;
+import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.border.EmptyBorder;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.Controller;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Model;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ProbabilityDistributionHandler;
+
+public class PortDistributionConfigurationPopUp extends JFrame implements Observer{
+	
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	private Port port;
+	
+	private JSplitPane splitPane;
+	
+	private JScrollPane scrollPane;
+	/**
+	 * ComboBox for link selection
+	 */
+	private JComboBox<String> cmbDistribution;
+	
+	/**
+	 * Distributions that can be selected;
+	 */
+	LinkedList<Class<? extends ProbabilityDistributionHandler>> availableDistributions;
+	
+	/**
+	 * Last index which was selected in the combo box
+	 */
+	int lastIndex = -1;
+	
+	boolean mutex = false;
+	
+	private Controller controller;
+	
+	private PortDistributionConfigurationPopUp that = this;
+	
+	public PortDistributionConfigurationPopUp(Port port, Controller controller) {
+		this.port = port;
+		this.controller = controller;
+		this.setSize(480, 360);
+		splitPane = new JSplitPane();
+		splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
+		splitPane.setBorder(new EmptyBorder(0, 0, 0, 0));
+		getContentPane().add(splitPane, BorderLayout.CENTER);
+		
+		JPanel panel = new JPanel();
+		splitPane.setLeftComponent(panel);
+		panel.setLayout(null);
+		
+		JLabel lblDescription = new JLabel("Distribution Type:");
+		lblDescription.setBounds(10, 10, 120, 20);
+		panel.add(lblDescription);
+		
+		cmbDistribution = new JComboBox<String>();
+		cmbDistribution.setBounds(120, 10, 190, 20);
+		panel.add(cmbDistribution);
+		
+		JButton btnImport = new JButton("Import");
+		btnImport.setBounds(320, 10, 100, 20);
+		panel.add(btnImport);
+		btnImport.addActionListener(a -> {
+			ImportPopUp<ProbabilityDistributionHandler> popUp = new ImportPopUp<ProbabilityDistributionHandler>(this, ProbabilityDistributionHandler.class);
+			try {
+				Class<? extends ProbabilityDistributionHandler> imported = popUp.showPopUp();
+				if (imported == null)
+					return;
+				if (controller.getImportController().addDistributionHandler(imported)) {
+					update(null, null);
+				} else {
+					JOptionPane.showMessageDialog(that, "Import failed: Invalid Distribution Handler");
+				}
+			} catch (Exception e1) {
+				JOptionPane.showMessageDialog(that, "Import failed: " + e1.getMessage());
+			}
+		});
+
+		splitPane.setDividerLocation(40);
+		
+		scrollPane = new JScrollPane();
+		splitPane.setRightComponent(scrollPane);
+		
+		update(null,null);
+		
+		this.addWindowListener(new WindowAdapter() {
+			public void windowClosing(java.awt.event.WindowEvent e) {
+				that.controller.removeObserver(that);
+			}
+		});
+		
+		cmbDistribution.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				if (mutex)
+					return;
+
+				/**
+				 * New Distribution
+				 */
+				ProbabilityDistributionHandler newDistribution = null;
+				try {
+					// Create new Instance of the protocol
+					newDistribution = controller.getImportController().getDistributionHandlers()
+							.get(cmbDistribution.getSelectedIndex()).newInstance();
+				} catch (InstantiationException | IllegalAccessException e1) {
+					System.out.println("WARNING: Distribution could not be initialized");
+				}
+				if (newDistribution == null) {
+					cmbDistribution.setSelectedIndex(lastIndex);
+					System.out.println("WARNING: Invalid Distribution Selected - restore last index");
+				} else {
+					/**
+					 * Add new Distribution
+					 */
+					port.setTriggerHandler(newDistribution);
+					/**
+					 * Update Index
+					 */
+					lastIndex = cmbDistribution.getSelectedIndex();
+					
+					update(null, null);
+				}
+			}
+		});
+		
+		this.controller.addObserver(this);
+	}
+
+	@Override
+	public void update(Observable o, Object arg) {
+		if(port == null)return;
+		ProbabilityDistributionHandler handler = port.getTriggerHandler();
+		
+		if(handler!=null)
+			scrollPane.setViewportView(handler.getConfigurationPanel());
+		else{
+			scrollPane.setViewportView(null);
+			return;
+		}
+		
+		
+		mutex = true;
+		/**
+		 *  Update Distribution function
+		 */
+		availableDistributions = controller.getImportController().getDistributionHandlers();
+		cmbDistribution.removeAllItems();
+		for (int i = 0; i < availableDistributions.size(); i++)
+			try {
+				cmbDistribution.addItem(availableDistributions.get(i).newInstance().getSimpleDescription());
+			} catch (InstantiationException | IllegalAccessException e1) {
+				System.out.println("Distribution " + i + " is invalid");
+				cmbDistribution.addItem("unknown");
+			}
+		// Set Index to selected Protocol
+		lastIndex = -1;
+		for (int i = 0; i < availableDistributions.size(); i++) {
+			if (handler.getClass().equals(availableDistributions.get(i))) {
+				// Select the right protocol and save last index
+				lastIndex = i;
+			}
+		}
+		cmbDistribution.setSelectedIndex(lastIndex);
+		
+		mutex = false;
+	}
+	
+	public static void main(String[] args) {
+		PortDistributionConfigurationPopUp test = new PortDistributionConfigurationPopUp(null, new Controller(new Model()));
+		test.setEnabled(true);
+		test.setVisible(true);
+	}
+}

+ 44 - 11
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/PortEditorPanel.java

@@ -77,13 +77,18 @@ public class PortEditorPanel extends JPanel
      */
     private JTextField tfJitter;
     
+    /**
+     * Controller for notifying other parts of the Framework
+     */
+    private Controller controller;
+    
     /**
      * Creates a new PortEditorPanel, which allows editing of the Ports of toEdit
      * @param toEdit SmartDevice, which ports will be edited
      * @param controller Controller to modify the Model
      */
     public PortEditorPanel(SmartDevice toEdit, Controller controller) {
-    	
+    	this.controller = controller;
     	this.toEdit = toEdit;
         //Create the list of ports
         Port[] ports = new Port[toEdit.getPorts().size()];
@@ -175,15 +180,21 @@ public class PortEditorPanel extends JPanel
         tfTriggerInterval = new JTextField();
         tfTriggerInterval.setBounds(160, 100, 130, 20);
         editPanel.add(tfTriggerInterval);
-        tfTriggerInterval.setColumns(10);
-        tfTriggerInterval.addFocusListener(this);
-        tfTriggerInterval.addActionListener(this);
-        tfTriggerInterval.addMouseListener(this);
+        //tfTriggerInterval.setColumns(10);
+        //tfTriggerInterval.addFocusListener(this);
+        //tfTriggerInterval.addActionListener(this);
+        //tfTriggerInterval.addMouseListener(this);
         tfTriggerInterval.setToolTipText(toolTipTrigger);
+        tfTriggerInterval.setEnabled(false);
         
-        JLabel lblTriggerIntervalUnit = new JLabel("ms");
-        lblTriggerIntervalUnit.setBounds(3000, 100, 50, 20);
-        editPanel.add(lblTriggerIntervalUnit);
+        JButton btnEditTriggerInterval = new JButton("Edit Distribution");
+        btnEditTriggerInterval.setBounds(300, 100, 150, 20);
+        btnEditTriggerInterval.addActionListener(l->openEditDistribution());
+        editPanel.add(btnEditTriggerInterval);
+        
+        //JLabel lblTriggerIntervalUnit = new JLabel("ms");
+        //lblTriggerIntervalUnit.setBounds(300, 100, 50, 20);
+        //editPanel.add(lblTriggerIntervalUnit);
         
         
         String toolTipResponse = "<html>Time in milliseconds which this port needs to calculate<br>"
@@ -269,7 +280,21 @@ public class PortEditorPanel extends JPanel
         	updateLabel(toEdit.getPorts().get(list.getSelectedIndex()));
     }
      
-    //Listens to the list
+    private void openEditDistribution() {
+    	if(list.getSelectedIndex() < 0 || list.getSelectedIndex() >= toEdit.getPorts().size())return;
+		/**
+		 * Port, which is being edited at the moment 
+		 */
+		Port toChange = toEdit.getPorts().get(list.getSelectedIndex());
+		
+		PortDistributionConfigurationPopUp popUp = new PortDistributionConfigurationPopUp(toChange, controller);
+		popUp.setEnabled(true);
+		popUp.setVisible(true);
+		popUp.setLocationRelativeTo(this);
+		popUp.setFocusable(true);
+	}
+
+	//Listens to the list
     @SuppressWarnings("unchecked")
 	public void valueChanged(ListSelectionEvent e) {
     	if(!(e.getSource() instanceof JList<?>)||!(((JList<?>)e.getSource()).getSelectedValue() instanceof Port))return;
@@ -289,7 +314,7 @@ public class PortEditorPanel extends JPanel
     	tfLastTrigger.setBackground(Color.WHITE);
     	tfResponseTime.setText(""+port.getResponseTime());
     	tfResponseTime.setBackground(Color.WHITE);
-    	tfTriggerInterval.setText(""+port.getTriggerInterval());
+    	tfTriggerInterval.setText(""+port.getTriggerInterval()+" ms");
     	tfTriggerInterval.setBackground(Color.WHITE);
     	tfJitter.setText(""+port.getJitter());
     	tfJitter.setBackground(Color.WHITE);
@@ -373,9 +398,16 @@ public class PortEditorPanel extends JPanel
 			toChange.setStatus((short) cmbStatus.getSelectedIndex());
 		
 		//Edit trigger Interval
+		/**
 		if(tfTriggerInterval.getText()!=""+toChange.getTriggerInterval()){
 			try {
-				toChange.setTriggerInterval(Long.parseLong(tfTriggerInterval.getText()));
+				//TODO: Advanced Triggers
+				ProbabilityDistributionHandler dist = toChange.getTriggerHandler();
+				if(dist instanceof ConstantValueDistribution){
+					((ConstantValueDistribution)dist).setValue(Long.parseLong(tfTriggerInterval.getText()));
+					toChange.resampleTriggerInterval();
+				}
+					//toChange.setTriggerInterval(Long.parseLong(tfTriggerInterval.getText()));
 				tfTriggerInterval.setBackground(Color.WHITE);
 			} catch (Exception e) {
 				tfTriggerInterval.setBackground(Color.RED);
@@ -383,6 +415,7 @@ public class PortEditorPanel extends JPanel
 		}else{
 			tfTriggerInterval.setBackground(Color.WHITE);
 		}
+		*/
 		
 		//Edit Response time
 		if(tfResponseTime.getText()!=""+toChange.getResponseTime()){

+ 1 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/SmartDeviceCreationPopUp.java

@@ -100,7 +100,7 @@ public class SmartDeviceCreationPopUp extends JDialog {
 	 */
 	public SmartDeviceCreationPopUp(SmartDevice deviceToEdit, boolean edit, Controller control) {
 
-		setModal(true);
+		//setModal(true);
 		// setType(Type.POPUP); -> Crashes on Linux
 		this.controller = control;
 		this.maxX = controller.getSettingsController().getWidth();

+ 1 - 1
src/test/java/de/tu_darmstadt/tk/shNetSimTests/control/ConfigurationTest.java

@@ -100,7 +100,7 @@ public class ConfigurationTest {
 
 	@Test
 	public void testGetDeviceVisualizationRadiusDefault() {
-		Assert.assertEquals(17, config.getDeviceVisualizationRadius());
+		Assert.assertEquals(25, config.getDeviceVisualizationRadius());
 	}
 
 	@Test

+ 1 - 1
src/test/resources/control/testCompilation/project1/MQTT_protocolProject1.javaTest

@@ -93,7 +93,7 @@ public class MQTT_protocolProject1 implements Protocol {
 	}
 	
 	@Override
-	public Collection<Packet> generateNextPakets(Port port, long timestep, boolean packetLost) {
+	public Collection<Packet> generateNextPackets(Port port, long timestep, boolean packetLost) {
 		/**
 		 * Packets which will be generated
 		 */