Prerequisites
Before you begin, set up your device and configure the DUT for HFP audio gateway functions.
Connect a remote device
To connect a remote device, run the following command from the bluetoothctl menu:
Parameters
<bt_address> is the Bluetooth address of the remote device.
Example
To connect to a paired remote device with <bt_address> 20:19:D8:36:90:40, run the following command:
connect 20:19:D8:36:90:40
Sample output
[Test]# connect 20:19:D8:36:90:40
Attempting to connect to 20:19:D8:36:90:40
[CHG] Device 20:19:D8:36:90:40 Connected: yes
[CHG] Device 20:19:D8:36:90:40 UUIDs: 00001108-0000-1000-8000-00805f9b34fb
[CHG] Device 20:19:D8:36:90:40 UUIDs: 0000110b-0000-1000-8000-00805f9b34fb
[CHG] Device 20:19:D8:36:90:40 UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
[CHG] Device 20:19:D8:36:90:40 UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
[CHG] Device 20:19:D8:36:90:40 UUIDs: 0000111e-0000-1000-8000-00805f9b34fb
[CHG] Device 20:19:D8:36:90:40 ServicesResolved: yes
[CHG] Device 20:19:D8:36:90:40 Bonded: yes
[CHG] Device 20:19:D8:36:90:40 Paired: yes
[NEW] Endpoint /org/bluez/hci0/dev_20_19_D8_36_90_40/sep1
[NEW] Transport /org/bluez/hci0/dev_20_19_D8_36_90_40/sep1/fd1
Connection successful
[CHG] Transport /org/bluez/hci0/dev_20_19_D8_36_90_40/sep1/fdl State: active
[CHG] Transport /org/bluez/hci0/dev_20_19_D8_36_90_40/sep1/fd1 Volume: 0x0068 (104)
[CHG] Transport /org/bluez/hci0/dev_20_19_D8_36_90_40/sep1/fd1 State: idle
Verify audio gateway functionality
To verify the audio gateway functionality, do the following:
The pactl tool isn’t available by default. Enable and build the tool on your device.
-
List all cards, verify the available profiles of the BlueZ card, and find its active profile by running the following command:
Sample output
# pactl list cards
Card #65
Name: bluez_card.20_19_D8_36_90_40
Driver: module-bluez5-device.c
Owner Module: n/a
Properties:
device.api = "bluez5"
device.bus = "bluetooth"
media.class = "Audio/Device"
device.name = "bluez_card.20_19_D8_36_90_40"
device.description = " MyHeadset"
device.alias = " MyHeadset"
device.form_factor = "headset"
device.string = "20:19:D8:36:90:40 "
api.bluez5.icon = "audio-headset"
api.bluez5.path = "/org/bluez/hci0/dev_20_19_D8_36_90_40"
api.bluez5.address = "20:19:D8:36:90:40"
api.bluez5.device = ""
api.bluez5.class = "0x240404"
api.bluez5.connection = "connected"
device.icon_name = "audio-headset-bluetooth"
bluez5.profile = "off"
spa.object.id = "5"
factory.id = "15"
client.id = "33"
object.id = "36"
object.serial = "65"
Profiles:
off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
a2dp-sink: High Fidelity Playback (A2DP Sink, codec SBC) (sinks: 1, sources: 0, priority: 18, available: yes)
a2dp-sink-sbc_xq: High Fidelity Playback (A2DP Sink, codec SBC-XQ) (sinks: 1, sources: 0, priority: 17, available: yes)
headset-head-unit-cvsd: Headset Head Unit (HSP/HFP, codec CVSD) (sinks: 1, sources: 1, priority: 2, available: yes)
headset-head-unit: Headset Head Unit (HSP/HFP, codec mSBC) (sinks: 1, sources: 1, priority: 3, available: yes)
Active Profile: a2dp-sink
Ports:
headset-input: Handsfree (type: Headset, priority: 0, latency offset: 0 usec, available)
Properties:
port.type = "headset"
Part of profile(s): headset-head-unit-cvsd, headset-head-unit
headset-output: Headset (type: Headset, priority: 0, latency offset: 0 usec, available)
Properties:
port.type = "headset"
Part of profile(s): a2dp-sink, a2dp-sink-sbc_xq
headset-hf-output: Handsfree (type: Headset, priority: 0, latency offset: 0 usec, available)
Properties:
port.type = "headset"
Part of profile(s): headset-head-unit-cvsd, headset-head-unit
-
If the active profile is
a2dp-sink (Active Profile: a2dp-sink), switch the active profile to headset-head-unit by running the following command:
pactl set-card-profile bluez_card.20_19_D8_36_90_40 headset-head-unit
This setting ensures that the audio is streamed over SCO when multiple profiles are connected.
-
Verify that the active profile of the BlueZ card is set to
headset-head-unit by running the following command:
Sample output
# pactl list cards
Card #65
Name: bluez_card.20_19_D8_36_90_40
Driver: module-bluez5-device.c
Owner Module: n/a
Properties:
device.api = "bluez5"
device.bus = "bluetooth"
media.class = "Audio/Device"
device.name = "bluez_card.20_19_D8_36_90_40"
device.description = " MyHeadset"
device.alias = " MyHeadset"
device.form_factor = "headset"
device.string = "20:19:D8:36:90:40 "
api.bluez5.icon = "audio-headset"
api.bluez5.path = "/org/bluez/hci0/dev_20_19_D8_36_90_40"
api.bluez5.address = "20:19:D8:36:90:40"
api.bluez5.device = ""
api.bluez5.class = "0x240404"
api.bluez5.connection = "connected"
device.icon_name = "audio-headset-bluetooth"
bluez5.profile = "off"
spa.object.id = "5"
factory.id = "15"
client.id = "33"
object.id = "36"
object.serial = "65"
Profiles:
off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
a2dp-sink: High Fidelity Playback (A2DP Sink, codec SBC) (sinks: 1, sources: 0, priority: 18, available: yes)
a2dp-sink-sbc_xq: High Fidelity Playback (A2DP Sink, codec SBC-XQ) (sinks: 1, sources: 0, priority: 17, available: yes)
headset-head-unit-cvsd: Headset Head Unit (HSP/HFP, codec CVSD) (sinks: 1, sources: 1, priority: 2, available: yes)
headset-head-unit: Headset Head Unit (HSP/HFP, codec mSBC) (sinks: 1, sources: 1, priority: 3, available: yes)
Active Profile: headset-head-unit
-
Create a dummy SCO as follows:
a. Run SSH.
b. Play a WAV file by running the following command:
Example
To play the
AG_playback.wav file, run the following command:
paplay AG_playback.wav -v
Sample output
sh-5.1# paplay AG_playback.wav -v
Opening a playback stream with sample specification 's16le 2ch 44100Hz' and channel map 'front-left,front-right'.
Connection established.
Stream successfully created.
Buffer metrics: maxlength=4194304, tlength=352800, prebuf=349276, minreq=3528
Using sample spec 's16le 2ch 44100Hz', channel map 'front-left,front-right'.
Connected to device bluez_output.20:19:D8:36:90:40 (index: 68, suspended: no).
Stream started.
Time: 2.003 sec; Latency: 2042009 usec.
-
Receive microphone data from the remote device by running the following command:
parec -v --rate=<rate> --format=<format> --channels=<channel_number> --file-format=<file_format audio_filepath> --device=<device_name>
Parameters
| Options | Parameter | Description | Example |
|---|
--rate | <rate> | The specific sample rate to play the audio file. | 16000 |
--format | <format> | The specific sample format to play the audio file. | s16le |
--channels | <channel_number> | The specific number of channels to play the audio file. | 1 |
--file-format | <file_format audio_filepath> | The file format to play the audio file from a directory. | wav /data/rec1.wav |
--device | <device_name> | The device name of the source or sink to play the audio file. | bluez_input.20:19:D8:36:90:40 |
To identify the device name from a list of sources, run the following command in SSH:Sample outputsh-5.1# pactl list sources short
51 alsa_output.platform-sound.HiFi__Speaker__sink.monitor PipeWire s16le 2ch 48000Hz SUSPENDED
52 alsa_input.platform-sound.HiFi__Mic1__source PipeWire s16le 2ch 48000Hz SUSPENDED
65 bluez_input.20:19:D8:36:90:40 PipeWire float32le 1ch 48000Hz SUSPENDED
68 bluez_output.20:19:D8:36:90:40.monitor PipeWire float32le 2ch 48000Hz SUSPENDED
Example
To receive microphone data from a remote device for the example values listed in the table, run the following command:
parec -v --rate=16000 --format=s16le --channels=1 --file-format=wav /data/rec1.wav --device=bluez_input.20:19:D8:36:90:40
Sample output
sh-5.1# parec -v --rate=16000 --format=s16le --channels=1 --file-format=wav /data/rec1.wav --device=bluez_input.20:19:D8:36:90:40
Opening a recording stream with sample specification 's16le 1ch 16000Hz' and channel map 'mono'.
Connection established.
Stream successfully created.
Buffer metrics: maxlength=4194304, fragsize=64000
Using sample spec 's16le 1ch 16000Hz', channel map 'mono'.
Connected to device bluez_input.20:19:D8:36:90:40 (index: 65, suspended: no).
- Play the recorded microphone data and verify if the audio is clear.
Disconnect a remote device
To disconnect a remote device, run the following command from the bluetoothctl menu:
Parameters
<bt_address> is the Bluetooth address of the remote device.
Example
To disconnect a paired remote device with <bt_address> 20:19:D8:36:90:40, run the following command:
disconnect 20:19:D8:36:90:40
Sample output
[MyHeadset]# disconnect 20:19:D8:36:90:40
Attempting to disconnect from 20:19:D8:36:90:40
[DEL] Transport /org/bluez/hci0/dev_20_19_D8_36_90_40/sep1/fd2
[DEL] Endpoint /org/bluez/hci0/dev_20_19_D8_36_90_40/sep1
[CHG] Device 20:19:D8:36:90:40 ServicesResolved: no
Successful disconnected
[CHG] Device 20:19:D8:36:90:40 Connected: no