diff --git a/lib/BluetoothOTA/src/BluetoothSoftwareUpdate.cpp b/lib/BluetoothOTA/src/BluetoothSoftwareUpdate.cpp index e5401c32..40ac092b 100644 --- a/lib/BluetoothOTA/src/BluetoothSoftwareUpdate.cpp +++ b/lib/BluetoothOTA/src/BluetoothSoftwareUpdate.cpp @@ -6,84 +6,113 @@ #include #include #include - -static BLECharacteristic swUpdateTotalSizeCharacteristic("e74dd9c0-a301-4a6f-95a1-f0e1dbea8e1e", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ); -static BLECharacteristic swUpdateDataCharacteristic("e272ebac-d463-4b98-bc84-5cc1a39ee517", BLECharacteristic::PROPERTY_WRITE); -static BLECharacteristic swUpdateCRC32Characteristic("4826129c-c22a-43a3-b066-ce8f0d5bacc6", BLECharacteristic::PROPERTY_WRITE); -static BLECharacteristic swUpdateResultCharacteristic("5e134862-7411-4424-ac4a-210937432c77", BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY); +#include "CallbackCharacteristic.h" CRC32 crc; uint32_t rebootAtMsec = 0; // If not zero we will reboot at this time (used to reboot shortly after the update completes) -class UpdateCallbacks : public BLECharacteristicCallbacks +class TotalSizeCharacteristic : public CallbackCharacteristic { - void onRead(BLECharacteristic *pCharacteristic) { - DEBUG_MSG("Got on read\n"); +public: + TotalSizeCharacteristic() + : CallbackCharacteristic("e74dd9c0-a301-4a6f-95a1-f0e1dbea8e1e", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ) + { } - void onWrite(BLECharacteristic *pCharacteristic) + void onWrite(BLECharacteristic *c) { - // dumpCharacteristic(pCharacteristic); + BLEKeepAliveCallbacks::onWrite(c); - if (pCharacteristic == &swUpdateTotalSizeCharacteristic) - { - // Check if there is enough to OTA Update - uint32_t len = getValue32(pCharacteristic, 0); - crc.reset(); - bool canBegin = Update.begin(len); - DEBUG_MSG("Setting update size %u, result %d\n", len, canBegin); - if(!canBegin) - // Indicate failure by forcing the size to 0 - pCharacteristic->setValue(0UL); - } - else if (pCharacteristic == &swUpdateDataCharacteristic) - { - std::string value = pCharacteristic->getValue(); - uint32_t len = value.length(); - uint8_t *data = pCharacteristic->getData(); - // DEBUG_MSG("Writing %u\n", len); - crc.update(data, len); - Update.write(data, len); - } - else if (pCharacteristic == &swUpdateCRC32Characteristic) - { - uint32_t expectedCRC = getValue32(pCharacteristic, 0); - DEBUG_MSG("expected CRC %u\n", expectedCRC); - - uint8_t result = 0xff; - - // Check the CRC before asking the update to happen. - if(crc.finalize() != expectedCRC) { - DEBUG_MSG("Invalid CRC!\n"); - result = 0xe0; // FIXME, use real error codes - } - else { - if (Update.end()) - { - DEBUG_MSG("OTA done, rebooting in 5 seconds!\n"); - rebootAtMsec = millis() + 5000; - } - else - { - DEBUG_MSG("Error Occurred. Error #: %d\n", Update.getError()); - } - result = Update.getError(); - } - swUpdateResultCharacteristic.setValue(&result, 1); - swUpdateResultCharacteristic.notify(); - } - else { - DEBUG_MSG("unexpected write\n"); - } + // Check if there is enough to OTA Update + uint32_t len = getValue32(c, 0); + crc.reset(); + bool canBegin = Update.begin(len); + DEBUG_MSG("Setting update size %u, result %d\n", len, canBegin); + if (!canBegin) + // Indicate failure by forcing the size to 0 + c->setValue(0UL); } }; -void bluetoothRebootCheck() { - if(rebootAtMsec && millis() > rebootAtMsec) +class DataCharacteristic : public CallbackCharacteristic +{ +public: + DataCharacteristic() + : CallbackCharacteristic( + "e272ebac-d463-4b98-bc84-5cc1a39ee517", BLECharacteristic::PROPERTY_WRITE) + { + } + + void onWrite(BLECharacteristic *c) + { + BLEKeepAliveCallbacks::onWrite(c); + + std::string value = c->getValue(); + uint32_t len = value.length(); + uint8_t *data = c->getData(); + // DEBUG_MSG("Writing %u\n", len); + crc.update(data, len); + Update.write(data, len); + } +}; + +static BLECharacteristic swUpdateResultCharacteristic("5e134862-7411-4424-ac4a-210937432c77", BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY); + + +class CRC32Characteristic : public CallbackCharacteristic +{ +public: + CRC32Characteristic() + : CallbackCharacteristic( + "4826129c-c22a-43a3-b066-ce8f0d5bacc6", BLECharacteristic::PROPERTY_WRITE) + { + } + + void onWrite(BLECharacteristic *c) + { + BLEKeepAliveCallbacks::onWrite(c); + + uint32_t expectedCRC = getValue32(c, 0); + DEBUG_MSG("expected CRC %u\n", expectedCRC); + + uint8_t result = 0xff; + + // Check the CRC before asking the update to happen. + if (crc.finalize() != expectedCRC) + { + DEBUG_MSG("Invalid CRC!\n"); + result = 0xe0; // FIXME, use real error codes + } + else + { + if (Update.end()) + { + DEBUG_MSG("OTA done, rebooting in 5 seconds!\n"); + rebootAtMsec = millis() + 5000; + } + else + { + DEBUG_MSG("Error Occurred. Error #: %d\n", Update.getError()); + } + result = Update.getError(); + } + swUpdateResultCharacteristic.setValue(&result, 1); + swUpdateResultCharacteristic.notify(); + } +}; + + +static TotalSizeCharacteristic swUpdateTotalSizeCharacteristic; +static DataCharacteristic swUpdateDataCharacteristic; +static CRC32Characteristic swUpdateCRC32Characteristic; + + +void bluetoothRebootCheck() +{ + if (rebootAtMsec && millis() > rebootAtMsec) ESP.restart(); } -static UpdateCallbacks updateCb; /* SoftwareUpdateService UUID cb0b9a0b-a84c-4c0d-bdbb-442e3144ee30 @@ -96,7 +125,8 @@ e272ebac-d463-4b98-bc84-5cc1a39ee517 write data, variable sized, r 4826129c-c22a-43a3-b066-ce8f0d5bacc6 write crc32, write last - writing this will complete the OTA operation, now you can read result 5e134862-7411-4424-ac4a-210937432c77 read|notify result code, readable but will notify when the OTA operation completes */ -BLEService *createUpdateService(BLEServer* server) { +BLEService *createUpdateService(BLEServer *server) +{ // Create the BLE Service BLEService *service = server->createService("cb0b9a0b-a84c-4c0d-bdbb-442e3144ee30"); @@ -105,12 +135,7 @@ BLEService *createUpdateService(BLEServer* server) { addWithDesc(service, &swUpdateCRC32Characteristic, "crc32"); addWithDesc(service, &swUpdateResultCharacteristic, "result code"); - swUpdateTotalSizeCharacteristic.setCallbacks(&updateCb); - swUpdateDataCharacteristic.setCallbacks(&updateCb); - swUpdateCRC32Characteristic.setCallbacks(&updateCb); - - swUpdateResultCharacteristic.addDescriptor(new(btPool) BLE2902()); // Needed so clients can request notification + swUpdateResultCharacteristic.addDescriptor(new (btPool) BLE2902()); // Needed so clients can request notification return service; } - diff --git a/lib/BluetoothOTA/src/CallbackCharacteristic.h b/lib/BluetoothOTA/src/CallbackCharacteristic.h new file mode 100644 index 00000000..daec1d50 --- /dev/null +++ b/lib/BluetoothOTA/src/CallbackCharacteristic.h @@ -0,0 +1,33 @@ +#pragma once +#include "PowerFSM.h" // FIXME - someday I want to make this OTA thing a separate lb at at that point it can't touch this +#include "BLECharacteristic.h" + +/** + * This mixin just lets the power management state machine know the phone is still talking to us + */ +class BLEKeepAliveCallbacks : public BLECharacteristicCallbacks +{ +public: + void onRead(BLECharacteristic *c) + { + powerFSM.trigger(EVENT_CONTACT_FROM_PHONE); + } + + void onWrite(BLECharacteristic *c) + { + powerFSM.trigger(EVENT_CONTACT_FROM_PHONE); + } +}; + +/** + * A characterstic with a set of overridable callbacks + */ +class CallbackCharacteristic : public BLECharacteristic, public BLEKeepAliveCallbacks +{ +public: + CallbackCharacteristic(const char *uuid, uint32_t btprops) + : BLECharacteristic(uuid, btprops) + { + setCallbacks(this); + } +}; diff --git a/platformio.ini b/platformio.ini index 37629545..355170de 100644 --- a/platformio.ini +++ b/platformio.ini @@ -21,7 +21,8 @@ framework = arduino board_build.partitions = partition-table.csv ; note: we add src to our include search path so that lmic_project_config can override -build_flags = -Wall -Wextra -Wno-missing-field-initializers -Isrc -Os -Wl,-Map,.pio/build/esp32/output.map -DAXP_DEBUG_PORT=Serial +; FIXME fix dependencies on arduino-fsm +build_flags = -Wall -Wextra -Wno-missing-field-initializers -I.pio/libdeps/esp32/arduino-fsm -Isrc -Os -Wl,-Map,.pio/build/esp32/output.map -DAXP_DEBUG_PORT=Serial ; not needed included in ttgo-t-beam board file ; also to use PSRAM https://docs.platformio.org/en/latest/platforms/espressif32.html#external-ram-psram diff --git a/src/MeshBluetoothService.cpp b/src/MeshBluetoothService.cpp index bb735f59..e90f6536 100644 --- a/src/MeshBluetoothService.cpp +++ b/src/MeshBluetoothService.cpp @@ -11,39 +11,11 @@ #include "NodeDB.h" #include "configuration.h" #include "PowerFSM.h" +#include "CallbackCharacteristic.h" // This scratch buffer is used for various bluetooth reads/writes - but it is safe because only one bt operation can be in proccess at once static uint8_t trBytes[_max(_max(_max(_max(ToRadio_size, RadioConfig_size), User_size), MyNodeInfo_size), FromRadio_size)]; -/** - * This mixin just lets the power management state machine know the phone is still talking to us - */ -class BLEKeepAliveCallbacks : public BLECharacteristicCallbacks -{ -public: - void onRead(BLECharacteristic *c) - { - powerFSM.trigger(EVENT_CONTACT_FROM_PHONE); - } - - void onWrite(BLECharacteristic *c) - { - powerFSM.trigger(EVENT_CONTACT_FROM_PHONE); - } -}; - -/** - * A characterstic with a set of overridable callbacks - */ -class CallbackCharacteristic : public BLECharacteristic, public BLEKeepAliveCallbacks -{ -public: - CallbackCharacteristic(const char *uuid, uint32_t btprops) - : BLECharacteristic(uuid, btprops) - { - setCallbacks(this); - } -}; class ProtobufCharacteristic : public CallbackCharacteristic {