Talk:TIP Bluetooth Proximity Monitor
From Gentoo Linux Wiki
I suppose, that using sudo to start/kill xscreensaver and hcitool is better than
- chmod +s /usr/bin/hcitool
Simply edit your /etc/sudoers
Am I right? yes
Contents |
[edit] KDE
Try this, if you are using kde:
START_CMD='true' FAR_CMD='dcop kdesktop KScreensaverIface lock' NEAR_CMD='dcop kdesktop KScreensaverIface quit'
[edit] Phone off.
I have edited the script so that it works when the phone is switched off. I also used sudo to save logging in as root.
Here is my code:
| File: ~/btproximity |
#!/bin/sh
DEVICE="00:00:00:00:00:00"
CHECK_INTERVAL=2
THRESHOLD=-7
PID=0
START_CMD='/usr/bin/xscreensaver -nosplash'
FAR_CMD='/usr/bin/xscreensaver-command -lock'
NEAR_CMD='/bin/killall xscreensaver'
HCITOOL="sudo /usr/bin/hcitool"
DEBUG="/dev/null"
connected=0
function msg {
echo "$1" >> $DEBUG
}
function check_connection {
connected=0;
found=0
for s in `$HCITOOL con`; do
if [[ "$s" == "$DEVICE" ]]; then
found=1;
fi
done
if [[ $found == 1 ]]; then
connected=1;
else
msg 'Attempting connection...'
if [ -z "`$HCITOOL cc $DEVICE 2>&1`" ]; then
msg 'Connected.'
connected=1;
else
connected=0;
fi
fi
}
function check_xscreensaver {
PID=`ps -C xscreensaver --no-heading | awk '{ print $1 }'`
if [ "$PID" == "" ]; then
$START_CMD &
fi
}
name=`$HCITOOL name $DEVICE`
msg "Monitoring proximity of \"$name\" [$DEVICE]";
state="near"
while /bin/true; do
check_xscreensaver
check_connection
if [[ $connected -eq 1 ]]; then
rssi=`$HCITOOL rssi $DEVICE | sed -e 's/RSSI return value: //g'`
if (( $rssi <= $THRESHOLD )); then
if [[ "$state" == "near" ]]; then
msg "*** Device \"$name\" [$DEVICE] has left proximity"
state="far"
$FAR_CMD > /dev/null 2>&1
fi
else
if [[ "$state" == "far" ]]; then
msg "*** Device \"$name\" [$DEVICE] is within proximity"
state="near"
$NEAR_CMD > /dev/null 2>&1
$START_CMD &
fi
fi
msg "state = $state, RSSI = $rssi, PID = $PID"
else
if [[ "$state" == "near" ]]; then
msg "*** Device \"$name\" [$DEVICE] has been disconnected"
state="far"
$FAR_CMD > /dev/null 2>&1
fi
fi
sleep $CHECK_INTERVAL
done
|
It probably wouldn't be too hard to patch xscreensaver to include -unlock functionality, but for *practical* purposes, perhaps one might consider finding a more secure/bulletproof fashion of patching then just "-unlock". -unlock would be the hackish solution; Here's an idea:
$hash = randomly_generated_hex_hash() xscreensaver-command -lock-with-hash=$hash ## which may or may not be "432F36EA4B3" xscreensaver-command -unlock-with-hash=$hash
this may not be *perfectly* secure, since the hash may be kept in plain text in the script's memory, but it'll provide at least a mildly secure solution. One might even consider using crypt() for extra security. EDIT: To anyone actually _planning_ on patching, I shouldn't need to explain why "-unlock" as a practical solution is a bad idea, but generally it's because permissions aren't checked, and even if they are, it's not exactly a chore to run a command for a user that isn't you. The point isn't to make it unhackable, the point is to keep people from unlocking your screen with a single command for shits and giggles, excuse my french.
- This script is great. Thanks!
- But if I swiched off my phone I must wait a few seconds befor xscreensaver starts. 10 seconds are a long time ;)
- The script search for my device, but there must be a timeout befor it defenetly says the device is not present
- Is it possible to change that timeout?
[edit] Distance w/ RSSI?
Hello,
This code is fantastic.
I also want to know the exact distance of my mobile form my pc in feets, using RSSI. How can I do it? Do you have some code for it?
Thanks,
Sriharsha
- Sriharsha:
- As far as I know, you can't calculate REAL distance with RSSI, since RSSI is just a signal strength, and signal strength may vary from phone to phone.
- -Ben (author)
[edit] Running as root
FWIW Ubuntu ACPI scripts use the following to figure out which user is running the X session, and control the screen saver:
PATH="$PATH:/usr/bin/X11"
user=`who| grep -m1 " :0" | awk '{print $1}'`
export XAUTHORITY=/home/$user/.Xauthority
export DISPLAY=:0
su - $user -c "xscreensaver-command -deactivate"
I suppose you can use this to avoid SUIDing hcitool.
[edit] Works but...
This ingenious script actually works, but unfortunately, the signal strength of my mobile phone (Samsung SHG-D500) seems to fluctuate a lot. One moment, when sitting in my in front of my PC, hcitool rssi <addr> returns 0, a few seconds later it returns -7.
Even with THRESHOLD set to -15, I get accidental screen locks when just sitting in front of my computer. Maybe I just have the wrong phone for this....
--raptux 19:06, September 7, 2005 (GMT)
My Nokia 6600 exibits the same problem I get 10 rssi=0 then it goes -1 -2 ... -7 and reconnects.
-- nivw 14:29, Feb 2, 2006
Hello,
With my Samsung E530 the RSSI value is also not very stable... I'm wondering if it isn't a general problem that is independant of the phone/device ?
Maybe one could combine the RSSI and LQ (Link Quality) values of determine if the device is near or far ? I'm not an expert and I would appreciate your opinions on this !
Another problem that I have with a Dell X510 (Axim) PDA : when I connect to that device, the connection always times out after ~10 seconds ! Is there something I can do ? Does it come from Windows Mobile or from the hardware ? Do you have any ideas ?
Thank you in advance !
Sofia
Hey, Same Problem as Sofia, Windows Mobile 6 HTC S71. hcitool cc <mac> will connect then drop after a few seconds, even when hcitool auth <mac> is called.
Cheers, Tag
[edit] gnome-screensaver
| Code: CMD Changes |
FAR_CMD='/usr/bin/gnome-screensaver-command --lock' NEAR_CMD='/usr/bin/gnome-screensaver-command --deactivate' |
Full Code (Locks when device turned off / out of range, Unlocks gnome-screensaver without password when device re-enters range):
| Code: BTProx.sh |
#!/bin/bash
#set -o verbose sh -v
# Copied from Steven on http://gentoo-wiki.com/Talk:TIP_Bluetooth_Proximity_Monitor
# Modified By Jamie Paton <jamie.paton@googlemail.com>
# These are the sections you'll need to edit
# You'll need to use the MAC address of your phone here
#Use "hcitool scan" to find the MAC of your device
DEVICE="00:38:13:59:43:12"
# How often to check the distance between phone and computer in seconds
CHECK_INTERVAL=10
# The RSSI threshold at which a phone is considered far or near
THRESHOLD=-8
# The command to run when your phone gets too far away
FAR_CMD='/usr/bin/gnome-screensaver-command --activate'
# The command to run when your phone is close again
#NEAR_CMD='/opt/gnome/bin/gnome-screensaver-command --poke'
NEAR_CMD='/usr/bin/gnome-screensaver-command --deactivate'
HCITOOL="sudo /usr/bin/hcitool"
STARTX_PID=0
DEBUG="/tmp/btproximity.log"
connected=0
state="far"
function msg {
echo "$1" >> "$DEBUG"
echo "$1"
}
function check_connection {
connected=0;
found=0
for s in `$HCITOOL con`; do
if [[ "$s" == "$DEVICE" ]]; then
found=1;
fi
done
if [[ $found == 1 ]]; then
connected=1;
else
msg 'Attempting connection...'
if [ -z "`$HCITOOL cc $DEVICE 2>&1`" ]; then
msg 'Connected'
connected=1;
else
if [ -z "`l2ping -c 2 -t 5 -i $DEVICE 2>&1`" ]; then
if [ -z "`$HCITOOL cc $DEVICE 2>&1`" ]; then
msg 'Ping is good!'
connected=1;
else
msg "ERROR: Could not connect to device $DEVICE."
connected=0;
fi
fi
fi
fi
if [[ $connected -eq 0 ]]; then
$FAR_CMD > /dev/null 2>&1
state="far"
fi
}
check_connection
while [[ $connected -eq 0 ]]; do
check_connection
sleep 10
done
name=`$HCITOOL name $DEVICE`
msg "Monitoring proximity of \"$name\" [$DEVICE]";
while /bin/true; do
state="far"
check_connection
if [[ $connected -eq 1 ]]; then
rssi=$($HCITOOL rssi $DEVICE | sed -e 's/RSSI return value: //g')
if [[ $rssi -le $THRESHOLD ]]; then
if [[ "$state" == "near" ]]; then
msg "*** Device \"$name\" [$DEVICE] has left proximity"
state="far"
$FAR_CMD > /dev/null 2>&1
fi
else
if [[ "$state" == "far" && $rssi -ge $[$THRESHOLD+2] ]]; then
msg "*** Device \"$name\" [$DEVICE] is within proximity"
state="near"
$NEAR_CMD > /dev/null 2>&1
STARTX_PID=$(pgrep startx)
fi
fi
msg "state = $state, RSSI = $rssi"
fi
sleep $CHECK_INTERVAL
done
|
[edit] making it better
Work grate here.
Hay, According to a post at the BlueZ ML , I see that python may be used to write an event driven program. then there wouldn't be a need to pool the BT device: post
But I dont know python :-(
[edit] Security concerns
There's a very subtle security issue here.
Firstly, there's an unsubtle issue. Unless the link is encrypted, anyone can pretend to be your phone by faking the Bluetooth address. So, first step, make sure the link is encrypted (or simply don't trust the RSSI unless the link is encrypted and fall back to some secondary mechanism such as a timeout).
Then there's the subtle issue. RSSI is probably estimated by examining on all packets the device receives, not just those that contain data. Unfortunately, only the data is encrypted. This means an attacker could inject high strength packets with no payload onto link while you're out of range. This might be enough to cause your screen to unlock.
So, second step, don't use automatic unlocking if you want any semblence of security.
Even this second step isn't sufficient. An attacker could inject periodic high strength packets while the screen is unlocked and thus prevent the screen from locking as you walk away.
So, I wouldn't recommend this as the sole screen locking mechanism for any high security application.
Coupling this method with a normal screen saver timeout might form a good second line of defence. If you walk away from your screen without locking it then if there's no attacker present the screen will lock faster than without the RSSI checking. Similarly, if an attacker is present and you forget to lock your screen then you're no worse of than if you'd just had a timer (which is a method that suits most people just fine).
-- Steven (a Bluetooth firmware engineer using guest access) 19:27, 7 February 2006 (GMT)
Here are my additions:
- I use it to log on and off from the home and pcs
- I set a margin so FAR is when below -6 and Near is above -4 , so if I am standing at the door , my pc wont go nutch.
- I ping the cellular if hcitool cc doesnt work. it seems to help. u need to add l2ping to the sudo for that user.
| Code: btproximity.sh |
#!/bin/bash
#set -o verbose sh -v
DEVICE="00:0E:6D:45:97:A1"
CHECK_INTERVAL=2
THRESHOLD=-6
STARTX_PID=0
FAR_CMD='/bin/kill -9 $STARTX_PID'
NEAR_CMD='/usr/bin/startx -- :1'
HCITOOL="sudo /usr/bin/hcitool"
DEBUG="~/log/btproximity.log"
connected=0
function msg {
echo "$1" #>> "$DEBUG"
}
function check_connection {
connected=0;
found=0
for s in `$HCITOOL con`; do
if [[ "$s" == "$DEVICE" ]]; then
found=1;
fi
done
if [[ $found == 1 ]]; then
connected=1;
else
msg 'Attempting connection...'
if [ -z "`$HCITOOL cc $DEVICE 2>&1`" ]; then
msg 'Connected.'
connected=1;
else
if [ -z "`l2ping -c 2 $DEVICE 2>&1`" ]; then
if [ -z "`$HCITOOL cc $DEVICE 2>&1`" ]; then
msg 'Connected.'
connected=1;
else
msg "ERROR: Could not connect to device $DEVICE."
connected=0;
fi
fi
fi
fi
}
check_connection
while [[ $connected -eq 0 ]]; do
check_connection
sleep 3
done
name=`$HCITOOL name $DEVICE`
msg "Monitoring proximity of \"$name\" [$DEVICE]";
state="near"
while /bin/true; do
check_connection
if [[ $connected -eq 1 ]]; then
rssi=$($HCITOOL rssi $DEVICE | sed -e 's/RSSI return value: //g')
if [[ $rssi -le $THRESHOLD ]]; then
if [[ "$state" == "near" ]]; then
msg "*** Device \"$name\" [$DEVICE] has left proximity"
state="far"
$FAR_CMD > /dev/null 2>&1
fi
else
fi
else
if [[ "$state" == "far" && $rssi -ge $[$THRESHOLD+2] ]]; then
msg "*** Device \"$name\" [$DEVICE] is within proximity"
state="near"
$NEAR_CMD > /dev/null 2>&1
STARTX_PID=$(pgrep startx)
fi
fi
msg "state = $state, RSSI = $rssi"
fi
sleep $CHECK_INTERVAL
done
|
[edit] perl script
I've got a link for you. It's an untested perl script. http://www.chaostal.de/members/balle/bluetooth/blue-cmd.txt
[edit] What about console locking ?
Nice work, but I need to lock and unlock a console for a server without X.
To unlock it it-s simple: login with user and password, then verify if the Bluetooth device is in range. If it's not then logout, else drop to prompt.
To lock run the script but instead of calling kscreensaver call logout.
Simple as that.
Now since I'm not familiar with bash I'll need a little help:
1. Where should I call the script to check if my Bluetooth device is in range whan I login ? is it /etc/login.access ? Or is it ~/.bashrc
2. How do I split the bash file in two: one that searches and locks (as in logout) the console when the device is no longer in range and another that searches if the device in range when I login with name and password?
3 Is 'screen' a solution for not losing all the work done ? As in 'screen' when I first login, logout (and the work is still there), login and 'screen -r' back to my work.
Thanks.
PS: keep up the good work.
Fuzzy
- Hi
- I think pam_blue is what you are looking for. pam_blue
- It's a pam module so even login gdm works automatically when my phone is near my computer.
- -- ticapix
[edit] l2ping
I did pretty much the same thing with l2ping instead of hcitool. It seems to work slightly faster. (It takes hcitool rssi about 20 seconds to notice I'm gone.) --76.201.17.71 20:02, 17 July 2007 (UTC)
[edit] blueproximity
You can install blueproximity, that integrates with gnome, with an icon tray, and have a very easy and nice graphical appearance.
