Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bluetooth HSP/HFP not working in Raspberry PI 3 #2229

Open
SoloVeniaASaludar opened this issue Oct 14, 2017 · 75 comments
Open

Bluetooth HSP/HFP not working in Raspberry PI 3 #2229

SoloVeniaASaludar opened this issue Oct 14, 2017 · 75 comments
Labels
Bluetooth Issue pelwell_there_is_no_escape Waiting for external input Waiting for a comment from the originator of the issue, or a collaborator.

Comments

@SoloVeniaASaludar
Copy link

SoloVeniaASaludar commented Oct 14, 2017

Trying to use a bluetooth mic/speaker in a raspberry pi 3 (headless).

Hardware is Raspberry pi 3, firmware updated today, running raspbian also dist-upgraded today. Using bluez and pulseaudio (system service start mode).

  • The device is trusted, paired and connects/disconnects without problems.
  • When device is initially connected, "pactl list" shows the device is using the profile named "headset_head_unit: Headset Head Unit (HSP/HFP) (sinks: 1, sources: 1, priority: 20, available: yes)". With this profile, no sound (trying to play with aplay command).
  • When profile is changed to "a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 10, available: yes)" (using command pactl set-card-profile), the sound is played correctly.

No error messages seen in any log file.

Moreover, if I "down" ("hciadmin hci0 down") the internal raspberry bluetooth controller and use instead an external bluetooth controller connected in an usb port, both modes works correctly. Thus, problem seems related with the bluetooth device in raspberry card.

These are result from some related commands.

pi@raspberrypi:~ $ uname -a
Linux raspberrypi 4.9.56-v7+ #1044 SMP Fri Oct 13 15:23:13 BST 2017 armv7l GNU/Linux

pi@raspberrypi:~ $ hciconfig -a
hci0:   Type: Primary  Bus: UART
    BD Address: B8:27:EB:7E:DA:2A  ACL MTU: 1021:8  SCO MTU: 64:1
    UP RUNNING 
    RX bytes:14641 acl:101 sco:0 events:1341 errors:0
    TX bytes:2208546 acl:2358 sco:7 commands:97 errors:0
    Features: 0xbf 0xfe 0xcf 0xfe 0xdb 0xff 0x7b 0x87
    Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3 
    Link policy: RSWITCH SNIFF 
    Link mode: SLAVE ACCEPT 
    Name: 'raspberrypi'
    Class: 0x0c0000
    Service Classes: Rendering, Capturing
    Device Class: Miscellaneous, 
    HCI Version: 4.1 (0x7)  Revision: 0x145
    LMP Version: 4.1 (0x7)  Subversion: 0x2209
    Manufacturer: Broadcom Corporation (15)

pi@raspberrypi:~ $ pactl list
...
Card #3
    Name: bluez_card.E8_07_BF_11_10_A0
    Driver: module-bluez5-device.c
    Owner Module: 15
    Properties:
        device.description = "SPUBT710"
        device.string = "E8:07:BF:11:10:A0"
        device.api = "bluez"
        device.class = "sound"
        device.bus = "bluetooth"
        device.form_factor = "speaker"
        bluez.path = "/org/bluez/hci0/dev_E8_07_BF_11_10_A0"
        bluez.class = "0x240414"
        bluez.alias = "SPUBT710"
        device.icon_name = "audio-speakers-bluetooth"
    Profiles:
        headset_head_unit: Headset Head Unit (HSP/HFP) (sinks: 1, sources: 1, priority: 20, available: yes)
        a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 10, available: yes)
        off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
    Active Profile: headset_head_unit
    Ports:
        speaker-output: Speaker (priority: 0, latency offset: 0 usec)
            Part of profile(s): headset_head_unit, a2dp_sink
        speaker-input: Bluetooth Input (priority: 0, latency offset: 0 usec)
            Part of profile(s): headset_head_unit 

# systemctl status bluetooth
● bluetooth.service - Bluetooth service
   Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2017-10-14 15:49:16 UTC; 36min ago
     Docs: man:bluetoothd(8)
 Main PID: 461 (bluetoothd)
   Status: "Running"
   CGroup: /system.slice/bluetooth.service
           └─461 /usr/lib/bluetooth/bluetoothd

Oct 14 15:49:16 raspberrypi bluetoothd[461]: Bluetooth daemon 5.43
Oct 14 15:49:16 raspberrypi systemd[1]: Started Bluetooth service.
Oct 14 15:49:16 raspberrypi bluetoothd[461]: Starting SDP server
Oct 14 15:49:16 raspberrypi bluetoothd[461]: Bluetooth management interface 1.14 initialized
Oct 14 15:49:16 raspberrypi bluetoothd[461]: Failed to obtain handles for "Service Changed" characteristic
Oct 14 15:49:16 raspberrypi bluetoothd[461]: Sap driver initialization failed.
Oct 14 15:49:16 raspberrypi bluetoothd[461]: sap-server: Operation not permitted (1)
Oct 14 15:49:16 raspberrypi bluetoothd[461]: Endpoint registered: sender=:1.3 path=/MediaEndpoint/A2DPSource
Oct 14 15:49:16 raspberrypi bluetoothd[461]: Endpoint registered: sender=:1.3 path=/MediaEndpoint/A2DPSink
Oct 14 15:55:04 raspberrypi bluetoothd[461]: /org/bluez/hci0/dev_E8_07_BF_11_10_A0/fd0: fd(24) ready

systemctl status pulseaudio

● pulseaudio.service - Pulse Audio
   Loaded: loaded (/etc/systemd/system/pulseaudio.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2017-10-14 15:49:12 UTC; 36min ago
 Main PID: 343 (pulseaudio)
   CGroup: /system.slice/pulseaudio.service
           └─343 /usr/bin/pulseaudio --system --disallow-exit --disable-shm --exit-idle-time=-1

Oct 14 15:49:12 raspberrypi pulseaudio[343]: W: [pulseaudio] main.c: OK, so you are running PA in system mode. Please make sure that you actually do want to do that.
Oct 14 15:49:12 raspberrypi pulseaudio[343]: W: [pulseaudio] main.c: Please read http://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/WhatIsWrongWithSystemWide/ for an explanation why system mode is usually a bad idea.
Oct 14 15:49:12 raspberrypi pulseaudio[343]: W: [pulseaudio] authkey.c: Failed to open cookie file '/var/run/pulse/.config/pulse/cookie': No such file or directory
Oct 14 15:49:12 raspberrypi pulseaudio[343]: W: [pulseaudio] authkey.c: Failed to load authentication key '/var/run/pulse/.config/pulse/cookie': No such file or directory
Oct 14 15:49:12 raspberrypi pulseaudio[343]: W: [pulseaudio] authkey.c: Failed to open cookie file '/var/run/pulse/.pulse-cookie': No such file or directory
Oct 14 15:49:12 raspberrypi pulseaudio[343]: W: [pulseaudio] authkey.c: Failed to load authentication key '/var/run/pulse/.pulse-cookie': No such file or directory
Oct 14 15:49:16 raspberrypi pulseaudio[343]: E: [pulseaudio] bluez5-util.c: Found duplicated D-Bus path for adapter /org/bluez/hci0
Oct 14 15:49:16 raspberrypi pulseaudio[343]: E: [pulseaudio] bluez5-util.c: Found duplicated D-Bus path for device /org/bluez/hci0/dev_E8_07_BF_11_10_A0
@pratham2003
Copy link

I'm facing the same issue too

1 similar comment
@Pillar1989
Copy link

I'm facing the same issue too

@JamesH65
Copy link
Contributor

JamesH65 commented Dec 5, 2017

Would it be possible for commenters to try the latest kernel (4.14) and see if the problems persists? Note, this is a testing branch, so should not be done on a critical system unless it's well backed up!

sudo BRANCH=next rpi-update

@JamesH65 JamesH65 added the Waiting for external input Waiting for a comment from the originator of the issue, or a collaborator. label Dec 5, 2017
@pelwell
Copy link
Contributor

pelwell commented Dec 5, 2017

It's not a kernel issue - it's a BlueZ limitation. As of version 5.0, BlueZ does not support HFP or HSP, only A2DP. I've not found an official explanation from BlueZ, but there are some notes from the PulseAudio devs here: https://www.freedesktop.org/wiki/Software/PulseAudio/Notes/5.0/

If anyone knows of a solution that doesn't involve installing BlueZ 4 as well I'll be interested to hear it.

@viktorgino
Copy link

To get HFP/HSP working properly you'll need PulseAudio 11 https://www.freedesktop.org/wiki/Software/PulseAudio/Notes/11.0/
HFP works using ofono, but it is only started fully working with version PA version 11.
@SoloVeniaASaludar can you try to install lates versions of PA, bluez and ofono and report back?

@bluetiger9
Copy link

bluetiger9 commented Jan 21, 2018

Seems that, we have a solution to use the HSP profile with Raspberry Pi 3’s built in BCM43438 chip. The culprit was the so called SCO audio routing. HSP / HFP uses SCO audio packets to transmit audio and in order to make PulseAudio work the packets must be routed to the HCI interface. This can be done by sending the the following HCI command:

sudo hcitool cmd 0x3F 0x01C 0x01 0x02 0x00 0x01 0x01

After issuing this command, both paplay and parecord should work with the HSP profile.

More details here:
https://www.spinics.net/lists/linux-bluetooth/msg73883.html
https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Bluetooth/#index8h3
http://youness.net/raspberry-pi/bluetooth-headset-raspberry-pi-3-ad2p-hsp#comment-2484

@pelwell
Copy link
Contributor

pelwell commented Jan 23, 2018

Ooh, interesting. That hci command that could easily be added to the Pi-specific script /usr/bin/btuart if it solves the problem.

@YOUN3SS
Copy link

YOUN3SS commented Feb 8, 2018

Hi,

I confirm that this command solves the problem.
More details: How To Connect Bluetooth Headset Or Speaker To Raspberry Pi 3

@kp339
Copy link

kp339 commented Apr 10, 2018

Hi,

hcitool cmd can solve the connect problem in HSP/HFP mode, but the sound is terrible, have distortion.
Do anyone have the same problem as I do?

Thanks!

@bluetiger9
Copy link

@kp339, the sound is a little noisy for me too. I contacted the Cypress's support, their FW team is checking the CYW43438's firmware right now.

@kp339
Copy link

kp339 commented Apr 10, 2018

@bluetiger9 If there is any progress, please let me know. Thanks!

@CliveWongTohSoon
Copy link

It happens to me too, the sound is too distorted until the speech recognition can't even work. Please let me know how to improve the sound quality.

@bluetiger9
Copy link

bluetiger9 commented May 23, 2018

The problem was identified as a timing issue in PulseAudio.

In an nutshell, PulseAudio uses a hard-coded (e)SCO packet size of 48 bytes, instead of using the packet size negotiated at the eSCO connect (ex 60 bytes). The timing logic used for SCO connections, is to send (e)SCO packets (one at a time), at each SCO packet received. If the negotiated packet size is bigger (ex 60 bytes) than the hard-coded 48 bytes, the SCO packets are received at a lower rate, which causes PulseAudio to send the SCO packets way too slow.

More details on the following [pulseaudio-discuss] thread:
[pulseaudio-discuss] Bluetooth - HSP / HFP - source based timing & hard-coded MTU causes SCO packets to be badly delayed

As a workaround PulseAudio 11.1 can be used, with the module-bluetooth-discover started with autodetect_mtu=yes parameter. The parameter can be set in /etc/pulse/default.pa:

.ifexists module-bluetooth-discover.so
load-module module-bluetooth-discover autodetect_mtu=yes
.endif

(note: be aware that this setting breaks the compatibility with some adapters)

The PulseAudio 11.1 is not yet available for Raspbian, but it can be compiled from source:

$ git clone git://anongit.freedesktop.org/pulseaudio/pulseaudio
$ cd pulseaudio
$ sudo apt-get build-dep pulseaudio
$ ./bootstrap.sh
$ make
$ sudo make install
$ sudo ldconfig

Cheers,
Attila

@kp339
Copy link

kp339 commented May 24, 2018

Yeah, and if your PulseAudio's version lower than 11.1, you can try this way:

  1. You should build pulseaudio from source like Attila push below
  2. Modify the mtu packets in source code, bcm43438 mtu packets is 64
diff --git a/src/modules/bluetooth/backend-native.c
index 8d9d95c..7dde1f8 100644
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -148,10 +148,10 @@ static int bluez5_sco_acquire_cb(pa_bluetooth_transport *t, bool optional, size_
      * by the kernel */
 
     if (imtu)
-        *imtu = 48;
+        *imtu = 64;
 
     if (omtu)
-        *omtu = 48;
+        *omtu = 64;

diff --git a/src/modules/bluetooth/backend-ofono.c
index 755df9e..e1091b6 100644
--- a/src/modules/bluetooth/backend-ofono.c
+++ b/src/modules/bluetooth/backend-ofono.c
@@ -170,9 +170,9 @@ static int hf_audio_agent_transport_acquire(pa_bluetooth_transport *t, bool opti
      * made available to userspace by the Bluetooth kernel subsystem.
      * Meanwhile the empiric value 48 will be used. */
     if (imtu)
-        *imtu = 48;
+        *imtu = 64;
     if (omtu)
-        *omtu = 48;
+        *omtu = 64;
 
     t->codec = card->codec;



  1. If you want to fit more devices, you can modify the code refer to the 11.1 source.

  2. Rebuild the pulseaudio source code and replace the libbluez5-util.so in system:
    $ sudo cp ./src/.libs/libbluez5-util.so /usr/lib/pulse-x.x/modules

  3. Reboot the system

  4. And from the test I found that before you connect your headset, you should enter HCI command first or you will find that your headset profile "headset_head_unit" available is no.

Thanks Attila.

@CliveWongTohSoon
Copy link

CliveWongTohSoon commented May 24, 2018

Hi @bluetiger9 the issue seems to be fixed, sound improves dramatically, thanks! However, I noticed that I can't seem to play anything in my root after using this (I need to be in the root to run manipulate GPIO on my pi), is there any fix? The audio does play with paplay audio.wav, but if I go to my root, paplay audio.wav gives error as such:

No protocol specified
xcb_connection_has_error() returned true
Connection failure: Connection refused
pa_context_connect() failed: Connection refused

Any idea how to fix?

@JamesH65
Copy link
Contributor

Can anybody give a précis of the current state of this? Sounds like it's pretty much fixed?

Related to #1401?

@pelwell
Copy link
Contributor

pelwell commented Jun 28, 2018

Yes, the two issues are (already) linked. The next Raspbian release (due shortly) includes a startup script to send the HCI command mentioned above that switches SCO traffic to the HCI interface.

@et-hzn
Copy link

et-hzn commented Oct 18, 2018

Indeed. Issues with SCO traffic routing and mtu packet size are fixed. I can confirm that but....
After using it for a while and making calls there is a timeout error on hci0;

I am using R-Pi3B+ with
Linux RPi-Host-1 4.14.71-v7+ #1145 SMP Fri Sep 21 15:38:35 BST 2018 armv7l GNU/Linux
Raspbian Stretch 9.4
PulseAudio 10.0 (patched for coping with the MTU size problem)
Bluez 5.50
Ofono 1.18

/var/log/kern.log shows something like this when the error occurs:

Oct 18 09:25:21 RPi-Host-1 kernel: [51675.649493] Bluetooth: hci0 command 0x0c24 tx timeout
Oct 18 09:25:21 RPi-Host-1 kernel: [51675.649742] Bluetooth: hci0: Frame reassembly failed (-84)
Oct 18 09:25:21 RPi-Host-1 kernel: [51675.649749] Bluetooth: hci0: Frame reassembly failed (-84)
Oct 18 09:25:21 RPi-Host-1 kernel: [51675.649808] Bluetooth: hci0: Frame reassembly failed (-84)
Oct 18 09:25:21 RPi-Host-1 kernel: [51675.649858] Bluetooth: hci0: Frame reassembly failed (-84)
Oct 18 09:25:21 RPi-Host-1 kernel: [51675.649893] Bluetooth: hci0: Frame reassembly failed (-84)
Oct 18 09:25:21 RPi-Host-1 kernel: [51675.649909] Bluetooth: hci0: Frame reassembly failed (-84)
Oct 18 09:25:21 RPi-Host-1 kernel: [51675.649980] Bluetooth: hci0: Frame reassembly failed (-84)
Oct 18 09:25:23 RPi-Host-1 kernel: [51677.719490] Bluetooth: hci0 command 0x0c52 tx timeout
Oct 18 09:25:25 RPi-Host-1 kernel: [51679.799507] Bluetooth: hci0 command 0x0406 tx timeout
Oct 18 09:28:56 RPi-Host-1 kernel: [51890.408019] Bluetooth: hci0 link tx timeout

The only way I have found until now to get it going again is re-booting the RaspberryPi.

Reloading bluetooth (sudo systemctl relaod bluetooth) does not solve this. And unloading the kernel modules (rmmod bluetooth) is impossible as the module is "in use"

Anybody knows of any progress in getting newer BCM43438 firmware? Or knows how to restart bluetooth without rebooting?

Thanks,

Engelbert

@oscargomezf
Copy link
Contributor

oscargomezf commented Oct 18, 2018 via email

@pelwell
Copy link
Contributor

pelwell commented Oct 18, 2018

I use the following script to reset the bluetooth interface - I call it btreset:

sudo killall hciattach
if grep -a Zero /proc/device-tree/model; then
  raspi-gpio set 45 op dl
  sleep 1
  raspi-gpio set 45 op dh
else
  /opt/vc/bin/vcmailbox 0x38041 8 8 128 0
  sleep 1
  /opt/vc/bin/vcmailbox 0x38041 8 8 128 1
fi
sleep 4
sudo btuart

@oscargomezf
Copy link
Contributor

oscargomezf commented Oct 18, 2018 via email

@pelwell
Copy link
Contributor

pelwell commented Oct 18, 2018

  1. It is 45 on the Zero, and 128 (GPIO 0 of the expander) on the 3B+.
  2. Just BT.
  3. Do you see the "... 0", sleep 1, "... 1"? That's low, then high.

@bluetiger9
Copy link

@CliveWongTohSoon, check out the following page:
Running PulseAudio as System-Wide Daemon

@et-hzn
Copy link

et-hzn commented Oct 19, 2018

Phil,

Thanks a lot. That indeed resets the bluetooth device and communication is re-established on my R-Pi3B+.

Now of course I would like to know why it gets stuck but that is probably a firmware problem somewhere. Would not know how to debug that.

Another thing I noticed is that after every HFP call I make the usage count of bluetooth kernel module is increasing by 1. Actually during the call it is increasing by 2 and when the call is finished only a +1 remains. So something is released but not everything.

Anybody any hints on how to attack this? Or is there a way to forcefully reload the bluetooth kernel module at regular interval to reset the count? "rmmod bluetooth" does not work obviously as the count is not 0 so the module is "in use"

Thanks,

Engelbert

@pelwell
Copy link
Contributor

pelwell commented Oct 19, 2018

Another thing I noticed is that after every HFP call I make the usage count of bluetooth kernel module is increasing by 1.

Although I understand the basic concepts I've never written a Bluetooth app of any description. However, a simple, repeatable problem like you describe sounds very fixable. If you can reduce your code down to the simple test and upload it somewhere with simple instructions (including links for installing any non-standard dependencies) I can take a look when I get a moment.

@oscargomezf
Copy link
Contributor

oscargomezf commented Oct 19, 2018 via email

@et-hzn
Copy link

et-hzn commented Oct 19, 2018

Well actually this is what I see:
Before a call:
#lsmod |grep bluetooth|grep hci_uart
bluetooth 368640 220 hci_uart,btbcm,rfcomm

After the call:
#lsmod |grep bluetooth|grep hci_uart
bluetooth 368640 221 hci_uart,btbcm,rfcomm

But I have no clue what is now exactly increasing and indeed as you point out does it harm?

An "rfkill list" on my R-Pi only shows this btw:

rfkill list

3: hci0: Bluetooth
Soft blocked: no
Hard blocked: no

@et-hzn
Copy link

et-hzn commented Oct 19, 2018

Phil,

Below how to do that. (to get it down to the very basic) but actually it is not a bluetooth app that I am developing it is actually getting HFP working stable (also using Ofono and Pulseaudio as part of this) so it continues to work over a long period of time.

You will need the ofono source to be installed as it contains a number of python scripts that will allow you to use ofono to make calls etc.

The basics actually comes down to this:

  1. Make sure bluetooth pairing between R-Pi and Mobile phone is succesfull and both are in connected state
  2. Make sure the "ofono modem" is enabled (use "enable-modem" from the ofono tools)
  3. Check the count using: lsmod |grep bluetooth (value = x)
  4. Make a call using "dial-number extension-to-be-dialed" from ofono tools
  5. Answer the call at the B-party (HFP now active and sound on headset/speaker on R-Pi side)
  6. Check the count (it is now increased by 2 so x+2).
  7. Terminate the call
  8. Check the count again. It is now x+1.

During the call 2 "sound channels" are opened via bluetooth to get the audio to/from the R-Pi. Maybe one of them is not released correctly? Could of course also be a PulseAudio or Ofono problem. And maybe it is no problem at all.
After booting the and before the first call the usage count is:28 and I now have it at 575 and still working OK

Engelbert

@pelwell
Copy link
Contributor

pelwell commented Oct 9, 2019

Thanks for the report - I've opened a case with Cypress.

@killerkalamari
Copy link

Having problems with SCO on a non-Raspberry Pi CYW43455 used in the recently discontinued Samsung Artik 710 module. Dunno if that helps any, but mentioning it just in case. Thanks for looking into this!

Also, maybe some Pi 3 B+'s use the CYW43455 as well, at least if this press release is accurate: https://www.cypress.com/news/cypress-delivers-robust-wireless-connectivity-raspberry-pi-3-model-b-iot-single-board-computer

@pelwell
Copy link
Contributor

pelwell commented Oct 14, 2019

We've never made a secret of the fact that all 3B+s use CYW43455.

@killerkalamari
Copy link

killerkalamari commented Oct 14, 2019

I just went ahead and tried that hcitool command on the CYW43455 and at least for me it got the audio to play. It clips on the end, but that's probably a separate issue (and I'm using bluealsa, so that could even be involved). However, this is not a Pi, so my results are not that relevant. I have a Pi 3 (older, non-B+) and Pi 4 and I plan on giving those a try when I can.

EDIT for offtopic info:
I was able to recreate the audio truncation issue with the Pi 3 (non-plus) and bluealsa with hsp-ag. Ended up not being able to test on the Pi 4 for unrelated reasons. Also tried the Pi 3 with pulseaudio in headset mode. With pulse the beginning of the audio was gone and the sound seemed to play slower than it should, with extremely bad quality. So, the results weren't as conclusive as I was hoping. It appears that there are probably software issues with both bluealsa and pulse... or there could also be further hardware problems, hard to say. There is a third non-free bluetooth stack for Linux, I might give it a try and see what happens.

EDIT 2 offtopic: Opened a bluealsa bug, here, and the truncation was resolved with a bluealsa source modification: arkq/bluez-alsa#260

@ole1986
Copy link

ole1986 commented Oct 16, 2019

Secret or not. I was expecting to have a proper working chip for WLAN and BLUETOOTH on my Pi 3 which is not the case and in addition to this people reporting several other issues, related to this ticket here.

@pelwell
Copy link
Contributor

pelwell commented Oct 17, 2019

FWIW, Cypress have acknowledged my request and forwarded it to the right person, but nothing more so far.

@pelwell
Copy link
Contributor

pelwell commented Oct 22, 2019

Cypress think that the required SCO audio routing is already enabled in the firmware. They would like a log of the HCI traffic to the modem, which you can capture by running "sudo btmon -w btmon.cap" somewhere, ideally before you pair the device. After pairing, connect to it and attempt to play something short - I use piano2.wav from https://www.kozco.com/tech/soundtests.html - then run the hcitool cmd line and try again. After successful playback you can Ctrl-C the btmon command and upload the resulting capture somewhere - it was about 500kB for me.

@pelwell pelwell added the Close within 30 days Issue will be closed within 30 days unless requested to stay open label Oct 28, 2019
@pelwell
Copy link
Contributor

pelwell commented Oct 28, 2019

Without HCI logs and/or a detailed description of the equipment and steps involved to reproduce the problem there is little we can do. Will close if no response in 30 days.

@aurelihein
Copy link

Hello,
Here is the test ask done on Rpi4 using SCO mode : 20191029-sco_issue_rpi4.zip
You will find the cmd line used for the test : 20191029-complete_log_cmdline
Let me know
Regards,

@pelwell
Copy link
Contributor

pelwell commented Oct 29, 2019

Thank you - that's very helpful, and it's been forwarded to Cypress.

@pelwell pelwell removed Close within 30 days Issue will be closed within 30 days unless requested to stay open Waiting for external input Waiting for a comment from the originator of the issue, or a collaborator. labels Oct 29, 2019
@pelwell
Copy link
Contributor

pelwell commented Nov 1, 2019

@aurelihein I have audio playing over HSP/HFP now. In order for it to work properly I had to follow this guide: https://hackaday.io/project/165208-an-old-rotary-phone-as-bluetooth-set/log/162491-setting-up-the-bluetooth

I started from a clean Raspbian install. Pairing and audio device selection can be done using the standard Raspbian Bluetooth tool (but note that starting pulseaudio will require the audio device is reselected, and I found I usually had to do it twice for it to work (there is a beep on connection, and I only got that on the second attempt).

There are one or two steps missing from the guide:

  1. ofono must be enabled and started. Running sudo systemctl enable --now ofono will start it immediately and at every boot.
  2. pulseaudio must be started - pulseaudio --start should do it.

If you don't edit default.pa it will use a2dp. If you don't patch pulseaudio with the correct mtu size it will sound strangely slowed down. If you don't start pulseaudio then when you play a sound it will try, then switch back to another output (HDMI for me).

Note that this assumes you are running Raspbian, which has the magic hcitool command in /usr/bin/bthelper. Without that (and if the headset has been powered off since it was last run) you'll get no sound.

@aurelihein
Copy link

Nope it does not work ! They are talking about Rpi zero !
I am talking about Rpi4 !! bthelper doesn't handle Rpi4 yet !

@pelwell
Copy link
Contributor

pelwell commented Nov 4, 2019

I was testing on a convenient 3B+ which runs the same firmware on the same hardware. The crucial difference is that the 3B+ doesn't have a MAC address from the new dc:a6:32 OUI. The bthelper command needs to be updated to also recognise the new OUI and apply the same patch. An offline task is then to figure out why the HCI cmd is necessary, given that according to Cypress this should be the default.

Try replacing the hciconfig ... grep ... line with:

/bin/hciconfig "$dev" | grep -qE "BD Address (B8:27:EB|DC:A6:32):" || exit 0

pelwell pushed a commit to pelwell/pi-bluetooth that referenced this issue Nov 4, 2019
The bthelper script uses the OUI of the BDADDR (Bluetooth MAC address)
to determine whether or not to run on a Bluetooth interface. Pi 4s
have BDADDRs from a new OUI range (DC:A6:32:...), meaning that
the "is it a Pi's on-board BT interface" test must be amended to include
that as a possibility.

See: raspberrypi/linux#2229 (comment)

Signed-off-by: Phil Elwell <[email protected]>
@pelwell
Copy link
Contributor

pelwell commented Nov 4, 2019

See RPi-Distro/pi-bluetooth#10.

XECDesign pushed a commit to RPi-Distro/pi-bluetooth that referenced this issue Nov 5, 2019
The bthelper script uses the OUI of the BDADDR (Bluetooth MAC address)
to determine whether or not to run on a Bluetooth interface. Pi 4s
have BDADDRs from a new OUI range (DC:A6:32:...), meaning that
the "is it a Pi's on-board BT interface" test must be amended to include
that as a possibility.

See: raspberrypi/linux#2229 (comment)

Signed-off-by: Phil Elwell <[email protected]>
@pelwell
Copy link
Contributor

pelwell commented Nov 11, 2019

Forget my previous post and try this instead:

  1. Start with a clean Raspbian image. Edit /usr/bin/bthelper and comment out the hci cmd line to prove that it isn't required.
  2. Pair the headset using the Raspbian Bluetooth plugin, then use the volume control to select it for output.
  3. Before playing any audio, edit .asoundrc and change profile "a2dp" to profile "sco". This will be deleted when you disconnect the headset, but for now this is a proof of concept.
  4. Play some audio, and revel in the poor telephone-quality audio.
  5. Now use the volume control to connect to the headset for audio input. (If you take a look at .asoundrc you'll see that the pcm.input section is already configured for "sco".
  6. Use your favourite audio capture app, or run arecord test.wav and speak into the microphone, ending with Ctrl-C. Then aplay test.wav to replay your recording.

If this works for you then it shows there's nothing fundamentally wrong with the Bluetooth modem and its HSP handling.

@pelwell pelwell added the Waiting for external input Waiting for a comment from the originator of the issue, or a collaborator. label Nov 11, 2019
@pelwell
Copy link
Contributor

pelwell commented Nov 11, 2019

To summarise my findings so far:

  1. The bthelper script wasn't applying the "hci cmd" fix on Pi 4s - this has now been fixed.
  2. The LXPanel volume plugin and the BlueALSA audio interface will automatically use "a2dp" for audio output and "sco" for audio input.
  3. Editing .asoundrc after connecting to a headset allows "sco" mode (HSP) to be used.

It isn't clear to me why anyone would want to use HSP for output when A2DP is available, which leads me to ask:
i. Do items 1-3 above cover all the issues?
ii. If 3 is useful, would it help if the plugin was altered to allow such a connection without the need to manually edit .asoundrc, e.g. by provided two different connection modes?
iii. If the above doesn't resolve your problems, describe your use case and where it fails.

@StuartIanNaylor
Copy link

StuartIanNaylor commented Feb 27, 2020

Anyone know how to get this working as doesn't seem to be.

Also if you want HSP then if *imtu should be 48/60/64?
https://hackaday.io/project/165208-an-old-rotary-phone-as-bluetooth-set/log/162491-setting-up-the-bluetooth

Confused.com but in the latest 2020-02-05 a bluetooth speaker/mic does not seem to work?

Im PA11.0 MTA is now set in the kernel for PA.

Improved bluetooth MTU configuration
The packet size (a.k.a. MTU, "maximum transmission unit") that PulseAudio uses with the bluetooth HSP profile was previously always configured to be 48 bytes. That worked with most hardware, but some adapters require a different packet size. Now PulseAudio asks the kernel what packet size should be used, which fixes the problem.

However, a new problem appeared: some adapters that used to work with 48 byte packet size don't any more work with the size that the kernel tells PulseAudio to use. If you find that HSP audio stopped working when upgrading to PulseAudio 11.0, you can revert to the old behaviour by passing option "autodetect_mtu=no" to module-bluetooth-discover in /etc/pulse/default.pa. If that fixes the problem, then please report the problem to the BlueZ and/or PulseAudio developers, so that the kernel can be fixed.

Update: We decided to disable the MTU autodetection in 11.1 by default, because the feature caused too much problems and it looked like the kernel would not really get fixed even when people reported issues.

So the kernel should have a MTU config of 64?

There are a ton of devices that use HSP and since 1.6 HSP has been wideband audio it was just pulseaudio and settings that make HSP bad not HSP.
The devices are not OS configurable and firmware and HSP is likely to continue and the same questions are being asked on the Ubuntu bugzilla as why on Ubuntu does HSP sound so bad when you plug into other OS it sounds great.
Ubuntu is the same but other distros and win or android HSP is 16Khz great quality plug it into a Pi and not because of the MTU and not using ofono with pulseaudio

I am not even sure if PA12 works with HSF/HSP as even with a bluetoothdongle/headset I can not switch profile.
In PA12 they swapped the priority with A2DP & HSF/HSP because it would 'stick' in HSF/HSP profile but now the opisite happens but rather than lower quality on headphones you now get headsets that are now only headphone only.

Seems Arch and Ubuntu are the same and maybe its just me but PA12/Bluetooth seems to be broken for HSF/HSP

Also if you go the bluealsa route for some reason bluealsa is compiled with

--enable-ofono
enable HFP over oFono - requires no extra libraries at build time. Including this option will disable bluealsa's internal HSP/HFP and instead defer all telephone integration to oFono

So disabling internal bluealsa support which would seem contary in terms of bloat to the rational of opting for bluealsa

@E500E
Copy link

E500E commented Jun 17, 2020

The problem was identified as a timing issue in PulseAudio.

In an nutshell, PulseAudio uses a hard-coded (e)SCO packet size of 48 bytes, instead of using the packet size negotiated at the eSCO connect (ex 60 bytes). The timing logic used for SCO connections, is to send (e)SCO packets (one at a time), at each SCO packet received. If the negotiated packet size is bigger (ex 60 bytes) than the hard-coded 48 bytes, the SCO packets are received at a lower rate, which causes PulseAudio to send the SCO packets way too slow.

More details on the following [pulseaudio-discuss] thread:
[pulseaudio-discuss] Bluetooth - HSP / HFP - source based timing & hard-coded MTU causes SCO packets to be badly delayed

Thank you @bluetiger9 and @kp339 ---- With your clues I was able to solve the metallic garbled noises by recompiling pulseaudio --- thanks so much!

However I seem to be stuck on the next step - getting echo cancellation to work.
I am trying to use my pi0w as a bluetooth HFP set. Meaning my phone connects via bluetooth to the pi0w. The pi0w has a speaker and a microphone (via a USB audio adapter) and the goal is that I conduct my telephone call with the speaker/microphone.

The problem is that I can place calls and hear the other call participant clearly as well as speak, but I just cannot get the echo cancellation module to work I have tried these combos to no avail:

  • Buster, onboard BCM2835 bluetooth, pulseaudio 12.2 (recompiled so that imtu=60 instead of 48)
  • Buster, onboard USB bluetooth, pulseaudio 12.2
  • Stretch, onboard BCM2835 bluetooth, pulseaudio 10.0 (recompiled so that imtu=60 instead of 48)
  • Stretch, onboard USB bluetooth, pulseaudio 10.0

What happens is that I place the call, the conversation starts, and the other call participant has a devil of a time in the call because he/she can hear himself/herself. No doubt it is because of echo from the other participant speaking, getting played out of my pi's speaker, then picked up by my pi's microphone, and then fed back through the call.

First I tried putting this in /etc/pulse/default.pa
load-module module-echo-cancel aec_method=webrtc

But that didn't work at all. Then, instead of putting that line inside the file, tried to manually load the echo cancel module on the shell:
pactl load-module module-echo-cancel

which just seems to crash pulseaudio every time. You can see the results of pulseaudio -v -v -v below --- the last two lines show the attempted load and "Illegal Instruction" and then pulseaudio quits.

D: [pulseaudio] srbchannel.c: SHM block is 65496 bytes, ringbuffer capacity is 2 * 32724 bytes
D: [pulseaudio] protocol-native.c: Enabling srbchannel...
D: [pulseaudio] module-augment-properties.c: Looking for .desktop file for pactl
D: [pulseaudio] protocol-native.c: Client enabled srbchannel.
I: [pulseaudio] module-echo-cancel.c: Using AEC engine: webrtc
Illegal instruction

This happens on both Buster and Stretch, and happens whether or not I use the sudo apt-get install pulseaudio pulseaudio-module-bluetooth -y command to get a "standard" version of pulse audio, or if I compile my own version of pulseaudio (to solve for metallic / robotic / garbled noises.
Any advice would be appreciated. Thanks.

@ciaranj
Copy link

ciaranj commented Aug 31, 2022

Just went through this process (loosely following this guide) on an RPi 3B+, no bluetooth dongle, all onboard kit with wifi enabled.
Raspbian Bullseye which was shipping PulseAudio 14.2.

I needed to make the changes suggested above by @kp339 (MTU from 48->64) in order to significantly reduce the garbled sound, which works a treat. (Even with the auto_detect_mtu module parameter specified.)

As the codebase has moved on from 11.1 -> 14.2, I've included an updated diff in case it helps others.

diff --git a/src/modules/bluetooth/backend-native.c b/src/modules/bluetooth/backend-native.c
index 5ba743966..87b479e0c 100644
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -194,8 +194,8 @@ static int sco_acquire_cb(pa_bluetooth_transport *t, bool optional, size_t *imtu
     if (sock < 0)
         goto fail;

-    if (imtu) *imtu = 48;
-    if (omtu) *omtu = 48;
+    if (imtu) *imtu = 64;
+    if (omtu) *omtu = 64;

     if (t->device->autodetect_mtu) {
         struct sco_options sco_opt;
diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c
index d7a13efd0..2b4ba578c 100644
--- a/src/modules/bluetooth/backend-ofono.c
+++ b/src/modules/bluetooth/backend-ofono.c
@@ -269,9 +269,9 @@ static int hf_audio_agent_transport_acquire(pa_bluetooth_transport *t, bool opti
      * made available to userspace by the Bluetooth kernel subsystem.
      * Meanwhile the empiric value 48 will be used. */
     if (imtu)
-        *imtu = 48;
+        *imtu = 64;
     if (omtu)
-        *omtu = 48;
+        *omtu = 64;

     err = socket_accept(card->fd);
     if (err < 0) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bluetooth Issue pelwell_there_is_no_escape Waiting for external input Waiting for a comment from the originator of the issue, or a collaborator.
Projects
None yet
Development

No branches or pull requests