{"id":27639468,"url":"https://github.com/h2zero/nimbleota","last_synced_at":"2025-10-09T16:05:49.994Z","repository":{"id":269618122,"uuid":"865003069","full_name":"h2zero/NimBLEOta","owner":"h2zero","description":"BLE over the air firmware updating for esp32","archived":false,"fork":false,"pushed_at":"2025-04-12T22:27:28.000Z","size":106,"stargazers_count":13,"open_issues_count":2,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-07-18T04:00:32.469Z","etag":null,"topics":["arduino","ble","esp32","nimble","nimble-arduino-library","over-the-air-update"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/h2zero.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"h2zero","custom":["https://paypal.me/h2zero"]}},"created_at":"2024-09-29T18:23:44.000Z","updated_at":"2025-07-18T00:56:04.000Z","dependencies_parsed_at":"2024-12-24T21:44:59.965Z","dependency_job_id":"4bf5cad4-f179-4391-aa2c-17d7e6f77051","html_url":"https://github.com/h2zero/NimBLEOta","commit_stats":null,"previous_names":["h2zero/nimbleota"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/h2zero/NimBLEOta","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2zero%2FNimBLEOta","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2zero%2FNimBLEOta/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2zero%2FNimBLEOta/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2zero%2FNimBLEOta/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/h2zero","download_url":"https://codeload.github.com/h2zero/NimBLEOta/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2zero%2FNimBLEOta/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266608972,"owners_count":23955546,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","ble","esp32","nimble","nimble-arduino-library","over-the-air-update"],"created_at":"2025-04-23T22:16:53.059Z","updated_at":"2025-10-09T16:05:49.914Z","avatar_url":"https://github.com/h2zero.png","language":"C++","funding_links":["https://github.com/sponsors/h2zero","https://paypal.me/h2zero"],"categories":[],"sub_categories":[],"readme":"# NimBLE OTA\n\n`NimBLE OTA` is based on the [Espressif ble ota component](https://components.espressif.com/components/espressif/ble_ota/versions/0.1.12) which will update the firmware of an esp32 device Over The Air via Bluetooth Low Energy.\n\nThis creates an OTA Service with the UUID `0x8018` and an optional [Device Information Service.](https://www.bluetooth.com/specifications/specs/device-information-service-1-1/)\n\n## Sponsored by\n\n\u003ca href = \"https://www.theengs.io\"\u003e\u003cimg src=\"extras/logo-Theengs.jpg\" height=\"100\"/\u003e\u003c/a\u003e\n\n## Dependencies\n\n[NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino) Version 2.1 or higher. Or [esp-nimble-cpp](https://github.com/h2zero/esp-nimble-cpp) Version 2.0 or higher.\n\n## Supported MCU's\n\nEspressif esp32 devices with Bluetooth capability.\n\n## Using\n```\n#include \u003cNimBLEOta.h\u003e // include the header in your source file\n\nstatic NimBLEOta bleOta; // Create an instance of NimBLEOta\n\nvoid setup() {\n    NimBLEDevice::init(\"NimBLE OTA\"); // Initialize NimBLE\n    bleOta.start(); // start the service\n}\n```\n\nIf you want to have callbacks to your application to receive information about BLE OTA operations you can pass an optional pointer to your callback class which must be derived from `NimBLEOtaCallbacks`.\n```\nclass OtaCallbacks : public NimBLEOtaCallbacks {\n} otaCallbacks;\n\nvoid setup() {\n    NimBLEDevice::init(\"NimBLE OTA\"); // Initialize NimBLE\n    bleOta.start(\u0026otaCallbacks); // start the service with callbacks\n}\n```\n\nCheck out the examples for more detail.\n\n### Security\n\nIf you want to enable security you should initialize the NimBLE security options before calling `bleOta.start()`, you must enable man in the middle protection and use a passkey like so:\n```\n// Use passkey authentication\nNimBLEDevice::setSecurityAuth(false, true, true);\nNimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY);\n```\n\nYou can now start NimBLEOta with security enabled by pass `true` as the second parameter to `start()`, i.e. `bleOta.start(\u0026otaCallbacks, true);`\n\n## Uploading OTA\n\nFor best results use the included [python script.](scripts\\nimbleota.py)  \nThis also works with [BLEOTA_WEBAPP](https://gb88.github.io/BLEOTA/) by @gb88.\n\n## 1. How it works\n\n- `OTA Service`: It is used for OTA upgrade and contains 4 characteristics, as shown in the following table:\n\n|  Characteristics   | UUID  |  Prop   | description  |\n|  ----  | ----  |  ----  | ----  |\n|  RECV_FW_CHAR | 0x8020 | Write, notify  | Firmware received, send ACK |\n|  PROGRESS_BAR_CHAR  | 0x8021 | Read, notify  | Read the progress bar and report the progress bar |\n|  COMMAND_CHAR  | 0x8022 | Write, notify  | Send the command and ACK |\n|  CUSTOMER_CHAR  | 0x8023 | Write, notify  | User-defined data to send and receive |\n\n## 2. Data transmission\n\n### 2.1 Command package format\n\n|  unit   | Command_ID  |  PayLoad   | CRC16  |\n|  ----  | ----  |  ----  | ----  |\n|  Byte | Byte: 0 ~ 1 | Byte: 2 ~ 17  | Byte: 18 ~ 19 |\n\nCommand_ID:\n\n- 0x0001: Start OTA, Payload bytes(2 to 5), indicates the length of the firmware. Other Payload is set to 0 by default. CRC16 calculates bytes(0 to 17).\n- 0x0002: Stop OTA, and the remaining Payload will be set to 0. CRC16 calculates bytes(0 to 17).\n- 0x0003: The Payload bytes(2 or 3) is the payload of the Command_ID for which the response will be sent. Payload bytes(4 to 5) is a response to the command. 0x0000 indicates accept, 0x0001 indicates reject. Other payloads are set to 0. CRC16 computes bytes(0 to 17).\n\n### 2.2 Firmware package format\n\nThe format of the firmware package sent by the client is as follows:\n\n|  unit   | Sector_Index  |  Packet_Seq   | PayLoad  |\n|  ----  | ----  |  ----  | ----  |\n|  Byte | Byte: 0 ~ 1 | Byte: 2  | Byte: 3 ~ (MTU_size - 4) |\n\n- Sector_Index：Indicates the number of sectors, sector number increases from 0, cannot jump, must be send 4K data and then start transmit the next sector, otherwise it will immediately send the error ACK for request retransmission.\n- Packet_Seq：If Packet_Seq is 0xFF, it indicates that this is the last packet of the sector, and the last 2 bytes of Payload is the CRC16 value of 4K data for the entire sector, the remaining bytes will set to 0x0. Server will check the total length and CRC of the data from the client, reply the correct ACK, and then start receive the next sector of firmware data.\n\nThe format of the reply packet is as follows:\n\n|  unit   | Sector_Index  |  ACK_Status   | CRC6  |\n|  ----  | ----  |  ----  | ----  |\n|  Byte | Byte: 0 ~ 1 | Byte: 2 ~ 3  | Byte: 18 ~ 19 |\n\nACK_Status:\n\n- 0x0000: Success\n- 0x0001: CRC error\n- 0x0002: Sector_Index error, bytes(4 ~ 5) indicates the desired Sector_Index\n- 0x0003：Payload length error\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fh2zero%2Fnimbleota","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fh2zero%2Fnimbleota","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fh2zero%2Fnimbleota/lists"}