~aleteoryx/muditaos

6e76dc3e5f1381725ee1de3c11c35d74fd9242d2 — Mateusz Szczesny 2 years ago a8fa8bf
[BH-1787] Reboot to MSC endpoint

To allow the automation of gathering logs and swapping out OS images during tests a MSC reboot
endpoint was added. Together with a change to ecoboot, this allows the sending of a "reboot to
MSC" command. The deivce will then reboot and enter MSC mode.
25 files changed, 322 insertions(+), 139 deletions(-)

M module-bsp/board/rt1051/bsp/lpm/RT1051LPMCommon.cpp
M module-bsp/bsp/lpm/bsp_lpm.hpp
M module-services/service-desktop/endpoints/CMakeLists.txt
M module-services/service-desktop/endpoints/developerMode/DeveloperModeHelper.cpp
M module-services/service-desktop/endpoints/deviceInfo/DeviceInfoEndpointCommon.cpp
M module-services/service-desktop/endpoints/factoryReset/FactoryResetEndpoint.cpp
M module-services/service-desktop/endpoints/filesystem/FS_Helper.cpp
M module-services/service-desktop/endpoints/include/endpoints/Context.hpp
M module-services/service-desktop/endpoints/include/endpoints/EndpointType.hpp
M module-services/service-desktop/endpoints/include/endpoints/JsonKeyNames.hpp
A module-services/service-desktop/endpoints/include/endpoints/reboot/RebootEndpoint.hpp
A module-services/service-desktop/endpoints/include/endpoints/reboot/RebootHelper.hpp
A module-services/service-desktop/endpoints/reboot/RebootEndpoint.cpp
A module-services/service-desktop/endpoints/reboot/RebootHelper.cpp
M module-services/service-desktop/endpoints/security/SecurityEndpointHelper.cpp
M module-services/service-desktop/endpoints/update/UpdateHelper.cpp
M module-services/service-desktop/include/service-desktop/Sync.hpp
M module-sys/SystemManager/PowerManager.cpp
M module-sys/SystemManager/SystemManagerCommon.cpp
M module-sys/SystemManager/include/SystemManager/PowerManager.hpp
M module-sys/SystemManager/include/SystemManager/SystemManagerCommon.hpp
M module-sys/common/include/system/Common.hpp
M products/BellHybrid/services/desktop/endpoints/EndpointFactoryBell.cpp
M products/BellHybrid/services/desktop/endpoints/deviceInfo/DeviceInfoEndpoint.cpp
M products/PurePhone/services/desktop/endpoints/deviceInfo/DeviceInfoEndpoint.cpp
M module-bsp/board/rt1051/bsp/lpm/RT1051LPMCommon.cpp => module-bsp/board/rt1051/bsp/lpm/RT1051LPMCommon.cpp +3 -0
@@ 47,6 47,9 @@ namespace bsp
        case RebootType::NormalRestart:
            set_boot_reason(boot_reason_code_os);
            break;
        case RebootType::GoToMSC:
            set_boot_reason(boot_reason_code_usb_mc_mode);
            break;
        default:
            set_boot_reason(boot_reason_code_unknown);
        }

M module-bsp/bsp/lpm/bsp_lpm.hpp => module-bsp/bsp/lpm/bsp_lpm.hpp +2 -1
@@ 30,7 30,8 @@ namespace bsp
            GoToRecoveryFactoryReset, //! GOto recovery into the factory reset mode
            GoToRecoveryRecovery,     //! Goto to recovery into recovery mode
            GoToRecoveryBackup,       //! Goto to recovery into backup mode
            GoToRecoveryRestore       //! Goto to recovery into restore mode
            GoToRecoveryRestore,      //! Goto to recovery into restore mode
            GoToMSC                   //! Goto msc mode 
        };

        LowPowerMode()          = default;

M module-services/service-desktop/endpoints/CMakeLists.txt => module-services/service-desktop/endpoints/CMakeLists.txt +4 -0
@@ 63,6 63,8 @@ target_sources(
        security/SecurityEndpointHelper.cpp
        update/UpdateEndpoint.cpp
        update/UpdateHelper.cpp
        reboot/RebootEndpoint.cpp
        reboot/RebootHelper.cpp
    PUBLIC
        include/endpoints/backup/BackupEndpoint.hpp
        include/endpoints/backup/BackupHelper.hpp


@@ 88,6 90,8 @@ target_sources(
        include/endpoints/security/SecurityEndpointHelper.hpp
        include/endpoints/update/UpdateEndpoint.hpp
        include/endpoints/update/UpdateHelper.hpp
        include/endpoints/reboot/RebootEndpoint.hpp
        include/endpoints/reboot/RebootHelper.hpp
)

target_include_directories(

M module-services/service-desktop/endpoints/developerMode/DeveloperModeHelper.cpp => module-services/service-desktop/endpoints/developerMode/DeveloperModeHelper.cpp +3 -3
@@ 188,9 188,9 @@ namespace sdesktop::endpoints
            if (keyValue == json::developerMode::simStateInfo) {
                auto response = ResponseContext{
                    .body = json11::Json::object(
                        {{json::selectedSim, std::to_string(static_cast<int>(Store::GSM::get()->selected))},
                         {json::sim, std::to_string(static_cast<int>(Store::GSM::get()->sim))},
                         {json::trayState, std::to_string(static_cast<int>(Store::GSM::get()->tray))}})};
                        {{json::deviceInfo::selectedSim, std::to_string(static_cast<int>(Store::GSM::get()->selected))},
                         {json::deviceInfo::sim, std::to_string(static_cast<int>(Store::GSM::get()->sim))},
                         {json::deviceInfo::trayState, std::to_string(static_cast<int>(Store::GSM::get()->tray))}})};
                response.status = http::Code::OK;
                return {sent::no, std::move(response)};
            }

M module-services/service-desktop/endpoints/deviceInfo/DeviceInfoEndpointCommon.cpp => module-services/service-desktop/endpoints/deviceInfo/DeviceInfoEndpointCommon.cpp +3 -3
@@ 26,9 26,9 @@ namespace sdesktop::endpoints
    auto DeviceInfoEndpointCommon::handleGet(Context &context) -> http::Code
    {
        const auto &requestBody = context.getBody();
        if (not requestBody.object_items().empty() and requestBody[json::fileList].is_number()) {
        if (not requestBody.object_items().empty() and requestBody[json::deviceInfo::fileList].is_number()) {

            const auto diagFileType = parseDiagnosticFileType(requestBody[json::fileList]);
            const auto diagFileType = parseDiagnosticFileType(requestBody[json::deviceInfo::fileList]);

            if (!magic_enum::enum_contains<DiagnosticFileType>(diagFileType)) {
                LOG_ERROR("Bad diagnostic type '%s' requested", magic_enum::enum_name(diagFileType).data());


@@ 100,7 100,7 @@ namespace sdesktop::endpoints
            fileArray.push_back(file);
        }

        return json11::Json::object{{json::files, fileArray}};
        return json11::Json::object{{json::deviceInfo::files, fileArray}};
    }

    auto DeviceInfoEndpointCommon::listDirectory(const std::string &path) -> std::vector<std::string>

M module-services/service-desktop/endpoints/factoryReset/FactoryResetEndpoint.cpp => module-services/service-desktop/endpoints/factoryReset/FactoryResetEndpoint.cpp +5 -5
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <endpoints/factoryReset/FactoryResetEndpoint.hpp>


@@ 19,14 19,14 @@ namespace sdesktop::endpoints
    {
        if (context.getMethod() == http::Method::post) {

            if (context.getBody()[json::factoryRequest] == true) {
            if (context.getBody()[json::factoryReset::factoryRequest] == true) {
                auto msg = std::make_shared<sdesktop::FactoryMessage>();
                ownerServicePtr->bus.sendUnicast(msg, service::name::service_desktop);

                context.setResponseBody(json11::Json::object({{json::factoryRequest, true}}));
                context.setResponseBody(json11::Json::object({{json::factoryReset::factoryRequest, true}}));
            }
            else {
                context.setResponseBody(json11::Json::object({{json::factoryRequest, false}}));
                context.setResponseBody(json11::Json::object({{json::factoryReset::factoryRequest, false}}));
            }

            sender::putToSendQueue(context.createSimpleResponse());


@@ 34,7 34,7 @@ namespace sdesktop::endpoints
            return;
        }
        else {
            context.setResponseBody(json11::Json::object({{json::factoryRequest, false}}));
            context.setResponseBody(json11::Json::object({{json::factoryReset::factoryRequest, false}}));

            sender::putToSendQueue(context.createSimpleResponse());


M module-services/service-desktop/endpoints/filesystem/FS_Helper.cpp => module-services/service-desktop/endpoints/filesystem/FS_Helper.cpp +10 -10
@@ 138,14 138,14 @@ namespace sdesktop::endpoints
        catch (const std::runtime_error &e) {
            LOG_ERROR("Logs flush exception: %s", e.what());

            json11::Json::object response({{json::reason, e.what()}});
            json11::Json::object response({{json::common::reason, e.what()}});
            return ResponseContext{.status = http::Code::InternalServerError, .body = response};
        }

        if (!std::filesystem::exists(filePath)) {
            LOG_ERROR("File %s not found", filePath.c_str());

            json11::Json::object response({{json::reason, json::fs::fileDoesNotExist}});
            json11::Json::object response({{json::common::reason, json::fs::fileDoesNotExist}});
            return ResponseContext{.status = http::Code::NotFound, .body = response};
        }



@@ 166,13 166,13 @@ namespace sdesktop::endpoints
            LOG_ERROR("FileOperations exception: %s", e.what());

            code     = http::Code::InternalServerError;
            response = json11::Json::object({{json::reason, std::string(e.what())}});
            response = json11::Json::object({{json::common::reason, std::string(e.what())}});
        }
        catch (std::exception &e) {
            LOG_ERROR("FileOperations exception: %s", e.what());

            code     = http::Code::BadRequest;
            response = json11::Json::object({{json::reason, std::string(e.what())}});
            response = json11::Json::object({{json::common::reason, std::string(e.what())}});
        }

        return ResponseContext{.status = code, .body = response};


@@ 190,7 190,7 @@ namespace sdesktop::endpoints
        catch (std::exception &e) {
            LOG_ERROR("Exception during getting data: %s", e.what());

            json11::Json::object response({{json::reason, e.what()}});
            json11::Json::object response({{json::common::reason, e.what()}});
            return ResponseContext{.status = http::Code::BadRequest, .body = response};
        }



@@ 213,7 213,7 @@ namespace sdesktop::endpoints
            LOG_ERROR("%s", errorReason.str().c_str());

            code     = http::Code::BadRequest;
            response = json11::Json::object({{json::reason, errorReason.str()}});
            response = json11::Json::object({{json::common::reason, errorReason.str()}});
        }

        return ResponseContext{.status = code, .body = response};


@@ 263,13 263,13 @@ namespace sdesktop::endpoints
            LOG_ERROR("FileOperations exception: %s", e.what());

            code     = http::Code::InternalServerError;
            response = json11::Json::object({{json::reason, std::string(e.what())}});
            response = json11::Json::object({{json::common::reason, std::string(e.what())}});
        }
        catch (std::exception &e) {
            LOG_ERROR("FileOperations exception: %s", e.what());

            code     = http::Code::BadRequest;
            response = json11::Json::object({{json::reason, std::string(e.what())}});
            response = json11::Json::object({{json::common::reason, std::string(e.what())}});
        }

        return ResponseContext{.status = code, .body = response};


@@ 288,7 288,7 @@ namespace sdesktop::endpoints
            LOG_ERROR("%s", errorReason.str().c_str());

            auto code     = http::Code::BadRequest;
            auto response = json11::Json::object({{json::reason, errorReason.str()}});
            auto response = json11::Json::object({{json::common::reason, errorReason.str()}});

            return ResponseContext{.status = code, .body = response};
        }


@@ 301,7 301,7 @@ namespace sdesktop::endpoints
        catch (std::exception &e) {
            LOG_ERROR("Exception during sending data: %s", e.what());
            auto code     = http::Code::NotAcceptable;
            auto response = json11::Json::object({{json::reason, e.what()}});
            auto response = json11::Json::object({{json::common::reason, e.what()}});

            return ResponseContext{.status = code, .body = response};
        }

M module-services/service-desktop/endpoints/include/endpoints/Context.hpp => module-services/service-desktop/endpoints/include/endpoints/Context.hpp +1 -1
@@ 47,7 47,7 @@ namespace sdesktop::endpoints
            if (!body.is_object()) {
                body = json11::Json();
            }
            if (static_cast<int>(endpoint) > lastEndpoint) {
            if (static_cast<unsigned>(endpoint) > lastEndpoint) {
                endpoint = EndpointType::invalid;
            }
            if (method > http::Method::del) {

M module-services/service-desktop/endpoints/include/endpoints/EndpointType.hpp => module-services/service-desktop/endpoints/include/endpoints/EndpointType.hpp +6 -3
@@ 1,8 1,10 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <magic_enum.hpp>

namespace sdesktop::endpoints
{



@@ 22,9 24,10 @@ namespace sdesktop::endpoints
        developerMode,
        bluetooth,
        usbSecurity,
        outbox
        outbox,
        reboot
    };

    inline constexpr auto lastEndpoint = static_cast<int>(EndpointType::outbox);
    inline constexpr auto lastEndpoint = magic_enum::enum_count<EndpointType>() - 1;

} // namespace sdesktop::endpoints

M module-services/service-desktop/endpoints/include/endpoints/JsonKeyNames.hpp => module-services/service-desktop/endpoints/include/endpoints/JsonKeyNames.hpp +56 -59
@@ 5,68 5,57 @@

namespace sdesktop::endpoints::json
{
    inline constexpr auto batteryLevel        = "batteryLevel";
    inline constexpr auto batteryState        = "batteryState";
    inline constexpr auto selectedSim         = "selectedSim";
    inline constexpr auto sim                 = "sim";
    inline constexpr auto trayState           = "trayState";
    inline constexpr auto signalStrength      = "signalStrength";
    inline constexpr auto deviceSpaceTotal    = "deviceSpaceTotal";
    inline constexpr auto systemReservedSpace = "systemReservedSpace";
    inline constexpr auto usedUserSpace       = "usedUserSpace";
    inline constexpr auto gitRevision         = "gitRevision";
    inline constexpr auto gitBranch           = "gitBranch";
    inline constexpr auto gitTag              = "gitTag";
    inline constexpr auto currentRTCTime      = "currentRTCTime";
    inline constexpr auto updateReady         = "updateReady";
    inline constexpr auto updateFileList      = "updateFileList";
    inline constexpr auto factoryRequest      = "factoryRequest";
    inline constexpr auto networkStatus       = "networkStatus";
    inline constexpr auto networkOperatorName = "networkOperatorName";
    inline constexpr auto accessTechnology    = "accessTechnology";
    namespace common
    {
        inline constexpr auto reason = "reason";
    } // namespace common

    namespace deviceInfo
    {
        inline constexpr auto batteryLevel           = "batteryLevel";
        inline constexpr auto batteryState           = "batteryState";
        inline constexpr auto selectedSim            = "selectedSim";
        inline constexpr auto sim                    = "sim";
        inline constexpr auto trayState              = "trayState";
        inline constexpr auto signalStrength         = "signalStrength";
        inline constexpr auto deviceSpaceTotal       = "deviceSpaceTotal";
        inline constexpr auto systemReservedSpace    = "systemReservedSpace";
        inline constexpr auto usedUserSpace          = "usedUserSpace";
        inline constexpr auto gitRevision            = "gitRevision";
        inline constexpr auto gitBranch              = "gitBranch";
        inline constexpr auto currentRTCTime         = "currentRTCTime";
        inline constexpr auto networkStatus          = "networkStatus";
        inline constexpr auto networkOperatorName    = "networkOperatorName";
        inline constexpr auto accessTechnology       = "accessTechnology";
        inline constexpr auto version                = "version";
        inline constexpr auto serialNumber           = "serialNumber";
        inline constexpr auto caseColour             = "caseColour";
        inline constexpr auto fileList               = "fileList";
        inline constexpr auto files                  = "files";
        inline constexpr auto recoveryStatusFilePath = "recoveryStatusFilePath";
        inline constexpr auto updateFilePath         = "updateFilePath";
        inline constexpr auto backupFilePath         = "backupFilePath";
        inline constexpr auto syncFilePath           = "syncFilePath";
        inline constexpr auto mtpPath                = "mtpPath";
        inline constexpr auto deviceToken            = "deviceToken";
        inline constexpr auto onboardingState        = "onboardingState";
    } // namespace deviceInfo

    namespace factoryReset
    {
        inline constexpr auto factoryRequest = "factoryRequest";
    } // namespace factoryReset

    inline constexpr auto update                 = "update";
    inline constexpr auto updateInfo             = "updateInfo";
    inline constexpr auto updateError            = "updateError";
    inline constexpr auto errorCode              = "errorCode";
    inline constexpr auto statusCode             = "statusCode";
    inline constexpr auto updateHistory          = "updateHistory";
    inline constexpr auto usbMscMode             = "usbMscMode";
    inline constexpr auto versionString          = "string";
    inline constexpr auto fileExists             = "fileExists";
    inline constexpr auto boot                   = "boot";
    inline constexpr auto version                = "version";
    inline constexpr auto taskId                 = "id";
    inline constexpr auto state                  = "state";
    inline constexpr auto success                = "success";
    inline constexpr auto reboot                 = "reboot";
    inline constexpr auto request                = "request";
    inline constexpr auto restore                = "restore";
    inline constexpr auto finished               = "finished";
    inline constexpr auto pending                = "pending";
    inline constexpr auto location               = "location";
    inline constexpr auto reason                 = "reason";
    inline constexpr auto serialNumber           = "serialNumber";
    inline constexpr auto caseColour             = "caseColour";
    inline constexpr auto fileList               = "fileList";
    inline constexpr auto files                  = "files";
    inline constexpr auto recoveryStatusFilePath = "recoveryStatusFilePath";
    inline constexpr auto updateFilePath         = "updateFilePath";
    inline constexpr auto backupFilePath         = "backupFilePath";
    inline constexpr auto syncFilePath           = "syncFilePath";
    inline constexpr auto mtpPath                = "mtpPath";
    inline constexpr auto deviceToken            = "deviceToken";
    inline constexpr auto onboardingState        = "onboardingState";
    namespace update
    {
        inline constexpr auto update = "update";
        inline constexpr auto reboot = "reboot";
    } // namespace update

    namespace updateprocess
    namespace sync
    {
        inline constexpr auto command       = "command";
        inline constexpr auto updateAborted = "updateAborted";
        namespace commands
        {
            inline constexpr auto abort = "abort";
        } // namespace commands
    }     // namespace updateprocess
        inline constexpr auto state = "state";
    } // namespace sync

    namespace messages
    {


@@ 125,4 114,12 @@ namespace sdesktop::endpoints::json
        inline constexpr auto timeLeftToNextAttempt = "timeLeftToNextAttempt";
    } // namespace usb

    namespace reboot
    {
        inline constexpr auto rebootType = "rebootType";
        inline constexpr auto msc        = "msc";
        inline constexpr auto reboot     = "reboot";
        inline constexpr auto shutdown   = "shutdown";
    } // namespace reboot

} // namespace sdesktop::endpoints::json

A module-services/service-desktop/endpoints/include/endpoints/reboot/RebootEndpoint.hpp => module-services/service-desktop/endpoints/include/endpoints/reboot/RebootEndpoint.hpp +26 -0
@@ 0,0 1,26 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <endpoints/Endpoint.hpp>
#include "RebootHelper.hpp"

namespace sdesktop::endpoints
{
    class RebootEndpoint : public Endpoint
    {
      public:
        explicit RebootEndpoint(sys::Service *ownerServicePtr)
            : Endpoint(ownerServicePtr), helper(std::make_unique<RebootHelper>(ownerServicePtr))
        {
            debugName = "RebootEndpoint";
        }

        auto handle(Context &context) -> void override;

      private:
        const std::unique_ptr<RebootHelper> helper;
    };

} // namespace sdesktop::endpoints

A module-services/service-desktop/endpoints/include/endpoints/reboot/RebootHelper.hpp => module-services/service-desktop/endpoints/include/endpoints/reboot/RebootHelper.hpp +20 -0
@@ 0,0 1,20 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <endpoints/BaseHelper.hpp>

namespace sdesktop::endpoints
{
    class RebootHelper : public BaseHelper
    {
      public:
        explicit RebootHelper(sys::Service *p) : BaseHelper(p)
        {}

        auto processPost(Context &context) -> ProcessResult final;

      private:
    };
} // namespace sdesktop::endpoints

A module-services/service-desktop/endpoints/reboot/RebootEndpoint.cpp => module-services/service-desktop/endpoints/reboot/RebootEndpoint.cpp +34 -0
@@ 0,0 1,34 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <endpoints/reboot/RebootEndpoint.hpp>
#include <endpoints/HttpEnums.hpp>
#include <log/log.hpp>
#include <endpoints/message/Sender.hpp>

namespace sdesktop::endpoints
{
    auto RebootEndpoint::handle(Context &context) -> void
    {
        const auto &[sent, response] = helper->process(context.getMethod(), context);

        if (sent == sent::delayed) {
            LOG_DEBUG("There is no proper delayed serving mechanism - depend on invisible context caching");
        }
        if (sent == sent::no) {
            if (not response.has_value()) {
                LOG_ERROR("Response not sent & response not created : respond with error");
                context.setResponseStatus(http::Code::NotAcceptable);
            }
            else {
                context.setResponse(response.value());
            }

            sender::putToSendQueue(context.createSimpleResponse());
        }
        if (sent == sent::yes and response.has_value()) {
            LOG_ERROR("Response set when we already handled response in handler");
        }
    }

} // namespace sdesktop::endpoints

A module-services/service-desktop/endpoints/reboot/RebootHelper.cpp => module-services/service-desktop/endpoints/reboot/RebootHelper.cpp +36 -0
@@ 0,0 1,36 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <endpoints/Context.hpp>
#include <endpoints/reboot/RebootHelper.hpp>
#include <endpoints/JsonKeyNames.hpp>
#include <endpoints/message/Sender.hpp>
#include <service-desktop/DesktopMessages.hpp>
#include <service-desktop/ServiceDesktop.hpp>

#include <json11.hpp>

namespace sdesktop::endpoints
{
    using sender::putToSendQueue;
    auto RebootHelper::processPost(Context &context) -> ProcessResult
    {
        const auto rebootType = context.getBody()[json::reboot::rebootType].string_value();

        if (rebootType == json::reboot::msc) {
            sys::SystemManagerCommon::RebootMSC(owner);
            return {sent::no, ResponseContext{.status = http::Code::Accepted}};
        }
        else if (rebootType == json::reboot::reboot) {
            sys::SystemManagerCommon::Reboot(owner);
            return {sent::no, ResponseContext{.status = http::Code::Accepted}};
        }
        else if (rebootType == json::reboot::shutdown) {
            sys::SystemManagerCommon::RegularPowerDown(owner);
            return {sent::no, ResponseContext{.status = http::Code::Accepted}};
        }
        LOG_ERROR("Invalid request: %s", rebootType.c_str());
        return {sent::no, ResponseContext{.status = http::Code::BadRequest}};
    }

} // namespace sdesktop::endpoints

M module-services/service-desktop/endpoints/security/SecurityEndpointHelper.cpp => module-services/service-desktop/endpoints/security/SecurityEndpointHelper.cpp +1 -1
@@ 68,7 68,7 @@ namespace sdesktop::endpoints
            case BlockReason::BatteryCriticalLevel:
                responseContext.status = http::Code::Locked;
                responseContext.body =
                    json11::Json::object({{json::reason, std::to_string(static_cast<int>(security.reason))}});
                    json11::Json::object({{json::common::reason, std::to_string(static_cast<int>(security.reason))}});
                break;
            }
        }

M module-services/service-desktop/endpoints/update/UpdateHelper.cpp => module-services/service-desktop/endpoints/update/UpdateHelper.cpp +1 -1
@@ 174,7 174,7 @@ namespace sdesktop::endpoints
    {
        const auto &body = context.getBody();

        if (body[json::update] != true || body[json::reboot] != true) {
        if (body[json::update::update] != true || body[json::update::reboot] != true) {
            return {sent::no, ResponseContext{.status = http::Code::BadRequest}};
        }


M module-services/service-desktop/include/service-desktop/Sync.hpp => module-services/service-desktop/include/service-desktop/Sync.hpp +3 -3
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 71,10 71,10 @@ class Sync
        OperationState state = OperationState::Stopped;
        json11::Json to_json() const
        {
            auto response = json11::Json::object{{sdesktop::endpoints::json::state, opToString(state)}};
            auto response = json11::Json::object{{sdesktop::endpoints::json::sync::state, opToString(state)}};

            if (state == OperationState::Error) {
                response[sdesktop::endpoints::json::reason] = completionCodeToString(completionCode);
                response[sdesktop::endpoints::json::common::reason] = completionCodeToString(completionCode);
            }

            return response;

M module-sys/SystemManager/PowerManager.cpp => module-sys/SystemManager/PowerManager.cpp +9 -4
@@ 80,17 80,22 @@ namespace sys
    PowerManager::~PowerManager()
    {}

    int32_t PowerManager::PowerOff()
    std::int32_t PowerManager::PowerOff()
    {
        return lowPowerControl->PowerOff();
    }

    int32_t PowerManager::Reboot()
    std::int32_t PowerManager::Reboot()
    {
        return lowPowerControl->Reboot(bsp::LowPowerMode::RebootType::NormalRestart);
    }

    int32_t PowerManager::RebootToRecovery(RecoveryReason reason)
    std::int32_t PowerManager::RebootMSC()
    {
        return lowPowerControl->Reboot(bsp::LowPowerMode::RebootType::GoToMSC);
    }

    std::int32_t PowerManager::RebootToRecovery(RecoveryReason reason)
    {
        switch (reason) {
        case RecoveryReason::FactoryReset:


@@ 110,7 115,7 @@ namespace sys

    [[nodiscard]] cpu::UpdateResult PowerManager::UpdateCpuFrequency()
    {
        uint32_t cpuLoad = cpuStatistics.GetPercentageCpuLoad();
        std::uint32_t cpuLoad = cpuStatistics.GetPercentageCpuLoad();
        cpu::UpdateResult retval;
        const cpu::AlgorithmData data{
            cpuLoad, lowPowerControl->GetCurrentFrequencyLevel(), GetMinimumCpuFrequencyRequested()};

M module-sys/SystemManager/SystemManagerCommon.cpp => module-sys/SystemManager/SystemManagerCommon.cpp +32 -0
@@ 115,6 115,9 @@ namespace sys
        case SystemManagerCommon::State::Reboot:
            LOG_INFO("  --->  REBOOT <--- ");
            break;
        case SystemManagerCommon::State::RebootMSC:
            LOG_INFO("  --->  REBOOT MSC <--- ");
            break;
        case SystemManagerCommon::State::ShutdownReady:
            LOG_INFO("  ---> SHUTDOWN <--- ");
            break;


@@ 135,6 138,9 @@ namespace sys
        case State::Reboot:
            powerManager->Reboot();
            break;
        case State::RebootMSC:
            powerManager->RebootMSC();
            break;
        case State::ShutdownReady:
            powerManager->PowerOff();
            break;


@@ 264,6 270,13 @@ namespace sys
                                  service::name::system_manager);
    }

    bool SystemManagerCommon::RegularPowerDown(Service *s)
    {
        s->bus.sendUnicast(std::make_shared<SystemManagerCmd>(Code::CloseSystem, CloseReason::RegularPowerDown),
                           service::name::system_manager);
        return true;
    }

    bool SystemManagerCommon::Reboot(Service *s)
    {
        s->bus.sendUnicast(std::make_shared<SystemManagerCmd>(Code::Reboot, CloseReason::Reboot),


@@ 271,6 284,13 @@ namespace sys
        return true;
    }

    bool SystemManagerCommon::RebootMSC(Service *s)
    {
        s->bus.sendUnicast(std::make_shared<SystemManagerCmd>(Code::RebootMSC, CloseReason::RebootMSC),
                           service::name::system_manager);
        return true;
    }

    bool SystemManagerCommon::RebootToRecovery(Service *s, RecoveryReason recoveryReason)
    {
        s->bus.sendUnicast(


@@ 546,6 566,9 @@ namespace sys
                case Code::Reboot:
                    RebootHandler();
                    break;
                case Code::RebootMSC:
                    RebootHandlerMSC();
                    break;
                case Code::RebootToRecovery:
                case Code::FactoryReset:
                    RebootToRecoveryHandler(data->closeReason, data->recoveryReason);


@@ 711,6 734,10 @@ namespace sys
            DestroyServices(getWhiteListFor(WhiteListType::RegularClose));
            set(State::Reboot);
            break;
        case CloseReason::RebootMSC:
            DestroyServices(getWhiteListFor(WhiteListType::RegularClose));
            set(State::RebootMSC);
            break;
        case CloseReason::RebootToRecovery:
        case CloseReason::FactoryReset:
            DestroyServices(getWhiteListFor(WhiteListType::Update));


@@ 740,6 767,11 @@ namespace sys
        CloseSystemHandler(CloseReason::Reboot);
    }

    void SystemManagerCommon::RebootHandlerMSC()
    {
        CloseSystemHandler(CloseReason::RebootMSC);
    }

    void SystemManagerCommon::RebootToRecoveryHandler(CloseReason closeReason, RecoveryReason recoveryReason)
    {
        CloseSystemHandler(closeReason);

M module-sys/SystemManager/include/SystemManager/PowerManager.hpp => module-sys/SystemManager/include/SystemManager/PowerManager.hpp +4 -3
@@ 48,9 48,10 @@ namespace sys
        explicit PowerManager(CpuStatistics &cpuStats, TaskStatistics &taskStats);
        ~PowerManager();

        int32_t PowerOff();
        int32_t Reboot();
        int32_t RebootToRecovery(RecoveryReason reason);
        std::int32_t PowerOff();
        std::int32_t Reboot();
        std::int32_t RebootMSC();
        std::int32_t RebootToRecovery(RecoveryReason reason);

        /// called periodically to calculate the CPU requirement
        ///

M module-sys/SystemManager/include/SystemManager/SystemManagerCommon.hpp => module-sys/SystemManager/include/SystemManager/SystemManagerCommon.hpp +11 -1
@@ 34,6 34,7 @@ namespace sys
        CloseSystem,
        Restore,
        Reboot,
        RebootMSC,
        RebootToRecovery,
        FactoryReset,
        None,


@@ 78,7 79,8 @@ namespace sys
            Shutdown,
            ShutdownReady,
            Reboot,
            RebootToRecovery
            RebootToRecovery,
            RebootMSC
        } state = State::Running;

        explicit SystemManagerCommon(std::vector<std::unique_ptr<BaseServiceCreator>> &&creators);


@@ 96,6 98,10 @@ namespace sys

        static bool Reboot(Service *s);

        static bool RebootMSC(Service *s);

        static bool RegularPowerDown(Service *s);

        static bool RebootToRecovery(Service *s, RecoveryReason recoveryReason);

        static bool SuspendService(const std::string &name, Service *caller);


@@ 179,6 185,8 @@ namespace sys

        void RebootHandler();

        void RebootHandlerMSC();

        void RebootToRecoveryHandler(CloseReason closeReason, RecoveryReason recoveryReason);

        void FreqUpdateTick();


@@ 225,6 233,8 @@ inline const char *c_str(sys::SystemManagerCommon::State state)
        return "Shutdown";
    case sys::SystemManagerCommon::State::Reboot:
        return "Reboot";
    case sys::SystemManagerCommon::State::RebootMSC:
        return "RebootMSC";
    case sys::SystemManagerCommon::State::RebootToRecovery:
        return "RebootToRecovery";
    case sys::SystemManagerCommon::State::ShutdownReady:

M module-sys/common/include/system/Common.hpp => module-sys/common/include/system/Common.hpp +1 -0
@@ 51,6 51,7 @@ namespace sys
        RegularPowerDown,
        OnboardingPowerDown,
        Reboot,
        RebootMSC,
        RebootToRecovery,
        FactoryReset,
        SystemBrownout,

M products/BellHybrid/services/desktop/endpoints/EndpointFactoryBell.cpp => products/BellHybrid/services/desktop/endpoints/EndpointFactoryBell.cpp +3 -0
@@ 10,6 10,7 @@
#include <endpoints/nullEndpoint/NullEndpoint.hpp>
#include <endpoints/restore/RestoreEndpoint.hpp>
#include <endpoints/update/UpdateEndpoint.hpp>
#include <endpoints/reboot/RebootEndpoint.hpp>
#include <log/log.hpp>

namespace sdesktop::endpoints


@@ 33,6 34,8 @@ namespace sdesktop::endpoints
            return std::make_unique<RestoreEndpoint>(ownerServicePtr);
        case EndpointType::factory:
            return std::make_unique<FactoryResetEndpoint>(ownerServicePtr);
        case EndpointType::reboot:
            return std::make_unique<RebootEndpoint>(ownerServicePtr);
        default:
            return std::make_unique<NullEndpoint>(ownerServicePtr);
        }

M products/BellHybrid/services/desktop/endpoints/deviceInfo/DeviceInfoEndpoint.cpp => products/BellHybrid/services/desktop/endpoints/deviceInfo/DeviceInfoEndpoint.cpp +20 -17
@@ 37,24 37,27 @@ namespace sdesktop::endpoints
        const auto [totalDeviceSpaceMiB, reservedSystemSpaceMiB, usedUserSpaceMiB] = getStorageInfo();

        context.setResponseBody(json11::Json::object(
            {{json::batteryLevel, std::to_string(Store::Battery::get().level)},
             {json::batteryState, std::to_string(static_cast<int>(Store::Battery::get().state))},
             {json::deviceSpaceTotal, std::to_string(totalDeviceSpaceMiB)},
             {json::systemReservedSpace, std::to_string(reservedSystemSpaceMiB)},
             {json::usedUserSpace, std::to_string(usedUserSpaceMiB)},
             {json::gitRevision, std::string(GIT_REV)},
             {json::gitBranch, std::string(GIT_BRANCH)},
             {json::currentRTCTime, std::to_string(static_cast<std::uint32_t>(std::time(nullptr)))},
             {json::version, std::string(VERSION)},
             {json::serialNumber, getSerialNumber()},
             {json::caseColour, getCaseColour()},
             {json::recoveryStatusFilePath,
            {{json::deviceInfo::batteryLevel, std::to_string(Store::Battery::get().level)},
             {json::deviceInfo::batteryState, std::to_string(static_cast<int>(Store::Battery::get().state))},
             {json::deviceInfo::deviceSpaceTotal, std::to_string(totalDeviceSpaceMiB)},
             {json::deviceInfo::systemReservedSpace, std::to_string(reservedSystemSpaceMiB)},
             {json::deviceInfo::usedUserSpace, std::to_string(usedUserSpaceMiB)},
             {json::deviceInfo::gitRevision, std::string(GIT_REV)},
             {json::deviceInfo::gitBranch, std::string(GIT_BRANCH)},
             {json::deviceInfo::currentRTCTime, std::to_string(static_cast<std::uint32_t>(std::time(nullptr)))},
             {json::deviceInfo::version, std::string(VERSION)},
             {json::deviceInfo::serialNumber, getSerialNumber()},
             {json::deviceInfo::caseColour, getCaseColour()},
             {json::deviceInfo::recoveryStatusFilePath,
              (purefs::dir::getTemporaryPath() / sdesktop::paths::recoveryStatusFilename).string()},
             {json::updateFilePath, (purefs::dir::getTemporaryPath() / sdesktop::paths::updateFilename).string()},
             {json::backupFilePath, (purefs::dir::getTemporaryPath() / sdesktop::paths::backupFilename).string()},
             {json::syncFilePath, (purefs::dir::getTemporaryPath() / sdesktop::paths::syncFilename).string()},
             {json::mtpPath, getMtpPath().string()},
             {json::onboardingState, std::to_string(static_cast<int>(getOnboardingState()))}}));
             {json::deviceInfo::updateFilePath,
              (purefs::dir::getTemporaryPath() / sdesktop::paths::updateFilename).string()},
             {json::deviceInfo::backupFilePath,
              (purefs::dir::getTemporaryPath() / sdesktop::paths::backupFilename).string()},
             {json::deviceInfo::syncFilePath,
              (purefs::dir::getTemporaryPath() / sdesktop::paths::syncFilename).string()},
             {json::deviceInfo::mtpPath, getMtpPath().string()},
             {json::deviceInfo::onboardingState, std::to_string(static_cast<int>(getOnboardingState()))}}));

        return http::Code::OK;
    }

M products/PurePhone/services/desktop/endpoints/deviceInfo/DeviceInfoEndpoint.cpp => products/PurePhone/services/desktop/endpoints/deviceInfo/DeviceInfoEndpoint.cpp +28 -24
@@ 50,32 50,36 @@ namespace sdesktop::endpoints
        }();

        context.setResponseBody(json11::Json::object(
            {{json::batteryLevel, std::to_string(Store::Battery::get().level)},
             {json::batteryState, std::to_string(static_cast<int>(Store::Battery::get().state))},
             {json::selectedSim, std::to_string(static_cast<int>(Store::GSM::get()->selected))},
             {json::trayState, std::to_string(static_cast<int>(Store::GSM::get()->tray))},
             {json::signalStrength, std::to_string(signalStrength)},
             {json::accessTechnology,
            {{json::deviceInfo::batteryLevel, std::to_string(Store::Battery::get().level)},
             {json::deviceInfo::batteryState, std::to_string(static_cast<int>(Store::Battery::get().state))},
             {json::deviceInfo::selectedSim, std::to_string(static_cast<int>(Store::GSM::get()->selected))},
             {json::deviceInfo::trayState, std::to_string(static_cast<int>(Store::GSM::get()->tray))},
             {json::deviceInfo::signalStrength, std::to_string(signalStrength)},
             {json::deviceInfo::accessTechnology,
              std::to_string(static_cast<int>(Store::GSM::get()->getNetwork().accessTechnology))},
             {json::networkStatus, std::to_string(static_cast<int>(Store::GSM::get()->getNetwork().status))},
             {json::networkOperatorName, Store::GSM::get()->getNetworkOperatorName()},
             {json::deviceSpaceTotal, std::to_string(totalDeviceSpaceMiB)},
             {json::systemReservedSpace, std::to_string(reservedSystemSpaceMiB)},
             {json::usedUserSpace, std::to_string(usedUserSpaceMiB)},
             {json::gitRevision, std::string(GIT_REV)},
             {json::gitBranch, std::string(GIT_BRANCH)},
             {json::currentRTCTime, std::to_string(static_cast<uint32_t>(std::time(nullptr)))},
             {json::version, std::string(VERSION)},
             {json::serialNumber, getSerialNumber()},
             {json::caseColour, getCaseColour()},
             {json::recoveryStatusFilePath,
             {json::deviceInfo::networkStatus,
              std::to_string(static_cast<int>(Store::GSM::get()->getNetwork().status))},
             {json::deviceInfo::networkOperatorName, Store::GSM::get()->getNetworkOperatorName()},
             {json::deviceInfo::deviceSpaceTotal, std::to_string(totalDeviceSpaceMiB)},
             {json::deviceInfo::systemReservedSpace, std::to_string(reservedSystemSpaceMiB)},
             {json::deviceInfo::usedUserSpace, std::to_string(usedUserSpaceMiB)},
             {json::deviceInfo::gitRevision, std::string(GIT_REV)},
             {json::deviceInfo::gitBranch, std::string(GIT_BRANCH)},
             {json::deviceInfo::currentRTCTime, std::to_string(static_cast<std::uint32_t>(std::time(nullptr)))},
             {json::deviceInfo::version, std::string(VERSION)},
             {json::deviceInfo::serialNumber, getSerialNumber()},
             {json::deviceInfo::caseColour, getCaseColour()},
             {json::deviceInfo::recoveryStatusFilePath,
              (purefs::dir::getTemporaryPath() / sdesktop::paths::recoveryStatusFilename).string()},
             {json::updateFilePath, (purefs::dir::getTemporaryPath() / sdesktop::paths::updateFilename).string()},
             {json::backupFilePath, (purefs::dir::getTemporaryPath() / sdesktop::paths::backupFilename).string()},
             {json::syncFilePath, (purefs::dir::getTemporaryPath() / sdesktop::paths::syncFilename).string()},
             {json::mtpPath, getMtpPath().string()},
             {json::deviceToken, getDeviceToken()},
             {json::onboardingState, std::to_string(static_cast<int>(getOnboardingState()))}}));
             {json::deviceInfo::updateFilePath,
              (purefs::dir::getTemporaryPath() / sdesktop::paths::updateFilename).string()},
             {json::deviceInfo::backupFilePath,
              (purefs::dir::getTemporaryPath() / sdesktop::paths::backupFilename).string()},
             {json::deviceInfo::syncFilePath,
              (purefs::dir::getTemporaryPath() / sdesktop::paths::syncFilename).string()},
             {json::deviceInfo::mtpPath, getMtpPath().string()},
             {json::deviceInfo::deviceToken, getDeviceToken()},
             {json::deviceInfo::onboardingState, std::to_string(static_cast<int>(getOnboardingState()))}}));

        return http::Code::OK;
    }