From 736f54f7ca8d13344a6bd7160d263ee6a49d5233 Mon Sep 17 00:00:00 2001 From: Janus Varmarken Date: Wed, 1 Aug 2018 14:32:27 -0700 Subject: [PATCH] First attempt at labeling traffic with user actions --- .../iotproject/analysis/TrafficLabeler.java | 62 ++++++++++++++++ .../analysis/TriggerTrafficExtractor.java | 2 +- .../uci/iotproject/analysis/UserAction.java | 72 +++++++++++++++++++ 3 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/TrafficLabeler.java create mode 100644 Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/UserAction.java diff --git a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/TrafficLabeler.java b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/TrafficLabeler.java new file mode 100644 index 0000000..eb2e030 --- /dev/null +++ b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/TrafficLabeler.java @@ -0,0 +1,62 @@ +package edu.uci.iotproject.analysis; + +import org.pcap4j.core.PacketListener; +import org.pcap4j.core.PcapPacket; + +import java.time.Instant; +import java.util.*; + +/** + * A {@link PacketListener} that marks network traffic as (potentially) related to a user's actions by comparing the + * timestamp of each packet to the timestamps of the provided list of user actions. + * + * @author Janus Varmarken {@literal } + * @author Rahmadi Trimananda {@literal } + */ +public class TrafficLabeler implements PacketListener { + + private final Map> mActionToTrafficMap; + private final List mActionsSorted; + + public TrafficLabeler(List userActions) { + // Init map with empty lists (no packets have been mapped to UserActions at the onset). + mActionToTrafficMap = new HashMap<>(); + userActions.forEach(ua -> mActionToTrafficMap.put(ua, new ArrayList<>())); + // Sort list of UserActions by timestamp in order to facilitate fast Packet-to-UserAction mapping. + // For safety reasons, we create an internal copy of the list to prevent external code from changing the list's + // contents as that would render our assumptions about order of elements invalid. + // In addition, this also ensures that we do not break assumptions made by external code as we avoid reordering + // the elements of the list passed from the external code. + // If performance is to be favored over safety, assign userActions to mActionsSorted directly. + mActionsSorted = new ArrayList<>(); + mActionsSorted.addAll(userActions); + Collections.sort(mActionsSorted, (ua1, ua2) -> ua1.getTimestamp().compareTo(ua2.getTimestamp())); + } + + + @Override + public void gotPacket(PcapPacket packet) { + // Locate UserAction corresponding to packet, if any. + int index = Collections.binarySearch(mActionsSorted, new UserAction(null, packet.getTimestamp()), (listItem, key) -> { + // Start of inclusion interval is the time of the user action + Instant intervalStart = listItem.getTimestamp(); + // End of inclusion interval is some arbitrary number of milliseconds after the user action. + Instant intervalEnd = intervalStart.plusMillis(TriggerTrafficExtractor.INCLUSION_WINDOW_MILLIS); + if (key.getTimestamp().isAfter(intervalStart) && key.getTimestamp().isBefore(intervalEnd)) { + // Packet lies within specified interval after the current UserAction, so we're done. + // Communicate termination to binarySearch by returning 0 which indicates equality. + return 0; + } + // If packet lies outside inclusion interval of current list item, continue search in lower or upper half of + // list depending on whether the timestamp of the current list item is smaller or greater than that of the + // packet. + return listItem.getTimestamp().compareTo(key.getTimestamp()); + }); + if (index >= 0) { + // Associate the packet to the its corresponding user action (located during the binary search above). + mActionToTrafficMap.get(mActionsSorted.get(index)).add(packet); + } + // Ignore packet if it is not found to be in temporal proximity of a user action. + } + +} diff --git a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/TriggerTrafficExtractor.java b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/TriggerTrafficExtractor.java index 26276b1..aa48e87 100644 --- a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/TriggerTrafficExtractor.java +++ b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/TriggerTrafficExtractor.java @@ -22,7 +22,7 @@ public class TriggerTrafficExtractor implements PcapPacketFilter { private int mTriggerIndex = 0; - private static final int INCLUSION_WINDOW_MILLIS = 20_000; + public static final int INCLUSION_WINDOW_MILLIS = 20_000; public TriggerTrafficExtractor(String pcapFilePath, List triggerTimes, String deviceIp) throws PcapNativeException, NotOpenException { mPcapFilePath = pcapFilePath; diff --git a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/UserAction.java b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/UserAction.java new file mode 100644 index 0000000..ef339a9 --- /dev/null +++ b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/UserAction.java @@ -0,0 +1,72 @@ +package edu.uci.iotproject.analysis; + +import java.time.Instant; + +/** + * Models a user's action, such as toggling the smart plug on/off at a given time. + * + * @author Janus Varmarken + */ +public class UserAction { + + /** + * The specific type of action the user performed. + */ + private final Type mType; + + /** + * The time the action took place. + */ + private final Instant mTimestamp; + + public UserAction(Type typeOfAction, Instant timeOfAction) { + mType = typeOfAction; + mTimestamp = timeOfAction; + } + + /** + * Get the specific type of action performed by the user. + * @return the specific type of action performed by the user. + */ + public Type getType() { + return mType; + } + + /** + * Get the time at which the user performed this action. + * @return the time at which the user performed this action. + */ + public Instant getTimestamp() { + return mTimestamp; + } + + /** + * Enum for indicating what type of action the user performed. + */ + public enum Type { + TOGGLE_ON, TOGGLE_OFF + } + + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof UserAction) { + UserAction that = (UserAction) obj; + return this.mType == that.mType && this.mTimestamp.equals(that.mTimestamp); + } else { + return false; + } + } + + @Override + public int hashCode() { + final int prime = 31; + int hashCode = 17; + hashCode = prime * hashCode + mType.hashCode(); + hashCode = prime * hashCode + mTimestamp.hashCode(); + return hashCode; + } +} -- 2.34.1