Skip to content

Instantly share code, notes, and snippets.

@kolargol
Last active May 11, 2022 18:29
Show Gist options
  • Save kolargol/3e5533487e05c181c88d to your computer and use it in GitHub Desktop.
Save kolargol/3e5533487e05c181c88d to your computer and use it in GitHub Desktop.
bash script that detect iphone proximity and takes actions when it arrives/leave range. This example terminate all SSH sessions on server where it is running when iPhone leave range.
#!/bin/bash
# Script that detects arrival,presence,departure of iPhone based on bluetooth. It also execute actions
# In this script it terminate SSH sessions when defined device lefts range
# Requires: bluetooth, hcitools, curl
# Written by Zbyszek Żółkiewski, please visit: http://blog.onefellow.com
# Install:
# - copy ip_scan.sh to /usr/local/bin/ on your local machine/server
# - chmod ugo+x /usr/local/bin/ip_scan.sh
# - change 'ip_iphone' variable to point you your iPhone mac-address
# - pair iPhone with your linux/whatever machine you want to perform actions/detection
# - option: insert your boxcar_id otherwise comment-out boxcar_send function in action_after_grace
# - put into cron: echo "*/1 * * * * root /usr/local/bin/ip_scan_bl.sh" > /etc/cron.d/iphone_scan_bl , or whatever user you want
# bluetooth mac
ip_iphone=""
iphone=$(hcitool rssi $ip_iphone > /dev/null 2>&1;echo $?)
# logfile
log_file="iphone_scan.log"
# action on away is not done before this N run of this script
grace_t="3"
# optional boxcar id
boxcar_id=""
boxcar_psh="PI: SSH shell terminated"
boxcar_tit="iPhone left known network"
boxcar_lng="Details: You just left appartment and SSH sessions were terminated."
# functions
say_log(){
# write timestamp and output to logfile
date "+%Y-%m-%d %H:%M:%S $1" >> /var/log/$log_file
}
action_arrive(){
# perform action on arrive
say_log "Welcome Professor!"
}
action_left(){
# perform action on left, maybe you want to close windows or doors?
say_log "No Action"
}
action_after_grace(){
# perform action after extended absence
ps ax | egrep "sshd: [a-zA-Z]+@pts" | awk '{print $1}' | while read ssh_pid; do
say_log "Action: Killing SSH PID: $ssh_pid"
kill $ssh_pid
done
}
action_away(){
# disallow any SSH users if iPhone is not authorized in local network
check_ssh=$(ps ax|egrep -c "sshd: [a-zA-Z]+@pts")
if [ "$check_ssh" -gt "0" ];then
say_log "Warning: SSH sessions found. Terminating all logged in users"
action_after_grace
fi
# avoid printing anything, as it just poison logfile
}
boxcar_send(){
curl -d user_credentials=$boxcar_id \
-d "notification[message]=$boxcar_psh" \
-d "notification[long_message]=$boxcar_lng" \
-d "notification[title]=$boxcar_tit" \
-d "notification[sound]=21.caf" \
-d "notification[silent]=0" \
-d "notification[message_level]=1" \
-d "notification[action_loc_key]=read" \
https://new.boxcar.io/account/notifications.xml
}
# end functions
# check if state changed...
state_c=$(cat /tmp/iphone_present)
if [ "$state_c" != "$iphone" ]; then
ip_state="same"
else
ip_state="changed"
fi
# 0 - hci successful, 1 - with error (no signal,power off, etc..)
if [ "$iphone" = "0" ];then
# Check signal strength. Tune to your needs
rssi=$(hcitool rssi $ip_iphone |awk '{print $4}')
if [ "$rssi" -gt "-15" ]; then
range="close"
elif [ "$rssi" -lt "-14" ]; then
range="away"
fi
# Got signal, if state is same as before we know iPhone was already here
if [ "$ip_state" = "changed" ]; then
# state changed, and it is new, so we know iphone just appeared in net
say_log "iPhone just arrived! Range: $range [$rssi]"
# perform action on arrive
action_arrive
# set markers
echo "1" > /tmp/iphone_present
echo "0" > /tmp/iphone_action
else
# state same, iphone was already here
say_log "iPhone is present on network. Range: $range [$rssi]"
fi
else
# No signal, error, whatever go wrong with bluetooth lead here, check if it is known state
if [ "$ip_state" = "changed" ]; then
# New state - this looks like iPhone go out of range
say_log "iPhone just left network"
# perform action immediately when device left network
action_left
# set markers
echo "0" > /tmp/iphone_present
echo "1" > /tmp/iphone_grace_c
else
# State is known and same as before, let's count gracetime and...
grace_c=$(cat /tmp/iphone_grace_c)
if [ "$grace_c" -le "$grace_t" ]; then
# counting of gracetime
say_log "iPhone out of network [ grace time: $grace_c/$grace_t ]"
grace_c=$((grace_c+1))
echo "$grace_c" > /tmp/iphone_grace_c
else
# ...if we reach max $grace_t, let's perform some action here(once)
is_action_done=$(cat /tmp/iphone_action)
if [ "$is_action_done" -ne "1" ];then
# perform action, yeah, once
action_after_grace
# send notification, so you are aware
if [ "$boxcar_id" ]; then
boxcar_send
fi
# mark that this action was already performed, so we do not repeat it forever...
echo "1" > /tmp/iphone_action
else
# nobody here, just tellin
say_log "iPhone out of network"
# but maybe we still want to perform some actiion, like throw away anyone on ssh..
action_away
fi
fi
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment