You are not logged in.
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
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
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
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
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
Glad to hear, please mark the topic as [SOLVED] by editing the title in your first post.
Offline