mirror of
https://github.com/meshtastic/firmware.git
synced 2025-04-25 09:42:35 +00:00
move bluetooth OTA back into main tree for now
This commit is contained in:
parent
140e29840a
commit
14fdd33972
@ -1,21 +1,30 @@
|
|||||||
#include "BluetoothUtil.h"
|
|
||||||
#include "BluetoothSoftwareUpdate.h"
|
#include "BluetoothSoftwareUpdate.h"
|
||||||
#include "configuration.h"
|
#include "BluetoothUtil.h"
|
||||||
#include <esp_gatt_defs.h>
|
|
||||||
#include <BLE2902.h>
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <Update.h>
|
|
||||||
#include <CRC32.h>
|
|
||||||
#include "CallbackCharacteristic.h"
|
#include "CallbackCharacteristic.h"
|
||||||
|
#include "RadioLibInterface.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
#include "lock.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <BLE2902.h>
|
||||||
|
#include <CRC32.h>
|
||||||
|
#include <Update.h>
|
||||||
|
#include <esp_gatt_defs.h>
|
||||||
|
|
||||||
|
using namespace meshtastic;
|
||||||
|
|
||||||
CRC32 crc;
|
CRC32 crc;
|
||||||
uint32_t rebootAtMsec = 0; // If not zero we will reboot at this time (used to reboot shortly after the update completes)
|
uint32_t rebootAtMsec = 0; // If not zero we will reboot at this time (used to reboot shortly after the update completes)
|
||||||
|
|
||||||
|
uint32_t updateExpectedSize, updateActualSize;
|
||||||
|
|
||||||
|
Lock *updateLock;
|
||||||
|
|
||||||
class TotalSizeCharacteristic : public CallbackCharacteristic
|
class TotalSizeCharacteristic : public CallbackCharacteristic
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TotalSizeCharacteristic()
|
TotalSizeCharacteristic()
|
||||||
: CallbackCharacteristic("e74dd9c0-a301-4a6f-95a1-f0e1dbea8e1e", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ)
|
: CallbackCharacteristic("e74dd9c0-a301-4a6f-95a1-f0e1dbea8e1e",
|
||||||
|
BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,8 +32,11 @@ public:
|
|||||||
{
|
{
|
||||||
BLEKeepAliveCallbacks::onWrite(c);
|
BLEKeepAliveCallbacks::onWrite(c);
|
||||||
|
|
||||||
|
LockGuard g(updateLock);
|
||||||
// Check if there is enough to OTA Update
|
// Check if there is enough to OTA Update
|
||||||
uint32_t len = getValue32(c, 0);
|
uint32_t len = getValue32(c, 0);
|
||||||
|
updateExpectedSize = len;
|
||||||
|
updateActualSize = 0;
|
||||||
crc.reset();
|
crc.reset();
|
||||||
bool canBegin = Update.begin(len);
|
bool canBegin = Update.begin(len);
|
||||||
DEBUG_MSG("Setting update size %u, result %d\n", len, canBegin);
|
DEBUG_MSG("Setting update size %u, result %d\n", len, canBegin);
|
||||||
@ -34,32 +46,39 @@ public:
|
|||||||
else {
|
else {
|
||||||
// This totally breaks abstraction to up up into the app layer for this, but quick hack to make sure we only
|
// This totally breaks abstraction to up up into the app layer for this, but quick hack to make sure we only
|
||||||
// talk to one service during the sw update.
|
// talk to one service during the sw update.
|
||||||
//DEBUG_MSG("FIXME, crufty shutdown of mesh bluetooth for sw update.");
|
// DEBUG_MSG("FIXME, crufty shutdown of mesh bluetooth for sw update.");
|
||||||
//void stopMeshBluetoothService();
|
// void stopMeshBluetoothService();
|
||||||
//stopMeshBluetoothService();
|
// stopMeshBluetoothService();
|
||||||
|
|
||||||
|
if (RadioLibInterface::instance)
|
||||||
|
RadioLibInterface::instance->sleep(); // FIXME, nasty hack - the RF95 ISR/SPI code on ESP32 can fail while we are
|
||||||
|
// writing flash - shut the radio off during updates
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_BLOCKSIZE 512
|
||||||
|
|
||||||
class DataCharacteristic : public CallbackCharacteristic
|
class DataCharacteristic : public CallbackCharacteristic
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DataCharacteristic()
|
DataCharacteristic() : CallbackCharacteristic("e272ebac-d463-4b98-bc84-5cc1a39ee517", BLECharacteristic::PROPERTY_WRITE) {}
|
||||||
: CallbackCharacteristic(
|
|
||||||
"e272ebac-d463-4b98-bc84-5cc1a39ee517", BLECharacteristic::PROPERTY_WRITE)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void onWrite(BLECharacteristic *c)
|
void onWrite(BLECharacteristic *c)
|
||||||
{
|
{
|
||||||
BLEKeepAliveCallbacks::onWrite(c);
|
BLEKeepAliveCallbacks::onWrite(c);
|
||||||
|
|
||||||
|
LockGuard g(updateLock);
|
||||||
std::string value = c->getValue();
|
std::string value = c->getValue();
|
||||||
uint32_t len = value.length();
|
uint32_t len = value.length();
|
||||||
uint8_t *data = c->getData();
|
assert(len <= MAX_BLOCKSIZE);
|
||||||
|
static uint8_t
|
||||||
|
data[MAX_BLOCKSIZE]; // we temporarily copy here because I'm worried that a fast sender might be able overwrite srcbuf
|
||||||
|
memcpy(data, c->getData(), len);
|
||||||
// DEBUG_MSG("Writing %u\n", len);
|
// DEBUG_MSG("Writing %u\n", len);
|
||||||
crc.update(data, len);
|
crc.update(data, len);
|
||||||
Update.write(data, len);
|
Update.write(data, len);
|
||||||
|
updateActualSize += len;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,38 +86,36 @@ static BLECharacteristic *resultC;
|
|||||||
|
|
||||||
class CRC32Characteristic : public CallbackCharacteristic
|
class CRC32Characteristic : public CallbackCharacteristic
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CRC32Characteristic()
|
CRC32Characteristic() : CallbackCharacteristic("4826129c-c22a-43a3-b066-ce8f0d5bacc6", BLECharacteristic::PROPERTY_WRITE) {}
|
||||||
: CallbackCharacteristic(
|
|
||||||
"4826129c-c22a-43a3-b066-ce8f0d5bacc6", BLECharacteristic::PROPERTY_WRITE)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void onWrite(BLECharacteristic *c)
|
void onWrite(BLECharacteristic *c)
|
||||||
{
|
{
|
||||||
BLEKeepAliveCallbacks::onWrite(c);
|
BLEKeepAliveCallbacks::onWrite(c);
|
||||||
|
|
||||||
|
LockGuard g(updateLock);
|
||||||
uint32_t expectedCRC = getValue32(c, 0);
|
uint32_t expectedCRC = getValue32(c, 0);
|
||||||
|
uint32_t actualCRC = crc.finalize();
|
||||||
DEBUG_MSG("expected CRC %u\n", expectedCRC);
|
DEBUG_MSG("expected CRC %u\n", expectedCRC);
|
||||||
|
|
||||||
uint8_t result = 0xff;
|
uint8_t result = 0xff;
|
||||||
|
|
||||||
// Check the CRC before asking the update to happen.
|
if (updateActualSize != updateExpectedSize) {
|
||||||
if (crc.finalize() != expectedCRC)
|
DEBUG_MSG("Expected %u bytes, but received %u bytes!\n", updateExpectedSize, updateActualSize);
|
||||||
|
result = 0xe1; // FIXME, use real error codes
|
||||||
|
} else if (actualCRC != expectedCRC) // Check the CRC before asking the update to happen.
|
||||||
{
|
{
|
||||||
DEBUG_MSG("Invalid CRC!\n");
|
DEBUG_MSG("Invalid CRC! expected=%u, actual=%u\n", expectedCRC, actualCRC);
|
||||||
result = 0xe0; // FIXME, use real error codes
|
result = 0xe0; // FIXME, use real error codes
|
||||||
}
|
} else {
|
||||||
else
|
if (Update.end()) {
|
||||||
{
|
|
||||||
if (Update.end())
|
|
||||||
{
|
|
||||||
DEBUG_MSG("OTA done, rebooting in 5 seconds!\n");
|
DEBUG_MSG("OTA done, rebooting in 5 seconds!\n");
|
||||||
rebootAtMsec = millis() + 5000;
|
rebootAtMsec = millis() + 5000;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUG_MSG("Error Occurred. Error #: %d\n", Update.getError());
|
DEBUG_MSG("Error Occurred. Error #: %d\n", Update.getError());
|
||||||
|
|
||||||
|
if (RadioLibInterface::instance)
|
||||||
|
RadioLibInterface::instance->startReceive(); // Resume radio
|
||||||
}
|
}
|
||||||
result = Update.getError();
|
result = Update.getError();
|
||||||
}
|
}
|
||||||
@ -108,8 +125,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void bluetoothRebootCheck()
|
void bluetoothRebootCheck()
|
||||||
{
|
{
|
||||||
if (rebootAtMsec && millis() > rebootAtMsec)
|
if (rebootAtMsec && millis() > rebootAtMsec)
|
||||||
@ -122,11 +137,15 @@ See bluetooth-api.md
|
|||||||
*/
|
*/
|
||||||
BLEService *createUpdateService(BLEServer *server, std::string hwVendor, std::string swVersion, std::string hwVersion)
|
BLEService *createUpdateService(BLEServer *server, std::string hwVendor, std::string swVersion, std::string hwVersion)
|
||||||
{
|
{
|
||||||
|
if (!updateLock)
|
||||||
|
updateLock = new Lock();
|
||||||
|
|
||||||
// Create the BLE Service
|
// Create the BLE Service
|
||||||
BLEService *service = server->createService(BLEUUID("cb0b9a0b-a84c-4c0d-bdbb-442e3144ee30"), 25, 0);
|
BLEService *service = server->createService(BLEUUID("cb0b9a0b-a84c-4c0d-bdbb-442e3144ee30"), 25, 0);
|
||||||
|
|
||||||
assert(!resultC);
|
assert(!resultC);
|
||||||
resultC = new BLECharacteristic("5e134862-7411-4424-ac4a-210937432c77", BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
|
resultC = new BLECharacteristic("5e134862-7411-4424-ac4a-210937432c77",
|
||||||
|
BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
|
||||||
|
|
||||||
addWithDesc(service, new TotalSizeCharacteristic, "total image size");
|
addWithDesc(service, new TotalSizeCharacteristic, "total image size");
|
||||||
addWithDesc(service, new DataCharacteristic, "data");
|
addWithDesc(service, new DataCharacteristic, "data");
|
||||||
@ -135,7 +154,8 @@ BLEService *createUpdateService(BLEServer *server, std::string hwVendor, std::st
|
|||||||
|
|
||||||
resultC->addDescriptor(addBLEDescriptor(new BLE2902())); // Needed so clients can request notification
|
resultC->addDescriptor(addBLEDescriptor(new BLE2902())); // Needed so clients can request notification
|
||||||
|
|
||||||
BLECharacteristic *swC = new BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_SW_VERSION_STR), BLECharacteristic::PROPERTY_READ);
|
BLECharacteristic *swC =
|
||||||
|
new BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_SW_VERSION_STR), BLECharacteristic::PROPERTY_READ);
|
||||||
swC->setValue(swVersion);
|
swC->setValue(swVersion);
|
||||||
service->addCharacteristic(addBLECharacteristic(swC));
|
service->addCharacteristic(addBLECharacteristic(swC));
|
||||||
|
|
||||||
@ -143,7 +163,8 @@ BLEService *createUpdateService(BLEServer *server, std::string hwVendor, std::st
|
|||||||
mfC->setValue(hwVendor);
|
mfC->setValue(hwVendor);
|
||||||
service->addCharacteristic(addBLECharacteristic(mfC));
|
service->addCharacteristic(addBLECharacteristic(mfC));
|
||||||
|
|
||||||
BLECharacteristic *hwvC = new BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_HW_VERSION_STR), BLECharacteristic::PROPERTY_READ);
|
BLECharacteristic *hwvC =
|
||||||
|
new BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_HW_VERSION_STR), BLECharacteristic::PROPERTY_READ);
|
||||||
hwvC->setValue(hwVersion);
|
hwvC->setValue(hwVersion);
|
||||||
service->addCharacteristic(addBLECharacteristic(hwvC));
|
service->addCharacteristic(addBLECharacteristic(hwvC));
|
||||||
|
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <BLEDevice.h>
|
||||||
|
#include <BLEServer.h>
|
||||||
|
#include <BLEUtils.h>
|
||||||
|
|
||||||
BLEService *createUpdateService(BLEServer* server, std::string hwVendor, std::string swVersion, std::string hwVersion);
|
BLEService *createUpdateService(BLEServer *server, std::string hwVendor, std::string swVersion, std::string hwVersion);
|
||||||
|
|
||||||
void destroyUpdateService();
|
void destroyUpdateService();
|
||||||
void bluetoothRebootCheck();
|
void bluetoothRebootCheck();
|
@ -19,10 +19,6 @@ class RadioLibInterface : public RadioInterface
|
|||||||
volatile PendingISR pending = ISR_NONE;
|
volatile PendingISR pending = ISR_NONE;
|
||||||
volatile bool timerRunning = false;
|
volatile bool timerRunning = false;
|
||||||
|
|
||||||
/** Our ISR code currently needs this to find our active instance
|
|
||||||
*/
|
|
||||||
static RadioLibInterface *instance;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Raw ISR handler that just calls our polymorphic method
|
* Raw ISR handler that just calls our polymorphic method
|
||||||
*/
|
*/
|
||||||
@ -57,6 +53,11 @@ class RadioLibInterface : public RadioInterface
|
|||||||
/// are _trying_ to receive a packet currently (note - we might just be waiting for one)
|
/// are _trying_ to receive a packet currently (note - we might just be waiting for one)
|
||||||
bool isReceiving;
|
bool isReceiving;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Our ISR code currently needs this to find our active instance
|
||||||
|
*/
|
||||||
|
static RadioLibInterface *instance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Glue functions called from ISR land
|
* Glue functions called from ISR land
|
||||||
*/
|
*/
|
||||||
@ -80,6 +81,13 @@ class RadioLibInterface : public RadioInterface
|
|||||||
*/
|
*/
|
||||||
virtual bool canSleep();
|
virtual bool canSleep();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start waiting to receive a message
|
||||||
|
*
|
||||||
|
* External functions can call this method to wake the device from sleep.
|
||||||
|
*/
|
||||||
|
virtual void startReceive() = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** start an immediate transmit */
|
/** start an immediate transmit */
|
||||||
void startSend(MeshPacket *txp);
|
void startSend(MeshPacket *txp);
|
||||||
@ -110,11 +118,6 @@ class RadioLibInterface : public RadioInterface
|
|||||||
/** are we actively receiving a packet (only called during receiving state) */
|
/** are we actively receiving a packet (only called during receiving state) */
|
||||||
virtual bool isActivelyReceiving() = 0;
|
virtual bool isActivelyReceiving() = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Start waiting to receive a message
|
|
||||||
*/
|
|
||||||
virtual void startReceive() = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Raw ISR handler that just calls our polymorphic method
|
* Raw ISR handler that just calls our polymorphic method
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user