diff --git a/app/os/main.cpp b/app/os/main.cpp index 6620c00ffa..47ae730c5e 100644 --- a/app/os/main.cpp +++ b/app/os/main.cpp @@ -36,7 +36,7 @@ auto coreflashmanager = CoreFlashManagerIS25LP016D(coreqspi); auto coreflash = CoreFlashIS25LP016D(coreqspi, coreflashmanager); auto firmwarekit = FirmwareKit(coreflash); -auto rc = RobotController {sleep_timeout, battery}; +auto rc = RobotController {sleep_timeout, battery, firmwarekit}; void initializeSD() { @@ -87,7 +87,7 @@ auto main() -> int initializeUpdateFlash(); rc.initializeComponents(); - // rc.registerOnUpdateLoadedCallback(setPendingUpdate); + rc.registerOnUpdateLoadedCallback(setPendingUpdate); rc.registerEvents(); while (true) { diff --git a/libs/RobotKit/include/RobotController.h b/libs/RobotKit/include/RobotController.h index 1198319bb6..36265595e1 100644 --- a/libs/RobotKit/include/RobotController.h +++ b/libs/RobotKit/include/RobotController.h @@ -12,6 +12,7 @@ #include "StateMachine.h" #include "interface/RobotController.h" #include "interface/drivers/Battery.h" +#include "interface/drivers/FirmwareUpdate.h" #include "interface/drivers/Timeout.h" namespace leka { @@ -22,8 +23,9 @@ class RobotController : public interface::RobotController public: sm_t state_machine {static_cast(*this)}; - explicit RobotController(interface::Timeout &sleep_timeout, interface::Battery &battery) - : _sleep_timeout(sleep_timeout), _battery(battery) {}; + explicit RobotController(interface::Timeout &sleep_timeout, interface::Battery &battery, + interface::FirmwareUpdate &firmware_update) + : _sleep_timeout(sleep_timeout), _battery(battery), _firmware_update(firmware_update) {}; void runLaunchingBehavior() final { @@ -69,7 +71,10 @@ class RobotController : public interface::RobotController void applyUpdate() final { - // TODO (@yann): Run FirmwareKit load update + auto firmware_version = FirmwareVersion {.major = 1, .minor = 2, .revision = 3}; + if (_firmware_update.loadUpdate(firmware_version) && _on_update_loaded_callback != nullptr) { + _on_update_loaded_callback(); + } } void raise(auto event) { state_machine.process_event(event); }; @@ -80,6 +85,11 @@ class RobotController : public interface::RobotController _ble.init(); } + void registerOnUpdateLoadedCallback(std::function const &on_update_loaded_callback) + { + _on_update_loaded_callback = on_update_loaded_callback; + } + void registerEvents() { using namespace system::robot::sm; @@ -112,6 +122,9 @@ class RobotController : public interface::RobotController BatteryKit _battery_kit {_battery}; uint8_t _minimal_battery_level_to_update {25}; + interface::FirmwareUpdate &_firmware_update; + std::function _on_update_loaded_callback {}; + BLEKit _ble {}; inline static BLEServiceDeviceInformation _service_device_information {}; inline static BLEServiceBattery _service_battery {}; diff --git a/libs/RobotKit/tests/RobotController_test.cpp b/libs/RobotKit/tests/RobotController_test.cpp index 6e2653480d..78c5e01de4 100644 --- a/libs/RobotKit/tests/RobotController_test.cpp +++ b/libs/RobotKit/tests/RobotController_test.cpp @@ -9,6 +9,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" #include "mocks/leka/Battery.h" +#include "mocks/leka/FirmwareUpdate.h" #include "mocks/leka/Timeout.h" using namespace leka; @@ -19,6 +20,7 @@ namespace event = system::robot::sm::event; using testing::_; using testing::AnyNumber; +using ::testing::MockFunction; using testing::Return; ACTION_TEMPLATE(GetCallback, HAS_1_TEMPLATE_PARAMS(typename, callback_t), AND_1_VALUE_PARAMS(pointer)) @@ -62,8 +64,9 @@ class RobotControllerTest : public testing::Test mock::Timeout sleep_timeout {}; mock::Battery battery {}; + mock::FirmwareUpdate firmware_update {}; - RobotController> rc {sleep_timeout, battery}; + RobotController> rc {sleep_timeout, battery, firmware_update}; interface::Timeout::callback_t on_sleep_timeout = {}; @@ -196,6 +199,7 @@ TEST_F(RobotControllerTest, stateChargingEventUpdateRequestedGuardIsReadyToUpdat // TODO (@yann): Trigger update_requested in StateMachine from BLE and remove isReadyToUpdate call EXPECT_CALL(battery, isCharging).WillOnce(Return(false)); + EXPECT_CALL(firmware_update, loadUpdate).Times(0); rc.isReadyToUpdate(); EXPECT_TRUE(rc.state_machine.is(lksm::state::charging)); @@ -210,22 +214,68 @@ TEST_F(RobotControllerTest, stateChargingEventUpdateRequestedGuardIsReadyToUpdat // TODO (@yann): Trigger update_requested in StateMachine from BLE and remove isReadyToUpdate call EXPECT_CALL(battery, isCharging).WillOnce(Return(true)); EXPECT_CALL(battery, level).WillOnce(Return(returned_level)); + EXPECT_CALL(firmware_update, loadUpdate).Times(0); rc.isReadyToUpdate(); EXPECT_TRUE(rc.state_machine.is(lksm::state::charging)); } -TEST_F(RobotControllerTest, stateChargingEventUpdateRequestedGuardIsReadyToUpdateTrue) +TEST_F(RobotControllerTest, stateChargingEventUpdateRequestedGuardIsReadyToUpdateTrueLoadUpdateSuccess) { rc.state_machine.set_current_states(lksm::state::charging); uint8_t returned_level {100}; + MockFunction mock_on_update_loaded_callback; + rc.registerOnUpdateLoadedCallback(mock_on_update_loaded_callback.AsStdFunction()); + + // TODO (@yann): Trigger update_requested in StateMachine from BLE and remove isReadyToUpdate and applyUpdate calls + + EXPECT_CALL(battery, isCharging).WillOnce(Return(true)); + EXPECT_CALL(battery, level).WillOnce(Return(returned_level)); + EXPECT_CALL(firmware_update, loadUpdate).WillOnce(Return(true)); + EXPECT_CALL(mock_on_update_loaded_callback, Call).Times(1); + rc.isReadyToUpdate(); + rc.applyUpdate(); + + // EXPECT_TRUE(rc.state_machine.is(lksm::state::updating)); +} + +TEST_F(RobotControllerTest, + stateChargingEventUpdateRequestedGuardIsReadyToUpdateTrueLoadUpdateSuccessOnUpdateLoadedCallbackFail) +{ + rc.state_machine.set_current_states(lksm::state::charging); + + uint8_t returned_level {100}; + + rc.registerOnUpdateLoadedCallback(nullptr); + + // TODO (@yann): Trigger update_requested in StateMachine from BLE and remove isReadyToUpdate and applyUpdate calls + + EXPECT_CALL(battery, isCharging).WillOnce(Return(true)); + EXPECT_CALL(battery, level).WillOnce(Return(returned_level)); + EXPECT_CALL(firmware_update, loadUpdate).WillOnce(Return(true)); + rc.isReadyToUpdate(); + rc.applyUpdate(); + + // EXPECT_TRUE(rc.state_machine.is(lksm::state::updating)); +} + +TEST_F(RobotControllerTest, stateChargingEventUpdateRequestedGuardIsReadyToUpdateTrueLoadUpdateFail) +{ + rc.state_machine.set_current_states(lksm::state::charging); + + uint8_t returned_level {100}; + + MockFunction mock_on_update_loaded_callback; + rc.registerOnUpdateLoadedCallback(mock_on_update_loaded_callback.AsStdFunction()); + // TODO (@yann): Trigger update_requested in StateMachine from BLE and remove isReadyToUpdate and applyUpdate calls - // TODO (@yann): EXPECT_CALL from FirmwareKit applyUpdate action EXPECT_CALL(battery, isCharging).WillOnce(Return(true)); EXPECT_CALL(battery, level).WillOnce(Return(returned_level)); + EXPECT_CALL(firmware_update, loadUpdate).WillOnce(Return(false)); + EXPECT_CALL(mock_on_update_loaded_callback, Call).Times(0); rc.isReadyToUpdate(); rc.applyUpdate();