X-Git-Url: http://plrg.eecs.uci.edu/git/?p=pingpong.git;a=blobdiff_plain;f=Code%2FProjects%2FSmartPlugDetector%2Fsrc%2Fmain%2Fjava%2Fedu%2Fuci%2Fiotproject%2FMain.java;h=1addfb313266c94a74575a9edfdf5f0e6bbb6295;hp=b8b5b75afc00ef5ef49236535f3bfd1fe52d1ab4;hb=36741790f65056a81f26fe697da398d66d71cbcf;hpb=b75badc4351428ada557dd27fe500cf60befe342 diff --git a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/Main.java b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/Main.java index b8b5b75..1addfb3 100644 --- a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/Main.java +++ b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/Main.java @@ -6,6 +6,9 @@ import edu.uci.iotproject.analysis.TcpConversationUtils; import edu.uci.iotproject.analysis.TrafficLabeler; import edu.uci.iotproject.analysis.TriggerTrafficExtractor; import edu.uci.iotproject.analysis.UserAction; +import edu.uci.iotproject.comparison.seqalignment.ExtractedSequence; +import edu.uci.iotproject.comparison.seqalignment.SequenceAlignment; +import edu.uci.iotproject.comparison.seqalignment.SequenceExtraction; import edu.uci.iotproject.io.TriggerTimesFileReader; import org.pcap4j.core.*; import org.pcap4j.packet.namednumber.DataLinkType; @@ -35,49 +38,111 @@ public class Main { // 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 = "/Users/varmarken/temp/UCI IoT Project/experiments"; // Janus + boolean verbose = true; - // D-Link July 26 experiment + // 1) D-Link July 26 experiment // final String inputPcapFile = path + "/2018-07/dlink/dlink.wlan1.local.pcap"; // final String outputPcapFile = path + "/2018-07/dlink/dlink-processed.pcap"; // final String triggerTimesFile = path + "/2018-07/dlink/dlink-july-26-2018.timestamps"; -// final String deviceIp = "192.168.1.199"; // .246 == phone; .199 == dlink plug? +// final String deviceIp = "192.168.1.246"; // .246 == phone; .199 == dlink plug? - // TP-Link July 25 experiment + // 2) TP-Link July 25 experiment // final String inputPcapFile = path + "/2018-07/tplink/tplink.wlan1.local.pcap"; // final String outputPcapFile = path + "/2018-07/tplink/tplink-processed.pcap"; // final String triggerTimesFile = path + "/2018-07/tplink/tplink-july-25-2018.timestamps"; // final String deviceIp = "192.168.1.159"; - // SmartThings Plug July 25 experiment + // 2b) TP-Link July 25 experiment TRUNCATED: + // Only contains "true local" events, i.e., before the behavior changes to remote-like behavior. + // Last included event is at July 25 10:38:11; file filtered to only include packets with arrival time <= 10:38:27. +// final String inputPcapFile = path + "/2018-07/tplink/tplink.wlan1.local.truncated.pcap"; +// final String outputPcapFile = path + "/2018-07/tplink/tplink-processed.truncated.pcap"; +// final String triggerTimesFile = path + "/2018-07/tplink/tplink-july-25-2018.truncated.timestamps"; +// final String deviceIp = "192.168.1.159"; + + // 3) SmartThings Plug July 25 experiment // final String inputPcapFile = path + "/2018-07/stplug/stplug.wlan1.local.pcap"; // final String outputPcapFile = path + "/2018-07/stplug/stplug-processed.pcap"; // final String triggerTimesFile = path + "/2018-07/stplug/smartthings-july-25-2018.timestamps"; // final String deviceIp = "192.168.1.246"; // .246 == phone; .142 == SmartThings Hub (note: use eth0 capture for this!) - // Wemo July 30 experiment -// final String inputPcapFile = path + "/2018-07/wemo/wemo.wlan1.local.pcap"; -// final String outputPcapFile = path + "/2018-07/wemo/wemo-processed.pcap"; -// final String triggerTimesFile = path + "/2018-07/wemo/wemo-july-30-2018.timestamps"; -// final String deviceIp = "192.168.1.145"; + // 4) Wemo July 30 experiment + final String inputPcapFile = path + "/2018-07/wemo/wemo.wlan1.local.pcap"; + final String outputPcapFile = path + "/2018-07/wemo/wemo-processed.pcap"; + final String triggerTimesFile = path + "/2018-07/wemo/wemo-july-30-2018.timestamps"; + final String deviceIp = "192.168.1.145"; - // Wemo Insight July 31 experiment + // 5) Wemo Insight July 31 experiment // final String inputPcapFile = path + "/2018-07/wemoinsight/wemoinsight.wlan1.local.pcap"; // final String outputPcapFile = path + "/2018-07/wemoinsight/wemoinsight-processed.pcap"; // final String triggerTimesFile = path + "/2018-07/wemoinsight/wemo-insight-july-31-2018.timestamps"; // final String deviceIp = "192.168.1.135"; - // TP-Link BULB August 1 experiment + // 6) TP-Link Bulb August 1 experiment // final String inputPcapFile = path + "/2018-08/tplink-bulb/tplinkbulb.wlan1.local.pcap"; // final String outputPcapFile = path + "/2018-08/tplink-bulb/tplinkbulb-processed.pcap"; // final String triggerTimesFile = path + "/2018-08/tplink-bulb/tplink-bulb-aug-3-2018.timestamps"; // final String deviceIp = "192.168.1.140"; - // Kwikset Doorlock August 6 experiment - final String inputPcapFile = path + "/2018-08/kwikset-doorlock/kwikset-doorlock.wlan1.local.pcap"; - 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!) + // 7) Kwikset Doorlock August 6 experiment +// final String inputPcapFile = path + "/2018-08/kwikset-doorlock/kwikset-doorlock.wlan1.local.pcap"; +// 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!) + + // 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 triggerTimesFile = path + "/2018-08/hue-bulb/hue-bulb-aug-7-2018.timestamps"; +// final String deviceIp = "192.168.1.246"; + + // 9) Lifx Bulb August 8 experiment +// final String inputPcapFile = path + "/2018-08/lifx-bulb/lifx-bulb.wlan1.local.pcap"; +// final String outputPcapFile = path + "/2018-08/lifx-bulb/lifx-bulb-processed.pcap"; +// final String triggerTimesFile = path + "/2018-08/lifx-bulb/lifx-bulb-aug-8-2018.timestamps"; +// final String deviceIp = "192.168.1.246"; // .246 == phone; .231 == Lifx + + // 10) Amcrest Camera August 9 experiment +// final String inputPcapFile = path + "/2018-08/amcrest-camera/amcrest-camera.wlan1.local.pcap"; +// final String outputPcapFile = path + "/2018-08/amcrest-camera/amcrest-camera-processed.pcap"; +// final String triggerTimesFile = path + "/2018-08/amcrest-camera/amcrest-camera-aug-9-2018.timestamps"; +// final String deviceIp = "192.168.1.246"; // .246 == phone; .235 == camera + + // 11) Arlo Camera August 10 experiment +// final String inputPcapFile = path + "/2018-08/arlo-camera/arlo-camera.wlan1.local.pcap"; +// final String outputPcapFile = path + "/2018-08/arlo-camera/arlo-camera-processed.pcap"; +// final String triggerTimesFile = path + "/2018-08/arlo-camera/arlo-camera-aug-10-2018.timestamps"; +// final String deviceIp = "192.168.1.140"; // .246 == phone; .140 == camera + + // 12) Blossom sprinkler August 13 experiment +// final String inputPcapFile = path + "/2018-08/blossom/blossom.wlan1.local.pcap"; +// final String outputPcapFile = path + "/2018-08/blossom/blossom-processed.pcap"; +// final String triggerTimesFile = path + "/2018-08/blossom/blossom-aug-13-2018.timestamps"; +// final String deviceIp = "192.168.1.229"; // .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.246"; // .246 == phone; .183 == siren + + // 14) Nest thermostat August 15 experiment +// final String inputPcapFile = path + "/2018-08/nest/nest.wlan1.local.pcap"; +// final String outputPcapFile = path + "/2018-08/nest/nest-processed.pcap"; +// final String triggerTimesFile = path + "/2018-08/nest/nest-aug-15-2018.timestamps"; +// final String deviceIp = "192.168.1.246"; // .246 == phone; .127 == Nest thermostat + + // 15) Alexa August 16 experiment +// final String inputPcapFile = path + "/2018-08/alexa/alexa.wlan1.local.pcap"; +// final String outputPcapFile = path + "/2018-08/alexa/alexa-processed.pcap"; +// final String triggerTimesFile = path + "/2018-08/alexa/alexa-aug-16-2018.timestamps"; +// final String deviceIp = "192.168.1.225"; // .246 == phone; .225 == Alexa + // August 17 +// final String inputPcapFile = path + "/2018-08/alexa/alexa2.wlan1.local.pcap"; +// final String outputPcapFile = path + "/2018-08/alexa/alexa2-processed.pcap"; +// final String triggerTimesFile = path + "/2018-08/alexa/alexa-aug-17-2018.timestamps"; +// final String deviceIp = "192.168.1.225"; // .246 == phone; .225 == Alexa TriggerTimesFileReader ttfr = new TriggerTimesFileReader(); List triggerTimes = ttfr.readTriggerTimes(triggerTimesFile, false); @@ -136,22 +201,78 @@ public class Main { Map>> ons = new HashMap<>(); // Contains all OFF events: hostname -> sequence identifier -> list of conversations with that sequence Map>> offs = new HashMap<>(); - userActionsToConvsByHostname.forEach((ua, hostnameToConvs) -> { - Map>> outer = ua.getType() == Type.TOGGLE_ON ? ons : offs; - hostnameToConvs.forEach((host, convs) -> { - Map> seqsToConvs = TcpConversationUtils. - groupConversationsByPacketSequence(convs); - outer.merge(host, seqsToConvs, (oldMap, newMap) -> { - newMap.forEach((sequence, cs) -> oldMap.merge(sequence, cs, (list1, list2) -> { - list1.addAll(list2); - return list1; - })); - return oldMap; + + if (verbose) { + userActionsToConvsByHostname.forEach((ua, hostnameToConvs) -> { + Map>> outer = ua.getType() == Type.TOGGLE_ON ? ons : offs; + hostnameToConvs.forEach((host, convs) -> { + Map> seqsToConvs = TcpConversationUtils. + groupConversationsByPacketSequenceVerbose(convs); + outer.merge(host, seqsToConvs, (oldMap, newMap) -> { + newMap.forEach((sequence, cs) -> oldMap.merge(sequence, cs, (list1, list2) -> { + list1.addAll(list2); + return list1; + })); + return oldMap; + }); }); }); - }); + } else { + userActionsToConvsByHostname.forEach((ua, hostnameToConvs) -> { + Map>> outer = ua.getType() == Type.TOGGLE_ON ? ons : offs; + hostnameToConvs.forEach((host, convs) -> { + Map> seqsToConvs = TcpConversationUtils. + groupConversationsByPacketSequence(convs); + outer.merge(host, seqsToConvs, (oldMap, newMap) -> { + newMap.forEach((sequence, cs) -> oldMap.merge(sequence, cs, (list1, list2) -> { + list1.addAll(list2); + return list1; + })); + return oldMap; + }); + }); + }); + } + // ================================================================================================ + // <<< Some work-in-progress/explorative code that extracts a "representative" sequence >>> + // + // Currently need to know relevant hostname in advance :( + String hostname = "events.tplinkra.com"; + // Conversations with 'hostname' for ON events. + List onsForHostname = new ArrayList<>(); + // Conversations with 'hostname' for OFF events. + List offsForHostname = new ArrayList<>(); + // "Unwrap" sequence groupings in ons/offs maps. + ons.get(hostname).forEach((k,v) -> onsForHostname.addAll(v)); + offs.get(hostname).forEach((k,v) -> offsForHostname.addAll(v)); + // Extract representative sequence for ON and OFF by providing the list of conversations with + // 'hostname' observed for each event type (the training data). + SequenceExtraction seqExtraction = new SequenceExtraction(); + ExtractedSequence extractedSequenceForOn = seqExtraction.extract(onsForHostname); + ExtractedSequence extractedSequenceForOff = seqExtraction.extract(offsForHostname); + // Let's check how many ONs align with OFFs and vice versa (that is, how many times an event is incorrectly + // labeled). + int onsLabeledAsOff = 0; + Integer[] representativeOnSeq = TcpConversationUtils.getPacketLengthSequence(extractedSequenceForOn.getRepresentativeSequence()); + Integer[] representativeOffSeq = TcpConversationUtils.getPacketLengthSequence(extractedSequenceForOff.getRepresentativeSequence()); + SequenceAlignment seqAlg = seqExtraction.getAlignmentAlgorithm(); + for (Conversation c : onsForHostname) { + Integer[] onSeq = TcpConversationUtils.getPacketLengthSequence(c); + if (seqAlg.calculateAlignment(representativeOffSeq, onSeq) <= extractedSequenceForOff.getMaxAlignmentCost()) { + onsLabeledAsOff++; + } + } + int offsLabeledAsOn = 0; + for (Conversation c : offsForHostname) { + Integer[] offSeq = TcpConversationUtils.getPacketLengthSequence(c); + if (seqAlg.calculateAlignment(representativeOnSeq, offSeq) <= extractedSequenceForOn.getMaxAlignmentCost()) { + offsLabeledAsOn++; + } + } System.out.println(""); + // ================================================================================================ + // ------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------