First attempt at labeling traffic with user actions
authorJanus Varmarken <varmarken@gmail.com>
Wed, 1 Aug 2018 21:32:27 +0000 (14:32 -0700)
committerJanus Varmarken <varmarken@gmail.com>
Thu, 2 Aug 2018 00:31:13 +0000 (17:31 -0700)
Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/TrafficLabeler.java [new file with mode: 0644]
Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/TriggerTrafficExtractor.java
Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/UserAction.java [new file with mode: 0644]

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 (file)
index 0000000..eb2e030
--- /dev/null
@@ -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 <jvarmark@uci.edu>}
+ * @author Rahmadi Trimananda {@literal <rtrimana@uci.edu>}
+ */
+public class TrafficLabeler implements PacketListener {
+
+    private final Map<UserAction, List<PcapPacket>> mActionToTrafficMap;
+    private final List<UserAction> mActionsSorted;
+
+    public TrafficLabeler(List<UserAction> 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.
+    }
+
+}
index 26276b17ca33797c864a6c97433ad30be49fe4e4..aa48e8722536193f45a8f04953b64f56988e1431 100644 (file)
@@ -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<Instant> 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 (file)
index 0000000..ef339a9
--- /dev/null
@@ -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;
+    }
+}