summaryrefslogtreecommitdiff
path: root/src/Components/Ble/DfuService.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Components/Ble/DfuService.h')
-rw-r--r--src/Components/Ble/DfuService.h168
1 files changed, 131 insertions, 37 deletions
diff --git a/src/Components/Ble/DfuService.h b/src/Components/Ble/DfuService.h
index 6249893d..d7ba460c 100644
--- a/src/Components/Ble/DfuService.h
+++ b/src/Components/Ble/DfuService.h
@@ -1,67 +1,161 @@
#pragma once
+
#include <cstdint>
#include <array>
#include <host/ble_gap.h>
namespace Pinetime {
+ namespace System {
+ class SystemTask;
+ }
+ namespace Drivers {
+ class SpiNorFlash;
+ }
namespace Controllers {
- class DeviceInformationService {
+ class Ble;
+
+ class DfuService {
public:
- DeviceInformationService();
+ DfuService(Pinetime::System::SystemTask &systemTask, Pinetime::Controllers::Ble &bleController,
+ Pinetime::Drivers::SpiNorFlash &spiNorFlash);
void Init();
+ int OnServiceData(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt *context);
+ void OnTimeout();
+ void Reset();
+
+ class NotificationManager {
+ public:
+ NotificationManager();
+ bool AsyncSend(uint16_t connection, uint16_t charactHandle, uint8_t *data, size_t size);
+ void Send(uint16_t connection, uint16_t characteristicHandle, const uint8_t *data, const size_t s);
+ private:
+ TimerHandle_t timer;
+ uint16_t connectionHandle = 0;
+ uint16_t characteristicHandle = 0;
+ size_t size = 0;
+ uint8_t buffer[10];
+ public:
+ void OnNotificationTimer();
+ void Reset();
+ };
+ class DfuImage {
+ public:
+ DfuImage(Pinetime::Drivers::SpiNorFlash& spiNorFlash) : spiNorFlash{spiNorFlash} {}
+ void Init(size_t chunkSize, size_t totalSize, uint16_t expectedCrc);
+ void Erase();
+ void Append(uint8_t* data, size_t size);
+ bool Validate();
+ bool IsComplete();
+
+ private:
+ Pinetime::Drivers::SpiNorFlash& spiNorFlash;
+ static constexpr size_t bufferSize = 200;
+ bool ready = false;
+ size_t chunkSize = 0;
+ size_t totalSize = 0;
+ size_t maxSize = 475136;
+ size_t bufferWriteIndex = 0;
+ size_t totalWriteIndex = 0;
+ static constexpr size_t writeOffset = 0x40000;
+ uint8_t tempBuffer[bufferSize];
+ uint16_t expectedCrc = 0;
- int OnDeviceInfoRequested(uint16_t conn_handle, uint16_t attr_handle,
- struct ble_gatt_access_ctxt *ctxt);
+ void WriteMagicNumber();
+ uint16_t ComputeCrc(uint8_t const *p_data, uint32_t size, uint16_t const *p_crc);
+
+ };
private:
- static constexpr uint16_t deviceInfoId {0x180a};
- static constexpr uint16_t manufacturerNameId {0x2a29};
- static constexpr uint16_t modelNumberId {0x2a24};
- static constexpr uint16_t serialNumberId {0x2a25};
- static constexpr uint16_t fwRevisionId {0x2a26};
- static constexpr uint16_t hwRevisionId {0x2a27};
-
- static constexpr char* manufacturerName = "Codingfield";
- static constexpr char* modelNumber = "1";
- static constexpr char* serialNumber = "9.8.7.6.5.4";
- static constexpr char* fwRevision = "0.5.0";
- static constexpr char* hwRevision = "1.0.0";
-
- static constexpr ble_uuid16_t deviceInfoUuid {
- .u { .type = BLE_UUID_TYPE_16 },
- .value = deviceInfoId
+ Pinetime::System::SystemTask &systemTask;
+ Pinetime::Controllers::Ble &bleController;
+ DfuImage dfuImage;
+ NotificationManager notificationManager;
+
+ static constexpr uint16_t dfuServiceId{0x1530};
+ static constexpr uint16_t packetCharacteristicId{0x1532};
+ static constexpr uint16_t controlPointCharacteristicId{0x1531};
+ static constexpr uint16_t revisionCharacteristicId{0x1534};
+
+ uint16_t revision{0x0008};
+
+ static constexpr ble_uuid128_t serviceUuid{
+ .u {.type = BLE_UUID_TYPE_128},
+ .value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15,
+ 0xDE, 0xEF, 0x12, 0x12, 0x30, 0x15, 0x00, 0x00}
};
- static constexpr ble_uuid16_t manufacturerNameUuid {
- .u { .type = BLE_UUID_TYPE_16 },
- .value = manufacturerNameId
+ static constexpr ble_uuid128_t packetCharacteristicUuid{
+ .u {.type = BLE_UUID_TYPE_128},
+ .value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15,
+ 0xDE, 0xEF, 0x12, 0x12, 0x32, 0x15, 0x00, 0x00}
};
- static constexpr ble_uuid16_t modelNumberUuid {
- .u { .type = BLE_UUID_TYPE_16 },
- .value = modelNumberId
+ static constexpr ble_uuid128_t controlPointCharacteristicUuid{
+ .u {.type = BLE_UUID_TYPE_128},
+ .value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15,
+ 0xDE, 0xEF, 0x12, 0x12, 0x31, 0x15, 0x00, 0x00}
};
- static constexpr ble_uuid16_t serialNumberUuid {
- .u { .type = BLE_UUID_TYPE_16 },
- .value = serialNumberId
+ static constexpr ble_uuid128_t revisionCharacteristicUuid{
+ .u {.type = BLE_UUID_TYPE_128},
+ .value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15,
+ 0xDE, 0xEF, 0x12, 0x12, 0x34, 0x15, 0x00, 0x00}
};
- static constexpr ble_uuid16_t fwRevisionUuid {
- .u { .type = BLE_UUID_TYPE_16 },
- .value = fwRevisionId
+ struct ble_gatt_chr_def characteristicDefinition[4];
+ struct ble_gatt_svc_def serviceDefinition[2];
+ uint16_t packetCharacteristicHandle;
+ uint16_t controlPointCharacteristicHandle;
+ uint16_t revisionCharacteristicHandle;
+
+ enum class States : uint8_t {
+ Idle, Init, Start, Data, Validate, Validated
};
+ States state = States::Idle;
- static constexpr ble_uuid16_t hwRevisionUuid {
- .u {.type = BLE_UUID_TYPE_16},
- .value = hwRevisionId
+ enum class ImageTypes : uint8_t {
+ NoImage = 0x00,
+ SoftDevice = 0x01,
+ Bootloader = 0x02,
+ SoftDeviceAndBootloader = 0x03,
+ Application = 0x04
};
- struct ble_gatt_chr_def characteristicDefinition[6];
- struct ble_gatt_svc_def serviceDefinition[2];
+ enum class Opcodes : uint8_t {
+ StartDFU = 0x01,
+ InitDFUParameters = 0x02,
+ ReceiveFirmwareImage = 0x03,
+ ValidateFirmware = 0x04,
+ ActivateImageAndReset = 0x05,
+ PacketReceiptNotificationRequest = 0x08,
+ Response = 0x10,
+ PacketReceiptNotification = 0x11
+ };
+
+ enum class ErrorCodes {
+ NoError = 0x01,
+ InvalidState = 0x02,
+ NotSupported = 0x03,
+ DataSizeExceedsLimits = 0x04,
+ CrcError = 0x05,
+ OperationFailed = 0x06
+ };
+
+ uint8_t nbPacketsToNotify = 0;
+ uint32_t nbPacketReceived = 0;
+ uint32_t bytesReceived = 0;
+
+ uint32_t softdeviceSize = 0;
+ uint32_t bootloaderSize = 0;
+ uint32_t applicationSize = 0;
+ uint16_t expectedCrc = 0;
+ int SendDfuRevision(os_mbuf *om) const;
+ int WritePacketHandler(uint16_t connectionHandle, os_mbuf *om);
+ int ControlPointHandler(uint16_t connectionHandle, os_mbuf *om);
+ TimerHandle_t timeoutTimer;
};
}
} \ No newline at end of file