M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +10 -2
@@ 290,8 290,11 @@ sys::ReturnCodes ServiceCellular::SwitchPowerModeHandler(const sys::ServicePower
void ServiceCellular::registerMessageHandlers()
{
phoneModeObserver->connect(this);
- phoneModeObserver->subscribe(
- [this](sys::phone_modes::PhoneMode mode) { connectionManager->onPhoneModeChange(mode); });
+ phoneModeObserver->subscribe([this](sys::phone_modes::PhoneMode mode) {
+ if (priv->simCard->isSimCardSelected()) {
+ connectionManager->onPhoneModeChange(mode);
+ }
+ });
phoneModeObserver->subscribe([&](sys::phone_modes::Tethering tethering) {
if (tethering == sys::phone_modes::Tethering::On) {
priv->tetheringHandler->enable();
@@ 574,6 577,11 @@ void ServiceCellular::registerMessageHandlers()
return handleCellularSetConnectionFrequencyMessage(request);
});
+ connect(typeid(RetryPhoneModeChangeRequest), [&](sys::Message *request) -> sys::MessagePointer {
+ connectionManager->onPhoneModeChange(phoneModeObserver->getCurrentPhoneMode());
+ return sys::MessageNone{};
+ });
+
handle_CellularGetChannelMessage();
}
M module-services/service-cellular/connection-manager/ConnectionManager.cpp => module-services/service-cellular/connection-manager/ConnectionManager.cpp +36 -4
@@ 61,12 61,23 @@ auto ConnectionManager::isMessagesOnlyMode() -> bool
auto ConnectionManager::handleModeChangeToCommonOffline() -> bool
{
- if (cellular->isConnectedToNetwork()) {
+ auto isConnected = cellular->isConnectedToNetwork();
+
+ if (not isConnected.has_value()) {
+ retryOnFail();
+ return false;
+ }
+
+ if (isConnected.value()) {
cellular->hangUpOngoingCall();
- cellular->disconnectFromNetwork();
+ if (!cellular->disconnectFromNetwork()) {
+ retryOnFail();
+ return false;
+ }
cellular->clearNetworkIndicator();
}
+ failRetries = 0;
minutesOfflineElapsed = static_cast<std::chrono::minutes>(0);
minutesOnlineElapsed = static_cast<std::chrono::minutes>(0);
@@ 101,9 112,20 @@ auto ConnectionManager::handleModeChangeToConnected() -> bool
cellular->stopConnectionTimer();
onlinePeriod = false;
}
- if (!cellular->isConnectedToNetwork()) {
- cellular->connectToNetwork();
+
+ auto isConnected = cellular->isConnectedToNetwork();
+ if (not isConnected.has_value()) {
+ retryOnFail();
+ return false;
}
+
+ if (not isConnected.value()) {
+ if (!cellular->connectToNetwork()) {
+ retryOnFail();
+ return false;
+ }
+ }
+ failRetries = 0;
return true;
}
@@ 111,3 133,13 @@ auto ConnectionManager::forceDismissCalls() -> bool
{
return forceDismissCallsFlag;
}
+void ConnectionManager::retryOnFail()
+{
+ if (failRetries < maxFailRetries) {
+ cellular->retryPhoneModeChange();
+ failRetries++;
+ return;
+ }
+ LOG_FATAL("Not able to handle phone mode change!!");
+ failRetries = 0;
+}
M module-services/service-cellular/connection-manager/ConnectionManagerCellularCommands.cpp => module-services/service-cellular/connection-manager/ConnectionManagerCellularCommands.cpp +6 -2
@@ 33,7 33,7 @@ auto ConnectionManagerCellularCommands::connectToNetwork() -> bool
return false;
}
-auto ConnectionManagerCellularCommands::isConnectedToNetwork() -> bool
+auto ConnectionManagerCellularCommands::isConnectedToNetwork() -> std::optional<bool>
{
using at::cfun::Functionality;
@@ 48,7 48,7 @@ auto ConnectionManagerCellularCommands::isConnectedToNetwork() -> bool
}
}
}
- return false;
+ return std::nullopt;
}
auto ConnectionManagerCellularCommands::clearNetworkIndicator() -> bool
@@ 106,3 106,7 @@ void ConnectionManagerCellularCommands::holdMinimumCpuFrequency()
}
return;
}
+void ConnectionManagerCellularCommands::retryPhoneModeChange()
+{
+ cellular.bus.sendUnicast(std::make_shared<cellular::RetryPhoneModeChangeRequest>(), cellular.serviceName);
+}
M module-services/service-cellular/service-cellular/CellularMessage.hpp => module-services/service-cellular/service-cellular/CellularMessage.hpp +5 -0
@@ 976,4 976,9 @@ namespace cellular
at::SimInsertedStatus insertedStatus;
};
+ class RetryPhoneModeChangeRequest : public sys::DataMessage
+ {
+ public:
+ RetryPhoneModeChangeRequest() : sys::DataMessage(MessageType::MessageTypeUninitialized){};
+ };
} // namespace cellular
M module-services/service-cellular/service-cellular/connection-manager/ConnectionManager.hpp => module-services/service-cellular/service-cellular/connection-manager/ConnectionManager.hpp +6 -1
@@ 10,7 10,7 @@
// connection timer period is 1 minute, connect to network for 5 minutes
constexpr std::chrono::minutes connectedPeriod{5};
-
+constexpr auto maxFailRetries = 5;
/**
* @brief Intended for GSM network connection management depending on the selected phone mode.
* Switching modes takes place at Phone Modes Observer event.
@@ 63,6 63,7 @@ class ConnectionManager
std::chrono::minutes minutesOnlineElapsed{0};
std::shared_ptr<ConnectionManagerCellularCommandsInterface> cellular;
bool onlinePeriod = false;
+ int failRetries = 0;
/// Flag determining if we should always dismiss incoming calls - even when
/// we are in offline mode (messages only) and we connect to network to poll
@@ 94,4 95,8 @@ class ConnectionManager
* @return true on success, false on fail
*/
auto handleModeChangeToConnected() -> bool;
+ /**
+ * Request retry if phone mode changing fails
+ */
+ void retryOnFail();
};
M module-services/service-cellular/service-cellular/connection-manager/ConnectionManagerCellularCommands.hpp => module-services/service-cellular/service-cellular/connection-manager/ConnectionManagerCellularCommands.hpp +2 -1
@@ 14,13 14,14 @@ class ConnectionManagerCellularCommands : public ConnectionManagerCellularComman
{}
auto disconnectFromNetwork() -> bool final;
auto connectToNetwork() -> bool final;
- auto isConnectedToNetwork() -> bool final;
+ auto isConnectedToNetwork() -> std::optional<bool> final;
auto clearNetworkIndicator() -> bool final;
auto hangUpOngoingCall() -> bool final;
auto isConnectionTimerActive() -> bool final;
void startConnectionTimer() final;
void stopConnectionTimer() final;
void holdMinimumCpuFrequency() final;
+ void retryPhoneModeChange() final;
private:
ServiceCellular &cellular;
M module-services/service-cellular/service-cellular/connection-manager/ConnectionManagerCellularCommandsInterface.hpp => module-services/service-cellular/service-cellular/connection-manager/ConnectionManagerCellularCommandsInterface.hpp +6 -1
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
+#include <optional>
class ConnectionManagerCellularCommandsInterface
{
@@ 25,7 26,7 @@ class ConnectionManagerCellularCommandsInterface
* * Checks current state of modem radio module
* @return true when modem radio module is enabled, false when modem radio module is disabled
*/
- virtual auto isConnectedToNetwork() -> bool = 0;
+ virtual auto isConnectedToNetwork() -> std::optional<bool> = 0;
/**
* * It's disabling modem radio module, so it can't connect to the GSM network
* @return true on success, false on fail
@@ 53,4 54,8 @@ class ConnectionManagerCellularCommandsInterface
* @brief Holds minimum cpu frequency
*/
virtual void holdMinimumCpuFrequency() = 0;
+ /**
+ * Request retry if phone mode changing fails
+ */
+ virtual void retryPhoneModeChange() = 0;
};
M module-services/service-cellular/src/SimCard.hpp => module-services/service-cellular/src/SimCard.hpp +8 -0
@@ 166,6 166,14 @@ namespace cellular::service
*/
void handleSimCardSelected();
/**
+ * Get Sim selected state
+ * @return true when Sim is selected, fail when not
+ */
+ bool isSimCardSelected()
+ {
+ return isSimSelected;
+ }
+ /**
* Notification events
*/
std::function<void()> onSimReady;
M module-services/service-cellular/tests/unittest_connection-manager.cpp => module-services/service-cellular/tests/unittest_connection-manager.cpp +4 -1
@@ 7,6 7,8 @@
#include <service-cellular/connection-manager/ConnectionManager.hpp>
#include <service-cellular/connection-manager/ConnectionManagerCellularCommandsInterface.hpp>
+#include <optional>
+
using namespace testing;
class MockCellular : public ConnectionManagerCellularCommandsInterface
@@ 14,13 16,14 @@ class MockCellular : public ConnectionManagerCellularCommandsInterface
public:
MOCK_METHOD(bool, disconnectFromNetwork, (), (override));
MOCK_METHOD(bool, connectToNetwork, (), (override));
- MOCK_METHOD(bool, isConnectedToNetwork, (), (override));
+ MOCK_METHOD(std::optional<bool>, isConnectedToNetwork, (), (override));
MOCK_METHOD(bool, clearNetworkIndicator, (), (override));
MOCK_METHOD(bool, hangUpOngoingCall, (), (override));
MOCK_METHOD(bool, isConnectionTimerActive, (), (override));
MOCK_METHOD(void, startConnectionTimer, (), (override));
MOCK_METHOD(void, stopConnectionTimer, (), (override));
MOCK_METHOD(void, holdMinimumCpuFrequency, (), (override));
+ MOCK_METHOD(void, retryPhoneModeChange, (), (override));
};
TEST(ConnectionManager, onPhoneModeChange)