M module-cellular/at/response.cpp => module-cellular/at/response.cpp +108 -0
@@ 520,5 520,113 @@ namespace at
return false;
}
} // namespace ccfc
+
+ namespace mmi
+ {
+ auto getClass(const ServiceClass &serviceClass) noexcept
+ -> app::manager::actions::IMMICustomResultParams::MMIResultMessage
+ {
+ using namespace app::manager::actions;
+
+ auto message = IMMICustomResultParams::MMIResultMessage::CommonNoMessage;
+ switch (serviceClass) {
+ case ServiceClass::Voice:
+ message = IMMICustomResultParams::MMIResultMessage::CommonVoice;
+ break;
+ case ServiceClass::Data:
+ message = IMMICustomResultParams::MMIResultMessage::CommonData;
+ break;
+ case ServiceClass::Fax:
+ message = IMMICustomResultParams::MMIResultMessage::CommonFax;
+ break;
+ case ServiceClass::DataSync:
+ message = IMMICustomResultParams::MMIResultMessage::CommonSync;
+ break;
+ case ServiceClass::DataAsync:
+ message = IMMICustomResultParams::MMIResultMessage::CommonAsync;
+ break;
+ case ServiceClass::AllDisabled:
+ message = IMMICustomResultParams::MMIResultMessage::CommonAllDisabled;
+ break;
+ }
+ return message;
+ }
+ } // namespace mmi
+
+ namespace clck
+ {
+ auto parseQueryResponse(const std::vector<std::string> &data, std::vector<ClckParsed> &parsed) -> bool
+ {
+ using namespace mmi;
+
+ auto constexpr responseToken = "+CLCK: ";
+ auto constexpr emptyString = "";
+ auto constexpr minTokens = 2;
+ parsed.clear();
+
+ for (auto el : data) {
+ if (el.find("OK") != std::string::npos) {
+ return true;
+ }
+ if (el.find(responseToken) == std::string::npos) {
+ parsed.clear();
+ return false;
+ }
+ utils::findAndReplaceAll(el, responseToken, emptyString);
+ auto tokens = utils::split(el, ",");
+ if (tokens.size() < minTokens) {
+ parsed.clear();
+ return false;
+ }
+ for (auto &t : tokens) {
+ t = utils::trim(t);
+ }
+
+ int statusToken = 0;
+ int serviceClassToken = 0;
+
+ if (!utils::toNumeric(tokens[0], statusToken) || !utils::toNumeric(tokens[1], serviceClassToken)) {
+ return false;
+ }
+ auto status = static_cast<Status>(statusToken);
+ auto serviceClass = static_cast<ServiceClass>(serviceClassToken);
+
+ if (magic_enum::enum_contains<Status>(status) &&
+ magic_enum::enum_contains<ServiceClass>(serviceClass)) {
+ parsed.push_back(ClckParsed(status, serviceClass));
+ }
+ else {
+ parsed.clear();
+ return false;
+ }
+ }
+ return true;
+ }
+
+ auto iterLessIter(ClckParsed a, ClckParsed b) -> bool
+ {
+ return a.serviceClass < b.serviceClass;
+ }
+
+ auto getStatus(const Status &status) noexcept
+ -> app::manager::actions::IMMICustomResultParams::MMIResultMessage
+ {
+ using namespace app::manager::actions;
+
+ auto message = IMMICustomResultParams::MMIResultMessage::CommonNoMessage;
+ switch (status) {
+ case Status::Disable:
+ message = IMMICustomResultParams::MMIResultMessage::CommonDeactivated;
+ break;
+ case Status::Enable:
+ message = IMMICustomResultParams::MMIResultMessage::CommonActivated;
+ break;
+ case Status::Query:
+ message = IMMICustomResultParams::MMIResultMessage::CommonQuery;
+ break;
+ }
+ return message;
+ }
+ } // namespace clck
} // namespace response
} // namespace at
M module-cellular/at/response.hpp => module-cellular/at/response.hpp +40 -0
@@ 334,5 334,45 @@ namespace at
auto getNumbers(std::vector<ParsedCcfc> &parsed) -> CcfcNumbers;
auto isAnyActive(std::vector<ParsedCcfc> &parsed) -> bool;
} // namespace ccfc
+
+ namespace mmi
+ {
+
+ enum class ServiceClass
+ {
+ Voice = 1,
+ Data = 2,
+ Fax = 4,
+ DataSync = 16,
+ DataAsync = 32,
+ AllDisabled = 255
+ };
+
+ auto getClass(const ServiceClass &serviceClass) noexcept
+ -> app::manager::actions::IMMICustomResultParams::MMIResultMessage;
+ } // namespace mmi
+
+ namespace clck
+ {
+ enum class Status
+ {
+ Disable,
+ Enable,
+ Query
+ };
+
+ struct ClckParsed
+ {
+ Status status;
+ mmi::ServiceClass serviceClass;
+ explicit ClckParsed(Status status, mmi::ServiceClass serviceClass)
+ : status(status), serviceClass(serviceClass){};
+ };
+
+ auto parseQueryResponse(const std::vector<std::string> &data, std::vector<ClckParsed> &parsed) -> bool;
+ auto iterLessIter(ClckParsed a, ClckParsed b) -> bool;
+ auto getStatus(const Status &status) noexcept
+ -> app::manager::actions::IMMICustomResultParams::MMIResultMessage;
+ } // namespace clck
} // namespace response
} // namespace at
M module-cellular/test/unittest_response.cpp => module-cellular/test/unittest_response.cpp +116 -0
@@ 152,3 152,119 @@ TEST_CASE("Response COPS")
REQUIRE(at::response::parseCOPS(resp, ret) == false);
}
}
+
+TEST_CASE("Response CLCK")
+{
+ SECTION("OK CLCK QUERY - all disabled")
+ {
+
+ at::Result resp;
+ resp.code = at::Result::Code::OK;
+ std::vector<at::response::clck::ClckParsed> ret;
+ resp.response.push_back("+CLCK: 0,255");
+ resp.response.push_back("OK");
+
+ REQUIRE(resp.code == at::Result::Code::OK);
+ REQUIRE(at::response::clck::parseQueryResponse(resp.response, ret) == true);
+ REQUIRE(ret.size() == 1);
+ REQUIRE(ret[0].status == at::response::clck::Status::Disable);
+ REQUIRE(ret[0].serviceClass == at::response::mmi::ServiceClass::AllDisabled);
+ }
+
+ SECTION("OK CLCK QUERY - voice enabled")
+ {
+
+ at::Result resp;
+ resp.code = at::Result::Code::OK;
+ std::vector<at::response::clck::ClckParsed> ret;
+ resp.response.push_back("+CLCK: 1,1");
+ resp.response.push_back("OK");
+
+ REQUIRE(resp.code == at::Result::Code::OK);
+ REQUIRE(at::response::clck::parseQueryResponse(resp.response, ret) == true);
+ REQUIRE(ret.size() == 1);
+ REQUIRE(ret[0].status == at::response::clck::Status::Enable);
+ REQUIRE(ret[0].serviceClass == at::response::mmi::ServiceClass::Voice);
+ }
+
+ SECTION("OK CLCK QUERY - voice, fax enabled")
+ {
+
+ at::Result resp;
+ resp.code = at::Result::Code::OK;
+ std::vector<at::response::clck::ClckParsed> ret;
+ resp.response.push_back("+CLCK: 1,1");
+ resp.response.push_back("+CLCK: 1,4");
+ resp.response.push_back("OK");
+
+ REQUIRE(resp.code == at::Result::Code::OK);
+ REQUIRE(at::response::clck::parseQueryResponse(resp.response, ret) == true);
+ REQUIRE(ret.size() == 2);
+
+ REQUIRE(ret[0].status == at::response::clck::Status::Enable);
+ REQUIRE(ret[0].serviceClass == at::response::mmi::ServiceClass::Voice);
+
+ REQUIRE(ret[1].status == at::response::clck::Status::Enable);
+ REQUIRE(ret[1].serviceClass == at::response::mmi::ServiceClass::Fax);
+ }
+
+ SECTION("WRONG CLCK QUERY - invalid status")
+ {
+
+ at::Result resp;
+ resp.code = at::Result::Code::OK;
+ std::vector<at::response::clck::ClckParsed> ret;
+ resp.response.push_back("+CLCK: 8,1");
+ resp.response.push_back("+CLCK: 1,4");
+ resp.response.push_back("OK");
+
+ REQUIRE(resp.code == at::Result::Code::OK);
+ REQUIRE(at::response::clck::parseQueryResponse(resp.response, ret) == false);
+ REQUIRE(ret.size() == 0);
+ }
+
+ SECTION("WRONG CLCK QUERY - invalid class")
+ {
+
+ at::Result resp;
+ resp.code = at::Result::Code::OK;
+ std::vector<at::response::clck::ClckParsed> ret;
+ resp.response.push_back("+CLCK: 1,1");
+ resp.response.push_back("+CLCK: 1,99");
+ resp.response.push_back("OK");
+
+ REQUIRE(resp.code == at::Result::Code::OK);
+ REQUIRE(at::response::clck::parseQueryResponse(resp.response, ret) == false);
+ REQUIRE(ret.size() == 0);
+ }
+
+ SECTION("WRONG CLCK QUERY - too short")
+ {
+
+ at::Result resp;
+ resp.code = at::Result::Code::OK;
+ std::vector<at::response::clck::ClckParsed> ret;
+ resp.response.push_back("+CLCK: 1");
+ resp.response.push_back("+CLCK: 1,4");
+ resp.response.push_back("OK");
+
+ REQUIRE(resp.code == at::Result::Code::OK);
+ REQUIRE(at::response::clck::parseQueryResponse(resp.response, ret) == false);
+ REQUIRE(ret.size() == 0);
+ }
+
+ SECTION("WRONG CLCK QUERY - invalid response token")
+ {
+
+ at::Result resp;
+ resp.code = at::Result::Code::OK;
+ std::vector<at::response::clck::ClckParsed> ret;
+ resp.response.push_back("+CLC: 1,1");
+ resp.response.push_back("+CLCK: 1,4");
+ resp.response.push_back("OK");
+
+ REQUIRE(resp.code == at::Result::Code::OK);
+ REQUIRE(at::response::clck::parseQueryResponse(resp.response, ret) == false);
+ REQUIRE(ret.size() == 0);
+ }
+}
M module-services/service-appmgr/data/MmiActionsParams.cpp => module-services/service-appmgr/data/MmiActionsParams.cpp +10 -0
@@ 62,3 62,13 @@ auto MMIResultParams::getCustomData() const noexcept -> std::shared_ptr<MMICusto
{
return customResult;
}
+
+void MMICallBarringResult::addMessages(const std::pair<MMIResultMessage, MMIResultMessage> &message) noexcept
+{
+ data.push_back(message);
+}
+
+auto MMICallBarringResult::getMessages(void) noexcept -> std::vector<std::pair<MMIResultMessage, MMIResultMessage>>
+{
+ return data;
+}
M module-services/service-appmgr/service-appmgr/data/MmiActionsParams.hpp => module-services/service-appmgr/service-appmgr/data/MmiActionsParams.hpp +29 -2
@@ 30,7 30,9 @@ namespace app::manager::actions
NoneSpecified,
CallForwardingNotification,
CallForwardingData,
- Clir
+ Clir,
+ CallBarringNotification,
+ CallBarringData
};
enum class MMIResultMessage
@@ 40,6 42,16 @@ namespace app::manager::actions
CommonFailure,
CommonMMINotSupported,
CommonNoMessage,
+ CommonVoice,
+ CommonData,
+ CommonFax,
+ CommonAsync,
+ CommonSync,
+ CommonAllDisabled,
+
+ CommonActivated,
+ CommonDeactivated,
+ CommonQuery,
ClirAccordingToSubscription,
ClirEnabled,
@@ 59,7 71,10 @@ namespace app::manager::actions
DisablingFailed,
EnablingSuccessful,
EnablingFailed,
- CallForwardingDisabled
+ CallForwardingDisabled,
+
+ CallBarringActivated,
+ CallBarringDeactivated,
};
@@ 119,6 134,18 @@ namespace app::manager::actions
{}
};
+ class MMICallBarringResult : public MMICustomResultParams
+ {
+ public:
+ explicit MMICallBarringResult(MMIType type) : MMICustomResultParams(type)
+ {}
+ void addMessages(const std::pair<MMIResultMessage, MMIResultMessage> &message) noexcept;
+ auto getMessages(void) noexcept -> std::vector<std::pair<MMIResultMessage, MMIResultMessage>>;
+
+ private:
+ std::vector<std::pair<MMIResultMessage, MMIResultMessage>> data;
+ };
+
class MMIParams : public ActionParams
{
public:
M module-services/service-cellular/CellularRequestHandler.cpp => module-services/service-cellular/CellularRequestHandler.cpp +60 -10
@@ 17,14 17,15 @@
#include "service-cellular/requests/UssdRequest.hpp"
#include "service-cellular/service-cellular/requests/ClirRequest.hpp"
#include "service-cellular/requests/CallForwardingRequest.hpp"
+#include "service-cellular/requests/CallBarringRequest.hpp"
#include <service-appmgr/model/ApplicationManager.hpp>
+#include "service-cellular/service-cellular/requests/ClirRequest.hpp"
+#include "service-cellular/service-cellular/requests/SupplementaryServicesRequest.hpp"
#include <module-cellular/at/response.hpp>
-using namespace cellular;
-
-void CellularRequestHandler::handle(ImeiRequest &request, at::Result &result)
+void CellularRequestHandler::handle(cellular::ImeiRequest &request, at::Result &result)
{
if (!request.checkModemResponse(result)) {
request.setHandled(false);
@@ 36,7 37,7 @@ void CellularRequestHandler::handle(ImeiRequest &request, at::Result &result)
sys::Bus::SendUnicast(msg, app::manager::ApplicationManager::ServiceName, &cellular);
}
-void CellularRequestHandler::handle(UssdRequest &request, at::Result &result)
+void CellularRequestHandler::handle(cellular::UssdRequest &request, at::Result &result)
{
auto requestHandled = request.checkModemResponse(result);
@@ 50,7 51,7 @@ void CellularRequestHandler::handle(UssdRequest &request, at::Result &result)
request.setHandled(requestHandled);
}
-void CellularRequestHandler::handle(CallRequest &request, at::Result &result)
+void CellularRequestHandler::handle(cellular::CallRequest &request, at::Result &result)
{
if (!request.checkModemResponse(result)) {
request.setHandled(false);
@@ 66,28 67,28 @@ void CellularRequestHandler::handle(CallRequest &request, at::Result &result)
request.setHandled(true);
}
-void CellularRequestHandler::handle(SupplementaryServicesRequest &request, at::Result &result)
+void CellularRequestHandler::handle(cellular::SupplementaryServicesRequest &request, at::Result &result)
{
auto requestHandled = request.checkModemResponse(result);
request.setHandled(requestHandled);
sendMmiResult(requestHandled);
}
-void CellularRequestHandler::handle(PasswordRegistrationRequest &request, at::Result &result)
+void CellularRequestHandler::handle(cellular::PasswordRegistrationRequest &request, at::Result &result)
{
auto requestHandled = request.checkModemResponse(result);
request.setHandled(requestHandled);
sendMmiResult(requestHandled);
}
-void CellularRequestHandler::handle(PinChangeRequest &request, at::Result &result)
+void CellularRequestHandler::handle(cellular::PinChangeRequest &request, at::Result &result)
{
auto requestHandled = request.checkModemResponse(result);
request.setHandled(requestHandled);
sendMmiResult(requestHandled);
}
-void CellularRequestHandler::handle(ClirRequest &request, at::Result &result)
+void CellularRequestHandler::handle(cellular::ClirRequest &request, at::Result &result)
{
using namespace app::manager::actions;
using namespace cellular;
@@ 119,7 120,7 @@ void CellularRequestHandler::handle(ClirRequest &request, at::Result &result)
request.setHandled(requestHandled);
}
-void CellularRequestHandler::handle(CallForwardingRequest &request, at::Result &result)
+void CellularRequestHandler::handle(cellular::CallForwardingRequest &request, at::Result &result)
{
using namespace app::manager::actions;
using namespace cellular;
@@ 184,6 185,55 @@ void CellularRequestHandler::handle(CallForwardingRequest &request, at::Result &
request.setHandled(requestHandled);
}
+void CellularRequestHandler::handle(cellular::CallBarringRequest &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;
+ if (requestHandled) {
+ auto procedureType = request.getProcedureType();
+
+ if (procedureType == cellular::SupplementaryServicesRequest::ProcedureType::Activation) {
+ response = std::make_shared<MMICallBarringResult>(IMMICustomResultParams::MMIType::CallBarringNotification);
+ response->addMessage(IMMICustomResultParams::MMIResultMessage::CallBarringActivated);
+ }
+ else if (procedureType == SupplementaryServicesRequest::ProcedureType::Deactivation) {
+ response = std::make_shared<MMICallBarringResult>(IMMICustomResultParams::MMIType::CallBarringNotification);
+ response->addMessage(IMMICustomResultParams::MMIResultMessage::CallBarringDeactivated);
+ }
+ else if (procedureType == SupplementaryServicesRequest::ProcedureType::Interrogation) {
+ std::vector<clck::ClckParsed> parsed;
+
+ if (clck::parseQueryResponse(result.response, parsed)) {
+ MMICallBarringResult resp = MMICallBarringResult(IMMICustomResultParams::MMIType::CallBarringData);
+ std::sort(parsed.begin(), parsed.end(), clck::iterLessIter);
+ for (auto el : parsed) {
+ resp.addMessages(std::make_pair<IMMICustomResultParams::MMIResultMessage,
+ IMMICustomResultParams::MMIResultMessage>(
+ mmi::getClass(el.serviceClass), clck::getStatus(el.status)));
+ }
+ response = std::make_shared<MMICallBarringResult>(resp);
+ }
+ }
+ else {
+ response = std::make_shared<MMICallBarringResult>(IMMICustomResultParams::MMIType::CallBarringNotification);
+ response->addMessage(IMMICustomResultParams::MMIResultMessage::CommonMMINotSupported);
+ }
+ }
+
+ if (response == nullptr) {
+ response = std::make_shared<MMICallBarringResult>(IMMICustomResultParams::MMIType::CallBarringNotification);
+ 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
@@ 20,6 20,7 @@ class CellularRequestHandler : public cellular::RequestHandler
void handle(cellular::PinChangeRequest &request, at::Result &result) final;
void handle(cellular::ClirRequest &request, at::Result &result) final;
void handle(cellular::CallForwardingRequest &request, at::Result &result) final;
+ void handle(cellular::CallBarringRequest &request, at::Result &result) final;
private:
ServiceCellular &cellular;
M module-services/service-cellular/service-cellular/RequestHandler.hpp => module-services/service-cellular/service-cellular/RequestHandler.hpp +2 -0
@@ 16,6 16,7 @@ namespace cellular
class ClipRequest;
class ClirRequest;
class CallForwardingRequest;
+ class CallBarringRequest;
class RequestHandler
{
@@ 28,5 29,6 @@ namespace cellular
virtual void handle(SupplementaryServicesRequest &request, at::Result &result) = 0;
virtual void handle(ClirRequest &request, at::Result &result) = 0;
virtual void handle(CallForwardingRequest &request, at::Result &result) = 0;
+ virtual void handle(CallBarringRequest &request, at::Result &result) = 0;
};
} // namespace cellular