From b069b7bc6be50968145fe4d1ec9d5922e78d981a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Zieli=C5=84ski?= Date: Mon, 21 Nov 2022 12:20:02 +0100 Subject: [PATCH] [MOS-793] Connect GUI and modem VoLTE steering Additionally, fixed many covert bugs that emerged due to modem restarting. --- module-apps/CMakeLists.txt | 5 - .../ApplicationSettings.cpp | 35 +++++++ .../ApplicationSettings.hpp | 6 ++ .../windows/network/NetworkWindow.cpp | 41 +++++---- module-cellular/modem/ATCommon.hpp | 2 + module-cellular/modem/mux/DLCChannel.h | 2 + .../service-cellular/ServiceCellular.cpp | 92 ++++++++++++++----- .../call/api/ModemCallApi.cpp | 20 +++- .../service-cellular/CellularMessage.hpp | 2 +- .../src/ModemResetHandler.cpp | 8 ++ .../src/ModemResetHandler.hpp | 6 ++ .../src/ServiceCellularPriv.cpp | 42 ++++++++- .../src/ServiceCellularPriv.hpp | 3 + .../service-cellular/src/SimCard.cpp | 12 ++- .../service-cellular/src/SimCard.hpp | 9 +- .../service-cellular/src/VolteHandler.hpp | 13 +++ pure_changelog.md | 2 +- 17 files changed, 243 insertions(+), 57 deletions(-) diff --git a/module-apps/CMakeLists.txt b/module-apps/CMakeLists.txt index a958f78979851fd84ca32cf0867b8e78cba6c5ee..7c35e07aed6d371cca7688bf6abea1598c55bcc0 100644 --- a/module-apps/CMakeLists.txt +++ b/module-apps/CMakeLists.txt @@ -58,11 +58,6 @@ if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") endforeach() endif() -option(ENABLE_VOLTE "Enable VoLTE" OFF) -if(${ENABLE_VOLTE}) - target_compile_definitions(${PROJECT_NAME} PUBLIC ENABLE_VOLTE=1) -endif() - option(DISABLED_SETTINGS_OPTIONS "Enable Disabled Settings Options" OFF) if(${DISABLED_SETTINGS_OPTIONS}) target_compile_definitions(${PROJECT_NAME} PUBLIC DISABLED_SETTINGS_OPTIONS=1) diff --git a/module-apps/application-settings/ApplicationSettings.cpp b/module-apps/application-settings/ApplicationSettings.cpp index d5917ce01107be65c1857f6614d5af5a653a8ee0..e3f8209d35800c8bcd1d11947e9dfefa1e8e1b03 100644 --- a/module-apps/application-settings/ApplicationSettings.cpp +++ b/module-apps/application-settings/ApplicationSettings.cpp @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -74,6 +75,7 @@ #include #include #include +#include #include #include #include @@ -321,6 +323,12 @@ namespace app return handleAudioStop(notification); }); + connect(typeid(cellular::GetVolteStateResponse), + [&](sys::Message *msg) -> sys::MessagePointer { return handleVolteState(msg); }); + + connect(typeid(cellular::VolteStateNotification), + [&](sys::Message *msg) -> sys::MessagePointer { return handleVolteState(msg); }); + createUserInterface(); settings->registerValueChange(settings::operators_on, @@ -345,6 +353,9 @@ namespace app bluetoothSettingsModel->requestBondedDevices(); bluetoothSettingsModel->requestStatus(); + + bus.sendUnicast(std::make_shared(), service::name::cellular); + return ret; } @@ -769,6 +780,11 @@ namespace app return statusIndicators.phoneMode; } + auto ApplicationSettings::getVolteState() const noexcept -> cellular::VolteState + { + return volteState; + } + void ApplicationSettings::setAutoLockTime(std::chrono::seconds lockTime) { bus.sendUnicast(std::make_shared(lockTime), service::name::appmgr); @@ -805,4 +821,23 @@ namespace app } return sys::MessageNone{}; } + + auto ApplicationSettings::handleVolteState(sys::Message *msg) -> sys::MessagePointer + { + auto *volteStateMessage = static_cast(msg); + volteState = volteStateMessage->volteState; + + if (isCurrentWindow(gui::window::name::network)) { + // refreshWindow() would be insufficient because wouldn't trigger list rebuild + switchWindow(gui::window::name::network); + } + + return sys::MessageNone{}; + } + + void ApplicationSettings::sendVolteChangeRequest(bool enable) + { + auto message = std::make_shared(enable); + bus.sendUnicast(std::move(message), service::name::cellular); + }; } /* namespace app */ diff --git a/module-apps/application-settings/include/application-settings/ApplicationSettings.hpp b/module-apps/application-settings/include/application-settings/ApplicationSettings.hpp index 4304acfad8ea2199c0c02ec537e956436e9451c2..532df7c65fa0c9ae16bda79b84bd1cb6e08d9a4f 100644 --- a/module-apps/application-settings/include/application-settings/ApplicationSettings.hpp +++ b/module-apps/application-settings/include/application-settings/ApplicationSettings.hpp @@ -13,6 +13,7 @@ #include #include #include +#include class AudioStopNotification; // Forward declaration @@ -183,12 +184,16 @@ namespace app auto getCurrentPhoneMode() const noexcept -> sys::phone_modes::PhoneMode override; + auto getVolteState() const noexcept -> cellular::VolteState; + void sendVolteChangeRequest(bool enable); + private: void attachQuotesWindows(); void switchToAllDevicesViaBtErrorPrompt(std::shared_ptr msg, const std::string &errorMsg); auto handleSimNotification() -> sys::MessagePointer; auto handleAudioStop(AudioStopNotification *notification) -> sys::MessagePointer; + auto handleVolteState(sys::Message *msg) -> sys::MessagePointer; std::shared_ptr soundsPlayer; Store::GSM::SelectedSIM selectedSim = Store::GSM::get()->selected; @@ -200,6 +205,7 @@ namespace app bool callsFromFavorites = false; int connectionFrequency = 0; bool flightModeOn = true; + cellular::VolteState volteState{cellular::VolteState::Undefined}; std::shared_ptr bluetoothSettingsModel = nullptr; }; diff --git a/module-apps/application-settings/windows/network/NetworkWindow.cpp b/module-apps/application-settings/windows/network/NetworkWindow.cpp index f98c994550538bebc4883a217389c80316d34418..ee0e01b77c42150c174629bbe7a5fad4b8398dc3 100644 --- a/module-apps/application-settings/windows/network/NetworkWindow.cpp +++ b/module-apps/application-settings/windows/network/NetworkWindow.cpp @@ -37,23 +37,21 @@ namespace gui gui::option::SettingRightItem::ArrowWhite, false)); -#if ENABLE_VOLTE == 1 -#pragma message "state switching not connected to the actual state yet - see MOS-793" - auto getNextVolteState = []() { - using namespace gui::option; - - static size_t volteStateIndex; - static constexpr SettingRightItem volteStates[]{ - SettingRightItem::Transiting, SettingRightItem::On, SettingRightItem::Off}; - - auto currentIndex = ++volteStateIndex % (sizeof(volteStates) / sizeof(volteStates[0])); - return volteStates[currentIndex]; - }; - optList.emplace_back(std::make_unique( utils::translate("app_settings_network_voice_over_lte"), - [=](gui::Item &item) { - refreshOptionsList(); + [&](gui::Item &item) { + auto *settingsApp = static_cast(application); + switch (settingsApp->getVolteState()) { + case cellular::VolteState::Off: + settingsApp->sendVolteChangeRequest(true); + break; + case cellular::VolteState::On: + settingsApp->sendVolteChangeRequest(false); + break; + default: + LOG_INFO("Skip request due unsettled VoLTE state"); + break; + } return true; }, [&](Item &item) { @@ -63,8 +61,17 @@ namespace gui return true; }, nullptr, - getNextVolteState())); -#endif + [&]() { + auto const *settingsApp = static_cast(application); + switch (settingsApp->getVolteState()) { + case cellular::VolteState::Off: + return option::SettingRightItem::Off; + case cellular::VolteState::On: + return option::SettingRightItem::On; + default: + return option::SettingRightItem::Transiting; + } + }())); #if DISABLED_SETTINGS_OPTIONS == 1 auto operatorsOn = operatorsSettings->getOperatorsOn(); diff --git a/module-cellular/modem/ATCommon.hpp b/module-cellular/modem/ATCommon.hpp index 484e9662b331dd053bb9712cb8748a8daeb27561..87bb85b05b8a4c0ca0cc79ebd67870536d3486d0 100644 --- a/module-cellular/modem/ATCommon.hpp +++ b/module-cellular/modem/ATCommon.hpp @@ -77,6 +77,8 @@ namespace at }; + virtual ~Channel() = default; + /// waits till ok or timeout virtual auto cmd(const std::string &cmd, std::chrono::milliseconds timeout = at::default_timeout, diff --git a/module-cellular/modem/mux/DLCChannel.h b/module-cellular/modem/mux/DLCChannel.h index 47b2d31b086d1cead6c837b590ccb20eb91899e0..d3166fa3efc0f00e69edacaf141c0d863f152b80 100644 --- a/module-cellular/modem/mux/DLCChannel.h +++ b/module-cellular/modem/mux/DLCChannel.h @@ -33,6 +33,8 @@ class DLCChannel : public at::Channel DLCChannel(DLCI_t DLCI, const std::string &name, bsp::Cellular *cellular, const Callback_t &callback = nullptr); DLCChannel() : Channel{nullptr}, name{"none"}, DLCI{-1} {}; + virtual ~DLCChannel() = default; + bool init(); bool establish(); void sendData(std::vector &data); diff --git a/module-services/service-cellular/ServiceCellular.cpp b/module-services/service-cellular/ServiceCellular.cpp index a8c5519eec214f823687e7e162c8685cb0117bec..a3ce1816ddb39cea1367d7a7502cf93cae565642 100644 --- a/module-services/service-cellular/ServiceCellular.cpp +++ b/module-services/service-cellular/ServiceCellular.cpp @@ -405,11 +405,7 @@ void ServiceCellular::registerMessageHandlers() connect(typeid(sdesktop::developerMode::DeveloperModeRequest), [&](sys::Message *request) -> sys::MessagePointer { auto msg = static_cast(request); if (typeid(*msg->event.get()) == typeid(sdesktop::developerMode::CellularHotStartEvent)) { - priv->simCard->setChannel(nullptr); - priv->networkTime->setChannel(nullptr); - priv->simContacts->setChannel(nullptr); - priv->imeiGetHandler->setChannel(nullptr); - + priv->privDeinit(); cmux->closeChannels(); ///> change state - simulate hot start handle_power_up_request(); @@ -602,7 +598,9 @@ void ServiceCellular::registerMessageHandlers() }); connect(typeid(cellular::GetVolteStateRequest), [&](sys::Message *request) -> sys::MessagePointer { - return std::make_shared(priv->volteHandler->getVolteState()); + bus.sendUnicast(std::make_shared(priv->volteHandler->getVolteState()), + request->sender); + return sys::MessageNone{}; }); connect(typeid(cellular::SwitchVolteOnOffRequest), [&](sys::Message *request) -> sys::MessagePointer { @@ -614,14 +612,29 @@ void ServiceCellular::registerMessageHandlers() } settings->setValue( settings::Cellular::volteEnabled, message->enable ? "1" : "0", settings::SettingsScope::Global); - if (not priv->volteHandler->switchVolte(*channel, message->enable)) { - auto notification = std::make_shared(priv->volteHandler->getVolteState()); - bus.sendMulticast(std::move(notification), sys::BusChannel::ServiceCellularNotifications); + try { + if (not priv->volteHandler->switchVolte(*channel, message->enable)) { + auto notification = + std::make_shared(priv->volteHandler->getVolteState()); + bus.sendMulticast(std::move(notification), sys::BusChannel::ServiceCellularNotifications); + priv->modemResetHandler->performHardReset(); + } + } + catch (std::runtime_error const &exc) { + LOG_ERROR("%s", exc.what()); priv->modemResetHandler->performHardReset(); } return sys::MessageNone{}; }); + connect(typeid(cellular::msg::notification::SimReady), [&](sys::Message *) { + if (priv->volteHandler->isFunctionalityResetNeeded()) { + LOG_INFO("First run after VoLTE switch, functionality reset needed"); + priv->modemResetHandler->performFunctionalityReset(); + } + return sys::MessageNone{}; + }); + handle_CellularGetChannelMessage(); } @@ -821,6 +834,7 @@ bool ServiceCellular::handle_power_down_waiting() bool ServiceCellular::handle_power_down() { LOG_DEBUG("Powered Down"); + priv->privDeinit(); cmux->closeChannels(); cmux.reset(); cmux = std::make_unique(PortSpeed_e::PS460800, this); @@ -892,23 +906,28 @@ bool ServiceCellular::handle_audio_conf_procedure() bool ServiceCellular::handle_cellular_priv_init() { auto channel = cmux->get(CellularMux::Channel::Commands); - priv->simCard->setChannel(channel); - priv->networkTime->setChannel(channel); - priv->simContacts->setChannel(channel); - priv->imeiGetHandler->setChannel(channel); + if (!channel) { + LOG_ERROR("no cmux channel provided"); + priv->modemResetHandler->performHardReset(); + return true; + } - bool needReset = false; + priv->privInit(channel); auto enableVolte = settings->getValue(settings::Cellular::volteEnabled, settings::SettingsScope::Global) == "1" ? true : false; - + bool volteNeedReset = false; try { - needReset = !priv->tetheringHandler->configure() || !priv->volteHandler->switchVolte(*channel, enableVolte); + volteNeedReset = !priv->volteHandler->switchVolte(*channel, enableVolte); + auto notification = std::make_shared(priv->volteHandler->getVolteState()); + bus.sendMulticast(std::move(notification), sys::BusChannel::ServiceCellularNotifications); } catch (std::runtime_error const &exc) { LOG_ERROR("%s", exc.what()); } - if (needReset) { + + auto tetheringNeedReset = !priv->tetheringHandler->configure(); + if (tetheringNeedReset || volteNeedReset) { priv->modemResetHandler->performHardReset(); return true; } @@ -1086,7 +1105,12 @@ auto ServiceCellular::receiveSMS(std::string messageNumber) -> bool bool ServiceCellular::getOwnNumber(std::string &destination) { - auto ret = cmux->get(CellularMux::Channel::Commands)->cmd(at::AT::CNUM); + auto channel = cmux->get(CellularMux::Channel::Commands); + if (not channel) { + LOG_ERROR("ServiceCellular::getOwnNumber failed because no cmux channel provided"); + return false; + } + auto ret = channel->cmd(at::AT::CNUM); if (ret) { auto begin = ret.response[0].find(','); @@ -1113,8 +1137,13 @@ bool ServiceCellular::getOwnNumber(std::string &destination) bool ServiceCellular::getIMSI(std::string &destination, bool fullNumber) { - auto ret = cmux->get(CellularMux::Channel::Commands)->cmd(at::AT::CIMI); + auto channel = cmux->get(CellularMux::Channel::Commands); + if (!channel) { + LOG_ERROR("no cmux channel provided"); + return false; + } + auto ret = channel->cmd(at::AT::CIMI); if (ret) { if (fullNumber) { destination = ret.response[0]; @@ -1253,9 +1282,13 @@ void save_SIM_detection_status(DLCChannel *channel) bool sim_check_hot_swap(DLCChannel *channel) { - assert(channel); bool reboot_needed = false; + if (!channel) { + LOG_ERROR("no cmux channel provided"); + return reboot_needed; + } + if (!is_SIM_detection_enabled(channel)) { reboot_needed = true; } @@ -1287,6 +1320,11 @@ bool ServiceCellular::handle_sim_sanity_check() bool ServiceCellular::handle_modem_on() { auto channel = cmux->get(CellularMux::Channel::Commands); + if (!channel) { + LOG_ERROR("no cmux channel provided"); + return false; + } + channel->cmd("AT+CCLK?"); // inform host ap ready cmux->informModemHostWakeup(); @@ -1299,6 +1337,11 @@ bool ServiceCellular::handle_modem_on() bool ServiceCellular::handle_URCReady() { auto channel = cmux->get(CellularMux::Channel::Commands); + if (!channel) { + LOG_ERROR("no cmux channel provided"); + return false; + } + bool ret = true; ret = ret && channel->cmd(at::AT::ENABLE_NETWORK_REGISTRATION_URC); @@ -1476,6 +1519,7 @@ void ServiceCellular::handle_CellularGetChannelMessage() auto getChannelMsg = static_cast(req); LOG_DEBUG("Handle request for channel: %s", CellularMux::name(getChannelMsg->dataChannel).c_str()); std::shared_ptr channelResponsMessage = + // MOS-809: find out if there's a need here for checking 'cmux' against nullptr std::make_shared(cmux->get(getChannelMsg->dataChannel)); LOG_DEBUG("channel ptr: %p", channelResponsMessage->dataChannelPtr); bus.sendUnicast(std::move(channelResponsMessage), req->sender); @@ -1869,7 +1913,13 @@ auto ServiceCellular::handleDBQueryResponseMessage(db::QueryResponse *msg) -> st auto ServiceCellular::handleCellularListCallsMessage(CellularMessage *msg) -> std::shared_ptr { at::cmd::CLCC cmd; - auto base = cmux->get(CellularMux::Channel::Commands)->cmd(cmd); + auto channel = cmux->get(CellularMux::Channel::Commands); + if (!channel) { + LOG_ERROR("no cmux channel provided"); + return std::make_shared(false); + } + + auto base = channel->cmd(cmd); if (auto response = cmd.parseCLCC(base); response) { const auto &data = response.getData(); auto it = std::find_if(std::begin(data), std::end(data), [&](const auto &entry) { diff --git a/module-services/service-cellular/call/api/ModemCallApi.cpp b/module-services/service-cellular/call/api/ModemCallApi.cpp index 7a6c0c615cab1b8db58f180dded8726bae48b2b9..bfc02bf3cc9d7afa2c497dc6b671e623fe614723 100644 --- a/module-services/service-cellular/call/api/ModemCallApi.cpp +++ b/module-services/service-cellular/call/api/ModemCallApi.cpp @@ -30,19 +30,31 @@ namespace cellular bool Api::hangupCall() { if (cmux == nullptr) { - throw std::runtime_error("call api not initialized"); + return false; } auto channel = cmux->get(CellularMux::Channel::Commands); - return channel != nullptr && channel->cmd(at::AT::ATH); + if (channel != nullptr) { + auto response = channel->cmd(at::AT::ATH); + if (response) { + return true; + } + } + return false; } bool Api::rejectCall() { if (cmux == nullptr) { - throw std::runtime_error("call api not initialized"); + return false; } auto channel = cmux->get(CellularMux::Channel::Commands); - return channel != nullptr && channel->cmd(at::AT::CHUP); + if (channel != nullptr) { + auto response = channel->cmd(at::AT::CHUP); + if (response) { + return true; + } + } + return false; } bool Api::areCallsFromFavouritesEnabled() diff --git a/module-services/service-cellular/service-cellular/CellularMessage.hpp b/module-services/service-cellular/service-cellular/CellularMessage.hpp index e3fc63e6fda738bf32b6bbd8e4b27c30ef44d656..c2fc123eef87d912c5d861d22a556d36a95a55cd 100644 --- a/module-services/service-cellular/service-cellular/CellularMessage.hpp +++ b/module-services/service-cellular/service-cellular/CellularMessage.hpp @@ -1059,7 +1059,7 @@ namespace cellular class GetVolteStateRequest : public sys::DataMessage {}; - struct GetVolteStateResponse : public sys::ResponseMessage + struct GetVolteStateResponse : public sys::DataMessage { VolteState volteState; explicit GetVolteStateResponse(VolteState volteState) : volteState(volteState) diff --git a/module-services/service-cellular/src/ModemResetHandler.cpp b/module-services/service-cellular/src/ModemResetHandler.cpp index 4626dc49e9d0475d620456f4ffb9ce54319d0708..5e3d09bb8488e4e607695019f97181143a5dfafb 100644 --- a/module-services/service-cellular/src/ModemResetHandler.cpp +++ b/module-services/service-cellular/src/ModemResetHandler.cpp @@ -87,4 +87,12 @@ namespace cellular::service onCellularStateSet(State::ST::StatusCheck); return true; } + + auto ModemResetHandler::performFunctionalityReset() -> bool + { + if (onFunctionalityReset) { + return onFunctionalityReset(); + } + return false; + } } // namespace cellular::service diff --git a/module-services/service-cellular/src/ModemResetHandler.hpp b/module-services/service-cellular/src/ModemResetHandler.hpp index 3f11c8c3033493cbeff89fdf05d8597afe44afce..fd7e8ba0f4b82c5292c90025851851cb5b1ca130 100644 --- a/module-services/service-cellular/src/ModemResetHandler.hpp +++ b/module-services/service-cellular/src/ModemResetHandler.hpp @@ -29,6 +29,11 @@ namespace cellular::service * @return */ auto performReboot() -> bool; + /** + * It performs functionality reset via AT command. It does not require cellular reinitialisation. + * @return true on success + */ + auto performFunctionalityReset() -> bool; /** * It handles STATUS pin changed event when any reset procedure is in progress, other case it's doing nothing. * @param isActive STATUS pin value. True when STATUS is active, false when it's inactive @@ -48,6 +53,7 @@ namespace cellular::service std::function onTurnModemOff; std::function onSoftReset; std::function onHardReset; + std::function onFunctionalityReset; private: enum class ProcedureInProgress diff --git a/module-services/service-cellular/src/ServiceCellularPriv.cpp b/module-services/service-cellular/src/ServiceCellularPriv.cpp index ba18301c45e61097cea71ddc049c692a8dc6d532..9b8143d705da670bd1079634588f777d43b05b08 100644 --- a/module-services/service-cellular/src/ServiceCellularPriv.cpp +++ b/module-services/service-cellular/src/ServiceCellularPriv.cpp @@ -91,7 +91,11 @@ namespace cellular::internal owner->bus.sendMulticast(); return sys::MessageNone{}; } - return std::make_shared(simCard->handleIsPinNeeded()); + auto simLockState = simCard->handleIsPinNeeded(); + if (!simLockState.has_value()) { + return sys::MessageNone{}; + } + return std::make_shared(simLockState.value()); }); owner->connect(typeid(request::sim::ChangePin), [&](sys::Message *request) -> sys::MessagePointer { auto msg = static_cast(request); @@ -255,7 +259,6 @@ namespace cellular::internal result = false; } else { - auto channel = owner->cmux->get(CellularMux::Channel::Commands); saveNewMultiPartSMSUIDCallback(multiPartSMSUID); for (unsigned i = 0; i < partHandler.getPartsCount(); i++) { @@ -400,6 +403,25 @@ namespace cellular::internal } return false; }; + + modemResetHandler->onFunctionalityReset = [this]() -> bool { + auto channel = owner->cmux->get(CellularMux::Channel::Commands); + if (channel == nullptr) { + return false; + } + auto succeed = false; + auto response = channel->cmd(at::AT::CFUN_DISABLE_TRANSMITTING); + if (response) { + succeed = true; + } + constexpr auto delay = 200; + vTaskDelay(pdMS_TO_TICKS(delay)); + response = channel->cmd(at::AT::CFUN_FULL_FUNCTIONALITY); + if (response) { + succeed |= true; + } + return succeed; + }; } void ServiceCellularPriv::initCSQHandler() @@ -552,4 +574,20 @@ namespace cellular::internal return sys::MessageNone{}; }); } + + void ServiceCellularPriv::privInit(at::BaseChannel *channel) + { + simCard->setChannel(channel); + networkTime->setChannel(channel); + simContacts->setChannel(channel); + imeiGetHandler->setChannel(channel); + } + + void ServiceCellularPriv::privDeinit() + { + simCard->setChannel(nullptr); + networkTime->setChannel(nullptr); + simContacts->setChannel(nullptr); + imeiGetHandler->setChannel(nullptr); + } } // namespace cellular::internal diff --git a/module-services/service-cellular/src/ServiceCellularPriv.hpp b/module-services/service-cellular/src/ServiceCellularPriv.hpp index 99fec1d9dfe512024a4ecd31a73d3bd365f362bf..a4886ebd500fe9cdefa1eea3fcbb50f97f4d7a3f 100644 --- a/module-services/service-cellular/src/ServiceCellularPriv.hpp +++ b/module-services/service-cellular/src/ServiceCellularPriv.hpp @@ -59,6 +59,9 @@ namespace cellular::internal void setInitialMultiPartSMSUID(std::uint8_t uid); std::function saveNewMultiPartSMSUIDCallback; + void privInit(at::BaseChannel *channel); + void privDeinit(); + private: void initSimCard(); void initSMSSendHandler(); diff --git a/module-services/service-cellular/src/SimCard.cpp b/module-services/service-cellular/src/SimCard.cpp index d0cacd27fc17142ea14d53e6a821467ff3e13ec6..67571c890c1f3a9e305f33ad0c22eabaaea4ac14 100644 --- a/module-services/service-cellular/src/SimCard.cpp +++ b/module-services/service-cellular/src/SimCard.cpp @@ -70,7 +70,7 @@ namespace cellular return true; } - bool SimCard::handleIsPinNeeded() const + std::optional SimCard::handleIsPinNeeded() const { return isPinNeeded(); } @@ -276,8 +276,12 @@ namespace cellular at::factory(at::AT::CLCK) + "\"SC\"," + (lock ? "1" : "0") + ",\"" + pin + "\""); } - bool SimCard::isPinNeeded() const + std::optional SimCard::isPinNeeded() const { + if (not ready()) { + return std::nullopt; + } + auto resp = channel->cmd(at::factory(at::AT::CLCK) + "\"SC\",2\r"); int val = 0; if (at::response::parseCLCK(resp, val)) { @@ -288,6 +292,10 @@ namespace cellular std::optional SimCard::simState() const { + if (not ready()) { + return at::SimState::Unknown; + } + auto resp = channel->cmd(at::factory(at::AT::GET_CPIN)); if (resp.code == at::Result::Code::OK) { if (resp.response.size()) { diff --git a/module-services/service-cellular/src/SimCard.hpp b/module-services/service-cellular/src/SimCard.hpp index 0af558ef36de6d22b170eff5c85148c5c62adbac..1fec431748177b31bc178d3f4f4bfaf16efa585d 100644 --- a/module-services/service-cellular/src/SimCard.hpp +++ b/module-services/service-cellular/src/SimCard.hpp @@ -84,7 +84,7 @@ namespace cellular::service * Request message handlers */ bool handleSetActiveSim(api::SimSlot sim); - bool handleIsPinNeeded() const; + std::optional handleIsPinNeeded() const; bool handleChangePin(const api::SimCode &old_pin, const api::SimCode &pin); bool handleUnblockWithPuk(const api::SimCode &puk, const api::SimCode &pin); bool handleSetPinLock(const api::SimCode &pin, api::SimPinState pinLock); @@ -231,10 +231,11 @@ namespace cellular::service */ sim::Result changePin(const std::string &oldPin, const std::string &newPin) const; - /** Check whether the pin needs to be provided, only for standard pin. - * \return true if need pin to unlock SIM card functionality + /** Check whether the PIN needs to be provided, only for standard PIN. + * \return true if need PIN to unlock SIM card functionality, false if don't need, std::nullopt if SIM card + * not ready */ - bool isPinNeeded() const; + std::optional isPinNeeded() const; /** Process sim::Result from PIN lock/unlock operations * \param result result from operation (`sendCommand()`) diff --git a/module-services/service-cellular/src/VolteHandler.hpp b/module-services/service-cellular/src/VolteHandler.hpp index 86a43cd520cd9c1946b487d76d0421e6d4fe57ba..68a3a746dff93e4ffd7a1f14145f0c8585862e8f 100644 --- a/module-services/service-cellular/src/VolteHandler.hpp +++ b/module-services/service-cellular/src/VolteHandler.hpp @@ -78,9 +78,15 @@ namespace cellular::service throw std::runtime_error("[VoLTE] failed to " + std::string(enable ? "enable" : "disable") + " IMS"); } + volteState = enable ? cellular::VolteState::SwitchingToOn : cellular::VolteState::SwitchingToOff; + isFirstRunAfterSwitch = false; } else { + if (volteState == cellular::VolteState::SwitchingToOn || + volteState == cellular::VolteState::SwitchingToOff) { + isFirstRunAfterSwitch = true; + } volteState = enable ? cellular::VolteState::On : cellular::VolteState::Off; } @@ -92,11 +98,18 @@ namespace cellular::service return volteState; } + auto isFunctionalityResetNeeded() -> bool + { + return isFirstRunAfterSwitch; + } + private: std::string imsStateToString(response::qcfg_ims::IMSState imsState) const { return std::to_string(magic_enum::enum_integer(imsState)); } + cellular::VolteState volteState = cellular::VolteState::Undefined; + bool isFirstRunAfterSwitch = false; }; } // namespace cellular::service diff --git a/pure_changelog.md b/pure_changelog.md index c7495883cdd0a7aa6d46eea7e709415e5dba57e7..40062811e8c5518bcd49c22495c7ddfec98dcaa2 100644 --- a/pure_changelog.md +++ b/pure_changelog.md @@ -42,7 +42,7 @@ * Added tethering information on the status bar * Added basic MMS handling * Added run-time statistics for tasks -* Added VoLTE state in settings database +* Added VoLTE support ## [1.3.0 2022-08-04]