# Basic Example — BLE GATT Server

Full "air fryer" device built with the [`pedroluisdionisiofraga/ble-gatt-server`](../../) component. Exposes sensor data, device control, and device information as BLE services — a mobile app or any BLE Central can discover, connect, and read/write characteristics.

## Architecture Overview

```text
┌──────────────────────────────────────────────────────────┐
│           Mobile App (BLE Central / GATT Client)         │
└──────────────────────┬───────────────────────────────────┘
                       │  BLE Connection
┌──────────────────────▼───────────────────────────────────┐
│                 ESP32 (BLE Peripheral / GATT Server)     │
│                                                          │
│   main.c ─── Defines services, characteristics           │
│      │        and read/write handlers                    │
│      │                                                   │
│   ble-gatt-server component ── Advertising, GATT,        │
│                                connection management     │
│                                                          │
│                 ESP-IDF Bluedroid Stack                  │
└──────────────────────────────────────────────────────────┘
```

The example builds against the component at the repo root via `override_path` in [main/idf_component.yml](main/idf_component.yml); consumers who copy it get the published Registry version instead.

## BLE Profile

The device advertises with the name **`ESP32-S3 BLE GATT Server`** and exposes **3 GATT services** with **9 characteristics** total:

### Sensor Service (`0x00FE`)

| UUID | Name | Permissions | Description |
| ------ | ------ | :-----------: | ------------- |
| `0xFF01` | Temperature | R | Current temperature in °C |
| `0xFF02` | Temp Threshold | W | Alert threshold (0–100 °C) |
| `0xFF03` | Humidity | R/W | Humidity % (calibration) |

### Control Service (`0x00FD`)

| UUID | Name | Permissions | Description |
| ------ | ------ | :-----------: | ------------- |
| `0xFF11` | Brightness | R | LED brightness level (0–255) |
| `0xFF12` | Command | W | `0x01` RUN · `0x02` STOP · `0x03` IDLE |
| `0xFF13` | Fan Speed | R/W | Fan speed (0–100 %) |

### Device Info Service (`0x00FC`)

| UUID | Name | Permissions | Description |
| ------ | ------ | :-----------: | ------------- |
| `0xFF21` | FW Version | R | Firmware version string |
| `0xFF22` | Reset | W | Write `0xAA` to reboot |
| `0xFF23` | Device Name | R/W | BLE device name |

> All characteristics include a **User Description Descriptor** (`0x2901`) automatically. Full UUID map available in [`ble_uuids.json`](ble_uuids.json).

## Build & Flash

From this directory:

```bash
idf.py set-target esp32s3   # or esp32, esp32c3, esp32c6, esp32h2
idf.py build flash monitor
```

Tested on **ESP32-S3**. The `0x01` RUN / `0x02` STOP commands toggle an LED on GPIO 12.

## Adding a New Service

You only touch `main/main.c`:

**1. Define data and handlers:**

```c
static uint8_t battery_level = 100;

static int on_read_battery(uint8_t *buf, size_t max_len)
{
  if (max_len < 1) return 0;
  buf[0] = battery_level;
  return 1;
}
```

**2. Define characteristics:**

```c
static ble_characteristic_t battery_chars[] = {
  {
    .uuid = 0xFF31,
    .name = "Battery Level",
    .description = "Battery percentage",
    .size = 1,
    .read = on_read_battery,
    .write = NULL,
  },
};
```

**3. Add the service to the array:**

```c
static ble_service_t my_services[] = {
  // ... existing services ...
  {
    .uuid = 0x00FB,
    .name = "Battery Service",
    .characteristics = battery_chars,
    .characteristic_count = sizeof(battery_chars) / sizeof(battery_chars[0]),
  },
};
```

Build and flash — the new service will appear automatically to BLE clients.

## Authors

- **Pedro Luis Dionísio Fraga** — [pedrodfraga@hotmail.com](mailto:pedrodfraga@hotmail.com)

To create a project from this example, run:

idf.py create-project-from-example "pedroluisdionisiofraga/ble-gatt-server=0.1.3:basic"

or download archive (~6.46 KB)