From cb729513eb04ee41f005cbaac8d82775d1a7bc5e Mon Sep 17 00:00:00 2001 From: Kuba Date: Tue, 19 Jan 2021 16:03:43 +0100 Subject: [PATCH] [EGD-4862] Add CLIP, CLIR etc responses parser It allows to show proper GUI windows for CLIP, CLIR and IMEI MMI response --- module-bsp/board/rt1051/bsp/usb | 2 +- module-cellular/at/response.cpp | 63 ++++++- module-cellular/at/response.hpp | 32 +++- module-cellular/test/unittest_response.cpp | 166 ++++++++++++++++++ .../service-appmgr/data/MmiActionsParams.cpp | 5 + .../service-appmgr/data/MmiActionsParams.hpp | 37 +++- .../CellularRequestHandler.cpp | 61 ++++++- .../CellularRequestHandler.hpp | 1 + .../service-cellular/RequestHandler.hpp | 1 + 9 files changed, 352 insertions(+), 16 deletions(-) diff --git a/module-bsp/board/rt1051/bsp/usb b/module-bsp/board/rt1051/bsp/usb index b9c297b301ce89380eb036912b1c1da96f5d4beb..6c4d2f6c0e8669b5e4a590ab5e9b210dec29d904 160000 --- a/module-bsp/board/rt1051/bsp/usb +++ b/module-bsp/board/rt1051/bsp/usb @@ -1 +1 @@ -Subproject commit b9c297b301ce89380eb036912b1c1da96f5d4beb +Subproject commit 6c4d2f6c0e8669b5e4a590ab5e9b210dec29d904 diff --git a/module-cellular/at/response.cpp b/module-cellular/at/response.cpp index c1cc539fd3a5d01381d3bbb132a0d5c9c594ec95..6499c175fefa67897adb9997b1aa94ca09d76a87 100644 --- a/module-cellular/at/response.cpp +++ b/module-cellular/at/response.cpp @@ -353,11 +353,15 @@ namespace at namespace clir { - std::optional parseClir(const std::string &response) + std::optional 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 + { + 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(urcToken); + auto clipState = static_cast(clipToken); + + if (magic_enum::enum_contains(urcState) && + magic_enum::enum_contains(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 diff --git a/module-cellular/at/response.hpp b/module-cellular/at/response.hpp index 901e2b3087007fce8d231814472e58edff17ad3b..1830fdfe863e507c766cd9a897e8911b33620cb1 100644 --- a/module-cellular/at/response.hpp +++ b/module-cellular/at/response.hpp @@ -273,12 +273,42 @@ namespace at {} }; - auto parseClir(const std::string &response) -> std::optional; + auto parse(const std::string &response) -> std::optional; 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; + auto getClipState(const ClipState &state) + -> app::manager::actions::IMMICustomResultParams::MMIResultMessage; + } // namespace clip + namespace ccfc { diff --git a/module-cellular/test/unittest_response.cpp b/module-cellular/test/unittest_response.cpp index 9024866c4ce4955773b2b4ed7d722d3e01525d3f..1dfffcf9a5673b248b448df530246aefb56b5fd6 100644 --- a/module-cellular/test/unittest_response.cpp +++ b/module-cellular/test/unittest_response.cpp @@ -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") { diff --git a/module-services/service-appmgr/data/MmiActionsParams.cpp b/module-services/service-appmgr/data/MmiActionsParams.cpp index e7abf8c8aa736107e1f467c6df942a683dd18d2b..193ea9dd3308e320e1bcea6fa58e2df4392d22f6 100644 --- a/module-services/service-appmgr/data/MmiActionsParams.cpp +++ b/module-services/service-appmgr/data/MmiActionsParams.cpp @@ -72,3 +72,8 @@ auto MMICallBarringResult::getMessages(void) noexcept -> std::vector std::string +{ + return imei; +} diff --git a/module-services/service-appmgr/service-appmgr/data/MmiActionsParams.hpp b/module-services/service-appmgr/service-appmgr/data/MmiActionsParams.hpp index 6c24721010870853c5f70130bb41ec86dc96cb9d..5f5fa2c0a5024d9a82707c44cb8116a12b5c516f 100644 --- a/module-services/service-appmgr/service-appmgr/data/MmiActionsParams.hpp +++ b/module-services/service-appmgr/service-appmgr/data/MmiActionsParams.hpp @@ -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 = 0; @@ -175,4 +184,24 @@ namespace app::manager::actions MMIResult result; std::shared_ptr 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 diff --git a/module-services/service-cellular/CellularRequestHandler.cpp b/module-services/service-cellular/CellularRequestHandler.cpp index 686ebe01c7e17a3ef108bb1172defb339762f943..09312239df193a8c68b510ee99d6a7dcb6b2cf27 100644 --- a/module-services/service-cellular/CellularRequestHandler.cpp +++ b/module-services/service-cellular/CellularRequestHandler.cpp @@ -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 #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 response; + if (requestHandled) { + response = std::make_shared(result.response[0]); } - request.setHandled(true); - auto msg = std::make_shared(result.response[0]); + else { + response = std::make_shared(MMIImeiResult()); + response->addMessage(IMMICustomResultParams::MMIResultMessage::CommonFailure); + } + + auto msg = std::make_shared(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 response = std::make_shared(); + 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(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; diff --git a/module-services/service-cellular/service-cellular/CellularRequestHandler.hpp b/module-services/service-cellular/service-cellular/CellularRequestHandler.hpp index aa343c59aa3e9562321b65e630b4b955655222e1..5e84cb15fa97446cfdc2e4b1235b1a35d09cf1ca 100644 --- a/module-services/service-cellular/service-cellular/CellularRequestHandler.hpp +++ b/module-services/service-cellular/service-cellular/CellularRequestHandler.hpp @@ -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; diff --git a/module-services/service-cellular/service-cellular/RequestHandler.hpp b/module-services/service-cellular/service-cellular/RequestHandler.hpp index 12445bc8a4a717c7c1ac7231afb3e1d18b573665..f4f630c5a05d312ed0dd63aea8895f512d3ef70b 100644 --- a/module-services/service-cellular/service-cellular/RequestHandler.hpp +++ b/module-services/service-cellular/service-cellular/RequestHandler.hpp @@ -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; };