From dc3d655abe4a8ab76728bc76a930e7c902318731 Mon Sep 17 00:00:00 2001 From: Alek-Mudita <54846206+Alek-Mudita@users.noreply.github.com> Date: Fri, 13 Mar 2020 16:42:42 +0100 Subject: [PATCH] Egd 2566 signal strength indicator (#214) * [EGD-2566] refactored cellular notification recogniton * [EGD-2566] add new conversion to dBm * [EGD-2566] added dBm to bar calculations some minor fixes connected to signal strength put static data in event store * [EGD-2566] removed magic number * [EGD-2566] PR fixes * [EGD-2566] PR fixes * [EGD-2566] missing rebase fix * [EGD-2566] moved Signal Strength to separate file. * [EGD-2566] missing return * [EGD-2566] update signalstrength without message sending * [EGD-2566] reverted USE_DAEFAULT_BAUDRATE to 1 * [EGD-2566][fix] missing change for closing end call window * [EGD-2566] fix for proper checking for CSQ. Verbose setting of singla strength in Store * [EGD-2566] fixed inlude in ScopeDTime. * [EGD-2566] added mutex in GSM store * [EGD-2566] missing change * [EGD-2566] reverted USE_DAEFAULT_BAUDRATE * [EGD-2566] PR fixy --- module-apps/Application.cpp | 30 +++--- module-apps/Application.hpp | 3 + .../application-call/ApplicationCall.cpp | 2 + module-apps/windows/AppWindow.cpp | 15 +-- module-apps/windows/AppWindow.hpp | 4 +- module-cellular/Modem/ATParser.cpp | 5 +- module-cellular/Modem/TS0710/TS0710.cpp | 19 ++-- module-cellular/at/URC_QIND.hpp | 5 +- module-cellular/at/src/URC_Any.cpp | 2 +- module-cellular/at/src/URC_QIND.cpp | 2 +- module-gui/gui/widgets/TopBar.cpp | 63 ++++++------ module-gui/gui/widgets/TopBar.hpp | 12 +-- .../service-cellular/CMakeLists.txt | 1 + .../service-cellular/ServiceCellular.cpp | 98 +++++-------------- .../service-cellular/ServiceCellular.hpp | 39 +------- .../service-cellular/SignalStrength.cpp | 69 +++++++++++++ .../service-cellular/SignalStrength.hpp | 55 +++++++++++ .../messages/CellularMessage.hpp | 10 +- module-utils/Utils.hpp | 9 ++ module-utils/common_data/EventStore.cpp | 22 ++++- module-utils/common_data/EventStore.hpp | 26 ++++- module-utils/time/ScopedTime.hpp | 9 +- 22 files changed, 294 insertions(+), 206 deletions(-) create mode 100644 module-services/service-cellular/SignalStrength.cpp create mode 100644 module-services/service-cellular/SignalStrength.hpp diff --git a/module-apps/Application.cpp b/module-apps/Application.cpp index 56f64cd94..a29aa2666 100644 --- a/module-apps/Application.cpp +++ b/module-apps/Application.cpp @@ -158,6 +158,7 @@ void Application::render( gui::RefreshModes mode ) { currwin->updateBatteryLevel(Store::Battery::get().level); } currwin->setSIM(); + currwin->updateSignalStrength(); std::list commandsList = currwin->buildDrawList(); @@ -218,27 +219,26 @@ int Application::refreshWindow(gui::RefreshModes mode) { return 0; } +bool Application::signalStrengthUpdateHandler() +{ + if ((state == State::ACTIVE_FORGROUND) && getCurrentWindow()->updateSignalStrength()) + { + refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST); + } + + return true; +} + sys::Message_t Application::DataReceivedHandler(sys::DataMessage* msgl) { bool handled = false; - if (msgl->messageType == MessageType::CellularNotification) + auto msg = dynamic_cast(msgl); + if (msg != nullptr && msg->type == CellularNotificationMessage::Type::SignalStrengthUpdate) { - CellularNotificationMessage *msg = reinterpret_cast(msgl); - if( msg->type == CellularNotificationMessage::Type::SignalStrengthUpdate ) { - if ((state == State::ACTIVE_FORGROUND) && (getCurrentWindow()->updateSignalStrength(msg->signalStrength))) - { - //loop and update all widnows - for ( auto it = windows.begin(); it != windows.end(); it++ ) { - it->second->updateSignalStrength( msg->signalStrength); - } - handled = true; - refreshWindow( gui::RefreshModes::GUI_REFRESH_FAST ); - } - } + handled = signalStrengthUpdateHandler(); } - - if (msgl->messageType == MessageType::AppInputEvent) + else if (msgl->messageType == MessageType::AppInputEvent) { AppInputEventMessage* msg = reinterpret_cast( msgl ); if (getCurrentWindow() != nullptr) diff --git a/module-apps/Application.hpp b/module-apps/Application.hpp index 4dcea9c4a..3fb180098 100644 --- a/module-apps/Application.hpp +++ b/module-apps/Application.hpp @@ -23,6 +23,7 @@ #include "Interface/SettingsRecord.hpp" #include "SwitchData.hpp" +#include "service-cellular/api/CellularServiceAPI.hpp" #include "windows/AppWindow.hpp" namespace gui { @@ -98,6 +99,8 @@ class Application: public sys::Service { private: State state = State::DEACTIVATED; + bool signalStrengthUpdateHandler(); + public: std::list timerIDs; std::list appTimers; // @TODO decide on type diff --git a/module-apps/application-call/ApplicationCall.cpp b/module-apps/application-call/ApplicationCall.cpp index 31c23f279..a26954d0f 100644 --- a/module-apps/application-call/ApplicationCall.cpp +++ b/module-apps/application-call/ApplicationCall.cpp @@ -97,6 +97,7 @@ void ApplicationCall::IncomingCallHandler(const CellularNotificationMessage *con else { AudioServiceAPI::RoutingStart(this); + runCallTimer(); std::unique_ptr data = std::make_unique(msg->data); // send to itself message to switch (run) call application callWindow->setState(gui::CallWindow::State::INCOMING_CALL); @@ -121,6 +122,7 @@ void ApplicationCall::RingingHandler(const CellularNotificationMessage *const ms LOG_INFO("---------------------------------Ringing"); AudioServiceAPI::RoutingStart(this); + runCallTimer(); std::unique_ptr data = std::make_unique(msg->data); callWindow->setState(gui::CallWindow::State::OUTGOING_CALL); diff --git a/module-apps/windows/AppWindow.cpp b/module-apps/windows/AppWindow.cpp index b2759bdfc..08ee73b78 100644 --- a/module-apps/windows/AppWindow.cpp +++ b/module-apps/windows/AppWindow.cpp @@ -82,17 +82,10 @@ bool AppWindow::updateBatteryLevel( uint32_t percentage ) { //if they are different make a change and return true, otherwise return false; return topBar->setBatteryLevel(percentage); } -//updates battery level in the window -bool AppWindow::updateSignalStrength( uint32_t strength ) { - - uint32_t newStrength = 0; - if( strength >= 2 ) newStrength = 1; - if( strength >= 10 ) newStrength = 2; - if( strength >= 15 ) newStrength = 3; - if( strength >= 20 ) newStrength = 4; - if( strength >= 25 ) newStrength = 5; - topBar->setSignalStrength( newStrength ); - return true; +// updates battery level in the window +bool AppWindow::updateSignalStrength() +{ + return topBar->updateSignalStrength(); } bool AppWindow::updateTime( const UTF8& timeStr ) { diff --git a/module-apps/windows/AppWindow.hpp b/module-apps/windows/AppWindow.hpp index 55f188e1c..3ce71ebd3 100644 --- a/module-apps/windows/AppWindow.hpp +++ b/module-apps/windows/AppWindow.hpp @@ -66,8 +66,8 @@ public: //updates battery level in the window bool updateBatteryLevel( uint32_t percentage ); //updates battery level in the window - bool updateSignalStrength( uint32_t strength ); - virtual bool updateTime( const UTF8& timeStr ); + bool updateSignalStrength(); + virtual bool updateTime( const UTF8& timeStr ); virtual bool updateTime( const uint32_t& timestamp, bool mode24H ); void setTitle(const UTF8 &text); diff --git a/module-cellular/Modem/ATParser.cpp b/module-cellular/Modem/ATParser.cpp index 271a37f1a..6544d9b6d 100644 --- a/module-cellular/Modem/ATParser.cpp +++ b/module-cellular/Modem/ATParser.cpp @@ -58,7 +58,8 @@ std::vector ATParser::ParseURC() { return resp; } -int ATParser::ProcessNewData(sys::Service *service) { +int ATParser::ProcessNewData(sys::Service *service) +{ char rawBuffer[256] = {0}; LOG_DEBUG("Receiving data from ProcessNewData"); @@ -66,8 +67,8 @@ int ATParser::ProcessNewData(sys::Service *service) { { cpp_freertos::LockGuard lock(mutex); - LOG_DEBUG("Appending %i bytes to responseBuffer[%d]: %s", length, responseBuffer.size(), responseBuffer.c_str()); responseBuffer.append(reinterpret_cast(rawBuffer), length); + LOG_DEBUG("Appending %i bytes to responseBuffer[%d]: %s", length, responseBuffer.size(), utils::removeNewLines(responseBuffer).c_str()); } auto ret = ParseURC(); diff --git a/module-cellular/Modem/TS0710/TS0710.cpp b/module-cellular/Modem/TS0710/TS0710.cpp index 6e982e4d7..a57a0c239 100644 --- a/module-cellular/Modem/TS0710/TS0710.cpp +++ b/module-cellular/Modem/TS0710/TS0710.cpp @@ -6,7 +6,9 @@ #include "bsp/cellular/bsp_cellular.hpp" #include "projdefs.h" #include "service-cellular/ServiceCellular.hpp" +#include "service-cellular/SignalStrength.hpp" #include "service-cellular/messages/CellularMessage.hpp" +#include #include #include @@ -389,18 +391,13 @@ TS0710::ConfState TS0710::StartMultiplexer() { { auto beg = res.response[0].find(" "); auto end = res.response[0].find(",", 1); - auto message = res.response[0].substr(beg + 1, end - beg - 1); - LOG_DEBUG("Setting new signal strength"); - auto msg = std::make_shared(static_cast(CellularNotificationMessage::Type::SignalStrengthUpdate)); - msg->signalStrength = std::stoll(message); - if (msg->signalStrength > ServiceCellular::getSignalStrengthDBRange()) { - LOG_ERROR("Signal strength value out of range."); - msg->dBmSignalStrength = ServiceCellular::getSignalStrengthDB(0); + SignalStrength signalStrength(std::stoi(res.response[0].substr(beg + 1, end - beg - 1))); + if (signalStrength.isValid()) + { + Store::GSM::get()->setSignalStrength(signalStrength.data); + auto msg = std::make_shared(CellularNotificationMessage::Type::SignalStrengthUpdate); + sys::Bus::SendMulticast(msg, sys::BusChannels::ServiceCellularNotifications, pv_parent); } - else { - msg->dBmSignalStrength = ServiceCellular::getSignalStrengthDB(msg->signalStrength); - } - sys::Bus::SendMulticast(msg, sys::BusChannels::ServiceCellularNotifications, pv_parent); } else { diff --git a/module-cellular/at/URC_QIND.hpp b/module-cellular/at/URC_QIND.hpp index 45e4a6b6b..fa5e432a6 100644 --- a/module-cellular/at/URC_QIND.hpp +++ b/module-cellular/at/URC_QIND.hpp @@ -6,11 +6,12 @@ namespace at::urc { struct QIND : public Any { - static const auto invalid_rssi_modulo = 99; - static const auto invalid_ber = 99; const std::string urc_name = "+QIND"; const std::string type_csq = "csq"; + static const auto invalid_rssi_modulo = 99; + static const auto invalid_ber = 99; + QIND(const std::string &val); ~QIND() override = default; auto what() -> std::string final; diff --git a/module-cellular/at/src/URC_Any.cpp b/module-cellular/at/src/URC_Any.cpp index 2706d6920..7fe9604c0 100644 --- a/module-cellular/at/src/URC_Any.cpp +++ b/module-cellular/at/src/URC_Any.cpp @@ -21,7 +21,7 @@ namespace at::urc auto Any::is() -> bool { - return head.find(what()); + return head.find(what()) != std::string::npos; } } // namespace at::urc diff --git a/module-cellular/at/src/URC_QIND.cpp b/module-cellular/at/src/URC_QIND.cpp index 6a0a748d2..fd667b49a 100644 --- a/module-cellular/at/src/URC_QIND.cpp +++ b/module-cellular/at/src/URC_QIND.cpp @@ -16,7 +16,7 @@ auto QIND::is_csq() -> bool { if (tokens.size() > CSQ) { - return tokens[CSQ].find(type_csq); + return tokens[CSQ].find(type_csq) != std::string::npos; } return false; } diff --git a/module-gui/gui/widgets/TopBar.cpp b/module-gui/gui/widgets/TopBar.cpp index c9984a59c..64bd2e77a 100644 --- a/module-gui/gui/widgets/TopBar.cpp +++ b/module-gui/gui/widgets/TopBar.cpp @@ -19,21 +19,20 @@ namespace gui { -uint32_t TopBar::signalStrength = 0; + const uint32_t TopBar::signalOffset = 35; + const uint32_t TopBar::batteryOffset = 415; + gui::TopBar::TimeMode TopBar::timeMode = TimeMode::TIME_24H; + uint32_t TopBar::time = 0; -const uint32_t TopBar::signalOffset = 35; -const uint32_t TopBar::batteryOffset = 415; -gui::TopBar::TimeMode TopBar::timeMode = TimeMode::TIME_24H; -uint32_t TopBar::time = 0; + TopBar::TopBar() + { -TopBar::TopBar() { + prepareWidget(); - prepareWidget(); - - setFillColor( ColorFullWhite ); - setBorderColor( ColorNoColor ); - setFilled(true); - setSize(480, 50); + setFillColor(ColorFullWhite); + setBorderColor(ColorNoColor); + setFilled(true); + setSize(480, 50); } TopBar::TopBar( Item* parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h ) : Rect{ parent, x, y, w, h } { @@ -70,12 +69,9 @@ void TopBar::prepareWidget() { signal[3] = new gui::Image( this, signalOffset,17,0,0, "signal3" ); signal[4] = new gui::Image( this, signalOffset,17,0,0, "signal4" ); signal[5] = new gui::Image( this, signalOffset,17,0,0, "signal5" ); - for( uint32_t i=0; isetVisible( false ); + updateSignalStrength(); - signal[signalStrength]->setVisible( true ); - - //icons for battery + //icons for battery battery = { new gui::Image(this, batteryOffset, 17, 0, 0, "battery0"), new gui::Image(this, batteryOffset, 17, 0, 0, "battery1"), new gui::Image(this, batteryOffset, 17, 0, 0, "battery2"), new gui::Image(this, batteryOffset, 17, 0, 0, "battery3"), @@ -142,11 +138,8 @@ void TopBar::setActive( TopBar::Elements element, bool active ) { } break; case Elements::SIGNAL: { elements.signal = active; - for (uint32_t i = 0; i < signalImgCount; ++i) - signal[i]->setVisible(false); - if( active ) - signal[signalStrength]->setVisible(true); - } break; + updateSignalStrength(); + } break; case Elements::TIME: { elements.time = active; timeLabel->setVisible(active); @@ -215,14 +208,24 @@ void TopBar::setBatteryCharging(bool plugged) } } -void TopBar::setSignalStrength( uint32_t sth) { - - signalStrength = sth; - for( uint32_t i=0; isetVisible( false ); - } - signal[signalStrength]->setVisible( true ); -}; +bool TopBar::updateSignalStrength() +{ + for (uint32_t i = 0; i < signalImgCount; i++) + { + signal[i]->setVisible(false); + } + if (elements.signal) + { + auto rssiBar = Store::GSM::get()->getSignalStrength().rssiBar; + if (rssiBar < Store::RssiBar::noOfSupprtedBars) + { + signal[static_cast(rssiBar)]->setVisible(true); + return true; + } + return false; + } + return true; +} void TopBar::setTime( const UTF8& time ) { timeLabel->setText(time); diff --git a/module-gui/gui/widgets/TopBar.hpp b/module-gui/gui/widgets/TopBar.hpp index 435dea99e..e1227122a 100644 --- a/module-gui/gui/widgets/TopBar.hpp +++ b/module-gui/gui/widgets/TopBar.hpp @@ -54,9 +54,8 @@ namespace gui { static uint32_t time; protected: - static uint32_t signalStrength; Label *timeLabel; - Image *signal[6]; + Image *signal[static_cast(Store::RssiBar::noOfSupprtedBars)]; Image *lock; std::array battery = {nullptr}; Label *charging = nullptr; @@ -100,14 +99,11 @@ namespace gui { bool setBatteryLevel(uint32_t percent); void setBatteryCharging(bool plugged); + /** - * @brief Sets signal strength. This will cause appropriate image to be displayed. + * @brief updates signal strength. This will cause appropriate image to be displayed. */ - void setSignalStrength(uint32_t sth); - uint32_t getSignalStrength() - { - return signalStrength; - }; + bool updateSignalStrength(); void simSet(); void setTime(const UTF8 &time); diff --git a/module-services/service-cellular/CMakeLists.txt b/module-services/service-cellular/CMakeLists.txt index 549e3947b..249ae6cb9 100644 --- a/module-services/service-cellular/CMakeLists.txt +++ b/module-services/service-cellular/CMakeLists.txt @@ -18,5 +18,6 @@ target_sources( ${PROJECT_NAME} "${CMAKE_CURRENT_LIST_DIR}/ServiceCellular.cpp" "${CMAKE_CURRENT_LIST_DIR}/api/CellularServiceAPI.cpp" "${CMAKE_CURRENT_LIST_DIR}/CellularCall.cpp" + "${CMAKE_CURRENT_LIST_DIR}/SignalStrength.cpp" ) diff --git a/module-services/service-cellular/ServiceCellular.cpp b/module-services/service-cellular/ServiceCellular.cpp index c3592e237..fc38bb74d 100644 --- a/module-services/service-cellular/ServiceCellular.cpp +++ b/module-services/service-cellular/ServiceCellular.cpp @@ -32,6 +32,7 @@ #include "log/log.hpp" +#include "service-cellular/SignalStrength.hpp" #include "service-evtmgr/messages/EVMessages.hpp" #include "ucs2/UCS2.hpp" @@ -44,7 +45,6 @@ #include const char *ServiceCellular::serviceName = "ServiceCellular"; -constexpr int32_t ServiceCellular::signalStrengthToDB[]; inline const auto cellularStack = 16384UL; @@ -110,62 +110,12 @@ ServiceCellular::ServiceCellular() : sys::Service(serviceName, "", cellularStack LOG_DEBUG("Notifications callback called with %i data bytes", data.size()); TS0710_Frame frame(data); std::string message; - CellularNotificationMessage::Type type = identifyNotification(frame.getFrame().data, message); - auto msg = std::make_shared(type); + auto msg = identifyNotification(frame.getFrame().data); - switch (type) + if (msg->type == CellularNotificationMessage::Type::None) { - - case CellularNotificationMessage::Type::ModemOn: - case CellularNotificationMessage::Type::PowerUpProcedureComplete: - case CellularNotificationMessage::Type::Ringing: - case CellularNotificationMessage::Type::ServiceReady: - case CellularNotificationMessage::Type::CallActive: - case CellularNotificationMessage::Type::CallAborted: - // no data field is used - break; - - case CellularNotificationMessage::Type::IncomingCall: - msg->data = message; - break; - - case CellularNotificationMessage::Type::NewIncomingSMS: { - // find message number - std::string notification(data.begin(), data.end()); - auto begin = notification.find(","); - auto end = notification.find("\r"); - msg->data = notification.substr(begin + 1, end); - } - break; - - case CellularNotificationMessage::Type::SignalStrengthUpdate: - LOG_DEBUG("Setting new signal strength"); - msg->signalStrength = std::stoll(message); - if (msg->signalStrength > (sizeof(signalStrengthToDB) / sizeof(signalStrengthToDB[0]))) - { - LOG_ERROR("Signal strength value out of range."); - msg->dBmSignalStrength = signalStrengthToDB[0]; - } - else - { - msg->dBmSignalStrength = signalStrengthToDB[msg->signalStrength]; - } - - break; - - case CellularNotificationMessage::Type::SIM: { - auto message = std::make_shared(); - sys::Bus::SendUnicast(message, "EventManager", this); - } - break; - - case CellularNotificationMessage::Type::None: - // do not send notification msg + LOG_INFO("Skipped uknown notification"); return; - case CellularNotificationMessage::Type::RawCommand: { - LOG_INFO(" IGNORE RawCmd"); - return; - } } sys::Bus::SendMulticast(msg, sys::BusChannels::ServiceCellularNotifications, this); @@ -631,15 +581,12 @@ namespace } } // namespace -CellularNotificationMessage::Type ServiceCellular::identifyNotification(const std::vector &data, std::string &message) +std::shared_ptr ServiceCellular::identifyNotification(const std::vector &data) { - std::string str(data.begin(), data.end()); { - std::string logStr = str; - logStr.erase(std::remove(logStr.begin(), logStr.end(), '\r'), logStr.end()); - logStr.erase(std::remove(logStr.begin(), logStr.end(), '\n'), logStr.end()); + std::string logStr = utils::removeNewLines(str); LOG_DEBUG("Notification:: %s", logStr.c_str()); } @@ -663,7 +610,9 @@ CellularNotificationMessage::Type ServiceCellular::identifyNotification(const st LOG_ERROR("SIM ERROR"); Store::GSM::get()->sim = Store::GSM::SIM::SIM_FAIL; } - return CellularNotificationMessage::Type::SIM; + auto message = std::make_shared(); + sys::Bus::SendUnicast(message, "EventManager", this); + return std::make_shared(CellularNotificationMessage::Type::SIM); } // Incoming call @@ -672,43 +621,50 @@ CellularNotificationMessage::Type ServiceCellular::identifyNotification(const st auto beg = str.find("\"",ret); auto end = str.find("\"",ret + beg+1); - message = str.substr(beg+1,end-beg-1); + auto message = str.substr(beg + 1, end - beg - 1); - return CellularNotificationMessage::Type::IncomingCall; + return std::make_shared(CellularNotificationMessage::Type::IncomingCall, message); } // Call aborted/failed if (isAbortCallNotification(str)) { LOG_TRACE("call aborted"); - return CellularNotificationMessage::Type::CallAborted; + return std::make_shared(CellularNotificationMessage::Type::CallAborted); } // Received new SMS if (str.find("+CMTI: ") != std::string::npos) { LOG_TRACE("received new SMS notification"); - message = "888777333"; // TODO:M.P add SMS nr parsing - - return CellularNotificationMessage::Type::NewIncomingSMS; + // find message number + auto tokens = utils::split(str, ','); + if (tokens.size() == 2) + { + return std::make_shared(CellularNotificationMessage::Type::NewIncomingSMS, tokens[1]); + } } // Received signal strength change auto qind = at::urc::QIND(str); - if (qind.is()) + if (qind.is() && qind.is_csq()) { if (!qind.validate(at::urc::QIND::RSSI)) { - LOG_ERROR("Invalid csq - ignore"); + LOG_INFO("Invalid csq - ignore"); } else { - message = std::string(qind.tokens[at::urc::QIND::RSSI]); - return CellularNotificationMessage::Type::SignalStrengthUpdate; + SignalStrength signalStrength(std::stoi(qind.tokens[at::urc::QIND::RSSI])); + if (signalStrength.isValid()) + { + Store::GSM::get()->setSignalStrength(signalStrength.data); + return std::make_shared(CellularNotificationMessage::Type::SignalStrengthUpdate); + } } } LOG_WARN("Unhandled notification"); - return CellularNotificationMessage::Type::None; + return std::make_shared(CellularNotificationMessage::Type::None); } bool ServiceCellular::sendSMS(void) diff --git a/module-services/service-cellular/ServiceCellular.hpp b/module-services/service-cellular/ServiceCellular.hpp index 9d9753868..7ef6b81ad 100644 --- a/module-services/service-cellular/ServiceCellular.hpp +++ b/module-services/service-cellular/ServiceCellular.hpp @@ -69,9 +69,6 @@ public: static const char *serviceName; - static int32_t getSignalStrengthDB(int32_t strength) { return signalStrengthToDB[strength]; } - static int32_t getSignalStrengthDBRange() { return (sizeof(signalStrengthToDB) / sizeof(signalStrengthToDB[0])); } - bool sendSMS(UTF8& number, UTF8& text); bool sendSMS(void); bool receiveSMS(std::string messageNumber); @@ -103,42 +100,8 @@ public: cellular::State state; - static constexpr int32_t signalStrengthToDB[] = { - -109, //0 - -109, //1 - -109, //2 - -107, - -105, - -103, - -101, - -99, - -97, - -95, - -93, - -91, - -89, - -87, - -85, - -83, - -81, - -79, - -77, - -75, - -73, - -71, - -69, - -67, - -65, - -63, - -61, - -59, - -57, - -55, - -53 //30 - }; - /// URC GSM notification handler - CellularNotificationMessage::Type identifyNotification(const std::vector &data, std::string &message); + std::shared_ptr identifyNotification(const std::vector &data); std::vector messageParts; diff --git a/module-services/service-cellular/SignalStrength.cpp b/module-services/service-cellular/SignalStrength.cpp new file mode 100644 index 000000000..f81244541 --- /dev/null +++ b/module-services/service-cellular/SignalStrength.cpp @@ -0,0 +1,69 @@ +#include "SignalStrength.hpp" +#include + +SignalStrength::SignalStrength(int rssi) +{ + setRssi(rssi); +} + +int SignalStrength::rssiTodBm(const int rssi) +{ + int ret = rssidBm_invalid; + if (rssi == rssi_invalid || rssi == rssi_tdscmda_invalid) + { + return ret; + } + + if (rssi >= rssi_low && rssi <= rssi_max) + { + ret = rssi_low_dBm - rssi * rssi_step; + } + else if (rssi >= rssi_tdscmda_low && rssi <= rssi_tdscmda_max) + { + LOG_WARN("TD-SCDMA rssi range - signal strength indicator not fully supported"); + ret = rssi_tdscmda_low_dBm - rssi * rssi_tdscmda_step; + } + + return ret; +} + +Store::RssiBar SignalStrength::rssidBmToBar(const int rssidBm) +{ + using namespace Store; + + if (rssidBm == rssidBm_invalid) + { + return RssiBar::zero; + } + else if (rssidBm >= rssidBm_five_bar_margin) + { + return RssiBar::five; + } + else if (rssidBm >= rssidBm_four_bar_margin) + { + return RssiBar::four; + } + else if (rssidBm >= rssidBm_three_bar_margin) + { + return RssiBar::three; + } + else if (rssidBm >= rssidBm_two_bar_margin) + { + return RssiBar::two; + } + else if (rssidBm >= rssidBm_one_bar_margin) + { + return RssiBar::one; + } + else + { + return RssiBar::zero; + } +} + +void SignalStrength::setRssi(const int rssi) +{ + data.rssi = rssi; + data.rssidBm = rssiTodBm(data.rssi); + data.rssiBar = rssidBmToBar(data.rssidBm); +} diff --git a/module-services/service-cellular/SignalStrength.hpp b/module-services/service-cellular/SignalStrength.hpp new file mode 100644 index 000000000..e52ee6dca --- /dev/null +++ b/module-services/service-cellular/SignalStrength.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include "common_data/EventStore.hpp" +#include + +class SignalStrength +{ + // 0 -113dBm or less + // 1 -111dBm + // 2...30 -109dBm...-53dBm + // 31 -51dBm or greater + // 99 Not known or not detectable + // 100 -116dBm or less + // 101 -115dBm + // 102..190 -114dBm...-26dBm + // 191 -25dBm or greater + // 199 Not known or not detectable + static const auto rssi_low = 0; + static const auto rssi_max = 31; + static const auto rssi_low_dBm = -113; + static const auto rssi_max_dBm = -51; + static const auto rssi_invalid = 99; + static const auto rssi_step = (rssi_low_dBm - rssi_max_dBm) / (rssi_max - rssi_low); + + static const auto rssi_tdscmda_low = 100; + static const auto rssi_tdscmda_max = 191; + static const auto rssi_tdscmda_invalid = 199; + static const auto rssi_tdscmda_low_dBm = -116; + static const auto rssi_tdscmda_max_dBm = -25; + static const auto rssi_tdscmda_step = (rssi_tdscmda_low_dBm - rssi_tdscmda_max_dBm) / (rssi_tdscmda_max - rssi_low); + + static const auto rssidBm_invalid = 0; + static const auto rssidBm_five_bar_margin = -60; + static const auto rssidBm_four_bar_margin = -75; + static const auto rssidBm_three_bar_margin = -90; + static const auto rssidBm_two_bar_margin = -100; + static const auto rssidBm_one_bar_margin = -110; + + public: + SignalStrength(int rssi); + ~SignalStrength() = default; + SignalStrength(Store::SignalStrength); + + Store::SignalStrength data; + + void setRssi(int rssi); + bool isValid() + { + return data.rssidBm != rssidBm_invalid; + }; + + /// @return 0 - if invalid + static int rssiTodBm(const int rssi); + static Store::RssiBar rssidBmToBar(const int rssidBm); +}; diff --git a/module-services/service-cellular/messages/CellularMessage.hpp b/module-services/service-cellular/messages/CellularMessage.hpp index 892c9ff15..19141ab39 100644 --- a/module-services/service-cellular/messages/CellularMessage.hpp +++ b/module-services/service-cellular/messages/CellularMessage.hpp @@ -12,11 +12,12 @@ #ifndef PUREPHONE_CELLULARMESSAGE_HPP #define PUREPHONE_CELLULARMESSAGE_HPP +#include "../SignalStrength.hpp" +#include "MessageType.hpp" +#include "Service/Message.hpp" +#include "utf8/UTF8.hpp" #include #include -#include "Service/Message.hpp" -#include "MessageType.hpp" -#include "utf8/UTF8.hpp" class CellularMessage : public sys::DataMessage { public: @@ -55,9 +56,6 @@ public: Type type=Type::None; std::string data; - uint32_t signalStrength=0; - int32_t dBmSignalStrength=0; - }; class CellularRequestMessage : public CellularMessage{ diff --git a/module-utils/Utils.hpp b/module-utils/Utils.hpp index be8904663..88079193a 100644 --- a/module-utils/Utils.hpp +++ b/module-utils/Utils.hpp @@ -51,6 +51,15 @@ namespace utils return res; } + static inline std::string removeNewLines(const std::string &s) + { + std::string retStr = s; + retStr.erase(std::remove(retStr.begin(), retStr.end(), '\r'), retStr.end()); + retStr.erase(std::remove(retStr.begin(), retStr.end(), '\n'), retStr.end()); + + return retStr; + } + static inline bool is_number(const std::string &s) { return !s.empty() && std::find_if(s.begin(), s.end(), [](char c) { return !std::isdigit(c); }) == s.end(); diff --git a/module-utils/common_data/EventStore.cpp b/module-utils/common_data/EventStore.cpp index 5bb5c6dca..e03b0db28 100644 --- a/module-utils/common_data/EventStore.cpp +++ b/module-utils/common_data/EventStore.cpp @@ -1,4 +1,6 @@ #include "EventStore.hpp" +#include +#include namespace Store { @@ -16,15 +18,31 @@ namespace Store return battery; } - GSM *GSM::ptr = nullptr; + cpp_freertos::MutexStandard mutex; GSM *GSM::get() { - if (!ptr) + cpp_freertos::LockGuard lock(mutex); + static GSM *ptr = nullptr; + if (ptr == nullptr) { ptr = new GSM(); } return ptr; } + void GSM::setSignalStrength(const SignalStrength &signalStrength) + { + cpp_freertos::LockGuard lock(mutex); + LOG_INFO("Setting signal strenth to rssi = %d dBm (%d) : %u bars", signalStrength.rssidBm, signalStrength.rssi, signalStrength.rssiBar); + + get()->signalStrength = signalStrength; + } + + SignalStrength GSM::getSignalStrength() + { + cpp_freertos::LockGuard lock(mutex); + + return get()->signalStrength; + } }; // namespace Store diff --git a/module-utils/common_data/EventStore.hpp b/module-utils/common_data/EventStore.hpp index 227c7ab0b..4aa0cddeb 100644 --- a/module-utils/common_data/EventStore.hpp +++ b/module-utils/common_data/EventStore.hpp @@ -6,6 +6,7 @@ // - gsm SIM tray // it's not meant to serve as polling interface - rather to serve data +#include namespace Store { struct Battery @@ -21,10 +22,29 @@ namespace Store static Battery &modify(); }; + enum class RssiBar : size_t + { + zero = 0, + one = 1, + two = 2, + three = 3, + four = 4, + five = 5, + noOfSupprtedBars + }; + + struct SignalStrength + { + int rssi = 0; + int rssidBm = 0; + RssiBar rssiBar = RssiBar::zero; + }; + struct GSM { private: - static GSM *ptr; + GSM() = default; + SignalStrength signalStrength; public: enum class Tray @@ -52,6 +72,10 @@ namespace Store ON_NEED_SIMFLOW, /// modem is on, initialized, no SIM initialization yet ON_INITIALIZED, /// modem is on, and it's fully initialized } modem = Modem::OFF; + + void setSignalStrength(const SignalStrength &signalStrength); + SignalStrength getSignalStrength(); + static GSM *get(); }; }; // namespace Store diff --git a/module-utils/time/ScopedTime.hpp b/module-utils/time/ScopedTime.hpp index ff2f41e5e..1a5aa3c66 100644 --- a/module-utils/time/ScopedTime.hpp +++ b/module-utils/time/ScopedTime.hpp @@ -1,15 +1,14 @@ #pragma once -namespace utils -{ - namespace time - { - #include #include #include #include +namespace utils +{ + namespace time + { class Scoped { TickType_t timestamp;