Resolving conflict.
authorrtrimana <rtrimana@uci.edu>
Mon, 17 Sep 2018 23:30:54 +0000 (16:30 -0700)
committerrtrimana <rtrimana@uci.edu>
Mon, 17 Sep 2018 23:30:54 +0000 (16:30 -0700)
1  2 
Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/Main.java

@@@ -8,6 -8,8 +8,8 @@@ import edu.uci.iotproject.comparison.se
  import edu.uci.iotproject.comparison.seqalignment.SequenceExtraction;
  import edu.uci.iotproject.io.TriggerTimesFileReader;
  import edu.uci.iotproject.util.PrintUtils;
+ import org.apache.commons.math3.stat.clustering.Cluster;
+ import org.apache.commons.math3.stat.clustering.DBSCANClusterer;
  import org.pcap4j.core.*;
  import org.pcap4j.packet.namednumber.DataLinkType;
  
@@@ -18,6 -20,8 +20,8 @@@ import java.net.UnknownHostException
  import java.time.Instant;
  import java.util.*;
  import java.util.concurrent.TimeoutException;
+ import java.util.stream.Collectors;
+ import java.util.stream.Stream;
  
  /**
   * This is a system that reads PCAP files to compare
@@@ -37,8 -41,8 +41,8 @@@ public class Main 
          // ------------ # Code for extracting traffic generated by a device within x seconds of a trigger # ------------
          // Paths to input and output files (consider supplying these as arguments instead) and IP of the device for
          // which traffic is to be extracted:
-         String path = "/scratch/July-2018"; // Rahmadi
//        String path = "/Users/varmarken/temp/UCI IoT Project/experiments"; // Janus
//        String path = "/scratch/July-2018"; // Rahmadi
+         String path = "/Users/varmarken/temp/UCI IoT Project/experiments"; // Janus
          boolean verbose = true;
          final String onPairsPath = "/scratch/July-2018/on.txt";
          final String offPairsPath = "/scratch/July-2018/off.txt";
  //        final String outputPcapFile = path + "/2018-08/kwikset-doorlock/kwikset-doorlock-processed.pcap";
  //        final String triggerTimesFile = path + "/2018-08/kwikset-doorlock/kwikset-doorlock-aug-6-2018.timestamps";
  //        final String deviceIp = "192.168.1.246"; // .246 == phone; .142 == SmartThings Hub (note: use eth0 capture for this!)
 +        // September 12, 2018 - includes both wlan1 and eth1 interfaces
 +        //final String inputPcapFile = path + "/2018-08/kwikset-doorlock/kwikset3.wlan1.local.pcap";
 +//        final String inputPcapFile = path + "/2018-08/kwikset-doorlock/kwikset3.eth1.local.pcap";
 +//        final String outputPcapFile = path + "/2018-08/kwikset-doorlock/kwikset3-processed.pcap";
 +//        final String triggerTimesFile = path + "/2018-08/kwikset-doorlock/kwikset-doorlock-sept-12-2018.timestamps";
 +//        final String deviceIp = "192.168.1.142"; // .246 == phone; .142 == SmartThings Hub (note: use eth0 capture for this!)
 +
          // 8) Hue Bulb August 7 experiment
  //        final String inputPcapFile = path + "/2018-08/hue-bulb/hue-bulb.wlan1.local.pcap";
  //        final String outputPcapFile = path + "/2018-08/hue-bulb/hue-bulb-processed.pcap";
  //        final String deviceIp = "192.168.1.246"; // .246 == phone; .229 == sprinkler
  
  //        // 13) DLink siren August 14 experiment
//        final String inputPcapFile = path + "/2018-08/dlink-siren/dlink-siren.wlan1.local.pcap";
//        final String outputPcapFile = path + "/2018-08/dlink-siren/dlink-siren-processed.pcap";
//        final String triggerTimesFile = path + "/2018-08/dlink-siren/dlink-siren-aug-14-2018.timestamps";
//        final String deviceIp = "192.168.1.183"; // .246 == phone; .183 == siren
+         final String inputPcapFile = path + "/2018-08/dlink-siren/dlink-siren.wlan1.local.pcap";
+         final String outputPcapFile = path + "/2018-08/dlink-siren/dlink-siren-processed.pcap";
+         final String triggerTimesFile = path + "/2018-08/dlink-siren/dlink-siren-aug-14-2018.timestamps";
+         final String deviceIp = "192.168.1.183"; // .246 == phone; .183 == siren
  
          // 14) Nest thermostat August 15 experiment
  //        final String inputPcapFile = path + "/2018-08/nest/nest.wlan1.local.pcap";
  //        final String triggerTimesFile = path + "/2018-08/alexa/alexa-aug-17-2018.timestamps";
  //        final String deviceIp = "192.168.1.225"; // .246 == phone; .225 == Alexa
  
-         final String inputPcapFile = path + "/2018-08/noise/noise.eth1.pcap";
-         final String outputPcapFile = path + "/2018-08/noise/noise-processed.pcap";
-         final String triggerTimesFile = path + "/2018-08/noise/noise-sept-17-2018.timestamps";
-         final String deviceIp = "192.168.1.142"; //  .142 == SmartThings Hub; .199 == dlink plug; .183 == siren
 +        // September 17
++//        final String inputPcapFile = path + "/2018-08/noise/noise.eth1.pcap";
++//        final String outputPcapFile = path + "/2018-08/noise/noise-processed.pcap";
++//        final String triggerTimesFile = path + "/2018-08/noise/noise-sept-17-2018.timestamps";
++//        final String deviceIp = "192.168.1.142"; //  .142 == SmartThings Hub; .199 == dlink plug; .183 == siren
 +
          TriggerTimesFileReader ttfr = new TriggerTimesFileReader();
          List<Instant> triggerTimes = ttfr.readTriggerTimes(triggerTimesFile, false);
          // Tag each trigger with "ON" or "OFF", assuming that the first trigger is an "ON" and that they alternate.
  
  
  
+         /*
+          * NOTE: no need to generate these more complex on/off maps that also contain mappings from hostname and
+          * sequence identifiers as we do not care about hostnames and sequences during clustering.
+          * We can simply use the UserAction->List<Conversation> map to generate ON/OFF groupings of conversations.
+          */
+         /*
          // Contains all ON events: hostname -> sequence identifier -> list of conversations with that sequence
          Map<String, Map<String, List<Conversation>>> ons = new HashMap<>();
          // Contains all OFF events: hostname -> sequence identifier -> list of conversations with that sequence
                  });
              });
          });
+         */
+         // ================================================ CLUSTERING ================================================
+         // Note: no need to use the more convoluted on/off maps; can simply use the UserAction->List<Conversation> map
+         // when don't care about hostnames and sequences (see comment earlier).
+         List<Conversation> onConversations = userActionToConversations.entrySet().stream().
+                 filter(e -> e.getKey().getType() == Type.TOGGLE_ON). // drop all OFF events from stream
+                 map(e -> e.getValue()). // no longer interested in the UserActions
+                 flatMap(List::stream). // flatten List<List<T>> to a List<T>
+                 collect(Collectors.toList());
+         List<Conversation> offConversations = userActionToConversations.entrySet().stream().
+                 filter(e -> e.getKey().getType() == Type.TOGGLE_OFF).
+                 map(e -> e.getValue()).
+                 flatMap(List::stream).
+                 collect(Collectors.toList());
+         List<PcapPacketPair> onPairs = onConversations.stream().
+                 map(c -> c.isTls() ? TcpConversationUtils.extractTlsAppDataPacketPairs(c) :
+                         TcpConversationUtils.extractPacketPairs(c)).
+                 flatMap(List::stream). // flatten List<List<>> to List<>
+                 collect(Collectors.toList());
+         List<PcapPacketPair> offPairs = offConversations.stream().
+                 map(c -> c.isTls() ? TcpConversationUtils.extractTlsAppDataPacketPairs(c) :
+                         TcpConversationUtils.extractPacketPairs(c)).
+                 flatMap(List::stream). // flatten List<List<>> to List<>
+                 collect(Collectors.toList());
+         // Note: need to update the DnsMap of all PcapPacketPairs if we want to use the IP/hostname-sensitive distance.
+         Stream.concat(Stream.of(onPairs), Stream.of(offPairs)).flatMap(List::stream).forEach(p -> p.setDnsMap(dnsMap));
+         // Perform clustering on conversation logged as part of all ON events.
+         DBSCANClusterer<PcapPacketPair> onClusterer = new DBSCANClusterer<>(10.0, 5);
+         List<Cluster<PcapPacketPair>> onClusters = onClusterer.cluster(onPairs);
+         // Perform clustering on conversation logged as part of all OFF events.
+         DBSCANClusterer<PcapPacketPair> offClusterer = new DBSCANClusterer<>(10.0, 5);
+         List<Cluster<PcapPacketPair>> offClusters = offClusterer.cluster(offPairs);
+         // Output clusters
+         System.out.println("========================================");
+         System.out.println("       Clustering results for ON        ");
+         System.out.println("       Number of clusters: " + onClusters.size());
+         int count = 0;
+         for (Cluster<PcapPacketPair> c : onClusters) {
+             System.out.println(String.format("<<< Cluster #%02d (%03d points) >>>", ++count, c.getPoints().size()));
+             System.out.print(PrintUtils.toSummaryString(c));
+         }
+         System.out.println("========================================");
+         System.out.println("       Clustering results for OFF       ");
+         System.out.println("       Number of clusters: " + offClusters.size());
+         count = 0;
+         for (Cluster<PcapPacketPair> c : offClusters) {
+             System.out.println(String.format("<<< Cluster #%03d (%06d points) >>>", ++count, c.getPoints().size()));
+             System.out.print(PrintUtils.toSummaryString(c));
+         }
+         System.out.println("========================================");
+         // ============================================================================================================
  
+         /*
          System.out.println("==== ON ====");
          // Print out all the pairs into a file for ON events
          File fileOnEvents = new File(onPairsPath);
              }
          }
          pwOff.close();
+         */
  
  //        // ================================================================================================
  //        // <<< Some work-in-progress/explorative code that extracts a "representative" sequence >>>