From 2597c8b8b41144d8cfd79aa3d040d8c931638acb Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Tue, 3 Feb 2026 15:23:43 -0700 Subject: [PATCH] Document HFP Audio Gateway across README and docs site - README: Add HFP AG to features, tools table (8 tools), architecture diagram, project structure, and roadmap. Update total from 61 to 69. - Docs site: Create reference page (hfp-ag-tools.md) and practical guide (hfp-ag.md) covering AG enable, call simulation, volume, indicators, AT commands, and E2E test flow. - Update tools overview, architecture, introduction, and sidebar to include HFP AG category. --- README.md | 30 ++- docs-site/astro.config.mjs | 2 + .../content/docs/explanation/architecture.md | 11 +- .../docs/getting-started/introduction.md | 2 + docs-site/src/content/docs/guides/hfp-ag.md | 174 ++++++++++++ .../content/docs/reference/hfp-ag-tools.md | 251 ++++++++++++++++++ docs-site/src/content/docs/reference/tools.md | 16 +- 7 files changed, 479 insertions(+), 7 deletions(-) create mode 100644 docs-site/src/content/docs/guides/hfp-ag.md create mode 100644 docs-site/src/content/docs/reference/hfp-ag-tools.md 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 |