Skip to content

Instantly share code, notes, and snippets.

@apexskier
Last active May 7, 2017 20:17
Show Gist options
  • Save apexskier/9072112 to your computer and use it in GitHub Desktop.
Save apexskier/9072112 to your computer and use it in GitHub Desktop.
Car Bluetooth RasPi stuff
# /etc/udev/rules.d/99-input.rules
SUBSYSTEM=="input", GROUP="input", MODE="0660"
KERNEL=="input[0-9]*", RUN+="/usr/lib/udev/bluetooth"
# Configuration file for the audio service
# /etc/bluetooth/audio.conf
# This section contains options which are not specific to any
# particular interface
[General]
Enable=Source,Sink,Media,Socket
# Switch to master role for incoming connections (defaults to true)
#Master=true
# If we want to disable support for specific services
# Defaults to supporting all implemented services
#Disable=Control,Source
# SCO routing. Either PCM or HCI (in which case audio is routed to/from ALSA)
# Defaults to HCI
#SCORouting=PCM
# Automatically connect both A2DP and HFP/HSP profiles for incoming
# connections. Some headsets that support both profiles will only connect the
# other one automatically so the default setting of true is usually a good
# idea.
AutoConnect=true
# Headset interface specific options (i.e. options which affect how the audio
# service interacts with remote headset devices)
[Headset]
# Set to true to support HFP, false means only HSP is supported
# Defaults to true
HFP=true
# Maximum number of connected HSP/HFP devices per adapter. Defaults to 1
MaxConnected=1
# Set to true to enable use of fast connectable mode (faster page scanning)
# for HFP when incomming call starts. Default settings are restored after
# call is answered or rejected. Page scan interval is much shorter and page
# scan type changed to interlaced. Such allows faster connection initiated
# by a headset.
FastConnectable=false
# Just an example of potential config options for the other interfaces
#[A2DP]
#SBCSources=1
#MPEG12Sources=0
#!/bin/bash
pulseaudio --start
touch /home/pi/savedbtdevice
mac=""
paid=""
mac_=""
connected=0
macregex="\([0-9ABCDE]\{2\}:\)\{5\}[0-9ABCDE]\{2\}"
getmac() {
mac=`grep -o -m 1 "$macregex" /home/pi/savedbtdevice`
# use the first actively connected bt device if no saved mac
# TODO: filter to the first audio device
if [ -z "$mac" ]
then
mac=`hcitool con | grep SLAVE | grep -o -m 1 "$macregex"`
fi
mac_=${mac//:/_}
echo "got mac: '$mac'"
}
testcon() {
hcitool rssi $mac &>/dev/null
ret=$?
if [ $ret -ne 0 ]
then
connected=1
else
connected=0
fi
return $connected
}
mute() {
pacmd "set-sink-mute 0 1"
}
unmute() {
pacmd "set-sink-mute 0 0"
}
connect() {
getmac
if [ -z "$mac" ]
then
echo "no mac found"
return -1
fi
if [ -n "$LASTPAID" ]
then
disconnect
fi
mute
qpath=`qdbus --system org.bluez | grep "/dev_" | grep -m 1 "$mac_"`
qdbus --system org.bluez $qpath org.bluez.AudioSource.Disconnect > /dev/null 2> /dev/null
sleep 5
qdbus --system org.bluez $qpath org.bluez.AudioSource.Connect # > /dev/null
ret=$?
echo $ret
source=`pactl list | grep -m 1 "Name: bluez_source" | cut -c 8-`
sink=`pactl list | grep -m 1 "Name: alsa_output" | cut -c 8-`
paid=`pactl load-module module-loopback source=$source sink=$sink`
if testcon && [ -n "$paid" ]
then
echo "connected successfully to $mac"
echo "pulseaudio connected: [$paid] $source -> $sink"
unmute
else
echo "connection error"
exit -1
fi
export LASTPAID=paid
}
disconnect() {
mute
getmac
paid=$paid
if [ -z "$paid" ]
then
paid=$LASTPAID
fi
if [ -n "$paid" ]
then
pactl unload-module $paid
fi
qpath=`qdbus --system org.bluez | grep "/dev_" | grep -m 1 "$mac_"`
qdbus --system org.bluez $qpath org.bluez.AudioSource.Disconnect
testcon
}
# MAIN
getmac
if [ -n "$2" ]
then
echo "$2" > /home/pi/savedbtdevice
fi
case "$1" in
connect-notimeout)
disconnect
while :
do
if testcon
then
exit 0
else
connect
fi
sleep 1
done
;;
connect)
connect
;;
disconnect)
disconnect
;;
*)
echo "Usage: $0 {connect|disconnect} [mac]"
exit -1
;;
esac
exit 0
#!/bin/bash
# /usr/lib/udev/bluetooth
AUDIOSINK="alsa_output.platform-bcm2835_AUD0.0.analog-stereo"
echo "Bluetooth script: $ACTION" >> /var/log/bluetooth_dev
ACTION=$(expr "$ACTION" : "\([a-zA-Z]\+\).*")
if [ "$ACTION" = "add" ]
then
# Turn off BT discover mode before connecting existing BT device to audio
sudo hciconfig hci0 noscan
# Set volume level to 100 percent
amixer -q set Master 100%
pacmd set-sink-volume 0 65537
mac=`hcitool con | grep SLAVE | grep -o -m 1 "\([0-9ABCDE]\{2\}:\)\{5\}[0-9ABCDE]\{2\}"`
if [ -n "$mac" ]
then
echo "$mac connected" >> /home/pi/bt.log
touch /home/pi/savedbtdevice
echo $mac > /home/pi/savedbtdevice
su pi -c "/home/pi/auto-connect-bt.sh connect"
fi
# for dev in $(find /sys/devices/virtual/input/ -name input*)
# do
# if [ -f "$dev/name" ]
# then
# mac=$(cat "$dev/name" | sed 's/:/_/g')
# bluez_dev=bluez_source.$mac
# sleep 1
# CONFIRM=`sudo -u pi pactl list short | grep $bluez_dev`
# if [ ! -z "$CONFIRM" ]
# then
# echo "Setting audio source to: $bluez_dev" >> /var/log/bluetooth_dev
# echo pactl load-module module-loopback source=$bluez_dev sink=$AUDIOSINK rate=44100 adjust_time=0 >> /var/log/bluetooth_dev
# sudo -u pi pactl load-module module-loopback source=$bluez_dev sink=$AUDIOSINK rate=44100 adjust_time=0 >> /var/log/bluetooth_dev
# fi
# fi
# done
fi
if [ "$ACTION" = "remove" ]
then
# reenable bluetooth discovery
service bluetooth-agent start
fi
### BEGIN INIT INFO
# Provides: bluetooth-agent
# Required-Start: $remote_fs $syslog bluetooth pulseaudio
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Makes Bluetooth discoverable and connectable to 0000
# Description: Start Bluetooth-Agent at boot time.
### END INIT INFO
#! /bin/sh
# /etc/init.d/bluetooth-agent
USER=root
HOME=/root
BTPIN=0000
export USER HOME BTPIN
case "$1" in
start)
# turn on bluetooth and make discoverable
sudo hciconfig hci0 piscan
start-stop-daemon -S -x /usr/bin/bluetooth-agent -c pi -b -- 0000
echo "Bluetooth discoverable with the password 0000."
su pi -c "/home/pi/auto-connect-bt.sh connect-notimeout"
;;
stop)
echo "Stopping bluetooth agent."
start-stop-daemon -K -x /usr/bin/bluetooth-agent
;;
restart)
service bluetooth-agent stop
service bluetooth-agent start
;;
*)
echo "Usage: /etc/init.d/bluetooth-agent {start|stop}"
exit 1
;;
esac
exit 0
# /etc/bluetooth/main.conf
[General]
# List of plugins that should not be loaded on bluetoothd startup
#DisablePlugins = network,input
# Default adaper name
# %h - substituted for hostname
# %d - substituted for adapter id
Name = Sitkum
# Default device class. Only the major and minor device class bits are
# considered.
Class = 0x200420
# How long to stay in discoverable mode before going back to non-discoverable
# The value is in seconds. Default is 180, i.e. 3 minutes.
# 0 = disable timer, i.e. stay discoverable forever
DiscoverableTimeout = 0
# How long to stay in pairable mode before going back to non-discoverable
# The value is in seconds. Default is 0.
# 0 = disable timer, i.e. stay pairable forever
PairableTimeout = 0
# Use some other page timeout than the controller default one
# which is 16384 (10 seconds).
PageTimeout = 8192
# Discover scheduler interval used in Adapter.DiscoverDevices
# The value is in seconds. Defaults is 30.
DiscoverSchedulerInterval = 30
# Automatic connection for bonded devices driven by platform/user events.
# If a platform plugin uses this mechanism, automatic connections will be
# enabled during the interval defined below. Initially, this feature
# intends to be used to establish connections to ATT channels.
AutoConnectTimeout = 60
# What value should be assumed for the adapter Powered property when
# SetProperty(Powered, ...) hasn't been called yet. Defaults to true
InitiallyPowered = true
# Remember the previously stored Powered state when initializing adapters
RememberPowered = true
# Use vendor, product and version information for DID profile support.
# The values are separated by ":" and VID, PID and version.
#DeviceID = 1234:5678:abcd
# Do reverse service discovery for previously unknown devices that connect to
# us. This option is really only needed for qualification since the BITE tester
# doesn't like us doing reverse SDP for some test cases (though there could in
# theory be other useful purposes for this too). Defaults to true.
ReverseServiceDiscovery = true
# Enable name resolving after inquiry. Set it to 'false' if you don't need
# remote devices name and want shorter discovery cycle. Defaults to 'true'.
NameResolving = true
# Enable runtime persistency of debug link keys. Default is false which
# makes debug link keys valid only for the duration of the connection
# that they were created for.
DebugKeys = false
# Enable the GATT Attribute Server. Default is false, because it is only
# useful for testing.
AttributeServer = false
DisablePlugins = pnat
# RFCOMM configuration file.
# /cat/bluetooth/rfcomm.conf
rfcomm0 {
# Automatically bind the device at startup
bind no;
# Bluetooth address of the device
device E4:98:D6:55:2E:27;
# RFCOMM channel for the connection
channel 10;
# Description of the connection
comment "Dungeness";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment