# `Dala.Hardware.Bluetooth`
[🔗](https://github.com/manhvu/dala/blob/main/lib/dala/hardware/bluetooth.ex#L1)

Bluetooth Low Energy (BLE) support.

Provides BLE central (client) and peripheral (server) functionality.
Requires `:bluetooth` permission (request via `Dala.Permissions.request/2`).

## Events

Bluetooth events arrive as:

    handle_info({:bluetooth, :state_changed, state}, socket)
    handle_info({:bluetooth, :device_found, %{id: id, name: name, rssi: rssi}}, socket)
    handle_info({:bluetooth, :device_connected, %{id: id, name: name}}, socket)
    handle_info({:bluetooth, :device_disconnected, %{id: id}}, socket)
    handle_info({:bluetooth, :characteristic_read, %{device: id, service: uuid, characteristic: uuid, value: data}}, socket)
    handle_info({:bluetooth, :characteristic_written, %{device: id, service: uuid, characteristic: uuid}}, socket)
    handle_info({:bluetooth, :notification_received, %{device: id, service: uuid, characteristic: uuid, value: data}}, socket)

## States

- `:unknown` - State not determined
- `:resetting` - Resetting
- `:unsupported` - BLE not supported
- `:unauthorized` - Permission denied
- `:powered_off` - Bluetooth is off
- `:powered_on` - Bluetooth is on and ready

iOS: `CBCentralManager` / `CBPeripheralManager`.
Android: `BluetoothAdapter` / `BluetoothLeScanner`.

# `device_id`

```elixir
@type device_id() :: String.t()
```

# `state`

```elixir
@type state() ::
  :unknown
  | :resetting
  | :unsupported
  | :unauthorized
  | :powered_off
  | :powered_on
```

# `uuid`

```elixir
@type uuid() :: String.t()
```

# `connect`

```elixir
@spec connect(Dala.Socket.t(), device_id()) :: Dala.Socket.t()
```

Connect to a BLE device.

Device ID is obtained from `:device_found` event.

# `disconnect`

```elixir
@spec disconnect(Dala.Socket.t(), device_id()) :: Dala.Socket.t()
```

Disconnect from a BLE device.

# `discover_services`

```elixir
@spec discover_services(Dala.Socket.t(), device_id()) :: Dala.Socket.t()
```

Discover services for a connected device.

# `read_characteristic`

```elixir
@spec read_characteristic(Dala.Socket.t(), device_id(), uuid(), uuid()) ::
  Dala.Socket.t()
```

Read a characteristic value.

Results arrive as `:bluetooth, :characteristic_read` message.

# `start_scan`

```elixir
@spec start_scan(
  Dala.Socket.t(),
  keyword()
) :: Dala.Socket.t()
```

Start scanning for BLE devices.

Options:
  - `services: [uuid]` - filter by service UUIDs (optional)
  - `timeout_ms: integer` - scan duration (default: 10000)

Found devices arrive as `:bluetooth, :device_found` messages.

# `state`

```elixir
@spec state() :: state()
```

Check current Bluetooth state.

# `stop_scan`

```elixir
@spec stop_scan(Dala.Socket.t()) :: Dala.Socket.t()
```

Stop scanning for devices.

# `subscribe`

```elixir
@spec subscribe(Dala.Socket.t(), device_id(), uuid(), uuid()) :: Dala.Socket.t()
```

Subscribe to notifications for a characteristic.

Notifications arrive as `:bluetooth, :notification_received` messages.

# `unsubscribe`

```elixir
@spec unsubscribe(Dala.Socket.t(), device_id(), uuid(), uuid()) :: Dala.Socket.t()
```

Unsubscribe from notifications for a characteristic.

# `write_characteristic`

```elixir
@spec write_characteristic(Dala.Socket.t(), device_id(), uuid(), uuid(), binary()) ::
  Dala.Socket.t()
```

Write a characteristic value.

Value should be a binary (for bytes) or integer/list for simple values.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
