M module-cellular/CMakeLists.txt => module-cellular/CMakeLists.txt +1 -0
@@ 40,6 40,7 @@ set(SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/at/cmd/src/QNWINFO.cpp
${CMAKE_CURRENT_SOURCE_DIR}/at/cmd/src/QSIMSTAT.cpp
${CMAKE_CURRENT_SOURCE_DIR}/at/cmd/src/QCFGUsbnet.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/at/cmd/src/CSQ.cpp
)
add_library(${PROJECT_NAME} STATIC ${SOURCES})
A module-cellular/at/cmd/CSQ.hpp => module-cellular/at/cmd/CSQ.hpp +43 -0
@@ 0,0 1,43 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "Result.hpp"
+#include <at/Cmd.hpp>
+#include <functional>
+
+namespace at
+{
+ namespace csq
+ {
+ constexpr auto tokensCount = 2;
+
+ enum class Tokens
+ {
+ Csq,
+ Ber
+ };
+ } // namespace csq
+ namespace result
+ {
+ struct CSQ : public Result
+ {
+ uint32_t csq;
+ uint32_t ber;
+ explicit CSQ(const Result &);
+ };
+ } // namespace result
+
+ namespace cmd
+ {
+ class CSQ : public Cmd
+ {
+ public:
+ CSQ() noexcept;
+ explicit CSQ(at::cmd::Modifier mod) noexcept;
+ [[nodiscard]] auto parseCSQ(const Result &base_result) -> result::CSQ;
+ };
+ } // namespace cmd
+
+} // namespace at
A module-cellular/at/cmd/src/CSQ.cpp => module-cellular/at/cmd/src/CSQ.cpp +77 -0
@@ 0,0 1,77 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <log/log.hpp>
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <at/cmd/CSQ.hpp>
+#include <chrono>
+
+namespace at
+{
+ namespace cmd
+ {
+ using namespace std::chrono_literals;
+ CSQ::CSQ(at::cmd::Modifier mod) noexcept : Cmd("AT+CSQ", mod, 300ms)
+ {}
+
+ CSQ::CSQ() noexcept : CSQ(at::cmd::Modifier::None)
+ {}
+
+ result::CSQ CSQ::parseCSQ(const Result &base_result)
+ {
+ auto constexpr responseHeader = "+CSQ: ";
+
+ result::CSQ p{base_result};
+ // use parent operator bool
+ if (p.Result::operator bool()) {
+ if (p.response.empty()) {
+ LOG_ERROR("Can't parse - empty response");
+ p.code = result::CSQ::Code::PARSING_ERROR;
+
+ return p;
+ }
+
+ std::string str = p.response[0];
+ if (str.find(responseHeader) == std::string::npos) {
+ LOG_ERROR("Can't parse - bad header");
+ p.code = result::CSQ::Code::PARSING_ERROR;
+ return p;
+ }
+
+ utils::findAndReplaceAll(str, responseHeader, "");
+ utils::trim(str);
+
+ std::vector<std::string> tokens = utils::split(str, ',');
+ if (tokens.size() != csq::tokensCount) {
+ LOG_ERROR("Can't parse - wrong token count");
+ p.code = result::CSQ::Code::PARSING_ERROR;
+ return p;
+ }
+
+ auto csq = 0;
+ auto ber = 0;
+ if (utils::toNumeric(tokens.at(magic_enum::enum_integer(csq::Tokens::Csq)), csq) &&
+ utils::toNumeric(tokens.at(magic_enum::enum_integer(csq::Tokens::Ber)), ber)) {
+ p.csq = csq;
+ p.ber = ber;
+ }
+ else {
+ LOG_ERROR("Can't parse - bad value");
+ p.code = result::CSQ::Code::PARSING_ERROR;
+ }
+ }
+
+ return p;
+ }
+
+ } // namespace cmd
+
+ namespace result
+ {
+ CSQ::CSQ(const Result &that) : Result(that)
+ {}
+
+ } // namespace result
+} // namespace at
M module-cellular/test/mock/AtCommon_channel.hpp => module-cellular/test/mock/AtCommon_channel.hpp +51 -0
@@ 566,4 566,55 @@ namespace at
return result;
}
};
+
+ /// provides invalid QSIMSTAT response
+ class QSIMSTAT_tooFewTokens : public ChannelMock
+ {
+ public:
+ auto ResultMock() -> Result final
+ {
+ auto result = Result();
+ result.code = Result::Code::OK;
+ result.response = {"+QCFG: \"usbnet\",", "OK"};
+ return result;
+ }
+ };
+
+ /// provides proper CSQ response
+ class CSQ_successChannel : public ChannelMock
+ {
+ public:
+ auto ResultMock() -> Result final
+ {
+ auto result = Result();
+ result.code = Result::Code::OK;
+ result.response = {"+CSQ: 28,99", "OK"};
+ return result;
+ }
+ };
+
+ /// provides invalid CSQ response
+ class CSQ_tooFewTokens : public ChannelMock
+ {
+ public:
+ auto ResultMock() -> Result final
+ {
+ auto result = Result();
+ result.code = Result::Code::OK;
+ result.response = {"+CSQ: 28", "OK"};
+ return result;
+ }
+ };
+ /// provides invalid CSQ response
+ class CSQ_toManyTokens : public ChannelMock
+ {
+ public:
+ auto ResultMock() -> Result final
+ {
+ auto result = Result();
+ result.code = Result::Code::OK;
+ result.response = {"+CSQ: 28,99,43", "OK"};
+ return result;
+ }
+ };
} // namespace at
M module-cellular/test/unittest_parse_result.cpp => module-cellular/test/unittest_parse_result.cpp +56 -1
@@ 15,7 15,7 @@
#include <at/cmd/QNWINFO.hpp>
#include <at/cmd/QSIMSTAT.hpp>
#include <at/cmd/QCFGUsbnet.hpp>
-
+#include <at/cmd/CSQ.hpp>
#include "mock/AtCommon_channel.hpp"
#include "PhoneNumber.hpp"
#include "Result.hpp"
@@ 815,3 815,58 @@ TEST_CASE("QCFGUsbnet parser")
REQUIRE(response.code == at::Result::Code::PARSING_ERROR);
}
}
+
+TEST_CASE("CSQ parser")
+{
+ SECTION("Empty data")
+ {
+ at::cmd::CSQ cmd;
+ at::Result result;
+ auto response = cmd.parseCSQ(result);
+ REQUIRE(!response);
+ }
+
+ SECTION("Failing channel")
+ {
+ at::cmd::CSQ cmd;
+ at::FailingChannel channel;
+ auto base = channel.cmd(cmd);
+ auto response = cmd.parseCSQ(base);
+ REQUIRE(!response);
+ REQUIRE(response.code == at::Result::Code::ERROR);
+ }
+
+ SECTION("success")
+ {
+ constexpr uint32_t csq = 28;
+ constexpr uint32_t ber = 99;
+
+ at::cmd::CSQ cmd;
+ at::CSQ_successChannel channel;
+ auto base = channel.cmd(cmd);
+ auto response = cmd.parseCSQ(base);
+ REQUIRE(response);
+ REQUIRE(response.csq == csq);
+ REQUIRE(response.ber == ber);
+ }
+
+ SECTION("too few tokens")
+ {
+ at::cmd::CSQ cmd;
+ at::CSQ_tooFewTokens channel;
+ auto base = channel.cmd(cmd);
+ auto response = cmd.parseCSQ(base);
+ REQUIRE(!response);
+ REQUIRE(response.code == at::Result::Code::PARSING_ERROR);
+ }
+
+ SECTION("Failed - too many tokens")
+ {
+ at::cmd::CSQ cmd;
+ at::CSQ_toManyTokens channel;
+ auto base = channel.cmd(cmd);
+ auto response = cmd.parseCSQ(base);
+ REQUIRE(!response);
+ REQUIRE(response.code == at::Result::Code::PARSING_ERROR);
+ }
+}<
\ No newline at end of file
M module-services/service-cellular/CMakeLists.txt => module-services/service-cellular/CMakeLists.txt +2 -0
@@ 13,6 13,8 @@ set(SOURCES
src/ImeiGetHandler.cpp
src/TerhetingHandler.cpp
src/ModemResetHandler.cpp
+ src/URCCounter.cpp
+ src/CSQHandler.cpp
CellularCall.cpp
CellularServiceAPI.cpp
M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +12 -0
@@ 148,6 148,14 @@ ServiceCellular::ServiceCellular()
simTimer = sys::TimerFactory::createSingleShotTimer(
this, "simTimer", std::chrono::milliseconds{6000}, [this](sys::Timer &) { priv->simCard->handleSimTimer(); });
+ csqTimer = sys::TimerFactory::createPeriodicTimer(this, "csqTimer", std::chrono::seconds{60}, [this](sys::Timer &) {
+ auto message = std::make_shared<cellular::URCCounterMessage>(csqCounter.getCounter());
+ csqCounter.clearCounter();
+ bus.sendUnicast(std::move(message), serviceName);
+
+ priv->csqHandler->handleTimerTick();
+ });
+
ongoingCall.setStartCallAction([=](const CalllogRecord &rec) {
auto call = DBServiceAPI::CalllogAdd(this, rec);
if (call.ID == DB_ID_NONE) {
@@ 307,6 315,7 @@ void ServiceCellular::registerMessageHandlers()
priv->connectNetworkTime();
priv->connectSimContacts();
priv->connectImeiGetHandler();
+ priv->connectCSQHandler();
connect(typeid(CellularStartOperatorsScanMessage), [&](sys::Message *request) -> sys::MessagePointer {
auto msg = static_cast<CellularStartOperatorsScanMessage *>(request);
@@ 555,6 564,7 @@ void ServiceCellular::registerMessageHandlers()
[&](sys::Message *request) -> sys::MessagePointer { return handleSmsDoneNotification(request); });
connect(typeid(CellularSignalStrengthUpdateNotification), [&](sys::Message *request) -> sys::MessagePointer {
+ csqCounter.count();
return handleSignalStrengthUpdateNotification(request);
});
@@ 867,6 877,8 @@ bool ServiceCellular::handle_cellular_priv_init()
interval)) {
connectionManager->setInterval(std::chrono::minutes{interval});
}
+
+ priv->initCSQHandler();
priv->state->set(State::ST::APNConfProcedure);
return true;
}
M module-services/service-cellular/service-cellular/CellularMessage.hpp => module-services/service-cellular/service-cellular/CellularMessage.hpp +34 -0
@@ 1018,4 1018,38 @@ namespace cellular
public:
RetryPhoneModeChangeRequest() : sys::DataMessage(MessageType::MessageTypeUninitialized){};
};
+
+ class URCCounterMessage : public sys::DataMessage
+ {
+ public:
+ explicit URCCounterMessage(const uint32_t urcCounter)
+ : sys::DataMessage(MessageType::MessageTypeUninitialized), urcCounter(urcCounter){};
+ auto getCounter()
+ {
+ return urcCounter;
+ }
+
+ private:
+ uint32_t urcCounter;
+ };
+
+ class RetrySwitchCSQMode : public sys::DataMessage
+ {
+ public:
+ explicit RetrySwitchCSQMode(bool switchToPollMode)
+ : sys::DataMessage(MessageType::MessageTypeUninitialized), switchToPollMode(switchToPollMode){};
+ auto isSwitchToPollMode()
+ {
+ return switchToPollMode;
+ };
+
+ private:
+ bool switchToPollMode = false;
+ };
+
+ class RetryGetCSQ : public sys::DataMessage
+ {
+ public:
+ RetryGetCSQ() : sys::DataMessage(MessageType::MessageTypeUninitialized){};
+ };
} // namespace cellular
M module-services/service-cellular/service-cellular/ServiceCellular.hpp => module-services/service-cellular/service-cellular/ServiceCellular.hpp +4 -0
@@ 10,6 10,7 @@
#include "PacketDataCellularMessage.hpp"
#include "src/CallManager.hpp"
#include <service-cellular/connection-manager/ConnectionManager.hpp>
+#include "src/URCCounter.hpp"
#include <modem/ATURCStream.hpp>
#include <modem/mux/DLCChannel.h>
@@ 113,6 114,7 @@ class ServiceCellular : public sys::Service
sys::TimerHandle stateTimer;
sys::TimerHandle ussdTimer;
sys::TimerHandle simTimer;
+ sys::TimerHandle csqTimer;
// used to enter modem sleep mode
sys::TimerHandle sleepTimer;
@@ 141,6 143,8 @@ class ServiceCellular : public sys::Service
ussd::State ussdState = ussd::State::none;
+ cellular::service::URCCounter csqCounter;
+
bool nextPowerStateChangeAwaiting = false;
/// one point of state change handling
A module-services/service-cellular/src/CSQHandler.cpp => module-services/service-cellular/src/CSQHandler.cpp +106 -0
@@ 0,0 1,106 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "CSQHandler.hpp"
+
+#include <log/log.hpp>
+
+namespace cellular::service
+{
+
+ void CSQHandler::handleTimerTick()
+ {
+ if (isInPollMode()) {
+ timeSpentInPollMode++;
+ if (isPollModeTimeElapsed()) {
+ switchToReportMode();
+ return;
+ }
+
+ getCSQ();
+ }
+ }
+
+ void CSQHandler::handleURCCounterMessage(const uint32_t counter)
+ {
+ urcCounter = counter;
+ if (isTooManyURC() && not isInPollMode()) {
+ switchToPollMode();
+ }
+ }
+
+ auto CSQHandler::isInPollMode() -> bool
+ {
+ return currentMode == CSQMode::Polling;
+ }
+
+ auto CSQHandler::isTooManyURC() -> bool
+ {
+ return urcCounter > urcThreshold;
+ }
+
+ auto CSQHandler::isPollModeTimeElapsed() -> bool
+ {
+ return timeSpentInPollMode > pollTime;
+ }
+
+ bool CSQHandler::switchToReportMode()
+ {
+ LOG_INFO("CSQ poll mode time elapsed, switch to report mode.");
+ if (onEnableCsqReporting != nullptr && onEnableCsqReporting()) {
+ timeSpentInPollMode = std::chrono::minutes{0};
+ currentMode = CSQMode::Reporting;
+ return true;
+ }
+
+ LOG_ERROR("Failed to switch to CSQ report mode! Retry!");
+ if (onRetrySwitchMode != nullptr) {
+ onRetrySwitchMode(false);
+ }
+ return false;
+ }
+
+ bool CSQHandler::switchToPollMode()
+ {
+ LOG_INFO("Too many signal strength updates, switch to poll mode.");
+ if (onDisableCsqReporting != nullptr && onDisableCsqReporting()) {
+ currentMode = CSQMode::Polling;
+ return true;
+ }
+
+ LOG_ERROR("Failed to switch to CSQ poll mode! Retry!");
+ if (onRetrySwitchMode != nullptr) {
+ onRetrySwitchMode(false);
+ }
+ return false;
+ }
+
+ bool CSQHandler::getCSQ()
+ {
+ if (onGetCsq != nullptr) {
+ if (auto result = onGetCsq(); result.has_value()) {
+ auto csq = result.value();
+ if (csq.csq != invalid_rssi_low && csq.csq != invalid_rssi_high) {
+ LOG_INFO("Propagate valid CSQ");
+ if (onPropagateCSQ != nullptr) {
+ onPropagateCSQ(csq.csq);
+ return true;
+ }
+ }
+ else {
+ LOG_INFO("Invalid CSQ, notify service antenna");
+ if (onInvalidCSQ != nullptr) {
+ onInvalidCSQ();
+ return true;
+ }
+ }
+ }
+ }
+
+ LOG_ERROR("Failed to get CSQ! Retry!");
+ if (onRetryGetCSQ != nullptr) {
+ onRetryGetCSQ();
+ }
+ return false;
+ }
+} // namespace cellular::service
A module-services/service-cellular/src/CSQHandler.hpp => module-services/service-cellular/src/CSQHandler.hpp +55 -0
@@ 0,0 1,55 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <at/cmd/CSQ.hpp>
+
+#include <cstdint>
+#include <chrono>
+#include <functional>
+
+namespace cellular::service
+{
+
+ constexpr auto urcThreshold = 4;
+ constexpr auto pollTime = std::chrono::minutes{15};
+
+ static const auto invalid_rssi_low = 99;
+ static const auto invalid_rssi_high = 199;
+
+ enum class CSQMode
+ {
+ Reporting,
+ Polling
+ };
+
+ class CSQHandler
+ {
+ public:
+ void handleTimerTick();
+ void handleURCCounterMessage(const uint32_t counter);
+
+ std::function<bool()> onEnableCsqReporting;
+ std::function<bool()> onDisableCsqReporting;
+ std::function<std::optional<at::result::CSQ>()> onGetCsq;
+ std::function<void(uint32_t)> onPropagateCSQ;
+ std::function<void()> onInvalidCSQ;
+
+ std::function<void(bool)> onRetrySwitchMode;
+ std::function<void()> onRetryGetCSQ;
+
+ bool switchToReportMode();
+ bool switchToPollMode();
+ bool getCSQ();
+
+ private:
+ uint32_t urcCounter = 0;
+ CSQMode currentMode = CSQMode::Reporting;
+ std::chrono::minutes timeSpentInPollMode{};
+
+ auto isInPollMode() -> bool;
+ auto isPollModeTimeElapsed() -> bool;
+ auto isTooManyURC() -> bool;
+ };
+} // namespace cellular::service
M module-services/service-cellular/src/ServiceCellularPriv.cpp => module-services/service-cellular/src/ServiceCellularPriv.cpp +104 -2
@@ 6,6 6,7 @@
#include "SMSPartsHandler.hpp"
#include <service-cellular-api>
+#include <service-cellular/Constans.hpp>
#include <service-evtmgr/EVMessages.hpp>
#include <service-evtmgr/Constants.hpp>
@@ 14,8 15,11 @@
#include <service-time/Constants.hpp>
#include <queries/messages/sms/QuerySMSUpdate.hpp>
+#include <service-antenna/AntennaServiceAPI.hpp>
+
#include <at/ATFactory.hpp>
#include <at/cmd/QCFGUsbnet.hpp>
+#include <at/cmd/CSQ.hpp>
#include <ucs2/UCS2.hpp>
#include <service-appmgr/Constants.hpp>
@@ 30,8 34,8 @@ namespace cellular::internal
: owner{owner}, simCard{std::make_unique<SimCard>()}, state{std::make_unique<State>(owner)},
networkTime{std::make_unique<NetworkTime>()}, simContacts{std::make_unique<SimContacts>()},
imeiGetHandler{std::make_unique<service::ImeiGetHandler>()},
- tetheringHandler{std::make_unique<TetheringHandler>()}, modemResetHandler{
- std::make_unique<ModemResetHandler>()}
+ tetheringHandler{std::make_unique<TetheringHandler>()},
+ modemResetHandler{std::make_unique<ModemResetHandler>()}, csqHandler{std::make_unique<CSQHandler>()}
{
initSimCard();
initSMSSendHandler();
@@ 390,4 394,102 @@ namespace cellular::internal
return false;
};
}
+
+ void ServiceCellularPriv::initCSQHandler()
+ {
+ csqHandler->onEnableCsqReporting = [this]() {
+ constexpr auto cpuSentinelTimeout = 2000;
+ auto handle = owner->getTaskHandle();
+ if (owner->cpuSentinel) {
+ owner->cpuSentinel->HoldMinimumFrequencyAndWait(
+ bsp::CpuFrequencyMHz::Level_4, handle, cpuSentinelTimeout);
+ }
+
+ auto channel = owner->cmux->get(CellularMux::Channel::Commands);
+ if (channel) {
+ auto result = channel->cmd(at::AT::CSQ_URC_ON);
+ if (result) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ csqHandler->onDisableCsqReporting = [this]() {
+ constexpr auto cpuSentinelTimeout = 2000;
+ auto handle = owner->getTaskHandle();
+ if (owner->cpuSentinel) {
+ owner->cpuSentinel->HoldMinimumFrequencyAndWait(
+ bsp::CpuFrequencyMHz::Level_4, handle, cpuSentinelTimeout);
+ }
+
+ auto channel = owner->cmux->get(CellularMux::Channel::Commands);
+ if (channel) {
+ auto result = channel->cmd(at::AT::CSQ_URC_OFF);
+ if (result) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ csqHandler->onGetCsq = [this]() -> std::optional<at::result::CSQ> {
+ auto channel = owner->cmux->get(CellularMux::Channel::Commands);
+ if (!channel) {
+ return std::nullopt;
+ }
+ auto command = at::cmd::CSQ();
+ auto response = channel->cmd(command);
+ if (response.code == at::Result::Code::OK) {
+ auto result = command.parseCSQ(response);
+ if (result) {
+ return result;
+ }
+ }
+ return std::nullopt;
+ };
+
+ csqHandler->onPropagateCSQ = [this](uint32_t csq) {
+ SignalStrength signalStrength(static_cast<int>(csq));
+ Store::GSM::get()->setSignalStrength(signalStrength.data);
+ auto message = std::make_shared<CellularSignalStrengthUpdateNotification>("");
+ owner->bus.sendMulticast(message, sys::BusChannel::ServiceCellularNotifications);
+ };
+
+ csqHandler->onInvalidCSQ = [this]() { AntennaServiceAPI::InvalidCSQNotification(owner); };
+
+ csqHandler->onRetrySwitchMode = [this](bool isSwitchToPollMode) {
+ owner->bus.sendUnicast(std::make_shared<RetrySwitchCSQMode>(isSwitchToPollMode), ::service::name::cellular);
+ };
+
+ csqHandler->onRetryGetCSQ = [this]() {
+ owner->bus.sendUnicast(std::make_shared<RetryGetCSQ>(), ::service::name::cellular);
+ };
+
+ owner->csqTimer.start();
+ }
+
+ void ServiceCellularPriv::connectCSQHandler()
+ {
+ owner->connect(typeid(URCCounterMessage), [&](sys::Message *request) -> sys::MessagePointer {
+ auto message = dynamic_cast<cellular::URCCounterMessage *>(request);
+ csqHandler->handleURCCounterMessage(message->getCounter());
+ return sys::MessageNone{};
+ });
+
+ owner->connect(typeid(RetrySwitchCSQMode), [&](sys::Message *request) -> sys::MessagePointer {
+ auto message = dynamic_cast<cellular::RetrySwitchCSQMode *>(request);
+ if (message->isSwitchToPollMode()) {
+ csqHandler->switchToPollMode();
+ return sys::MessageNone{};
+ }
+ csqHandler->switchToReportMode();
+ return sys::MessageNone{};
+ });
+
+ owner->connect(typeid(RetryGetCSQ), [&](sys::Message *request) -> sys::MessagePointer {
+ csqHandler->getCSQ();
+ return sys::MessageNone{};
+ });
+ }
} // namespace cellular::internal
M module-services/service-cellular/src/ServiceCellularPriv.hpp => module-services/service-cellular/src/ServiceCellularPriv.hpp +7 -0
@@ 13,9 13,11 @@
#include "ImeiGetHandler.hpp"
#include "TetheringHandler.hpp"
#include "ModemResetHandler.hpp"
+#include "CSQHandler.hpp"
namespace cellular::internal
{
+ using service::CSQHandler;
using service::ModemResetHandler;
using service::NetworkTime;
using service::SimCard;
@@ 35,6 37,8 @@ namespace cellular::internal
std::unique_ptr<service::ImeiGetHandler> imeiGetHandler;
std::unique_ptr<TetheringHandler> tetheringHandler;
std::unique_ptr<ModemResetHandler> modemResetHandler;
+ std::unique_ptr<CSQHandler> csqHandler;
+
State::PowerState nextPowerState = State::PowerState::Off;
std::uint8_t multiPartSMSUID = 0;
@@ 45,6 49,7 @@ namespace cellular::internal
void connectNetworkTime();
void connectSimContacts();
void connectImeiGetHandler();
+ void connectCSQHandler();
void requestNetworkTimeSettings();
void setInitialMultiPartSMSUID(std::uint8_t uid);
@@ 55,6 60,8 @@ namespace cellular::internal
void initSMSSendHandler();
void initTetheringHandler();
void initModemResetHandler();
+ void initCSQHandler();
+
/** Send SMS action used by the SMSSendHandler
* \param record SMS record to send
*/
A module-services/service-cellular/src/URCCounter.cpp => module-services/service-cellular/src/URCCounter.cpp +21 -0
@@ 0,0 1,21 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "URCCounter.hpp"
+
+namespace cellular::service
+{
+
+ void URCCounter::count()
+ {
+ urcOccurences++;
+ }
+ void URCCounter::clearCounter()
+ {
+ urcOccurences = 0;
+ }
+ auto URCCounter::getCounter() -> uint32_t
+ {
+ return urcOccurences;
+ }
+} // namespace cellular::service
A module-services/service-cellular/src/URCCounter.hpp => module-services/service-cellular/src/URCCounter.hpp +20 -0
@@ 0,0 1,20 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+#include <cstdint>
+
+namespace cellular::service
+{
+
+ class URCCounter
+ {
+ public:
+ void count();
+ void clearCounter();
+ auto getCounter() -> uint32_t;
+
+ private:
+ uint32_t urcOccurences = 0;
+ };
+} // namespace cellular::service