Compare commits
2 Commits
8d5b663c78
...
7f8c320b5a
| Author | SHA1 | Date | |
|---|---|---|---|
|
7f8c320b5a
|
|||
|
316fbd7c60
|
144
src/BLEOTA.cpp
144
src/BLEOTA.cpp
@@ -1,24 +1,146 @@
|
||||
#include "BLEOTA.h"
|
||||
|
||||
BLEOTAClass::BLEOTAClass(){
|
||||
_pVersionNumber = new BLECharacteristic(VERSION_NUMBER_UUID, BLECharacteristic::PROPERTY_READ);
|
||||
_pVersionNumberDescriptor = new BLEDescriptor(VERSION_NUMBER_DESCRIPTOR_UUID);
|
||||
/*
|
||||
MAIN CLASS
|
||||
*/
|
||||
|
||||
BLEOTAClass::BLEOTAClass()
|
||||
: pVersionNumber_(new BLECharacteristic(VERSION_NUMBER_UUID, BLECharacteristic::PROPERTY_READ)),
|
||||
pVersionNumberDescriptor_(new BLEDescriptor(VERSION_NUMBER_DESCRIPTOR_UUID)),
|
||||
pOTACommand_(new BLECharacteristic(OTA_COMMAND_UUID, BLECharacteristic::PROPERTY_NOTIFY | BLECharacteristic::PROPERTY_WRITE)),
|
||||
pOTACommandDescriptor_(new BLEDescriptor(OTA_COMMAND_DESCRIPTOR_UUID)),
|
||||
pOTAFile_(new BLECharacteristic(OTA_FILE_UUID, BLECharacteristic::PROPERTY_WRITE)),
|
||||
pOTAFileDescriptor_(new BLEDescriptor(OTA_FILE_DESCRIPTOR_UUID)) {
|
||||
cmdCallbacks_ = new OTACommandCallbacks(this);
|
||||
fileCallbacks_ = new OTAFileCallbacks(this);
|
||||
};
|
||||
|
||||
void BLEOTAClass::begin(BLEServer* server, char* versionNumber) {
|
||||
// set internal versionNumber
|
||||
_vNum = versionNumber;
|
||||
vNum_ = versionNumber;
|
||||
// set internal server
|
||||
_pServer = server;
|
||||
pServer_ = server;
|
||||
// create service
|
||||
BLEService* otaService = _pServer->createService(OTA_SERVICE_UUID);
|
||||
// version number property
|
||||
otaService->addCharacteristic(_pVersionNumber);
|
||||
_pVersionNumber->setValue(_vNum);
|
||||
_pVersionNumberDescriptor->setValue("Version Number");
|
||||
_pVersionNumber->addDescriptor(_pVersionNumberDescriptor);
|
||||
BLEService* otaService = pServer_->createService(OTA_SERVICE_UUID);
|
||||
|
||||
pVersionNumber_->setValue(vNum_);
|
||||
pVersionNumberDescriptor_->setValue("Version Number");
|
||||
pVersionNumber_->addDescriptor(pVersionNumberDescriptor_);
|
||||
|
||||
otaService->addCharacteristic(pVersionNumber_);
|
||||
pOTACommandDescriptor_->setValue("OTA Command");
|
||||
pOTACommand_->addDescriptor(pOTACommandDescriptor_);
|
||||
otaService->addCharacteristic(pOTACommand_);
|
||||
|
||||
pOTAFileDescriptor_->setValue("OTA File");
|
||||
pOTAFile_->addDescriptor(pOTAFileDescriptor_);
|
||||
otaService->addCharacteristic(pOTAFile_);
|
||||
|
||||
otaService->start();
|
||||
setOTAcommand(CMD_ON);
|
||||
state_ = STAGE_READY;
|
||||
}
|
||||
|
||||
void BLEOTAClass::setOTAcommand(otaCommand cmd) {
|
||||
uint8_t commandBuffer[1] = {};
|
||||
commandBuffer[0] = cmd;
|
||||
pOTACommand_->setValue(commandBuffer, 1);
|
||||
pOTACommand_->notify();
|
||||
currentCommand_ = cmd;
|
||||
}
|
||||
|
||||
void BLEOTAClass::loop() {
|
||||
if (millis() - lastLoop_ > 2000) {
|
||||
if (state_ == STAGE_ERROR && currentCommand_ != CMD_ERROR) {
|
||||
setOTAcommand(CMD_ERROR);
|
||||
}
|
||||
if (state_ == STAGE_DONE) {
|
||||
// reboot
|
||||
ESP.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
COMMAND CHARACTERISTIC CALLBACKS
|
||||
*/
|
||||
|
||||
// so that the callback has access to the main class
|
||||
BLEOTAClass::OTACommandCallbacks::OTACommandCallbacks(BLEOTAClass* pParent) : pParent_(pParent) {};
|
||||
|
||||
void BLEOTAClass::OTACommandCallbacks::onWrite(BLECharacteristic* pCharacteristic, esp_ble_gatts_cb_param_t* param) {
|
||||
size_t cmdLength = pCharacteristic->getLength();
|
||||
if (cmdLength > 4 && pParent_->state_ == STAGE_READY) {
|
||||
// error
|
||||
Serial.println("Error: command too long");
|
||||
pParent_->state_ = STAGE_ERROR;
|
||||
} else if (cmdLength > 1 && pParent_->state_ == STAGE_READY) {
|
||||
// process file size
|
||||
uint8_t* cmdBuffer = pCharacteristic->getData();
|
||||
uint32_t cmd = ((uint32_t)cmdBuffer[0] << 24) |
|
||||
((uint32_t)cmdBuffer[1] << 16) |
|
||||
((uint32_t)cmdBuffer[2] << 8) | (uint32_t)cmdBuffer[3];
|
||||
pParent_->fileSize_ = cmd;
|
||||
// start update
|
||||
if (!Update.begin(pParent_->fileSize_, U_FLASH)) {
|
||||
// error
|
||||
Serial.printf("Error: ");
|
||||
Update.printError(Serial);
|
||||
pParent_->state_ = STAGE_ERROR;
|
||||
return;
|
||||
}
|
||||
pParent_->state_ = STAGE_FLASHING;
|
||||
} else if (cmdLength == 0) {
|
||||
// process cmd
|
||||
uint8_t cmd = pCharacteristic->getData()[0];
|
||||
if (cmd == otaCommand::CMD_AGREE) {
|
||||
// process agree
|
||||
if (!Update.end()) {
|
||||
// error
|
||||
Serial.println("Error: client and server ready, but Updater is not");
|
||||
pParent_->state_ = STAGE_ERROR;
|
||||
} else {
|
||||
// reboot logic
|
||||
pParent_->state_ = STAGE_DONE;
|
||||
}
|
||||
} else if (cmd == CMD_DISAGREE) {
|
||||
// process disagree
|
||||
// start over
|
||||
Update.abort();
|
||||
pParent_->fileProgress_ = 0;
|
||||
} else {
|
||||
Serial.println("Error: wrong command");
|
||||
pParent_->state_ = STAGE_ERROR;
|
||||
}
|
||||
} else {
|
||||
Serial.println("Error: command length");
|
||||
pParent_->state_ = STAGE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
FILE CHARACTERISTIC CALLBACKS
|
||||
*/
|
||||
|
||||
// so that the callback has access to the main class
|
||||
BLEOTAClass::OTAFileCallbacks::OTAFileCallbacks(BLEOTAClass* pParent) : pParent_(pParent) {};
|
||||
|
||||
void BLEOTAClass::OTAFileCallbacks::onWrite(BLECharacteristic* pCharacteristic, esp_ble_gatts_cb_param_t* param) {
|
||||
size_t packetSize = pCharacteristic->getLength();
|
||||
if (packetSize == 0) {
|
||||
// problem
|
||||
// output error
|
||||
Serial.println("Error: no packet");
|
||||
pParent_->state_ = STAGE_ERROR;
|
||||
} else {
|
||||
// write file to updater
|
||||
uint8_t* filePacket = pCharacteristic->getData();
|
||||
if (Update.write(filePacket, packetSize) != packetSize) {
|
||||
Update.printError(Serial);
|
||||
pParent_->state_ = STAGE_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BLEOTAClass BLEota;
|
||||
83
src/BLEOTA.h
83
src/BLEOTA.h
@@ -3,20 +3,81 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <BLEServer.h>
|
||||
#include <Update.h>
|
||||
|
||||
#define OTA_SERVICE_UUID "71a4438e-fd52-4b15-b3d2-ec0e3e56193b"
|
||||
#define VERSION_NUMBER_UUID "1978a3df-c009-4837-b295-57ef429dde8c"
|
||||
#define VERSION_NUMBER_DESCRIPTOR_UUID "1e0c35d1-ba03-4f4d-a99c-bac7664d95ed"
|
||||
#define OTA_SERVICE_UUID "71a4438e-fd52-4b15-b3d2-ec0e3e561900"
|
||||
|
||||
#define VERSION_NUMBER_UUID "71a4438e-fd52-4b15-b3d2-ec0e3e561910"
|
||||
#define VERSION_NUMBER_DESCRIPTOR_UUID "71a4438e-fd52-4b15-b3d2-ec0e3e561911"
|
||||
|
||||
#define OTA_COMMAND_UUID "71a4438e-fd52-4b15-b3d2-ec0e3e561920"
|
||||
#define OTA_COMMAND_DESCRIPTOR_UUID "71a4438e-fd52-4b15-b3d2-ec0e3e561921"
|
||||
|
||||
#define OTA_FILE_UUID "71a4438e-fd52-4b15-b3d2-ec0e3e561930"
|
||||
#define OTA_FILE_DESCRIPTOR_UUID "71a4438e-fd52-4b15-b3d2-ec0e3e561931"
|
||||
|
||||
class BLEOTAClass {
|
||||
public:
|
||||
BLEOTAClass();
|
||||
void begin(BLEServer* server, char* versionNumber = "1.0.0");
|
||||
private:
|
||||
BLEServer* _pServer;
|
||||
char* _vNum;
|
||||
BLECharacteristic* _pVersionNumber;
|
||||
BLEDescriptor* _pVersionNumberDescriptor;
|
||||
public:
|
||||
BLEOTAClass();
|
||||
void begin(BLEServer* server, char* versionNumber = "1.0.0");
|
||||
void loop();
|
||||
|
||||
typedef enum otaCommand {
|
||||
CMD_ON = 0x00,
|
||||
CMD_READY = 0x01,
|
||||
CMD_DONE = 0x02,
|
||||
CMD_AGREE = 0x03,
|
||||
CMD_DISAGREE = 0x04,
|
||||
CMD_ERROR = 0x0F
|
||||
};
|
||||
|
||||
typedef enum otaStage {
|
||||
STAGE_READY,
|
||||
STAGE_FLASHING,
|
||||
STAGE_DONE,
|
||||
STAGE_ERROR
|
||||
};
|
||||
private:
|
||||
|
||||
void setOTAcommand(otaCommand cmd);
|
||||
|
||||
class OTACommandCallbacks : public BLECharacteristicCallbacks {
|
||||
public:
|
||||
OTACommandCallbacks(BLEOTAClass* pParent);
|
||||
void onWrite(BLECharacteristic* pCharacteristic, esp_ble_gatts_cb_param_t* param) override;
|
||||
private:
|
||||
BLEOTAClass* pParent_;
|
||||
};
|
||||
|
||||
class OTAFileCallbacks : public BLECharacteristicCallbacks {
|
||||
public:
|
||||
OTAFileCallbacks(BLEOTAClass* pParent);
|
||||
void onWrite(BLECharacteristic* pCharacteristic, esp_ble_gatts_cb_param_t* param) override;
|
||||
private:
|
||||
BLEOTAClass* pParent_;
|
||||
};
|
||||
|
||||
BLEServer* pServer_;
|
||||
char* vNum_;
|
||||
|
||||
BLECharacteristic* pVersionNumber_;
|
||||
BLEDescriptor* pVersionNumberDescriptor_;
|
||||
|
||||
BLECharacteristic* pOTACommand_;
|
||||
BLEDescriptor* pOTACommandDescriptor_;
|
||||
OTACommandCallbacks* cmdCallbacks_;
|
||||
otaCommand currentCommand_;
|
||||
|
||||
BLECharacteristic* pOTAFile_;
|
||||
BLEDescriptor* pOTAFileDescriptor_;
|
||||
OTAFileCallbacks* fileCallbacks_;
|
||||
|
||||
uint32_t fileSize_ = 0;
|
||||
uint32_t fileProgress_ = 0;
|
||||
|
||||
otaStage state_ = otaStage::STAGE_READY;
|
||||
|
||||
unsigned long lastLoop_ = 0;
|
||||
};
|
||||
|
||||
extern BLEOTAClass BLEota;
|
||||
|
||||
Reference in New Issue
Block a user