temp/pulseaudio: fork for Bluetooth HFP/HSP support
🚨 PSA for distros 🚨
The UPSTREAM MR is still in its early days, do not ship this to any stable branch of your distro!
Distros & maintainers violating this disclaimer will be called out in public. You have been warned!
UPSTREAM MR STATUS: unreviewed, but tested by pmOS developers, thanks! Can be shipped to unstable branches such as postmarketOS edge
I will update this description when the status changes regarding this.
UPSTREAM MR URL: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/693
Read more here: https://do-not-ship.it/
ModemManager integration in PulseAudio for Bluetooth HFP 1.8 support
PulseAudio has 2 backends for Bluetooth HFP: native-backend & ofono-backend. The latter includes audio support, HFP AT commands support, etc. completely bypassing PulseAudio. ModemManager is a similar daemon as oFono, but only handles the modem. Bluetooth HFP is not support, that's up to another daemon such as PulseAudio or PipeWire. This MR adds the necessary glue to allow PulseAudio talk to ModemManager if ModemManager is present, if not, the cellular AT commands report proper ERRORs, so the backend acts still like before.
Supported HFP 1.8 features
Followed the Bluetooth HFP 1.8 spec for implementing the following features:
- Accept call (
ATA
) - Reject call (
AT+CHUP
) - Hang up call (
AT+CHUP
) - Dial number (
ATD$number;
) - Ring indication (
RING
) - Query signal strength, roaming & service status, call status (
AT+CIND
) - Enhanced Error Reporting (
AT+CMEE
) - Configure indicators (
AT+BIA
) - Update HFP if an indicator changes (
+CIEV
) - Enhanced Call reporting (
AT+CLIP
&+CLIP
) - Call list (
AT+CLCC
) - DTMF tone generation during call (
AT+VTS
) - Subscriber number reporting (
AT+CNUM
) - Operator name reporting in both numeric & string format (
AT+COPS
) - Fake
AT+NREC
response: noise reduction is not active at all, but make the HF happy and following the spec by reporting 'OK' - Only reply
OK
to commands we actually support, as the spec wants it - Advertise AG new features through
AT+BRSF
- Restart codec negotiation if the HF asks for it (
AT+BCC
) - Support a bunch of out-of-spec AT commands (3GPP standard) as they are used by car multimedia systems:
-
AT+CGSN
: get IMEI -
AT+CGMR
: get modem revision ID -
AT+CGMI
: get modem name -
AT+CGMM
: get modem manufacturer -
AT+CREG?
: get service status
-
Unsupported HFP 1.8 features
Not supported since the Linux Mobile stack does not support these features yet in the various dialers (ModemManager has the necessary capabilities though):
- Call holding
- Call multiparty/conference I marked the code in various places where we can apply changes to implement these features in the future. This MR is already a lot, let's do that in a following up MR.
Other unsupported features are:
- Enhanced Voice Recognisation: needs some kind of voice assitant
- Memory dialing: needs phonebook access
- HF indicator: Enhanced Driver Safety. This indicator is not really documented, but Android supports it. No idea for what it is actually used.
This list is rather small after this MR so we have finally feature-parity with Android/iOS/brick phones
Testing tools for this MR
- Your Bluetooth HFP device: not all HFP devices support these features. My car multimedia system is the only one supporting them all. My headset only supports half of them.
- Pair & connect your HFP device
- Test each feature of your HFP device
-
nOBEX: provides an HFP client, instructions are explained in detail in their README. You can compare your Android phone in various scenarios with this MR, all AT commands & responses are printed out with nOBEX.
- Run the
hfp_client.py
as root after enabling--compat
in BlueZ - Pair & connect your phone (you might need to send some setup commands, see their README)
- AT commands can be send/received in nOBEX's hfp_client.
- Run the
Demo on my HFP headset
- Call is received on phone, headset is notified over RFCOMM
- Headset button is used to 'answer' the call, triggers sending
ATA
over RFCOMM - Headset button is used to 'end' the call, triggers sending
AT+CHUP
over RFCOMM - Call is ended, headset is notified over RFCOMM
Demo on my car multimedia system
HFP indicators
Call management
https://tube.tchncs.de/w/xbfPeVxkZF3TaurTh2DfYR
Tested by
Thanks to anyone who tested this MR! To avoid losing the test results in comments, I collect them here for upstream:
- @TravMurav: Briefly tested the MR on msm8916 wileyfox-crackling and a bunch of cheap-ish headsets: all three were able to ring on the call, button works to answer and drop the call, the headset that spells the number out did spell it out (in Chinese but I assume it said the right digits :)
- @TravMurav: Extensively tested the MR in a car and found an edge case where hanging up didn't work. Fixed in v7.
- @tiol11: Tested this MR extensively in a car, everything works with Phosh. Discovered a bug in KDE Plasma dialer related to this. This MR is not responsible for this, reported upstream.