You are not logged in.

#1 2021-10-15 06:56:48

Neokil
Member
Registered: 2021-10-15
Posts: 3

[SOLVED] Create UDEV-Rule for Bluetooth-Headset

Hello there,

I am new here and hope that you guys can help me with my UDEV-Rules.
The Issue that I am trying to solve is, that whenever I connect my Bluetooth-Headset the wrong Sound-Profile is selected, but I found out that I can easily change the Profile using

pactl set-card-profile $(pactl list short cards | grep bluez_card | cut -f1) handsfree_head_unit

To automate this I thought I could simply create a UDEV-Rule that would switch the profile whenever the Headset is connected, but I cannot get the rule to execute.
I had a look at the udev-monitoring:

$ udevadm monitor --environment --udev
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing

UDEV  [146050.378395] add      /devices/pci0000:00/0000:00:14.0/usb3/3-10/3-10:1.0/bluetooth/hci0/hci0:256 (bluetooth)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb3/3-10/3-10:1.0/bluetooth/hci0/hci0:256
SUBSYSTEM=bluetooth
DEVTYPE=link
SEQNUM=60752
USEC_INITIALIZED=146050376735
SYSTEMD_ALIAS=/sys/subsystem/bluetooth/devices/hci0:256
SYSTEMD_WANTS=bluetooth.target
SYSTEMD_USER_WANTS=bluetooth.target
TAGS=:systemd:
CURRENT_TAGS=:systemd:

UDEV  [146051.179783] add      /devices/virtual/input/input82 (input)
ACTION=add
DEVPATH=/devices/virtual/input/input82
SUBSYSTEM=input
PRODUCT=5/ecb/1f41/1f
NAME="JBL CLUB950NC (AVRCP)"
PHYS="f0:77:c3:5c:73:8e"
PROP=0
EV=100007
KEY=xxx
REL=0
MODALIAS=input:b0005v0ECBp1F41e001F-e0,1,2,14,k71,72,73,8A,8B,A3,A5,A6,A7,A8,AB,AE,C8,C9,D0,161,164,166,16A,16C,18B,18E,18F,190,191,192,193,195,ramlsfw
SEQNUM=60753
USEC_INITIALIZED=146051178091
ID_INPUT=1
ID_INPUT_KEY=1
ID_BUS=bluetooth
TAGS=:seat:
CURRENT_TAGS=:seat:

UDEV  [146051.320235] add      /devices/virtual/input/input82/event10 (input)
ACTION=add
DEVPATH=/devices/virtual/input/input82/event10
SUBSYSTEM=input
DEVNAME=/dev/input/event10
SEQNUM=60754
USEC_INITIALIZED=146051318681
ID_INPUT=1
ID_INPUT_KEY=1
ID_BUS=bluetooth
LIBINPUT_DEVICE_GROUP=5/ecb/1f41:f0:77:c3:5c:73:8e
MAJOR=13
MINOR=74
TAGS=:power-switch:
CURRENT_TAGS=:power-switch:

and from that I came up with a few rules that I tried because from the Wiki I was not sure what the correct thing would be.
For Debugging I am using an echo-command to write into a temp-file so I can see if the command was executed at all but until now it does not seem to work

$ cat /etc/udev/rules.d/99-bluetooth-headset-profile.rules
SUBSYSTEM=="input", ATTRS{address}=="f0:77:c3:5c:73:8e", RUN+="echo 'attr-addr' | tee /tmp/udev-test"
SUBSYSTEM=="input", ATTRS{PHYS}=="f0:77:c3:5c:73:8e", RUN+="echo 'attr-phys' | tee /tmp/udev-test"
SUBSYSTEM=="input", ENV{PHYS}=="f0:77:c3:5c:73:8e", RUN+="echo 'env-phys' | tee /tmp/udev-test"

Am I getting something fundamentally wrong here?

Greetings
Neokil

Last edited by Neokil (2021-10-20 13:27:45)

Offline

#2 2021-10-15 08:51:35

V1del
Forum Moderator
Registered: 2012-10-16
Posts: 24,461

Re: [SOLVED] Create UDEV-Rule for Bluetooth-Headset

The one inherent problem with your rules is that you try to use shell primitives in the RUN= clause. udev's RUN isn't a shell so the pipe has no meaning, I'm also fairly certain you can't rely on PATH and should use fully qualified paths. So pop that echo into an actual script with a shebang and make it executable.

#!/usr/bin/bash
echo $@ >> /tmp/udev-test

make it executable and use

SUBSYSTEM=="input", ATTRS{address}=="f0:77:c3:5c:73:8e", RUN+="/path/to/script attr-addr"
SUBSYSTEM=="input", ATTRS{PHYS}=="f0:77:c3:5c:73:8e", RUN+="/path/to/script  attr-phys "
SUBSYSTEM=="input", ENV{PHYS}=="f0:77:c3:5c:73:8e", RUN+="/path/to/script env-phys"

That's for the inherent problem in the rules.

As for your actual issue, if you are using pulseaudio then you can disable the automatic profile switching for bluetooth headset if you add auto-switch=0 to module-bluetooth-policy in your /etc/pulse/default.pa which might be a bit of an easier change, assuming the profile switch happens due to that rule.

Last edited by V1del (2021-10-15 08:52:19)

Offline

#3 2021-10-15 10:09:07

Neokil
Member
Registered: 2021-10-15
Posts: 3

Re: [SOLVED] Create UDEV-Rule for Bluetooth-Headset

Thanks for the hint that RUN= is no shell, I did not keep that in mind and the echos get executed just fine when I move them into a script file.

The Issue with the Profiles is the following, this is the pulse-audio-info for the headset

Card #9
	Name: bluez_card.98_52_3D_7B_20_61
	Driver: module-bluez5-device.c
	Owner Module: 34
	Properties:
		device.description = "JBL CLUB950NC"
		device.string = "98:52:3D:7B:20:61"
		device.api = "bluez"
		device.class = "sound"
		device.bus = "bluetooth"
		device.form_factor = "headset"
		bluez.path = "/org/bluez/hci0/dev_98_52_3D_7B_20_61"
		bluez.class = "0x240404"
		bluez.alias = "JBL CLUB950NC"
		device.icon_name = "audio-headset-bluetooth"
		device.intended_roles = "phone"
		bluetooth.codec = "mSBC"
	Profiles:
		a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 40, available: yes)
		handsfree_head_unit: Handsfree Head Unit (HFP) (sinks: 1, sources: 1, priority: 30, available: yes)
		off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
	Active Profile: handsfree_head_unit
	Ports:
		headset-output: Headset (type: Headset, priority: 0, latency offset: 0 usec, availability unknown)
			Part of profile(s): a2dp_sink, handsfree_head_unit
		headset-input: Headset (type: Headset, priority: 0, latency offset: 0 usec, availability unknown)
			Part of profile(s): handsfree_head_unit

The issue is, that the "a2dp_sink" is the default profile and I always have to manually switch the profile to "handsfree_head_unit" whenever I need to use a mic (which is 99% of the time when I use the headset). As far as I understood the "auto-switch"-feature is supposed to automatically do that but it stays on the "a2dp_sink" profile when I start using the mic and it records everything extremely loud so it overdrives completely, which is a not so good experience for the other people in the video-meeting.
And since I could not find a possibility to disable the first profile I thought the easiest way would be to automatically switch profile as soon as the headset is connected.
But maybe there is a build-in solution to my problem and I just did not find it yet?

Offline

#4 2021-10-15 11:17:32

V1del
Forum Moderator
Registered: 2012-10-16
Posts: 24,461

Re: [SOLVED] Create UDEV-Rule for Bluetooth-Headset

The point of the rule is to switch to "the best available profile for the given time" which is a2dp for the majority of normal usecases so it will by default always select a2dp since that what most people want when not actively recording. As mentioned in the link the logical switch to handsfree will by default only happen in the limitedish subset of well behaved recording clients that actively set their role to phone (... check 'pactl list source-outputs') . Since you apparently just want it to be handsfree regardless, you can "adjust" that logic for this case.

So from this perspective you have two options, either switch the auto-switch=0 which should disable this logic and instead turn to the normal fallback of "we should pick whatever the user intentionally picked last", or set it to 2 which should make it switch more aggressively when any recording client appears.

Also another option I forgot because it's new, as of pulse 15 you can tell it to keep to a profile without any of the other heuristics triggering: https://www.freedesktop.org/wiki/Softwa … ettosticky

If you are trying to do this via a normal udev rule there are multiple things you'd need to consider which would be better handled in pulse itself, you'd need to expose your environment to the udev rule and this would be a oneshot so if the heuristics do change it back to a2dp from within pulse you are back at square one and you'd likely need to add some artificial delay since udev will likely run before pulse has registered the device.

All of this is solvable in an eventual script, but imo using pulses/the servers capabilities directly will lead to more consistent results.

Offline

#5 2021-10-20 09:29:52

Neokil
Member
Registered: 2021-10-15
Posts: 3

Re: [SOLVED] Create UDEV-Rule for Bluetooth-Headset

Sorry for not replying for a few days. First I want to thank you for your help, the "other option" with the sticky-profile worked just fine and I learned a lot regarding udev on the way (even if I dont need it for that now).
Thanks and have a nice day

Offline

#6 2021-10-20 09:39:30

V1del
Forum Moderator
Registered: 2012-10-16
Posts: 24,461

Re: [SOLVED] Create UDEV-Rule for Bluetooth-Headset

Glad to hear, please mark the topic as [SOLVED] by editing the title in your first post.

Offline

Board footer

Powered by FluxBB