pulseaudio merge requestshttps://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests2024-03-08T15:03:57Zhttps://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/693bluetooth: enhanced HFP support in backend-native with ModemManager2024-03-08T15:03:57ZDylan Van Asschebluetooth: enhanced HFP support in backend-native with ModemManager#### :rotating_light: PSA for distros :rotating_light:
*This MR is still in its early days, **do not ship this to any branch of your distro**!
<del>I also do not want any social media buzz or whatever. I put in a lot of work into this ...#### :rotating_light: PSA for distros :rotating_light:
*This MR is still in its early days, **do not ship this to any branch of your distro**!
<del>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 ;)</del> 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! :fire:*
**MR STATUS**: unreviewed, do not ship to any branch<br>
I will update this description when the status changes regarding this.
![Don't Ship Badge](https://do-not-ship.it/dontshipwip.svg)<br>
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](https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=489628) 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 :tada:
## 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](https://github.com/nccgroup/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.
## MR dependencies
Depends on !631.
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
1. 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?
2. What is still needed to land !631? It blocks a lot this MR.
3. <del>Some HFP devices such as the Sennheiser HD350BT have additional `\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?</del> Implemented in v2.
## Demo on my HFP headset
1. Call is received on phone, headset is notified over RFCOMM
2. Headset button is used to 'answer' the call, triggers sending `ATA` over RFCOMM
3. Headset button is used to 'end' the call, triggers sending `AT+CHUP` over RFCOMM
4. Call is ended, headset is notified over RFCOMM
![bluetooth-hfp1](/uploads/b4b60b5d1c6b4a2b5b554cd5896dbb9b/bluetooth-hfp1.mp4)
## Demo on my car multimedia system
### Indicators
![bluetooth-hfp-indicators](/uploads/70299eedd6fe79512c06e916040510ac/bluetooth-hfp-indicators.jpg)
### Call management
https://tube.tchncs.de/w/xbfPeVxkZF3TaurTh2DfYRhttps://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/663bluez5: do NameHasOwner before using org.bluez2021-12-15T18:16:11ZWim Taymansbluez5: do NameHasOwner before using org.bluezWe should not be using org.bluez when the bluetooth service is not
running or else we might try to activate it. The activation of the
bluetooth service should be done at boot time.We should not be using org.bluez when the bluetooth service is not
running or else we might try to activate it. The activation of the
bluetooth service should be done at boot time.https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/50WIP: Don't create card profile for unsupported Bluetooth profiles2021-10-01T09:27:05ZJoão Paulo Rechi VitaWIP: Don't create card profile for unsupported Bluetooth profilesCurrently we decide which card profiles should be created based solely on the list of UUIDs supported by the remote device. This used to be accurate when having PulseAudio running meant all supported audio profiles would be registered wi...Currently we decide which card profiles should be created based solely on the list of UUIDs supported by the remote device. This used to be accurate when having PulseAudio running meant all supported audio profiles would be registered with the local adapter, but things are a bit more dynamic now and only the null headset backend may be available.
This series also lays the groundwork for having a mechanism to disable certain Bluetooth profiles on specific products, based on DMI or device-tree ids. I am not entirely sure that mechanism is something we would want upstream, but I do need it downstream to avoid exposing a broken profile on a product where SCO connections don't really work (thus HSP / HFP don't work either). For the curious reader, that mechanism is implemented by the last two commits of https://gitlab.freedesktop.org/jprvita/pulseaudio/tree/bluetooth-disable-profiles-per-product.https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/592bluetooth: backend-native: Handle RegisterProfile failure2021-10-01T09:27:05ZJoão Paulo Rechi Vitabluetooth: backend-native: Handle RegisterProfile failureThis is how we have been working around https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/303 in Endless OS for the case where PulseAudio is brought up in the user session before PulseAudio in the GDM session has finished, in...This is how we have been working around https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/303 in Endless OS for the case where PulseAudio is brought up in the user session before PulseAudio in the GDM session has finished, in which case the later PulseAudio instance fails to register Bluetooth profiles with bluetoothd.
This depends on https://lore.kernel.org/linux-bluetooth/20210611020728.15233-1-jprvita@endlessos.org/ on the BlueZ side.https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/254bluetooth: add support of mSBC codec to HFP profile2021-04-26T13:53:05ZPhilipp Skadorovbluetooth: add support of mSBC codec to HFP profileThe work is based on work by Sathish Narasimman from Intel: https://patchwork.freedesktop.org/patch/245272/
It re-uses mSBC encoding/decoding code from the above patch-work but re-works sending over the streaming socket,
so it addresses ...The work is based on work by Sathish Narasimman from Intel: https://patchwork.freedesktop.org/patch/245272/
It re-uses mSBC encoding/decoding code from the above patch-work but re-works sending over the streaming socket,
so it addresses the issue of MTU (48) different from mSBC frame size (60).https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/522Draft: bluetooth: assume software volume control until peer replies2021-03-15T16:43:19ZIgor KovalenkoDraft: bluetooth: assume software volume control until peer repliesSupport for remote audio volume control is optional for HSP and HFP profiles,
and there is no feedback from peer for +VGM and +VGS.
In practice remote volume control is implemented for speaker and changing volume
using +VGS reply works,...Support for remote audio volume control is optional for HSP and HFP profiles,
and there is no feedback from peer for +VGM and +VGS.
In practice remote volume control is implemented for speaker and changing volume
using +VGS reply works, while doing the same with +VGM for mic does not.
Assume software volume control for peer mic until peer sends AT+VGM= command
which should mean peer supports remote volume control for mic as well.
This change is based on Rodrigo Araujo's work here
https://lists.freedesktop.org/archives/pulseaudio-discuss/2017-September/028820.html
Note the new `can_attenuate_source_volume` API change for transport also works for A2DP profiles. For A2DP new callbacks are not defined which indicates A2DP transport endpoints cannot do volume attenuation which turns on software volume control.https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/94bluetooth: HFP profile implementation2021-03-01T15:56:23ZDoron Somechbluetooth: HFP profile implementationSimple HFP profile implementation, none of the telephony features are supported, nonetheless, the implementation should be compliant with the HFP specification.
Headsets that don't support the HSP profile can now be used easily without o...Simple HFP profile implementation, none of the telephony features are supported, nonetheless, the implementation should be compliant with the HFP specification.
Headsets that don't support the HSP profile can now be used easily without ofono.