M image/assets/lang/English.json => image/assets/lang/English.json +1 -0
@@ 217,6 217,7 @@
"app_desktop_screen_blocked_info": "Sorry, phone blocked",
"app_desktop_press_to_unlock": "<text>Press <b>Unlock</b> and then <b>#</b></text>",
"app_desktop_unread_messages": "<text>Unread <b>messages</b></text>",
+ "app_desktop_low_battery_notification": "<text>low battery level - GSM off</text>",
"app_desktop_missed_calls": "<text>Missed <b>calls</b></text>",
"app_desktop_menu_phone": "PHONE",
"app_desktop_menu_contacts": "CONTACTS",
M image/assets/lang/Polski.json => image/assets/lang/Polski.json +1 -0
@@ 70,6 70,7 @@
"app_desktop_pin_info2": "Pozostało prób",
"app_desktop_pin_blocked1": "Telefon zablokowany",
"app_desktop_unread_messages": "nieprzeczytane wiadomości",
+ "app_desktop_low_battery_notification": "<text>niski poziom baterii - moduł GSM wyłączony</text>",
"app_desktop_missed_calls": "nieodebrane połączenia",
"app_desktop_menu_phone": "TELEFON",
"app_desktop_menu_contacts": "KONTAKTY",
A image/user/db/settings_v2_001.sql => image/user/db/settings_v2_001.sql +43 -0
@@ 0,0 1,43 @@
+--
+-- Main settings table, for string application persistent data
+--
+CREATE TABLE IF NOT EXISTS settings_tab (
+ path TEXT NOT NULL UNIQUE PRIMARY KEY,
+ value TEXT
+);
+
+--
+-- Dictionary table, for variables with fixed set of values
+--
+CREATE TABLE IF NOT EXISTS dictionary_tab (
+ id INTEGER PRIMARY KEY,
+ path TEXT NOT NULL,
+ value TEXT,
+ CONSTRAINT dictionary_unique
+ UNIQUE (path, value) ON CONFLICT REPLACE
+ );
+
+--
+-- Table contains information who to inform
+-- about changes in values.
+--
+CREATE TABLE IF NOT EXISTS notifications_tab (
+ id INTEGER PRIMARY KEY,
+ path TEXT NOT NULL,
+ service TEXT,
+ CONSTRAINT notification_unique
+ UNIQUE(path, service)
+ );
+
+CREATE TABLE IF NOT EXISTS settings_changed_tab(
+
+ id INTEGER PRIMARY KEY,
+ path TEXT NOT NULL,
+ value TEXT,
+ CONSTRAINT changed_unique
+ UNIQUE(path ) ON CONFLICT REPLACE
+);
+
+CREATE TRIGGER IF NOT EXISTS on_update UPDATE OF value ON settings_tab
+WHEN new.value <> old.value BEGIN INSERT OR REPLACE INTO settings_changed_tab (path, value) VALUES (new.path,new.value); END;
+
M image/user/db/settings_v2_002.sql => image/user/db/settings_v2_002.sql +19 -42
@@ 1,43 1,20 @@
---
--- Main settings table, for string application persistent data
---
-CREATE TABLE IF NOT EXISTS settings_tab (
- path TEXT NOT NULL UNIQUE PRIMARY KEY,
- value TEXT
-);
-
---
--- Dictionary table, for variables with fixed set of values
---
-CREATE TABLE IF NOT EXISTS dictionary_tab (
- id INTEGER PRIMARY KEY,
- path TEXT NOT NULL,
- value TEXT,
- CONSTRAINT dictionary_unique
- UNIQUE (path, value) ON CONFLICT REPLACE
- );
-
---
--- Table contains information who to inform
--- about changes in values.
---
-CREATE TABLE IF NOT EXISTS notifications_tab (
- id INTEGER PRIMARY KEY,
- path TEXT NOT NULL,
- service TEXT,
- CONSTRAINT notification_unique
- UNIQUE(path, service)
- );
-
-CREATE TABLE IF NOT EXISTS settings_changed_tab(
-
- id INTEGER PRIMARY KEY,
- path TEXT NOT NULL,
- value TEXT,
- CONSTRAINT changed_unique
- UNIQUE(path ) ON CONFLICT REPLACE
-);
-
-CREATE TRIGGER IF NOT EXISTS on_update UPDATE OF value ON settings_tab
-WHEN new.value <> old.value BEGIN INSERT OR REPLACE INTO settings_changed_tab (path, value) VALUES (new.path,new.value); END;
+-- ----------- insert default values ----------------------
+INSERT OR REPLACE INTO dictionary_tab (path, value) VALUES
+ ('system/phone_mode', 'online'),
+ ('system/phone_mode', 'offline'),
+ ('system/phone_mode', 'dnd');
+-- ----------- insert default values -------------------
+INSERT OR IGNORE INTO settings_tab (path, value) VALUES
+ ('system/phone_mode', 'online'),
+ ('gs_time_format_12', '0'),
+ ('gs_time_date_format', '1'),
+ ('gs_active_sim', 'SIM1'),
+ ('gs_lock_pass_hash', '3333'),
+ ('gs_lock_time', '30000'),
+ ('gs_display_language', 'English'),
+ ('gs_input_language', 'English');
+ ('bt_state', '0'),
+ ('bt_device_visibility', '0'),
+ ('bt_device_name', 'PurePhone'),
+ ('bt_bonded_devices', '');
M module-apps/application-desktop/ApplicationDesktop.cpp => module-apps/application-desktop/ApplicationDesktop.cpp +16 -0
@@ 29,6 29,7 @@
#include <module-db/queries/notifications/QueryNotificationsClear.hpp>
#include <module-services/service-db/agents/settings/SystemSettings.hpp>
#include <module-utils/magic_enum/include/magic_enum.hpp>
+#include <SystemManager/messages/SystemManagerMessage.hpp>
#include <cassert>
namespace app
@@ 82,6 83,11 @@ namespace app
switchWindow(app::window::name::desktop_mmi_internal, std::move(data));
return msgHandled();
});
+
+ addActionReceiver(app::manager::actions::DisplayLowBatteryNotification, [this](auto &&data) {
+ handleLowBatteryNotification(std::move(data));
+ return msgHandled();
+ });
}
ApplicationDesktop::~ApplicationDesktop()
@@ 389,4 395,14 @@ namespace app
}
}
+ void ApplicationDesktop::handleLowBatteryNotification(manager::actions::ActionParamsPtr &&data)
+ {
+ auto actionData = static_cast<manager::actions::LowBatteryNotificationParams *>(data.get());
+ notifications.batteryLowLevel = actionData->getActiveState();
+ auto currentWindow = getCurrentWindow();
+ if (currentWindow->getName() == window::name::desktop_main_window) {
+ currentWindow->rebuild();
+ }
+ }
+
} // namespace app
M module-apps/application-desktop/ApplicationDesktop.hpp => module-apps/application-desktop/ApplicationDesktop.hpp +5 -1
@@ 44,6 44,8 @@ namespace app
Counters notSeen;
Counters notRead;
+ bool batteryLowLevel = false;
+
} notifications;
gui::PinLockHandler lockHandler;
@@ 87,6 89,7 @@ namespace app
private:
void activeSimChanged(std::string value);
void lockPassHashChanged(std::string value);
+ void handleLowBatteryNotification(manager::actions::ActionParamsPtr &&data);
unsigned int lockPassHash = 0;
};
@@ 103,7 106,8 @@ namespace app
manager::actions::ShowMMIResponse,
manager::actions::ShowMMIPush,
manager::actions::ShowMMIResult,
- manager::actions::DisplayCMEError}};
+ manager::actions::DisplayCMEError,
+ manager::actions::DisplayLowBatteryNotification}};
}
};
M module-apps/application-desktop/widgets/NotificationsBox.cpp => module-apps/application-desktop/widgets/NotificationsBox.cpp +24 -8
@@ 119,11 119,20 @@ namespace
return number;
}
+ void setNotificationHboxLayoutProperties(gui::HBox *hbox)
+ {
+ hbox->setAlignment(Alignment(gui::Alignment::Vertical::Center));
+ hbox->setMargins(gui::Margins(0, 0, 0, 10));
+ hbox->setPenWidth(style::window::default_border_no_focus_w);
+ hbox->setPenFocusWidth(style::window::default_border_focus_w);
+ hbox->setEdges(RectangleEdge::Bottom | RectangleEdge::Top);
+ }
+
} // namespace
-auto NotificationsBox::addNotification(UTF8 icon,
- UTF8 name,
- UTF8 indicator,
+auto NotificationsBox::addNotification(const UTF8 &icon,
+ const UTF8 &name,
+ const UTF8 &indicator,
std::function<bool()> showCallback,
std::function<bool()> clearCallback,
std::function<void(bool)> onFocus) -> bool
@@ 139,11 148,7 @@ auto NotificationsBox::addNotification(UTF8 icon,
el->addWidget(buildNotificationCountText(indicator));
// 3. Set hbox layout properties
- el->setAlignment(Alignment(gui::Alignment::Vertical::Center));
- el->setMargins(gui::Margins(0, 0, 0, 10));
- el->setPenWidth(style::window::default_border_no_focus_w);
- el->setPenFocusWidth(style::window::default_border_focus_w);
- el->setEdges(RectangleEdge::Bottom | RectangleEdge::Top);
+ setNotificationHboxLayoutProperties(el);
el->focusChangedCallback = [el, onFocus](Item &) -> bool {
onFocus(el->focus);
@@ 161,6 166,17 @@ auto NotificationsBox::addNotification(UTF8 icon,
return el->visible;
}
+auto NotificationsBox::addNotification(const UTF8 &icon, const UTF8 &name) -> bool
+{
+ auto el = new gui::HBox(this, 0, 0, style::window::default_body_width, style::window::label::default_h);
+
+ el->addWidget(buildNotificationIcon(icon));
+ el->addWidget(buildNotificationNameLabel(name, el->area().w));
+ setNotificationHboxLayoutProperties(el);
+
+ return el->visible;
+}
+
bool NotificationsBox::onInput(const InputEvent &inputEvent)
{
M module-apps/application-desktop/widgets/NotificationsBox.hpp => module-apps/application-desktop/widgets/NotificationsBox.hpp +5 -3
@@ 13,13 13,15 @@ namespace gui
public:
NotificationsBox(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
- auto addNotification(UTF8 icon,
- UTF8 name,
- UTF8 indicator,
+ auto addNotification(const UTF8 &icon,
+ const UTF8 &name,
+ const UTF8 &indicator,
std::function<bool()> showCallback,
std::function<bool()> clearCallback,
std::function<void(bool)> onFocus) -> bool;
+ auto addNotification(const UTF8 &icon, const UTF8 &name) -> bool;
+
bool onInput(const InputEvent &inputEvent) override;
bool clearAll(const InputEvent &event);
M module-apps/application-desktop/windows/DesktopMainWindow.cpp => module-apps/application-desktop/windows/DesktopMainWindow.cpp +3 -0
@@ 270,6 270,9 @@ namespace gui
bottomBar->setActive(BottomBar::Side::LEFT, !isFocused);
};
+ if (app->notifications.batteryLowLevel) {
+ notifications->addNotification("battery1_W_M", utils::localize.get("app_desktop_low_battery_notification"));
+ }
if (app->notifications.notSeen.Calls > 0) {
notifications->addNotification(
"phone",
M module-services/service-appmgr/model/ApplicationManager.cpp => module-services/service-appmgr/model/ApplicationManager.cpp +2 -0
@@ 10,6 10,7 @@
#include <Service/Message.hpp>
#include <Service/Timer.hpp>
#include <SystemManager/SystemManager.hpp>
+#include <SystemManager/messages/SystemManagerMessage.hpp>
#include <application-call/ApplicationCall.hpp>
#include <application-special-input/ApplicationSpecialInput.hpp>
#include <i18n/i18n.hpp>
@@ 246,6 247,7 @@ namespace app::manager
connect(typeid(CellularMMIResultMessage), convertibleToActionHandler);
connect(typeid(CellularMMIResponseMessage), convertibleToActionHandler);
connect(typeid(CellularMMIPushMessage), convertibleToActionHandler);
+ connect(typeid(sys::CriticalBatteryLevelNotification), convertibleToActionHandler);
}
sys::ReturnCodes ApplicationManager::SwitchPowerModeHandler(const sys::ServicePowerMode mode)
M module-services/service-appmgr/service-appmgr/Actions.hpp => module-services/service-appmgr/service-appmgr/Actions.hpp +1 -0
@@ 47,6 47,7 @@ namespace app::manager
ShowMMIResponse,
ShowMMIPush,
DisplayCMEError,
+ DisplayLowBatteryNotification,
UserAction // The last enumerator in the Action enum.
// All user-defined actions shall have values greater than UserAction.
// All system-wide actions shall have values lesser than UserAction.
M module-services/service-cellular/CellularServiceAPI.cpp => module-services/service-cellular/CellularServiceAPI.cpp +7 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "service-cellular/CellularMessage.hpp"
@@ 347,3 347,9 @@ bool CellularServiceAPI::SetVoLTE(sys::Service *serv, bool voLTE)
return sys::Bus::SendUnicast(
std::make_shared<CellularChangeVoLTEDataMessage>(voLTE), ServiceCellular::serviceName, serv);
}
+
+bool CellularServiceAPI::ChangeModulePowerState(sys::Service *serv, cellular::State::PowerState newState)
+{
+ return sys::Bus::SendUnicast(
+ std::make_shared<CellularPowerStateChange>(newState), ServiceCellular::serviceName, serv);
+}
M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +112 -17
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "CellularUrcHandler.hpp"
@@ 94,12 94,18 @@ const char *State::c_str(State::ST state)
switch (state) {
case ST::Idle:
return "Idle";
+ case ST::WaitForStartPermission:
+ return "WaitForStartPermission";
+ case ST::PowerUpRequest:
+ return "PowerUpRequest";
case ST::StatusCheck:
return "StatusCheck";
case ST::PowerUpInProgress:
return "PowerUpInProgress";
case ST::PowerUpProcedure:
return "PowerUpProcedure";
+ case ST::BaudDetect:
+ return "BaudDetect";
case ST::AudioConfigurationProcedure:
return "AudioConfigurationProcedure";
case ST::APNConfProcedure:
@@ 226,21 232,8 @@ void ServiceCellular::CallStateTimerHandler()
sys::ReturnCodes ServiceCellular::InitHandler()
{
board = EventManagerServiceAPI::GetBoard(this);
- cmux->SelectAntenna(bsp::cellular::antenna::lowBand);
- switch (board) {
- case bsp::Board::T4:
- state.set(this, State::ST::StatusCheck);
- break;
- case bsp::Board::T3:
- state.set(this, State::ST::PowerUpProcedure);
- break;
- case bsp::Board::Linux:
- state.set(this, State::ST::PowerUpProcedure);
- break;
- default:
- return sys::ReturnCodes::Failure;
- break;
- }
+
+ state.set(this, State::ST::WaitForStartPermission);
return sys::ReturnCodes::Success;
}
@@ 345,6 338,12 @@ void ServiceCellular::registerMessageHandlers()
return std::make_shared<CellularResponseMessage>(true);
});
+ connect(typeid(CellularPowerStateChange), [&](sys::Message *request) -> sys::MessagePointer {
+ auto msg = static_cast<CellularPowerStateChange *>(request);
+ nextPowerState = msg->getNewState();
+ handle_power_state_change();
+ return sys::MessageNone{};
+ });
handle_CellularGetChannelMessage();
}
@@ 385,6 384,12 @@ void ServiceCellular::change_state(cellular::StateChange *msg)
case State::ST::Idle:
handle_idle();
break;
+ case State::ST::WaitForStartPermission:
+ handle_wait_for_start_permission();
+ break;
+ case State::ST::PowerUpRequest:
+ handle_power_up_request();
+ break;
case State::ST::StatusCheck:
handle_status_check();
break;
@@ 394,6 399,14 @@ void ServiceCellular::change_state(cellular::StateChange *msg)
case State::ST::PowerUpProcedure:
handle_power_up_procedure();
break;
+ case State::ST::BaudDetect:
+ if (nextPowerStateChangeAwaiting) {
+ handle_power_state_change();
+ }
+ else {
+ handle_baud_detect();
+ }
+ break;
case State::ST::AudioConfigurationProcedure:
handle_audio_conf_procedure();
break;
@@ 435,6 448,9 @@ void ServiceCellular::change_state(cellular::StateChange *msg)
break;
case State::ST::PowerDown:
handle_power_down();
+ if (nextPowerStateChangeAwaiting) {
+ handle_power_state_change();
+ }
break;
};
}
@@ 445,6 461,34 @@ bool ServiceCellular::handle_idle()
return true;
}
+bool ServiceCellular::handle_wait_for_start_permission()
+{
+ auto msg = std::make_shared<CellularCheckIfStartAllowedMessage>();
+ sys::Bus::SendUnicast(msg, service::name::system_manager, this);
+
+ return true;
+}
+
+bool ServiceCellular::handle_power_up_request()
+{
+ cmux->SelectAntenna(bsp::cellular::antenna::lowBand);
+ switch (board) {
+ case bsp::Board::T4:
+ state.set(this, State::ST::StatusCheck);
+ break;
+ case bsp::Board::T3:
+ state.set(this, State::ST::PowerUpProcedure);
+ break;
+ case bsp::Board::Linux:
+ state.set(this, State::ST::PowerUpProcedure);
+ break;
+ case bsp::Board::none:
+ return false;
+ break;
+ }
+ return true;
+}
+
bool ServiceCellular::handle_power_up_procedure()
{
switch (board) {
@@ 510,6 554,13 @@ bool ServiceCellular::handle_power_up_in_progress_procedure(void)
vTaskDelay(pdMS_TO_TICKS(msModemUartInitTime));
isAfterForceReboot = false;
}
+
+ state.set(this, cellular::State::ST::BaudDetect);
+ return true;
+}
+
+bool ServiceCellular::handle_baud_detect()
+{
auto ret = cmux->BaudDetectProcedure();
if (ret == TS0710::ConfState::Success) {
state.set(this, cellular::State::ST::CellularConfProcedure);
@@ 552,7 603,7 @@ bool ServiceCellular::handle_power_down()
isAfterForceReboot = true;
cmux.reset();
cmux = std::make_unique<TS0710>(PortSpeed_e::PS460800, this);
- InitHandler();
+
return true;
}
@@ 1975,6 2026,50 @@ void ServiceCellular::handleStateTimer(void)
}
}
+void ServiceCellular::handle_power_state_change()
+{
+ nextPowerStateChangeAwaiting = false;
+ auto modemActive = cmux->IsModemActive();
+
+ if (nextPowerState == State::PowerState::On) {
+ if (state.get() == State::ST::PowerDownWaiting) {
+ LOG_DEBUG("Powerdown in progress. Powerup request queued.");
+ nextPowerStateChangeAwaiting = true;
+ }
+ else if (state.get() == State::ST::PowerUpProcedure || state.get() == State::ST::PowerUpInProgress) {
+ LOG_DEBUG("Powerup already in progress");
+ }
+ else if (state.get() == State::ST::PowerDown || state.get() == State::ST::WaitForStartPermission) {
+ LOG_INFO("Modem Power UP.");
+ state.set(this, State::ST::PowerUpRequest);
+ }
+ else {
+ LOG_DEBUG("Modem already powered up.");
+ }
+ }
+ else {
+ if (state.get() == State::ST::PowerUpProcedure || state.get() == State::ST::PowerUpInProgress) {
+ LOG_DEBUG("Powerup in progress. Powerdown request queued.");
+ nextPowerStateChangeAwaiting = true;
+ }
+ else if (state.get() == State::ST::PowerDownWaiting) {
+ LOG_DEBUG("Powerdown already in progress.");
+ }
+ else if (state.get() == State::ST::PowerDown) {
+ LOG_DEBUG("Modem already powered down.");
+ }
+ else if (state.get() == State::ST::WaitForStartPermission && !modemActive) {
+ LOG_DEBUG("Modem already powered down.");
+ state.set(this, State::ST::PowerDown);
+ }
+ else {
+ LOG_INFO("Modem Power DOWN.");
+ cmux->TurnOffModem();
+ state.set(this, State::ST::PowerDownWaiting);
+ }
+ }
+}
+
bool ServiceCellular::handleUSSDRequest(CellularUSSDMessage::RequestType requestType, const std::string &request)
{
constexpr uint32_t commandTimeout = 120000;
A module-services/service-cellular/doc/README.md => module-services/service-cellular/doc/README.md +12 -0
@@ 0,0 1,12 @@
+## Service Cellular state machine
+
+Full state machine of Cellular service could be found below.
+
+
+
+## GSM powerup/powerdown control flow
+
+In order to protect system of sudden blackout, GSM module has to be switched off below certain critical battery level.
+This way system voltage will not be dropped down when module is trying to acheive cellular network connection.
+
+<
\ No newline at end of file
A module-services/service-cellular/doc/cellular_gsm_onoff_flow.puml => module-services/service-cellular/doc/cellular_gsm_onoff_flow.puml +62 -0
@@ 0,0 1,62 @@
+@startuml
+
+participant "Battery level check" as batt
+participant "System Manager" as sysmgr
+participant "Service Cellular" as cell
+participant "Application Manager" as appmgr
+participant "ApplicaionDesktop" as appdsktp
+
+== Initial check ==
+
+ activate cell
+ cell -> sysmgr : CellularCheckIfStartAllowedMessage
+ activate sysmgr
+ sysmgr -> batt : BatteryLevelCriticalCheckMessage
+ activate batt
+ batt -> sysmgr : BatteryLevelCriticalMessage
+ deactivate batt
+ sysmgr -> cell : CellularPowerStateChange(Off)
+ cell -> cell : handle_power_state_change
+ sysmgr -> appmgr : CriticalBatteryLevelNotification(true)
+ deactivate cell
+ deactivate sysmgr
+ activate appmgr
+ appmgr -> appdsktp : actions::DisplayLowBatteryNotification
+ deactivate appmgr
+alt
+ activate cell
+ cell -> sysmgr : CellularCheckIfStartAllowedMessage
+ activate sysmgr
+ sysmgr -> batt : BatteryLevelNormalCheckMessage
+ activate batt
+ batt -> sysmgr : BatteryLevelCriticalMessage
+ deactivate batt
+ sysmgr -> cell : CellularPowerStateChange(On)
+ cell -> cell : handle_power_state_change
+ sysmgr -> appmgr : CriticalBatteryLevelNotification(false)
+ deactivate cell
+ deactivate sysmgr
+end
+
+== Normal flow ==
+ batt -> sysmgr : BatteryLevelCriticalMessage
+ activate sysmgr
+ sysmgr -> cell : CellularPowerStateChange(Off)
+ activate cell
+ cell -> cell : handle_power_state_change
+ sysmgr -> appmgr : CriticalBatteryLevelNotification(true)
+ deactivate cell
+ activate appmgr
+ appmgr -> appdsktp : actions::DisplayLowBatteryNotification
+ deactivate appmgr
+alt
+ batt -> sysmgr : BatteryLevelNormalMessage
+ activate sysmgr
+ sysmgr -> cell : CellularPowerStateChange(On)
+ activate cell
+ cell -> cell : handle_power_state_change
+ sysmgr -> appmgr : CriticalBatteryLevelNotification(false)
+ deactivate cell
+end
+
+@enduml
A module-services/service-cellular/doc/cellular_gsm_onoff_flow.svg => module-services/service-cellular/doc/cellular_gsm_onoff_flow.svg +72 -0
@@ 0,0 1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="945px" preserveAspectRatio="none" style="width:1168px;height:945px;" version="1.1" viewBox="0 0 1168 945" width="1168px" zoomAndPan="magnify"><defs><filter height="300%" id="f17c9soi04i4ed" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="29.1328" style="stroke:#A80036;stroke-width:1.0;" width="10" x="89" y="143.6953"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="29.1328" style="stroke:#A80036;stroke-width:1.0;" width="10" x="89" y="384.7578"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="158.6641" style="stroke:#A80036;stroke-width:1.0;" width="10" x="341" y="114.5625"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="158.6641" style="stroke:#A80036;stroke-width:1.0;" width="10" x="341" y="355.625"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="299.1953" style="stroke:#A80036;stroke-width:1.0;" width="10" x="341" y="593.5547"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="116.3984" style="stroke:#A80036;stroke-width:1.0;" width="10" x="346" y="776.3516"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="222.9297" style="stroke:#A80036;stroke-width:1.0;" width="10" x="600" y="50.2969"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="211.9297" style="stroke:#A80036;stroke-width:1.0;" width="10" x="600" y="302.3594"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="71.2656" style="stroke:#A80036;stroke-width:1.0;" width="10" x="600" y="622.6875"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="71.2656" style="stroke:#A80036;stroke-width:1.0;" width="10" x="600" y="805.4844"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="29.1328" style="stroke:#A80036;stroke-width:1.0;" width="10" x="806" y="273.2266"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="29.1328" style="stroke:#A80036;stroke-width:1.0;" width="10" x="806" y="693.9531"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="204.9297" style="stroke:#000000;stroke-width:2.0;" width="889.5" x="10" y="317.3594"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="146.6641" style="stroke:#000000;stroke-width:2.0;" width="889.5" x="10" y="738.0859"/><line style="stroke:#A80036;stroke-width:1.0;stroke-dasharray:5.0,5.0;" x1="94" x2="94" y1="40.2969" y2="901.75"/><line style="stroke:#A80036;stroke-width:1.0;stroke-dasharray:5.0,5.0;" x1="345.5" x2="345.5" y1="40.2969" y2="901.75"/><line style="stroke:#A80036;stroke-width:1.0;stroke-dasharray:5.0,5.0;" x1="605" x2="605" y1="40.2969" y2="901.75"/><line style="stroke:#A80036;stroke-width:1.0;stroke-dasharray:5.0,5.0;" x1="810.5" x2="810.5" y1="40.2969" y2="901.75"/><line style="stroke:#A80036;stroke-width:1.0;stroke-dasharray:5.0,5.0;" x1="1082.5" x2="1082.5" y1="40.2969" y2="901.75"/><rect fill="#FEFECE" filter="url(#f17c9soi04i4ed)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="144" x="20" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="130" x="27" y="24.9951">Battery level check</text><rect fill="#FEFECE" filter="url(#f17c9soi04i4ed)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="144" x="20" y="900.75"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="130" x="27" y="920.7451">Battery level check</text><rect fill="#FEFECE" filter="url(#f17c9soi04i4ed)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="129" x="279.5" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="115" x="286.5" y="24.9951">System Manager</text><rect fill="#FEFECE" filter="url(#f17c9soi04i4ed)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="129" x="279.5" y="900.75"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="115" x="286.5" y="920.7451">System Manager</text><rect fill="#FEFECE" filter="url(#f17c9soi04i4ed)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="118" x="544" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="104" x="551" y="24.9951">Service Cellular</text><rect fill="#FEFECE" filter="url(#f17c9soi04i4ed)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="118" x="544" y="900.75"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="104" x="551" y="920.7451">Service Cellular</text><rect fill="#FEFECE" filter="url(#f17c9soi04i4ed)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="153" x="732.5" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="139" x="739.5" y="24.9951">Application Manager</text><rect fill="#FEFECE" filter="url(#f17c9soi04i4ed)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="153" x="732.5" y="900.75"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="139" x="739.5" y="920.7451">Application Manager</text><rect fill="#FEFECE" filter="url(#f17c9soi04i4ed)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="143" x="1009.5" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="129" x="1016.5" y="24.9951">ApplicaionDesktop</text><rect fill="#FEFECE" filter="url(#f17c9soi04i4ed)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="143" x="1009.5" y="900.75"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="129" x="1016.5" y="920.7451">ApplicaionDesktop</text><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="29.1328" style="stroke:#A80036;stroke-width:1.0;" width="10" x="89" y="143.6953"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="29.1328" style="stroke:#A80036;stroke-width:1.0;" width="10" x="89" y="384.7578"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="158.6641" style="stroke:#A80036;stroke-width:1.0;" width="10" x="341" y="114.5625"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="158.6641" style="stroke:#A80036;stroke-width:1.0;" width="10" x="341" y="355.625"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="299.1953" style="stroke:#A80036;stroke-width:1.0;" width="10" x="341" y="593.5547"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="116.3984" style="stroke:#A80036;stroke-width:1.0;" width="10" x="346" y="776.3516"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="222.9297" style="stroke:#A80036;stroke-width:1.0;" width="10" x="600" y="50.2969"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="211.9297" style="stroke:#A80036;stroke-width:1.0;" width="10" x="600" y="302.3594"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="71.2656" style="stroke:#A80036;stroke-width:1.0;" width="10" x="600" y="622.6875"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="71.2656" style="stroke:#A80036;stroke-width:1.0;" width="10" x="600" y="805.4844"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="29.1328" style="stroke:#A80036;stroke-width:1.0;" width="10" x="806" y="273.2266"/><rect fill="#FFFFFF" filter="url(#f17c9soi04i4ed)" height="29.1328" style="stroke:#A80036;stroke-width:1.0;" width="10" x="806" y="693.9531"/><rect fill="#EEEEEE" filter="url(#f17c9soi04i4ed)" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1161.5" x="0" y="70.8633"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1161.5" y1="70.8633" y2="70.8633"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1161.5" y1="73.8633" y2="73.8633"/><rect fill="#EEEEEE" filter="url(#f17c9soi04i4ed)" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="107" x="527.25" y="60.2969"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="88" x="533.25" y="76.3638">Initial check</text><polygon fill="#A80036" points="362,110.5625,352,114.5625,362,118.5625,358,114.5625" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="356" x2="599" y1="114.5625" y2="114.5625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="230" x="368" y="109.4966">CellularCheckIfStartAllowedMessage</text><polygon fill="#A80036" points="110,139.6953,100,143.6953,110,147.6953,106,143.6953" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="104" x2="340" y1="143.6953" y2="143.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="219" x="116" y="138.6294">BatteryLevelCriticalCheckMessage</text><polygon fill="#A80036" points="329,168.8281,339,172.8281,329,176.8281,333,172.8281" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="94" x2="335" y1="172.8281" y2="172.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="180" x="101" y="167.7622">BatteryLevelCriticalMessage</text><polygon fill="#A80036" points="588,197.9609,598,201.9609,588,205.9609,592,201.9609" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="351" x2="594" y1="201.9609" y2="201.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="197" x="358" y="196.895">CellularPowerStateChange(Off)</text><line style="stroke:#A80036;stroke-width:1.0;" x1="610" x2="652" y1="231.0938" y2="231.0938"/><line style="stroke:#A80036;stroke-width:1.0;" x1="652" x2="652" y1="231.0938" y2="244.0938"/><line style="stroke:#A80036;stroke-width:1.0;" x1="611" x2="652" y1="244.0938" y2="244.0938"/><polygon fill="#A80036" points="621,240.0938,611,244.0938,621,248.0938,617,244.0938" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="182" x="617" y="226.0278">handle_power_state_change</text><polygon fill="#A80036" points="794,269.2266,804,273.2266,794,277.2266,798,273.2266" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="346" x2="800" y1="273.2266" y2="273.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="231" x="353" y="268.1606">CriticalBatteryLevelNotification(true)</text><polygon fill="#A80036" points="1071,298.3594,1081,302.3594,1071,306.3594,1075,302.3594" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="811" x2="1077" y1="302.3594" y2="302.3594"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="243" x="818" y="297.2935">actions::DisplayLowBatteryNotification</text><path d="M10,317.3594 L74,317.3594 L74,324.3594 L64,334.3594 L10,334.3594 L10,317.3594 " fill="#EEEEEE" style="stroke:#000000;stroke-width:1.0;"/><rect fill="none" height="204.9297" style="stroke:#000000;stroke-width:2.0;" width="889.5" x="10" y="317.3594"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="19" x="25" y="330.4263">alt</text><polygon fill="#A80036" points="362,351.625,352,355.625,362,359.625,358,355.625" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="356" x2="599" y1="355.625" y2="355.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="230" x="368" y="350.5591">CellularCheckIfStartAllowedMessage</text><polygon fill="#A80036" points="110,380.7578,100,384.7578,110,388.7578,106,384.7578" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="104" x2="340" y1="384.7578" y2="384.7578"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="223" x="116" y="379.6919">BatteryLevelNormalCheckMessage</text><polygon fill="#A80036" points="329,409.8906,339,413.8906,329,417.8906,333,413.8906" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="94" x2="335" y1="413.8906" y2="413.8906"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="180" x="101" y="408.8247">BatteryLevelCriticalMessage</text><polygon fill="#A80036" points="588,439.0234,598,443.0234,588,447.0234,592,443.0234" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="351" x2="594" y1="443.0234" y2="443.0234"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="197" x="358" y="437.9575">CellularPowerStateChange(On)</text><line style="stroke:#A80036;stroke-width:1.0;" x1="610" x2="652" y1="472.1563" y2="472.1563"/><line style="stroke:#A80036;stroke-width:1.0;" x1="652" x2="652" y1="472.1563" y2="485.1563"/><line style="stroke:#A80036;stroke-width:1.0;" x1="611" x2="652" y1="485.1563" y2="485.1563"/><polygon fill="#A80036" points="621,481.1563,611,485.1563,621,489.1563,617,485.1563" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="182" x="617" y="467.0903">handle_power_state_change</text><polygon fill="#A80036" points="799,510.2891,809,514.2891,799,518.2891,803,514.2891" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="346" x2="805" y1="514.2891" y2="514.2891"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="235" x="353" y="509.2231">CriticalBatteryLevelNotification(false)</text><rect fill="#EEEEEE" filter="url(#f17c9soi04i4ed)" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1161.5" x="0" y="549.8555"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1161.5" y1="549.8555" y2="549.8555"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1161.5" y1="552.8555" y2="552.8555"/><rect fill="#EEEEEE" filter="url(#f17c9soi04i4ed)" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="108" x="526.75" y="539.2891"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="89" x="532.75" y="555.356">Normal flow</text><polygon fill="#A80036" points="329,589.5547,339,593.5547,329,597.5547,333,593.5547" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="94" x2="335" y1="593.5547" y2="593.5547"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="180" x="101" y="588.4888">BatteryLevelCriticalMessage</text><polygon fill="#A80036" points="588,618.6875,598,622.6875,588,626.6875,592,622.6875" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="351" x2="594" y1="622.6875" y2="622.6875"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="197" x="358" y="617.6216">CellularPowerStateChange(Off)</text><line style="stroke:#A80036;stroke-width:1.0;" x1="610" x2="652" y1="651.8203" y2="651.8203"/><line style="stroke:#A80036;stroke-width:1.0;" x1="652" x2="652" y1="651.8203" y2="664.8203"/><line style="stroke:#A80036;stroke-width:1.0;" x1="611" x2="652" y1="664.8203" y2="664.8203"/><polygon fill="#A80036" points="621,660.8203,611,664.8203,621,668.8203,617,664.8203" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="182" x="617" y="646.7544">handle_power_state_change</text><polygon fill="#A80036" points="794,689.9531,804,693.9531,794,697.9531,798,693.9531" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="351" x2="800" y1="693.9531" y2="693.9531"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="231" x="358" y="688.8872">CriticalBatteryLevelNotification(true)</text><polygon fill="#A80036" points="1071,719.0859,1081,723.0859,1071,727.0859,1075,723.0859" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="811" x2="1077" y1="723.0859" y2="723.0859"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="243" x="818" y="718.02">actions::DisplayLowBatteryNotification</text><path d="M10,738.0859 L74,738.0859 L74,745.0859 L64,755.0859 L10,755.0859 L10,738.0859 " fill="#EEEEEE" style="stroke:#000000;stroke-width:1.0;"/><rect fill="none" height="146.6641" style="stroke:#000000;stroke-width:2.0;" width="889.5" x="10" y="738.0859"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="19" x="25" y="751.1528">alt</text><polygon fill="#A80036" points="334,772.3516,344,776.3516,334,780.3516,338,776.3516" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="94" x2="340" y1="776.3516" y2="776.3516"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="184" x="101" y="771.2856">BatteryLevelNormalMessage</text><polygon fill="#A80036" points="588,801.4844,598,805.4844,588,809.4844,592,805.4844" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="356" x2="594" y1="805.4844" y2="805.4844"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="197" x="363" y="800.4185">CellularPowerStateChange(On)</text><line style="stroke:#A80036;stroke-width:1.0;" x1="610" x2="652" y1="834.6172" y2="834.6172"/><line style="stroke:#A80036;stroke-width:1.0;" x1="652" x2="652" y1="834.6172" y2="847.6172"/><line style="stroke:#A80036;stroke-width:1.0;" x1="611" x2="652" y1="847.6172" y2="847.6172"/><polygon fill="#A80036" points="621,843.6172,611,847.6172,621,851.6172,617,847.6172" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="182" x="617" y="829.5513">handle_power_state_change</text><polygon fill="#A80036" points="799,872.75,809,876.75,799,880.75,803,876.75" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="356" x2="805" y1="876.75" y2="876.75"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="235" x="363" y="871.6841">CriticalBatteryLevelNotification(false)</text><!--MD5=[4d4302522169880a6f8cbf95a6a95f20]
+@startuml
+
+participant "Battery level check" as batt
+participant "System Manager" as sysmgr
+participant "Service Cellular" as cell
+participant "Application Manager" as appmgr
+participant "ApplicaionDesktop" as appdsktp
+
+== Initial check ==
+
+ activate cell
+ cell -> sysmgr : CellularCheckIfStartAllowedMessage
+ activate sysmgr
+ sysmgr -> batt : BatteryLevelCriticalCheckMessage
+ activate batt
+ batt -> sysmgr : BatteryLevelCriticalMessage
+ deactivate batt
+ sysmgr -> cell : CellularPowerStateChange(Off)
+ cell -> cell : handle_power_state_change
+ sysmgr -> appmgr : CriticalBatteryLevelNotification(true)
+ deactivate cell
+ deactivate sysmgr
+ activate appmgr
+ appmgr -> appdsktp : actions::DisplayLowBatteryNotification
+ deactivate appmgr
+alt
+ activate cell
+ cell -> sysmgr : CellularCheckIfStartAllowedMessage
+ activate sysmgr
+ sysmgr -> batt : BatteryLevelNormalCheckMessage
+ activate batt
+ batt -> sysmgr : BatteryLevelCriticalMessage
+ deactivate batt
+ sysmgr -> cell : CellularPowerStateChange(On)
+ cell -> cell : handle_power_state_change
+ sysmgr -> appmgr : CriticalBatteryLevelNotification(false)
+ deactivate cell
+ deactivate sysmgr
+end
+
+== Normal flow ==
+ batt -> sysmgr : BatteryLevelCriticalMessage
+ activate sysmgr
+ sysmgr -> cell : CellularPowerStateChange(Off)
+ activate cell
+ cell -> cell : handle_power_state_change
+ sysmgr -> appmgr : CriticalBatteryLevelNotification(true)
+ deactivate cell
+ activate appmgr
+ appmgr -> appdsktp : actions::DisplayLowBatteryNotification
+ deactivate appmgr
+alt
+ batt -> sysmgr : BatteryLevelNormalMessage
+ activate sysmgr
+ sysmgr -> cell : CellularPowerStateChange(On)
+ activate cell
+ cell -> cell : handle_power_state_change
+ sysmgr -> appmgr : CriticalBatteryLevelNotification(false)
+ deactivate cell
+end
+
+@enduml
+
+PlantUML version 1.2020.22(Sun Dec 06 10:36:27 CET 2020)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: pl
+Country: PL
+--></g></svg><
\ No newline at end of file
A module-services/service-cellular/doc/cellular_state_machine.puml => module-services/service-cellular/doc/cellular_state_machine.puml +75 -0
@@ 0,0 1,75 @@
+@startuml
+
+[*] --> WaitForStartPermission
+
+WaitForStartPermission -> PowerDown : PowerDownRequest && !isModemActive
+
+WaitForStartPermission --> PowerUpRequest : PowerUpRequest
+
+PowerDown --> PowerUpRequest : PowerUpRequest
+
+PowerUpRequest --> PowerUpProcedure : board == T3 | Linux
+
+PowerUpRequest -> StatusCheck : board == T4
+
+StatusCheck --> PowerUpInPorgress : modemActive
+
+StatusCheck -> PowerUpProcedure : !modemActive
+
+PowerUpProcedure --> CellularConfProcedure : hotStart
+
+PowerUpProcedure --> PowerUpInPorgress : coldStart || event: modem ACTIVE
+
+PowerUpInPorgress --> BaudDetect
+
+BaudDetect -> CellularConfProcedure : Success
+
+BaudDetect --> ModemFatalFailure : Failure
+
+CellularConfProcedure --> AudioConfigurationProcedure : Success
+
+CellularConfProcedure -> Failed : Failed
+
+AudioConfigurationProcedure -> AudioConfigurationProcedure : Failed
+
+AudioConfigurationProcedure --> Failed : Baud setup fail
+
+AudioConfigurationProcedure ---> Idle : reset called
+
+AudioConfigurationProcedure --> APNConfProcedure : Success
+
+APNConfProcedure --> SanityCheck
+
+SanityCheck --> ModemOn : Success
+
+SanityCheck --> ModemFatalFailure : Failure
+
+ModemOn -> URCReady
+
+Event:CellularSimProcedure --> SimSelect
+
+Event:SIM_READY --> SimInit
+
+SimInit --> Failed : Failure
+
+SimInit --> Ready : Success
+
+Event:PowerDownDeregistering --> PowerDownStarted : state != PowerDownWaiting
+
+Event:PowerDownDeregistered --> PowerDownWaiting
+
+Event:PowerDownRequest -> PowerDownWaiting
+
+PowerDownWaiting ---> PowerDown : (If T3 && timeout) \n || Event:modemInactive
+
+PowerDown --> PowerUpRequest : nextPowerStateChangeAwaiting \n && nextPowerState == on
+
+BaudDetect ---> PowerDownWaiting : nextPowerStateChangeAwaiting \n && nextPowerState == off
+
+Event:PowerUpProcedureComplete --> CellularConfProcedure : board == T3 || Linux
+
+Event:modemActive --> PowerDown : state != PowerUpProcedure
+
+Event:powerDownRequest --> PowerDown : state != PowerDown,PowerDownWaiting,\n PowerUpProcedure,PowerUpInProgress
+
+@enduml<
\ No newline at end of file
A module-services/service-cellular/doc/cellular_state_machine.svg => module-services/service-cellular/doc/cellular_state_machine.svg +121 -0
@@ 0,0 1,121 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="1228px" preserveAspectRatio="none" style="width:1673px;height:1228px;" version="1.1" viewBox="0 0 1673 1228" width="1673px" zoomAndPan="magnify"><defs><filter height="300%" id="f1nwecmqn105lg" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><ellipse cx="96.5" cy="32" fill="#000000" filter="url(#f1nwecmqn105lg)" rx="10" ry="10" style="stroke:none;stroke-width:1.0;"/><g id="WaitForStartPermission"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="179" x="7" y="149"/><line style="stroke:#A80036;stroke-width:1.5;" x1="7" x2="186" y1="175.2969" y2="175.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="159" x="17" y="166.9951">WaitForStartPermission</text></g><g id="PowerDown"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="103" x="480" y="149"/><line style="stroke:#A80036;stroke-width:1.5;" x1="480" x2="583" y1="175.2969" y2="175.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="83" x="490" y="166.9951">PowerDown</text></g><g id="PowerUpRequest"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="141" x="472" y="291"/><line style="stroke:#A80036;stroke-width:1.5;" x1="472" x2="613" y1="317.2969" y2="317.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="121" x="482" y="308.9951">PowerUpRequest</text></g><g id="PowerUpProcedure"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="154" x="727.5" y="418"/><line style="stroke:#A80036;stroke-width:1.5;" x1="727.5" x2="881.5" y1="444.2969" y2="444.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="134" x="737.5" y="435.9951">PowerUpProcedure</text></g><g id="StatusCheck"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="108" x="488.5" y="418"/><line style="stroke:#A80036;stroke-width:1.5;" x1="488.5" x2="596.5" y1="444.2969" y2="444.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="88" x="498.5" y="435.9951">StatusCheck</text></g><g id="PowerUpInPorgress"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="156" x="704.5" y="545"/><line style="stroke:#A80036;stroke-width:1.5;" x1="704.5" x2="860.5" y1="571.2969" y2="571.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="136" x="714.5" y="562.9951">PowerUpInPorgress</text></g><g id="CellularConfProcedure"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="174" x="1127.5" y="672"/><line style="stroke:#A80036;stroke-width:1.5;" x1="1127.5" x2="1301.5" y1="698.2969" y2="698.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="154" x="1137.5" y="689.9951">CellularConfProcedure</text></g><g id="BaudDetect"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="103" x="849" y="672"/><line style="stroke:#A80036;stroke-width:1.5;" x1="849" x2="952" y1="698.2969" y2="698.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="83" x="859" y="689.9951">BaudDetect</text></g><g id="ModemFatalFailure"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="149" x="910" y="1164"/><line style="stroke:#A80036;stroke-width:1.5;" x1="910" x2="1059" y1="1190.2969" y2="1190.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="129" x="920" y="1181.9951">ModemFatalFailure</text></g><g id="AudioConfigurationProcedure"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="223" x="1103" y="799"/><line style="stroke:#A80036;stroke-width:1.5;" x1="1103" x2="1326" y1="825.2969" y2="825.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="203" x="1113" y="816.9951">AudioConfigurationProcedure</text></g><g id="Failed"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="60" x="1433.5" y="926"/><line style="stroke:#A80036;stroke-width:1.5;" x1="1433.5" x2="1493.5" y1="952.2969" y2="952.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="40" x="1443.5" y="943.9951">Failed</text></g><g id="Idle"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="50" x="1260.5" y="1037"/><line style="stroke:#A80036;stroke-width:1.5;" x1="1260.5" x2="1310.5" y1="1063.2969" y2="1063.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="24" x="1273.5" y="1054.9951">Idle</text></g><g id="APNConfProcedure"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="152" x="1063.5" y="926"/><line style="stroke:#A80036;stroke-width:1.5;" x1="1063.5" x2="1215.5" y1="952.2969" y2="952.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="132" x="1073.5" y="943.9951">APNConfProcedure</text></g><g id="SanityCheck"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="105" x="1087" y="1037"/><line style="stroke:#A80036;stroke-width:1.5;" x1="1087" x2="1192" y1="1063.2969" y2="1063.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="85" x="1097" y="1054.9951">SanityCheck</text></g><g id="ModemOn"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="92" x="1094.5" y="1164"/><line style="stroke:#A80036;stroke-width:1.5;" x1="1094.5" x2="1186.5" y1="1190.2969" y2="1190.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="72" x="1104.5" y="1181.9951">ModemOn</text></g><g id="URCReady"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="93" x="1222" y="1164"/><line style="stroke:#A80036;stroke-width:1.5;" x1="1222" x2="1315" y1="1190.2969" y2="1190.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="73" x="1232" y="1181.9951">URCReady</text></g><g id="Event:CellularSimProcedure"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="211" x="801" y="7"/><line style="stroke:#A80036;stroke-width:1.5;" x1="801" x2="1012" y1="33.2969" y2="33.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="191" x="811" y="24.9951">Event:CellularSimProcedure</text></g><g id="SimSelect"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="88" x="862.5" y="149"/><line style="stroke:#A80036;stroke-width:1.5;" x1="862.5" x2="950.5" y1="175.2969" y2="175.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="68" x="872.5" y="166.9951">SimSelect</text></g><g id="Event:SIM_READY"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="143" x="1516" y="672"/><line style="stroke:#A80036;stroke-width:1.5;" x1="1516" x2="1659" y1="698.2969" y2="698.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="123" x="1526" y="689.9951">Event:SIM_READY</text></g><g id="SimInit"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="65" x="1555" y="799"/><line style="stroke:#A80036;stroke-width:1.5;" x1="1555" x2="1620" y1="825.2969" y2="825.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="45" x="1565" y="816.9951">SimInit</text></g><g id="Ready"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="63" x="1574" y="926"/><line style="stroke:#A80036;stroke-width:1.5;" x1="1574" x2="1637" y1="952.2969" y2="952.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="43" x="1584" y="943.9951">Ready</text></g><g id="Event:PowerDownDeregistering"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="241" x="1047" y="7"/><line style="stroke:#A80036;stroke-width:1.5;" x1="1047" x2="1288" y1="33.2969" y2="33.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="221" x="1057" y="24.9951">Event:PowerDownDeregistering</text></g><g id="PowerDownStarted"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="153" x="1091" y="149"/><line style="stroke:#A80036;stroke-width:1.5;" x1="1091" x2="1244" y1="175.2969" y2="175.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="133" x="1101" y="166.9951">PowerDownStarted</text></g><g id="Event:PowerDownDeregistered"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="238" x="414.5" y="799"/><line style="stroke:#A80036;stroke-width:1.5;" x1="414.5" x2="652.5" y1="825.2969" y2="825.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="218" x="424.5" y="816.9951">Event:PowerDownDeregistered</text></g><g id="PowerDownWaiting"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="153" x="457" y="926"/><line style="stroke:#A80036;stroke-width:1.5;" x1="457" x2="610" y1="952.2969" y2="952.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="133" x="467" y="943.9951">PowerDownWaiting</text></g><g id="Event:PowerDownRequest"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="206" x="215.5" y="926"/><line style="stroke:#A80036;stroke-width:1.5;" x1="215.5" x2="421.5" y1="952.2969" y2="952.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="186" x="225.5" y="943.9951">Event:PowerDownRequest</text></g><g id="Event:PowerUpProcedureComplete"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="265" x="1115" y="545"/><line style="stroke:#A80036;stroke-width:1.5;" x1="1115" x2="1380" y1="571.2969" y2="571.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="245" x="1125" y="562.9951">Event:PowerUpProcedureComplete</text></g><g id="Event:modemActive"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="158" x="607.5" y="7"/><line style="stroke:#A80036;stroke-width:1.5;" x1="607.5" x2="765.5" y1="33.2969" y2="33.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="138" x="617.5" y="24.9951">Event:modemActive</text></g><g id="Event:powerDownRequest"><rect fill="#FEFECE" filter="url(#f1nwecmqn105lg)" height="50" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="206" x="284.5" y="7"/><line style="stroke:#A80036;stroke-width:1.5;" x1="284.5" x2="490.5" y1="33.2969" y2="33.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="186" x="294.5" y="24.9951">Event:powerDownRequest</text></g><!--MD5=[f915ac7c515e4418b9971fc24141bfa8]
+link *start to WaitForStartPermission--><path d="M96.5,42.19 C96.5,62.43 96.5,111.61 96.5,143.57 " fill="none" id="*start-to-WaitForStartPermission" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="96.5,148.93,100.5,139.93,96.5,143.93,92.5,139.93,96.5,148.93" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[88ab108be6f5d0bf533f01e1c35c5b74]
+link WaitForStartPermission to PowerDown--><path d="M186.1,174 C272.69,174 401.22,174 474.62,174 " fill="none" id="WaitForStartPermission-to-PowerDown" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="479.81,174,470.81,170,474.81,174,470.81,178,479.81,174" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="257" x="204.5" y="167.0669">PowerDownRequest && !isModemActive</text><!--MD5=[0c907647073cf18eded21f91f1f8f134]
+link WaitForStartPermission to PowerUpRequest--><path d="M172.68,199.06 C227.43,216.33 303,240.15 369.5,261 C401.42,271.01 436.66,282.02 466.96,291.47 " fill="none" id="WaitForStartPermission-to-PowerUpRequest" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="471.78,292.97,464.3761,286.4752,467.0061,291.4835,461.9977,294.1135,471.78,292.97" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="108" x="370.5" y="249.5669">PowerUpRequest</text><!--MD5=[584390472df753eb5ace16f97522b8e7]
+link PowerDown to PowerUpRequest--><path d="M583.2,175.34 C624.21,178.69 679.19,190.7 707.5,229 C736.39,268.08 674.33,290.93 618.24,303.13 " fill="none" id="PowerDown-to-PowerUpRequest" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="613.18,304.21,622.8155,306.2489,618.0705,303.1692,621.1502,298.4241,613.18,304.21" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="108" x="716.5" y="249.5669">PowerUpRequest</text><!--MD5=[584390472df753eb5ace16f97522b8e7]
+link PowerDown to PowerUpRequest--><path d="M507.91,199.09 C500.91,207.81 494.14,218.18 490.5,229 C485.96,242.48 485.18,247.81 490.5,261 C494.39,270.65 500.92,279.53 508.06,287.19 " fill="none" id="PowerDown-to-PowerUpRequest-1" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="511.61,290.85,508.2238,281.6016,508.1322,287.2577,502.4761,287.1661,511.61,290.85" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="203" x="491.5" y="242.0669">nextPowerStateChangeAwaiting</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="173" x="510.5" y="257.1997">&& nextPowerState == on</text><!--MD5=[fd7c4f6a4c6d13e246c834aa3ba49585]
+link PowerUpRequest to PowerUpProcedure--><path d="M593.02,341.1 C637.87,362.5 703.28,393.71 749.45,415.74 " fill="none" id="PowerUpRequest-to-PowerUpProcedure" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="754.14,417.97,747.7441,410.4805,749.6286,415.8142,744.2949,417.6987,754.14,417.97" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="127" x="690.5" y="384.0669">board == T3 | Linux</text><!--MD5=[1f58f805457b87f5122cad7e5f47ae2e]
+link PowerUpRequest to StatusCheck--><path d="M542.5,341.1 C542.5,361.59 542.5,391.08 542.5,412.88 " fill="none" id="PowerUpRequest-to-StatusCheck" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="542.5,417.97,546.5,408.97,542.5,412.97,538.5,408.97,542.5,417.97" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="82" x="543.5" y="384.0669">board == T4</text><!--MD5=[d831c87685770c4b5421553c9e07c620]
+link StatusCheck to PowerUpInPorgress--><path d="M588.44,468.02 C614.79,481.78 648.5,499.38 678.5,515 C695.74,523.97 714.59,533.77 731.45,542.52 " fill="none" id="StatusCheck-to-PowerUpInPorgress" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="736.15,544.96,730.0065,537.2621,731.7127,542.6555,726.3193,544.3617,736.15,544.96" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="89" x="679.5" y="511.0669">modemActive</text><!--MD5=[5076860d7ea1929d04394078621bcf05]
+link StatusCheck to PowerUpProcedure--><path d="M596.79,443 C632.93,443 681.12,443 721.97,443 " fill="none" id="StatusCheck-to-PowerUpProcedure" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="727.43,443,718.43,439,722.43,443,718.43,447,727.43,443" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="94" x="615" y="436.0669">!modemActive</text><!--MD5=[d397ed2e524c17c524214a6bc49619b6]
+link PowerUpProcedure to CellularConfProcedure--><path d="M881.71,448.95 C921.88,455.19 969.37,468.77 1002.5,498 C1037.47,528.85 1011.91,559.8 1042.5,595 C1071.09,627.89 1113.14,652.85 1148.5,669.73 " fill="none" id="PowerUpProcedure-to-CellularConfProcedure" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1153.22,671.96,1146.7764,664.5115,1148.6949,669.8331,1143.3733,671.7516,1153.22,671.96" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="53" x="1043.5" y="574.5669">hotStart</text><!--MD5=[c78ef4752e5fc097b033474b61fe6478]
+link PowerUpProcedure to PowerUpInPorgress--><path d="M790.57,468.21 C786.11,477.26 781.74,487.81 779.5,498 C776.52,511.51 776.73,526.8 777.9,539.73 " fill="none" id="PowerUpProcedure-to-PowerUpInPorgress" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="778.42,544.74,781.4993,535.3849,777.9197,539.7651,773.5394,536.1855,778.42,544.74" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="217" x="780.5" y="511.0669">coldStart || event: modem ACTIVE</text><!--MD5=[727c9e726932860737726ca6f5028085]
+link PowerUpInPorgress to BaudDetect--><path d="M805.25,595.1 C825,616.03 853.61,646.32 874.31,668.25 " fill="none" id="PowerUpInPorgress-to-BaudDetect" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="877.82,671.97,874.5645,662.6747,874.3932,668.329,868.7389,668.1577,877.82,671.97" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[f6b42f2832973fdffd6f80cf1316681b]
+link BaudDetect to CellularConfProcedure--><path d="M952.35,697 C998.33,697 1066.59,697 1121.93,697 " fill="none" id="BaudDetect-to-CellularConfProcedure" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1127.24,697,1118.24,693,1122.24,697,1118.24,701,1127.24,697" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="53" x="1013.25" y="690.0669">Success</text><!--MD5=[fb0ab7093ebe96a0eb9a906c1d94f36d]
+link BaudDetect to ModemFatalFailure--><path d="M929.41,722.09 C953.71,745.2 984.5,782.47 984.5,823 C984.5,823 984.5,823 984.5,1063 C984.5,1095.62 984.5,1133.03 984.5,1158.35 " fill="none" id="BaudDetect-to-ModemFatalFailure" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="984.5,1163.57,988.5,1154.57,984.5,1158.57,980.5,1154.57,984.5,1163.57" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="42" x="985.5" y="955.5669">Failure</text><!--MD5=[68f100448ff22dc026a7f78db7e4edea]
+link CellularConfProcedure to AudioConfigurationProcedure--><path d="M1214.5,722.1 C1214.5,742.59 1214.5,772.08 1214.5,793.88 " fill="none" id="CellularConfProcedure-to-AudioConfigurationProcedure" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1214.5,798.97,1218.5,789.97,1214.5,793.97,1210.5,789.97,1214.5,798.97" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="53" x="1215.5" y="765.0669">Success</text><!--MD5=[5d7ae24bf63e4aed2a4253c65e46f11f]
+link CellularConfProcedure to Failed--><path d="M1290.33,722.13 C1330.65,738.3 1378.38,763.28 1410.5,799 C1441.62,833.61 1454.71,887.59 1460.04,920.77 " fill="none" id="CellularConfProcedure-to-Failed" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1460.83,925.91,1463.4212,916.4081,1460.0729,920.9676,1455.5134,917.6194,1460.83,925.91" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="37" x="1440.5" y="828.5669">Failed</text><!--MD5=[8bec8aa94f11da26fdaa532b9e927b58]
+link AudioConfigurationProcedure to AudioConfigurationProcedure--><path d="M1326.28,813.01 C1346.69,814.4 1361,818.07 1361,824 C1361,829.42 1349.04,832.95 1331.4,834.58 " fill="none" id="AudioConfigurationProcedure-to-AudioConfigurationProcedure" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1326.28,834.99,1335.5617,838.2839,1331.2651,834.6043,1334.9447,830.3077,1326.28,834.99" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="37" x="1367" y="828.5669">Failed</text><!--MD5=[f66ed35969f9ee770eed229d3a3a3084]
+link AudioConfigurationProcedure to Failed--><path d="M1254.8,849.06 C1279.27,863.33 1311.3,881.41 1340.5,896 C1369.64,910.56 1403.6,925.31 1428.45,935.71 " fill="none" id="AudioConfigurationProcedure-to-Failed" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1433.29,937.73,1426.5286,930.5687,1428.6767,935.8019,1423.4436,937.95,1433.29,937.73" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="95" x="1341.5" y="892.0669">Baud setup fail</text><!--MD5=[82b15964c7ea4c9e08a8f2c3031886b6]
+link AudioConfigurationProcedure to Idle--><path d="M1229.21,849.08 C1234.3,858.2 1239.68,868.84 1243.5,879 C1263.09,931.07 1275.29,995.09 1281.2,1031.66 " fill="none" id="AudioConfigurationProcedure-to-Idle" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1282.03,1036.85,1284.5407,1027.3265,1281.2311,1031.9142,1276.6434,1028.6047,1282.03,1036.85" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="74" x="1270.5" y="955.5669">reset called</text><!--MD5=[0510a649553933047eef813e676d387c]
+link AudioConfigurationProcedure to APNConfProcedure--><path d="M1200.04,849.1 C1187.64,869.77 1169.76,899.57 1156.64,921.43 " fill="none" id="AudioConfigurationProcedure-to-APNConfProcedure" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1153.92,925.97,1161.9943,920.3303,1156.503,921.6888,1155.1444,916.1975,1153.92,925.97" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="53" x="1181.5" y="892.0669">Success</text><!--MD5=[7ef9c75e84b5805cea2dd0fad20a72d8]
+link APNConfProcedure to SanityCheck--><path d="M1139.5,976.19 C1139.5,992.56 1139.5,1014.28 1139.5,1031.64 " fill="none" id="APNConfProcedure-to-SanityCheck" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1139.5,1036.88,1143.5,1027.88,1139.5,1031.88,1135.5,1027.88,1139.5,1036.88" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[8c0f7218f4a51008def03317319fcc3d]
+link SanityCheck to ModemOn--><path d="M1139.69,1087.1 C1139.86,1107.59 1140.09,1137.08 1140.27,1158.88 " fill="none" id="SanityCheck-to-ModemOn" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1140.31,1163.97,1144.2327,1154.936,1140.2671,1158.9702,1136.233,1155.0046,1140.31,1163.97" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="53" x="1141.5" y="1130.0669">Success</text><!--MD5=[33f60799b5f26f20f5dd174f2ed7c1a3]
+link SanityCheck to ModemFatalFailure--><path d="M1109.61,1087.1 C1083.45,1108.2 1045.48,1138.83 1018.23,1160.8 " fill="none" id="SanityCheck-to-ModemFatalFailure" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1014.29,1163.97,1023.8132,1161.4585,1018.1902,1160.8413,1018.8073,1155.2182,1014.29,1163.97" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="42" x="1072.5" y="1130.0669">Failure</text><!--MD5=[3905e8178637947b22a281c6f6af1a81]
+link ModemOn to URCReady--><path d="M1187,1189 C1196.85,1189 1206.7,1189 1216.55,1189 " fill="none" id="ModemOn-to-URCReady" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1221.7,1189,1212.7,1185,1216.7,1189,1212.7,1193,1221.7,1189" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[25bdad021a3357d0304ecf42b5cd666e]
+link Event:CellularSimProcedure to SimSelect--><path d="M906.5,57.07 C906.5,81.01 906.5,117.78 906.5,143.47 " fill="none" id="Event:CellularSimProcedure-to-SimSelect" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="906.5,148.78,910.5,139.78,906.5,143.78,902.5,139.78,906.5,148.78" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[70270a8730f9b46f42f00f8c6cb6b504]
+link Event:SIM_READY to SimInit--><path d="M1587.5,722.1 C1587.5,742.59 1587.5,772.08 1587.5,793.88 " fill="none" id="Event:SIM_READY-to-SimInit" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1587.5,798.97,1591.5,789.97,1587.5,793.97,1583.5,789.97,1587.5,798.97" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[b86a93dae48bca6b30f35403ce1d8717]
+link SimInit to Failed--><path d="M1563.59,849.1 C1542.83,870.03 1512.78,900.32 1491.02,922.25 " fill="none" id="SimInit-to-Failed" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1487.34,925.97,1496.5181,922.3974,1490.8612,922.4202,1490.8384,916.7634,1487.34,925.97" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="42" x="1533.5" y="892.0669">Failure</text><!--MD5=[b5461c294bec50186077517b36d4e59b]
+link SimInit to Ready--><path d="M1590.97,849.1 C1593.92,869.59 1598.17,899.08 1601.31,920.88 " fill="none" id="SimInit-to-Ready" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1602.04,925.97,1604.7117,916.4904,1601.3249,921.0214,1596.7939,917.6346,1602.04,925.97" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="53" x="1598.5" y="892.0669">Success</text><!--MD5=[413a005fcb8ce8860adb73228c80b7ef]
+link Event:PowerDownDeregistering to PowerDownStarted--><path d="M1167.5,57.07 C1167.5,81.01 1167.5,117.78 1167.5,143.47 " fill="none" id="Event:PowerDownDeregistering-to-PowerDownStarted" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1167.5,148.78,1171.5,139.78,1167.5,143.78,1163.5,139.78,1167.5,148.78" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="176" x="1168.5" y="107.5669">state != PowerDownWaiting</text><!--MD5=[b6a5c31cebdae095f367e2e47186e206]
+link Event:PowerDownDeregistered to PowerDownWaiting--><path d="M533.5,849.1 C533.5,869.59 533.5,899.08 533.5,920.88 " fill="none" id="Event:PowerDownDeregistered-to-PowerDownWaiting" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="533.5,925.97,537.5,916.97,533.5,920.97,529.5,916.97,533.5,925.97" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[24c673904b079bd1ceff7ed1ad2637b1]
+link Event:PowerDownRequest to PowerDownWaiting--><path d="M421.8,951 C431.71,951 441.62,951 451.53,951 " fill="none" id="Event:PowerDownRequest-to-PowerDownWaiting" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="456.71,951,447.71,947,451.71,951,447.71,955,456.71,951" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[bd7f44948400696f1debeec448c84662]
+link PowerDownWaiting to PowerDown--><path d="M456.81,926.97 C410.94,907.93 361.5,875.66 361.5,825 C361.5,315 361.5,315 361.5,315 C361.5,255 425.39,215.95 474.83,194.71 " fill="none" id="PowerDownWaiting-to-PowerDown" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="479.57,192.71,469.7231,192.516,474.9618,194.6503,472.8275,199.8891,479.57,192.71" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="116" x="380" y="567.0669">(If T3 && timeout)</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="151" x="366.5" y="582.1997">|| Event:modemInactive</text><!--MD5=[538f577aff9d45ee5f10c76efb758677]
+link BaudDetect to PowerDownWaiting--><path d="M864.05,722.08 C833.38,742.41 788.42,772.38 749.5,799 C686.88,841.82 614.77,892.52 571.72,922.92 " fill="none" id="BaudDetect-to-PowerDownWaiting" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="567.39,925.98,577.0489,924.0551,571.474,923.0955,572.4337,917.5206,567.39,925.98" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="203" x="750.5" y="821.0669">nextPowerStateChangeAwaiting</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="173" x="769.5" y="836.1997">&& nextPowerState == off</text><!--MD5=[0efad0401ca8edd085e226b25311ae33]
+link Event:PowerUpProcedureComplete to CellularConfProcedure--><path d="M1241.14,595.1 C1235.73,615.59 1227.94,645.08 1222.19,666.88 " fill="none" id="Event:PowerUpProcedureComplete-to-CellularConfProcedure" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="1220.84,671.97,1227.0211,664.3023,1222.1265,667.1384,1219.2904,662.2438,1220.84,671.97" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="131" x="1233.5" y="638.0669">board == T3 || Linux</text><!--MD5=[18dc0415e66d1a4a3ab66d026941b242]
+link Event:modemActive to PowerDown--><path d="M680.53,57.18 C674.8,76.06 664.46,101.87 647.5,119 C631.08,135.58 608.6,147.65 587.8,156.11 " fill="none" id="Event:modemActive-to-PowerDown" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="583.12,157.97,592.9604,158.3779,587.7692,156.1303,590.0168,150.9391,583.12,157.97" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="178" x="670.5" y="107.5669">state != PowerUpProcedure</text><!--MD5=[8ce29d3611eab794d01643cc4f798f18]
+link Event:powerDownRequest to PowerDown--><path d="M379.4,57.08 C374.75,75.66 372.02,101.11 384.5,119 C404.81,148.1 442.62,161.56 474.81,167.77 " fill="none" id="Event:powerDownRequest-to-PowerDown" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="479.92,168.71,471.785,163.1583,475.0013,167.8118,470.3479,171.0282,479.92,168.71" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="257" x="385.5" y="100.0669">state != PowerDown,PowerDownWaiting,</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="248" x="392" y="115.1997">PowerUpProcedure,PowerUpInProgress</text><!--MD5=[9b7c7df649ad4c52f08ebef10d9c7447]
+@startuml
+
+[*] - -> WaitForStartPermission
+
+WaitForStartPermission -> PowerDown : PowerDownRequest && !isModemActive
+
+WaitForStartPermission - -> PowerUpRequest : PowerUpRequest
+
+PowerDown - -> PowerUpRequest : PowerUpRequest
+
+PowerUpRequest - -> PowerUpProcedure : board == T3 | Linux
+
+PowerUpRequest -> StatusCheck : board == T4
+
+StatusCheck - -> PowerUpInPorgress : modemActive
+
+StatusCheck -> PowerUpProcedure : !modemActive
+
+PowerUpProcedure - -> CellularConfProcedure : hotStart
+
+PowerUpProcedure - -> PowerUpInPorgress : coldStart || event: modem ACTIVE
+
+PowerUpInPorgress - -> BaudDetect
+
+BaudDetect -> CellularConfProcedure : Success
+
+BaudDetect - -> ModemFatalFailure : Failure
+
+CellularConfProcedure - -> AudioConfigurationProcedure : Success
+
+CellularConfProcedure -> Failed : Failed
+
+AudioConfigurationProcedure -> AudioConfigurationProcedure : Failed
+
+AudioConfigurationProcedure - -> Failed : Baud setup fail
+
+AudioConfigurationProcedure - - -> Idle : reset called
+
+AudioConfigurationProcedure - -> APNConfProcedure : Success
+
+APNConfProcedure - -> SanityCheck
+
+SanityCheck - -> ModemOn : Success
+
+SanityCheck - -> ModemFatalFailure : Failure
+
+ModemOn -> URCReady
+
+Event:CellularSimProcedure - -> SimSelect
+
+Event:SIM_READY - -> SimInit
+
+SimInit - -> Failed : Failure
+
+SimInit - -> Ready : Success
+
+Event:PowerDownDeregistering - -> PowerDownStarted : state != PowerDownWaiting
+
+Event:PowerDownDeregistered - -> PowerDownWaiting
+
+Event:PowerDownRequest -> PowerDownWaiting
+
+PowerDownWaiting - - -> PowerDown : (If T3 && timeout) \n || Event:modemInactive
+
+PowerDown - -> PowerUpRequest : nextPowerStateChangeAwaiting \n && nextPowerState == on
+
+BaudDetect - - -> PowerDownWaiting : nextPowerStateChangeAwaiting \n && nextPowerState == off
+
+Event:PowerUpProcedureComplete - -> CellularConfProcedure : board == T3 || Linux
+
+Event:modemActive - -> PowerDown : state != PowerUpProcedure
+
+Event:powerDownRequest - -> PowerDown : state != PowerDown,PowerDownWaiting,\n PowerUpProcedure,PowerUpInProgress
+
+@enduml
+
+PlantUML version 1.2020.22(Sun Dec 06 10:36:27 CET 2020)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: pl
+Country: PL
+--></g></svg><
\ No newline at end of file
M module-services/service-cellular/service-cellular/CellularMessage.hpp => module-services/service-cellular/service-cellular/CellularMessage.hpp +23 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 144,6 144,22 @@ class CellularSetOperatorMessage : public sys::Message
}
};
+class CellularPowerStateChange : public CellularMessage
+{
+ public:
+ explicit CellularPowerStateChange(cellular::State::PowerState new_state)
+ : CellularMessage(MessageType::CellularPowerStateChange), newState(new_state)
+ {}
+
+ cellular::State::PowerState getNewState() const noexcept
+ {
+ return newState;
+ }
+
+ private:
+ cellular::State::PowerState newState;
+};
+
class CellularStartOperatorsScanMessage : public CellularMessage
{
bool fullInfo = false;
@@ 715,6 731,12 @@ class CellularChangeVoLTEDataMessage : public CellularVoLTEDataMessage
{}
};
+class CellularCheckIfStartAllowedMessage : public sys::Message
+{
+ public:
+ CellularCheckIfStartAllowedMessage() : sys::Message()
+ {}
+};
namespace cellular
{
M module-services/service-cellular/service-cellular/CellularServiceAPI.hpp => module-services/service-cellular/service-cellular/CellularServiceAPI.hpp +1 -1
@@ 94,7 94,6 @@ namespace CellularServiceAPI
CellularSimCardLockDataMessage::SimCardLock lock,
const std::vector<unsigned int> &pin);
bool SetSimCard(sys::Service *serv, Store::GSM::SIM sim);
-
/**
* @brief get all APNs from phone configuration
*/
@@ 113,4 112,5 @@ namespace CellularServiceAPI
bool GetDataTransfer(sys::Service *serv);
bool SetVoLTE(sys::Service *serv, bool value);
+ bool ChangeModulePowerState(sys::Service *serv, cellular::State::PowerState newState);
}; // namespace CellularServiceAPI
M module-services/service-cellular/service-cellular/ServiceCellular.hpp => module-services/service-cellular/service-cellular/ServiceCellular.hpp +12 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 188,6 188,8 @@ class ServiceCellular : public sys::Service
};
bool resetCellularModule(ResetType type);
bool isAfterForceReboot = false;
+ bool nextPowerStateChangeAwaiting = false;
+ cellular::State::PowerState nextPowerState = cellular::State::PowerState::Off;
/// one point of state change handling
void change_state(cellular::StateChange *msg);
@@ 202,12 204,18 @@ class ServiceCellular : public sys::Service
bool handle_power_down();
/// idle handler
bool handle_idle();
+ /// wait for start permission handlers
+ bool handle_wait_for_start_permission();
+ /// start the module in proper way
+ bool handle_power_up_request();
/// cellular power up procedure
bool handle_status_check();
/// cellular power up procedure
bool handle_power_up_in_progress_procedure();
/// cellular power up procedure
bool handle_power_up_procedure();
+ /// detect communication baud rate
+ bool handle_baud_detect();
/// configure basic modem parameters
bool handle_start_conf_procedure();
/// configure modem audio parameters
@@ 229,6 237,9 @@ class ServiceCellular : public sys::Service
/// \note some run state should be added to ignore non system messages now...
bool handle_fatal_failure();
bool handle_ready();
+ /// Process change of power state
+ void handle_power_state_change();
+
std::unique_ptr<settings::Settings> settings = std::make_unique<settings::Settings>(this);
bool handle_apn_conf_procedure();
M module-services/service-cellular/service-cellular/State.hpp => module-services/service-cellular/service-cellular/State.hpp +9 -0
@@ 13,9 13,12 @@ namespace cellular
enum class ST
{
Idle, /// does nothing
+ WaitForStartPermission, /// waiting for permission to start the module
+ PowerUpRequest, /// process request of power up
StatusCheck, /// set on service start - check for modem status - skipped on T3 board
PowerUpProcedure, /// due to lack of Status pin on T3, we don't know whether is on or off
PowerUpInProgress, /// waiting for modem powered up by polling various bauds
+ BaudDetect, /// baud detection procedure
CellularConfProcedure, /// configuration procedure
AudioConfigurationProcedure, /// audio configuration for modem (could be in ModemConfiguration)
APNConfProcedure, /// Configure APN set by user, check if modem have similar
@@ 32,6 35,12 @@ namespace cellular
PowerDown, /// modem is known to be turned off
};
+ enum class PowerState
+ {
+ Off,
+ On
+ };
+
private:
enum ST state = ST::Idle;
M module-services/service-evtmgr/EventManager.cpp => module-services/service-evtmgr/EventManager.cpp +5 -0
@@ 273,6 273,11 @@ sys::ReturnCodes EventManager::InitHandler()
return std::make_shared<sys::ResponseMessage>();
});
+ connect(sevm::BatteryLevelCriticalCheckMessage(), [&](sys::Message *msgl) {
+ EventWorker->checkBatteryLevelCritical();
+ return std::make_shared<sys::ResponseMessage>();
+ });
+
// initialize keyboard worker
EventWorker = std::make_unique<WorkerEvent>(this);
M module-services/service-evtmgr/WorkerEvent.cpp => module-services/service-evtmgr/WorkerEvent.cpp +5 -0
@@ 262,3 262,8 @@ void WorkerEvent::processKeyEvent(bsp::KeyEvents event, bsp::KeyCodes code)
}
sys::Bus::SendUnicast(message, service::name::evt_manager, this->service);
}
+
+void WorkerEvent::checkBatteryLevelCritical()
+{
+ battery_level_check::checkBatteryLevelCritical();
+}
M module-services/service-evtmgr/api/EventManagerServiceAPI.cpp => module-services/service-evtmgr/api/EventManagerServiceAPI.cpp +6 -0
@@ 35,3 35,9 @@ bsp::Board EventManagerServiceAPI::GetBoard(sys::Service *serv)
}
return bsp::Board::none;
}
+
+void EventManagerServiceAPI::checkBatteryLevelCriticalState(sys::Service *serv)
+{
+ auto msg = std::make_shared<sevm::BatteryLevelCriticalCheckMessage>();
+ sys::Bus::SendUnicast(msg, service::name::evt_manager, serv);
+}
M module-services/service-evtmgr/battery-level-check/BatteryLevelCheck.cpp => module-services/service-evtmgr/battery-level-check/BatteryLevelCheck.cpp +41 -4
@@ 12,6 12,15 @@ namespace battery_level_check
{
namespace
{
+ enum class CheckState
+ {
+ InitialCheck,
+ LevelCritical,
+ LevelNormal
+ };
+
+ CheckState state = CheckState::InitialCheck;
+
constexpr inline auto DEFAULT_LEVEL = 10;
unsigned int batteryLevelCritical = DEFAULT_LEVEL;
@@ 23,21 32,49 @@ namespace battery_level_check
return level < batteryLevelCritical;
}
+ void sendCriticalLevelMessage()
+ {
+ auto levelCriticalMessage = std::make_shared<sevm::BatteryLevelCriticalMessage>();
+ sys::Bus::SendUnicast(levelCriticalMessage, service::name::system_manager, parentService);
+ }
+
+ void sendNormalLevelMessage()
+ {
+ auto levelNormalMessage = std::make_shared<sevm::BatteryLevelNormalMessage>();
+ sys::Bus::SendUnicast(levelNormalMessage, service::name::system_manager, parentService);
+ }
} // namespace
void init(sys::Service *service)
{
parentService = service;
- checkBatteryLevelCritical();
}
void checkBatteryLevelCritical()
{
- if (Store::Battery::get().state == Store::Battery::State::Discharging) {
+ switch (state) {
+ case CheckState::InitialCheck:
+ if (isBatteryLevelCritical(Store::Battery::get().level)) {
+ sendCriticalLevelMessage();
+ state = CheckState::LevelCritical;
+ }
+ else {
+ sendNormalLevelMessage();
+ state = CheckState::LevelNormal;
+ }
+ break;
+ case CheckState::LevelCritical:
+ if (!isBatteryLevelCritical(Store::Battery::get().level)) {
+ sendNormalLevelMessage();
+ state = CheckState::LevelNormal;
+ }
+ break;
+ case CheckState::LevelNormal:
if (isBatteryLevelCritical(Store::Battery::get().level)) {
- auto levelCriticalMessage = std::make_shared<sevm::BatteryLevelCriticalMessage>();
- sys::Bus::SendUnicast(levelCriticalMessage, service::name::system_manager, parentService);
+ sendCriticalLevelMessage();
+ state = CheckState::LevelCritical;
}
+ break;
}
}
M module-services/service-evtmgr/service-evtmgr/BatteryMessages.hpp => module-services/service-evtmgr/service-evtmgr/BatteryMessages.hpp +11 -15
@@ 30,27 30,23 @@ namespace sevm
}
bool plugged = false;
};
- class BatterySetCriticalLevel : public Message
+ class BatterySetCriticalLevel : public sys::Message
{
public:
- BatterySetCriticalLevel(std::uint8_t level)
- : Message(MessageType::EVMBatterySetCriticalLevel), criticalLevel(level)
+ BatterySetCriticalLevel(std::uint8_t level) : Message(), criticalLevel(level)
{}
unsigned int criticalLevel = 0;
};
- class BatteryLevelCriticalMessage : public Message
- {
- public:
- BatteryLevelCriticalMessage() : Message(MessageType::EVMBatteryLevelCritical)
- {}
- };
+ class BatteryLevelCriticalCheckMessage : public sys::Message
+ {};
+ class BatteryLevelCriticalMessage : public sys::Message
+ {};
- class BatteryBrownoutMessage : public Message
- {
- public:
- BatteryBrownoutMessage() : Message(MessageType::EVMBatteryBrownout)
- {}
- };
+ class BatteryLevelNormalMessage : public sys::Message
+ {};
+
+ class BatteryBrownoutMessage : public sys::Message
+ {};
} // namespace sevm
M module-services/service-evtmgr/service-evtmgr/EventManagerServiceAPI.hpp => module-services/service-evtmgr/service-evtmgr/EventManagerServiceAPI.hpp +2 -0
@@ 19,4 19,6 @@ namespace EventManagerServiceAPI
* @return board type
*/
bsp::Board GetBoard(sys::Service *serv);
+
+ void checkBatteryLevelCriticalState(sys::Service *serv);
} // namespace EventManagerServiceAPI
M module-services/service-evtmgr/service-evtmgr/WorkerEvent.hpp => module-services/service-evtmgr/service-evtmgr/WorkerEvent.hpp +2 -0
@@ 74,4 74,6 @@ class WorkerEvent : public sys::Worker
* @param queueID Index of the queue in the queues vector.
*/
bool handleMessage(uint32_t queueID) override final;
+
+ void checkBatteryLevelCritical();
};
M module-sys/SystemManager/SystemManager.cpp => module-sys/SystemManager/SystemManager.cpp +28 -4
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "SystemManager.hpp"
@@ 11,7 11,11 @@
#include <service-evtmgr/KbdMessage.hpp>
#include <service-evtmgr/BatteryMessages.hpp>
#include <service-evtmgr/Constants.hpp>
+#include <service-evtmgr/EventManagerServiceAPI.hpp>
#include <Service/Timer.hpp>
+#include <service-cellular/CellularServiceAPI.hpp>
+#include <service-cellular/CellularMessage.hpp>
+#include <service-appmgr/model/ApplicationManager.hpp>
#include "messages/CpuFrequencyMessage.hpp"
const inline size_t systemManagerStack = 4096 * 2;
@@ 255,13 259,33 @@ namespace sys
return MessageNone{};
});
+ connect(sevm::BatteryBrownoutMessage(), [&](Message *) {
+ LOG_INFO("Battery Brownout voltage level reached!");
+ return MessageNone{};
+ });
+
+ connect(CellularCheckIfStartAllowedMessage(), [&](Message *) {
+ EventManagerServiceAPI::checkBatteryLevelCriticalState(this);
+ return MessageNone{};
+ });
+
connect(sevm::BatteryLevelCriticalMessage(), [&](Message *) {
- LOG_INFO("Battery Critical SOC Level reached!");
+ LOG_INFO("Battery Critical Level reached!");
+ CellularServiceAPI::ChangeModulePowerState(this, cellular::State::PowerState::Off);
+
+ auto msg = std::make_shared<CriticalBatteryLevelNotification>(true);
+ Bus::SendUnicast(msg, app::manager::ApplicationManager::ServiceName, this);
+
return MessageNone{};
});
- connect(sevm::BatteryBrownoutMessage(), [&](Message *) {
- LOG_INFO("Battery Brownout voltage level reached!");
+ connect(sevm::BatteryLevelNormalMessage(), [&](Message *) {
+ LOG_INFO("Battery level normal.");
+ CellularServiceAPI::ChangeModulePowerState(this, cellular::State::PowerState::On);
+
+ auto msg = std::make_shared<CriticalBatteryLevelNotification>(false);
+ Bus::SendUnicast(msg, app::manager::ApplicationManager::ServiceName, this);
+
return MessageNone{};
});
A module-sys/SystemManager/data/SystemManagerActionsParams.hpp => module-sys/SystemManager/data/SystemManagerActionsParams.hpp +24 -0
@@ 0,0 1,24 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <service-appmgr/service-appmgr/Actions.hpp>
+
+namespace app::manager::actions
+{
+ class LowBatteryNotificationParams : public ActionParams
+ {
+ public:
+ explicit LowBatteryNotificationParams(bool isActive) : isActive(isActive){};
+
+ [[nodiscard]] bool getActiveState() const noexcept
+ {
+ return isActive;
+ }
+
+ private:
+ bool isActive;
+ };
+
+} // namespace app::manager::actions
M module-sys/SystemManager/messages/SystemManagerMessage.hpp => module-sys/SystemManager/messages/SystemManagerMessage.hpp +22 -0
@@ 6,6 6,10 @@
#include <MessageType.hpp>
#include <Service/Message.hpp>
+#include "SystemManager/Constants.hpp"
+#include "SystemManager/data/SystemManagerActionsParams.hpp"
+#include <service-appmgr/service-appmgr/Actions.hpp>
+
namespace sys
{
@@ 15,4 19,22 @@ namespace sys
SystemManagerMessage() : sys::DataMessage(MessageType::PMChangePowerMode){};
};
+ class CriticalBatteryLevelNotification : public sys::Message, public app::manager::actions::ConvertibleToAction
+ {
+ public:
+ explicit CriticalBatteryLevelNotification(bool isActive) : sys::Message(), isActive(isActive)
+ {}
+
+ [[nodiscard]] auto toAction() const -> std::unique_ptr<app::manager::ActionRequest>
+ {
+ return std::make_unique<app::manager::ActionRequest>(
+ service::name::system_manager,
+ app::manager::actions::DisplayLowBatteryNotification,
+ std::make_unique<app::manager::actions::LowBatteryNotificationParams>(isActive));
+ }
+
+ private:
+ bool isActive;
+ };
+
} // namespace sys
M source/MessageType.hpp => source/MessageType.hpp +1 -3
@@ 74,6 74,7 @@ enum class MessageType
CellularHangupCall, ///< Hang up call
CellularCall, ///< Call related events
CellularCallRequest, ///< Call request
+ CellularPowerStateChange, ///< Change power state of the module
CellularListCurrentCalls,
CellularSimProcedure, // Broadcast on sim state changed
@@ 169,9 170,6 @@ enum class MessageType
// battery charger messages
EVMBatteryLevel,
EVMChargerPlugged,
- EVMBatterySetCriticalLevel,
- EVMBatteryLevelCritical,
- EVMBatteryBrownout,
// rtc messages
EVMMinuteUpdated, ///< This message is send to current focused application on every minute time change.
EVMTimeUpdated, ///< This message is send on every time update.