~aleteoryx/muditaos

cb729513eb04ee41f005cbaac8d82775d1a7bc5e — Kuba 5 years ago c8a6c4b
[EGD-4862] Add CLIP, CLIR etc responses parser

It allows to show proper GUI windows for CLIP,
 CLIR and IMEI MMI response
M module-bsp/board/rt1051/bsp/usb => module-bsp/board/rt1051/bsp/usb +1 -1
@@ 1,1 1,1 @@
Subproject commit b9c297b301ce89380eb036912b1c1da96f5d4beb
Subproject commit 6c4d2f6c0e8669b5e4a590ab5e9b210dec29d904

M module-cellular/at/response.cpp => module-cellular/at/response.cpp +60 -3
@@ 353,11 353,15 @@ namespace at

        namespace clir
        {
            std::optional<ClirResponse> parseClir(const std::string &response)
            std::optional<ClirResponse> parse(const std::string &response)
            {
                auto constexpr toRemove    = "+CLIR: ";
                auto constexpr emptyString = "";

                if (response.find(toRemove) == std::string::npos) {
                    return std::nullopt;
                }

                auto resp = response;
                utils::findAndReplaceAll(resp, toRemove, emptyString);



@@ 366,8 370,8 @@ namespace at
                    t = utils::trim(t);
                }
                if (tokens.size() == clirTokens) {
                    int state;
                    int status;
                    int state  = 0;
                    int status = 0;

                    if (!utils::toNumeric(tokens[0], state) || !utils::toNumeric(tokens[1], status)) {
                        return std::nullopt;


@@ 628,5 632,58 @@ namespace at
                return message;
            }
        } // namespace clck

        namespace clip
        {
            auto parse(std::string response) -> std::optional<ClipParsed>
            {
                auto constexpr toRemove    = "+CLIP: ";
                auto constexpr emptyString = "";

                if (response.find(toRemove) == std::string::npos) {
                    return std::nullopt;
                }

                utils::findAndReplaceAll(response, toRemove, emptyString);

                auto tokens = utils::split(response, ",");
                for (auto &t : tokens) {
                    t = utils::trim(t);
                }
                if (tokens.size() == clipTokens) {
                    int urcToken;
                    int clipToken;

                    if (!utils::toNumeric(tokens[0], urcToken) || !utils::toNumeric(tokens[1], clipToken)) {
                        return std::nullopt;
                    }
                    auto urcState  = static_cast<UrcState>(urcToken);
                    auto clipState = static_cast<ClipState>(clipToken);

                    if (magic_enum::enum_contains<UrcState>(urcState) &&
                        magic_enum::enum_contains<ClipState>(clipState)) {
                        return ClipParsed(urcState, clipState);
                    }
                }
                return std::nullopt;
            }
            auto getClipState(const ClipState &state) -> app::manager::actions::IMMICustomResultParams::MMIResultMessage
            {
                auto message = app::manager::actions::IMMICustomResultParams::MMIResultMessage::CommonNoMessage;

                switch (state) {
                case ClipState::NotProvisioned:
                    message = app::manager::actions::IMMICustomResultParams::MMIResultMessage::ClipNotProvisioned;
                    break;
                case ClipState::Provisioned:
                    message = app::manager::actions::IMMICustomResultParams::MMIResultMessage::ClipProvisioned;
                    break;
                case ClipState::Unknown:
                    message = app::manager::actions::IMMICustomResultParams::MMIResultMessage::ClipUnknown;
                    break;
                }
                return message;
            }
        } // namespace clip
    }     // namespace response
} // namespace at

M module-cellular/at/response.hpp => module-cellular/at/response.hpp +31 -1
@@ 273,12 273,42 @@ namespace at
                {}
            };

            auto parseClir(const std::string &response) -> std::optional<ClirResponse>;
            auto parse(const std::string &response) -> std::optional<ClirResponse>;
            auto getState(const ServiceState &state) -> app::manager::actions::IMMICustomResultParams::MMIResultMessage;
            auto getStatus(const ServiceStatus &status)
                -> app::manager::actions::IMMICustomResultParams::MMIResultMessage;
        } // namespace clir

        namespace clip
        {
            auto constexpr clipTokens = 2;

            enum class UrcState
            {
                SupressUrc,
                DisplayUrc
            };

            enum class ClipState
            {
                NotProvisioned,
                Provisioned,
                Unknown
            };

            struct ClipParsed
            {
                UrcState urcState;
                ClipState clipState;
                explicit ClipParsed(UrcState urc, ClipState clip) : urcState(urc), clipState(clip)
                {}
            };

            auto parse(std::string response) -> std::optional<ClipParsed>;
            auto getClipState(const ClipState &state)
                -> app::manager::actions::IMMICustomResultParams::MMIResultMessage;
        } // namespace clip

        namespace ccfc
        {


M module-cellular/test/unittest_response.cpp => module-cellular/test/unittest_response.cpp +166 -0
@@ 152,6 152,172 @@ TEST_CASE("Response COPS")
        REQUIRE(at::response::parseCOPS(resp, ret) == false);
    }
}
TEST_CASE("Response CLIR")
{
    SECTION("OK CLIR? - according to subscription, not provisioned")
    {
        at::Result resp;
        resp.code = at::Result::Code::OK;
        resp.response.push_back("+CLIR: 0,0");
        resp.response.push_back("OK");
        REQUIRE(resp.code == at::Result::Code::OK);
        auto response = at::response::clir::parse(resp.response[0]);
        REQUIRE(response != std::nullopt);
        REQUIRE(response->serviceState == at::response::clir::ServiceState::AccordingToSubscription);
        REQUIRE(response->serviceStatus == at::response::clir::ServiceStatus::NotProvisioned);
    }

    SECTION("OK CLIR? - disabled, temporary allowed")
    {
        at::Result resp;
        resp.code = at::Result::Code::OK;
        resp.response.push_back("+CLIR: 2,4");
        resp.response.push_back("OK");
        REQUIRE(resp.code == at::Result::Code::OK);
        auto response = at::response::clir::parse(resp.response[0]);
        REQUIRE(response != std::nullopt);
        REQUIRE(response->serviceState == at::response::clir::ServiceState::ServiceDisabled);
        REQUIRE(response->serviceStatus == at::response::clir::ServiceStatus::TemporaryAllowed);
    }

    SECTION("WRONG CLIR? - invalid service state")
    {
        at::Result resp;
        resp.code = at::Result::Code::OK;
        resp.response.push_back("+CLIR: 6,4");
        resp.response.push_back("OK");
        REQUIRE(resp.code == at::Result::Code::OK);
        auto response = at::response::clir::parse(resp.response[0]);
        REQUIRE(response == std::nullopt);
    }

    SECTION("WRONG CLIR? - invalid service status")
    {
        at::Result resp;
        resp.code = at::Result::Code::OK;
        resp.response.push_back("+CLIR: 1,99");
        resp.response.push_back("OK");
        REQUIRE(resp.code == at::Result::Code::OK);
        auto response = at::response::clir::parse(resp.response[0]);
        REQUIRE(response == std::nullopt);
    }

    SECTION("WRONG CLIR? - to many toknes")
    {
        at::Result resp;
        resp.code = at::Result::Code::OK;
        resp.response.push_back("+CLIR: 1,4,6");
        resp.response.push_back("OK");
        REQUIRE(resp.code == at::Result::Code::OK);
        auto response = at::response::clir::parse(resp.response[0]);
        REQUIRE(response == std::nullopt);
    }

    SECTION("WRONG CLIR? - to little tokens")
    {
        at::Result resp;
        resp.code = at::Result::Code::OK;
        resp.response.push_back("+CLIR: 1");
        resp.response.push_back("OK");
        REQUIRE(resp.code == at::Result::Code::OK);
        auto response = at::response::clir::parse(resp.response[0]);
        REQUIRE(response == std::nullopt);
    }

    SECTION("WRONG CLIR? - invalid token")
    {
        at::Result resp;
        resp.code = at::Result::Code::OK;
        resp.response.push_back("+CLI: 1,1");
        resp.response.push_back("OK");
        REQUIRE(resp.code == at::Result::Code::OK);
        auto response = at::response::clir::parse(resp.response[0]);
        REQUIRE(response == std::nullopt);
    }
}

TEST_CASE("Response CLIP")
{
    SECTION("OK CLIP? - clip provisioned, display urc")
    {
        at::Result resp;
        resp.code = at::Result::Code::OK;
        resp.response.push_back("+CLIP: 1,1");
        resp.response.push_back("OK");
        REQUIRE(resp.code == at::Result::Code::OK);
        auto response = at::response::clip::parse(resp.response[0]);
        REQUIRE(response != std::nullopt);
        REQUIRE(response->clipState == at::response::clip::ClipState::Provisioned);
        REQUIRE(response->urcState == at::response::clip::UrcState::DisplayUrc);
    }

    SECTION("OK CLIP? - clip not provisioned, supress urc")
    {
        at::Result resp;
        resp.code = at::Result::Code::OK;
        resp.response.push_back("+CLIP: 0,0");
        resp.response.push_back("OK");
        REQUIRE(resp.code == at::Result::Code::OK);
        auto response = at::response::clip::parse(resp.response[0]);
        REQUIRE(response != std::nullopt);
        REQUIRE(response->clipState == at::response::clip::ClipState::NotProvisioned);
        REQUIRE(response->urcState == at::response::clip::UrcState::SupressUrc);
    }

    SECTION("WRONG CLIP? - clip invalid clip state")
    {
        at::Result resp;
        resp.code = at::Result::Code::OK;
        resp.response.push_back("+CLIP: 1,99");
        resp.response.push_back("OK");
        REQUIRE(resp.code == at::Result::Code::OK);
        auto response = at::response::clip::parse(resp.response[0]);
        REQUIRE(response == std::nullopt);
    }

    SECTION("WRONG CLIP? - clip urc state")
    {
        at::Result resp;
        resp.code = at::Result::Code::OK;
        resp.response.push_back("+CLIP: 77,1");
        resp.response.push_back("OK");
        REQUIRE(resp.code == at::Result::Code::OK);
        auto response = at::response::clip::parse(resp.response[0]);
        REQUIRE(response == std::nullopt);
    }

    SECTION("WRONG CLIP? - to many tokens")
    {
        at::Result resp;
        resp.code = at::Result::Code::OK;
        resp.response.push_back("+CLIP: 1,1,3");
        resp.response.push_back("OK");
        REQUIRE(resp.code == at::Result::Code::OK);
        auto response = at::response::clip::parse(resp.response[0]);
        REQUIRE(response == std::nullopt);
    }

    SECTION("WRONG CLIP? - to little tokens")
    {
        at::Result resp;
        resp.code = at::Result::Code::OK;
        resp.response.push_back("+CLIP: 0");
        resp.response.push_back("OK");
        REQUIRE(resp.code == at::Result::Code::OK);
        auto response = at::response::clip::parse(resp.response[0]);
        REQUIRE(response == std::nullopt);
    }
    SECTION("WRONG CLIP? - invalid token")
    {
        at::Result resp;
        resp.code = at::Result::Code::OK;
        resp.response.push_back("+CLI: 1,1");
        resp.response.push_back("OK");
        REQUIRE(resp.code == at::Result::Code::OK);
        auto response = at::response::clip::parse(resp.response[0]);
        REQUIRE(response == std::nullopt);
    }
}

TEST_CASE("Response CLCK")
{

M module-services/service-appmgr/data/MmiActionsParams.cpp => module-services/service-appmgr/data/MmiActionsParams.cpp +5 -0
@@ 72,3 72,8 @@ auto MMICallBarringResult::getMessages(void) noexcept -> std::vector<std::pair<M
{
    return data;
}

auto MMIImeiResult::getImei() const noexcept -> std::string
{
    return imei;
}

M module-services/service-appmgr/service-appmgr/data/MmiActionsParams.hpp => module-services/service-appmgr/service-appmgr/data/MmiActionsParams.hpp +33 -4
@@ 31,6 31,8 @@ namespace app::manager::actions
            CallForwardingNotification,
            CallForwardingData,
            Clir,
            Clip,
            Imei,
            CallBarringNotification,
            CallBarringData
        };


@@ 40,17 42,18 @@ namespace app::manager::actions
            NoneSpecifiedSuccess,
            NoneSpecifiedFailed,
            CommonFailure,
            CommonMMINotSupported,
            CommonNoMessage,
            CommonMMINotSupported,
            CommonEnabled,
            CommonDisabled,
            CommonVoice,
            CommonData,
            CommonFax,
            CommonAsync,
            CommonSync,
            CommonAsync,
            CommonAllDisabled,

            CommonActivated,
            CommonDeactivated,
            CommonActivated,
            CommonQuery,

            ClirAccordingToSubscription,


@@ 76,6 79,12 @@ namespace app::manager::actions
            CallBarringActivated,
            CallBarringDeactivated,

            ClipActivted,
            ClipDaectivated,
            ClipNotProvisioned,
            ClipProvisioned,
            ClipUnknown,

        };

        virtual auto getMessage() const -> std::vector<MMIResultMessage> = 0;


@@ 175,4 184,24 @@ namespace app::manager::actions
        MMIResult result;
        std::shared_ptr<MMICustomResultParams> customResult = nullptr;
    };

    class MMIClipResult : public MMICustomResultParams
    {
      public:
        MMIClipResult() : MMICustomResultParams(MMIType::Clip)
        {}
    };

    class MMIImeiResult : public MMICustomResultParams
    {
      public:
        explicit MMIImeiResult(const std::string &imei) : MMICustomResultParams(MMIType::Imei), imei(imei)
        {}
        explicit MMIImeiResult() : MMICustomResultParams(MMIType::Imei)
        {}
        auto getImei() const noexcept -> std::string;

      private:
        std::string imei;
    };
} // namespace app::manager::actions

M module-services/service-cellular/CellularRequestHandler.cpp => module-services/service-cellular/CellularRequestHandler.cpp +54 -7
@@ 18,6 18,8 @@
#include "service-cellular/service-cellular/requests/ClirRequest.hpp"
#include "service-cellular/requests/CallForwardingRequest.hpp"
#include "service-cellular/requests/CallBarringRequest.hpp"
#include "service-cellular/requests/ClirRequest.hpp"
#include "service-cellular/requests/ClipRequest.hpp"

#include <service-appmgr/model/ApplicationManager.hpp>
#include "service-cellular/service-cellular/requests/ClirRequest.hpp"


@@ 27,13 29,20 @@

void CellularRequestHandler::handle(cellular::ImeiRequest &request, at::Result &result)
{
    if (!request.checkModemResponse(result)) {
        request.setHandled(false);
        sendMmiResult(false);
        return;
    using namespace app::manager::actions;
    using namespace at::response;
    auto requestHandled = request.checkModemResponse(result);

    std::shared_ptr<MMICustomResultParams> response;
    if (requestHandled) {
        response = std::make_shared<MMIImeiResult>(result.response[0]);
    }
    request.setHandled(true);
    auto msg = std::make_shared<CellularMMIPushMessage>(result.response[0]);
    else {
        response = std::make_shared<MMIImeiResult>(MMIImeiResult());
        response->addMessage(IMMICustomResultParams::MMIResultMessage::CommonFailure);
    }

    auto msg = std::make_shared<CellularMMIResultMessage>(MMIResultParams::MMIResult::Success, response);
    sys::Bus::SendUnicast(msg, app::manager::ApplicationManager::ServiceName, &cellular);
}



@@ 105,7 114,7 @@ void CellularRequestHandler::handle(cellular::ClirRequest &request, at::Result &
            response->addMessage(IMMICustomResultParams::MMIResultMessage::ClirDisabled);
        }
        else if (procedureType == SupplementaryServicesRequest::ProcedureType::Interrogation) {
            auto clirParsed = clir::parseClir(result.response[0]);
            auto clirParsed = clir::parse(result.response[0]);
            if (clirParsed != std::nullopt) {
                response->addMessage(clir::getStatus(clirParsed->serviceStatus));
                response->addMessage(clir::getState(clirParsed->serviceState));


@@ 234,6 243,44 @@ void CellularRequestHandler::handle(cellular::CallBarringRequest &request, at::R
    request.setHandled(requestHandled);
}

void CellularRequestHandler::handle(cellular::ClipRequest &request, at::Result &result)
{
    using namespace app::manager::actions;
    using namespace at::response;
    using namespace cellular;
    auto requestHandled = request.checkModemResponse(result);

    std::shared_ptr<MMICustomResultParams> response = std::make_shared<MMIClipResult>();
    if (requestHandled) {
        auto procedureType = request.getProcedureType();
        if (procedureType == SupplementaryServicesRequest::ProcedureType::Activation) {
            response->addMessage(IMMICustomResultParams::MMIResultMessage::CommonEnabled);
        }
        else if (procedureType == SupplementaryServicesRequest::ProcedureType::Deactivation) {
            response->addMessage(IMMICustomResultParams::MMIResultMessage::CommonDisabled);
        }
        else if (procedureType == SupplementaryServicesRequest::ProcedureType::Interrogation) {
            auto parsed = clip::parse(result.response[0]);
            if (parsed != std::nullopt) {
                response->addMessage(clip::getClipState(parsed->clipState));
            }
            else {
                response->addMessage(IMMICustomResultParams::MMIResultMessage::CommonFailure);
            }
        }
        else {
            response->addMessage(IMMICustomResultParams::MMIResultMessage::CommonMMINotSupported);
        }
    }
    else {
        response->addMessage(IMMICustomResultParams::MMIResultMessage::CommonFailure);
    }

    auto msg = std::make_shared<CellularMMIResultMessage>(MMIResultParams::MMIResult::Success, response);
    sys::Bus::SendUnicast(msg, app::manager::ApplicationManager::ServiceName, &cellular);
    request.setHandled(requestHandled);
}

void CellularRequestHandler::sendMmiResult(bool result)
{
    using namespace app::manager::actions;

M module-services/service-cellular/service-cellular/CellularRequestHandler.hpp => module-services/service-cellular/service-cellular/CellularRequestHandler.hpp +1 -0
@@ 19,6 19,7 @@ class CellularRequestHandler : public cellular::RequestHandler
    void handle(cellular::SupplementaryServicesRequest &request, at::Result &result) final;
    void handle(cellular::PinChangeRequest &request, at::Result &result) final;
    void handle(cellular::ClirRequest &request, at::Result &result) final;
    void handle(cellular::ClipRequest &request, at::Result &result) final;
    void handle(cellular::CallForwardingRequest &request, at::Result &result) final;
    void handle(cellular::CallBarringRequest &request, at::Result &result) final;


M module-services/service-cellular/service-cellular/RequestHandler.hpp => module-services/service-cellular/service-cellular/RequestHandler.hpp +1 -0
@@ 28,6 28,7 @@ namespace cellular
        virtual void handle(PinChangeRequest &request, at::Result &result)             = 0;
        virtual void handle(SupplementaryServicesRequest &request, at::Result &result) = 0;
        virtual void handle(ClirRequest &request, at::Result &result)                  = 0;
        virtual void handle(ClipRequest &request, at::Result &result)                  = 0;
        virtual void handle(CallForwardingRequest &request, at::Result &result)        = 0;
        virtual void handle(CallBarringRequest &request, at::Result &result)           = 0;
    };