This is the repository for IoTCheck, a framework that model-checks smart home apps. Please read our paper before using IoTCheck.
Understanding and Automatically Detecting Conflicting Interactions between Smart Home Applications
Rahmadi Trimananda, Seyed Amir Hossein Aqajari, Jason Chuang, Brian Demsky, Guoqing Harry Xu, and Shan Lu,
Proceedings of the ACM SIGSOFT International Symposium on Foundations of Software Engineering 2020 (FSE 2020).
The following instructions explain how to quickly get started with IoTCheck. For more information about IoTCheck components, please see the Wiki page of this repository.
One easy way to install IoTCheck is using our Vagrant-packaged IoTCheck. Nevertheless, if the necessary components are present on our system, we could also download IoTCheck directly from this repository and set it up correctly to run on our system (our team has developed IoTCheck on Ubuntu 16.04.6 LTS (Xenial Xerus). Please see this script and this script for the necessary components and steps to correctly install IoTCheck after downloading it from this repository.
We have prepared 2 example runs to quickly test that the IoTCheck installation is working perfectly and to understand the output of IoTCheck runs.
- First, we need to get into the directory
iotcheck/smartthings-infrastructure
.
$ cd iotcheck/smartthings-infrastructure/
- Run the
iotcheck.sh
script for both non-conflict and conflict examples. Each example takes a few minutes to run and messages will be printed out on the screen.
iotcheck/smartthings-infrastructure $ ./iotcheck.sh -e exampleNonConflicts
iotcheck/smartthings-infrastructure $ ./iotcheck.sh -e exampleConflicts
- The results of all IoTCheck runs are collected in
iotcheck/logs/
.
The log files for the non-conflict example runs can be found in iotcheck/logs/exampleNonConflicts
. There are two log files for two pairs:
good-night-house.groovy--nfc-tag-toggle.groovy.log
for the pairgood-night-house.groovy
andnfc-tag-toggle.groovy
, andgood-night-house.groovy--single-button-controller.groovy.log
for the pairgood-night-house.groovy
andsingle-button-controller.groovy
.
If we open one of the log files, e.g., good-night-house.groovy--nfc-tag-toggle.groovy.log
, we can see the reported result printed as the following.
JavaPathfinder core system v8.0 (rev 61f7af9209cd126105042a7b12ace7e7eb3f5492) - (C) 2005-2014
United States Government. All rights reserved.
====================================================== system under test
main.main()
====================================================== search started: 5/26/20 3:54 PM
====================================================== results
no errors detected
====================================================== statistics
elapsed time: 00:00:10
states: new=13,visited=14,backtracked=27,end=0
search: maxDepth=5,constraints=0
choice generators: thread=1 (signal=0,lock=1,sharedRef=0,threadApi=0,reschedule=0), data=13
heap: new=589608,released=444025,maxLive=77394,gcCycles=27
instructions: 47693786
max memory: 1213MB
loaded code: classes=786,methods=15362
====================================================== search finished: 5/26/20 3:54 PM
Both log files will show the line no errors detected
, because there were no conflicts found between the two apps in each pair.
The log files for the conflict example runs can be found in iotcheck/logs/exampleConflicts
. There are two log files for two pairs:
enhanced-auto-lock-door.groovy--nfc-tag-toggle.groovy.log
for the pairenhanced-auto-lock-door.groovy
andnfc-tag-toggle.groovy
, andenhanced-auto-lock-door.groovy--single-button-controller.groovy.log
for the pairenhanced-auto-lock-door.groovy
andsingle-button-controller.groovy
.
If we open one of the log files, e.g., enhanced-auto-lock-door.groovy--nfc-tag-toggle.groovy.log
, we can see the reported result printed as the following.
JavaPathfinder core system v8.0 (rev 61f7af9209cd126105042a7b12ace7e7eb3f5492) - (C) 2005-2014
United States Government. All rights reserved.
====================================================== system under test
main.main()
====================================================== search started: 5/26/20 3:56 PM
====================================================== error 1
gov.nasa.jpf.vm.NoUncaughtExceptionsProperty
java.lang.RuntimeException: Conflict found between the two apps. App1 has written the value: "locked" to
the attribute: currentLock while App2 is writing the value: "unlocked" to the same variable!
...
====================================================== results
error #1: gov.nasa.jpf.vm.NoUncaughtExceptionsProperty "java.lang.RuntimeException: Conflict found between..."
====================================================== statistics
elapsed time: 00:00:07
states: new=5,visited=2,backtracked=6,end=0
search: maxDepth=3,constraints=0
choice generators: thread=1 (signal=0,lock=1,sharedRef=0,threadApi=0,reschedule=0), data=2
heap: new=497975,released=365064,maxLive=79104,gcCycles=6
instructions: 35487521
max memory: 1199MB
loaded code: classes=796,methods=14914
====================================================== search finished: 5/26/20 3:57 PM
This log file shows the line
gov.nasa.jpf.vm.NoUncaughtExceptionsProperty
java.lang.RuntimeException: Conflict found between the two apps. App1 has written the value: "locked" to
the attribute: currentLock while App2 is writing the value: "unlocked" to the same variable!
which means that a conflict has been found between the two apps: enhanced-auto-lock-door.groovy
is App1
and nfc-tag-toggle.groovy
is App2
. App1
wrote the value locked
to the shared lock state variable currentLock
, and App2
is found to subsequently write to the same variable with the value unlocked
. Since one attempts to lock and the other unlock the door, IoTCheck reports that these two apps have a conflict.
Our paper explains the 3 categories of interactions between smart home apps, namely device interaction, physical-medium interaction, and global-variable interaction. The details of our manual study and experimental results are documented here.
IoTCheck only prints out warning messages for potential conflicts in the physical-medium interaction category since detecting a conflict in this interaction category requires specific conditions (please read the paper for more information).
We use the script iotcheck.sh
to run experiments in each category and group of apps. Typing ./iotcheck.sh
in the directory iotcheck/smartthings-infrastructure
will print out the following help information on how to execute the individual experiments.
Usage: iotcheck.sh [options]
-h (print this usage info)
-e exampleConflicts
exampleNonConflicts
-d acfanheaterSwitches
alarms
cameras
cameraSwitches
dimmers
hueLights
lightSwitches
locks
musicPlayers
nonHueLights
relaySwitches
speeches
switches
thermostats
valves
ventfanSwitches
-g globalStateVariables
All the log files produced by these runs are collected in the directory iotcheck/logs/
. Each sub-directory contains the log files for the respective category.
The script runs IoTCheck for pairs listed in the files stored in iotcheck/smartthings-infrastructure/appLists/
.
For example, it uses the files locksAppList
and locksAppList2
in iotcheck/smartthings-infrastructure/appLists/device-interaction
to form pairs in the locks
group and run IoTCheck to model-check each pair.
We can put the sign #
in front of a specific app name in the file to tell IoTCheck to exclude that app in the pairing process. We can see this being done in the app list files in iotcheck/smartthings-infrastructure/appLists/examples
.
In the file exampleConflictsAppList
we can find the following list.
enhanced-auto-lock-door.groovy
#good-night-house.groovy
#nfc-tag-toggle.groovy
#single-button-controller.groovy
And, in the file exampleConflictsAppList2
we can find the following list.
#enhanced-auto-lock-door.groovy
#good-night-house.groovy
nfc-tag-toggle.groovy
single-button-controller.groovy
The app enhanced-auto-lock-door.groovy
is the only one uncommented in exampleConflictsAppList
. Thus, it is taken by IoTCheck and paired up with nfc-tag-toggle.groovy
and single-button-controller.groovy
, as the two uncommented apps in exampleConflictsAppList2
, to form 2 pairs:
enhanced-auto-lock-door.groovy
asApp1
andnfc-tag-toggle.groovy
asApp2
, andenhanced-auto-lock-door.groovy
asApp1
andsingle-button-controller.groovy
asApp2
.
In other words, if we just want to have IoTCheck model-check a specific pair, e.g., enhanced-auto-lock-door.groovy
as App1
and nfc-tag-toggle.groovy
as App2
, then we have to comment out single-button-controller.groovy
in exampleConflictsAppList2
by putting #
in front of it. Furthermore, IoTCheck also allows the pair of apps to be executed in different orders, so we could also uncomment only nfc-tag-toggle.groovy
in exampleConflictsAppList
and enhanced-auto-lock-door.groovy
in exampleConflictsAppList2
. This will form a pair: nfc-tag-toggle.groovy
as App1
and enhanced-auto-lock-door.groovy
as App2
. After we change the app list files, we can run the iotcheck.sh
script again. A conflict is confirmed for the two apps when IoTCheck reports a conflict for, at least, one of the two orders.
We can run an experiment in this category by running the following command in the directory iotcheck/smartthings-infrastructure
.
iotcheck/smartthings-infrastructure $ ./iotcheck.sh -d <category>
For example, we can run
iotcheck/smartthings-infrastructure $ ./iotcheck.sh -d locks
to run IoTCheck to check for conflicts between pairs in the locks
group.
For some of the groups, we run the experiments for their individual sub-groups:
- For the
Switches
group, we run the experiments forswitches
,lightSwitches
,acfanheaterSwitches
,cameraSwitches
, andventfanSwitches
. - For the
Lights
group, we run the experiments forhueLights
andnonHueLights
.
Note: switches
means the Switches - General
group and speeches
means the Speech Synthesizers
group in the paper.
We can run an experiment in this category by running the following command in the directory iotcheck/smartthings-infrastructure
.
iotcheck/smartthings-infrastructure $ ./iotcheck.sh -g globalStateVariables
IoTCheck only gives a warning when it detects that the interaction between apps in a pair may result in a Physical-Medium Conflict, but it does not report it as a real conflict (please see Section 5 - Physical Factors in the paper).
For the purpose of testing and understanding IoTCheck, we recommend running IoTCheck for categories with shorter lists of apps, e.g., acfanheaterSwitches
, cameraSwitches
, and ventfanSwitches
, to see how it performs model checking and generates results reported in log files. The other categories could run for hours, days, or weeks as we have tens to hundreds of pairs and each pair is run for up to 30 minutes (or 1 hour if IoTCheck also runs with the RandomHeuristic
search strategy) to check for conflicts. Alternatively, the timeout could be made shorter, e.g., 5 minutes, by changing the option in main.jpf
.
We tabulated the results reported in the log files in each category and reported the summary in Table 6 of our paper.
Please note that there could be 2 log files that are produced by the different orderings of the apps in the pair. For example, for the pair good-night-house.groovy
and nfc-tag-toggle.groovy
, there could be no conflict reported in good-night-house.groovy--nfc-tag-toggle.groovy.log
(good-night-house.groovy
is App1
and nfc-tag-toggle.groovy
is App2
), but there could be a conflict reported in nfc-tag-toggle.groovy--good-night-house.groovy.log
(nfc-tag-toggle.groovy
is App1
and good-night-house.groovy
is App2
). We checked both orderings in our tabulation. More details of our manual study and experimental results are documented here.
For more information about IoTCheck architecture explained in Section 7 in our paper, please see the Wiki page of this repository. If you have any questions regarding IoTCheck, please do not hesitate to contact the main author of the paper.