Skip to content

kodira/simple-ble-ota

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Simple BLE OTA

A drop-in ESP32 component that adds Over-The-Air (OTA) firmware update capability via Bluetooth Low Energy.

Features

  • High Performance: 40+ KB/s transfer speeds
  • Data Integrity: CRC32 verification prevents corrupted firmware
  • Error Reporting: Real-time notifications for failures
  • Drop-in Integration: Single function call to enable OTA
  • Non-intrusive: Works alongside existing BLE services
  • Python Client: Included client for easy firmware uploads

Quick Start

1. Add Component

Add to your project's idf_component.yml:

dependencies:
  simple_ble_ota:
    version: "^0.1.0"

Or clone directly into your components/ directory.

2. Initialize in Code

#include "simple_ble_ota.h"

void app_main(void)
{
    // Initialize NVS, NimBLE, etc. (your existing code)
    
    // Add Simple BLE OTA service
    ESP_ERROR_CHECK(simple_ble_ota_init());
    
    // Continue with your application...
}

3. Upload Firmware

Use the included Python client:

python3 simple-ble-ota-client.py firmware.bin

Requirements

  • ESP-IDF: >= 5.4.0
  • BLE Stack: NimBLE only
  • Python Client: pip install bleak

Protocol

The component implements a custom protocol over BLE GATT:

  • Service UUID: 487d0950-41b9-4c57-ad09-a46ac47e2150
  • Control Point: 487d0950-41b9-4c57-ad09-a46ac47e2151 (Write + Notify)
  • Data: 487d0950-41b9-4c57-ad09-a46ac47e2152 (Write + Write-No-Response)

Commands

  1. START (0x01): [0x01][size_bytes_0-3] - Begin OTA with firmware size
  2. DATA: Chunked firmware data (244 bytes optimal)
  3. COMPLETE (0x02): [0x02][crc32_bytes_0-3] - Finalize with CRC verification
  4. ERROR (0xFF): [0xFF][error_code] - Error notifications from ESP32

Integration Notes

BLE Stack Initialization

This component requires NimBLE to be initialized before calling simple_ble_ota_init():

// Example BLE initialization
nimble_port_init();
ble_hs_cfg.sync_cb = ble_app_on_sync;
ble_svc_gap_device_name_set("MyDevice");
ble_svc_gap_init();
ble_svc_gatt_init();

// Now add Simple BLE OTA
simple_ble_ota_init();

// Start NimBLE
nimble_port_freertos_init(nimble_host_task);

Existing Services

The component adds its service without affecting existing GATT services. You can add other services before or after calling simple_ble_ota_init().

Device Naming

The component does not set the BLE device name. Use your existing method:

ble_svc_gap_device_name_set("MyDevice");

Python Client

Installation

pip install bleak

Usage

# Basic usage
python3 simple-ble-ota-client.py firmware.bin

# Custom device name
python3 simple-ble-ota-client.py firmware.bin "MyDevice"

# Show help
python3 simple-ble-ota-client.py --help

Client Features

  • Automatic device discovery by name
  • Progress tracking with throughput display
  • CRC32 integrity verification
  • Comprehensive error handling
  • Batched transfers for optimal performance

API Reference

Functions

esp_err_t simple_ble_ota_init(void)

Initializes the Simple BLE OTA service and adds it to the GATT server.

Prerequisites:

  • NimBLE stack initialized
  • BLE host synced
  • GATT server running

Returns:

  • ESP_OK: Success
  • ESP_ERR_INVALID_STATE: BLE not initialized
  • ESP_FAIL: Failed to add service

bool simple_ble_ota_is_active(void)

Check if an OTA update is currently in progress.

Returns:

  • true: OTA update active
  • false: OTA idle

Error Codes

The ESP32 reports errors via BLE notifications:

  • 0x01: CRC mismatch (data corruption)
  • 0x02: Partition full (insufficient space)
  • 0x03: OTA begin failed
  • 0x04: OTA write failed
  • 0x05: OTA end failed
  • 0xFF: Unknown error

Performance

  • Transfer Speed: 40+ KB/s typical
  • Chunk Size: 244 bytes (optimal for BLE MTU)
  • Flow Control: Batched writes with periodic synchronization
  • Memory Usage: Minimal - uses ESP-IDF OTA buffers

Troubleshooting

Common Issues

"NimBLE stack not initialized"

  • Ensure nimble_port_init() is called before simple_ble_ota_init()

Device not discoverable

  • Set device name with ble_svc_gap_device_name_set()
  • Start advertising after initialization

Connection fails

  • Check device name matches Python client parameter
  • Ensure BLE advertising is active
  • Verify no firewall blocking Bluetooth

Transfer fails

  • Check partition table has OTA partitions
  • Ensure sufficient flash space
  • Verify firmware size is correct

Debug Logging

Enable component logging:

esp_log_level_set("SIMPLE_BLE_OTA", ESP_LOG_DEBUG);

License

MIT License - see LICENSE file for details.

Publish to Registry

Staging

$ compote registry login --profile "staging" --registry-url "https://components-staging.espressif.com" --default-namespace kodira
$ compote component upload --profile "staging" --name simple_ble_ota

Production

$ compote registry login --registry-url "https://components.espressif.com" --default-namespace kodira
$ compote component upload --name simple_ble_ota

About

Simple OTA over BLE for ESP32

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages