HFP Audio Gateway
import { Aside } from ‘@astrojs/starlight/components’;
mcbluetooth can act as an HFP Audio Gateway (the “phone” role), allowing you to test Bluetooth headsets and hands-free devices by simulating calls and controlling audio indicators.
HFP Roles
Section titled “HFP Roles”HFP (Hands-Free Profile) defines two roles:
| Role | Description | Example Device |
|---|---|---|
| AG (Audio Gateway) | The phone side — originates calls, sends ring signals | Phone, Linux (with mcbluetooth) |
| HF (Hands-Free) | The headset side — answers calls, controls volume | Headset, car kit, ESP32 test device |
mcbluetooth implements the AG role, so headsets connect to Linux as if it were a phone.
Enable the AG Profile
Section titled “Enable the AG Profile”bt_hfp_ag_enableThis registers a custom HFP AG profile with BlueZ via the ProfileManager1 D-Bus interface. Headsets can now discover and connect to Linux.
Connection Flow
Section titled “Connection Flow”When a headset connects, the following happens automatically:
1. HF connects RFCOMM → BlueZ calls NewConnection2. AT+BRSF exchange → Both sides share feature flags3. AT+CIND=? / AT+CIND? → Indicator mapping and values4. AT+CMER=3,0,0,1 → Enable indicator reporting → SLC established5. AT+BAC / +BCS → Codec negotiation (CVSD or mSBC)Check the connection status:
bt_hfp_ag_statusSimulate an Incoming Call
Section titled “Simulate an Incoming Call”Once a headset is connected with SLC established:
bt_hfp_ag_simulate_call address="AA:BB:CC:DD:EE:FF" number="+15551234567"The headset receives:
- RING alerts every 3 seconds
- +CLIP with caller ID information
The headset can:
- Answer with ATA (call becomes active)
- Reject with AT+CHUP (call is ended)
End a Call
Section titled “End a Call”From the AG (Linux) side:
bt_hfp_ag_end_call address="AA:BB:CC:DD:EE:FF"This terminates both ringing and active calls, updating the headset’s indicators.
Control Volume
Section titled “Control Volume”HFP volume uses a 0-15 scale:
# Set speaker volumebt_hfp_ag_set_volume address="AA:BB:CC:DD:EE:FF" type="speaker" level=12
# Set microphone gainbt_hfp_ag_set_volume address="AA:BB:CC:DD:EE:FF" type="microphone" level=10Update Status Indicators
Section titled “Update Status Indicators”Simulate phone status changes shown on the headset display:
# Signal strength (0-5)bt_hfp_ag_set_signal address="AA:BB:CC:DD:EE:FF" level=4
# Battery level (0-5)bt_hfp_ag_set_battery address="AA:BB:CC:DD:EE:FF" level=3These send +CIEV indicator updates to the headset.
HFP Indicators
Section titled “HFP Indicators”The AG maintains 7 standard indicators, reported to the HF device:
| Index | Name | Range | Description |
|---|---|---|---|
| 1 | service | 0-1 | Network service available |
| 2 | call | 0-1 | Active call exists |
| 3 | callsetup | 0-3 | 0=none, 1=incoming, 2=outgoing, 3=alerting |
| 4 | callheld | 0-2 | 0=none, 1=held+active, 2=held only |
| 5 | signal | 0-5 | Signal strength |
| 6 | roam | 0-1 | Roaming active |
| 7 | battchg | 0-5 | Battery charge level |
E2E Testing with ESP32
Section titled “E2E Testing with ESP32”The HFP AG tools are designed for end-to-end testing with the mcbluetooth-esp32 test harness, where the ESP32 acts as the HF (headset) device.
Typical Test Flow
Section titled “Typical Test Flow”# 1. Enable AG on Linuxbt_hfp_ag_enable
# 2. ESP32 connects as HF (from mcbluetooth-esp32)# SLC auto-negotiated
# 3. Linux simulates incoming callbt_hfp_ag_simulate_call address="<esp32>" number="5551234567"
# 4. ESP32 answers (sends ATA)# Call becomes active
# 5. Linux ends callbt_hfp_ag_end_call address="<esp32>"
# 6. Check statusbt_hfp_ag_statusAT Commands Handled
Section titled “AT Commands Handled”The AG automatically handles these AT commands from the HF device:
| Command | Purpose |
|---|---|
| AT+BRSF | Feature exchange |
| AT+CIND | Indicator mapping/values |
| AT+CMER | Enable indicator reporting |
| AT+CHLD | Call hold/multiparty support |
| AT+BAC / AT+BCS | Codec negotiation |
| ATA | Answer call |
| AT+CHUP | Hang up / reject |
| ATD | Outgoing call (from HF) |
| AT+VGS / AT+VGM | Volume control |
| AT+CLCC | List current calls |
| AT+COPS | Operator name query |
| AT+CNUM | Subscriber number |
| AT+BVRA | Voice recognition |
| AT+NREC | Noise reduction |
Disable the AG Profile
Section titled “Disable the AG Profile”bt_hfp_ag_disableThis unregisters the profile, disconnecting any active HFP sessions.