M Target_RT1051.cmake => Target_RT1051.cmake +1 -1
@@ 59,7 59,7 @@ add_compile_options(
set(TARGET_SOURCES
- ${CMAKE_CURRENT_LIST_DIR}/module-os/board/rt1051/_exit.c
+ ${CMAKE_CURRENT_LIST_DIR}/module-os/board/rt1051/_exit.cpp
CACHE INTERNAL ""
)
M board/rt1051/crashdump/crashcatcher_impl.cpp => board/rt1051/crashdump/crashcatcher_impl.cpp +6 -3
@@ 7,6 7,7 @@
#include <log/log.hpp>
#include <date/date.h>
+#include <exit_backtrace.h>
#include "crashdumpwriter_vfs.hpp"
#include "consoledump.hpp"
@@ 23,9 24,11 @@ const CrashCatcherMemoryRegion *CrashCatcher_GetMemoryRegions(void)
*/
static const CrashCatcherMemoryRegion regions[] = {
// SRAM_OC
- {0x20200000, 0x20210000, CRASH_CATCHER_BYTE},
+ {0x20200000, 0x20210000, CRASH_CATCHER_WORD},
// SRAM_DTC
- {0x20000000, 0x20070000, CRASH_CATCHER_BYTE},
+ {0x20000000, 0x20070000, CRASH_CATCHER_WORD},
+ // intentionally skip text section
+ // intentionally skip the heap section
// end tag
{0xFFFFFFFF, 0xFFFFFFFF, CRASH_CATCHER_BYTE},
};
@@ 57,6 60,6 @@ void CrashCatcher_DumpMemory(const void *pvMemory, CrashCatcherElementSizes elem
CrashCatcherReturnCodes CrashCatcher_DumpEnd(void)
{
cwrite.saveDump();
- abort();
+ _exit_backtrace(-1, false);
return CRASH_CATCHER_EXIT;
}
M board/rt1051/crashdump/crashdumpwriter_vfs.cpp => board/rt1051/crashdump/crashdumpwriter_vfs.cpp +8 -7
@@ 8,6 8,7 @@
#include <fcntl.h>
#include "purefs/vfs_subsystem.hpp"
#include <purefs/filesystem_paths.hpp>
+#include <exit_backtrace.h>
#include <filesystem>
#include <stdint.h>
@@ 23,12 24,12 @@ namespace crashdump
LOG_INFO("Crash dump %s preparing ...", crashDumpFilePath.c_str());
if (!rotator.rotateFile(crashDumpFilePath)) {
LOG_FATAL("Failed to rotate crash dumps errno: %i", errno);
- std::abort();
+ _exit_backtrace(-1, false);
}
file = std::fopen(crashDumpFilePath.c_str(), "w");
if (!file) {
LOG_FATAL("Failed to open crash dump file errno %i", errno);
- std::abort();
+ _exit_backtrace(-1, false);
}
}
@@ 44,23 45,23 @@ namespace crashdump
{
if (std::fwrite(buff, sizeof(*buff), size, file) != size) {
LOG_FATAL("Unable to write crash dump errno: %i", errno);
- std::abort();
+ _exit_backtrace(-1, false);
}
}
void CrashDumpWriterVFS::writeHalfWords(const uint16_t *buff, std::size_t size)
{
if (std::fwrite(buff, sizeof(*buff), size, file) != size) {
- LOG_FATAL("Unable to write crash dump");
- std::abort();
+ LOG_FATAL("Unable to write crash dump errno: %i", errno);
+ _exit_backtrace(-1, false);
}
}
void CrashDumpWriterVFS::writeWords(const uint32_t *buff, std::size_t size)
{
if (std::fwrite(buff, sizeof(*buff), size, file) != size) {
- LOG_FATAL("Unable to write crash dump");
- std::abort();
+ LOG_FATAL("Unable to write crash dump errno: %i", errno);
+ _exit_backtrace(-1, false);
}
}
M image/assets/lang/Deutsch.json => image/assets/lang/Deutsch.json +1 -1
@@ 635,7 635,7 @@
"app_bell_settings_bedtime_settings_volume": "<text>Lautstärke</text>",
"app_bell_settings_advanced": "Erweitert",
"app_bell_settings_turn_off": "Ausschalten",
- "app_bell_settings_advanced_time_units": "Zeit und Einheiten",
+ "app_bell_settings_time_units": "Zeit und Einheiten",
"app_bell_settings_advanced_language": "Sprache",
"app_bell_settings_advanced_about": "Über",
"app_bell_settings_advanced_about_product": "Mudita Harmony",
M image/assets/lang/English.json => image/assets/lang/English.json +1 -1
@@ 608,7 608,7 @@
"app_bell_onboarding_info_deep_click_correction": "<text font='gt_pressura' weight='light' size='38'>Be more gentle,<br></br>try </text><text font='gt_pressura' weight='regular' size='38'>light click </text><text font='gt_pressura' weight='light' size='38'>this time</text>",
"app_bell_onboarding_finalize": "Well done!",
"app_bell_settings_advanced": "Advanced",
- "app_bell_settings_advanced_time_units": "Time & units",
+ "app_bell_settings_time_units": "Time & units",
"app_bell_settings_advanced_temp_scale": "Temperature scale",
"app_bell_settings_advanced_language": "Language",
"app_bell_settings_advanced_about": "About",
M image/assets/lang/Espanol.json => image/assets/lang/Espanol.json +1 -1
@@ 634,7 634,7 @@
"app_bell_settings_bedtime_settings_volume": "Volumen",
"app_bell_settings_advanced": "Avanzados",
"app_bell_settings_turn_off": "Apagar",
- "app_bell_settings_advanced_time_units": "Hora y unidades",
+ "app_bell_settings_time_units": "Hora y unidades",
"app_bell_settings_advanced_language": "Idioma",
"app_bell_settings_advanced_about": "Información",
"app_bell_settings_advanced_about_product": "Mudita Harmony",
M image/assets/lang/Francais.json => image/assets/lang/Francais.json +1 -1
@@ 604,7 604,7 @@
"app_bell_settings_bedtime_settings_volume": "Volume",
"app_bell_settings_advanced": "Avancé",
"app_bell_settings_turn_off": "Éteindre",
- "app_bell_settings_advanced_time_units": "Temps et unités",
+ "app_bell_settings_time_units": "Temps et unités",
"app_bell_settings_advanced_language": "Langue",
"app_bell_settings_advanced_about": "À propos",
"app_bell_settings_advanced_about_product": "Mudita Harmony",
M image/assets/lang/Polski.json => image/assets/lang/Polski.json +1 -1
@@ 627,7 627,7 @@
"app_bell_onboarding_info_deep_click_warning": "<text font='gt_pressura' weight='light' size='38'>Głęboko </text><text font='gt_pressura' weight='regular' size='38'>wciśnięty</text>",
"app_bell_onboarding_info_deep_click_correction": "<text font='gt_pressura' weight='light' size='38'>Bądź bardziej delikatny, <br></br>spróbuj </text><text font='gt_pressura' weight='regular' size='38'>tym razem </text><text font='gt_pressura' weight='light' size='38'>lekko kliknąć</text>",
"app_bell_settings_advanced": "Zaawansowane",
- "app_bell_settings_advanced_time_units": "Czas i jednostki",
+ "app_bell_settings_time_units": "Czas i jednostki",
"app_bell_settings_advanced_temp_scale": "Skala temperatury",
"app_bell_settings_alarm_settings": "Alarm",
"app_bell_settings_alarm_settings_title": "Ustawienia alarmu",
M module-apps/apps-common/widgets/TimeSetFmtSpinner.cpp => module-apps/apps-common/widgets/TimeSetFmtSpinner.cpp +5 -3
@@ 36,13 36,15 @@ namespace gui
fmt->setEdges(RectangleEdge::Bottom);
focusChangedCallback = [&](Item &) {
- if (focus && editMode != EditMode::Browse) {
- setFocusItem(timeSetSpinner);
+ if (focus) {
+ setTimeFormat(this->timeFormat);
+ if (editMode != EditMode::Browse) {
+ setFocusItem(timeSetSpinner);
+ }
}
else {
setFocusItem(nullptr);
}
- setTimeFormat(this->timeFormat);
return true;
};
M module-bsp/board/rt1051/bellpx/bsp/lpm/PowerProfile.cpp => module-bsp/board/rt1051/bellpx/bsp/lpm/PowerProfile.cpp +4 -4
@@ 10,10 10,10 @@ namespace bsp
PowerProfile bellPowerProfile;
bellPowerProfile.frequencyShiftLowerThreshold = 50;
- bellPowerProfile.frequencyShiftUpperThreshold = 90;
- bellPowerProfile.maxBelowThresholdCount = 10;
- bellPowerProfile.maxBelowThresholdInRowCount = 5;
- bellPowerProfile.maxAboveThresholdCount = 3;
+ bellPowerProfile.frequencyShiftUpperThreshold = 80;
+ bellPowerProfile.maxBelowThresholdCount = 5;
+ bellPowerProfile.maxBelowThresholdInRowCount = 1;
+ bellPowerProfile.maxAboveThresholdCount = 2;
bellPowerProfile.minimalFrequency = CpuFrequencyHz::Level_0;
bellPowerProfile.frequencyIncreaseIntermediateStep = true;
M module-bsp/board/rt1051/bsp/eMMC/fsl_mmc.c => module-bsp/board/rt1051/bsp/eMMC/fsl_mmc.c +2 -25
@@ 1865,11 1865,7 @@ static status_t MMC_Write(
}
/* Wait for the card's buffer to be not full to write to improve the write performance. */
- error = MMC_PollingCardStatusBusy(card);
- if(kStatus_Success != error)
- {
- return error;
- }
+ while ((GET_SDMMCHOST_STATUS(card->host.base) & CARD_DATA0_STATUS_MASK) != CARD_DATA0_NOT_BUSY) {}
/* Wait for the card write process complete */
if (kStatus_Success != MMC_WaitWriteComplete(card)) {
@@ 2268,11 2264,7 @@ status_t MMC_EraseGroups(mmc_card_t *card, uint32_t startGroup, uint32_t endGrou
}
/* Wait for the card's buffer to be not full to write to improve the write performance. */
- status_t error = MMC_PollingCardStatusBusy(card);
- if(kStatus_Success != error)
- {
- return error;
- }
+ while ((GET_SDMMCHOST_STATUS(card->host.base) & CARD_DATA0_STATUS_MASK) != CARD_DATA0_NOT_BUSY) {}
if (kStatus_Success != MMC_WaitWriteComplete(card)) {
return kStatus_SDMMC_WaitWriteCompleteFailed;
@@ 2639,18 2631,3 @@ status_t MMC_StopBoot(mmc_card_t *card, uint32_t bootMode)
return kStatus_Success;
}
-
-status_t MMC_PollingCardStatusBusy(mmc_card_t *card)
-{
- int retries = 0;
- const int maxRetries = 10000;
- do {
- if ((GET_SDMMCHOST_STATUS(card->host.base) & CARD_DATA0_STATUS_MASK) == CARD_DATA0_NOT_BUSY) {
- return kStatus_Success;
- }
- // yeld
- SDMMCHOST_Delay(0);
- } while (retries++ < maxRetries);
-
- return kStatus_SDMMC_PollingCardIdleFailed;
-}
M module-bsp/board/rt1051/bsp/eMMC/fsl_mmc.h => module-bsp/board/rt1051/bsp/eMMC/fsl_mmc.h +0 -12
@@ 356,18 356,6 @@ extern "C"
*/
status_t MMC_SetMaxEraseUnitSize(mmc_card_t *card);
- /*!
- * @brief Polling card idle status.
- *
- * This function can be used to poll the status from busy to idle.
- *
- * @param card Card descriptor.
- *
- * @retval kStatus_SDMMC_TransferFailed Command tranfer failed.
- * @retval kStatus_Success Operate successfully.
- */
- status_t MMC_PollingCardStatusBusy(mmc_card_t *card);
-
/* @} */
#if defined(__cplusplus)
}
M module-bsp/board/rt1051/bsp/eMMC/fsl_sdmmc_common.h => module-bsp/board/rt1051/bsp/eMMC/fsl_sdmmc_common.h +0 -1
@@ 124,7 124,6 @@ enum _sdmmc_status
kStatus_SDMMC_CardDetectFailed = MAKE_STATUS(kStatusGroup_SDMMC, 39U), /*!< card detect failed */
kStatus_SDMMC_PartitioningFailed = MAKE_STATUS(kStatusGroup_SDMMC, 40U), /*!< Partitioning failed */
kStatus_SDMMC_PartitioningNotSupported = MAKE_STATUS(kStatusGroup_SDMMC, 41U), /*!< Partitioning not supported */
- kStatus_SDMMC_PollingCardIdleFailed = MAKE_STATUS(kStatusGroup_SDMMC, 42U), /*!< polling card idle status failed */
};
/*! @brief card operation voltage */
M module-db/Interface/ThreadRecord.cpp => module-db/Interface/ThreadRecord.cpp +1 -1
@@ 196,7 196,7 @@ std::unique_ptr<db::QueryResult> ThreadRecordInterface::markAsReadQuery(const st
auto ret = false;
if (record.isValid()) {
- LOG_FATAL("query-read %d", static_cast<int>(localQuery->read));
+ LOG_DEBUG("query-read %d", static_cast<int>(localQuery->read));
record.unreadMsgCount = localQuery->read == db::query::MarkAsRead::Read::True ? 0 : 1;
ret = Update(record);
}
M module-gui/gui/widgets/ListView.cpp => module-gui/gui/widgets/ListView.cpp +2 -4
@@ 148,6 148,8 @@ namespace gui
}
};
+ inputCallback = [&](Item &item, const InputEvent &event) { return body->onInput(event); };
+
focusChangedCallback = [this]([[maybe_unused]] Item &item) -> bool {
if (focus) {
setFocus();
@@ 261,8 263,4 @@ namespace gui
return Size(request_w, request_h);
}
- bool ListView::onInput(const InputEvent &inputEvent)
- {
- return body->onInput(inputEvent);
- }
} /* namespace gui */
M module-gui/gui/widgets/ListView.hpp => module-gui/gui/widgets/ListView.hpp +0 -1
@@ 55,7 55,6 @@ namespace gui
void setAlignment(const Alignment &value) override;
// virtual methods from Item
- bool onInput(const InputEvent &inputEvent) override;
bool onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) override;
auto handleRequestResize(const Item *, Length request_w, Length request_h) -> Size override;
};
M module-gui/gui/widgets/ListViewWithArrows.cpp => module-gui/gui/widgets/ListViewWithArrows.cpp +2 -5
@@ 33,6 33,8 @@ namespace gui
}
};
+ inputCallback = [&](Item &item, const InputEvent &event) { return body->onInput(event); };
+
focusChangedCallback = [this]([[maybe_unused]] Item &item) -> bool {
if (focus) {
setFocus();
@@ 213,9 215,4 @@ namespace gui
return true;
}
- bool ListViewWithArrows::onInput(const InputEvent &inputEvent)
- {
- return body->onInput(inputEvent);
- }
-
} /* namespace gui */
M module-gui/gui/widgets/ListViewWithArrows.hpp => module-gui/gui/widgets/ListViewWithArrows.hpp +0 -1
@@ 36,7 36,6 @@ namespace gui
void applySizeRestrictions(unsigned int w, unsigned int h, unsigned int outerLayoutsH, int outerLayoutsMargin);
void setAlignment(const Alignment &value) override;
- bool onInput(const InputEvent &inputEvent) override;
bool onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) override;
};
R module-os/board/rt1051/_exit.c => module-os/board/rt1051/_exit.cpp +33 -3
@@ 33,13 33,28 @@
#include <FreeRTOS.h>
#include <MIMXRT1051.h>
#include <log/log.hpp>
+#include <logdump/logdump.h>
#include <task.h>
#include <macros.h>
+#include <stdbool.h>
+#include <string.h>
+#include <exit_backtrace.h>
+#include <purefs/vfs_subsystem.hpp>
-void __attribute__((noreturn, used)) _exit(int code)
+
+static void __attribute__((noreturn)) stop_system(void)
{
- LOG_INFO("_exit %d", code);
- haltIfDebugging();
+ if (dumpLogs() != 1) {
+ LOG_ERROR("Cannot dump logs");
+ }
+
+ const auto err = purefs::subsystem::unmount_all();
+ if(err) {
+ LOG_WARN("Unable unmount all filesystems with error: %i.", err);
+ } else {
+ LOG_INFO("Filesystems unmounted successfully...");
+ }
+ LOG_INFO("Restarting the system...");
vTaskEndScheduler();
NVIC_SystemReset();
// waiting for system reset
@@ 49,3 64,18 @@ void __attribute__((noreturn, used)) _exit(int code)
#endif
};
}
+
+void __attribute__((noreturn, used)) _exit_backtrace(int code, bool bt_dump)
+{
+ LOG_INFO("_exit %d", code);
+ if( bt_dump ) {
+ _StackTrace_Dump_And_Abort();
+ }
+ stop_system();
+};
+
+
+void __attribute__((noreturn, used)) _exit(int code)
+{
+ _exit_backtrace(code, code!=0);
+}
A module-os/board/rt1051/include/exit_backtrace.h => module-os/board/rt1051/include/exit_backtrace.h +56 -0
@@ 0,0 1,56 @@
+// 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 <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** This is a extension for standard function @see exit which stop the system
+ * and optionaly takes a backtrace
+ * @param[in] code Standard terminate exit code
+ * @param[in] bt_dump If true backtrace will be created
+ * @note Function never returns
+ */
+void __attribute__((noreturn, used)) _exit_backtrace(int code, bool bt_dump);
+
+
+/** This is a standard function @see exit which stop the system
+ * and optionaly takes a backtrace
+ * @param[in] code Standard terminate exit code
+ * @note Function never returns and dump backtrace when code is not equal EXIT_SUCCESS
+ */
+void __attribute__((noreturn, used)) _exit(int code);
+
+
+/** This is internal backtrce function
+ * @note In never shouldn't to be called directly in the user code
+ */
+static inline void __attribute__((always_inline)) _StackTrace_Dump_stage_1(void)
+{
+ // Redirect to the save stacktrace syscall (1)
+ __asm volatile("svc #1\n");
+}
+
+/** This is internal backtrce function
+ * @note In never shouldn't to be called directly in the user code
+ */
+extern void _StackTrace_Dump_stage_2(void);
+
+
+/** This function save a backtrace on the disk and stop the system by abort
+ */
+static inline void __attribute__((always_inline)) _StackTrace_Dump_And_Abort(void)
+{
+ _StackTrace_Dump_stage_1();
+ _StackTrace_Dump_stage_2();
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
M module-os/board/rt1051/port.c => module-os/board/rt1051/port.c +10 -1
@@ 192,7 192,16 @@ volatile uint32_t ulDummy = 0;
void vPortSVCHandler( void )
{
__asm volatile (
- " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */
+ " tst lr, #0x04 \n" /* Extract SVC number from the opcode */
+ " ite eq \n"
+ " mrseq r0, MSP \n"
+ " mrsne r0, PSP \n"
+ " ldr r0, [r0, #24] \n"
+ " sub r0, r0, #2 \n"
+ " ldrb r0, [r0] \n"
+ " cmp r0, #0 \n" /* Check if SVC #0 */
+ " bne _StackTrace_Dump_svc_1 \n" /* Nono zero value go to the dump backtrace */
+ " ldr r3, pxCurrentTCBConst2 \n" /* On SVC #0 Restore the context and start OS. */
" ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
" ldmia r0!, {r4-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
M module-platform/rt1051/src/disk_emmc.cpp => module-platform/rt1051/src/disk_emmc.cpp +2 -3
@@ 105,9 105,8 @@ namespace purefs::blkdev
return statusBlkDevFail;
}
// Wait for the card's buffer to become empty
- auto error = MMC_PollingCardStatusBusy(mmcCard.get());
- if (kStatus_Success != error) {
- return error;
+ while ((GET_SDMMCHOST_STATUS(mmcCard->host.base) & CARD_DATA0_STATUS_MASK) != CARD_DATA0_NOT_BUSY) {
+ taskYIELD();
}
if (pmState == pm_state::suspend) {
driverUSDHC->Enable();
M module-services/service-desktop/endpoints/filesystem/FileContext.cpp => module-services/service-desktop/endpoints/filesystem/FileContext.cpp +32 -26
@@ 4,11 4,11 @@
#include <endpoints/filesystem/FileContext.hpp>
#include <log/log.hpp>
#include <utility>
+#include <fstream>
FileContext::FileContext(const std::filesystem::path &path,
std::size_t size,
std::size_t chunkSize,
- const std::string &openMode,
std::size_t offset)
: path(path), size(size), offset(offset), chunkSize(chunkSize)
{
@@ 16,28 16,18 @@ FileContext::FileContext(const std::filesystem::path &path,
throw std::invalid_argument("Invalid FileContext arguments");
}
- file = std::fopen(path.c_str(), openMode.c_str());
- if (!file) {
- throw std::runtime_error("File open error");
- }
-
- constexpr size_t streamBufferSize = 64 * 1024;
- streamBuffer = std::make_unique<char[]>(streamBufferSize);
- setvbuf(file, streamBuffer.get(), _IOFBF, streamBufferSize);
-
runningCrc32Digest.reset();
}
FileContext::~FileContext()
{
- std::fclose(file);
}
FileReadContext::FileReadContext(const std::filesystem::path &path,
std::size_t size,
std::size_t chunkSize,
std::size_t offset)
- : FileContext(path, size, chunkSize, "rb", offset)
+ : FileContext(path, size, chunkSize, offset)
{}
FileReadContext::~FileReadContext()
@@ 48,7 38,7 @@ FileWriteContext::FileWriteContext(const std::filesystem::path &path,
std::size_t chunkSize,
std::string crc32Digest,
std::size_t offset)
- : FileContext(path, size, chunkSize, "wb", offset), crc32Digest(std::move(crc32Digest))
+ : FileContext(path, size, chunkSize, offset), crc32Digest(std::move(crc32Digest))
{}
FileWriteContext::~FileWriteContext()
@@ 93,23 83,30 @@ auto FileReadContext::read() -> std::vector<std::uint8_t>
{
LOG_DEBUG("Getting file data");
- std::fseek(file, offset, SEEK_SET);
+ std::ifstream file(path, std::ios::binary);
+
+ if (!file.is_open() || file.fail()) {
+ LOG_ERROR("File %s open error", path.c_str());
+ throw std::runtime_error("File open error");
+ }
+
+ file.seekg(offset);
auto dataLeft = std::min(static_cast<std::size_t>(chunkSize), (size - offset));
std::vector<std::uint8_t> buffer(dataLeft);
- auto dataRead = std::fread(buffer.data(), sizeof(int8_t), dataLeft, file);
+ file.read(reinterpret_cast<char *>(buffer.data()), dataLeft);
- if (dataRead != dataLeft) {
+ if (file.bad()) {
LOG_ERROR("File %s read error", path.c_str());
throw std::runtime_error("File read error");
}
- runningCrc32Digest.add(buffer.data(), dataRead);
+ runningCrc32Digest.add(buffer.data(), dataLeft);
- LOG_DEBUG("Read %u bytes", static_cast<unsigned int>(dataRead));
- advanceFileOffset(dataRead);
+ LOG_DEBUG("Read %u bytes", static_cast<unsigned int>(dataLeft));
+ advanceFileOffset(dataLeft);
if (reachedEOF()) {
LOG_INFO("Reached EOF");
@@ 122,22 119,30 @@ auto FileWriteContext::write(const std::vector<std::uint8_t> &data) -> void
{
LOG_DEBUG("Sending file data");
- std::fseek(file, offset, SEEK_SET);
+ std::ofstream file(path, std::ios::binary | std::ios::app);
+
+ if (!file.is_open() || file.fail()) {
+ LOG_ERROR("File %s open error", path.c_str());
+ throw std::runtime_error("File open error");
+ }
+
+ file.seekp(offset);
auto dataLeft = std::min(static_cast<std::size_t>(chunkSize), (size - offset));
- auto dataWritten = std::fwrite(reinterpret_cast<const char *>(data.data()), sizeof(int8_t), dataLeft, file);
+ file.write(reinterpret_cast<const char *>(data.data()), dataLeft);
+ file.flush();
- if (dataWritten != dataLeft) {
+ if (file.bad()) {
LOG_ERROR("File %s write error", path.c_str());
throw std::runtime_error("File write error");
}
- runningCrc32Digest.add(data.data(), dataWritten);
+ runningCrc32Digest.add(data.data(), dataLeft);
- LOG_DEBUG("Written %u bytes", static_cast<unsigned int>(dataWritten));
+ LOG_DEBUG("Written %u bytes", static_cast<unsigned int>(dataLeft));
- advanceFileOffset(dataWritten);
+ advanceFileOffset(dataLeft);
if (reachedEOF()) {
LOG_INFO("Reached EOF of %s", path.c_str());
@@ 152,5 157,6 @@ auto FileWriteContext::crc32Matches() const -> bool
auto FileWriteContext::removeFile() -> void
{
- std::filesystem::remove(path);
+ std::error_code ec;
+ std::filesystem::remove(path, ec);
}
M module-services/service-desktop/endpoints/filesystem/FileOperations.cpp => module-services/service-desktop/endpoints/filesystem/FileOperations.cpp +12 -6
@@ 14,7 14,7 @@ FileOperations &FileOperations::instance()
auto FileOperations::createReceiveIDForFile(const std::filesystem::path &file) -> std::pair<transfer_id, std::size_t>
{
cancelTimedOutReadTransfer();
- const auto rxID = ++runningXfrId;
+ const auto rxID = ++runningRxId;
const auto size = std::filesystem::file_size(file);
if (size == 0) {
@@ 31,11 31,11 @@ auto FileOperations::createReceiveIDForFile(const std::filesystem::path &file) -
void FileOperations::cancelTimedOutReadTransfer()
{
- if (!runningXfrId) {
+ if (runningRxId == 0) {
return;
}
- auto timedOutXfer = runningXfrId - 1;
+ auto timedOutXfer = runningRxId.load();
const auto fileCtxEntry = readTransfers.find(timedOutXfer);
if (fileCtxEntry == readTransfers.end()) {
@@ 43,17 43,19 @@ void FileOperations::cancelTimedOutReadTransfer()
return;
}
+ fileCtxEntry->second.reset();
+
LOG_DEBUG("Canceling timed out rxID %u", static_cast<unsigned>(timedOutXfer));
readTransfers.erase(timedOutXfer);
}
void FileOperations::cancelTimedOutWriteTransfer()
{
- if (!runningXfrId) {
+ if (runningTxId == 0) {
return;
}
- auto timedOutXfer = runningXfrId - 1;
+ auto timedOutXfer = runningTxId.load();
const auto fileCtxEntry = writeTransfers.find(timedOutXfer);
if (fileCtxEntry == writeTransfers.end()) {
@@ 61,6 63,10 @@ void FileOperations::cancelTimedOutWriteTransfer()
return;
}
+ fileCtxEntry->second->removeFile();
+
+ fileCtxEntry->second.reset();
+
LOG_DEBUG("Canceling timed out rxID %u", static_cast<unsigned>(timedOutXfer));
writeTransfers.erase(timedOutXfer);
}
@@ 165,7 171,7 @@ auto FileOperations::createTransmitIDForFile(const std::filesystem::path &file,
const std::string &Crc32) -> transfer_id
{
cancelTimedOutWriteTransfer();
- const auto txID = ++runningXfrId;
+ const auto txID = ++runningTxId;
LOG_DEBUG("Creating txID %u", static_cast<unsigned>(txID));
M module-services/service-desktop/endpoints/include/endpoints/filesystem/FileContext.hpp => module-services/service-desktop/endpoints/include/endpoints/filesystem/FileContext.hpp +0 -3
@@ 19,7 19,6 @@ class FileContext
explicit FileContext(const std::filesystem::path &path,
std::size_t size,
std::size_t chunkSize,
- const std::string &openMode,
std::size_t offset = 0);
virtual ~FileContext();
@@ 40,8 39,6 @@ class FileContext
protected:
std::filesystem::path path{};
- std::FILE *file{};
- std::unique_ptr<char[]> streamBuffer;
std::size_t size{};
std::size_t offset{};
std::size_t chunkSize{};
M module-services/service-desktop/endpoints/include/endpoints/filesystem/FileOperations.hpp => module-services/service-desktop/endpoints/include/endpoints/filesystem/FileOperations.hpp +2 -1
@@ 23,7 23,8 @@ class FileOperations
std::map<transfer_id, std::unique_ptr<FileReadContext>> readTransfers;
std::map<transfer_id, std::unique_ptr<FileWriteContext>> writeTransfers;
- std::atomic<transfer_id> runningXfrId{0};
+ std::atomic<transfer_id> runningRxId{0};
+ std::atomic<transfer_id> runningTxId{0};
auto createFileReadContextFor(const std::filesystem::path &file, std::size_t fileSize, transfer_id xfrId) -> void;
M module-services/service-desktop/parser/ParserFSM.cpp => module-services/service-desktop/parser/ParserFSM.cpp +37 -8
@@ 7,20 7,33 @@
#include <memory>
#include <string>
+#include <Timers/TimerFactory.hpp>
#include "MessageHandler.hpp"
#include <endpoints/EndpointFactory.hpp>
#include <endpoints/message/Common.hpp>
+namespace
+{
+ constexpr auto receiveMsgTimerDelayMs = std::chrono::milliseconds{1000 * 5};
+ constexpr auto parserTimerName = "parserTimer";
+
+} // namespace
+
namespace sdesktop::endpoints
{
- StateMachine::StateMachine(sys::Service *OwnerService) : OwnerServicePtr(OwnerService)
+ StateMachine::StateMachine(sys::Service *OwnerService)
+ : OwnerServicePtr(OwnerService),
+ parserTimer{sys::TimerFactory::createSingleShotTimer(
+ OwnerService, parserTimerName, receiveMsgTimerDelayMs, [this](sys::Timer & /*timer*/) { resetParser(); })}
{}
void StateMachine::processMessage(std::string &&msg)
{
receivedMsg = std::move(msg);
+ restartTimer();
+
switch (state) {
case State::NoMsg:
parseHeader();
@@ 37,6 50,21 @@ namespace sdesktop::endpoints
}
}
+ void StateMachine::resetParser()
+ {
+ payload.clear();
+ header.clear();
+ payloadLength = 0;
+
+ setState(State::NoMsg);
+ LOG_DEBUG("Parser state reset");
+ }
+
+ void StateMachine::restartTimer()
+ {
+ parserTimer.restart(receiveMsgTimerDelayMs);
+ }
+
void StateMachine::parseHeader()
{
payload.clear();
@@ 51,7 79,7 @@ namespace sdesktop::endpoints
if (receivedMsg.size() < message::size_header) // header divided in few parts
{
- state = State::ReceivedPartialHeader;
+ setState(State::ReceivedPartialHeader);
header.append(receivedMsg); // append to whole header string
return;
}
@@ 61,7 89,7 @@ namespace sdesktop::endpoints
if (payloadLength == 0) // failed to obtain payload length from msg
{
LOG_ERROR("Damaged header!");
- state = State::NoMsg;
+ setState(State::NoMsg);
return;
}
@@ 109,7 137,7 @@ namespace sdesktop::endpoints
else // message divided in 2 or more packets
{
payload = receivedMsg.substr(0, std::string::npos); // take rest of the message
- state = State::ReceivedPartialPayload;
+ setState(State::ReceivedPartialPayload);
}
}
@@ 139,20 167,21 @@ namespace sdesktop::endpoints
{
if (payload.empty()) {
LOG_ERROR("Empty payload!");
- state = State::NoMsg;
+ setState(State::NoMsg);
return;
}
messageHandler->parseMessage(payload);
if (!messageHandler->isValid() || messageHandler->isJSONNull()) {
- LOG_DEBUG("Error parsing JSON");
- state = State::NoMsg;
+ LOG_ERROR("Error parsing JSON");
+ setState(State::NoMsg);
return;
}
messageHandler->processMessage();
- state = State::NoMsg;
+ setState(State::NoMsg);
+ parserTimer.stop();
}
void StateMachine::setMessageHandler(std::unique_ptr<MessageHandler> handler)
M module-services/service-desktop/parser/ParserFSM.hpp => module-services/service-desktop/parser/ParserFSM.hpp +6 -1
@@ 5,8 5,10 @@
#include "MessageHandler.hpp"
-#include <json11.hpp>
+#include <Timers/TimerHandle.hpp>
+#include <json11.hpp>
+#include <magic_enum.hpp>
#include <string>
namespace sdesktop::endpoints
@@ 44,8 46,11 @@ namespace sdesktop::endpoints
unsigned long payloadLength = 0;
sys::Service *OwnerServicePtr = nullptr;
std::unique_ptr<MessageHandler> messageHandler;
+ sys::TimerHandle parserTimer;
void parseHeader();
+ void resetParser();
+ void restartTimer();
void parsePartialHeader();
void parseNewMessage();
void parsePartialMessage();
M module-services/service-evtmgr/EventManager.cpp => module-services/service-evtmgr/EventManager.cpp +6 -7
@@ 62,13 62,13 @@ EventManagerSentinel::~EventManagerSentinel()
cpuSentinel->ReleaseMinimumFrequency();
}
-EventManagerCommon::EventManagerCommon(const std::string &name)
+EventManagerCommon::EventManagerCommon(LogDumpFunction logDumpFunction, const std::string &name)
: sys::Service(name, "", stackDepth), loggerTimer{sys::TimerFactory::createPeriodicTimer(
this,
loggerTimerName,
std::chrono::milliseconds{loggerDelayMs},
[this](sys::Timer & /*timer*/) { dumpLogsToFile(); })},
- settings(std::make_shared<settings::Settings>())
+ logDumpFunction(logDumpFunction), settings(std::make_shared<settings::Settings>())
{
LOG_INFO("[%s] Initializing", name.c_str());
alarmTimestamp = 0;
@@ 301,12 301,11 @@ void EventManagerCommon::handleKeyEvent(sys::Message *msg)
int EventManagerCommon::dumpLogsToFile()
{
- const auto logPath = purefs::dir::getLogsPath() / LOG_FILE_NAME;
- const auto ts = cpp_freertos::Ticks::TicksToMs(cpp_freertos::Ticks::GetTicks());
-
- LOG_DEBUG("Log flush timestamp: %d", static_cast<unsigned>(ts));
+ if (logDumpFunction) {
+ return logDumpFunction();
+ }
- return Log::Logger::get().dumpToFile(std::move(logPath));
+ return 0;
}
void EventManagerCommon::handleMinuteUpdate(time_t timestamp)
M module-services/service-evtmgr/service-evtmgr/EventManagerCommon.hpp => module-services/service-evtmgr/service-evtmgr/EventManagerCommon.hpp +30 -26
@@ 35,6 35,29 @@ class EventManagerSentinel
class EventManagerCommon : public sys::Service
{
+ public:
+ using LogDumpFunction = std::function<int()>;
+
+ explicit EventManagerCommon(LogDumpFunction logDumpFunction, const std::string &name = service::name::evt_manager);
+ ~EventManagerCommon() override;
+
+ sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) override;
+
+ // Invoked during initialization
+ sys::ReturnCodes InitHandler() final;
+
+ sys::ReturnCodes DeinitHandler() override;
+
+ void ProcessCloseReason(sys::CloseReason closeReason) override;
+
+ sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override final;
+
+ /**
+ * @brief Sends request to application manager to switch from current application to specific window in application
+ * with specified name .
+ */
+ static bool messageSetApplication(sys::Service *sender, const std::string &applicationName);
+
private:
static constexpr auto stackDepth = 4096;
void handleMinuteUpdate(time_t timestamp);
@@ 45,6 68,13 @@ class EventManagerCommon : public sys::Service
sys::TimerHandle loggerTimer;
+ LogDumpFunction logDumpFunction;
+
+ /// @return: < 0 - error occured during log flush
+ /// @return: 0 - log flush did not happen
+ /// @return: 1 - log flush successflul
+ int dumpLogsToFile();
+
protected:
std::function<void(const time_t)> onMinuteTick;
virtual void handleKeyEvent(sys::Message *msg);
@@ 61,30 91,4 @@ class EventManagerCommon : public sys::Service
uint32_t alarmTimestamp;
// ID of alarm waiting to trigger
uint32_t alarmID;
-
- public:
- explicit EventManagerCommon(const std::string &name = service::name::evt_manager);
- ~EventManagerCommon();
-
- sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) override;
-
- // Invoked during initialization
- sys::ReturnCodes InitHandler() final;
-
- sys::ReturnCodes DeinitHandler() override;
-
- void ProcessCloseReason(sys::CloseReason closeReason) override;
-
- sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override final;
-
- /// @return: < 0 - An error occurred during log flush
- /// @return: 0 - Log file reached max size
- /// @return: 1 - Logs flushed successflully
- int dumpLogsToFile();
-
- /**
- * @brief Sends request to application manager to switch from current application to specific window in application
- * with specified name .
- */
- static bool messageSetApplication(sys::Service *sender, const std::string &applicationName);
};
M module-sys/SystemManager/SystemManagerCommon.cpp => module-sys/SystemManager/SystemManagerCommon.cpp +49 -22
@@ 101,6 101,47 @@ namespace sys
LOG_DEBUG("%s", (GetName() + ":destructor").c_str());
}
+ void SystemManagerCommon::LogPowerOffReason()
+ {
+ // Power off system
+ switch (state) {
+ case SystemManagerCommon::State::Reboot:
+ LOG_INFO(" ---> REBOOT <--- ");
+ break;
+ case SystemManagerCommon::State::ShutdownReady:
+ LOG_INFO(" ---> SHUTDOWN <--- ");
+ break;
+ case SystemManagerCommon::State::RebootToUpdate:
+ LOG_INFO(" ---> REBOOT TO UPDATER <--- ");
+ break;
+ case SystemManagerCommon::State::Running:
+ case SystemManagerCommon::State::Suspend:
+ case SystemManagerCommon::State::Shutdown:
+ LOG_FATAL("State changed after reset/shutdown was requested to: %s! this is terrible failure!",
+ c_str(state));
+ break;
+ }
+ }
+
+ void SystemManagerCommon::PowerOff()
+ {
+ switch (state) {
+ case State::Reboot:
+ powerManager->Reboot();
+ break;
+ case State::ShutdownReady:
+ powerManager->PowerOff();
+ break;
+ case State::RebootToUpdate:
+ powerManager->RebootToUpdate(updateReason);
+ break;
+ case SystemManagerCommon::State::Running:
+ case SystemManagerCommon::State::Suspend:
+ case SystemManagerCommon::State::Shutdown:
+ exit(1);
+ }
+ }
+
void SystemManagerCommon::Run()
{
initialize();
@@ 132,34 173,19 @@ namespace sys
}
DestroySystemService(service::name::evt_manager, this);
-
CloseService();
- EndScheduler();
+ // it should be called before systemDeinit to make sure this log is dumped to the file
+ LogPowerOffReason();
if (systemDeinit) {
systemDeinit();
}
+ EndScheduler();
+
// Power off system
- switch (state) {
- case State::Reboot:
- LOG_INFO(" ---> REBOOT <--- ");
- powerManager->Reboot();
- break;
- case State::ShutdownReady:
- LOG_INFO(" ---> SHUTDOWN <--- ");
- powerManager->PowerOff();
- break;
- case State::RebootToUpdate:
- LOG_INFO(" ---> REBOOT TO UPDATER <--- ");
- powerManager->RebootToUpdate(updateReason);
- break;
- default:
- LOG_FATAL("State changed after reset/shutdown was requested to: %s! this is terrible failure!",
- c_str(state));
- exit(1);
- }
+ PowerOff();
}
void SystemManagerCommon::initialize()
@@ 323,11 349,12 @@ namespace sys
auto resp = std::static_pointer_cast<ResponseMessage>(ret.second);
if (ret.first != ReturnCodes::Success) {
- LOG_ERROR("Service to close: %s did not respond", name.c_str());
+ LOG_ERROR("Service to close: %s did not respond, error code %d", name.c_str(), static_cast<int>(ret.first));
return false;
}
else if (resp->retCode != ReturnCodes::Success) {
- LOG_ERROR("Service %s noticed failure at close", name.c_str());
+ LOG_ERROR(
+ "Service %s noticed failure at close, error code %d", name.c_str(), static_cast<int>(resp->retCode));
return false;
}
return true;
M module-sys/SystemManager/include/SystemManager/SystemManagerCommon.hpp => module-sys/SystemManager/include/SystemManager/SystemManagerCommon.hpp +4 -0
@@ 148,6 148,10 @@ namespace sys
void Run() override;
+ void LogPowerOffReason();
+
+ void PowerOff();
+
void StartSystemServices();
static bool RunService(std::shared_ptr<Service> service, Service *caller, TickType_t timeout = 5000);
M module-utils/log/CMakeLists.txt => module-utils/log/CMakeLists.txt +1 -1
@@ 2,6 2,7 @@ add_library(log STATIC)
add_subdirectory(api)
add_subdirectory(board)
+add_subdirectory(logdump)
target_sources(log
PRIVATE
@@ 16,7 17,6 @@ target_include_directories(log PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(log
PRIVATE
utility
- purefs-paths
PUBLIC
module-os
log-api
M module-utils/log/Logger.cpp => module-utils/log/Logger.cpp +7 -1
@@ 136,7 136,13 @@ namespace Log
/// @return: 1 - log flush successflul
auto Logger::dumpToFile(std::filesystem::path logPath) -> int
{
- auto firstDump = !std::filesystem::exists(logPath);
+ std::error_code errorCode;
+ auto firstDump = !std::filesystem::exists(logPath, errorCode);
+ if (errorCode) {
+ LOG_ERROR("Failed to check if file %s exists, error: %d", logPath.c_str(), errorCode.value());
+ return -EIO;
+ }
+
if (const bool maxSizeExceeded = !firstDump && std::filesystem::file_size(logPath) > maxFileSize;
maxSizeExceeded) {
LOG_DEBUG("Max log file size exceeded. Rotating log files...");
A module-utils/log/logdump/CMakeLists.txt => module-utils/log/logdump/CMakeLists.txt +19 -0
@@ 0,0 1,19 @@
+add_library(logdump STATIC)
+
+target_sources(logdump
+ PRIVATE
+ logdump.cpp
+ PUBLIC
+ include/logdump/logdump.h
+)
+
+target_include_directories(logdump
+ PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
+)
+
+target_link_libraries(logdump
+ PRIVATE
+ purefs-paths
+ log
+)
A module-utils/log/logdump/include/logdump/logdump.h => module-utils/log/logdump/include/logdump/logdump.h +17 -0
@@ 0,0 1,17 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+ /// @return: < 0 - error occurred during log flush
+ /// @return: 0 - log flush did not happen
+ /// @return: 1 - log flush successful
+ int dumpLogs();
+
+#ifdef __cplusplus
+}
+#endif
A module-utils/log/logdump/logdump.cpp => module-utils/log/logdump/logdump.cpp +11 -0
@@ 0,0 1,11 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <logdump/logdump.h>
+#include <purefs/filesystem_paths.hpp>
+#include <Logger.hpp>
+
+int dumpLogs()
+{
+ return Log::Logger::get().dumpToFile(purefs::dir::getLogsPath() / LOG_FILE_NAME);
+}
M products/BellHybrid/BellHybridMain.cpp => products/BellHybrid/BellHybridMain.cpp +7 -3
@@ 31,13 31,14 @@
#include <Application.hpp>
#include <ApplicationLauncher.hpp>
-#include <Logger.hpp>
#include <log/log.hpp>
+#include <logdump/logdump.h>
+#include <Logger.hpp>
#include <product/version.hpp>
#include <sys/SystemManager.hpp>
-#include <time/AlarmOperations.hpp>
#include <SystemWatchdog/SystemWatchdog.hpp>
#include <thread.hpp>
+#include <time/AlarmOperations.hpp>
#include <memory>
#include <vector>
@@ 66,7 67,7 @@ int main()
}
std::vector<std::unique_ptr<sys::BaseServiceCreator>> systemServices;
- systemServices.emplace_back(sys::CreatorFor<EventManager>());
+ systemServices.emplace_back(sys::CreatorFor<EventManager>([]() { return dumpLogs(); }));
systemServices.emplace_back(sys::CreatorFor<ServiceDB>());
systemServices.emplace_back(sys::CreatorFor<service::Audio>());
systemServices.emplace_back(sys::CreatorFor<ServiceDesktop>());
@@ 116,6 117,9 @@ int main()
[&platform] {
try {
LOG_DEBUG("System deinit");
+ if (dumpLogs() != 1) {
+ LOG_ERROR("Cannot dump logs");
+ }
platform->deinit();
}
catch (const std::runtime_error &e) {
M products/BellHybrid/CMakeLists.txt => products/BellHybrid/CMakeLists.txt +5 -0
@@ 17,6 17,7 @@ target_compile_options(BellHybrid
target_sources(BellHybrid
PRIVATE
+ ${TARGET_SOURCES}
BellHybridMain.cpp
PlatformFactory.cpp
EinkSentinelBell.cpp
@@ 51,6 52,7 @@ target_link_libraries(BellHybrid
bell::audio
bell::evtmgr
log
+ logdump
messagetype
module-bsp
module-vfs
@@ 101,3 103,6 @@ add_subdirectory(apps)
add_subdirectory(keymap)
add_subdirectory(services)
add_subdirectory(sys)
+
+option(CONFIG_ENABLE_TEMP "Enable displaying temperature" OFF)
+configure_file(config/ProductConfig.in.hpp ${CMAKE_BINARY_DIR}/ProductConfig.hpp @ONLY)
M products/BellHybrid/EinkSentinelBell.cpp => products/BellHybrid/EinkSentinelBell.cpp +1 -1
@@ 9,7 9,7 @@ namespace service::eink
{
namespace
{
- constexpr auto RedrawEinkCpuFrequency = bsp::CpuFrequencyHz::Level_5;
+ constexpr auto RedrawEinkCpuFrequency = bsp::CpuFrequencyHz::Level_4;
} // namespace
EinkSentinel::EinkSentinel(std::string name, sys::Service *service) : sys::CpuSentinel(name, service)
M products/BellHybrid/apps/Application.cpp => products/BellHybrid/apps/Application.cpp +8 -0
@@ 5,6 5,7 @@
#include <common/models/AlarmModel.hpp>
+#include <audio/AudioMessage.hpp>
#include <appmgr/messages/IdleTimerMessage.hpp>
#include <common/BellPowerOffPresenter.hpp>
#include <common/popups/presenter/AlarmActivatedPresenter.hpp>
@@ 116,6 117,13 @@ namespace app
void Application::onStop()
{
stopIdleTimer();
+ stopAllAudio();
+ }
+
+ void Application::stopAllAudio()
+ {
+ auto msg = std::make_shared<service::AudioStopRequest>();
+ this->bus.sendUnicast(msg, service::audioServiceName);
}
void Application::startIdleTimer()
M products/BellHybrid/apps/CMakeLists.txt => products/BellHybrid/apps/CMakeLists.txt +1 -0
@@ 18,6 18,7 @@ target_link_libraries(app
bell::app-common
bell::appmgr
bell::alarms
+ bell::audio
)
add_subdirectory(application-bell-main)
M products/BellHybrid/apps/application-bell-bedtime/ApplicationBellBedtime.cpp => products/BellHybrid/apps/application-bell-bedtime/ApplicationBellBedtime.cpp +2 -1
@@ 33,7 33,8 @@ namespace app
void ApplicationBellBedtime::createUserInterface()
{
windowsFactory.attach(gui::name::window::main_window, [](ApplicationCommon *app, const std::string &) {
- auto bedtimeModel = std::make_unique<bell_bedtime::BedtimeModel>(app);
+ auto audioModel = std::make_unique<AudioModel>(app);
+ auto bedtimeModel = std::make_unique<bell_bedtime::BedtimeModel>(app, std::move(audioModel));
auto provider = std::make_shared<bell_bedtime::BedtimeListItemProvider>(std::move(bedtimeModel));
auto presenter = std::make_unique<bell_bedtime::BellBedtimeWindowPresenter>(provider);
return std::make_unique<gui::BellBedtimeWindow>(app, std::move(presenter));
M products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.cpp => products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.cpp +10 -0
@@ 107,6 107,7 @@ namespace app::home_screen
}
void HomeScreenPresenter::handleAlarmModelReady()
{
+ setStartupAlarmState();
getView()->setAlarmTime(alarmModel->getAlarmTime());
stateController->handleAlarmModelReady();
}
@@ 145,4 146,13 @@ namespace app::home_screen
{
return latchPressed;
}
+
+ void HomeScreenPresenter::setStartupAlarmState()
+ {
+ static auto isStartup = true;
+ if (isStartup) {
+ alarmModel->activate(!latchPressed);
+ isStartup = false;
+ }
+ }
} // namespace app::home_screen
M products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.hpp => products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.hpp +2 -0
@@ 149,6 149,8 @@ namespace app::home_screen
std::unique_ptr<ProgressTimerWithSnoozeTimer> snoozeTimer;
bool latchPressed = false;
+ void setStartupAlarmState();
+
static constexpr auto timerName = "HS_timer";
static constexpr auto snoozeTick = std::chrono::seconds(1);
};
M products/BellHybrid/apps/application-bell-main/presenters/StateController.cpp => products/BellHybrid/apps/application-bell-main/presenters/StateController.cpp +4 -6
@@ 45,9 45,9 @@ namespace app::home_screen
return alarmModel.getAlarmStatus() == alarms::AlarmStatus::Ringing;
};
- auto switchToMenu = [](AbstractView &view) { view.switchToMenu(); };
- auto makeAlarmEditable = [](AbstractView &view) { view.setAlarmEdit(true); };
- auto makeAlarmNonEditable = [](AbstractView &view) { view.setAlarmEdit(false); };
+ auto switchToMenu = [](AbstractView &view) { view.switchToMenu(); };
+ auto makeAlarmEditable = [](AbstractView &view) { view.setAlarmEdit(true); };
+ auto makeAlarmNonEditable = [](AbstractView &view) { view.setAlarmEdit(false); };
auto switchToBatteryStatus = [](AbstractView &view) { view.switchToBatteryStatus(); };
auto updateBottomStats =
[](AbstractView &view, AbstractBatteryModel &batteryModel, AbstractTemperatureModel &temperatureModel) {
@@ 83,7 83,6 @@ namespace app::home_screen
alarmModel.setDefaultAlarmTime();
view.setAlarmTime(alarmModel.getAlarmTime());
};
- auto isDeepPress = [](AbstractPresenter &presenter) -> bool { return presenter.isStartupDeepPress(); };
} // namespace Helpers
namespace Events
@@ 289,7 288,6 @@ namespace app::home_screen
"Deactivated"_s + sml::on_entry<_> / Deactivated::entry,
"Deactivated"_s + event<Events::Reset> = "Init"_s,
- "Deactivated"_s [Helpers::isDeepPress] = "DeactivatedWait"_s,
"Deactivated"_s + event<Events::LightPress>/ Helpers::switchToMenu,
"Deactivated"_s + event<Events::RotateLeftPress> / Helpers::makeAlarmEditable = "DeactivatedEdit"_s,
"Deactivated"_s + event<Events::RotateRightPress> / Helpers::makeAlarmEditable = "DeactivatedEdit"_s,
@@ 363,7 361,7 @@ namespace app::home_screen
"AlarmRinging"_s + sml::on_exit<_> / AlarmRinging::exit,
"AlarmRinging"_s + event<Events::Reset> = "Init"_s,
"AlarmRinging"_s + event<Events::Timer> [Helpers::isSnoozeAllowed] / Helpers::snooze = "AlarmSnoozedWait"_s,
- "AlarmRinging"_s + event<Events::Timer> [!Helpers::isSnoozeAllowed] / Helpers::setDefaultAlarmTime = "ActivatedWait"_s,
+ "AlarmRinging"_s + event<Events::Timer> [!Helpers::isSnoozeAllowed] = "ActivatedWait"_s,
"AlarmRinging"_s + event<Events::LightPress> = "AlarmSnoozedWait"_s,
"AlarmRinging"_s + event<Events::RotateLeftPress> = "AlarmSnoozedWait"_s,
"AlarmRinging"_s + event<Events::RotateRightPress> = "AlarmSnoozedWait"_s,
M products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp => products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp +15 -3
@@ 5,6 5,7 @@
#include "data/BellMainStyle.hpp"
#include "widgets/SnoozeTimer.hpp"
#include "BellBatteryStatusWindow.hpp"
+#include "ProductConfig.hpp"
#include <application-bell-main/ApplicationBellMain.hpp>
#include <apps-common/widgets/BellBaseLayout.hpp>
@@ 18,7 19,6 @@
#include <time/time_constants.hpp>
#include <widgets/AlarmSetSpinner.hpp>
#include <widgets/TimeSetFmtSpinner.hpp>
-#include <widgets/TimeSetSpinner.hpp>
#include <chrono>
@@ 117,11 117,12 @@ namespace gui
bottomBox = new HBox(body->lastBox, 0, 0, 0, 0);
bottomBox->setMinimumSize(style::bell_base_layout::outer_layouts_w, style::bell_base_layout::outer_layouts_h);
bottomBox->setEdges(RectangleEdge::None);
+ bottomBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
battery = new BellBattery(bottomBox, 0, 0, 0, 0);
battery->setMinimumSize(battery::battery_widget_w, battery::battery_widget_h);
battery->setEdges(RectangleEdge::None);
- battery->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
+ battery->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
battery->setVisible(false);
bottomText = new TextFixedSize(bottomBox, 0, 0, 0, 0);
@@ 187,19 188,25 @@ namespace gui
void BellHomeScreenWindow::setTemperature(utils::temperature::Temperature newTemp)
{
+#if CONFIG_ENABLE_TEMP == 1
bottomText->setFont(bellMainStyle::mainWindow::bottomDescription::font_normal);
bottomText->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
bottomText->setText(utils::temperature::tempToStrDec(newTemp));
bottomBox->resizeItems();
+#else
+ bottomText->setVisible(false);
+ bottomBox->resizeItems();
+#endif
}
void BellHomeScreenWindow::setBottomDescription(const UTF8 &desc)
{
battery->setVisible(false);
- bottomBox->resizeItems();
+ bottomText->setVisible(true);
bottomText->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
bottomText->setFont(bellMainStyle::mainWindow::bottomDescription::font_small);
bottomText->setRichText(desc);
+ bottomBox->resizeItems();
}
void BellHomeScreenWindow::setBatteryLevelState(const Store::Battery &batteryContext)
@@ 209,7 216,12 @@ namespace gui
bottomText->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
}
else {
+#if CONFIG_ENABLE_TEMP == 1
bottomText->setAlignment(Alignment(Alignment::Horizontal::Right, Alignment::Vertical::Center));
+ battery->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
+#else
+ battery->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
+#endif
}
bottomBox->resizeItems();
}
M products/BellHybrid/apps/application-bell-meditation-timer/presenter/IntervalChimePresenter.cpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/IntervalChimePresenter.cpp +3 -2
@@ 29,12 29,13 @@ namespace app::meditation
std::string IntervalChimePresenter::getCurrentInterval() const
{
- // Always set interval as none
+ const auto value = settings->getValue(intervalDBRecordName, settings::SettingsScope::AppLocal);
for (auto const &option : intervalOptions) {
- if (option.first == std::chrono::minutes{0}) {
+ if (utils::to_string(option.first.count()) == value) {
return option.second;
}
}
+ // If not found, return "None"
return intervalOptions.at(0).second;
}
M products/BellHybrid/apps/application-bell-onboarding/windows/OnBoardingSettingsWindow.hpp => products/BellHybrid/apps/application-bell-onboarding/windows/OnBoardingSettingsWindow.hpp +1 -1
@@ 3,7 3,7 @@
#pragma once
-#include <application-bell-settings/windows/advanced/BellSettingsTimeUnitsWindow.hpp>
+#include <application-bell-settings/windows/BellSettingsTimeUnitsWindow.hpp>
namespace gui
{
M products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp => products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp +12 -12
@@ 18,7 18,6 @@
#include "presenter/advanced/FrontlightPresenter.hpp"
#include "windows/advanced/AboutYourBellWindow.hpp"
#include "windows/advanced/BellSettingsAdvancedWindow.hpp"
-#include "windows/advanced/BellSettingsTimeUnitsWindow.hpp"
#include "windows/advanced/BellSettingsLanguageWindow.hpp"
#include "windows/advanced/BellSettingsFrontlightWindow.hpp"
#include "windows/alarm_settings/BellSettingsAlarmSettingsMenuWindow.hpp"
@@ 27,6 26,7 @@
#include "windows/alarm_settings/BellSettingsPrewakeUpWindow.hpp"
#include "windows/BellSettingsBedtimeToneWindow.hpp"
#include "windows/BellSettingsHomeViewWindow.hpp"
+#include "windows/BellSettingsTimeUnitsWindow.hpp"
#include "windows/BellSettingsWindow.hpp"
#include "widgets/DialogYesNo.hpp"
@@ 87,15 87,6 @@ namespace app
});
windowsFactory.attach(
- gui::window::name::bellSettingsTimeUnits, [](ApplicationCommon *app, const std::string &name) {
- auto temperatureUnitModel = std::make_unique<bell_settings::TemperatureUnitModel>(app);
- auto timeUnitsProvider = std::make_shared<bell_settings::TimeUnitsModel>(app);
- auto presenter = std::make_unique<bell_settings::TimeUnitsWindowPresenter>(
- timeUnitsProvider, std::move(temperatureUnitModel));
- return std::make_unique<gui::BellSettingsTimeUnitsWindow>(app, std::move(presenter));
- });
-
- windowsFactory.attach(
gui::window::name::bellSettingsLanguage, [&](ApplicationCommon *app, const std::string &name) {
auto presenter = std::make_unique<bell_settings::LanguageWindowPresenter>(this);
return std::make_unique<gui::BellSettingsLanguageWindow>(app, std::move(presenter), name);
@@ 122,8 113,8 @@ namespace app
windowsFactory.attach(
gui::window::name::bellSettingsBedtimeTone, [this](ApplicationCommon *app, const std::string &name) {
- auto bedtimeModel = std::make_shared<bell_bedtime::BedtimeModel>(app);
- auto audioModel = std::make_unique<AudioModel>(this);
+ auto audioModel = std::make_unique<AudioModel>(app);
+ auto bedtimeModel = std::make_shared<bell_bedtime::BedtimeModel>(app, std::move(audioModel));
auto soundsRepository =
std::make_unique<SoundsRepository>(alarms::paths::getBedtimeReminderChimesDir());
auto provider = std::make_shared<bell_settings::BedtimeSettingsListItemProvider>(
@@ 133,6 124,15 @@ namespace app
return std::make_unique<gui::BellSettingsBedtimeToneWindow>(app, std::move(presenter));
});
+ windowsFactory.attach(
+ gui::window::name::bellSettingsTimeUnits, [](ApplicationCommon *app, const std::string &name) {
+ auto temperatureUnitModel = std::make_unique<bell_settings::TemperatureUnitModel>(app);
+ auto timeUnitsProvider = std::make_shared<bell_settings::TimeUnitsModel>(app);
+ auto presenter = std::make_unique<bell_settings::TimeUnitsWindowPresenter>(
+ timeUnitsProvider, std::move(temperatureUnitModel));
+ return std::make_unique<gui::BellSettingsTimeUnitsWindow>(app, std::move(presenter));
+ });
+
windowsFactory.attach(gui::BellTurnOffOptionWindow::defaultName,
[](ApplicationCommon *app, const std::string &name) {
return std::make_unique<gui::BellTurnOffOptionWindow>(app);
M products/BellHybrid/apps/application-bell-settings/CMakeLists.txt => products/BellHybrid/apps/application-bell-settings/CMakeLists.txt +2 -2
@@ 52,12 52,12 @@ target_sources(application-bell-settings
widgets/DialogYesNo.cpp
windows/BellSettingsBedtimeToneWindow.cpp
+ windows/BellSettingsTimeUnitsWindow.cpp
windows/BellSettingsHomeViewWindow.cpp
windows/BellSettingsWindow.cpp
windows/advanced/AboutYourBellWindow.cpp
windows/advanced/BellSettingsAdvancedWindow.cpp
windows/advanced/BellSettingsLanguageWindow.cpp
- windows/advanced/BellSettingsTimeUnitsWindow.cpp
windows/advanced/BellSettingsFrontlightWindow.cpp
windows/alarm_settings/BellSettingsAlarmSettingsSnoozeWindow.cpp
windows/alarm_settings/BellSettingsAlarmSettingsMenuWindow.cpp
@@ 113,7 113,7 @@ target_sources(application-bell-settings
PUBLIC
include/application-bell-settings/models/TimeUnitsModel.hpp
include/application-bell-settings/presenter/TimeUnitsPresenter.hpp
- include/application-bell-settings/windows/advanced/BellSettingsTimeUnitsWindow.hpp
+ include/application-bell-settings/windows/BellSettingsTimeUnitsWindow.hpp
include/application-bell-settings/ApplicationBellSettings.hpp
)
M products/BellHybrid/apps/application-bell-settings/data/BellSettingsStyle.hpp => products/BellHybrid/apps/application-bell-settings/data/BellSettingsStyle.hpp +1 -1
@@ 19,7 19,7 @@ namespace gui
namespace time_fmt_set_list_item
{
- inline constexpr auto font = style::window::font::supersizemelight;
+ inline constexpr auto font = style::window::font::supersizeme;
} // namespace time_fmt_set_list_item
namespace top_text
R products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/windows/advanced/BellSettingsTimeUnitsWindow.hpp => products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/windows/BellSettingsTimeUnitsWindow.hpp +0 -0
M products/BellHybrid/apps/application-bell-settings/models/TimeUnitsModel.cpp => products/BellHybrid/apps/application-bell-settings/models/TimeUnitsModel.cpp +15 -11
@@ 5,10 5,10 @@
#include "widgets/TimeFormatSetListItem.hpp"
#include "widgets/TimeSetListItem.hpp"
#include "widgets/TemperatureUnitListItem.hpp"
+#include "ProductConfig.hpp"
#include <gui/widgets/ListViewEngine.hpp>
#include <gui/widgets/Style.hpp>
-#include <gui/widgets/text/Text.hpp>
#include <service-time/Constants.hpp>
#include <service-time/api/TimeSettingsApi.hpp>
#include <service-time/service-time/TimeMessage.hpp>
@@ 56,9 56,11 @@ namespace app::bell_settings
timeSetListItem->timeSetFmtSpinner->setTimeFormat(timeFmtSetListItem->getTimeFmt());
};
+#if CONFIG_ENABLE_TEMP == 1
temperatureUnitListItem =
new gui::TemperatureUnitListItem(utils::translate("app_bell_settings_advanced_temp_scale"));
internalData.push_back(temperatureUnitListItem);
+#endif
for (auto item : internalData) {
item->deleteByList = false;
@@ 72,27 74,23 @@ namespace app::bell_settings
void TimeUnitsModel::saveData()
{
- const auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
- const auto newTime = std::localtime(&now);
- newTime->tm_hour = timeSetListItem->timeSetFmtSpinner->getHour();
- newTime->tm_min = timeSetListItem->timeSetFmtSpinner->getMinute();
+ const auto newTime = timeSetListItem->timeSetFmtSpinner->getTime();
+ const auto time_tm = std::localtime(&newTime);
const auto newFmt = timeFmtSetListItem->getTimeFmt();
LOG_INFO("Setting new time: %d:%d fmt: %s",
- newTime->tm_hour,
- newTime->tm_min,
+ time_tm->tm_hour,
+ time_tm->tm_min,
utils::time::Locale::format(newFmt).c_str());
- sendRtcUpdateTimeMessage(std::mktime(newTime));
+ sendRtcUpdateTimeMessage(newTime);
sendTimeFmtUpdateMessage(newFmt);
}
void TimeUnitsModel::loadData()
{
const auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
- const auto time = std::localtime(&now);
const auto timeFormat = stm::api::timeFormat();
- timeSetListItem->timeSetFmtSpinner->setHour(time->tm_hour);
- timeSetListItem->timeSetFmtSpinner->setMinute(time->tm_min);
timeSetListItem->timeSetFmtSpinner->setTimeFormat(timeFormat);
+ timeSetListItem->timeSetFmtSpinner->setTime(now);
timeFmtSetListItem->setTimeFmt(timeFormat);
}
@@ 116,12 114,18 @@ namespace app::bell_settings
auto TimeUnitsModel::getTemperatureUnit() const -> utils::temperature::Temperature::Unit
{
+#if CONFIG_ENABLE_TEMP == 1
return *utils::temperature::strToUnit(temperatureUnitListItem->getUnitAsStr());
+#else
+ return utils::temperature::Temperature::Unit::Celsius;
+#endif
}
auto TimeUnitsModel::setTemperatureUnit(const utils::temperature::Temperature::Unit unit) -> void
{
+#if CONFIG_ENABLE_TEMP == 1
temperatureUnitListItem->setUnit(unit);
+#endif
}
void TimeUnitsModelFactoryResetValues::loadData()
R products/BellHybrid/apps/application-bell-settings/windows/advanced/BellSettingsTimeUnitsWindow.cpp => products/BellHybrid/apps/application-bell-settings/windows/BellSettingsTimeUnitsWindow.cpp +2 -2
@@ 3,7 3,7 @@
#include "application-bell-settings/ApplicationBellSettings.hpp"
#include "BellSettingsStyle.hpp"
-#include "windows/advanced/BellSettingsTimeUnitsWindow.hpp"
+#include "windows/BellSettingsTimeUnitsWindow.hpp"
#include <gui/input/InputEvent.hpp>
#include <apps-common/options/OptionStyle.hpp>
@@ 24,7 24,7 @@ namespace gui
finishedCallback = [this]() {
application->switchWindow(
window::bell_finished::defaultName,
- BellFinishedWindowData::Factory::create("circle_success_big", gui::window::name::bellSettingsAdvanced));
+ BellFinishedWindowData::Factory::create("circle_success_big", gui::name::window::main_window));
};
}
M products/BellHybrid/apps/application-bell-settings/windows/BellSettingsWindow.cpp => products/BellHybrid/apps/application-bell-settings/windows/BellSettingsWindow.cpp +1 -0
@@ 44,6 44,7 @@ namespace gui
addWinSettings(utils::translate("app_bell_settings_alarm_settings"), BellSettingsAlarmSettingsMenuWindow::name);
addWinSettings(utils::translate("app_bell_settings_bedtime_tone"), window::name::bellSettingsBedtimeTone);
+ addWinSettings(utils::translate("app_bell_settings_time_units"), window::name::bellSettingsTimeUnits);
addWinSettings(utils::translate("app_bell_settings_advanced"), window::name::bellSettingsAdvanced);
addWinSettings(utils::translate("app_bell_settings_turn_off"), BellTurnOffOptionWindow::defaultName);
M products/BellHybrid/apps/application-bell-settings/windows/advanced/BellSettingsAdvancedWindow.cpp => products/BellHybrid/apps/application-bell-settings/windows/advanced/BellSettingsAdvancedWindow.cpp +0 -3
@@ 69,9 69,6 @@ namespace gui
std::make_unique<gui::option::OptionBellMenu>(name, callback(window), nullptr, this));
};
- addOption(utils::translate("app_bell_settings_advanced_time_units"),
- gui::window::name::bellSettingsTimeUnits,
- defaultCallback);
addOption(utils::translate("app_bell_settings_advanced_language"),
gui::window::name::bellSettingsLanguage,
defaultCallback);
M products/BellHybrid/apps/common/CMakeLists.txt => products/BellHybrid/apps/common/CMakeLists.txt +1 -0
@@ 38,6 38,7 @@ target_sources(application-bell-common
src/options/BellOptionWindow.cpp
src/options/BellShortOptionWindow.cpp
src/options/OptionBellMenu.cpp
+ src/options/BellOptionsNavigation.cpp
PUBLIC
include/common/BellListItemProvider.hpp
include/common/SoundsRepository.hpp
M products/BellHybrid/apps/common/include/common/models/BedtimeModel.hpp => products/BellHybrid/apps/common/include/common/models/BedtimeModel.hpp +1 -2
@@ 65,9 65,8 @@ namespace app::bell_bedtime
public:
BedtimeModel() = delete;
- explicit BedtimeModel(sys::Service *app)
+ explicit BedtimeModel(ApplicationCommon *app, std::unique_ptr<AudioModel> &&audioModel)
{
- audioModel = std::make_unique<AudioModel>(static_cast<ApplicationCommon *>(app));
bedtimeOnOff = std::make_unique<bell_bedtime::BedtimeOnOffModel>(app);
bedtimeTime = std::make_unique<bell_bedtime::BedtimeTimeModel>(app);
bedtimeTone = std::make_unique<bell_bedtime::AlarmToneModel>(app);
A products/BellHybrid/apps/common/include/common/options/BellOptionsNavigation.hpp => products/BellHybrid/apps/common/include/common/options/BellOptionsNavigation.hpp +11 -0
@@ 0,0 1,11 @@
+// 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 <InputEvent.hpp>
+
+namespace gui
+{
+ InputEvent invertNavigationDirection(const InputEvent &inputEvent);
+}; // namespace gui
M products/BellHybrid/apps/common/src/options/BellOptionWindow.cpp => products/BellHybrid/apps/common/src/options/BellOptionWindow.cpp +6 -0
@@ 3,6 3,7 @@
#include "common/options/BellOptionWindow.hpp"
#include "common/options/OptionBellMenu.hpp"
+#include "common/options/BellOptionsNavigation.hpp"
#include <messages/OptionsWindow.hpp>
#include <TextFixedSize.hpp>
@@ 38,6 39,11 @@ namespace gui
optionsList->prepareRebuildCallback = [this]() { recreateOptions(); };
optionsModel->createData(options);
+ auto storedCallback = optionsList->inputCallback;
+ optionsList->inputCallback = [&, storedCallback](Item &item, const InputEvent &event) {
+ return storedCallback(item, invertNavigationDirection(event));
+ };
+
setFocusItem(optionsList);
}
A products/BellHybrid/apps/common/src/options/BellOptionsNavigation.cpp => products/BellHybrid/apps/common/src/options/BellOptionsNavigation.cpp +19 -0
@@ 0,0 1,19 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "common/options/BellOptionsNavigation.hpp"
+
+namespace gui
+{
+ InputEvent invertNavigationDirection(const InputEvent &inputEvent)
+ {
+ InputEvent input = inputEvent;
+ if (input.is(KeyCode::KEY_UP)) {
+ input.setKeyCode(KeyCode::KEY_DOWN);
+ }
+ else if (input.is(KeyCode::KEY_DOWN)) {
+ input.setKeyCode(KeyCode::KEY_UP);
+ }
+ return input;
+ }
+}; // namespace gui
M products/BellHybrid/apps/common/src/options/BellShortOptionWindow.cpp => products/BellHybrid/apps/common/src/options/BellShortOptionWindow.cpp +7 -0
@@ 3,6 3,7 @@
#include "common/options/BellShortOptionWindow.hpp"
#include "common/options/OptionBellMenu.hpp"
+#include "common/options/BellOptionsNavigation.hpp"
#include <messages/OptionsWindow.hpp>
#include <TextFixedSize.hpp>
@@ 14,6 15,11 @@ namespace gui
app, style::bell_options::h + 2 * style::bell_options::option_margin))
{
buildInterface();
+
+ auto storedCallback = optionsList->inputCallback;
+ optionsList->inputCallback = [&, storedCallback](Item &item, const InputEvent &event) {
+ return storedCallback(item, invertNavigationDirection(event));
+ };
}
void BellShortOptionWindow::rebuild()
@@ 72,4 78,5 @@ namespace gui
optionsList->rebuildList(listview::RebuildType::InPlace);
}
+
} /* namespace gui */
M products/BellHybrid/apps/include/Application.hpp => products/BellHybrid/apps/include/Application.hpp +1 -0
@@ 18,6 18,7 @@ namespace app
void startIdleTimer();
void restartIdleTimer();
void stopIdleTimer();
+ void stopAllAudio();
private:
sys::MessagePointer handleKBDKeyEvent(sys::Message *msgl) override;
R products/BellHybrid/config.h => products/BellHybrid/config/ProductConfig.in.hpp +1 -1
@@ 3,4 3,4 @@
#pragma once
-#define ENABLE_GSM (0)
+#cmakedefine01 CONFIG_ENABLE_TEMP
M products/BellHybrid/services/appmgr/include/appmgr/IdleHandler.hpp => products/BellHybrid/services/appmgr/include/appmgr/IdleHandler.hpp +1 -1
@@ 11,7 11,7 @@
namespace app::manager
{
- constexpr auto idleReturnTimeout = std::chrono::minutes{3};
+ constexpr auto idleReturnTimeout = std::chrono::seconds{10};
using connectFunction = std::function<bool(const std::type_info &, sys::MessageHandler)>;
class IdleHandler
M products/BellHybrid/services/evtmgr/EventManager.cpp => products/BellHybrid/services/evtmgr/EventManager.cpp +4 -3
@@ 36,8 36,9 @@ namespace
};
}
-EventManager::EventManager(const std::string &name)
- : EventManagerCommon(name), temperatureSource{hal::temperature::AbstractTemperatureSource::Factory::create()},
+EventManager::EventManager(LogDumpFunction logDumpFunction, const std::string &name)
+ : EventManagerCommon(logDumpFunction, name),
+ temperatureSource{hal::temperature::AbstractTemperatureSource::Factory::create()},
backlightHandler(settings, this), userActivityHandler(std::make_shared<sys::CpuSentinel>(name, this), this)
{
buildKeySequences();
@@ 73,7 74,7 @@ void EventManager::initProductEvents()
backlightHandler.init();
connect(typeid(sevm::ScreenLightControlMessage), [&](sys::Message *msgl) {
- auto *m = static_cast<sevm::ScreenLightControlMessage *>(msgl);
+ auto *m = static_cast<sevm::ScreenLightControlMessage *>(msgl);
const auto params = m->getParams();
backlightHandler.processScreenRequest(m->getAction(), params.value_or(screen_light_control::Parameters()));
return sys::msgHandled();
M products/BellHybrid/services/evtmgr/include/evtmgr/EventManager.hpp => products/BellHybrid/services/evtmgr/include/evtmgr/EventManager.hpp +2 -1
@@ 18,7 18,8 @@ namespace hal::temperature
class EventManager : public EventManagerCommon
{
public:
- explicit EventManager(const std::string &name = service::name::evt_manager);
+ explicit EventManager(LogDumpFunction logDumpFunction = nullptr,
+ const std::string &name = service::name::evt_manager);
private:
void handleKeyEvent(sys::Message *msg) override;
M products/BellHybrid/services/time/AlarmOperations.cpp => products/BellHybrid/services/time/AlarmOperations.cpp +18 -5
@@ 9,6 9,8 @@
#include <db/SystemSettings.hpp>
#include <time/dateCommon.hpp>
+#include <string>
+
namespace alarms
{
namespace
@@ 55,19 57,30 @@ namespace alarms
{
public:
explicit BedtimeSettingsProviderImpl(sys::Service *service)
- : bedtimeModel{std::make_unique<app::bell_bedtime::BedtimeModel>(service)}
- {}
+ : bedtimeTimeModel{std::make_unique<app::bell_bedtime::BedtimeTimeModel>(service)}
+ {
+ settings.init(service::ServiceProxy{service->weak_from_this()});
+ }
auto isBedtimeEnabled() -> bool override
{
- return bedtimeModel.get()->getBedtimeOnOff().getValue();
+ bool enabled = false;
+ try {
+ enabled =
+ std::stoi(settings.getValue(bell::settings::Bedtime::active, settings::SettingsScope::Global));
+ }
+ catch (const std::exception &e) {
+ LOG_ERROR("BedtimeSettingsProviderImpl active db record not valid! err: %s", e.what());
+ }
+ return enabled;
}
auto getBedtimeTime() -> time_t override
{
- return bedtimeModel.get()->getBedtimeTime().getValue();
+ return bedtimeTimeModel->getValue();
}
private:
- std::unique_ptr<app::bell_bedtime::BedtimeModel> bedtimeModel;
+ std::unique_ptr<app::bell_bedtime::BedtimeTimeModel> bedtimeTimeModel;
+ settings::Settings settings;
};
} // namespace
M products/PurePhone/CMakeLists.txt => products/PurePhone/CMakeLists.txt +1 -0
@@ 63,6 63,7 @@ target_link_libraries(PurePhone
db
evtmgr
log
+ logdump
messagetype
module-apps
module-bsp
M products/PurePhone/PurePhoneMain.cpp => products/PurePhone/PurePhoneMain.cpp +6 -2
@@ 60,12 60,13 @@
#include <Application.hpp>
#include <ApplicationLauncher.hpp>
#include <log/log.hpp>
+#include <logdump/logdump.h>
#include <Logger.hpp>
#include <product/version.hpp>
#include <sys/SystemManager.hpp>
-#include <time/AlarmOperations.hpp>
#include <SystemWatchdog/SystemWatchdog.hpp>
#include <thread.hpp>
+#include <time/AlarmOperations.hpp>
#include <memory>
#include <vector>
@@ 94,7 95,7 @@ int main()
}
std::vector<std::unique_ptr<sys::BaseServiceCreator>> systemServices;
- systemServices.emplace_back(sys::CreatorFor<EventManager>());
+ systemServices.emplace_back(sys::CreatorFor<EventManager>([]() { return dumpLogs(); }));
systemServices.emplace_back(sys::CreatorFor<service::ServiceFileIndexer>());
systemServices.emplace_back(sys::CreatorFor<ServiceDB>());
#if ENABLE_GSM == 0
@@ 189,6 190,9 @@ int main()
[&platform] {
try {
LOG_DEBUG("System deinit");
+ if (dumpLogs() != 1) {
+ LOG_ERROR("Cannot dump logs");
+ }
platform->deinit();
}
catch (const std::runtime_error &e) {
M products/PurePhone/services/evtmgr/include/evtmgr/EventManager.hpp => products/PurePhone/services/evtmgr/include/evtmgr/EventManager.hpp +3 -2
@@ 12,8 12,9 @@
class EventManager : public EventManagerCommon
{
public:
- explicit EventManager(const std::string &name = service::name::evt_manager)
- : EventManagerCommon(name), vibrator(std::make_unique<vibra_handle::Vibra>(this)),
+ explicit EventManager(LogDumpFunction logDumpFunction = nullptr,
+ const std::string &name = service::name::evt_manager)
+ : EventManagerCommon(logDumpFunction, name), vibrator(std::make_unique<vibra_handle::Vibra>(this)),
backlightHandler(settings, this)
{}
M products/PurePhone/test/test-settings/test-service-db-settings-api.cpp => products/PurePhone/test/test-settings/test-service-db-settings-api.cpp +1 -2
@@ 57,8 57,7 @@ TEST_CASE("SettingsApi")
testStart = std::make_shared<std::mutex>();
testStart->lock();
std::cout << "start thr_id: " << std::this_thread::get_id() << std::endl << std::flush;
- auto ret = sys::SystemManagerCommon::RunSystemService(
- std::make_shared<EventManager>(service::name::evt_manager), manager.get());
+ auto ret = sys::SystemManagerCommon::RunSystemService(std::make_shared<EventManager>(), manager.get());
ret &= sys::SystemManagerCommon::RunSystemService(std::make_shared<ServiceDB>(), manager.get());
varWritter = std::make_shared<settings::MyService>("writterVar");
M third-party/CrashDebug/CrashCatcher/CrashCatcherPriv.h => third-party/CrashDebug/CrashCatcher/CrashCatcherPriv.h +84 -84
@@ 1,84 1,84 @@
-/* Copyright (C) 2017 Adam Green (https://github.com/adamgreen)
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-/* Private header file shared with unit tests. */
-#ifndef _CRASH_CATCHER_PRIV_H_
-#define _CRASH_CATCHER_PRIV_H_
-
-
-/* Definitions used by assembly language and C code. */
-#define CRASH_CATCHER_STACK_WORD_COUNT 125
-
-/* Does this device support THUMB instructions for FPU access? */
-#ifdef __ARM_ARCH_7EM__
-#define CRASH_CATCHER_WITH_FPU 1
-#else
-#define CRASH_CATCHER_WITH_FPU 0
-#endif
-
-
-/* Definitions only required from C code. */
-#if !defined(__ASSEMBLER__) || (!__ASSEMBLER__)
-
-#include <stdint.h>
-
-
-/* Bit in LR to indicate whether PSP was used for automatic stacking of registers during exception entry. */
-#define LR_PSP (1 << 2)
-
-/* Bit in LR set to 0 when automatic stacking of floating point registers occurs during exception handling. */
-#define LR_FLOAT (1 << 4)
-
-
-/* Bit in auto stacked xPSR which indicates whether stack was force 8-byte aligned. */
-#define PSR_STACK_ALIGN (1 << 9)
-
-/* This structure is filled in by the Hard Fault exception handler (or unit test) and then passed in as a parameter to
- CrashCatcher_Entry(). */
-typedef struct
-{
- uint32_t msp;
- uint32_t psp;
- uint32_t exceptionPSR;
- uint32_t r4;
- uint32_t r5;
- uint32_t r6;
- uint32_t r7;
- uint32_t r8;
- uint32_t r9;
- uint32_t r10;
- uint32_t r11;
- uint32_t exceptionLR;
-} CrashCatcherExceptionRegisters;
-
-/* This is the area of memory that would normally be used for the stack when running on an actual Cortex-M
- processor. Unit tests can write to this buffer to simulate stack overflow. */
-extern uint32_t g_crashCatcherStack[CRASH_CATCHER_STACK_WORD_COUNT];
-
-
-/* The main entry point into CrashCatcher. Is called from the HardFault exception handler and unit tests. */
-void CrashCatcher_Entry(const CrashCatcherExceptionRegisters* pExceptionRegisters);
-
-/* Called from CrashCatcher core to copy all floating point registers to supplied buffer. The supplied buffer must be
- large enough to contain 33 32-bit values (S0-S31 & FPCSR). */
-void CrashCatcher_CopyAllFloatingPointRegisters(uint32_t* pBuffer);
-
-/* Called from CrashCatcher core to copy upper 16 floating point registers to supplied buffer. The supplied buffer must be
- large enough to contain 16 32-bit values (S16-S31). */
-void CrashCatcher_CopyUpperFloatingPointRegisters(uint32_t* pBuffer);
-
-#endif // #if !defined(__ASSEMBLER__) || (!__ASSEMBLER__)
-
-
-#endif /* _CRASH_CATCHER_PRIV_H_ */
+/* Copyright (C) 2017 Adam Green (https://github.com/adamgreen)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* Private header file shared with unit tests. */
+#ifndef _CRASH_CATCHER_PRIV_H_
+#define _CRASH_CATCHER_PRIV_H_
+
+
+/* Definitions used by assembly language and C code. */
+#define CRASH_CATCHER_STACK_WORD_COUNT 8192
+
+/* Does this device support THUMB instructions for FPU access? */
+#ifdef __ARM_ARCH_7EM__
+#define CRASH_CATCHER_WITH_FPU 1
+#else
+#define CRASH_CATCHER_WITH_FPU 0
+#endif
+
+
+/* Definitions only required from C code. */
+#if !defined(__ASSEMBLER__) || (!__ASSEMBLER__)
+
+#include <stdint.h>
+
+
+/* Bit in LR to indicate whether PSP was used for automatic stacking of registers during exception entry. */
+#define LR_PSP (1 << 2)
+
+/* Bit in LR set to 0 when automatic stacking of floating point registers occurs during exception handling. */
+#define LR_FLOAT (1 << 4)
+
+
+/* Bit in auto stacked xPSR which indicates whether stack was force 8-byte aligned. */
+#define PSR_STACK_ALIGN (1 << 9)
+
+/* This structure is filled in by the Hard Fault exception handler (or unit test) and then passed in as a parameter to
+ CrashCatcher_Entry(). */
+typedef struct
+{
+ uint32_t msp;
+ uint32_t psp;
+ uint32_t exceptionPSR;
+ uint32_t r4;
+ uint32_t r5;
+ uint32_t r6;
+ uint32_t r7;
+ uint32_t r8;
+ uint32_t r9;
+ uint32_t r10;
+ uint32_t r11;
+ uint32_t exceptionLR;
+} CrashCatcherExceptionRegisters;
+
+/* This is the area of memory that would normally be used for the stack when running on an actual Cortex-M
+ processor. Unit tests can write to this buffer to simulate stack overflow. */
+extern uint32_t g_crashCatcherStack[CRASH_CATCHER_STACK_WORD_COUNT];
+
+
+/* The main entry point into CrashCatcher. Is called from the HardFault exception handler and unit tests. */
+void CrashCatcher_Entry(const CrashCatcherExceptionRegisters* pExceptionRegisters);
+
+/* Called from CrashCatcher core to copy all floating point registers to supplied buffer. The supplied buffer must be
+ large enough to contain 33 32-bit values (S0-S31 & FPCSR). */
+void CrashCatcher_CopyAllFloatingPointRegisters(uint32_t* pBuffer);
+
+/* Called from CrashCatcher core to copy upper 16 floating point registers to supplied buffer. The supplied buffer must be
+ large enough to contain 16 32-bit values (S16-S31). */
+void CrashCatcher_CopyUpperFloatingPointRegisters(uint32_t* pBuffer);
+
+#endif // #if !defined(__ASSEMBLER__) || (!__ASSEMBLER__)
+
+
+#endif /* _CRASH_CATCHER_PRIV_H_ */
M third-party/CrashDebug/CrashCatcher/CrashCatcher_armv7m.S => third-party/CrashDebug/CrashCatcher/CrashCatcher_armv7m.S +47 -2
@@ 42,7 42,7 @@ HardFault_Handler:
r11
exceptionLR */
// Prevent double fault
- ldr r0, = crash_orig_stack
+ ldr r0, =crash_orig_stack
ldr r0, [r0]
cmp r0, #0
bne .
@@ 53,7 53,6 @@ HardFault_Handler:
mrs r1, msp
ldr sp, =(g_crashCatcherStack + 4 * CRASH_CATCHER_STACK_WORD_COUNT)
push.w {r1-r11,lr}
-
// Call original console dump
ldr r0,=crash_orig_stack
str sp, [r0]
@@ 127,6 126,52 @@ CrashCatcher_CopyUpperFloatingPointRegisters:
.size CrashCatcher_CopyUpperFloatingPointRegisters, .-CrashCatcher_CopyUpperFloatingPointRegisters
+ /*
+ This function is called by the SVC #1 syscall
+ and then collect stack data for the crash dump
+ which will be run in the second stage
+ It also changes stack to the static internal
+ due to possibility of corruption of the oryginal
+ stack frame
+ extern "C" void _StackTrace_Dump_svc_1(void);
+ */
+ .global _StackTrace_Dump_svc_1
+ .type _StackTrace_Dump_svc_1 , %function
+ .thumb_func
+_StackTrace_Dump_svc_1:
+ mrs r3, xpsr
+ mrs r2, psp
+ mrs r1, msp
+ ldr sp, =(g_crashCatcherStack + 4 * CRASH_CATCHER_STACK_WORD_COUNT)
+ push.w {r1-r11,lr}
+
+ ldr r0, =crash_orig_stack
+ str sp, [r0]
+
+ mov sp, r1
+ bx lr
+ .pool
+ .size _StackTrace_Dump_svc_1, .-_StackTrace_Dump_svc_1
+
+
+ /* This function is the second stage of the crash dump
+ crash orig stack should contain valid stack from
+ the exception and now crash catcher should be able
+ to read stack frame pointer and dump data in the
+ user mode from the second part of the exit function
+ In our model crash newer return to the caller so
+ we can use simply branch without care about unstacking
+ extern "C" void _StackTrace_Dump_stage_2(void);
+ */
+ .global _StackTrace_Dump_stage_2
+ .type _StackTrace_Dump_stage_2 , %function
+ .thumb_func
+_StackTrace_Dump_stage_2:
+ ldr r0, =crash_orig_stack
+ ldr r0, [r0]
+ b CrashCatcher_Entry
+ .pool
+ .size _StackTrace_Dump_stage_2, .-_StackTrace_Dump_stage_2
.data
crash_orig_stack: .long 0