site  contact  subhomenews

Integrating bluetooth with pup_event

January 07, 2020 — BarryK

I posted about bluetooth audio working in Easy 2.2:

https://bkhome.org/news/202001/audiosonic-e920-speaker-working-with-easyos-22.html

A lot of things have to happen "under the bonnet" for bluetooth to work properly, such as daemons that start and stop when certain conditions are met. I have integrated bluetooth and bluez-alsa daemon loading with pup_event, and this is expected to also work with hot-plugging of bluetooth USB dongles.

It starts with a udev rule, /etc/udev/rules.d/91-pup_event.rules:

#200107 pup_event bluetooth hardware detection.
KERNEL=="hci[0-9]",SUBSYSTEM=="bluetooth",ACTION=="add",RUN+="/usr/local/pup_event/bluetoothhw"
KERNEL=="hci[0-9]",SUBSYSTEM=="bluetooth",ACTION=="remove",RUN+="/usr/local/pup_event/bluetoothhw"

The 'bluetoothhw' script will be called at bootup if bluetooth hardware exists, or if a dongle is plugged in or removed.

Here is the content of /usr/local/pup_event/bluetoothhw:

#!/bin/ash
#20-01-07 handler for bluetooth hardware.
#not using pup_event_frontend_d to detect bluetooth, instead have a udev
#rule, at /etc/udev/rules.d/91-pup_event.rules
#creation or removal of hci0, hci1, etc in /sys/class/bluetooth will call this script.

#needs to be delayed until after rc.services_ipc has called 'bluetoothhw' value...
. /etc/eventmanager

mkdir -p /tmp/pup_event_backend
HCIs="$(ls -1 /sys/class/bluetooth 2>/dev/null | tr '\n' ' ' | tr -s ' ' | sed -e 's% $%%')"
echo -n "${HCIs}" > /tmp/pup_event_backend/bluetoothhw_

if [ "${PE_SERVICE_MANAGER/* bluetoothhw*/}" == "" ];then
#/etc/rc.d/rc.services_ipc will have run pup_event_ipc which will be waiting on change
# to a /tmp/pup_event_ipc/bluetoothhw_* file...
CNT=0; FEXIST=0
while [ $CNT -lt 11 ];do
for aBT in /tmp/pup_event_ipc/bluetoothhw_*
do
[ "$aBT" == "" ] && continue
echo -n "${HCIs}" > ${aBT}
FEXIST=1
done
[ $FEXIST -eq 1 ] && break
sleep 1
CNT=$(($CNT+1))
done
fi

If there is one bluetooth hardware interface, usually named "hci0", this is written to /tmp/pup_event_backend/bluetoothhw_, or more than one, space-delimited, or an empty file is written if no interfaces (or dongle unplugged).

The BT interface, or lack thereof, is also written to any /tmp/pup_event_ipc/bluetoothhw_* files. These are the pup_event IPC mechanism -- look in /usr/local/pup_event for documentation on pup_event and IPC.

File /etc/eventmanager has this variable:

#180222 simple ipc-based service manager
#ref: /etc/rc.d/rc.services, rc.services_ipc
#names of services in /etc/init.d that must only start when a condition is met...
#format of each space-delimited parameter: dep1[:dep2[...]]%service1[:service2[...]]
#ex: network%rc.samba:sshd
#180228 optional append "ONESHOT" if no "stop)" option in script.
#200107 bluetoothhw condition, refer /usr/local/pup_event/bluetoothhw
# 'bluealsa' is first, to make sure runs before 'bluealsa'...
# note, rc.services_ipc stops the services in reverse order, so bluealsa will stop first.
PE_SERVICE_MANAGER='network%cups-net-fixONESHOT:qsyncONESHOT:dnsmasq:ec-net bluetoothhw%bluetooth:bluealsa'

At bootup, /etc/rc.d/rc.services executes the services (scripts) in /etc/init.d/, however, those defined in the 'PE_SERVICE_MANAGER' variable get passed on to /etc/rc.d/rc.services_ipc, which will execute them when certain criteria are met. For scripts 'bluetooth' and 'bluealsa', that criteria is 'bluetoothhw'.

Summarizing, when a change occurs to a /tmp/pup_event_ipc/bluetoothhw_* file, /etc/rc.d/rc.services_ipc will be triggered to either start or stop 'bluetooth' and 'bluealsa' service scripts. Start if there is a 'hci0' interface, or stop if there is no interface (such as dongle unplugged).

It works, but there are still details to be finished.  Quite a lot of details, to get some kind of easy GUI control.  The next thing that I need to look at is integration of bluetooth into Multiple Sound Card Wizard -- James (jamesbond in the Puppy Forum) has done a lot of work on this, for Fatdog. 

Tags: easy