M module-cellular/at/response.cpp => module-cellular/at/response.cpp +102 -0
@@ 685,5 685,107 @@ namespace at
return message;
}
} // namespace clip
+
+ namespace ccwa
+ {
+ auto parse(const std::vector<std::string> &data, std::vector<CcwaParsed> &parsed) noexcept -> bool
+ {
+
+ auto constexpr toRemove = "+CCWA: ";
+ auto constexpr emptyString = "";
+ auto constexpr tokenCount = 2;
+ parsed.clear();
+
+ for (auto el : data) {
+
+ if (el.find("OK") != std::string::npos) {
+ return true;
+ }
+
+ if (el.find(toRemove) == std::string::npos) {
+ parsed.clear();
+ return false;
+ }
+
+ utils::findAndReplaceAll(el, toRemove, emptyString);
+ auto tokens = utils::split(el, ",");
+ if (tokens.size() != tokenCount) {
+ 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)) {
+ parsed.clear();
+ 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(CcwaParsed(status, serviceClass));
+ }
+ else {
+ parsed.clear();
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ 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::CallWaitingDeactivated;
+ break;
+ case Status::Enable:
+ message = IMMICustomResultParams::MMIResultMessage::CallWaitingActivated;
+ break;
+ }
+ return message;
+ }
+
+ 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 ccwa
} // namespace response
} // namespace at
M module-cellular/at/response.hpp => module-cellular/at/response.hpp +32 -0
@@ 404,5 404,37 @@ namespace at
auto getStatus(const Status &status) noexcept
-> app::manager::actions::IMMICustomResultParams::MMIResultMessage;
} // namespace clck
+
+ namespace ccwa
+ {
+ enum class Status
+ {
+ Disable,
+ Enable
+ };
+ enum class ServiceClass
+ {
+ Voice = 1,
+ Data = 2,
+ Fax = 4,
+ DataSync = 16,
+ DataAsync = 32,
+ AllDisabled = 255
+ };
+
+ struct CcwaParsed
+ {
+ Status status;
+ ServiceClass serviceClass;
+ explicit CcwaParsed(const Status status, const ServiceClass serviceClass)
+ : status(status), serviceClass(serviceClass){};
+ };
+
+ auto parse(const std::vector<std::string> &data, std::vector<CcwaParsed> &parsed) noexcept -> bool;
+ auto getStatus(const Status &status) noexcept
+ -> app::manager::actions::IMMICustomResultParams::MMIResultMessage;
+ auto getClass(const ServiceClass &serviceClass) noexcept
+ -> app::manager::actions::IMMICustomResultParams::MMIResultMessage;
+ } // namespace ccwa
} // namespace response
} // namespace at
M module-cellular/test/unittest_response.cpp => module-cellular/test/unittest_response.cpp +115 -0
@@ 434,3 434,118 @@ TEST_CASE("Response CLCK")
REQUIRE(ret.size() == 0);
}
}
+
+TEST_CASE("Response CCWA?")
+{
+ SECTION("OK CCWA? - all disabled")
+ {
+
+ at::Result resp;
+ resp.code = at::Result::Code::OK;
+ std::vector<at::response::ccwa::CcwaParsed> ret;
+ resp.response.push_back("+CCWA: 0,255");
+ resp.response.push_back("OK");
+
+ REQUIRE(resp.code == at::Result::Code::OK);
+ REQUIRE(at::response::ccwa::parse(resp.response, ret) == true);
+ REQUIRE(ret.size() == 1);
+ REQUIRE(ret[0].status == at::response::ccwa::Status::Disable);
+ REQUIRE(ret[0].serviceClass == at::response::ccwa::ServiceClass::AllDisabled);
+ }
+
+ SECTION("OK CCWA? - voice, fax enabled")
+ {
+
+ at::Result resp;
+ resp.code = at::Result::Code::OK;
+ std::vector<at::response::ccwa::CcwaParsed> ret;
+ resp.response.push_back("+CCWA: 1,1");
+ resp.response.push_back("+CCWA: 1,4");
+ resp.response.push_back("OK");
+
+ REQUIRE(resp.code == at::Result::Code::OK);
+ REQUIRE(at::response::ccwa::parse(resp.response, ret) == true);
+ REQUIRE(ret.size() == 2);
+
+ REQUIRE(ret[0].status == at::response::ccwa::Status::Enable);
+ REQUIRE(ret[0].serviceClass == at::response::ccwa::ServiceClass::Voice);
+
+ REQUIRE(ret[1].status == at::response::ccwa::Status::Enable);
+ REQUIRE(ret[1].serviceClass == at::response::ccwa::ServiceClass::Fax);
+ }
+
+ SECTION("WRONG CCWA? - invalid status")
+ {
+
+ at::Result resp;
+ resp.code = at::Result::Code::OK;
+ std::vector<at::response::ccwa::CcwaParsed> ret;
+ resp.response.push_back("+CCWA: 9,1");
+ resp.response.push_back("+CCWA: 1,4");
+ resp.response.push_back("OK");
+
+ REQUIRE(resp.code == at::Result::Code::OK);
+ REQUIRE(at::response::ccwa::parse(resp.response, ret) == false);
+ REQUIRE(ret.size() == 0);
+ }
+
+ SECTION("WRONG CCWA? - invalid class")
+ {
+
+ at::Result resp;
+ resp.code = at::Result::Code::OK;
+ std::vector<at::response::ccwa::CcwaParsed> ret;
+ resp.response.push_back("+CCWA: 1,1");
+ resp.response.push_back("+CCWA: 1,66");
+ resp.response.push_back("OK");
+
+ REQUIRE(resp.code == at::Result::Code::OK);
+ REQUIRE(at::response::ccwa::parse(resp.response, ret) == false);
+ REQUIRE(ret.size() == 0);
+ }
+
+ SECTION("WRONG CCWA? - invalid token")
+ {
+
+ at::Result resp;
+ resp.code = at::Result::Code::OK;
+ std::vector<at::response::ccwa::CcwaParsed> ret;
+ resp.response.push_back("+CCW: 1,1");
+ resp.response.push_back("+CCWA: 1,66");
+ resp.response.push_back("OK");
+
+ REQUIRE(resp.code == at::Result::Code::OK);
+ REQUIRE(at::response::ccwa::parse(resp.response, ret) == false);
+ REQUIRE(ret.size() == 0);
+ }
+
+ SECTION("WRONG CCWA? - to little tokens")
+ {
+
+ at::Result resp;
+ resp.code = at::Result::Code::OK;
+ std::vector<at::response::ccwa::CcwaParsed> ret;
+ resp.response.push_back("+CCWA: 1,1");
+ resp.response.push_back("+CCWA: 1");
+ resp.response.push_back("OK");
+
+ REQUIRE(resp.code == at::Result::Code::OK);
+ REQUIRE(at::response::ccwa::parse(resp.response, ret) == false);
+ REQUIRE(ret.size() == 0);
+ }
+
+ SECTION("WRONG CCWA? - to many tokens")
+ {
+
+ at::Result resp;
+ resp.code = at::Result::Code::OK;
+ std::vector<at::response::ccwa::CcwaParsed> ret;
+ resp.response.push_back("+CCWA: 1,1,9");
+ resp.response.push_back("+CCWA: 1,4");
+ resp.response.push_back("OK");
+
+ REQUIRE(resp.code == at::Result::Code::OK);
+ REQUIRE(at::response::ccwa::parse(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
@@ 77,3 77,13 @@ auto MMIImeiResult::getImei() const noexcept -> std::string
{
return imei;
}
+
+void MMICallWaitingResult::addMessages(const std::pair<MMIResultMessage, MMIResultMessage> &message)
+{
+ messages.push_back(message);
+}
+
+auto MMICallWaitingResult::getMessages() const noexcept -> std::vector<std::pair<MMIResultMessage, MMIResultMessage>>
+{
+ return messages;
+}
M module-services/service-appmgr/service-appmgr/data/MmiActionsParams.hpp => module-services/service-appmgr/service-appmgr/data/MmiActionsParams.hpp +18 -1
@@ 34,7 34,9 @@ namespace app::manager::actions
Clip,
Imei,
CallBarringNotification,
- CallBarringData
+ CallBarringData,
+ CallWaitingNotification,
+ CallWaitingData
};
enum class MMIResultMessage
@@ 85,6 87,9 @@ namespace app::manager::actions
ClipProvisioned,
ClipUnknown,
+ CallWaitingActivated,
+ CallWaitingDeactivated,
+
};
virtual auto getMessage() const -> std::vector<MMIResultMessage> = 0;
@@ 204,4 209,16 @@ namespace app::manager::actions
private:
std::string imei;
};
+
+ class MMICallWaitingResult : public MMICustomResultParams
+ {
+ public:
+ explicit MMICallWaitingResult(const MMIType type) : MMICustomResultParams(type)
+ {}
+ void addMessages(const std::pair<MMIResultMessage, MMIResultMessage> &message);
+ auto getMessages() const noexcept -> std::vector<std::pair<MMIResultMessage, MMIResultMessage>>;
+
+ private:
+ std::vector<std::pair<MMIResultMessage, MMIResultMessage>> messages;
+ };
} // namespace app::manager::actions
M module-services/service-cellular/CellularRequestHandler.cpp => module-services/service-cellular/CellularRequestHandler.cpp +48 -3
@@ 15,15 15,13 @@
#include "service-cellular/requests/PinChangeRequest.hpp"
#include "service-cellular/requests/ImeiRequest.hpp"
#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-cellular/requests/ClirRequest.hpp"
#include "service-cellular/requests/ClipRequest.hpp"
+#include "service-cellular/requests/CallWaitingRequest.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>
@@ 281,6 279,53 @@ void CellularRequestHandler::handle(cellular::ClipRequest &request, at::Result &
request.setHandled(requestHandled);
}
+void CellularRequestHandler::handle(cellular::CallWaitingRequest &request, at::Result &result)
+{
+ using namespace app::manager::actions;
+ using namespace cellular;
+ using namespace at::response;
+ auto requestHandled = request.checkModemResponse(result);
+
+ std::shared_ptr<MMICustomResultParams> response;
+ if (requestHandled) {
+ auto procedureType = request.getProcedureType();
+ if (procedureType == SupplementaryServicesRequest::ProcedureType::Activation) {
+ response = std::make_shared<MMICallWaitingResult>(IMMICustomResultParams::MMIType::CallWaitingNotification);
+ response->addMessage(IMMICustomResultParams::MMIResultMessage::CallWaitingActivated);
+ }
+ else if (procedureType == SupplementaryServicesRequest::ProcedureType::Deactivation) {
+ response = std::make_shared<MMICallWaitingResult>(IMMICustomResultParams::MMIType::CallWaitingNotification);
+ response->addMessage(IMMICustomResultParams::MMIResultMessage::CallWaitingDeactivated);
+ }
+ else if (procedureType == SupplementaryServicesRequest::ProcedureType::Interrogation) {
+ std::vector<ccwa::CcwaParsed> parsed;
+ if (ccwa::parse(result.response, parsed)) {
+ MMICallWaitingResult resp = MMICallWaitingResult(IMMICustomResultParams::MMIType::CallWaitingData);
+ for (auto el : parsed) {
+ resp.addMessages(std::make_pair(ccwa::getClass(el.serviceClass), ccwa::getStatus(el.status)));
+ }
+ response = std::make_shared<MMICallWaitingResult>(resp);
+ }
+ else {
+ response =
+ std::make_shared<MMICallWaitingResult>(IMMICustomResultParams::MMIType::CallWaitingNotification);
+ response->addMessage(IMMICustomResultParams::MMIResultMessage::CommonFailure);
+ }
+ }
+ else {
+ response = std::make_shared<MMICallWaitingResult>(IMMICustomResultParams::MMIType::CallWaitingNotification);
+ response->addMessage(IMMICustomResultParams::MMIResultMessage::CommonMMINotSupported);
+ }
+ }
+ else {
+ response = std::make_shared<MMICallWaitingResult>(IMMICustomResultParams::MMIType::CallWaitingNotification);
+ 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
@@ 22,6 22,7 @@ class CellularRequestHandler : public cellular::RequestHandler
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;
+ void handle(cellular::CallWaitingRequest &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
@@ 17,6 17,7 @@ namespace cellular
class ClirRequest;
class CallForwardingRequest;
class CallBarringRequest;
+ class CallWaitingRequest;
class RequestHandler
{
@@ 31,5 32,6 @@ namespace cellular
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;
+ virtual void handle(CallWaitingRequest &request, at::Result &result) = 0;
};
} // namespace cellular