> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Perform Bluetooth HFP audio gateway functions

> You can perform HFP audio gateway functions using the ``bluetoothctl`` menu and ``paplay`` commands. Bluetooth HFP audio gateway functions allow you to connect or disconnect to a remote device and verify audio gateway functionality to ensure proper hands-free operation.

## Prerequisites

Before you begin, <a href="verify-hfp-functions#set-up-the-device-for-hfp-functions" target="_self">set up your device</a> and <a href="verify-hfp-functions#configure-the-dut-for-hfp-audio-gateway-functions" target="_self">configure the DUT for HFP audio gateway functions</a>.

## Connect a remote device

To connect a remote device, run the following command from the `bluetoothctl` menu:

```text theme={null}
connect <bt_address>
```

**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:

```text theme={null}
connect 20:19:D8:36:90:40
```

**Sample output**

```text theme={null}
[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:

<Note>
  The pactl tool isn't available by default. Enable and build the tool on your device.
</Note>

1. List all cards, verify the available profiles of the BlueZ card, and find its active profile by running the following command:

   ```text theme={null}
   pactl list cards
   ```

   **Sample output**

   ```text theme={null}
   # 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
   ```

2. If the active profile is `a2dp-sink` (`Active Profile: a2dp-sink`), switch the active profile to `headset-head-unit` by running the following command:

   ```text theme={null}
   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.

3. Verify that the active profile of the BlueZ card is set to `headset-head-unit` by running the following command:

   ```text theme={null}
   pactl list cards
   ```

   **Sample output**

   ```text theme={null}
   # 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
   ```

4. Create a dummy SCO as follows:

   a. Run SSH.

   b. Play a WAV file by running the following command:

   ```text theme={null}
   paplay <file.wav> -v
   ```

   **Example**

   To play the `AG_playback.wav` file, run the following command:

   ```text theme={null}
   paplay AG_playback.wav -v
   ```

   **Sample output**

   ```text theme={null}
   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.
   ```

5. Receive microphone data from the remote device by running the following command:

   ```text theme={null}
   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` |

<Note>
  To identify the device name from a list of sources, run the following command in SSH:

  ```text theme={null}
  pactl list sources short
  ```

  **Sample output**

  ```text theme={null}
  sh-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
  ```
</Note>

**Example**

To receive microphone data from a remote device for the example values listed in the table, run the following command:

```text theme={null}
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**

```text theme={null}
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).
```

6. 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:

```text theme={null}
disconnect <bt_address>
```

**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:

```text theme={null}
disconnect 20:19:D8:36:90:40
```

**Sample output**

```text theme={null}
[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
```
