# BLE GATT Server — NimBLE over Hosted HCI — Coprocessor
Connectable BLE peripheral exposing one custom 128-bit GATT service with two
characteristics (read/write + notify). NimBLE runs on the **host**; the
Bluetooth **controller** runs on the ESP-Hosted **co-processor**, reached over
the hosted transport (SDIO / SPI / SPI-HD / UART) via VHCI.
The only ESP-Hosted-specific code is one call —
`esp_hosted_bt_host_stack_setup()` — which brings the controller up and binds NimBLE
to the hosted HCI; everything else is standard NimBLE. See [Porting a BT stack
to ESP-Hosted](https://github.com/espressif/esp-hosted/blob/master/docs/design/bluetooth.md#porting-a-bt-stack-to-esp-hosted).
The bluedroid counterpart is
`bluetooth/esp_hosted_bluedroid/ble_gatt_server`.
## Supported Platforms and Transports
### Supported Coprocessors (BT controller)
| Coprocessor | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 | ESP32-S2 |
| :---------- | :---: | :------: | :------: | :------: | :------: | :-------: | :------: | :------: | :------: |
| BLE support | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | No (no BLE) |
### Supported Host Devices
| Host Device | ESP32-P4 | ESP32-H2 | Other MCUs |
| :---------- | :------: | :------: | :--------: |
| Support | Yes | Yes | [Yes](https://github.com/espressif/esp-hosted/blob/master/docs/getting-started-mcu.md) |
### Supported HCI transports
| HCI over hosted bus (VHCI) | SDIO | SPI Full-Duplex | SPI Half-Duplex | UART |
| :------------------------- | :--: | :-------------: | :-------------: | :--: |
| MCU host | Yes | Yes | Yes | Yes |
The co-processor is the BT controller. `sdkconfig.defaults` already enables the
controller-only profile with BT HCI carried over the host bus (VHCI); you only
select the transport (must match the host):
```bash
cd examples/bluetooth/esp_hosted_nimble/bleprph_gatt/cp
idf.py set-target <cp_chip>
idf.py menuconfig
```
```text
Component config
└── ESP-Hosted
└── Configure coprocessor
└── CP transport
├── Communication bus (co-processor <== bus ==> host)
│ ├── ( ) SPI Full Duplex
│ ├── (X) SDIO <── default
│ ├── ( ) SPI Half Duplex ← MCU host only
│ └── ( ) UART ← MCU host only
└── SDIO Configuration ← clock, GPIOs, checksum (defaults OK)
```
The Bluetooth profile is pre-selected by `sdkconfig.defaults`; confirm it under
**Features**:
```text
Component config
└── ESP-Hosted
└── Configure coprocessor
└── Features
└── Bluetooth <── enabled by sdkconfig.defaults
├── [*] Auto-initialise Bluetooth at boot
└── BT HCI transport
├── (X) HCI over VHCI (SPI/SDIO/SPI-HD) <── default
└── ( ) HCI over UART
```
The CP dependency config is pre-set in `sdkconfig.defaults` (do not remove):
```text
CONFIG_ESP_HOSTED_CP_FEAT_BT=y # ESP-Hosted BT controller feature
CONFIG_ESP_HOSTED_CP_BT_ENABLED=y # required by ESP_HOSTED_CP_FEAT_BT
CONFIG_ESP_HOSTED_CP_FEAT_BT_HCI_VHCI=y # BT HCI over the host bus (VHCI)
CONFIG_BT_ENABLED=y # BT controller stack on the CP
CONFIG_BT_CONTROLLER_ONLY=y # controller-only profile
CONFIG_ESP_HOSTED_CP_FEAT_WIFI=n # Wi-Fi off — BT controller-only CP
```
Then flash and monitor:
```bash
idf.py -p <cp_usb_serial_port> flash monitor
```
<!-- generated from ../README.md — edit that file, not this one -->
To create a project from this example, run:
idf.py create-project-from-example "espressif/esp_hosted=3.0.6:bluetooth/esp_hosted_nimble/bleprph_gatt/cp"