🚨 PSA for distros 🚨
This MR is still in its early days, do not ship this to any branch of your distro!
I also do not want any social media buzz or whatever. I put in a lot of work into this to get it in an upstreamable shape, so the least you can do as a distro is to be patient and give developers the credit they deserve ;) Toot is out to the general public: https://fosstodon.org/@dylanvanassche/108221554988020250 Distros & maintainers violating this disclaimer will be called out in public. You have been warned!
MR STATUS: unreviewed, do not ship to any branch
I will update this description when the status changes regarding this.
Read more here: https://do-not-ship.it/
ModemManager integration in native-backend
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
MR dependencies
Depends on !631 (merged). The UPower support is included in the list of commits (first 5 commits), since it provides the necessary infrastructure for the AT commands, therefore that MR needs to be merged first. Once merged, this MR will be a few commits smaller.
Open questions for PulseAudio maintainers
- ModemManager uses several constants to signal a call status for example. I used some
#define
statements to define them, but they are also shipped through ModemManager's GLib library. Should we depend on that library or use these lightweight#define
statements? - What is still needed to land !631 (merged)? It blocks a lot this MR.
-
Some HFP devices such as the Sennheiser HD350BT have additionalImplemented in v2.\r\n
characters in its RFCOMM responses, breaking AT commands. My car multimedia system does something similar, I see^M
at the end of each AT command from it in PulseAudio logs. Do we need to add some function to clean them?
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