diff --git a/README.md b/README.md
index 13758a8..306f077 100644
--- a/README.md
+++ b/README.md
@@ -39,6 +39,7 @@
- **Smart Pairing Agent** — Handles PIN codes, passkeys, and confirmations automatically
- **Protocol Analysis** — Capture and analyze Bluetooth traffic with btmon integration
- **Audio Intelligence** — PipeWire/PulseAudio integration for seamless audio control
+- **HFP Audio Gateway** — Act as a phone for headset testing and call simulation
- **OBEX Profiles** — File transfer, phonebook access, and message access
## Example Conversation
@@ -175,6 +176,16 @@ Interact with Bluetooth Low Energy devices — read sensors, write commands, sub
"Subscribe to heart rate notifications"
```
+### HFP Audio Gateway
+Act as a phone (Audio Gateway) for testing Bluetooth headsets. Simulate calls, control volume, and update status indicators over the HFP AT command protocol.
+
+```
+"Enable HFP Audio Gateway mode"
+"Simulate an incoming call to the connected headset"
+"Set the headset speaker volume to 12"
+"Update the battery indicator to level 3"
+```
+
### Protocol Analysis
Capture and analyze Bluetooth traffic for debugging and reverse engineering.
@@ -241,6 +252,18 @@ Access contacts and SMS messages from connected phones via PBAP and MAP profiles
| `bt_audio_volume` | Set volume (0-150%) |
| `bt_audio_mute` | Mute/unmute audio |
+### HFP Audio Gateway Tools (8)
+| Tool | Description |
+|------|-------------|
+| `bt_hfp_ag_enable` | Register HFP AG profile with BlueZ |
+| `bt_hfp_ag_disable` | Unregister HFP AG profile |
+| `bt_hfp_ag_status` | Get AG connections, SLC state, indicators |
+| `bt_hfp_ag_simulate_call` | Simulate incoming call (RING + CLIP) |
+| `bt_hfp_ag_end_call` | Terminate call from AG side |
+| `bt_hfp_ag_set_volume` | Set speaker or microphone volume (0-15) |
+| `bt_hfp_ag_set_signal` | Update signal strength indicator (0-5) |
+| `bt_hfp_ag_set_battery` | Update battery level indicator (0-5) |
+
### BLE Tools (7)
| Tool | Description |
|------|-------------|
@@ -311,7 +334,7 @@ Access contacts and SMS messages from connected phones via PBAP and MAP profiles
| `bt_obex_transfer_status` | Check transfer progress |
| `bt_obex_transfer_cancel` | Cancel active transfer |
-**Total: 61 tools**
+**Total: 69 tools**
## MCP Resources
@@ -339,7 +362,7 @@ Live state queries without tool calls:
│ ┌──────────────────── FastMCP Server ──────────────────────┐ │
│ │ │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐│
-│ │ │ Adapter │ │ Device │ │ Audio │ │ BLE │ │ OBEX ││
+│ │ │ Adapter │ │ Device │ │Audio/HFP│ │ BLE │ │ OBEX ││
│ │ │ Tools │ │ Tools │ │ Tools │ │ Tools │ │ Tools ││
│ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘│
│ │ │ │ │ │ │ │
@@ -432,10 +455,12 @@ mcbluetooth/
│ ├── obex_client.py # obexd D-Bus wrapper
│ ├── audio.py # PipeWire/Pulse integration
│ ├── agent.py # Pairing agent (Agent1)
+│ ├── hfp_ag.py # HFP Audio Gateway (Profile1)
│ └── tools/
│ ├── adapter.py # Adapter management
│ ├── device.py # Device management + pairing
│ ├── audio.py # Audio profile tools
+│ ├── hfp.py # HFP AG call simulation
│ ├── ble.py # BLE/GATT tools
│ ├── monitor.py # btmon integration
│ └── obex.py # OBEX profile tools
@@ -450,6 +475,7 @@ mcbluetooth/
- [x] Device discovery and management
- [x] Pairing with Agent1 support
- [x] Audio profiles (A2DP/HFP)
+- [x] HFP Audio Gateway (call simulation, indicators)
- [x] BLE/GATT operations
- [x] btmon packet capture
- [x] OBEX file transfer (OPP/FTP)
diff --git a/docs-site/astro.config.mjs b/docs-site/astro.config.mjs
index 448d9cc..0d2fada 100644
--- a/docs-site/astro.config.mjs
+++ b/docs-site/astro.config.mjs
@@ -49,6 +49,7 @@ export default defineConfig({
{ label: 'Adapter Management', slug: 'guides/adapters' },
{ label: 'Device Pairing', slug: 'guides/pairing' },
{ label: 'Audio Control', slug: 'guides/audio' },
+ { label: 'HFP Audio Gateway', slug: 'guides/hfp-ag' },
{ label: 'BLE & GATT', slug: 'guides/ble' },
{ label: 'OBEX File Transfer', slug: 'guides/obex' },
{ label: 'Phonebook & Messages', slug: 'guides/phonebook-messages' },
@@ -62,6 +63,7 @@ export default defineConfig({
{ label: 'Adapter Tools', slug: 'reference/adapter-tools' },
{ label: 'Device Tools', slug: 'reference/device-tools' },
{ label: 'Audio Tools', slug: 'reference/audio-tools' },
+ { label: 'HFP AG Tools', slug: 'reference/hfp-ag-tools' },
{ label: 'BLE Tools', slug: 'reference/ble-tools' },
{ label: 'OBEX Tools', slug: 'reference/obex-tools' },
{ label: 'Monitor Tools', slug: 'reference/monitor-tools' },
diff --git a/docs-site/src/content/docs/explanation/architecture.md b/docs-site/src/content/docs/explanation/architecture.md
index 1644fb0..97dab1c 100644
--- a/docs-site/src/content/docs/explanation/architecture.md
+++ b/docs-site/src/content/docs/explanation/architecture.md
@@ -61,7 +61,7 @@ The MCP server layer that exposes Bluetooth functionality:
| Component | Purpose |
|-----------|---------|
-| **MCP Tools** | 61 tools for Bluetooth operations |
+| **MCP Tools** | 69 tools for Bluetooth operations |
| **MCP Resources** | Live state queries via URIs |
| **Pairing Agent** | Handles PIN/passkey negotiation |
| **D-Bus Clients** | Async communication with BlueZ/obexd |
@@ -73,6 +73,7 @@ The official Linux Bluetooth stack daemon:
- Manages adapter hardware
- Handles device discovery and pairing
- Implements Bluetooth profiles (A2DP, HFP, etc.)
+- Manages custom profile registrations (HFP AG via ProfileManager1)
- Exposes D-Bus API on **system bus**
### obexd
@@ -113,6 +114,7 @@ Interfaces:
org.bluez.GattService1 - BLE services
org.bluez.GattCharacteristic1 - BLE characteristics
org.bluez.AgentManager1 - Pairing agent registration
+ org.bluez.ProfileManager1 - Custom profile registration (HFP AG)
```
### Session Bus (OBEX)
@@ -160,15 +162,16 @@ Tools are organized by functional area:
```python
# server.py
-from mcbluetooth.tools import adapter, audio, ble, device, monitor, obex
+from mcbluetooth.tools import adapter, audio, ble, device, hfp, monitor, obex
def create_server():
mcp = FastMCP("mcbluetooth")
adapter.register_tools(mcp)
- audio.register_tools(mcp)
- ble.register_tools(mcp)
device.register_tools(mcp)
+ audio.register_tools(mcp)
+ hfp.register_tools(mcp)
+ ble.register_tools(mcp)
monitor.register_tools(mcp)
obex.register_tools(mcp)
diff --git a/docs-site/src/content/docs/getting-started/introduction.md b/docs-site/src/content/docs/getting-started/introduction.md
index d508406..8036e4b 100644
--- a/docs-site/src/content/docs/getting-started/introduction.md
+++ b/docs-site/src/content/docs/getting-started/introduction.md
@@ -15,6 +15,7 @@ Ask Claude (or any MCP-compatible LLM) to:
- **"Read the battery level from my fitness tracker"**
- **"Send this PDF to my phone via Bluetooth"**
- **"Download my phone's contacts"**
+- **"Enable HFP Audio Gateway and simulate an incoming call"**
- **"Start capturing Bluetooth traffic for debugging"**
## Why mcbluetooth?
@@ -34,6 +35,7 @@ mcbluetooth exposes the full power of BlueZ:
- **Adapters** — Power, discovery, pairing acceptance
- **Devices** — Scanning, pairing, connection management
- **Audio** — A2DP/HFP profiles, volume, routing
+- **HFP Audio Gateway** — Phone simulation, call control, indicators
- **BLE/GATT** — Services, characteristics, notifications
- **OBEX** — File transfer, phonebook, messages
- **Monitoring** — HCI packet capture and analysis
diff --git a/docs-site/src/content/docs/guides/hfp-ag.md b/docs-site/src/content/docs/guides/hfp-ag.md
new file mode 100644
index 0000000..26953b6
--- /dev/null
+++ b/docs-site/src/content/docs/guides/hfp-ag.md
@@ -0,0 +1,174 @@
+---
+title: HFP Audio Gateway
+description: Use Linux as a phone to test Bluetooth headsets with call simulation
+---
+
+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
+
+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
+
+```
+bt_hfp_ag_enable
+```
+
+This registers a custom HFP AG profile with BlueZ via the ProfileManager1 D-Bus interface. Headsets can now discover and connect to Linux.
+
+
+
+## Connection Flow
+
+When a headset connects, the following happens automatically:
+
+```
+1. HF connects RFCOMM → BlueZ calls NewConnection
+2. AT+BRSF exchange → Both sides share feature flags
+3. AT+CIND=? / AT+CIND? → Indicator mapping and values
+4. AT+CMER=3,0,0,1 → Enable indicator reporting → SLC established
+5. AT+BAC / +BCS → Codec negotiation (CVSD or mSBC)
+```
+
+Check the connection status:
+
+```
+bt_hfp_ag_status
+```
+
+## 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
+
+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
+
+HFP volume uses a 0-15 scale:
+
+```
+# Set speaker volume
+bt_hfp_ag_set_volume address="AA:BB:CC:DD:EE:FF" type="speaker" level=12
+
+# Set microphone gain
+bt_hfp_ag_set_volume address="AA:BB:CC:DD:EE:FF" type="microphone" level=10
+```
+
+
+
+## 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=3
+```
+
+These send +CIEV indicator updates to the headset.
+
+## 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
+
+The HFP AG tools are designed for end-to-end testing with the [mcbluetooth-esp32](https://github.com/supported-systems/mcbluetooth-esp32) test harness, where the ESP32 acts as the HF (headset) device.
+
+### Typical Test Flow
+
+```
+# 1. Enable AG on Linux
+bt_hfp_ag_enable
+
+# 2. ESP32 connects as HF (from mcbluetooth-esp32)
+# SLC auto-negotiated
+
+# 3. Linux simulates incoming call
+bt_hfp_ag_simulate_call address="" number="5551234567"
+
+# 4. ESP32 answers (sends ATA)
+# Call becomes active
+
+# 5. Linux ends call
+bt_hfp_ag_end_call address=""
+
+# 6. Check status
+bt_hfp_ag_status
+```
+
+## 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
+
+```
+bt_hfp_ag_disable
+```
+
+This unregisters the profile, disconnecting any active HFP sessions.
diff --git a/docs-site/src/content/docs/reference/hfp-ag-tools.md b/docs-site/src/content/docs/reference/hfp-ag-tools.md
new file mode 100644
index 0000000..b3db602
--- /dev/null
+++ b/docs-site/src/content/docs/reference/hfp-ag-tools.md
@@ -0,0 +1,251 @@
+---
+title: HFP Audio Gateway Tools
+description: Reference for HFP Audio Gateway tools — act as a phone for headset testing
+---
+
+import { Aside } from '@astrojs/starlight/components';
+
+Tools for the HFP Audio Gateway role, allowing Linux to simulate a phone for testing Bluetooth headsets and hands-free devices.
+
+
+
+## bt_hfp_ag_enable
+
+Enable HFP Audio Gateway mode on Linux.
+
+Registers a custom HFP AG profile with BlueZ. After enabling, Bluetooth headsets (HF devices) can connect and Linux acts as the phone side.
+
+**Parameters:** None
+
+**Returns:**
+```json
+{
+ "status": "ok",
+ "role": "audio_gateway",
+ "profile": "HFP AG 1.7"
+}
+```
+
+**Example:**
+```
+bt_hfp_ag_enable
+```
+
+**Notes:**
+- Must be called before headsets can connect via HFP
+- Registers on RFCOMM channel 13
+- Supports HFP 1.7 features including codec negotiation (CVSD/mSBC)
+
+---
+
+## bt_hfp_ag_disable
+
+Disable HFP Audio Gateway mode.
+
+Unregisters the AG profile and disconnects any active HFP sessions.
+
+**Parameters:** None
+
+**Returns:**
+```json
+{
+ "status": "ok",
+ "disabled": true
+}
+```
+
+**Example:**
+```
+bt_hfp_ag_disable
+```
+
+---
+
+## bt_hfp_ag_status
+
+Get HFP Audio Gateway status.
+
+**Parameters:** None
+
+**Returns:**
+```json
+{
+ "status": "ok",
+ "registered": true,
+ "connections": [
+ {
+ "address": "AA:BB:CC:DD:EE:FF",
+ "slc_established": true,
+ "codec": "msbc",
+ "speaker_volume": 7,
+ "mic_volume": 7,
+ "calls": []
+ }
+ ],
+ "indicators": {
+ "service": 1,
+ "call": 0,
+ "callsetup": 0,
+ "callheld": 0,
+ "signal": 5,
+ "roam": 0,
+ "battchg": 5
+ }
+}
+```
+
+**Example:**
+```
+bt_hfp_ag_status
+```
+
+---
+
+## bt_hfp_ag_simulate_call
+
+Simulate an incoming call to a connected HF device.
+
+Sends RING and +CLIP (caller ID) notifications to the headset. The HF device sees an incoming call and can answer (ATA) or reject (AT+CHUP). Ringing repeats every 3 seconds until answered or ended.
+
+**Parameters:**
+
+| Name | Type | Required | Description |
+|------|------|----------|-------------|
+| `address` | string | Yes | Bluetooth address of connected HF device |
+| `number` | string | No | Caller phone number to display (default: "5551234567") |
+
+**Returns:**
+```json
+{
+ "status": "ok",
+ "call_state": "ringing",
+ "number": "5551234567"
+}
+```
+
+**Example:**
+```
+bt_hfp_ag_simulate_call address="AA:BB:CC:DD:EE:FF" number="+15551234567"
+```
+
+**Notes:**
+- Device must have an established SLC (Service Level Connection)
+- The HF device will hear a ring tone (if in-band ring is supported)
+- Use `bt_hfp_ag_end_call` to stop ringing or terminate
+
+---
+
+## bt_hfp_ag_end_call
+
+End an active or ringing call from the AG side.
+
+**Parameters:**
+
+| Name | Type | Required | Description |
+|------|------|----------|-------------|
+| `address` | string | Yes | Bluetooth address of connected HF device |
+
+**Returns:**
+```json
+{
+ "status": "ok",
+ "call_state": "ended"
+}
+```
+
+**Example:**
+```
+bt_hfp_ag_end_call address="AA:BB:CC:DD:EE:FF"
+```
+
+---
+
+## bt_hfp_ag_set_volume
+
+Set speaker or microphone volume on the HF device.
+
+Sends +VGS (speaker) or +VGM (microphone) command to change volume remotely.
+
+**Parameters:**
+
+| Name | Type | Required | Description |
+|------|------|----------|-------------|
+| `address` | string | Yes | Bluetooth address of connected HF device |
+| `type` | string | Yes | `"speaker"` for output volume, `"microphone"` for input |
+| `level` | integer | Yes | Volume level 0-15 (0 = muted, 15 = maximum) |
+
+**Returns:**
+```json
+{
+ "status": "ok",
+ "type": "speaker",
+ "level": 12
+}
+```
+
+**Example:**
+```
+# Set speaker volume
+bt_hfp_ag_set_volume address="AA:BB:CC:DD:EE:FF" type="speaker" level=12
+
+# Set microphone volume
+bt_hfp_ag_set_volume address="AA:BB:CC:DD:EE:FF" type="microphone" level=10
+```
+
+
+
+---
+
+## bt_hfp_ag_set_signal
+
+Update the signal strength indicator shown on the HF device.
+
+**Parameters:**
+
+| Name | Type | Required | Description |
+|------|------|----------|-------------|
+| `address` | string | Yes | Bluetooth address of connected HF device |
+| `level` | integer | Yes | Signal strength 0-5 |
+
+**Returns:**
+```json
+{
+ "status": "ok",
+ "signal_strength": 4
+}
+```
+
+**Example:**
+```
+bt_hfp_ag_set_signal address="AA:BB:CC:DD:EE:FF" level=4
+```
+
+---
+
+## bt_hfp_ag_set_battery
+
+Update the battery level indicator shown on the HF device.
+
+**Parameters:**
+
+| Name | Type | Required | Description |
+|------|------|----------|-------------|
+| `address` | string | Yes | Bluetooth address of connected HF device |
+| `level` | integer | Yes | Battery level 0-5 |
+
+**Returns:**
+```json
+{
+ "status": "ok",
+ "battery_level": 3
+}
+```
+
+**Example:**
+```
+bt_hfp_ag_set_battery address="AA:BB:CC:DD:EE:FF" level=3
+```
diff --git a/docs-site/src/content/docs/reference/tools.md b/docs-site/src/content/docs/reference/tools.md
index 16c9e78..5895e72 100644
--- a/docs-site/src/content/docs/reference/tools.md
+++ b/docs-site/src/content/docs/reference/tools.md
@@ -3,7 +3,7 @@ title: Tools Overview
description: Complete reference for all mcbluetooth MCP tools
---
-mcbluetooth provides **61 MCP tools** organized into functional categories.
+mcbluetooth provides **69 MCP tools** organized into functional categories.
## Tool Categories
@@ -12,6 +12,7 @@ mcbluetooth provides **61 MCP tools** organized into functional categories.
| [Adapter](/reference/adapter-tools/) | 7 | Hardware adapter management |
| [Device](/reference/device-tools/) | 12 | Device discovery, pairing, connection |
| [Audio](/reference/audio-tools/) | 7 | PipeWire/PulseAudio integration |
+| [HFP Audio Gateway](/reference/hfp-ag-tools/) | 8 | Phone role for headset testing |
| [BLE](/reference/ble-tools/) | 8 | Bluetooth Low Energy & GATT |
| [OBEX](/reference/obex-tools/) | 21 | File transfer, phonebook, messages |
| [Monitor](/reference/monitor-tools/) | 6 | Protocol capture & analysis |
@@ -95,6 +96,19 @@ Tools return JSON objects with:
| `bt_audio_volume` | Adjust volume |
| `bt_audio_mute` | Mute/unmute |
+### HFP Audio Gateway Tools
+
+| Tool | Description |
+|------|-------------|
+| `bt_hfp_ag_enable` | Register AG profile with BlueZ |
+| `bt_hfp_ag_disable` | Unregister AG profile |
+| `bt_hfp_ag_status` | Get connections and indicators |
+| `bt_hfp_ag_simulate_call` | Simulate incoming call |
+| `bt_hfp_ag_end_call` | End active/ringing call |
+| `bt_hfp_ag_set_volume` | Set speaker/mic volume |
+| `bt_hfp_ag_set_signal` | Update signal indicator |
+| `bt_hfp_ag_set_battery` | Update battery indicator |
+
### BLE Tools
| Tool | Description |