3

I have a bluetooth headset and I need to execute a .sh file everytime I connect it to make it work. I don't want to troubleshoot this bug since I know there's already people looking into it.

But I'm interested on a way to run that .sh script every time I connect a bluetooth device. And, if it's possible, every time I connect a headset/this specific headset.

Maccer
  • 243

3 Answers3

4

Look into udev rules. See the ArchWiki article on udev rules and this question about running a script when a USB device is plugged in.

There are also already many questions on this site regarding bluetooth and udev rules. See:

jayhendren
  • 8,384
  • 2
  • 33
  • 58
  • The +Run key in a Udev-Rule is not longer working under systemd. ps -p 1 -o comm= –  Nov 11 '16 at 19:09
1

For me this worked (ubuntu 22.04 on Raspberry PI 4):

#!/usr/bin/env python3
# Toggles headset connection
import dbus
from gi.repository import GLib
from dbus.mainloop.glib import DBusGMainLoop

dev_id = '74_A3_4A_DF_BB_8A'

def signal_handler(args, *kwargs): if (dev_id in kwargs['path']) & (args[0] == 'org.bluez.MediaControl1'): if args[1]['Connected']: print('connected') else: print('disconnected')

DBusGMainLoop(set_as_default=True) bus = dbus.SystemBus() #register your signal callback bus.add_signal_receiver(signal_handler, bus_name='org.bluez', interface_keyword='interface', member_keyword='member', path_keyword='path', message_keyword='msg') loop = GLib.MainLoop() loop.run()

About how to automatically run this script on boot. When I first tried this with the systemd unit, it didn't work for me. The unit was started before device hci0 appeared. The working solution turned out to be adding the line:

ExecStartPre=hciconfig hci0 up

Here is an example:

[Unit]
Description=Служба управления phasetimer.
After=sound.target
After=bluetooth.target

[Service] Type=simple KillSignal=SIGINT WorkingDirectory=/home/zenbooster/git/phasetimer ExecStartPre=hciconfig hci0 up ExecStart=python3 /home/zenbooster/git/phasetimer/guardian.py Restart=on-failure SyslogIdentifier=phasetimer-guardian RestartSec=5 TimeoutStartSec=infinity

[Install] WantedBy=multi-user.target

-1

Well, I would try this:

  1. Open a shell (bash, sh, ksh) and type: set -e (enables errorhandling)
  2. Insert Your BT- device
  3. Type: echo $?

You should get a number larger than 0, which is an errorcode. Depending on which shell you use, there might be set some environment variables:

  • ERR=$?=Errorcode
  • ERL=Linenumber if trap was detected in a script.
  • $?=0 then there is no errorcode, and U dont need to read further.

Write a script, or test by hand:

trap 'ERR=$?;errorhandler' listofcodes

errorhandler is the script that decides what todo when any of the listofcodes occur.

The list could be 1 10 14 15 (17 18 ...) or just 1 number, the one you want to catch.

# script errorhandler
errorhandler(){
case $ERR in
    1)
#    here U can take action or perhaps just ignore
    return
    ;;
    *) 
#    action if errorcode was different from 1

    ;;


esac
}

You would place line 1-4 in /etc/profile or similar to make it systemwide.

In /etc there should be an rc.d or init.d containg start and stop scripts related to boot and change in runstate. There should be a scriptfile for your BT device, check it out, but don't change content unless ...

If the errorcode in line 2 is zero then you must dig deeper.

jasonwryan
  • 73,126