
- power on
- agent on
- default-agent
- pairable on
- discoverable on
Code: Select all
#!/bin/bash
# Gene Weber - February 3rd 2018
#
# Uses bluetoothctl and empty-expect to check for and establish bluetooth device pairing.
# sudo apt install empty-expect
#
# Add the line: @reboot /home/pi/filename.sh to the cron system daemon using
# crontab -u pi -e
#
# This script can also be run on the Linux PC to be paired by changing only the Device_ID.
#
# "paired-devices" and "discoverable on" do not work using empty on Pi Zero W in cron,
# so this script works around these issues.
# Bluetooth ID of device to be paired.
DEVICE_ID=AA:11:A1:BB:2B:C3
PAIR_STRING="Device "$DEVICE_ID
rm empty.log
rm paired.log
# Delay until bluetooth service is running after power up.
RETURN_STATUS=1
until [ $RETURN_STATUS -eq 0 ]
do
sleep 1
sudo service bluetooth status | grep 'Status: "Running"' >empty.log
RETURN_STATUS=$?
done
PASS=1
PAIRED=1
while [ $PAIRED -ne 0 ]
do
echo -e "This is pairing attempt "$PASS".\n" >paired.log
# Write list of paired devices to log file.
bluetoothctl << EOF 2>&1 >>paired.log
paired-devices
exit
EOF
# Check if device ID is in the list of paired devices.
grep ^"$PAIR_STRING" paired.log >>empty.log
PAIRED=$?
# If device ID isn't paired, set controller to proper state and pair devices.
if [ $PAIRED -ne 0 ]
then
# Fork a bluetoothctl process. Capture PID and log.
# BTC.in and BTC.out are fifos for inter-process communication.
empty -f -i BTC.in -o BTC.out -p empty.pid -L empty.log bluetoothctl
# Allow some start up time for bluetoothctl
sleep 2
# Send power on command.
empty -s -o BTC.in 'power on\n'
# Watch for return of "Changing power on succeeded", then send agent on command.
empty -w -i BTC.out -o BTC.in succeeded 'agent on\n'
# Watch for return of "Agent registered", then send default-agent command.
empty -w -i BTC.out -o BTC.in registered 'default-agent\n'
# Watch for return of "Default agent request successful", then send pairable on command.
empty -w -i BTC.out -o BTC.in successful 'pairable on\n'
# Watch for return of "Changing pairable on succeeded", then trust Device.
empty -w -i BTC.out -o BTC.in succeeded 'trust '$DEVICE_ID'\n'
# Watch for return of "trust succeeded" or "not available", then attempt pairing.
# If Device was not availble to trust, it won't be available to pair, but that's OK.
empty -w -i BTC.out -o BTC.in succeeded 'pair '$DEVICE_ID'\n' available 'pair '$DEVICE_ID'\n'
# Watch for "Pairing successful", "not available" or "org.bluez.Error.ConnectionAttemptFailed".
# Start scanning of not available, else exit.
empty -w -i BTC.out -o BTC.in successful 'exit\n' available 'scan on\n' ConnectionAttemptFailed 'exit\n'
# Allow time for exit and PID removal.
sleep 2
# If PID still exists then Device was not availble and scan was started.
if [ -f "empty.pid" ]
then
# Allow up to a 3 minutes to find the desired Device ID, turn scan off if found.
empty -t 180 -w -i BTC.out -o BTC.in $DEVICE_ID 'scan off\n'
# Allow time after device is found before attempting next command.
sleep 3
# Watch for "Discovery stopped", then trust Device.
empty -w -i BTC.out -o BTC.in stopped 'trust '$DEVICE_ID'\n'
# Watch for "trust succeeded", then attempt pairing.
empty -w -i BTC.out -o BTC.in succeeded 'pair '$DEVICE_ID'\n'
# Watch for "Pairing successful", "not available" or "org.bluez.Error.ConnectionAttemptFailed".
# Then send exit command.
empty -w -i BTC.out -o BTC.in successful 'exit\n' Failed 'exit\n' ConnectionAttemptFailed 'exit\n'
fi
fi
# Ensure that the empty process gets terminated if script fails for some reason.
sleep 2
if [ -f "empty.pid" ]
then
empty -k `cat ./empty.pid`
echo -e "\nPairing script failed.\n" >> empty.log
fi
# Allow 5 tries to pair before giving up
PASS=$((PASS + 1))
if [ $PASS -eq 6 ]
then
PAIRED=0
fi
done
# Make bluetooth discoverable in case the laptop needs to do the pairing.
bluetoothctl << EOF2 2>&1 >>paired.log
discoverable on
exit
EOF2