M module-cellular/at/ErrorCode.hpp => module-cellular/at/ErrorCode.hpp +1 -1
@@ 54,6 54,7 @@ namespace at
ServiceProvPersPUKRequired = 45,
CorporatePersPINRequired = 46,
CorporatePersPUKRequired = 47,
+ PhoneBusy = 258,
AudioUnknownError = 901,
AudioInvalidParameters = 902,
AudioOperationNotSupported = 903,
@@ 69,7 70,6 @@ namespace at
*/
enum class NetworkErrorCode : uint32_t
{
-
MEFailure = 300,
SMS_MEReserved = 301,
OperationNotAllowed = 302,
M module-cellular/at/response.cpp => module-cellular/at/response.cpp +96 -0
@@ 424,5 424,101 @@ namespace at
return message;
}
} // namespace clir
+
+ namespace ccfc
+ {
+
+ auto parse(std::vector<std::string> response, std::vector<ParsedCcfc> &parsed) -> bool
+ {
+
+ auto constexpr toRemove = "+CCFC: ";
+ auto constexpr emptyString = "";
+ auto constexpr quote = "\"";
+
+ parsed.clear();
+
+ for (auto el : response) {
+
+ if (el.find("OK") != std::string::npos) {
+ return true;
+ }
+
+ utils::findAndReplaceAll(el, toRemove, emptyString);
+ auto tokens = utils::split(el, ",");
+
+ if (tokens.size() == serviceDisabledTokenCount) {
+ parsed.push_back(ParsedCcfc(ConnectionClass::None, ForwardingStatus::NotActive, ""));
+ }
+ else if (tokens.size() > serviceDisabledTokenCount) {
+ int statusToken = 0;
+ int connectionClassToken = 0;
+
+ if (!utils::toNumeric(tokens[Tokens::Status], statusToken) ||
+ !utils::toNumeric(tokens[Tokens::Class], connectionClassToken)) {
+ return false;
+ }
+ auto status = static_cast<ForwardingStatus>(statusToken);
+ auto connectionClass = static_cast<ConnectionClass>(connectionClassToken);
+
+ if (magic_enum::enum_contains<ForwardingStatus>(status) &&
+ magic_enum::enum_contains<ConnectionClass>(connectionClass)) {
+ auto number = tokens[Tokens::Number];
+ utils::findAndReplaceAll(number, quote, emptyString);
+ utils::trim(number);
+ parsed.push_back(ParsedCcfc(connectionClass, status, number));
+ }
+ else {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ auto getNumbers(std::vector<ParsedCcfc> &parsed) -> CcfcNumbers
+ {
+ CcfcNumbers numbers;
+
+ for (auto el : parsed) {
+ std::string number = "";
+ if (el.status == ForwardingStatus::Active) {
+ number = el.number;
+ }
+ switch (el.connectionClass) {
+ case ConnectionClass::None:
+ break;
+ case ConnectionClass::Voice:
+ numbers.voice = number;
+ break;
+ case ConnectionClass::Data:
+ break;
+ case ConnectionClass::Fax:
+ numbers.fax = number;
+ break;
+ case ConnectionClass::AllTelephonyExceptSMS:
+ break;
+ case ConnectionClass::ShortMessgeService:
+ break;
+ case ConnectionClass::DataAsync:
+ numbers.async = number;
+ break;
+ case ConnectionClass::DataSync:
+ numbers.sync = number;
+ break;
+ }
+ }
+ return numbers;
+ }
+
+ auto isAnyActive(std::vector<ParsedCcfc> &parsed) -> bool
+ {
+ for (auto el : parsed) {
+ if (el.status == ForwardingStatus::Active) {
+ return true;
+ }
+ }
+ return false;
+ }
+ } // namespace ccfc
} // namespace response
} // namespace at
M module-cellular/at/response.hpp => module-cellular/at/response.hpp +56 -0
@@ 278,5 278,61 @@ namespace at
auto getStatus(const ServiceStatus &status)
-> app::manager::actions::IMMICustomResultParams::MMIResultMessage;
} // namespace clir
+
+ namespace ccfc
+ {
+
+ enum class ConnectionClass
+ {
+ None = 0,
+ Voice = 1,
+ Data = 2,
+ Fax = 4,
+ AllTelephonyExceptSMS = 7,
+ ShortMessgeService = 8,
+ DataAsync = 16,
+ DataSync = 32
+ };
+
+ enum class ForwardingStatus
+ {
+ NotActive,
+ Active
+ };
+
+ struct ParsedCcfc
+ {
+ ConnectionClass connectionClass;
+ ForwardingStatus status;
+ std::string number;
+
+ explicit ParsedCcfc(ConnectionClass connectionClass, ForwardingStatus status, const std::string &number)
+ : connectionClass(connectionClass), status(status), number(number)
+ {}
+ };
+
+ enum Tokens
+ {
+ Status,
+ Class,
+ Number,
+ Type
+ };
+
+ struct CcfcNumbers
+ {
+ std::string voice;
+ std::string fax;
+ std::string sync;
+ std::string async;
+ };
+
+ auto constexpr serviceDisabledTokenCount = 2;
+ auto constexpr serviceEnabledTokenCount = 4;
+
+ auto parse(std::vector<std::string> response, std::vector<ParsedCcfc> &parsed) -> bool;
+ auto getNumbers(std::vector<ParsedCcfc> &parsed) -> CcfcNumbers;
+ auto isAnyActive(std::vector<ParsedCcfc> &parsed) -> bool;
+ } // namespace ccfc
} // namespace response
} // namespace at
M module-services/service-appmgr/data/MmiActionsParams.cpp => module-services/service-appmgr/data/MmiActionsParams.cpp +1 -1
@@ 38,7 38,7 @@ auto MMICallForwardingResult::getData() const -> std::tuple<std::string, std::st
void MMICallForwardingResult::accept(Visitor &v, std::string &displayMessage)
{
v.visit(*this, displayMessage);
-};
+}
MMIParams::MMIParams(std::string mmiData) : mmiData{std::move(mmiData)}
{}
M module-services/service-appmgr/service-appmgr/data/MmiActionsParams.hpp => module-services/service-appmgr/service-appmgr/data/MmiActionsParams.hpp +5 -1
@@ 38,6 38,7 @@ namespace app::manager::actions
NoneSpecifiedSuccess,
NoneSpecifiedFailed,
CommonFailure,
+ CommonMMINotSupported,
CommonNoMessage,
ClirAccordingToSubscription,
@@ 49,6 50,7 @@ namespace app::manager::actions
ClirTemporaryRestricted,
ClirTemporaryAllowed,
+ // Call forwarding
RegistrationSuccessful,
RegistrationFailed,
ErasureSuccessful,
@@ 56,7 58,9 @@ namespace app::manager::actions
DisablingSuccessful,
DisablingFailed,
EnablingSuccessful,
- EnablingFailed
+ EnablingFailed,
+ CallForwardingDisabled
+
};
virtual auto getMessage() const -> std::vector<MMIResultMessage> = 0;
M module-services/service-cellular/CellularRequestHandler.cpp => module-services/service-cellular/CellularRequestHandler.cpp +68 -2
@@ 15,10 15,10 @@
#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-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>
@@ 118,6 118,72 @@ void CellularRequestHandler::handle(ClirRequest &request, at::Result &result)
sys::Bus::SendUnicast(msg, app::manager::ApplicationManager::ServiceName, &cellular);
request.setHandled(requestHandled);
}
+
+void CellularRequestHandler::handle(CallForwardingRequest &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::Registration) {
+ response =
+ std::make_shared<MMICallForwardingResult>(IMMICustomResultParams::MMIType::CallForwardingNotification);
+ response->addMessage(IMMICustomResultParams::MMIResultMessage::RegistrationSuccessful);
+ }
+ else if (procedureType == SupplementaryServicesRequest::ProcedureType::Deactivation) {
+ response =
+ std::make_shared<MMICallForwardingResult>(IMMICustomResultParams::MMIType::CallForwardingNotification);
+ response->addMessage(IMMICustomResultParams::MMIResultMessage::DisablingSuccessful);
+ }
+ else if (procedureType == SupplementaryServicesRequest::ProcedureType::Erasure) {
+ response =
+ std::make_shared<MMICallForwardingResult>(IMMICustomResultParams::MMIType::CallForwardingNotification);
+ response->addMessage(IMMICustomResultParams::MMIResultMessage::ErasureSuccessful);
+ }
+ else if (procedureType == SupplementaryServicesRequest::ProcedureType::Interrogation) {
+ std::vector<ccfc::ParsedCcfc> parsed;
+ if (at::response::ccfc::parse(result.response, parsed)) {
+ if (ccfc::isAnyActive(parsed)) {
+ auto numbers = ccfc::getNumbers(parsed);
+ response =
+ std::make_shared<MMICallForwardingResult>(IMMICustomResultParams::MMIType::CallForwardingData,
+ numbers.voice,
+ numbers.fax,
+ numbers.sync,
+ numbers.async);
+ }
+ else {
+ response = std::make_shared<MMICallForwardingResult>(
+ IMMICustomResultParams::MMIType::CallForwardingNotification);
+ response->addMessage(IMMICustomResultParams::MMIResultMessage::CallForwardingDisabled);
+ }
+ }
+ }
+ }
+
+ else {
+ if (result.code == at::Result::Code::ERROR &&
+ std::get<at::EquipmentErrorCode>(result.errorCode) == at::EquipmentErrorCode::PhoneBusy) {
+ response =
+ std::make_shared<MMICallForwardingResult>(IMMICustomResultParams::MMIType::CallForwardingNotification);
+ response->addMessage(IMMICustomResultParams::MMIResultMessage::CommonMMINotSupported);
+ }
+ }
+
+ if (response.get() == nullptr) {
+ response =
+ std::make_shared<MMICallForwardingResult>(IMMICustomResultParams::MMIType::CallForwardingNotification);
+ 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::CallForwardingRequest &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
@@ 15,6 15,7 @@ namespace cellular
class PinChangeRequest;
class ClipRequest;
class ClirRequest;
+ class CallForwardingRequest;
class RequestHandler
{
@@ 26,5 27,6 @@ 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(CallForwardingRequest &request, at::Result &result) = 0;
};
} // namespace cellular