HFP on Raspberry Pi


Update (Sep 7, 2017):
If you are using Raspbian Stretch, please refer here instead of steps below. This post below is for Raspbian Jessie.


The purpose of this post is to enable Bluetooth Handsfree Profile (HFP) on Raspberry Pi so that Raspberry Pi can act like as a handsfree speaker phone or a handsfree car kit. There is one thing needs to be mentioned before start. The original plan was to use Raspberry Pi3’s on-board Bluetooth chip for this project. Unfortunately, it didn’t work. It seems that the problem is related with the chip. So, we have to use a Bluetooth dongle instead.

Here is the list of contents of this post.

Contents:
– Hardware Prerequisites
– Software Prerequisites
– Steps
1. Setting Up
2. oFono
3. PulseAudio
4. Connect your Phone
5. Make a Call!
– Conclusion
– Reference

Let’s get started.

 

Hardware Prerequisites
Since Raspberry Pi doesn’t have microphone input by default, it need to be added. In this post, I’ll use a USB sound card with a 3.5 mm jack microphone.

Also, as mentioned above, we’ll use a Bluetooth dongle instead of on-board Bluetooth chip.

Raspberry Pi 3 B+
– Bluetooth dongle (Panda Bluetooth 4.0 USB Adapter)
– USB Sound Card (SYBA USB sound adapter / FG-UAUDV1-C119)
Microphone with 3.5 mm audio jack
– Speakers with 3.5 mm audio jack (e.g. Rumfo Mini Speaker)

 

Software Prerequisites
Below are the required versions to enable Bluetooth HFP according to PulseAudio release note.

– Bluez 5.0 (or later)
– PulseAudio 6.0 (or later)
– oFono 1.13 (or later)

 

Steps
1. Setting Up
1-1. Connect Bluetooth dongle and USB sound card with Raspberry Pi.
1-2. Connect the microphone and speakers to 3.5 mm audio jacks on the USB sound card.
1-3. Boot up Raspberry Pi Board. If it’s not set up yet, please refer this post.
1-4. As described, we don’t use on-board Bluetooth chip. So it needs to be disabled. To do that, open “/etc/modprobe.d/raspi-blacklist.conf”.

sudo nano /etc/modprobe.d/raspi-blacklist.conf

1-5. Add lines below and save.

blacklist btbcm
blacklist hci_uart

1-6. Then reboot the board.

sudo reboot

1-7. After reboot, check dmesg and make sure there is no Bluetooth-related errors.

dmesg | grep -i bluetooth

1-8. Also, make sure hci0 is UP.

hciconfig

The result should be like this:

hci0:    Type: BR/EDR  Bus: USB
    BD Address: 00:1A:7D:DA:71:08  ACL MTU: 310:10  SCO MTU: 64:8
    UP RUNNING
    RX bytes:622 acl:0 sco:0 events:38 errors:0
    TX bytes:1437 acl:0 sco:0 commands:38 errors:0

If it’s DOWN for some reason, then turn it up.

sudo hciconfig hci0 up

2. oFono
2-1. oFono is not installed by default, so let’s install it.

sudo apt-get install ofono -y

2-2. Make sure the version is 1.13 or later.

pi@raspberrypi:~ $ ofonod --version
1.15

2-2. Then, start the service.

sudo systemctl start ofono

You can check the service running like below.

systemctl -a |grep ofono
  ofono.service     loaded    active   running   LSB: oFono Mobile Telephony Daemon

3. PulseAudio
Since the preinstalled PulseAudio is 5.0, it needs to be updated to at least 6.0.

pi@raspberrypi:~ $ pulseaudio --version
pulseaudio 5.0

3-1. Uninstall the current PulseAudio.

sudo apt-get purge pulseaudio -y

3-2. Open “/etc/apt/sources.list”.

sudo nano /etc/apt/sources.list

3-3. Add the line below:

deb http://ftp.debian.org/debian jessie-backports main

3-4. Execute commands below:

gpg --keyserver pgpkeys.mit.edu --recv-key 8B48AD6246925553
gpg --keyserver pgpkeys.mit.edu --recv-key 7638D0442B90D010
gpg -a --export 8B48AD6246925553 | sudo apt-key add --
gpg -a --export 7638D0442B90D010 | sudo apt-key add --

3-5. Update the package list.

sudo apt-get update

3-6. Install PulseAudio and its Bluetooth module:

sudo apt-get -t jessie-backports install pulseaudio pulseaudio-module-bluetooth -y

3-7. Check the version and make sure it’s 6.0 or later.

$ pulseaudio --version
pulseaudio 7.1

3-8. Open “/etc/pulse/default.pa”.

sudo nano /etc/pulse/default.pa

3-9. Add “headset=ofono” on the line of ‘module-bluetooth-discover’.

load-module module-bluetooth-discover headset=ofono

3-10. To enable echo canceling, add the lines below:

### Echo cancel and noise reduction
.ifexists module-echo-cancel.so
load-module module-echo-cancel aec_method=webrtc source_name=ec_out sink_name=ec_ref
set-default-source ec_out
set-default-sink ec_ref
.endif

3-11. Start PulseAudio.

pulseaudio --start

4. Connect your Phone
4-1. Launch bluetoothctl.

bluetoothctl

4-2. Then, input below commands.

power on
agent on
default-agent

4-3. Start searching your phone. Make sure your phone is discoverable.

scan on

4-4. After detecting your phone, turn scan off.

scan off

devices command shows a list of found devices.

[bluetooth]# devices
Device XX:XX:XX:XX:XX:XX Galaxy S7

4-5. Then, pair, trust and connect to your phone by specifying the Bluetooth device address (in this case it’s “XX:XX:XX:XX:XX:XX”, please replace it wity your device’s address).

pair XX:XX:XX:XX:XX:XX
trust XX:XX:XX:XX:XX:XX
connect XX:XX:XX:XX:XX:XX

If everything is ok, you should see “successful” at the end of the result for each command like below.

[bluetooth]# pair XX:XX:XX:XX:XX:XX
...
Pairing successful
[bluetooth]# trust XX:XX:XX:XX:XX:XX
...
trust succeeded
[bluetooth]# connect XX:XX:XX:XX:XX:XX
...
Connection successful

5. Make a Call!
To make a call, we’ll use oFono test scripts which is included in the source code.
5-1. First, download the source and extruct.

wget https://www.kernel.org/pub/linux/network/ofono/ofono-1.15.tar.gz
tar -xzvf ofono-1.15.tar.gz

5-2. Then, you can make a call by:

python ./test/dial-number 1234567890

If you want to end the call, then execute:

python ./test/hangup-active

 

Conclusion
Thanks for all the forums and articles I referred, now HFP is working on Raspberry Pi!
Next, I’m planning to apply echo canceling and ambient noise suppression, maybe equalizer.


Update (June 22, 2017):
Added one step (step 3-10) to enable echo cancellation. It seems that ‘module-echo-cancel’ does not only echo cancellation but ambient noise suppression. I haven’t check the noise suppression yet but I think the echo cancellation is working well based on my brief testing.


Update (May 2, 2018):
The steps to enable equalizer on HFP sending audio is newly posted.


 

Reference
– Connect Bluetooth Headset To Raspberry Pi 3 (A2DP & HSP)
http://youness.net/raspberry-pi/bluetooth-headset-raspberry-pi-3-ad2p-hsp

– PulseAudio 6.0 Release Notes –freedesktop.org
https://www.freedesktop.org/wiki/Software/PulseAudio/Notes/6.0/

– PulseAudio Documentation –freedesktop.org
https://freedesktop.org/wiki/Software/PulseAudio/Documentation/

– module-echo-cancel –freedesktop.org
https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Modules/#index45h3

– Pulseaudio echo cancellation — Debian User Forums
http://forums.debian.net/viewtopic.php?f=16&t=128306

 

Sponsor Link

7 Comments

  1. When I attempt to execute:
    gpg –keyserver pgpkeys.mit.edu –recv-key 8B48AD6246925553
    gpg –keyserver pgpkeys.mit.edu –recv-key 7638D0442B90D010

    I get “failed to start the dirmngr: no such directory found”
    And
    “Keyserver receive failed: no dirmngr”

    Any advice?

  2. may i know that after all of this, can it directly using voice recognition to make call, decline call and accept call? (without using any physical button). thanks.

  3. Hi Max,

    first and foremost – many thanks for your tutorials!!!

    I’m following your instructions but in my case, I’m using Buster ver and not Jessie, I guess I should use the following command instead:

    deb http://ftp.debian.org/debian buster-backports main

    and if so, do the following commands are the same or should be modified?
    gpg –keyserver pgpkeys.mit.edu –recv-key 8B48AD6246925553
    gpg –keyserver pgpkeys.mit.edu –recv-key 7638D0442B90D010
    gpg -a –export 8B48AD6246925553 | sudo apt-key add —
    gpg -a –export 7638D0442B90D010 | sudo apt-key add —

    once again, your info is PRICELESS!!

    I wish you and your family nothing but the best!
    Cheers,
    Ram

  4. Thanks for this tutorial, extremely helpful.

    I paired my iPhone 12 Pro with the Raspberry Pi 3B+ with a $8 USB bluetooth 4.0 dongle.
    Everything works great, I can phone call and play music and hear all the sounds on the Pi.

    I am trying to record the phone calls but it seems it is impossible to do so on the raspberry pi.
    For some reason pulse audio volume control and audacity does not recognize or can not sense the audio signal from the iPhone, really weird, I can hear the sound coming out from the audio jack from the Pi when I plug in a weird headphones. I am not using a USB soundcard, I am using the Pi’s built in sound card.

    Can you help me to record sound?

  5. Hello,
    Following your instruction, I am able to connect my RPi to an Android device. I’m able to make the call with the python script, except that the sound is not working. How can I force the sound provide by bluetooth to be routed to my sound card?
    THank you

Comments are closed.