M changelog.md => changelog.md +6 -0
@@ 1,5 1,11 @@
# MuditaOS changelog
+## [current release]
+
+### Added
+
+* `[cellular]` Added CLIR, CLIP, COLP, call waiting MMI support
+
## [0.47.1 2020-11-20]
### Added
M module-cellular/at/Commands.hpp => module-cellular/at/Commands.hpp +29 -7
@@ 16,6 16,7 @@ namespace at
inline const uint32_t default_timeout = 5000; /// if unsure - take this
inline const uint32_t default_doc_timeout =
300; /// if you've checked it's ok - or it was at least 300 in code somewhere, take this
+ inline const uint32_t default_long_doc_timeout = 15000;
/// at::Cmd structure with command, it's timeout and some runtime data
/// { command, timeout, last : {sent, response, status } }
@@ 137,9 138,19 @@ namespace at
GET_IMEI,
CCFC, /// Supplementary Services - Call Forwarding Number and Conditions Control
CCWA, /// Supplementary Services - Call Waiting Control
+ CCWA_GET,
CHLD, /// Supplementary Services - Call Related Supplementary Services
+ CLIP, /// Supplementary Services - Calling Line Identification Restriction
+ CLIP_GET,
CLIR, /// Supplementary Services - Calling Line Identification Restriction
+ CLIR_GET,
+ CLIR_ENABLE,
+ CLIR_DISABLE,
+ CLIR_RESET,
COLP, /// Supplementary Services - Connected Line Identification Presentation
+ COLP_GET,
+ COLP_ENABLE,
+ COLP_DISABLE,
CSSN, /// Supplementary Services - Supplementary Service Notifications
};
@@ 183,11 194,11 @@ namespace at
{AT::ATD, {"ATD"}},
{AT::IPR, {"AT+IPR="}},
{AT::CMUX, {"AT+CMUX="}},
- {AT::CFUN, {"AT+CFUN=", 15000}},
- {AT::CFUN_RESET, {"AT+CFUN=1,1", 15000}},
- {AT::CFUN_MIN_FUNCTIONALITY, {"AT+CFUN=0", 15000}},
- {AT::CFUN_FULL_FUNCTIONALITY, {"AT+CFUN=1", 15000}},
- {AT::CFUN_DISABLE_TRANSMITTING, {"AT+CFUN=4", 15000}},
+ {AT::CFUN, {"AT+CFUN=", default_long_doc_timeout}},
+ {AT::CFUN_RESET, {"AT+CFUN=1,1", default_long_doc_timeout}},
+ {AT::CFUN_MIN_FUNCTIONALITY, {"AT+CFUN=0", default_long_doc_timeout}},
+ {AT::CFUN_FULL_FUNCTIONALITY, {"AT+CFUN=1", default_long_doc_timeout}},
+ {AT::CFUN_DISABLE_TRANSMITTING, {"AT+CFUN=4", default_long_doc_timeout}},
{AT::CMGS, {"AT+CMGS=\""}},
{AT::QCMGS, {"AT+QCMGS=\""}},
{AT::CREG, {"AT+CREG?", default_doc_timeout}},
@@ 223,9 234,20 @@ namespace at
{AT::LIST_MESSAGES, {"AT+CMGL=\"ALL\"", default_doc_timeout}},
{AT::GET_IMEI, {"AT+GSN", default_doc_timeout}},
{AT::CCFC, {"AT+CCFC=", default_doc_timeout}},
- {AT::CCWA, {"AT+CCWA=\"", default_doc_timeout}},
+ {AT::CCWA, {"AT+CCWA=", default_doc_timeout}},
+ {AT::CCWA_GET, {"AT+CCWA?", default_doc_timeout}},
{AT::CHLD, {"AT+CHLD=\"", default_doc_timeout}},
- {AT::COLP, {"AT+COLP=\"", default_doc_timeout}},
+ {AT::CLIP, {"AT+CLIP=", default_long_doc_timeout}},
+ {AT::CLIP_GET, {"AT+CLIP?", default_long_doc_timeout}},
+ {AT::CLIR, {"AT+CLIR=", default_long_doc_timeout}},
+ {AT::CLIR_GET, {"AT+CLIR?", default_long_doc_timeout}},
+ {AT::CLIR_RESET, {"AT+CLIR=0", default_long_doc_timeout}},
+ {AT::CLIR_ENABLE, {"AT+CLIR=1", default_long_doc_timeout}},
+ {AT::CLIR_DISABLE, {"AT+CLIR=2", default_long_doc_timeout}},
+ {AT::COLP, {"AT+COLP", default_long_doc_timeout}},
+ {AT::COLP_GET, {"AT+COLP?", default_long_doc_timeout}},
+ {AT::COLP_ENABLE, {"AT+COLP=1", default_long_doc_timeout}},
+ {AT::COLP_DISABLE, {"AT+COLP=0", default_long_doc_timeout}},
{AT::CSSN, {"AT+CSSN=\"", default_doc_timeout}}};
if (fact.count(at)) {
M module-services/service-cellular/CMakeLists.txt => module-services/service-cellular/CMakeLists.txt +5 -0
@@ 18,8 18,13 @@ set(SOURCES
requests/PinChangeRequest.cpp
requests/ImeiRequest.cpp
requests/UssdRequest.cpp
+ requests/ClipRequest.cpp
+ requests/ClirRequest.cpp
+ requests/ColpRequest.cpp
+ requests/CallWaitingRequest.cpp
)
+
add_library(${PROJECT_NAME} STATIC ${SOURCES})
target_include_directories(${PROJECT_NAME}
M module-services/service-cellular/requests/CallForwardingRequest.cpp => module-services/service-cellular/requests/CallForwardingRequest.cpp +12 -5
@@ 37,18 37,21 @@ namespace cellular
auto CallForwardingRequest::command() -> std::string
{
- std::array<std::function<std::string()>, 2> commandParts = {
+ std::array<std::function<std::string()>, 3> commandParts = {
+ [this]() { return this->getCommandReason(); },
[this]() { return this->getCommandMode(); },
[this]() { return this->getCommandNumber(); },
};
- std::string cmd(at::factory(at::AT::CCFC) + this->getCommandReason());
+ std::string cmd(at::factory(at::AT::CCFC));
+ bool formatFirst = true;
for (auto &cmdPart : commandParts) {
auto partStr = cmdPart();
if (partStr.empty()) {
- break;
+ continue;
}
- cmd.append("," + partStr);
+ cmd.append(formatFirst ? partStr : "," + partStr);
+ formatFirst = false;
}
return cmd;
@@ 82,7 85,11 @@ namespace cellular
auto CallForwardingRequest::getCommandClass() const -> std::string
{
- return getCommandInformationClass(basicServiceGroup);
+ if (basicServiceGroup.empty()) {
+ return std::string();
+ }
+
+ return getCommandInformationClass(basicServiceGroup).value_or(std::string());
}
auto CallForwardingRequest::getCommandSubAddr() const -> std::string
A module-services/service-cellular/requests/CallWaitingRequest.cpp => module-services/service-cellular/requests/CallWaitingRequest.cpp +85 -0
@@ 0,0 1,85 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <string>
+
+#include <at/Commands.hpp>
+#include <Utils.hpp>
+
+#include "service-cellular/requests/CallWaitingRequest.hpp"
+
+namespace cellular
+{
+
+ std::unique_ptr<SupplementaryServicesRequest> CallWaitingRequest::create(const std::string &serviceCode,
+ const std::string &data,
+ GroupMatch matchGroups)
+ {
+ if (serviceCode == callWaitingServiceCode) {
+ return std::make_unique<CallWaitingRequest>(data, matchGroups);
+ }
+ else {
+ return nullptr;
+ }
+ }
+
+ auto CallWaitingRequest::command() -> std::string
+ {
+ if (!isValid()) {
+ return std::string();
+ }
+
+ std::array<std::function<std::string()>, 3> commandParts = {
+ [this]() { return this->getCommandPresentation(); },
+ [this]() { return this->getCommandMode(); },
+ [this]() { return this->getCommandClass(); },
+ };
+
+ std::string cmd(at::factory(at::AT::CCWA));
+ bool formatFirst = true;
+ for (auto &cmdPart : commandParts) {
+ auto partStr = cmdPart();
+ if (partStr.empty()) {
+ continue;
+ }
+ cmd.append(formatFirst ? partStr : "," + partStr);
+ formatFirst = false;
+ }
+
+ return cmd;
+ }
+
+ auto CallWaitingRequest::getCommandPresentation() const noexcept -> std::string
+ {
+ // fixed, we always want full report
+ return unsolicitedResultCodeEnable;
+ }
+
+ auto CallWaitingRequest::getCommandMode() const noexcept -> std::string
+ {
+ return utils::to_string(magic_enum::enum_integer(procedureType));
+ }
+
+ auto CallWaitingRequest::getCommandClass() const noexcept -> std::string
+ {
+ if (basicServiceGroup.empty()) {
+ return std::string();
+ }
+
+ return getCommandInformationClass(basicServiceGroup).value_or(std::string());
+ }
+
+ void CallWaitingRequest::handle(RequestHandler &h, at::Result &result)
+ {
+ h.handle(*this, result);
+ }
+
+ auto CallWaitingRequest::isValid() const noexcept -> bool
+ {
+ if (!getCommandInformationClass(basicServiceGroup).has_value()) {
+ return false;
+ }
+ return procedureType != ProcedureType::Registration && procedureType != ProcedureType::Erasure;
+ }
+
+} // namespace cellular
A module-services/service-cellular/requests/ClipRequest.cpp => module-services/service-cellular/requests/ClipRequest.cpp +41 -0
@@ 0,0 1,41 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <string>
+
+#include <at/Commands.hpp>
+#include <Utils.hpp>
+
+#include "service-cellular/requests/ClipRequest.hpp"
+
+namespace cellular
+{
+
+ std::unique_ptr<SupplementaryServicesRequest> ClipRequest::create(const std::string &serviceCode,
+ const std::string &data,
+ GroupMatch matchGroups)
+ {
+ if (serviceCode == clipServiceCode) {
+ return std::make_unique<ClipRequest>(data, matchGroups);
+ }
+ else {
+ return nullptr;
+ }
+ }
+
+ auto ClipRequest::command() -> std::string
+ {
+ return isValid() ? std::string(at::factory(at::AT::CLIP_GET)) : std::string();
+ }
+
+ auto ClipRequest::isValid() const noexcept -> bool
+ {
+ return procedureType == ProcedureType::Interrogation;
+ }
+
+ void ClipRequest::handle(RequestHandler &h, at::Result &result)
+ {
+ h.handle(*this, result);
+ }
+
+} // namespace cellular
A module-services/service-cellular/requests/ClirRequest.cpp => module-services/service-cellular/requests/ClirRequest.cpp +55 -0
@@ 0,0 1,55 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <string>
+
+#include <at/Commands.hpp>
+#include <Utils.hpp>
+
+#include "service-cellular/requests/ClirRequest.hpp"
+
+namespace cellular
+{
+
+ std::unique_ptr<SupplementaryServicesRequest> ClirRequest::create(const std::string &serviceCode,
+ const std::string &data,
+ GroupMatch matchGroups)
+ {
+ if (serviceCode == clirServiceCode) {
+ return std::make_unique<ClirRequest>(data, matchGroups);
+ }
+ else {
+ return nullptr;
+ }
+ }
+
+ auto ClirRequest::command() -> std::string
+ {
+ switch (procedureType) {
+ case ProcedureType::Deactivation:
+ return std::string(at::factory(at::AT::CLIR_DISABLE));
+ case ProcedureType::Activation:
+ return std::string(at::factory(at::AT::CLIR_ENABLE));
+ case ProcedureType::Interrogation:
+ return std::string(at::factory(at::AT::CLIR_GET));
+ case ProcedureType::Registration:
+ // not supported
+ return std::string();
+ case ProcedureType::Erasure:
+ // not supported
+ return std::string();
+ }
+ return std::string();
+ }
+
+ void ClirRequest::handle(RequestHandler &h, at::Result &result)
+ {
+ h.handle(*this, result);
+ }
+
+ auto ClirRequest::isValid() const noexcept -> bool
+ {
+ return procedureType != ProcedureType::Registration && procedureType != ProcedureType::Erasure;
+ }
+
+} // namespace cellular
A module-services/service-cellular/requests/ColpRequest.cpp => module-services/service-cellular/requests/ColpRequest.cpp +55 -0
@@ 0,0 1,55 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <string>
+
+#include <at/Commands.hpp>
+#include <Utils.hpp>
+
+#include "service-cellular/requests/ColpRequest.hpp"
+
+namespace cellular
+{
+
+ std::unique_ptr<SupplementaryServicesRequest> ColpRequest::create(const std::string &serviceCode,
+ const std::string &data,
+ GroupMatch matchGroups)
+ {
+ if (serviceCode == colpServiceCode) {
+ return std::make_unique<ColpRequest>(data, matchGroups);
+ }
+ else {
+ return nullptr;
+ }
+ }
+
+ auto ColpRequest::command() -> std::string
+ {
+ switch (procedureType) {
+ case ProcedureType::Deactivation:
+ return std::string(at::factory(at::AT::COLP_DISABLE));
+ case ProcedureType::Activation:
+ return std::string(at::factory(at::AT::COLP_ENABLE));
+ case ProcedureType::Interrogation:
+ return std::string(at::factory(at::AT::COLP_GET));
+ case ProcedureType::Registration:
+ // not supported
+ return std::string();
+ case ProcedureType::Erasure:
+ // not supported
+ return std::string();
+ }
+ return std::string();
+ }
+
+ void ColpRequest::handle(RequestHandler &h, at::Result &result)
+ {
+ h.handle(*this, result);
+ }
+
+ auto ColpRequest::isValid() const noexcept -> bool
+ {
+ return procedureType != ProcedureType::Registration && procedureType != ProcedureType::Erasure;
+ }
+
+} // namespace cellular
M module-services/service-cellular/requests/PasswordRegistrationRequest.cpp => module-services/service-cellular/requests/PasswordRegistrationRequest.cpp +4 -0
@@ 46,6 46,10 @@ namespace cellular
[this]() { return "," + this->getNewPassword(); },
};
+ if (!isValid()) {
+ return std::string();
+ }
+
std::string cmd(at::factory(at::AT::CPWD));
for (auto &cmdPart : commandParts) {
cmd.append(cmdPart());
M module-services/service-cellular/requests/PinChangeRequest.cpp => module-services/service-cellular/requests/PinChangeRequest.cpp +4 -0
@@ 49,6 49,10 @@ namespace cellular
[this]() { return "," + this->getNewPin(); },
};
+ if (!isValid()) {
+ return std::string();
+ }
+
std::string cmd;
switch (passChangeType) {
case PassChangeType::ChangePin:
M module-services/service-cellular/requests/SupplementaryServicesRequest.cpp => module-services/service-cellular/requests/SupplementaryServicesRequest.cpp +77 -9
@@ 5,10 5,14 @@
#include <memory>
#include <at/Commands.hpp>
+#include <Utils.hpp>
#include "service-cellular/requests/SupplementaryServicesRequest.hpp"
#include "service-cellular/requests/CallForwardingRequest.hpp"
-#include "service-cellular/requests/PasswordRegistrationRequest.hpp"
+#include "service-cellular/requests/ClipRequest.hpp"
+#include "service-cellular/requests/ClirRequest.hpp"
+#include "service-cellular/requests/ColpRequest.hpp"
+#include "service-cellular/requests/CallWaitingRequest.hpp"
namespace
{
@@ 50,6 54,10 @@ namespace cellular
auto factoryList = {
CallForwardingRequest::create,
+ CallWaitingRequest::create,
+ ClipRequest::create,
+ ClirRequest::create,
+ ColpRequest::create,
};
for (auto &createCb : factoryList) {
@@ 62,19 70,79 @@ namespace cellular
}
auto SupplementaryServicesRequest::getCommandInformationClass(const std::string &basicServiceGroup) const
- -> std::string
+ -> std::optional<std::string>
{
// according to EC25&EC21_AT_Commands_Manual_V1.3
- if (basicServiceGroup == basicServiceVoice) {
- return atInformationClassVoice;
+ int basicGroup = 0;
+ int informationClass = 0;
+
+ if (basicServiceGroup.empty()) {
+ // according to 3GPP TS 22.030 V16.0.0 Annex C
+ informationClass = atInformationClassAllTele + atInformationClassAllBearer;
}
- else if (basicServiceGroup == basicServiceVoiceFax) {
- return atInformationClassFax;
+ else {
+ utils::toNumeric(basicServiceGroup, basicGroup);
+ auto service = magic_enum::enum_cast<TeleAndBearerService>(basicGroup);
+
+ if (!service.has_value()) {
+ return std::nullopt;
+ }
+
+ switch (service.value()) {
+ // according to 3GPP TS 22.030 V16.0.0 Annex C
+ case TeleAndBearerService::AllTeleServices:
+ informationClass = atInformationClassAllTele;
+ break;
+ case TeleAndBearerService::Telephony:
+ informationClass = atInformationClassVoice;
+ break;
+ case TeleAndBearerService::AllDataTeleServices:
+ informationClass = atInformationClassAllDataTele;
+ break;
+ case TeleAndBearerService::FacsimileServices:
+ informationClass = atInformationClassFax;
+ break;
+ case TeleAndBearerService::ShortMessageServices:
+ informationClass = atInformationClassSms;
+ break;
+ case TeleAndBearerService::AllTeleServicesExceptSms:
+ informationClass = atInformationClassAllTele - atInformationClassSms;
+ break;
+ case TeleAndBearerService::VoiceGroupCallService:
+ LOG_INFO("Unsupported information class: 17 - Voice Group Call Service");
+ break;
+ case TeleAndBearerService::VoiceBroadcastService:
+ LOG_INFO("Unsupported information class: 18 - Voice Broadcast Service");
+ break;
+ case TeleAndBearerService::AllBearerServices:
+ informationClass = atInformationClassAllBearer;
+ break;
+ case TeleAndBearerService::AllAsyncServices:
+ informationClass = atInformationClassDataAsync;
+ break;
+ case TeleAndBearerService::AllSyncServices:
+ informationClass = atInformationClassDataSync;
+ break;
+ case TeleAndBearerService::AllDataCircuitSync:
+ informationClass = atInformationClassDataSync;
+ break;
+ case TeleAndBearerService::AllDataCircuitAsync:
+ informationClass = atInformationClassDataAsync;
+ break;
+ case TeleAndBearerService::AllGprsBearerServices:
+ LOG_INFO("Unsupported information class: 99 - All Gprs Bearer Services");
+ break;
+ case TeleAndBearerService::TelephonyAndAllSyncServices:
+ informationClass = atInformationClassVoice + atInformationClassDataSync;
+ break;
+ }
}
- else if (basicServiceGroup == basicServiceVoiceData) {
- return atInformationClassData;
+
+ if (informationClass == 0) {
+ return std::nullopt;
}
- return atInformationClassAllButSms;
+
+ return utils::to_string(informationClass);
}
}; // namespace cellular
A module-services/service-cellular/service-cellular/requests/CallWaitingRequest.hpp => module-services/service-cellular/service-cellular/requests/CallWaitingRequest.hpp +35 -0
@@ 0,0 1,35 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "SupplementaryServicesRequest.hpp"
+
+namespace cellular
+{
+ class CallWaitingRequest : public SupplementaryServicesRequest
+ {
+ public:
+ CallWaitingRequest(const std::string &data, GroupMatch matchGroups)
+ : SupplementaryServicesRequest(data, matchGroups)
+ {}
+
+ static std::unique_ptr<SupplementaryServicesRequest> create(const std::string &serviceCode,
+ const std::string &data,
+ GroupMatch matchGroups);
+
+ auto command() -> std::string final;
+ void handle(RequestHandler &h, at::Result &result) final;
+ auto isValid() const noexcept -> bool final;
+
+ auto getCommandPresentation() const noexcept -> std::string;
+ auto getCommandMode() const noexcept -> std::string;
+ auto getCommandClass() const noexcept -> std::string;
+
+ private:
+ static constexpr auto callWaitingServiceCode = "43";
+ static constexpr auto unsolicitedResultCodeEnable = "1";
+
+ std::string &basicServiceGroup = supplementaryInfoA;
+ };
+}; // namespace cellular
A module-services/service-cellular/service-cellular/requests/ClipRequest.hpp => module-services/service-cellular/service-cellular/requests/ClipRequest.hpp +27 -0
@@ 0,0 1,27 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "SupplementaryServicesRequest.hpp"
+
+namespace cellular
+{
+ class ClipRequest : public SupplementaryServicesRequest
+ {
+ public:
+ ClipRequest(const std::string &data, GroupMatch matchGroups) : SupplementaryServicesRequest(data, matchGroups)
+ {}
+
+ static std::unique_ptr<SupplementaryServicesRequest> create(const std::string &serviceCode,
+ const std::string &data,
+ GroupMatch matchGroups);
+
+ auto command() -> std::string final;
+ void handle(RequestHandler &h, at::Result &result) final;
+ auto isValid() const noexcept -> bool final;
+
+ private:
+ static constexpr auto clipServiceCode = "30";
+ };
+}; // namespace cellular
A module-services/service-cellular/service-cellular/requests/ClirRequest.hpp => module-services/service-cellular/service-cellular/requests/ClirRequest.hpp +27 -0
@@ 0,0 1,27 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "SupplementaryServicesRequest.hpp"
+
+namespace cellular
+{
+ class ClirRequest : public SupplementaryServicesRequest
+ {
+ public:
+ ClirRequest(const std::string &data, GroupMatch matchGroups) : SupplementaryServicesRequest(data, matchGroups)
+ {}
+
+ static std::unique_ptr<SupplementaryServicesRequest> create(const std::string &serviceCode,
+ const std::string &data,
+ GroupMatch matchGroups);
+
+ auto command() -> std::string final;
+ void handle(RequestHandler &h, at::Result &result) final;
+ auto isValid() const noexcept -> bool final;
+
+ private:
+ static constexpr auto clirServiceCode = "31";
+ };
+}; // namespace cellular
A module-services/service-cellular/service-cellular/requests/ColpRequest.hpp => module-services/service-cellular/service-cellular/requests/ColpRequest.hpp +27 -0
@@ 0,0 1,27 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "SupplementaryServicesRequest.hpp"
+
+namespace cellular
+{
+ class ColpRequest : public SupplementaryServicesRequest
+ {
+ public:
+ ColpRequest(const std::string &data, GroupMatch matchGroups) : SupplementaryServicesRequest(data, matchGroups)
+ {}
+
+ static std::unique_ptr<SupplementaryServicesRequest> create(const std::string &serviceCode,
+ const std::string &data,
+ GroupMatch matchGroups);
+
+ auto command() -> std::string final;
+ void handle(RequestHandler &h, at::Result &result) final;
+ auto isValid() const noexcept -> bool final;
+
+ private:
+ static constexpr auto colpServiceCode = "76";
+ };
+}; // namespace cellular
M module-services/service-cellular/service-cellular/requests/SupplementaryServicesRequest.hpp => module-services/service-cellular/service-cellular/requests/SupplementaryServicesRequest.hpp +41 -13
@@ 34,13 34,14 @@ namespace cellular
static std::unique_ptr<SupplementaryServicesRequest> create(const std::string &data, GroupMatch matchGroups);
SupplementaryServicesRequest(const std::string &data, GroupMatch matchGroups);
+ // according to 3GPP TS 22.030 V16.0.0
enum class ProcedureType
{
- Deactivation,
- Activation,
- Interrogation,
- Registration,
- Erasure
+ Deactivation, ///< MMI string starts with #
+ Activation, ///< MMI string starts with *
+ Interrogation, ///< MMI string starts with *#
+ Registration, ///< MMI string starts with **
+ Erasure ///< MMI string starts with ##
};
protected:
@@ 51,15 52,42 @@ namespace cellular
std::string supplementaryInfoC;
ProcedureType procedureType;
- static constexpr inline auto atInformationClassVoice = "1";
- static constexpr inline auto atInformationClassData = "2";
- static constexpr inline auto atInformationClassFax = "4";
- static constexpr inline auto atInformationClassAllButSms = "7";
+ // according to EC25&EC21_AT_Commands_Manual_V1.3
+ static constexpr inline auto atInformationClassVoice = 1 << 0;
+ static constexpr inline auto atInformationClassData = 1 << 1;
+ static constexpr inline auto atInformationClassFax = 1 << 2;
+ static constexpr inline auto atInformationClassSms = 1 << 3;
+ static constexpr inline auto atInformationClassDataSync = 1 << 4;
+ static constexpr inline auto atInformationClassDataAsync = 1 << 5;
- static constexpr inline auto basicServiceVoice = "11";
- static constexpr inline auto basicServiceVoiceData = "25";
- static constexpr inline auto basicServiceVoiceFax = "13";
+ static constexpr inline auto atInformationClassAllTele =
+ atInformationClassVoice + atInformationClassFax + atInformationClassSms;
+ static constexpr inline auto atInformationClassAllDataTele = atInformationClassFax + atInformationClassSms;
+ static constexpr inline auto atInformationClassAllBearer =
+ atInformationClassDataSync + atInformationClassDataAsync + atInformationClassData;
- auto getCommandInformationClass(const std::string &basicServiceGroup) const -> std::string;
+ // according to 3GPP TS 22.030 V16.0.0
+ enum class TeleAndBearerService
+ {
+ AllTeleServices = 10,
+ Telephony = 11,
+ AllDataTeleServices = 12,
+ FacsimileServices = 13,
+ ShortMessageServices = 16,
+ AllTeleServicesExceptSms = 19,
+
+ VoiceGroupCallService = 17,
+ VoiceBroadcastService = 18,
+
+ AllBearerServices = 20,
+ AllAsyncServices = 21,
+ AllSyncServices = 22,
+ AllDataCircuitSync = 24,
+ AllDataCircuitAsync = 25,
+ AllGprsBearerServices = 99,
+ TelephonyAndAllSyncServices = 26,
+ };
+
+ auto getCommandInformationClass(const std::string &basicServiceGroup) const -> std::optional<std::string>;
};
}; // namespace cellular
M module-services/service-cellular/tests/unittest_mmi.cpp => module-services/service-cellular/tests/unittest_mmi.cpp +85 -2
@@ 6,10 6,14 @@
#include <catch2/catch.hpp>
#include <service-cellular/RequestFactory.hpp>
#include <service-cellular/requests/CallForwardingRequest.hpp>
+#include <service-cellular/requests/CallWaitingRequest.hpp>
#include <service-cellular/requests/PasswordRegistrationRequest.hpp>
#include <service-cellular/requests/PinChangeRequest.hpp>
#include <service-cellular/requests/ImeiRequest.hpp>
#include <service-cellular/requests/UssdRequest.hpp>
+#include <service-cellular/requests/ClipRequest.hpp>
+#include <service-cellular/requests/ClirRequest.hpp>
+#include <service-cellular/requests/ColpRequest.hpp>
using namespace cellular;
@@ 24,9 28,85 @@ TEST_CASE("MMI requests")
};
std::vector<TestCase> testCases = {
- /// IMEIRequest
+ /// ImeiRequest
{R"(*#06#)", R"(AT+GSN)", typeid(ImeiRequest)},
+ /// ClipRequest
+ // bad procedure type
+ {R"(*30#)", std::string(), typeid(ClipRequest), false},
+ // query
+ {R"(*#30#)", R"(AT+CLIP?)", typeid(ClipRequest)},
+ // bad procedure type
+ {R"(##30#)", std::string(), typeid(ClipRequest), false},
+ // bad procedure type
+ {R"(#30#)", std::string(), typeid(ClipRequest), false},
+ // bad procedure type
+ {R"(**30#)", std::string(), typeid(ClipRequest), false},
+ // temporary mode enable
+ {R"(*30#600700800)", std::string(), typeid(CallRequest)},
+ // temporary mode disable
+ {R"(#30#600700800)", std::string(), typeid(CallRequest)},
+
+ /// ClirRequest
+ // bad procedure type
+ {R"(*31#)", R"(AT+CLIR=1)", typeid(ClirRequest)},
+ // query
+ {R"(*#31#)", R"(AT+CLIR?)", typeid(ClirRequest)},
+ // bad procedure type
+ {R"(##31#)", std::string(), typeid(ClirRequest), false},
+ // bad procedure type
+ {R"(#31#)", R"(AT+CLIR=2)", typeid(ClirRequest)},
+ // bad procedure type
+ {R"(**31#)", std::string(), typeid(ClirRequest), false},
+
+ /// ColpRequest
+ // bad procedure type
+ {R"(*76#)", R"(AT+COLP=1)", typeid(ColpRequest)},
+ // query
+ {R"(*#76#)", R"(AT+COLP?)", typeid(ColpRequest)},
+ // bad procedure type
+ {R"(##76#)", std::string(), typeid(ColpRequest), false},
+ // bad procedure type
+ {R"(#76#)", R"(AT+COLP=0)", typeid(ColpRequest)},
+ // bad procedure type
+ {R"(**76#)", std::string(), typeid(ColpRequest), false},
+
+ /// CallWaitingRequest
+ // enable all
+ {R"(*43#)", R"(AT+CCWA=1,1)", typeid(CallWaitingRequest)},
+ // enable all
+ {R"(*43*#)", R"(AT+CCWA=1,1)", typeid(CallWaitingRequest)},
+ // enable all tele services
+ {R"(*43*10#)", R"(AT+CCWA=1,1,13)", typeid(CallWaitingRequest)},
+ // enable voice
+ {R"(*43*11#)", R"(AT+CCWA=1,1,1)", typeid(CallWaitingRequest)},
+ // enable data
+ {R"(*43*12#)", R"(AT+CCWA=1,1,12)", typeid(CallWaitingRequest)},
+ // enable fax
+ {R"(*43*13#)", R"(AT+CCWA=1,1,4)", typeid(CallWaitingRequest)},
+ // enable sms
+ {R"(*43*16#)", R"(AT+CCWA=1,1,8)", typeid(CallWaitingRequest)},
+ // enable all tele except sms
+ {R"(*43*19#)", R"(AT+CCWA=1,1,5)", typeid(CallWaitingRequest)},
+ // enable all bearer
+ {R"(*43*20#)", R"(AT+CCWA=1,1,50)", typeid(CallWaitingRequest)},
+ // enable data circuit sync
+ {R"(*43*24#)", R"(AT+CCWA=1,1,16)", typeid(CallWaitingRequest)},
+ // enable data circuit async
+ {R"(*43*25#)", R"(AT+CCWA=1,1,32)", typeid(CallWaitingRequest)},
+ // disable all
+ {R"(#43#)", R"(AT+CCWA=1,0)", typeid(CallWaitingRequest)},
+ // query all
+ {R"(*#43#)", R"(AT+CCWA=1,2)", typeid(CallWaitingRequest)},
+ // bad procedure **
+ {R"(**43#)", std::string(), typeid(CallWaitingRequest), false},
+ // bad procedure ##
+ {R"(##43#)", std::string(), typeid(CallWaitingRequest), false},
+ // bad service group
+ {R"(*43*17#)", std::string(), typeid(CallWaitingRequest), false},
+ // bad service group
+ {R"(*43*17#)", std::string(), typeid(CallWaitingRequest), false},
+
/// CallForwardingRequest
// all diversions
{R"(##002#)", R"(AT+CCFC=4,4)", typeid(CallForwardingRequest)},
@@ 134,8 214,11 @@ TEST_CASE("MMI requests")
INFO("Failed on testcase: " << testCase.requestString);
REQUIRE(typeid(*request.get()).name() == testCase.expectedType.name());
REQUIRE(request->isValid() == testCase.expectedValid);
- if (typeid(*request.get()).name() != typeid(CallRequest).name() && request->isValid()) {
+ if (typeid(*request.get()).name() != typeid(CallRequest).name()) {
REQUIRE(requestCommand == testCase.expectedCommandString);
}
+ else {
+ REQUIRE(requestCommand == "ATD" + testCase.requestString + ";");
+ }
}
}