Adding range-based detection (improved the results for Nest Thermostat and Arlo Camera.
[pingpong.git] / Code / Projects / PacketLevelSignatureExtractor / src / main / java / edu / uci / iotproject / detection / layer3 / SignatureDetector.java
index 340310d8a6849379020c62655b702d9a5e22b70e..6e5b87ccebc3ca853a54ea4ee481ef9d3e2d451f 100644 (file)
@@ -5,6 +5,7 @@ import edu.uci.iotproject.analysis.UserAction;
 import edu.uci.iotproject.detection.AbstractClusterMatcher;
 import edu.uci.iotproject.detection.ClusterMatcherObserver;
 import edu.uci.iotproject.io.PcapHandleReader;
+import edu.uci.iotproject.util.PcapPacketUtils;
 import edu.uci.iotproject.util.PrintUtils;
 import org.apache.commons.math3.distribution.AbstractRealDistribution;
 import org.apache.commons.math3.distribution.NormalDistribution;
@@ -118,7 +119,7 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver
 
         // TODO: The following are tests for signatures against training data
 
-        // D-Link Plug experiment
+        // TODO: D-LINK PLUG experiment
 //        final String inputPcapFile = path + "/training/dlink-plug/wlan1/dlink-plug.wlan1.local.pcap";
         // D-Link Plug DEVICE signatures
 //        final String onSignatureFile = path + "/training/dlink-plug/signatures/dlink-plug-onSignature-device-side.sig";
@@ -135,12 +136,16 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver
 //        // D-Link Plug DEVICE signatures
 //        final String onSignatureFile = path + "/experimental_result/standalone/dlink-plug/signatures/dlink-plug-onSignature-device-side.sig";
 //        final String offSignatureFile = path + "/experimental_result/standalone/dlink-plug/signatures/dlink-plug-offSignature-device-side.sig";
+//        final String onClusterAnalysisFile = path + "/experimental_result/standalone/dlink-plug/analysis/dlink-plug-onClusters-device-side.cls";
+//        final String offClusterAnalysisFile = path + "/experimental_result/standalone/dlink-plug/analysis/dlink-plug-offClusters-device-side.cls";
         // D-Link Plug PHONE signatures
 //        final String onSignatureFile = path + "/experimental_result/standalone/dlink-plug/signatures/dlink-plug-onSignature-phone-side.sig";
 //        final String offSignatureFile = path + "/experimental_result/standalone/dlink-plug/signatures/dlink-plug-offSignature-phone-side.sig";
+//        final String onClusterAnalysisFile = path + "/experimental_result/standalone/dlink-plug/analysis/dlink-plug-onClusters-phone-side.cls";
+//        final String offClusterAnalysisFile = path + "/experimental_result/standalone/dlink-plug/analysis/dlink-plug-offClusters-phone-side.cls";
 
         // TODO: EXPERIMENT - November 9, 2018
-        // D-Link Siren experiment
+        // TODO: D-LINK SIREN experiment
         //final String inputPcapFile = path + "/experimental_result/standalone/dlink-siren/wlan1/dlink-siren.wlan1.local.pcap";
         //final String inputPcapFile = path + "/experimental_result/smarthome/dlink-siren/wlan1/dlink-siren.wlan1.detection.pcap";
 //        final String inputPcapFile = path + "/experimental_result/smarthome/dlink-siren/eth0/dlink-siren.eth0.detection.pcap";
@@ -153,8 +158,10 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver
 //        final String offSignatureFile = path + "/experimental_result/standalone/dlink-siren/signatures/dlink-siren-offSignature-phone-side.sig";
 //        final String onSignatureFile = path + "/training/signatures/dlink-siren/dlink-siren-onSignature-phone-side.sig";
 //        final String offSignatureFile = path + "/training/signatures/dlink-siren/dlink-siren-offSignature-phone-side.sig";
+//        final String onClusterAnalysisFile = path + "/experimental_result/standalone/dlink-siren/analysis/dlink-siren-onClusters-phone-side.cls";
+//        final String offClusterAnalysisFile = path + "/experimental_result/standalone/dlink-siren/analysis/dlink-siren-offClusters-phone-side.cls";
 
-        // TP-Link Plug experiment
+        // TODO: TP-LINK PLUG experiment
 ////        final String inputPcapFile = path + "/training/tplink-plug/wlan1/tplink-plug.wlan1.local.pcap";
 ////        final String inputPcapFile = path + "/experimental_result/wifi-Sniffer/tests2/airtool_2019-01-04_11.08.45.AM.pcap";
 //        final String inputPcapFile = path + "/experimental_result/wifi-Sniffer/tests2/command-frames-only.pcap";
@@ -166,33 +173,18 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver
 //        final String inputPcapFile = path + "/experimental_result/standalone/tplink-plug/wlan1/tplink-plug.wlan1.local.pcap";
 ////        final String inputPcapFile = path + "/experimental_result/standalone/tplink-plug/eth0/tplink-plug.eth0.local.pcap";
 ////        final String inputPcapFile = path + "/experimental_result/smarthome/tplink-plug/wlan1/tplink-plug.wlan1.detection.pcap";
-//        //final String inputPcapFile = path + "/experimental_result/smarthome/tplink-plug/eth0/tplink-plug.eth0.detection.pcap";
-//        // TP-Link Plug DEVICE signatures
+//        final String inputPcapFile = path + "/experimental_result/smarthome/tplink-plug/eth0/tplink-plug.eth0.detection.pcap";
+////        // TP-Link Plug DEVICE signatures
 ////        final String onSignatureFile = path + "/experimental_result/standalone/tplink-plug/signatures/tplink-plug-onSignature-device-side.sig";
 ////        final String offSignatureFile = path + "/experimental_result/standalone/tplink-plug/signatures/tplink-plug-offSignature-device-side.sig";
 //        final String onSignatureFile = path + "/experimental_result/standalone/tplink-plug/signatures/tplink-plug-onSignature-device-side-outbound.sig";
 //        final String offSignatureFile = path + "/experimental_result/standalone/tplink-plug/signatures/tplink-plug-offSignature-device-side-outbound.sig";
-        // TP-Link Plug PHONE signatures
-//        final String onSignatureFile = path + "/experimental_result/standalone/tplink-plug/signatures/tplink-plug-onSignature-phone-side.sig";
-//        final String offSignatureFile = path + "/experimental_result/standalone/tplink-plug/signatures/tplink-plug-offSignature-phone-side.sig";
-
-        // Arlo camera experiment
-//        final String inputPcapFile = path + "/training/arlo-camera/wlan1/arlo-camera.wlan1.local.pcap";
-////        // TP-Link Plug DEVICE signatures
-//        final String onSignatureFile = path + "/training/arlo-camera/signatures/arlo-camera-onSignature-phone-side.sig";
-//        final String offSignatureFile = path + "/training/arlo-camera/signatures/arlo-camera-offSignature-phone-side.sig";
-        // TODO: EXPERIMENT - November 13, 2018
-        // Arlo Camera experiment
-//        final String inputPcapFile = path + "/experimental_result/standalone/arlo-camera/wlan1/arlo-camera.wlan1.local.pcap";
-//        final String inputPcapFile = path + "/experimental_result/standalone/arlo-camera/eth0/arlo-camera.eth0.local.pcap";
-//        final String inputPcapFile = path + "/experimental_result/smarthome/arlo-camera/wlan1/arlo-camera.wlan1.detection.pcap";
-////        final String inputPcapFile = path + "/experimental_result/smarthome/arlo-camera/eth0/arlo-camera.eth0.detection.pcap";
-////        final String inputPcapFile = path + "/training/arlo-camera/eth0/arlo-camera.eth0.local.pcap";
-//        // Arlo Camera PHONE signatures
-////        final String onSignatureFile = path + "/experimental_result/standalone/arlo-camera/signatures/arlo-camera-onSignature-phone-side.sig";
-////        final String offSignatureFile = path + "/experimental_result/standalone/arlo-camera/signatures/arlo-camera-offSignature-phone-side.sig";
-//        final String onSignatureFile = path + "/experimental_result/standalone/arlo-camera/signatures/arlo-camera-onSignature-phone-side.sig.complete";
-//        final String offSignatureFile = path + "/experimental_result/standalone/arlo-camera/signatures/arlo-camera-offSignature-phone-side.sig.complete";
+//        // TP-Link Plug PHONE signatures
+////        final String onSignatureFile = path + "/experimental_result/standalone/tplink-plug/signatures/tplink-plug-onSignature-phone-side.sig";
+////        final String offSignatureFile = path + "/experimental_result/standalone/tplink-plug/signatures/tplink-plug-offSignature-phone-side.sig";
+//        // TP-Link Plug cluster analyses
+//        final String onClusterAnalysisFile = path + "/experimental_result/standalone/tplink-plug/analysis/tplink-plug-onClusters.cls";
+//        final String offClusterAnalysisFile = path + "/experimental_result/standalone/tplink-plug/analysis/tplink-plug-offClusters.cls";
 
         // Amazon Alexa experiment
 //        final String inputPcapFile = path + "/training/amazon-alexa/wlan1/alexa2.wlan1.local.pcap";
@@ -200,7 +192,25 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver
 //        final String onSignatureFile = path + "/training/amazon-alexa/signatures/amazon-alexa-onSignature-device-side.sig";
 //        final String offSignatureFile = path + "/training/amazon-alexa/signatures/amazon-alexa-offSignature-device-side.sig";
 
-        // SmartThings Plug experiment
+        // TODO: KWIKSET DOORLOCK Sep 12 experiment
+//        final String inputPcapFile = path + "/2018-08/kwikset-doorlock/kwikset3.wlan1.local.pcap";
+//        // Kwikset Doorlock PHONE signatures
+//        final String onSignatureFile = path + "/2018-08/kwikset-doorlock/onSignature-Kwikset-Doorlock-phone.sig";
+//        final String offSignatureFile = path + "/2018-08/kwikset-doorlock/offSignature-Kwikset-Doorlock-phone.sig";
+        // TODO: EXPERIMENT - November 10, 2018
+        // Kwikset Door lock experiment
+//        final String inputPcapFile = path + "/experimental_result/standalone/kwikset-doorlock/wlan1/kwikset-doorlock.wlan1.local.pcap";
+        //final String inputPcapFile = path + "/experimental_result/smarthome/kwikset-doorlock/wlan1/kwikset-doorlock.wlan1.detection.pcap";
+//        final String inputPcapFile = path + "/experimental_result/smarthome/kwikset-doorlock/eth0/kwikset-doorlock.eth0.detection.pcap";
+//        // Kwikset Door lock PHONE signatures
+//        final String onSignatureFile = path + "/experimental_result/standalone/kwikset-doorlock/signatures/kwikset-doorlock-onSignature-phone-side.sig";
+//        final String offSignatureFile = path + "/experimental_result/standalone/kwikset-doorlock/signatures/kwikset-doorlock-offSignature-phone-side.sig";
+////        final String onSignatureFile = path + "/training/signatures/kwikset-doorlock/kwikset-doorlock-onSignature-phone-side.sig";
+////        final String offSignatureFile = path + "/training/signatures/kwikset-doorlock/kwikset-doorlock-offSignature-phone-side.sig";
+//        final String onClusterAnalysisFile = path + "/experimental_result/standalone/kwikset-doorlock/analysis/kwikset-doorlock-onClusters-phone-side.cls";
+//        final String offClusterAnalysisFile = path + "/experimental_result/standalone/kwikset-doorlock/analysis/kwikset-doorlock-offClusters-phone-side.cls";
+
+        // TODO: SMARTTHINGS PLUG experiment
 //        final String inputPcapFile = path + "/training/st-plug/wlan1/st-plug.wlan1.local.pcap";
 //        // SmartThings Plug DEVICE signatures
 //        //final String onSignatureFile = path + "/training/st-plug/signatures/st-plug-onSignature-device-side.sig";
@@ -213,24 +223,78 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver
 //        final String inputPcapFile = path + "/experimental_result/standalone/st-plug/wlan1/st-plug.wlan1.local.pcap";
 //        final String inputPcapFile = path + "/experimental_result/standalone/st-plug/eth0/st-plug.eth0.local.pcap";
 //        //final String inputPcapFile = path + "/experimental_result/smarthome/st-plug/wlan1/st-plug.wlan1.detection.pcap";
-        final String inputPcapFile = path + "/experimental_result/smarthome/st-plug/eth0/st-plug.eth0.detection.pcap";
-//        // SmartThings Plug PHONE signatures
-        final String onSignatureFile = path + "/experimental_result/standalone/st-plug/signatures/st-plug-onSignature-phone-side.sig";
-        final String offSignatureFile = path + "/experimental_result/standalone/st-plug/signatures/st-plug-offSignature-phone-side.sig";
+//        final String inputPcapFile = path + "/experimental_result/smarthome/st-plug/eth0/st-plug.eth0.detection.pcap";
+////        // SmartThings Plug PHONE signatures
+//        final String onSignatureFile = path + "/experimental_result/standalone/st-plug/signatures/st-plug-onSignature-phone-side.sig";
+//        final String offSignatureFile = path + "/experimental_result/standalone/st-plug/signatures/st-plug-offSignature-phone-side.sig";
 //        final String onSignatureFile = path + "/training/signatures/st-plug/st-plug-onSignature-phone-side.sig";
 //        final String offSignatureFile = path + "/training/signatures/st-plug/st-plug-offSignature-phone-side.sig";
+//        final String onClusterAnalysisFile = path + "/experimental_result/standalone/st-plug/analysis/st-plug-onClusters-phone-side.cls";
+//        final String offClusterAnalysisFile = path + "/experimental_result/standalone/st-plug/analysis/st-plug-offClusters-phone-side.cls";
+
+        // TODO: ARLO CAMERA experiment
+//        final String inputPcapFile = path + "/training/arlo-camera/wlan1/arlo-camera.wlan1.local.pcap";
+////        // TP-Link Plug DEVICE signatures
+//        final String onSignatureFile = path + "/training/arlo-camera/signatures/arlo-camera-onSignature-phone-side.sig";
+//        final String offSignatureFile = path + "/training/arlo-camera/signatures/arlo-camera-offSignature-phone-side.sig";
+        // TODO: EXPERIMENT - November 13, 2018
+        // Arlo Camera experiment
+//        final String inputPcapFile = path + "/experimental_result/standalone/arlo-camera/wlan1/arlo-camera.wlan1.local.pcap";
+//        final String inputPcapFile = path + "/experimental_result/standalone/arlo-camera/eth0/arlo-camera.eth0.local.pcap";
+//        final String inputPcapFile = path + "/experimental_result/smarthome/arlo-camera/wlan1/arlo-camera.wlan1.detection.pcap";
+        final String inputPcapFile = path + "/experimental_result/smarthome/arlo-camera/eth0/arlo-camera.eth0.detection.pcap";
+//        final String inputPcapFile = path + "/training/arlo-camera/eth0/arlo-camera.eth0.local.pcap";
+        // Arlo Camera PHONE signatures
+//        final String onSignatureFile = path + "/experimental_result/standalone/arlo-camera/signatures/arlo-camera-onSignature-phone-side.sig";
+//        final String offSignatureFile = path + "/experimental_result/standalone/arlo-camera/signatures/arlo-camera-offSignature-phone-side.sig";
+        final String onSignatureFile = path + "/experimental_result/standalone/arlo-camera/signatures/arlo-camera-onSignature-phone-side.sig.complete";
+        final String offSignatureFile = path + "/experimental_result/standalone/arlo-camera/signatures/arlo-camera-offSignature-phone-side.sig.complete";
+        final String onClusterAnalysisFile = path + "/experimental_result/standalone/arlo-camera/analysis/arlo-camera-onClusters-phone-side.cls";
+        final String offClusterAnalysisFile = path + "/experimental_result/standalone/arlo-camera/analysis/arlo-camera-offClusters-phone-side.cls";
+
+        // TODO: NEST THERMOSTAT experiment
+//        final String inputPcapFile = path + "/training/nest-thermostat/wlan1/nest-thermostat.wlan1.local.pcap";
+//        // Nest Thermostat DEVICE signatures
+////        final String onSignatureFile = path + "/training/nest-thermostat/signatures/nest-thermostat-onSignature-device-side.sig";
+////        final String offSignatureFile = path + "/training/nest-thermostat/signatures/nest-thermostat-offSignature-device-side.sig";
+//        // Nest Thermostat PHONE signatures
+//        final String onSignatureFile = path + "/training/nest-thermostat/signatures/nest-thermostat-onSignature-phone-side.sig";
+//        final String offSignatureFile = path + "/training/nest-thermostat/signatures/nest-thermostat-offSignature-phone-side.sig";
+//        // TODO: EXPERIMENT - November 15, 2018
+        // Nest Thermostat experiment
+//        final String inputPcapFile = path + "/experimental_result/standalone/nest-thermostat/wlan1/nest-thermostat.wlan1.local.pcap";
+//        final String inputPcapFile = path + "/experimental_result/standalone/nest-thermostat/eth0/nest-thermostat.eth0.local.pcap";
+//        final String inputPcapFile = path + "/experimental_result/smarthome/nest-thermostat/wlan1/nest-thermostat.wlan1.detection.pcap";
+//        final String inputPcapFile = path + "/experimental_result/smarthome/nest-thermostat/eth0/nest-thermostat.eth0.detection.pcap";
+////        // Nest Thermostat PHONE signatures
+//        final String onSignatureFile = path + "/experimental_result/standalone/nest-thermostat/signatures/nest-thermostat-onSignature-phone-side.sig";
+//        final String offSignatureFile = path + "/experimental_result/standalone/nest-thermostat/signatures/nest-thermostat-offSignature-phone-side.sig";
+//        final String onClusterAnalysisFile = path + "/experimental_result/standalone/nest-thermostat/analysis/nest-thermostat-onClusters-phone-side.cls";
+//        final String offClusterAnalysisFile = path + "/experimental_result/standalone/nest-thermostat/analysis/nest-thermostat-offClusters-phone-side.cls";
 
         // TODO: EXPERIMENT - January 9, 2018
+        // TODO: BLOSSOM SPRINKLER experiment
         // Blossom Sprinkler experiment
+//        //final String inputPcapFile = path + "/training/blossom-sprinkler/wlan1/blossom-sprinkler.wlan1.local.pcap";
+//        final String inputPcapFile = path + "/2018-08/blossom/blossom.wlan1.local.pcap";
+//        //final String inputPcapFile = path + "/training/blossom-sprinkler/eth0/blossom-sprinkler.eth0.local.pcap";
+//        // Blossom Sprinkler DEVICE signatures
+//        final String onSignatureFile = path + "/training/blossom-sprinkler/signatures/blossom-sprinkler-onSignature-device-side.sig";
+//        final String offSignatureFile = path + "/training/blossom-sprinkler/signatures/blossom-sprinkler-offSignature-device-side.sig";
+
 ////        final String inputPcapFile = path + "/experimental_result/standalone/blossom-sprinkler/wlan1/blossom-sprinkler.wlan1.local.pcap";
 //        final String inputPcapFile = path + "/experimental_result/smarthome/blossom-sprinkler/eth0/blossom-sprinkler.eth0.detection.pcap";
 ////        final String inputPcapFile = path + "/experimental_result/smarthome/blossom-sprinkler/wlan1/blossom-sprinkler.wlan1.detection.pcap";
 //        // Blossom Sprinkler DEVICE signatures
-//        final String onSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-onSignature-device-side.sig";
-//        final String offSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-offSignature-device-side.sig";
+////        final String onSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-onSignature-device-side.sig";
+////        final String offSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-offSignature-device-side.sig";
+////        final String onClusterAnalysisFile = path + "/experimental_result/standalone/blossom-sprinkler/analysis/blossom-sprinkler-onClusters-device-side.cls";
+////        final String offClusterAnalysisFile = path + "/experimental_result/standalone/blossom-sprinkler/analysis/blossom-sprinkler-offClusters-device-side.cls";
 //        // Blossom Sprinkler PHONE signatures
-////        final String onSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-onSignature-phone-side.sig";
-////        final String offSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-offSignature-phone-side.sig";
+//        final String onSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-onSignature-phone-side.sig";
+//        final String offSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-offSignature-phone-side.sig";
+//        final String onClusterAnalysisFile = path + "/experimental_result/standalone/blossom-sprinkler/analysis/blossom-sprinkler-onClusters-phone-side.cls";
+//        final String offClusterAnalysisFile = path + "/experimental_result/standalone/blossom-sprinkler/analysis/blossom-sprinkler-offClusters-phone-side.cls";
 
         // LiFX Bulb experiment
 //        final String inputPcapFile = path + "/training/lifx-bulb/wlan1/lifx-bulb.wlan1.local.pcap";
@@ -241,32 +305,6 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver
 //        final String onSignatureFile = path + "/training/lifx-bulb/signatures/lifx-bulb-onSignature-phone-side.sig";
 //        final String offSignatureFile = path + "/training/lifx-bulb/signatures/lifx-bulb-offSignature-phone-side.sig";
 
-        // Blossom Sprinkler experiment
-//        //final String inputPcapFile = path + "/training/blossom-sprinkler/wlan1/blossom-sprinkler.wlan1.local.pcap";
-//        final String inputPcapFile = path + "/2018-08/blossom/blossom.wlan1.local.pcap";
-//        //final String inputPcapFile = path + "/training/blossom-sprinkler/eth0/blossom-sprinkler.eth0.local.pcap";
-//        // Blossom Sprinkler DEVICE signatures
-//        final String onSignatureFile = path + "/training/blossom-sprinkler/signatures/blossom-sprinkler-onSignature-device-side.sig";
-//        final String offSignatureFile = path + "/training/blossom-sprinkler/signatures/blossom-sprinkler-offSignature-device-side.sig";
-
-        // Nest Thermostat experiment
-//        final String inputPcapFile = path + "/training/nest-thermostat/wlan1/nest-thermostat.wlan1.local.pcap";
-//        // Nest Thermostat DEVICE signatures
-////        final String onSignatureFile = path + "/training/nest-thermostat/signatures/nest-thermostat-onSignature-device-side.sig";
-////        final String offSignatureFile = path + "/training/nest-thermostat/signatures/nest-thermostat-offSignature-device-side.sig";
-//        // Nest Thermostat PHONE signatures
-//        final String onSignatureFile = path + "/training/nest-thermostat/signatures/nest-thermostat-onSignature-phone-side.sig";
-//        final String offSignatureFile = path + "/training/nest-thermostat/signatures/nest-thermostat-offSignature-phone-side.sig";
-//        // TODO: EXPERIMENT - November 15, 2018
-        // Nest Thermostat experiment
-//        final String inputPcapFile = path + "/experimental_result/standalone/nest-thermostat/wlan1/nest-thermostat.wlan1.local.pcap";
-////        final String inputPcapFile = path + "/experimental_result/standalone/nest-thermostat/eth0/nest-thermostat.eth0.local.pcap";
-////        final String inputPcapFile = path + "/experimental_result/smarthome/nest-thermostat/wlan1/nest-thermostat.wlan1.detection.pcap";
-////        final String inputPcapFile = path + "/experimental_result/smarthome/nest-thermostat/eth0/nest-thermostat.eth0.detection.pcap";
-////        // Nest Thermostat PHONE signatures
-//        final String onSignatureFile = path + "/experimental_result/standalone/nest-thermostat/signatures/nest-thermostat-onSignature-phone-side.sig";
-//        final String offSignatureFile = path + "/experimental_result/standalone/nest-thermostat/signatures/nest-thermostat-offSignature-phone-side.sig";
-
         /*
         // Hue Bulb experiment
         final String inputPcapFile = path + "/training/hue-bulb/wlan1/hue-bulb.wlan1.local.pcap";
@@ -275,9 +313,7 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver
         final String offSignatureFile = path + "/training/hue-bulb/signatures/hue-bulb-offSignature-phone-side.sig";
         */
 
-
-
-        // TP-Link Bulb experiment
+        // TODO: TP-LINK BULB experiment
 //        final String inputPcapFile = path + "/training/tplink-bulb/wlan1/tplink-bulb.wlan1.local.pcap";
 //        // TP-Link Bulb PHONE signatures
 //        final String onSignatureFile = path + "/training/tplink-bulb/signatures/tplink-bulb-onSignature-phone-side.sig";
@@ -291,16 +327,11 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver
 //        // TP-Link Bulb PHONE signatures
 //        final String onSignatureFile = path + "/experimental_result/standalone/tplink-bulb/signatures/tplink-bulb-onSignature-phone-side.sig";
 //        final String offSignatureFile = path + "/experimental_result/standalone/tplink-bulb/signatures/tplink-bulb-offSignature-phone-side.sig";
+//        final String onClusterAnalysisFile = path + "/experimental_result/standalone/tplink-bulb/analysis/tplink-bulb-onClusters-phone-side.cls";
+//        final String offClusterAnalysisFile = path + "/experimental_result/standalone/tplink-bulb/analysis/tplink-bulb-offClusters-phone-side.cls";
 
-        /*
-        // WeMo Plug experiment
-        final String inputPcapFile = path + "/training/wemo-plug/wlan1/wemo-plug.wlan1.local.pcap";
-        // WeMo Plug PHONE signatures
-        final String onSignatureFile = path + "/training/wemo-plug/signatures/wemo-plug-onSignature-device-side.sig";
-        final String offSignatureFile = path + "/training/wemo-plug/signatures/wemo-plug-offSignature-device-side.sig";
-        */
         // TODO: EXPERIMENT - November 20, 2018
-        // WeMo Plug experiment
+        // TODO: WEMO PLUG experiment
 //        final String inputPcapFile = path + "/experimental_result/standalone/wemo-plug/wlan1/wemo-plug.wlan1.local.pcap";
 //        final String inputPcapFile = path + "/experimental_result/standalone/wemo-plug/eth0/wemo-plug.eth0.local.pcap";
         // TODO: WE HAVE 4 ADDITIONAL EVENTS (TRIGGERED MANUALLY), SO WE JUST IGNORE THEM BECAUSE THEY HAPPENED BEFORE
@@ -310,16 +341,11 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver
 //        // WeMo Plug PHONE signatures
 //        final String onSignatureFile = path + "/experimental_result/standalone/wemo-plug/signatures/wemo-plug-onSignature-phone-side.sig";
 //        final String offSignatureFile = path + "/experimental_result/standalone/wemo-plug/signatures/wemo-plug-offSignature-phone-side.sig";
+//        final String onClusterAnalysisFile = path + "/experimental_result/standalone/wemo-plug/analysis/wemo-plug-onClusters-phone-side.cls";
+//        final String offClusterAnalysisFile = path + "/experimental_result/standalone/wemo-plug/analysis/wemo-plug-offClusters-phone-side.cls";
 
-        /*
-        // WeMo Insight Plug experiment
-        final String inputPcapFile = path + "/training/wemo-insight-plug/wlan1/wemo-insight-plug.wlan1.local.pcap";
-        // WeMo Insight Plug PHONE signatures
-        final String onSignatureFile = path + "/training/wemo-insight-plug/signatures/wemo-insight-plug-onSignature-device-side.sig";
-        final String offSignatureFile = path + "/training/wemo-insight-plug/signatures/wemo-insight-plug-offSignature-device-side.sig";
-        */
         // TODO: EXPERIMENT - November 21, 2018
-        // WeMo Insight Plug experiment
+        // TODO: WEMO INSIGHT Plug experiment
 //        final String inputPcapFile = path + "/experimental_result/standalone/wemo-insight-plug/wlan1/wemo-insight-plug.wlan1.local.pcap";
 //        final String inputPcapFile = path + "/experimental_result/standalone/wemo-insight-plug/eth0/wemo-insight-plug.eth0.local.pcap";
         // TODO: WE HAVE 1 ADDITIONAL EVENT (FROM WEMO PLUG)
@@ -328,25 +354,22 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver
         // WeMo Insight Plug PHONE signatures
 //        final String onSignatureFile = path + "/experimental_result/standalone/wemo-insight-plug/signatures/wemo-insight-plug-onSignature-phone-side.sig";
 //        final String offSignatureFile = path + "/experimental_result/standalone/wemo-insight-plug/signatures/wemo-insight-plug-offSignature-phone-side.sig";
+//        final String onClusterAnalysisFile = path + "/experimental_result/standalone/wemo-insight-plug/analysis/wemo-insight-plug-onClusters-phone-side.cls";
+//        final String offClusterAnalysisFile = path + "/experimental_result/standalone/wemo-insight-plug/analysis/wemo-insight-plug-offClusters-phone-side.cls";
 
 
-        // Kwikset Doorlock Sep 12 experiment
-//        final String inputPcapFile = path + "/2018-08/kwikset-doorlock/kwikset3.wlan1.local.pcap";
-//        // Kwikset Doorlock PHONE signatures
-//        final String onSignatureFile = path + "/2018-08/kwikset-doorlock/onSignature-Kwikset-Doorlock-phone.sig";
-//        final String offSignatureFile = path + "/2018-08/kwikset-doorlock/offSignature-Kwikset-Doorlock-phone.sig";
-        // TODO: EXPERIMENT - November 10, 2018
-        // Kwikset Door lock experiment
-//        final String inputPcapFile = path + "/experimental_result/standalone/kwikset-doorlock/wlan1/kwikset-doorlock.wlan1.local.pcap";
-        //final String inputPcapFile = path + "/experimental_result/smarthome/kwikset-doorlock/wlan1/kwikset-doorlock.wlan1.detection.pcap";
-//        final String inputPcapFile = path + "/experimental_result/smarthome/kwikset-doorlock/eth0/kwikset-doorlock.eth0.detection.pcap";
-//        // Kwikset Door lock PHONE signatures
-//        final String onSignatureFile = path + "/experimental_result/standalone/kwikset-doorlock/signatures/kwikset-doorlock-onSignature-phone-side.sig";
-//        final String offSignatureFile = path + "/experimental_result/standalone/kwikset-doorlock/signatures/kwikset-doorlock-offSignature-phone-side.sig";
-////        final String onSignatureFile = path + "/training/signatures/kwikset-doorlock/kwikset-doorlock-onSignature-phone-side.sig";
-////        final String offSignatureFile = path + "/training/signatures/kwikset-doorlock/kwikset-doorlock-offSignature-phone-side.sig";
-
-
+        /*
+        // WeMo Plug experiment
+        final String inputPcapFile = path + "/training/wemo-plug/wlan1/wemo-plug.wlan1.local.pcap";
+        // WeMo Plug PHONE signatures
+        final String onSignatureFile = path + "/training/wemo-plug/signatures/wemo-plug-onSignature-device-side.sig";
+        final String offSignatureFile = path + "/training/wemo-plug/signatures/wemo-plug-offSignature-device-side.sig";
+        // WeMo Insight Plug experiment
+        final String inputPcapFile = path + "/training/wemo-insight-plug/wlan1/wemo-insight-plug.wlan1.local.pcap";
+        // WeMo Insight Plug PHONE signatures
+        final String onSignatureFile = path + "/training/wemo-insight-plug/signatures/wemo-insight-plug-onSignature-device-side.sig";
+        final String offSignatureFile = path + "/training/wemo-insight-plug/signatures/wemo-insight-plug-offSignature-device-side.sig";
+        */
 
         // D-Link Siren experiment
 //        final String inputPcapFile = path + "/2018-08/dlink-siren/dlink-siren.wlan1.local.pcap";
@@ -363,27 +386,36 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver
         System.out.println("OFF signature file in use is " + offSignatureFile);
         System.out.println("PCAP file that is the target of detection is " + inputPcapFile);
 
-        List<List<List<PcapPacket>>> onSignature = PrintUtils.deserializeSignatureFromFile(onSignatureFile);
-        List<List<List<PcapPacket>>> offSignature = PrintUtils.deserializeSignatureFromFile(offSignatureFile);
+        // Specify epsilon
+        // TODO: This would be specified through command line option
+        double eps = 10.0;
+        // Load signatures
+        List<List<List<PcapPacket>>> onSignature = PrintUtils.deserializeFromFile(onSignatureFile);
+        List<List<List<PcapPacket>>> offSignature = PrintUtils.deserializeFromFile(offSignatureFile);
+        // Load signature analyses
+        List<List<List<PcapPacket>>> onClusterAnalysis = PrintUtils.deserializeFromFile(onClusterAnalysisFile);
+        List<List<List<PcapPacket>>> offClusterAnalysis = PrintUtils.deserializeFromFile(offClusterAnalysisFile);
+
+        // TODO: FOR NOW WE DECIDE PER SIGNATURE AND THEN WE OR THE BOOLEANS
+        // TODO: SINCE WE ONLY HAVE 2 SIGNATURES FOR NOW (ON AND OFF), THEN IT IS USUALLY EITHER RANGE-BASED OR
+        // TODO: STRICT MATCHING
+        // Check if we should use range-based matching
+        boolean isRangeBasedForOn = PcapPacketUtils.isRangeBasedMatching(onSignature, eps, offSignature);
+        boolean isRangeBasedForOff = PcapPacketUtils.isRangeBasedMatching(offSignature, eps, onSignature);
+        // Update the signature with ranges if it is range-based
+        if (isRangeBasedForOn && isRangeBasedForOff) {
+            onSignature = PcapPacketUtils.useRangeBasedMatching(onSignature, onClusterAnalysis);
+            offSignature = PcapPacketUtils.useRangeBasedMatching(offSignature, offClusterAnalysis);
+        }
 
         // LAN
 //        SignatureDetector onDetector = new SignatureDetector(onSignature, null);
 //        SignatureDetector offDetector = new SignatureDetector(offSignature, null);
-
-        // TODO: We need the array that contains other signatures so that we can check for overlap and decide
-        // TODO: whether we use conservative or range-based matching
-        // Right now we have ON signature as other signature for OFF and OFF signature as other signature for ON
-        // In the future, we might have more other signatures
-        List<List<List<List<PcapPacket>>>> otherSignaturesOutsideOn = new ArrayList<>();
-        otherSignaturesOutsideOn.add(offSignature);
-        List<List<List<List<PcapPacket>>>> otherSignaturesOutsideOff = new ArrayList<>();
-        otherSignaturesOutsideOff.add(onSignature);
-
         // WAN
-        SignatureDetector onDetector = new SignatureDetector(onSignature, "128.195.205.105", 0,
-                otherSignaturesOutsideOn);
-        SignatureDetector offDetector = new SignatureDetector(offSignature, "128.195.205.105", 0,
-                otherSignaturesOutsideOff);
+        SignatureDetector onDetector = new SignatureDetector(onSignature, "128.195.205.105",
+                0, isRangeBasedForOn, eps);
+        SignatureDetector offDetector = new SignatureDetector(offSignature, "128.195.205.105",
+                0, isRangeBasedForOff, eps);
 
         final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).
                 withLocale(Locale.US).withZone(ZoneId.of("America/Los_Angeles"));
@@ -428,16 +460,14 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver
         PcapHandleReader reader = new PcapHandleReader(handle, p -> true, onDetector, offDetector);
         reader.readFromHandle();
 
-        //if (onDetector.isConservativeChecking(offSignature)) {
-        // System.out.println("Do conservative checking!");
-        //} else {
-        // TODO: WORK ON THIS RANGE-BASED CHECKING
-        // System.out.println("Do range-based checking!");
-        //}
-
         // TODO: need a better way of triggering detection than this...
-        onDetector.mClusterMatchers.forEach(cm -> cm.performDetection());
-        offDetector.mClusterMatchers.forEach(cm -> cm.performDetection());
+        if (isRangeBasedForOn && isRangeBasedForOff) {
+            onDetector.mClusterMatchers.forEach(cm -> cm.performDetectionRangeBased());
+            offDetector.mClusterMatchers.forEach(cm -> cm.performDetectionRangeBased());
+        } else {
+            onDetector.mClusterMatchers.forEach(cm -> cm.performDetectionConservative());
+            offDetector.mClusterMatchers.forEach(cm -> cm.performDetectionConservative());
+        }
 
         // Sort the list of detected events by timestamp to make it easier to compare it line-by-line with the trigger
         // times file.
@@ -451,11 +481,9 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver
         System.out.println("Number of detected events of type " + UserAction.Type.TOGGLE_OFF + ": " +
                 detectedEvents.stream().filter(ua -> ua.getType() == UserAction.Type.TOGGLE_OFF).count());
 
-
         // TODO: Temporary clean up until we clean the pipeline
 //      List<UserAction> cleanedDetectedEvents = SignatureDetector.removeDuplicates(detectedEvents);
 //      cleanedDetectedEvents.forEach(outputter);
-
     }
 
     /**
@@ -511,136 +539,14 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver
         return listUserActionClean;
     }
 
-//    /**
-//     * Check if there is any overlap between the signature stored in this class and another signature.
-//     * Conditions:
-//     * 1) If both signatures do not have any range, then we need to do conservative checking (return true).
-//     * 2) If both signatures have the same number of packets/packet lengths, then we check the range; if the
-//     *    numbers of packets/packet lengths are different then we assume that there is no overlap.
-//     * 3) If there is any range in the signatures, then we need to check for overlap.
-//     * 4) If there is overlap for every packet/packet length, then we return false (range-based checking); otherwise,
-//     *    true (conservative checking).
-//     *
-//     * @param otherSignature A {@code List} of {@code List} of {@code List} of {@code PcapPacket} objects to be checked
-//     *                       for overlaps with the signature stored in this class.
-//     * @return A boolean that is true if there is an overlap; false otherwise.
-//     */
-//    public boolean isConservativeChecking(List<List<List<PcapPacket>>> otherSignature) {
-//
-//        // Get the ranges of the two signatures
-//        List<List<List<PcapPacket>>> signatureRanges = getSequenceRanges(mSignature);
-//        List<List<List<PcapPacket>>> otherSignatureRanges = getSequenceRanges(otherSignature);
-//        if (!isRangeBased(signatureRanges) && !isRangeBased(otherSignatureRanges)) {
-//            // Conservative checking when there is no range
-//            return true;
-//        } else if(signatureRanges.size() != otherSignatureRanges.size()) {
-//            // The two signatures have different numbers of packets/packet lengths
-//            return false;
-//        } else {
-//            // There is range; check if there is overlap
-//            return checkOverlap(signatureRanges, otherSignatureRanges);
-//        }
-//    }
-//
-//    /*
-//     * Check for overlap since we have range in at least one of the signatures.
-//     * Overlap is only true when all ranges overlap. We need to check in order.
-//     */
-//    private boolean checkOverlap(List<List<List<PcapPacket>>> signatureRanges,
-//                                 List<List<List<PcapPacket>>> otherSignatureRanges) {
-//
-//        for(List<List<PcapPacket>> listListPcapPacket : signatureRanges) {
-//            // Lower bound of the range is in index 0
-//            // Upper bound of the range is in index 1
-//            int sequenceSetIndex = signatureRanges.indexOf(listListPcapPacket);
-//            List<PcapPacket> minSequenceSignature = listListPcapPacket.get(0);
-//            List<PcapPacket> maxSequenceSignature = listListPcapPacket.get(1);
-//            for(PcapPacket pcapPacket : minSequenceSignature) {
-//                // Get the lower and upper bounds of the current signature
-//                int packetIndex = minSequenceSignature.indexOf(pcapPacket);
-//                int lowerBound = pcapPacket.length();
-//                int upperBound = maxSequenceSignature.get(packetIndex).length();
-//                // Check for range overlap in the other signature!
-//                // Check the packet/packet length at the same position
-//                List<PcapPacket> minSequenceSignatureOther = otherSignatureRanges.get(sequenceSetIndex).get(0);
-//                List<PcapPacket> maxSequenceSignatureOther = otherSignatureRanges.get(sequenceSetIndex).get(1);
-//                int lowerBoundOther = minSequenceSignatureOther.get(packetIndex).length();
-//                int upperBoundOther = maxSequenceSignatureOther.get(packetIndex).length();
-//                if (!(lowerBoundOther <= lowerBound && lowerBound <= upperBoundOther) &&
-//                    !(lowerBoundOther <= upperBound && upperBound <= upperBoundOther)) {
-//                    return false;
-//                }
-//            }
-//        }
-//
-//        return true;
-//    }
-//
-//    /*
-//     * Check and see if there is any range in the signatures
-//     */
-//    private boolean isRangeBased(List<List<List<PcapPacket>>> signatureRanges) {
-//
-//        for(List<List<PcapPacket>> listListPcapPacket : signatureRanges) {
-//            // Lower bound of the range is in index 0
-//            // Upper bound of the range is in index 1
-//            List<PcapPacket> minSequence = listListPcapPacket.get(0);
-//            List<PcapPacket> maxSequence = listListPcapPacket.get(1);
-//            for(PcapPacket pcapPacket : minSequence) {
-//                int index = minSequence.indexOf(pcapPacket);
-//                if (pcapPacket.length() != maxSequence.get(index).length()) {
-//                    // If there is any packet length that differs in the minSequence
-//                    // and maxSequence, then it is range-based
-//                    return true;
-//                }
-//            }
-//        }
-//
-//        return false;
-//    }
-
-    /* Find the sequence with the minimum packet lengths.
-     * The second-layer list should contain the minimum sequence for element 0 and maximum sequence for element 1.
-     */
-    private List<List<List<PcapPacket>>> getSequenceRanges(List<List<List<PcapPacket>>> signature) {
-
-        // Start from the first index
-        List<List<List<PcapPacket>>> rangeBasedSequence = new ArrayList<>();
-        for(List<List<PcapPacket>> listListPcapPacket : signature) {
-            List<List<PcapPacket>> minMaxSequence = new ArrayList<>();
-            // Both searches start from index 0
-            List<PcapPacket> minSequence = new ArrayList<>(listListPcapPacket.get(0));
-            List<PcapPacket> maxSequence = new ArrayList<>(listListPcapPacket.get(0));
-            for(List<PcapPacket> listPcapPacket : listListPcapPacket) {
-                for(PcapPacket pcapPacket : listPcapPacket) {
-                    int index = listPcapPacket.indexOf(pcapPacket);
-                    // Set the new minimum if length at the index is minimum
-                    if (pcapPacket.length() < minSequence.get(index).length()) {
-                        minSequence.set(index, pcapPacket);
-                    }
-                    // Set the new maximum if length at the index is maximum
-                    if (pcapPacket.length() > maxSequence.get(index).length()) {
-                        maxSequence.set(index, pcapPacket);
-                    }
-                }
-            }
-            // minSequence as element 0 and maxSequence as element 1
-            minMaxSequence.add(minSequence);
-            minMaxSequence.add(maxSequence);
-            rangeBasedSequence.add(minMaxSequence);
-        }
-
-        return rangeBasedSequence;
-    }
-
-    public SignatureDetector(List<List<List<PcapPacket>>> searchedSignature, String routerWanIp, int inclusionTimeMillis,
-                             List<List<List<List<PcapPacket>>>> otherSignatures) {
+    public SignatureDetector(List<List<List<PcapPacket>>> searchedSignature, String routerWanIp,
+                             int inclusionTimeMillis, boolean isRangeBased, double eps) {
         // note: doesn't protect inner lists from changes :'(
         mSignature = Collections.unmodifiableList(searchedSignature);
         // Generate corresponding/appropriate ClusterMatchers based on the provided signature
         List<Layer3ClusterMatcher> clusterMatchers = new ArrayList<>();
         for (List<List<PcapPacket>> cluster : mSignature) {
-            clusterMatchers.add(new Layer3ClusterMatcher(cluster, routerWanIp, otherSignatures, this));
+            clusterMatchers.add(new Layer3ClusterMatcher(cluster, routerWanIp, isRangeBased, eps, this));
         }
         mClusterMatchers = Collections.unmodifiableList(clusterMatchers);