diff options
Diffstat (limited to 'src/Components/Ble/DfuService.cpp')
-rw-r--r-- | src/Components/Ble/DfuService.cpp | 110 |
1 files changed, 61 insertions, 49 deletions
diff --git a/src/Components/Ble/DfuService.cpp b/src/Components/Ble/DfuService.cpp index 38a550f0..a170fdfa 100644 --- a/src/Components/Ble/DfuService.cpp +++ b/src/Components/Ble/DfuService.cpp @@ -17,8 +17,8 @@ int DfuServiceCallback(uint16_t conn_handle, uint16_t attr_handle, } void NotificationTimerCallback(TimerHandle_t xTimer) { - auto dfuService = static_cast<DfuService *>(pvTimerGetTimerID(xTimer)); - dfuService->OnNotificationTimer(); + auto notificationManager = static_cast<DfuService::NotificationManager *>(pvTimerGetTimerID(xTimer)); + notificationManager->OnNotificationTimer(); } void TimeoutTimerCallback(TimerHandle_t xTimer) { @@ -70,7 +70,6 @@ DfuService::DfuService(Pinetime::System::SystemTask &systemTask, Pinetime::Contr 0 }, } { - notificationTimer = xTimerCreate ("notificationTimer", 1000, pdFALSE, this, NotificationTimerCallback); timeoutTimer = xTimerCreate ("notificationTimer", 10000, pdFALSE, this, TimeoutTimerCallback); } @@ -132,7 +131,7 @@ int DfuService::WritePacketHandler(uint16_t connectionHandle, os_mbuf *om) { } uint8_t data[]{16, 1, 1}; - SendNotification(connectionHandle, data, 3); + notificationManager.Send(connectionHandle, controlPointCharacteristicHandle, data, 3); state = States::Init; } return 0; @@ -162,30 +161,22 @@ int DfuService::WritePacketHandler(uint16_t connectionHandle, os_mbuf *om) { std::memcpy(tempBuffer + offset, om->om_data, om->om_len); if (nbPacketReceived > 0 && (nbPacketReceived % nbPacketsToNotify) == 0) { -#if 1 spiNorFlash.Write(writeOffset + ((nbPacketReceived - nbPacketsToNotify) * 20), tempBuffer, 200); -#endif } - bytesReceived += om->om_len; bleController.FirmwareUpdateCurrentBytes(bytesReceived); - //NRF_LOG_INFO("[DFU] -> Bytes received : %d in %d packets", bytesReceived, nbPacketReceived); - - if ((nbPacketReceived % nbPacketsToNotify) == 0 && bytesReceived != applicationSize) { uint8_t data[5]{static_cast<uint8_t>(Opcodes::PacketReceiptNotification), (uint8_t) (bytesReceived & 0x000000FFu), (uint8_t) (bytesReceived >> 8u), (uint8_t) (bytesReceived >> 16u), (uint8_t) (bytesReceived >> 24u)}; NRF_LOG_INFO("[DFU] -> Send packet notification: %d bytes received", bytesReceived); - SendNotification(connectionHandle, data, 5); + notificationManager.Send(connectionHandle, controlPointCharacteristicHandle, data, 5); } if (bytesReceived == applicationSize) { if ((nbPacketReceived % nbPacketsToNotify) != 0) { auto remaningPacket = nbPacketReceived % nbPacketsToNotify; - uint32_t spiOffset = writeOffset + ((nbPacketReceived - remaningPacket) * 20); - spiNorFlash.Write(writeOffset + ((nbPacketReceived - remaningPacket) * 20), tempBuffer, remaningPacket * 20); } @@ -196,7 +187,7 @@ int DfuService::WritePacketHandler(uint16_t connectionHandle, os_mbuf *om) { static_cast<uint8_t>(Opcodes::ReceiveFirmwareImage), static_cast<uint8_t>(ErrorCodes::NoError)}; NRF_LOG_INFO("[DFU] -> Send packet notification : all bytes received!"); - SendNotification(connectionHandle, data, 3); + notificationManager.Send(connectionHandle, controlPointCharacteristicHandle, data, 3); state = States::Validate; } } @@ -247,12 +238,12 @@ int DfuService::ControlPointHandler(uint16_t connectionHandle, os_mbuf *om) { NRF_LOG_INFO("[DFU] -> Init DFU parameters %s", isInitComplete ? " complete" : " not complete"); if (isInitComplete) { - notificationBuffer[0] = static_cast<uint8_t>(Opcodes::Response); - notificationBuffer[1] = static_cast<uint8_t>(Opcodes::InitDFUParameters); - notificationBuffer[2] = (isInitComplete ? uint8_t{1} : uint8_t{0}); - notificationSize = 3; - notificatonConnectionHandle = connectionHandle; - xTimerStart(notificationTimer, 0); + uint8_t data[3] { + static_cast<uint8_t>(Opcodes::Response), + static_cast<uint8_t>(Opcodes::InitDFUParameters), + (isInitComplete ? uint8_t{1} : uint8_t{0}) + }; + notificationManager.AsyncSend(connectionHandle, controlPointCharacteristicHandle, data, 3); return 0; } } @@ -279,21 +270,19 @@ int DfuService::ControlPointHandler(uint16_t connectionHandle, os_mbuf *om) { if(Validate()){ state = States::Validated; - - notificationBuffer[0] = static_cast<uint8_t>(Opcodes::Response); - notificationBuffer[1] = static_cast<uint8_t>(Opcodes::ValidateFirmware); - notificationBuffer[2] = static_cast<uint8_t>(ErrorCodes::NoError); - notificationSize = 3; - notificatonConnectionHandle = connectionHandle; - xTimerStart(notificationTimer, 0); - + uint8_t data[3] { + static_cast<uint8_t>(Opcodes::Response), + static_cast<uint8_t>(Opcodes::ValidateFirmware), + static_cast<uint8_t>(ErrorCodes::NoError) + }; + notificationManager.AsyncSend(connectionHandle, controlPointCharacteristicHandle, data, 3); } else { - notificationBuffer[0] = static_cast<uint8_t>(Opcodes::Response); - notificationBuffer[1] = static_cast<uint8_t>(Opcodes::ValidateFirmware); - notificationBuffer[2] = static_cast<uint8_t>(ErrorCodes::CrcError); - notificationSize = 3; - notificatonConnectionHandle = connectionHandle; - xTimerStart(notificationTimer, 0); + uint8_t data[3] { + static_cast<uint8_t>(Opcodes::Response), + static_cast<uint8_t>(Opcodes::ValidateFirmware), + static_cast<uint8_t>(ErrorCodes::CrcError) + }; + notificationManager.AsyncSend(connectionHandle, controlPointCharacteristicHandle, data, 3); } return 0; @@ -314,11 +303,7 @@ int DfuService::ControlPointHandler(uint16_t connectionHandle, os_mbuf *om) { } } -void DfuService::SendNotification(uint16_t connectionHandle, const uint8_t *data, const size_t size) { - auto *om = ble_hs_mbuf_from_flat(data, size); - auto ret = ble_gattc_notify_custom(connectionHandle, controlPointCharacteristicHandle, om); - ASSERT(ret == 0); -} + uint16_t DfuService::ComputeCrc(uint8_t const *p_data, uint32_t size, uint16_t const *p_crc) { uint16_t crc = (p_crc == NULL) ? 0xFFFF : *p_crc; @@ -376,13 +361,6 @@ void DfuService::WriteMagicNumber() { spiNorFlash.Write(offset, reinterpret_cast<uint8_t *>(magic), 4 * sizeof(uint32_t)); } -void DfuService::OnNotificationTimer() { - if(notificationSize > 0) { - SendNotification(notificatonConnectionHandle, notificationBuffer, notificationSize); - notificationSize = 0; - } -} - void DfuService::OnTimeout() { Reset(); } @@ -396,10 +374,44 @@ void DfuService::Reset() { bootloaderSize = 0; applicationSize = 0; expectedCrc = 0; - notificatonConnectionHandle = 0; - notificationSize = 0; - xTimerStop(notificationTimer, 0); + notificationManager.Reset(); bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Error); bleController.StopFirmwareUpdate(); systemTask.PushMessage(Pinetime::System::SystemTask::Messages::BleFirmwareUpdateFinished); } + +DfuService::NotificationManager::NotificationManager() { + timer = xTimerCreate ("notificationTimer", 1000, pdFALSE, this, NotificationTimerCallback); +} + +bool DfuService::NotificationManager::AsyncSend(uint16_t connection, uint16_t charactHandle, uint8_t *data, size_t s) { + if(size != 0 || s > 10) + return false; + + connectionHandle = connection; + characteristicHandle = charactHandle; + size = s; + std::memcpy(buffer, data, size); + xTimerStart(timer, 0); + return true; +} + +void DfuService::NotificationManager::OnNotificationTimer() { + if(size > 0) { + Send(connectionHandle, characteristicHandle, buffer, size); + size = 0; + } +} + +void DfuService::NotificationManager::Send(uint16_t connection, uint16_t charactHandle, const uint8_t *data, const size_t s) { + auto *om = ble_hs_mbuf_from_flat(data, s); + auto ret = ble_gattc_notify_custom(connection, charactHandle, om); + ASSERT(ret == 0); +} + +void DfuService::NotificationManager::Reset() { + connectionHandle = 0; + characteristicHandle = 0; + size = 0; + xTimerStop(timer, 0); +} |