From f9613d28c06f96fbc93ccbc59a8f749bbc5f7fa5 Mon Sep 17 00:00:00 2001 From: Reinhold Gschweicher Date: Sat, 30 Oct 2021 22:51:49 +0200 Subject: MotionService: fix not needed '/' in include --- src/components/ble/MotionService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/components/ble') diff --git a/src/components/ble/MotionService.cpp b/src/components/ble/MotionService.cpp index b4786ab5..50693057 100644 --- a/src/components/ble/MotionService.cpp +++ b/src/components/ble/MotionService.cpp @@ -1,5 +1,5 @@ #include "MotionService.h" -#include "components/motion//MotionController.h" +#include "components/motion/MotionController.h" #include "systemtask/SystemTask.h" using namespace Pinetime::Controllers; -- cgit v1.2.3-70-g09d2 From a631fa351858f722f8c4ba7992901722acf3f0c9 Mon Sep 17 00:00:00 2001 From: mabuch Date: Mon, 15 Nov 2021 20:41:32 +0100 Subject: fix Motion Service UUID in doc and code comments --- doc/MotionService.md | 6 +++--- src/components/ble/MotionService.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/components/ble') diff --git a/doc/MotionService.md b/doc/MotionService.md index 0d0a5514..7cec3fba 100644 --- a/doc/MotionService.md +++ b/doc/MotionService.md @@ -3,13 +3,13 @@ The motion service exposes step count and raw X/Y/Z motion value as READ and NOTIFY characteristics. ## Service -The service UUID is **00020000-78fc-48fe-8e23-433b3a1942d0** +The service UUID is **00030000-78fc-48fe-8e23-433b3a1942d0** ## Characteristics -### Step count (UUID 00020001-78fc-48fe-8e23-433b3a1942d0) +### Step count (UUID 00030001-78fc-48fe-8e23-433b3a1942d0) The current number of steps represented as a single `uint32_t` (4 bytes) value. -### Raw motion values (UUID 00020002-78fc-48fe-8e23-433b3a1942d0) +### Raw motion values (UUID 00030002-78fc-48fe-8e23-433b3a1942d0) The current raw motion values. This is a 3 `int16_t` array: - [0] : X diff --git a/src/components/ble/MotionService.cpp b/src/components/ble/MotionService.cpp index b4786ab5..284c60dc 100644 --- a/src/components/ble/MotionService.cpp +++ b/src/components/ble/MotionService.cpp @@ -5,7 +5,7 @@ using namespace Pinetime::Controllers; namespace { - // 0002yyxx-78fc-48fe-8e23-433b3a1942d0 + // 0003yyxx-78fc-48fe-8e23-433b3a1942d0 constexpr ble_uuid128_t CharUuid(uint8_t x, uint8_t y) { return ble_uuid128_t{ .u = {.type = BLE_UUID_TYPE_128}, @@ -13,7 +13,7 @@ namespace { }; } - // 00020000-78fc-48fe-8e23-433b3a1942d0 + // 00030000-78fc-48fe-8e23-433b3a1942d0 constexpr ble_uuid128_t BaseUuid() { return CharUuid(0x00, 0x00); } -- cgit v1.2.3-70-g09d2 From ac7b2da611fa5ef4cc989a9feb027f66c0ebfc6c Mon Sep 17 00:00:00 2001 From: Reinhold Gschweicher Date: Wed, 13 Oct 2021 22:08:35 +0200 Subject: Update includes to to be relative to src directory Don't use relative imports like `../foo.h` as those depend on the relative position of both files. Rather than that use imports relative to the `src` directory, which explicitly is part of the include directories. --- src/components/alarm/AlarmController.cpp | 2 +- src/components/battery/BatteryController.cpp | 2 +- src/components/ble/AlertNotificationClient.cpp | 4 ++-- src/components/ble/AlertNotificationClient.h | 2 +- src/components/ble/AlertNotificationService.cpp | 4 ++-- src/components/ble/BatteryInformationService.cpp | 2 +- src/components/ble/BleController.cpp | 2 +- src/components/ble/CurrentTimeClient.cpp | 2 +- src/components/ble/CurrentTimeClient.h | 2 +- src/components/ble/CurrentTimeService.cpp | 2 +- src/components/ble/DeviceInformationService.cpp | 2 +- src/components/ble/DfuService.cpp | 2 +- src/components/ble/HeartRateService.cpp | 2 +- src/components/ble/ImmediateAlertService.cpp | 4 ++-- src/components/ble/MotionService.cpp | 2 +- src/components/ble/MusicService.cpp | 2 +- src/components/ble/NavigationService.cpp | 2 +- src/components/ble/NimbleController.cpp | 2 +- src/components/ble/NimbleController.h | 26 +++++++++++----------- src/components/ble/NotificationManager.cpp | 2 +- src/components/ble/ServiceDiscovery.cpp | 4 ++-- src/components/brightness/BrightnessController.cpp | 2 +- src/components/datetime/DateTimeController.cpp | 2 +- .../firmwarevalidator/FirmwareValidator.cpp | 2 +- src/components/fs/FS.cpp | 2 +- src/components/gfx/Gfx.cpp | 2 +- src/components/heartrate/Biquad.cpp | 2 +- src/components/heartrate/HeartRateController.cpp | 2 +- src/components/heartrate/Ppg.cpp | 2 +- src/components/heartrate/Ppg.h | 4 ++-- src/components/heartrate/Ptagc.cpp | 2 +- src/components/motion/MotionController.cpp | 2 +- src/components/motor/MotorController.cpp | 2 +- src/components/rle/RleDecoder.cpp | 2 +- src/components/settings/Settings.cpp | 2 +- src/components/timer/TimerController.cpp | 2 +- src/displayapp/Colors.cpp | 2 +- src/displayapp/Colors.h | 2 +- src/displayapp/DisplayApp.cpp | 10 ++++----- src/displayapp/DisplayApp.h | 8 +++---- src/displayapp/DisplayAppRecovery.cpp | 6 ++--- src/displayapp/DisplayAppRecovery.h | 8 +++---- src/displayapp/LittleVgl.cpp | 4 ++-- src/displayapp/lv_pinetime_theme.c | 2 +- src/displayapp/screens/Alarm.cpp | 6 ++--- src/displayapp/screens/Alarm.h | 4 ++-- src/displayapp/screens/ApplicationList.cpp | 8 +++---- src/displayapp/screens/ApplicationList.h | 4 ++-- src/displayapp/screens/BatteryIcon.cpp | 4 ++-- src/displayapp/screens/BatteryInfo.cpp | 4 ++-- src/displayapp/screens/BatteryInfo.h | 2 +- src/displayapp/screens/BleIcon.cpp | 4 ++-- src/displayapp/screens/Brightness.cpp | 2 +- src/displayapp/screens/Brightness.h | 2 +- src/displayapp/screens/Clock.cpp | 10 ++++----- src/displayapp/screens/Clock.h | 2 +- src/displayapp/screens/DropDownDemo.cpp | 4 ++-- src/displayapp/screens/DropDownDemo.h | 2 +- src/displayapp/screens/Error.cpp | 2 +- src/displayapp/screens/Error.h | 2 +- src/displayapp/screens/FirmwareUpdate.cpp | 4 ++-- src/displayapp/screens/FirmwareUpdate.h | 2 +- src/displayapp/screens/FirmwareValidation.cpp | 4 ++-- src/displayapp/screens/FirmwareValidation.h | 2 +- src/displayapp/screens/FlashLight.cpp | 6 ++--- src/displayapp/screens/FlashLight.h | 2 +- src/displayapp/screens/HeartRate.cpp | 6 ++--- src/displayapp/screens/HeartRate.h | 2 +- src/displayapp/screens/InfiniPaint.cpp | 6 ++--- src/displayapp/screens/InfiniPaint.h | 2 +- src/displayapp/screens/Label.cpp | 2 +- src/displayapp/screens/Label.h | 2 +- src/displayapp/screens/List.cpp | 6 ++--- src/displayapp/screens/List.h | 4 ++-- src/displayapp/screens/Meter.cpp | 4 ++-- src/displayapp/screens/Meter.h | 2 +- src/displayapp/screens/Metronome.cpp | 4 ++-- src/displayapp/screens/Motion.cpp | 4 ++-- src/displayapp/screens/Motion.h | 2 +- src/displayapp/screens/Music.cpp | 6 ++--- src/displayapp/screens/Music.h | 2 +- src/displayapp/screens/Navigation.cpp | 4 ++-- src/displayapp/screens/Navigation.h | 2 +- src/displayapp/screens/NotificationIcon.cpp | 4 ++-- src/displayapp/screens/Notifications.cpp | 6 ++--- src/displayapp/screens/Notifications.h | 2 +- src/displayapp/screens/Paddle.cpp | 6 ++--- src/displayapp/screens/Paddle.h | 2 +- src/displayapp/screens/PineTimeStyle.cpp | 12 +++++----- src/displayapp/screens/PineTimeStyle.h | 4 ++-- src/displayapp/screens/Screen.cpp | 2 +- src/displayapp/screens/Screen.h | 2 +- src/displayapp/screens/ScreenList.h | 4 ++-- src/displayapp/screens/Steps.cpp | 6 ++--- src/displayapp/screens/Steps.h | 2 +- src/displayapp/screens/StopWatch.cpp | 6 ++--- src/displayapp/screens/StopWatch.h | 4 ++-- src/displayapp/screens/SystemInfo.cpp | 6 ++--- src/displayapp/screens/SystemInfo.h | 4 ++-- src/displayapp/screens/Tile.cpp | 6 ++--- src/displayapp/screens/Tile.h | 4 ++-- src/displayapp/screens/Timer.cpp | 8 +++---- src/displayapp/screens/Timer.h | 4 ++-- src/displayapp/screens/Twos.cpp | 2 +- src/displayapp/screens/Twos.h | 2 +- src/displayapp/screens/WatchFaceAnalog.cpp | 10 ++++----- src/displayapp/screens/WatchFaceAnalog.h | 4 ++-- src/displayapp/screens/WatchFaceDigital.cpp | 10 ++++----- src/displayapp/screens/WatchFaceDigital.h | 4 ++-- src/displayapp/screens/settings/QuickSettings.cpp | 2 +- src/displayapp/screens/settings/SettingDisplay.cpp | 2 +- .../screens/settings/SettingPineTimeStyle.cpp | 2 +- src/displayapp/screens/settings/SettingSetDate.cpp | 2 +- src/displayapp/screens/settings/SettingSetTime.cpp | 2 +- src/displayapp/screens/settings/SettingSteps.cpp | 2 +- .../screens/settings/SettingTimeFormat.cpp | 2 +- src/displayapp/screens/settings/SettingWakeUp.cpp | 2 +- .../screens/settings/SettingWatchFace.cpp | 2 +- src/displayapp/screens/settings/Settings.cpp | 2 +- src/drivers/Bma421.cpp | 4 ++-- src/drivers/Cst816s.cpp | 2 +- src/drivers/Cst816s.h | 2 +- src/drivers/DebugPins.cpp | 2 +- src/drivers/Hrs3300.cpp | 2 +- src/drivers/Hrs3300.h | 2 +- src/drivers/InternalFlash.cpp | 2 +- src/drivers/Spi.cpp | 2 +- src/drivers/Spi.h | 2 +- src/drivers/SpiMaster.cpp | 2 +- src/drivers/SpiNorFlash.cpp | 4 ++-- src/drivers/St7789.cpp | 4 ++-- src/drivers/TwiMaster.cpp | 2 +- src/drivers/Watchdog.cpp | 2 +- src/heartratetask/HeartRateTask.cpp | 2 +- src/logging/DummyLogger.h | 2 +- src/logging/NrfLogger.cpp | 2 +- src/logging/NrfLogger.h | 2 +- src/systemtask/SystemTask.cpp | 2 +- src/systemtask/SystemTask.h | 4 ++-- src/touchhandler/TouchHandler.cpp | 2 +- 140 files changed, 243 insertions(+), 243 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/alarm/AlarmController.cpp b/src/components/alarm/AlarmController.cpp index 67ca05a9..28b328d5 100644 --- a/src/components/alarm/AlarmController.cpp +++ b/src/components/alarm/AlarmController.cpp @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "AlarmController.h" +#include "components/alarm/AlarmController.h" #include "systemtask/SystemTask.h" #include "app_timer.h" #include "task.h" diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index e807f033..c875cb8d 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -1,4 +1,4 @@ -#include "BatteryController.h" +#include "components/battery/BatteryController.h" #include "drivers/PinMap.h" #include #include diff --git a/src/components/ble/AlertNotificationClient.cpp b/src/components/ble/AlertNotificationClient.cpp index 5e5c25cf..0f850874 100644 --- a/src/components/ble/AlertNotificationClient.cpp +++ b/src/components/ble/AlertNotificationClient.cpp @@ -1,6 +1,6 @@ -#include "AlertNotificationClient.h" +#include "components/ble/AlertNotificationClient.h" #include -#include "NotificationManager.h" +#include "components/ble/NotificationManager.h" #include "systemtask/SystemTask.h" using namespace Pinetime::Controllers; diff --git a/src/components/ble/AlertNotificationClient.h b/src/components/ble/AlertNotificationClient.h index dfba8143..2d6a3873 100644 --- a/src/components/ble/AlertNotificationClient.h +++ b/src/components/ble/AlertNotificationClient.h @@ -7,7 +7,7 @@ #include #undef max #undef min -#include "BleClient.h" +#include "components/ble/BleClient.h" namespace Pinetime { diff --git a/src/components/ble/AlertNotificationService.cpp b/src/components/ble/AlertNotificationService.cpp index 56fc595f..f616cce8 100644 --- a/src/components/ble/AlertNotificationService.cpp +++ b/src/components/ble/AlertNotificationService.cpp @@ -1,8 +1,8 @@ -#include "AlertNotificationService.h" +#include "components/ble/AlertNotificationService.h" #include #include #include -#include "NotificationManager.h" +#include "components/ble/NotificationManager.h" #include "systemtask/SystemTask.h" using namespace Pinetime::Controllers; diff --git a/src/components/ble/BatteryInformationService.cpp b/src/components/ble/BatteryInformationService.cpp index 29178667..b95a88d9 100644 --- a/src/components/ble/BatteryInformationService.cpp +++ b/src/components/ble/BatteryInformationService.cpp @@ -1,5 +1,5 @@ #include -#include "BatteryInformationService.h" +#include "components/ble/BatteryInformationService.h" #include "components/battery/BatteryController.h" using namespace Pinetime::Controllers; diff --git a/src/components/ble/BleController.cpp b/src/components/ble/BleController.cpp index 7c14aeb7..a80c9719 100644 --- a/src/components/ble/BleController.cpp +++ b/src/components/ble/BleController.cpp @@ -1,4 +1,4 @@ -#include "BleController.h" +#include "components/ble/BleController.h" using namespace Pinetime::Controllers; diff --git a/src/components/ble/CurrentTimeClient.cpp b/src/components/ble/CurrentTimeClient.cpp index 90d1f0c7..dd8171b9 100644 --- a/src/components/ble/CurrentTimeClient.cpp +++ b/src/components/ble/CurrentTimeClient.cpp @@ -1,4 +1,4 @@ -#include "CurrentTimeClient.h" +#include "components/ble/CurrentTimeClient.h" #include #include #include "components/datetime/DateTimeController.h" diff --git a/src/components/ble/CurrentTimeClient.h b/src/components/ble/CurrentTimeClient.h index 6424c035..9e48be79 100644 --- a/src/components/ble/CurrentTimeClient.h +++ b/src/components/ble/CurrentTimeClient.h @@ -5,7 +5,7 @@ #undef max #undef min #include -#include "BleClient.h" +#include "components/ble/BleClient.h" namespace Pinetime { namespace Controllers { diff --git a/src/components/ble/CurrentTimeService.cpp b/src/components/ble/CurrentTimeService.cpp index eefb7ec1..e509aeaf 100644 --- a/src/components/ble/CurrentTimeService.cpp +++ b/src/components/ble/CurrentTimeService.cpp @@ -1,4 +1,4 @@ -#include "CurrentTimeService.h" +#include "components/ble/CurrentTimeService.h" #include #include diff --git a/src/components/ble/DeviceInformationService.cpp b/src/components/ble/DeviceInformationService.cpp index 778d6e35..0f47c90f 100644 --- a/src/components/ble/DeviceInformationService.cpp +++ b/src/components/ble/DeviceInformationService.cpp @@ -1,4 +1,4 @@ -#include "DeviceInformationService.h" +#include "components/ble/DeviceInformationService.h" using namespace Pinetime::Controllers; diff --git a/src/components/ble/DfuService.cpp b/src/components/ble/DfuService.cpp index 3d6416fa..71dcc7e6 100644 --- a/src/components/ble/DfuService.cpp +++ b/src/components/ble/DfuService.cpp @@ -1,4 +1,4 @@ -#include "DfuService.h" +#include "components/ble/DfuService.h" #include #include "components/ble/BleController.h" #include "drivers/SpiNorFlash.h" diff --git a/src/components/ble/HeartRateService.cpp b/src/components/ble/HeartRateService.cpp index 75a038a2..f178af79 100644 --- a/src/components/ble/HeartRateService.cpp +++ b/src/components/ble/HeartRateService.cpp @@ -1,4 +1,4 @@ -#include "HeartRateService.h" +#include "components/ble/HeartRateService.h" #include "components/heartrate/HeartRateController.h" #include "systemtask/SystemTask.h" diff --git a/src/components/ble/ImmediateAlertService.cpp b/src/components/ble/ImmediateAlertService.cpp index 17ed1a96..c80b3783 100644 --- a/src/components/ble/ImmediateAlertService.cpp +++ b/src/components/ble/ImmediateAlertService.cpp @@ -1,6 +1,6 @@ -#include "ImmediateAlertService.h" +#include "components/ble/ImmediateAlertService.h" #include -#include "NotificationManager.h" +#include "components/ble/NotificationManager.h" #include "systemtask/SystemTask.h" using namespace Pinetime::Controllers; diff --git a/src/components/ble/MotionService.cpp b/src/components/ble/MotionService.cpp index b4786ab5..0146ae86 100644 --- a/src/components/ble/MotionService.cpp +++ b/src/components/ble/MotionService.cpp @@ -1,4 +1,4 @@ -#include "MotionService.h" +#include "components/ble/MotionService.h" #include "components/motion//MotionController.h" #include "systemtask/SystemTask.h" diff --git a/src/components/ble/MusicService.cpp b/src/components/ble/MusicService.cpp index 74fe9522..3457ce4c 100644 --- a/src/components/ble/MusicService.cpp +++ b/src/components/ble/MusicService.cpp @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "MusicService.h" +#include "components/ble/MusicService.h" #include "systemtask/SystemTask.h" namespace { diff --git a/src/components/ble/NavigationService.cpp b/src/components/ble/NavigationService.cpp index b49148d2..5418b9e5 100644 --- a/src/components/ble/NavigationService.cpp +++ b/src/components/ble/NavigationService.cpp @@ -16,7 +16,7 @@ along with this program. If not, see . */ -#include "NavigationService.h" +#include "components/ble/NavigationService.h" #include "systemtask/SystemTask.h" diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 1bcae1bc..43a8b0d6 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -1,4 +1,4 @@ -#include "NimbleController.h" +#include "components/ble/NimbleController.h" #include #define min // workaround: nimble's min/max macros conflict with libstdc++ #define max diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 76f89ba8..895b87f2 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -7,19 +7,19 @@ #include #undef max #undef min -#include "AlertNotificationClient.h" -#include "AlertNotificationService.h" -#include "BatteryInformationService.h" -#include "CurrentTimeClient.h" -#include "CurrentTimeService.h" -#include "DeviceInformationService.h" -#include "DfuService.h" -#include "ImmediateAlertService.h" -#include "MusicService.h" -#include "NavigationService.h" -#include "ServiceDiscovery.h" -#include "HeartRateService.h" -#include "MotionService.h" +#include "components/ble/AlertNotificationClient.h" +#include "components/ble/AlertNotificationService.h" +#include "components/ble/BatteryInformationService.h" +#include "components/ble/CurrentTimeClient.h" +#include "components/ble/CurrentTimeService.h" +#include "components/ble/DeviceInformationService.h" +#include "components/ble/DfuService.h" +#include "components/ble/ImmediateAlertService.h" +#include "components/ble/MusicService.h" +#include "components/ble/NavigationService.h" +#include "components/ble/ServiceDiscovery.h" +#include "components/ble/HeartRateService.h" +#include "components/ble/MotionService.h" namespace Pinetime { namespace Drivers { diff --git a/src/components/ble/NotificationManager.cpp b/src/components/ble/NotificationManager.cpp index 7ffed300..ec99c4ed 100644 --- a/src/components/ble/NotificationManager.cpp +++ b/src/components/ble/NotificationManager.cpp @@ -1,4 +1,4 @@ -#include "NotificationManager.h" +#include "components/ble/NotificationManager.h" #include #include diff --git a/src/components/ble/ServiceDiscovery.cpp b/src/components/ble/ServiceDiscovery.cpp index b36b241c..03bcfeb4 100644 --- a/src/components/ble/ServiceDiscovery.cpp +++ b/src/components/ble/ServiceDiscovery.cpp @@ -1,6 +1,6 @@ -#include "ServiceDiscovery.h" +#include "components/ble/ServiceDiscovery.h" #include -#include "BleClient.h" +#include "components/ble/BleClient.h" using namespace Pinetime::Controllers; diff --git a/src/components/brightness/BrightnessController.cpp b/src/components/brightness/BrightnessController.cpp index 6c524679..2d9f980a 100644 --- a/src/components/brightness/BrightnessController.cpp +++ b/src/components/brightness/BrightnessController.cpp @@ -1,4 +1,4 @@ -#include "BrightnessController.h" +#include "components/brightness/BrightnessController.h" #include #include "displayapp/screens/Symbols.h" #include "drivers/PinMap.h" diff --git a/src/components/datetime/DateTimeController.cpp b/src/components/datetime/DateTimeController.cpp index e9c5d870..4ac9e1f1 100644 --- a/src/components/datetime/DateTimeController.cpp +++ b/src/components/datetime/DateTimeController.cpp @@ -1,4 +1,4 @@ -#include "DateTimeController.h" +#include "components/datetime/DateTimeController.h" #include #include #include diff --git a/src/components/firmwarevalidator/FirmwareValidator.cpp b/src/components/firmwarevalidator/FirmwareValidator.cpp index 68e66d37..5a63b6b4 100644 --- a/src/components/firmwarevalidator/FirmwareValidator.cpp +++ b/src/components/firmwarevalidator/FirmwareValidator.cpp @@ -1,4 +1,4 @@ -#include "FirmwareValidator.h" +#include "components/firmwarevalidator/FirmwareValidator.h" #include #include "drivers/InternalFlash.h" diff --git a/src/components/fs/FS.cpp b/src/components/fs/FS.cpp index 857e6bf9..1cad4f02 100644 --- a/src/components/fs/FS.cpp +++ b/src/components/fs/FS.cpp @@ -1,4 +1,4 @@ -#include "FS.h" +#include "components/fs/FS.h" #include #include #include diff --git a/src/components/gfx/Gfx.cpp b/src/components/gfx/Gfx.cpp index cf271032..3eaaa3fe 100644 --- a/src/components/gfx/Gfx.cpp +++ b/src/components/gfx/Gfx.cpp @@ -1,4 +1,4 @@ -#include "Gfx.h" +#include "components/gfx/Gfx.h" #include "drivers/St7789.h" using namespace Pinetime::Components; diff --git a/src/components/heartrate/Biquad.cpp b/src/components/heartrate/Biquad.cpp index 0341eda6..b7edd403 100644 --- a/src/components/heartrate/Biquad.cpp +++ b/src/components/heartrate/Biquad.cpp @@ -4,7 +4,7 @@ C++ port Copyright (C) 2021 Jean-François Milants */ -#include "Biquad.h" +#include "components/heartrate/Biquad.h" using namespace Pinetime::Controllers; diff --git a/src/components/heartrate/HeartRateController.cpp b/src/components/heartrate/HeartRateController.cpp index 716813b3..e0d69272 100644 --- a/src/components/heartrate/HeartRateController.cpp +++ b/src/components/heartrate/HeartRateController.cpp @@ -1,4 +1,4 @@ -#include "HeartRateController.h" +#include "components/heartrate/HeartRateController.h" #include #include diff --git a/src/components/heartrate/Ppg.cpp b/src/components/heartrate/Ppg.cpp index fcba3815..c247d1f6 100644 --- a/src/components/heartrate/Ppg.cpp +++ b/src/components/heartrate/Ppg.cpp @@ -6,7 +6,7 @@ #include #include -#include "Ppg.h" +#include "components/heartrate/Ppg.h" using namespace Pinetime::Controllers; /** Original implementation from wasp-os : https://github.com/daniel-thompson/wasp-os/blob/master/wasp/ppg.py */ diff --git a/src/components/heartrate/Ppg.h b/src/components/heartrate/Ppg.h index 00014162..ed79b082 100644 --- a/src/components/heartrate/Ppg.h +++ b/src/components/heartrate/Ppg.h @@ -1,8 +1,8 @@ #pragma once #include -#include "Biquad.h" -#include "Ptagc.h" +#include "components/heartrate/Biquad.h" +#include "components/heartrate/Ptagc.h" namespace Pinetime { namespace Controllers { diff --git a/src/components/heartrate/Ptagc.cpp b/src/components/heartrate/Ptagc.cpp index e358371e..db496a15 100644 --- a/src/components/heartrate/Ptagc.cpp +++ b/src/components/heartrate/Ptagc.cpp @@ -5,7 +5,7 @@ */ #include -#include "Ptagc.h" +#include "components/heartrate/Ptagc.h" using namespace Pinetime::Controllers; diff --git a/src/components/motion/MotionController.cpp b/src/components/motion/MotionController.cpp index a2384d79..cae49105 100644 --- a/src/components/motion/MotionController.cpp +++ b/src/components/motion/MotionController.cpp @@ -1,4 +1,4 @@ -#include "MotionController.h" +#include "components/motion/MotionController.h" using namespace Pinetime::Controllers; diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index f596c718..c794a02c 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -1,4 +1,4 @@ -#include "MotorController.h" +#include "components/motor/MotorController.h" #include #include "systemtask/SystemTask.h" #include "app_timer.h" diff --git a/src/components/rle/RleDecoder.cpp b/src/components/rle/RleDecoder.cpp index df2bcb6b..19ebfec0 100644 --- a/src/components/rle/RleDecoder.cpp +++ b/src/components/rle/RleDecoder.cpp @@ -1,4 +1,4 @@ -#include "RleDecoder.h" +#include "components/rle/RleDecoder.h" using namespace Pinetime::Tools; diff --git a/src/components/settings/Settings.cpp b/src/components/settings/Settings.cpp index 37c09f91..ef73ad1c 100644 --- a/src/components/settings/Settings.cpp +++ b/src/components/settings/Settings.cpp @@ -1,4 +1,4 @@ -#include "Settings.h" +#include "components/settings/Settings.h" #include #include diff --git a/src/components/timer/TimerController.cpp b/src/components/timer/TimerController.cpp index 8d5f5c33..79e44d6f 100644 --- a/src/components/timer/TimerController.cpp +++ b/src/components/timer/TimerController.cpp @@ -2,7 +2,7 @@ // Created by florian on 16.05.21. // -#include "TimerController.h" +#include "components/timer/TimerController.h" #include "systemtask/SystemTask.h" #include "app_timer.h" #include "task.h" diff --git a/src/displayapp/Colors.cpp b/src/displayapp/Colors.cpp index f45f0722..93b1aa06 100644 --- a/src/displayapp/Colors.cpp +++ b/src/displayapp/Colors.cpp @@ -1,4 +1,4 @@ -#include "Colors.h" +#include "displayapp/Colors.h" using namespace Pinetime::Applications; using namespace Pinetime::Controllers; diff --git a/src/displayapp/Colors.h b/src/displayapp/Colors.h index 9db7dd20..43e2b801 100644 --- a/src/displayapp/Colors.h +++ b/src/displayapp/Colors.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include "components/settings/Settings.h" namespace Pinetime { namespace Applications { diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 13ee0045..f4d0ce45 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -1,9 +1,9 @@ -#include "DisplayApp.h" +#include "displayapp/DisplayApp.h" #include -#include -#include -#include -#include +#include "displayapp/screens/HeartRate.h" +#include "displayapp/screens/Motion.h" +#include "displayapp/screens/Timer.h" +#include "displayapp/screens/Alarm.h" #include "components/battery/BatteryController.h" #include "components/ble/BleController.h" #include "components/datetime/DateTimeController.h" diff --git a/src/displayapp/DisplayApp.h b/src/displayapp/DisplayApp.h index a87cab0b..39fe6314 100644 --- a/src/displayapp/DisplayApp.h +++ b/src/displayapp/DisplayApp.h @@ -5,9 +5,9 @@ #include #include #include -#include "Apps.h" -#include "LittleVgl.h" -#include "TouchEvents.h" +#include "displayapp/Apps.h" +#include "displayapp/LittleVgl.h" +#include "displayapp/TouchEvents.h" #include "components/brightness/BrightnessController.h" #include "components/motor/MotorController.h" #include "components/firmwarevalidator/FirmwareValidator.h" @@ -17,7 +17,7 @@ #include "components/alarm/AlarmController.h" #include "touchhandler/TouchHandler.h" -#include "Messages.h" +#include "displayapp/Messages.h" #include "BootErrors.h" namespace Pinetime { diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp index a42d81a2..fd7017a4 100644 --- a/src/displayapp/DisplayAppRecovery.cpp +++ b/src/displayapp/DisplayAppRecovery.cpp @@ -1,9 +1,9 @@ -#include "DisplayAppRecovery.h" +#include "displayapp/DisplayAppRecovery.h" #include #include #include -#include -#include +#include "components/rle/RleDecoder.h" +#include "touchhandler/TouchHandler.h" #include "displayapp/icons/infinitime/infinitime-nb.c" #include "components/ble/BleController.h" diff --git a/src/displayapp/DisplayAppRecovery.h b/src/displayapp/DisplayAppRecovery.h index 72868159..86e956d1 100644 --- a/src/displayapp/DisplayAppRecovery.h +++ b/src/displayapp/DisplayAppRecovery.h @@ -11,10 +11,10 @@ #include #include #include "BootErrors.h" -#include "TouchEvents.h" -#include "Apps.h" -#include "Messages.h" -#include "DummyLittleVgl.h" +#include "displayapp/TouchEvents.h" +#include "displayapp/Apps.h" +#include "displayapp/Messages.h" +#include "displayapp/DummyLittleVgl.h" namespace Pinetime { namespace Drivers { diff --git a/src/displayapp/LittleVgl.cpp b/src/displayapp/LittleVgl.cpp index 2bd5e57b..e7b58c16 100644 --- a/src/displayapp/LittleVgl.cpp +++ b/src/displayapp/LittleVgl.cpp @@ -1,5 +1,5 @@ -#include "LittleVgl.h" -#include "lv_pinetime_theme.h" +#include "displayapp/LittleVgl.h" +#include "displayapp/lv_pinetime_theme.h" #include #include diff --git a/src/displayapp/lv_pinetime_theme.c b/src/displayapp/lv_pinetime_theme.c index 1b8b1980..1780e64b 100644 --- a/src/displayapp/lv_pinetime_theme.c +++ b/src/displayapp/lv_pinetime_theme.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "lv_pinetime_theme.h" +#include "displayapp/lv_pinetime_theme.h" /********************* * DEFINES diff --git a/src/displayapp/screens/Alarm.cpp b/src/displayapp/screens/Alarm.cpp index 6b45a36e..772e5d45 100644 --- a/src/displayapp/screens/Alarm.cpp +++ b/src/displayapp/screens/Alarm.cpp @@ -15,9 +15,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "Alarm.h" -#include "Screen.h" -#include "Symbols.h" +#include "displayapp/screens/Alarm.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/Symbols.h" using namespace Pinetime::Applications::Screens; using Pinetime::Controllers::AlarmController; diff --git a/src/displayapp/screens/Alarm.h b/src/displayapp/screens/Alarm.h index 487ba1d5..4b301ce1 100644 --- a/src/displayapp/screens/Alarm.h +++ b/src/displayapp/screens/Alarm.h @@ -17,9 +17,9 @@ */ #pragma once -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include "systemtask/SystemTask.h" -#include "../LittleVgl.h" +#include "displayapp/LittleVgl.h" #include "components/alarm/AlarmController.h" namespace Pinetime { diff --git a/src/displayapp/screens/ApplicationList.cpp b/src/displayapp/screens/ApplicationList.cpp index 5c582f60..29c8affb 100644 --- a/src/displayapp/screens/ApplicationList.cpp +++ b/src/displayapp/screens/ApplicationList.cpp @@ -1,10 +1,10 @@ -#include "ApplicationList.h" +#include "displayapp/screens/ApplicationList.h" #include #include -#include "Symbols.h" -#include "Tile.h" +#include "displayapp/screens/Symbols.h" +#include "displayapp/screens/Tile.h" #include "displayapp/Apps.h" -#include "../DisplayApp.h" +#include "displayapp/DisplayApp.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/ApplicationList.h b/src/displayapp/screens/ApplicationList.h index 103c38ae..f430a89e 100644 --- a/src/displayapp/screens/ApplicationList.h +++ b/src/displayapp/screens/ApplicationList.h @@ -2,8 +2,8 @@ #include -#include "Screen.h" -#include "ScreenList.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/ScreenList.h" #include "components/datetime/DateTimeController.h" #include "components/settings/Settings.h" #include "components/battery/BatteryController.h" diff --git a/src/displayapp/screens/BatteryIcon.cpp b/src/displayapp/screens/BatteryIcon.cpp index c67bcb23..114b08fa 100644 --- a/src/displayapp/screens/BatteryIcon.cpp +++ b/src/displayapp/screens/BatteryIcon.cpp @@ -1,6 +1,6 @@ #include -#include "BatteryIcon.h" -#include "Symbols.h" +#include "displayapp/screens/BatteryIcon.h" +#include "displayapp/screens/Symbols.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/BatteryInfo.cpp b/src/displayapp/screens/BatteryInfo.cpp index 44ea7f51..e17de9ab 100644 --- a/src/displayapp/screens/BatteryInfo.cpp +++ b/src/displayapp/screens/BatteryInfo.cpp @@ -1,5 +1,5 @@ -#include "BatteryInfo.h" -#include "../DisplayApp.h" +#include "displayapp/screens/BatteryInfo.h" +#include "displayapp/DisplayApp.h" #include "components/battery/BatteryController.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/BatteryInfo.h b/src/displayapp/screens/BatteryInfo.h index 63454a26..d7600afe 100644 --- a/src/displayapp/screens/BatteryInfo.h +++ b/src/displayapp/screens/BatteryInfo.h @@ -3,7 +3,7 @@ #include #include #include -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include namespace Pinetime { diff --git a/src/displayapp/screens/BleIcon.cpp b/src/displayapp/screens/BleIcon.cpp index da3d15e7..5058f3eb 100644 --- a/src/displayapp/screens/BleIcon.cpp +++ b/src/displayapp/screens/BleIcon.cpp @@ -1,5 +1,5 @@ -#include "BleIcon.h" -#include "Symbols.h" +#include "displayapp/screens/BleIcon.h" +#include "displayapp/screens/Symbols.h" using namespace Pinetime::Applications::Screens; const char* BleIcon::GetIcon(bool isConnected) { diff --git a/src/displayapp/screens/Brightness.cpp b/src/displayapp/screens/Brightness.cpp index 1278cd62..d9901ae8 100644 --- a/src/displayapp/screens/Brightness.cpp +++ b/src/displayapp/screens/Brightness.cpp @@ -1,4 +1,4 @@ -#include "Brightness.h" +#include "displayapp/screens/Brightness.h" #include using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/Brightness.h b/src/displayapp/screens/Brightness.h index 14e48592..693570c7 100644 --- a/src/displayapp/screens/Brightness.h +++ b/src/displayapp/screens/Brightness.h @@ -2,7 +2,7 @@ #include #include -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include "components/brightness/BrightnessController.h" namespace Pinetime { diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp index 5a5cd18b..71f01b93 100644 --- a/src/displayapp/screens/Clock.cpp +++ b/src/displayapp/screens/Clock.cpp @@ -1,4 +1,4 @@ -#include "Clock.h" +#include "displayapp/screens/Clock.h" #include #include @@ -6,10 +6,10 @@ #include "components/motion/MotionController.h" #include "components/ble/BleController.h" #include "components/ble/NotificationManager.h" -#include "../DisplayApp.h" -#include "WatchFaceDigital.h" -#include "WatchFaceAnalog.h" -#include "PineTimeStyle.h" +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/WatchFaceDigital.h" +#include "displayapp/screens/WatchFaceAnalog.h" +#include "displayapp/screens/PineTimeStyle.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/Clock.h b/src/displayapp/screens/Clock.h index 648f72da..2fad1e21 100644 --- a/src/displayapp/screens/Clock.h +++ b/src/displayapp/screens/Clock.h @@ -5,7 +5,7 @@ #include #include #include -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include "components/datetime/DateTimeController.h" namespace Pinetime { diff --git a/src/displayapp/screens/DropDownDemo.cpp b/src/displayapp/screens/DropDownDemo.cpp index 9043c20d..cf239a2f 100644 --- a/src/displayapp/screens/DropDownDemo.cpp +++ b/src/displayapp/screens/DropDownDemo.cpp @@ -1,7 +1,7 @@ -#include "DropDownDemo.h" +#include "displayapp/screens/DropDownDemo.h" #include #include -#include "../DisplayApp.h" +#include "displayapp/DisplayApp.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/DropDownDemo.h b/src/displayapp/screens/DropDownDemo.h index ff388c57..bcf0f45c 100644 --- a/src/displayapp/screens/DropDownDemo.h +++ b/src/displayapp/screens/DropDownDemo.h @@ -1,7 +1,7 @@ #pragma once #include -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include namespace Pinetime { diff --git a/src/displayapp/screens/Error.cpp b/src/displayapp/screens/Error.cpp index 75946aba..1dbc3447 100644 --- a/src/displayapp/screens/Error.cpp +++ b/src/displayapp/screens/Error.cpp @@ -1,4 +1,4 @@ -#include "Error.h" +#include "displayapp/screens/Error.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/Error.h b/src/displayapp/screens/Error.h index 20dde7ee..23167545 100644 --- a/src/displayapp/screens/Error.h +++ b/src/displayapp/screens/Error.h @@ -1,6 +1,6 @@ #pragma once -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include "BootErrors.h" #include diff --git a/src/displayapp/screens/FirmwareUpdate.cpp b/src/displayapp/screens/FirmwareUpdate.cpp index 79bda0ba..373fcae4 100644 --- a/src/displayapp/screens/FirmwareUpdate.cpp +++ b/src/displayapp/screens/FirmwareUpdate.cpp @@ -1,7 +1,7 @@ -#include "FirmwareUpdate.h" +#include "displayapp/screens/FirmwareUpdate.h" #include #include "components/ble/BleController.h" -#include "../DisplayApp.h" +#include "displayapp/DisplayApp.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/FirmwareUpdate.h b/src/displayapp/screens/FirmwareUpdate.h index 8fc86d8c..a61178ce 100644 --- a/src/displayapp/screens/FirmwareUpdate.h +++ b/src/displayapp/screens/FirmwareUpdate.h @@ -1,6 +1,6 @@ #pragma once -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include #include "FreeRTOS.h" diff --git a/src/displayapp/screens/FirmwareValidation.cpp b/src/displayapp/screens/FirmwareValidation.cpp index eef8f919..ea417135 100644 --- a/src/displayapp/screens/FirmwareValidation.cpp +++ b/src/displayapp/screens/FirmwareValidation.cpp @@ -1,8 +1,8 @@ -#include "FirmwareValidation.h" +#include "displayapp/screens/FirmwareValidation.h" #include #include "Version.h" #include "components/firmwarevalidator/FirmwareValidator.h" -#include "../DisplayApp.h" +#include "displayapp/DisplayApp.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/FirmwareValidation.h b/src/displayapp/screens/FirmwareValidation.h index bfdb096d..278c4adf 100644 --- a/src/displayapp/screens/FirmwareValidation.h +++ b/src/displayapp/screens/FirmwareValidation.h @@ -1,6 +1,6 @@ #pragma once -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include namespace Pinetime { diff --git a/src/displayapp/screens/FlashLight.cpp b/src/displayapp/screens/FlashLight.cpp index dcb31a7f..c4d02643 100644 --- a/src/displayapp/screens/FlashLight.cpp +++ b/src/displayapp/screens/FlashLight.cpp @@ -1,6 +1,6 @@ -#include "FlashLight.h" -#include "../DisplayApp.h" -#include "Symbols.h" +#include "displayapp/screens/FlashLight.h" +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Symbols.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/FlashLight.h b/src/displayapp/screens/FlashLight.h index f2c65bbe..e91a1032 100644 --- a/src/displayapp/screens/FlashLight.h +++ b/src/displayapp/screens/FlashLight.h @@ -1,6 +1,6 @@ #pragma once -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include "components/brightness/BrightnessController.h" #include "systemtask/SystemTask.h" #include diff --git a/src/displayapp/screens/HeartRate.cpp b/src/displayapp/screens/HeartRate.cpp index b6ece27f..65d1aa2f 100644 --- a/src/displayapp/screens/HeartRate.cpp +++ b/src/displayapp/screens/HeartRate.cpp @@ -1,8 +1,8 @@ -#include -#include "HeartRate.h" +#include +#include "displayapp/screens/HeartRate.h" #include -#include "../DisplayApp.h" +#include "displayapp/DisplayApp.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/HeartRate.h b/src/displayapp/screens/HeartRate.h index 7f7d3ad3..d06415ca 100644 --- a/src/displayapp/screens/HeartRate.h +++ b/src/displayapp/screens/HeartRate.h @@ -2,7 +2,7 @@ #include #include -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include #include "systemtask/SystemTask.h" #include diff --git a/src/displayapp/screens/InfiniPaint.cpp b/src/displayapp/screens/InfiniPaint.cpp index 85a5e826..00d224e6 100644 --- a/src/displayapp/screens/InfiniPaint.cpp +++ b/src/displayapp/screens/InfiniPaint.cpp @@ -1,6 +1,6 @@ -#include "InfiniPaint.h" -#include "../DisplayApp.h" -#include "../LittleVgl.h" +#include "displayapp/screens/InfiniPaint.h" +#include "displayapp/DisplayApp.h" +#include "displayapp/LittleVgl.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/InfiniPaint.h b/src/displayapp/screens/InfiniPaint.h index 0a70e033..322ce757 100644 --- a/src/displayapp/screens/InfiniPaint.h +++ b/src/displayapp/screens/InfiniPaint.h @@ -2,7 +2,7 @@ #include #include -#include "Screen.h" +#include "displayapp/screens/Screen.h" namespace Pinetime { namespace Components { diff --git a/src/displayapp/screens/Label.cpp b/src/displayapp/screens/Label.cpp index 1761a7b5..62ec1f0a 100644 --- a/src/displayapp/screens/Label.cpp +++ b/src/displayapp/screens/Label.cpp @@ -1,4 +1,4 @@ -#include "Label.h" +#include "displayapp/screens/Label.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/Label.h b/src/displayapp/screens/Label.h index f1e49079..3fe5111f 100644 --- a/src/displayapp/screens/Label.h +++ b/src/displayapp/screens/Label.h @@ -1,6 +1,6 @@ #pragma once -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include namespace Pinetime { diff --git a/src/displayapp/screens/List.cpp b/src/displayapp/screens/List.cpp index 064b47a6..af3f30f6 100644 --- a/src/displayapp/screens/List.cpp +++ b/src/displayapp/screens/List.cpp @@ -1,6 +1,6 @@ -#include "List.h" -#include "../DisplayApp.h" -#include "Symbols.h" +#include "displayapp/screens/List.h" +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Symbols.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/List.h b/src/displayapp/screens/List.h index d9f61f29..023de3aa 100644 --- a/src/displayapp/screens/List.h +++ b/src/displayapp/screens/List.h @@ -3,8 +3,8 @@ #include #include #include -#include "Screen.h" -#include "../Apps.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/Apps.h" #include "components/settings/Settings.h" #define MAXLISTITEMS 4 diff --git a/src/displayapp/screens/Meter.cpp b/src/displayapp/screens/Meter.cpp index 57cde9cf..9c853109 100644 --- a/src/displayapp/screens/Meter.cpp +++ b/src/displayapp/screens/Meter.cpp @@ -1,6 +1,6 @@ -#include "Meter.h" +#include "displayapp/screens/Meter.h" #include -#include "../DisplayApp.h" +#include "displayapp/DisplayApp.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/Meter.h b/src/displayapp/screens/Meter.h index 9b3d1d48..50d9f83c 100644 --- a/src/displayapp/screens/Meter.h +++ b/src/displayapp/screens/Meter.h @@ -1,7 +1,7 @@ #pragma once #include -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include #include diff --git a/src/displayapp/screens/Metronome.cpp b/src/displayapp/screens/Metronome.cpp index 52cb8519..8347e1bb 100644 --- a/src/displayapp/screens/Metronome.cpp +++ b/src/displayapp/screens/Metronome.cpp @@ -1,5 +1,5 @@ -#include "Metronome.h" -#include "Symbols.h" +#include "displayapp/screens/Metronome.h" +#include "displayapp/screens/Symbols.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/Motion.cpp b/src/displayapp/screens/Motion.cpp index 2f1f7c21..3641110e 100644 --- a/src/displayapp/screens/Motion.cpp +++ b/src/displayapp/screens/Motion.cpp @@ -1,6 +1,6 @@ #include -#include "Motion.h" -#include "../DisplayApp.h" +#include "displayapp/screens/Motion.h" +#include "displayapp/DisplayApp.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/Motion.h b/src/displayapp/screens/Motion.h index 20a18d02..f6202b5b 100644 --- a/src/displayapp/screens/Motion.h +++ b/src/displayapp/screens/Motion.h @@ -2,7 +2,7 @@ #include #include -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include #include #include diff --git a/src/displayapp/screens/Music.cpp b/src/displayapp/screens/Music.cpp index 47ddb655..8a01a6fe 100644 --- a/src/displayapp/screens/Music.cpp +++ b/src/displayapp/screens/Music.cpp @@ -15,10 +15,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "Music.h" -#include "Symbols.h" +#include "displayapp/screens/Music.h" +#include "displayapp/screens/Symbols.h" #include -#include "../DisplayApp.h" +#include "displayapp/DisplayApp.h" #include "components/ble/MusicService.h" #include "displayapp/icons/music/disc.cpp" #include "displayapp/icons/music/disc_f_1.cpp" diff --git a/src/displayapp/screens/Music.h b/src/displayapp/screens/Music.h index 6f2d80a0..f9b4eaab 100644 --- a/src/displayapp/screens/Music.h +++ b/src/displayapp/screens/Music.h @@ -20,7 +20,7 @@ #include #include #include -#include "Screen.h" +#include "displayapp/screens/Screen.h" namespace Pinetime { namespace Controllers { diff --git a/src/displayapp/screens/Navigation.cpp b/src/displayapp/screens/Navigation.cpp index d437cc6d..674362a6 100644 --- a/src/displayapp/screens/Navigation.cpp +++ b/src/displayapp/screens/Navigation.cpp @@ -15,9 +15,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "Navigation.h" +#include "displayapp/screens/Navigation.h" #include -#include "../DisplayApp.h" +#include "displayapp/DisplayApp.h" #include "components/ble/NavigationService.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/Navigation.h b/src/displayapp/screens/Navigation.h index 48f00a76..07674ef1 100644 --- a/src/displayapp/screens/Navigation.h +++ b/src/displayapp/screens/Navigation.h @@ -20,7 +20,7 @@ #include #include #include -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include namespace Pinetime { diff --git a/src/displayapp/screens/NotificationIcon.cpp b/src/displayapp/screens/NotificationIcon.cpp index d8792f9d..0e913ae7 100644 --- a/src/displayapp/screens/NotificationIcon.cpp +++ b/src/displayapp/screens/NotificationIcon.cpp @@ -1,5 +1,5 @@ -#include "NotificationIcon.h" -#include "Symbols.h" +#include "displayapp/screens/NotificationIcon.h" +#include "displayapp/screens/Symbols.h" using namespace Pinetime::Applications::Screens; const char* NotificationIcon::GetIcon(bool newNotificationAvailable) { diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index 4f475813..569c422b 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -1,8 +1,8 @@ -#include "Notifications.h" -#include +#include "displayapp/screens/Notifications.h" +#include "displayapp/DisplayApp.h" #include "components/ble/MusicService.h" #include "components/ble/AlertNotificationService.h" -#include "Symbols.h" +#include "displayapp/screens/Symbols.h" using namespace Pinetime::Applications::Screens; extern lv_font_t jetbrains_mono_extrabold_compressed; diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index 0b5271e7..cbb7af6c 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -3,7 +3,7 @@ #include #include #include -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include "components/ble/NotificationManager.h" #include "components/motor/MotorController.h" diff --git a/src/displayapp/screens/Paddle.cpp b/src/displayapp/screens/Paddle.cpp index 26c2368b..aa3420dc 100644 --- a/src/displayapp/screens/Paddle.cpp +++ b/src/displayapp/screens/Paddle.cpp @@ -1,6 +1,6 @@ -#include "Paddle.h" -#include "../DisplayApp.h" -#include "../LittleVgl.h" +#include "displayapp/screens/Paddle.h" +#include "displayapp/DisplayApp.h" +#include "displayapp/LittleVgl.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/Paddle.h b/src/displayapp/screens/Paddle.h index fc2131a1..3a30eee6 100644 --- a/src/displayapp/screens/Paddle.h +++ b/src/displayapp/screens/Paddle.h @@ -2,7 +2,7 @@ #include #include -#include "Screen.h" +#include "displayapp/screens/Screen.h" namespace Pinetime { namespace Components { diff --git a/src/displayapp/screens/PineTimeStyle.cpp b/src/displayapp/screens/PineTimeStyle.cpp index fa88d459..781a359c 100644 --- a/src/displayapp/screens/PineTimeStyle.cpp +++ b/src/displayapp/screens/PineTimeStyle.cpp @@ -19,21 +19,21 @@ * Style/layout copied from TimeStyle for Pebble by Dan Tilden (github.com/tilden) */ -#include "PineTimeStyle.h" +#include "displayapp/screens/PineTimeStyle.h" #include #include #include #include -#include "BatteryIcon.h" -#include "BleIcon.h" -#include "NotificationIcon.h" -#include "Symbols.h" +#include "displayapp/screens/BatteryIcon.h" +#include "displayapp/screens/BleIcon.h" +#include "displayapp/screens/NotificationIcon.h" +#include "displayapp/screens/Symbols.h" #include "components/battery/BatteryController.h" #include "components/ble/BleController.h" #include "components/ble/NotificationManager.h" #include "components/motion/MotionController.h" #include "components/settings/Settings.h" -#include "../DisplayApp.h" +#include "displayapp/DisplayApp.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/PineTimeStyle.h b/src/displayapp/screens/PineTimeStyle.h index ba473806..f8c7c8b4 100644 --- a/src/displayapp/screens/PineTimeStyle.h +++ b/src/displayapp/screens/PineTimeStyle.h @@ -4,8 +4,8 @@ #include #include #include -#include "Screen.h" -#include "ScreenList.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/ScreenList.h" #include "components/datetime/DateTimeController.h" namespace Pinetime { diff --git a/src/displayapp/screens/Screen.cpp b/src/displayapp/screens/Screen.cpp index 6ae5b7bb..bc4cc438 100644 --- a/src/displayapp/screens/Screen.cpp +++ b/src/displayapp/screens/Screen.cpp @@ -1,4 +1,4 @@ -#include "Screen.h" +#include "displayapp/screens/Screen.h" using namespace Pinetime::Applications::Screens; void Screen::RefreshTaskCallback(lv_task_t* task) { diff --git a/src/displayapp/screens/Screen.h b/src/displayapp/screens/Screen.h index ce5741b2..04bb152c 100644 --- a/src/displayapp/screens/Screen.h +++ b/src/displayapp/screens/Screen.h @@ -1,7 +1,7 @@ #pragma once #include -#include "../TouchEvents.h" +#include "displayapp/TouchEvents.h" #include namespace Pinetime { diff --git a/src/displayapp/screens/ScreenList.h b/src/displayapp/screens/ScreenList.h index a9d747aa..e316e360 100644 --- a/src/displayapp/screens/ScreenList.h +++ b/src/displayapp/screens/ScreenList.h @@ -3,8 +3,8 @@ #include #include #include -#include "Screen.h" -#include "../DisplayApp.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/DisplayApp.h" namespace Pinetime { namespace Applications { diff --git a/src/displayapp/screens/Steps.cpp b/src/displayapp/screens/Steps.cpp index c41163ab..916138ed 100644 --- a/src/displayapp/screens/Steps.cpp +++ b/src/displayapp/screens/Steps.cpp @@ -1,7 +1,7 @@ -#include "Steps.h" +#include "displayapp/screens/Steps.h" #include -#include "../DisplayApp.h" -#include "Symbols.h" +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Symbols.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/Steps.h b/src/displayapp/screens/Steps.h index d7cf31e1..68daf16d 100644 --- a/src/displayapp/screens/Steps.h +++ b/src/displayapp/screens/Steps.h @@ -2,7 +2,7 @@ #include #include -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include namespace Pinetime { diff --git a/src/displayapp/screens/StopWatch.cpp b/src/displayapp/screens/StopWatch.cpp index 9b27a89d..a260d293 100644 --- a/src/displayapp/screens/StopWatch.cpp +++ b/src/displayapp/screens/StopWatch.cpp @@ -1,8 +1,8 @@ #include "StopWatch.h" -#include "Screen.h" -#include "Symbols.h" -#include "lvgl/lvgl.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/Symbols.h" +#include #include "projdefs.h" #include "FreeRTOSConfig.h" #include "task.h" diff --git a/src/displayapp/screens/StopWatch.h b/src/displayapp/screens/StopWatch.h index 25634e92..0720a586 100644 --- a/src/displayapp/screens/StopWatch.h +++ b/src/displayapp/screens/StopWatch.h @@ -1,8 +1,8 @@ #pragma once -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include "components/datetime/DateTimeController.h" -#include "../LittleVgl.h" +#include "displayapp/LittleVgl.h" #include "FreeRTOS.h" #include "portmacro_cmsis.h" diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index dd223b2f..350c15cf 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -1,7 +1,7 @@ -#include "SystemInfo.h" +#include "displayapp/screens/SystemInfo.h" #include -#include "../DisplayApp.h" -#include "Label.h" +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Label.h" #include "Version.h" #include "BootloaderVersion.h" #include "components/battery/BatteryController.h" diff --git a/src/displayapp/screens/SystemInfo.h b/src/displayapp/screens/SystemInfo.h index bfcc3aa4..a382ed8f 100644 --- a/src/displayapp/screens/SystemInfo.h +++ b/src/displayapp/screens/SystemInfo.h @@ -1,8 +1,8 @@ #pragma once #include -#include "Screen.h" -#include "ScreenList.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/ScreenList.h" namespace Pinetime { namespace Controllers { diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp index 1d4f0d0e..ba764a2e 100644 --- a/src/displayapp/screens/Tile.cpp +++ b/src/displayapp/screens/Tile.cpp @@ -1,6 +1,6 @@ -#include "Tile.h" -#include "../DisplayApp.h" -#include "BatteryIcon.h" +#include "displayapp/screens/Tile.h" +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/BatteryIcon.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/Tile.h b/src/displayapp/screens/Tile.h index 83d3fdf5..4869fef9 100644 --- a/src/displayapp/screens/Tile.h +++ b/src/displayapp/screens/Tile.h @@ -3,8 +3,8 @@ #include #include #include -#include "Screen.h" -#include "../Apps.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/Apps.h" #include "components/datetime/DateTimeController.h" #include "components/settings/Settings.h" #include "components/datetime/DateTimeController.h" diff --git a/src/displayapp/screens/Timer.cpp b/src/displayapp/screens/Timer.cpp index ff3099d5..a5e40195 100644 --- a/src/displayapp/screens/Timer.cpp +++ b/src/displayapp/screens/Timer.cpp @@ -1,8 +1,8 @@ -#include "Timer.h" +#include "displayapp/screens/Timer.h" -#include "Screen.h" -#include "Symbols.h" -#include "lvgl/lvgl.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/Symbols.h" +#include using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/Timer.h b/src/displayapp/screens/Timer.h index d0fc8ed1..23c87345 100644 --- a/src/displayapp/screens/Timer.h +++ b/src/displayapp/screens/Timer.h @@ -1,9 +1,9 @@ #pragma once -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include "components/datetime/DateTimeController.h" #include "systemtask/SystemTask.h" -#include "../LittleVgl.h" +#include "displayapp/LittleVgl.h" #include "components/timer/TimerController.h" diff --git a/src/displayapp/screens/Twos.cpp b/src/displayapp/screens/Twos.cpp index d12ef906..a1f0ba25 100644 --- a/src/displayapp/screens/Twos.cpp +++ b/src/displayapp/screens/Twos.cpp @@ -1,4 +1,4 @@ -#include "Twos.h" +#include "displayapp/screens/Twos.h" #include #include #include diff --git a/src/displayapp/screens/Twos.h b/src/displayapp/screens/Twos.h index 6d85cff6..48ea0794 100644 --- a/src/displayapp/screens/Twos.h +++ b/src/displayapp/screens/Twos.h @@ -1,7 +1,7 @@ #pragma once #include -#include "Screen.h" +#include "displayapp/screens/Screen.h" namespace Pinetime { namespace Applications { diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp index 53e7faf7..510d1139 100644 --- a/src/displayapp/screens/WatchFaceAnalog.cpp +++ b/src/displayapp/screens/WatchFaceAnalog.cpp @@ -1,9 +1,9 @@ #include -#include "WatchFaceAnalog.h" -#include "BatteryIcon.h" -#include "BleIcon.h" -#include "Symbols.h" -#include "NotificationIcon.h" +#include "displayapp/screens/WatchFaceAnalog.h" +#include "displayapp/screens/BatteryIcon.h" +#include "displayapp/screens/BleIcon.h" +#include "displayapp/screens/Symbols.h" +#include "displayapp/screens/NotificationIcon.h" LV_IMG_DECLARE(bg_clock); diff --git a/src/displayapp/screens/WatchFaceAnalog.h b/src/displayapp/screens/WatchFaceAnalog.h index 001414a6..ca0462a6 100644 --- a/src/displayapp/screens/WatchFaceAnalog.h +++ b/src/displayapp/screens/WatchFaceAnalog.h @@ -4,8 +4,8 @@ #include #include #include -#include "Screen.h" -#include "ScreenList.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/ScreenList.h" #include "components/datetime/DateTimeController.h" #include "components/battery/BatteryController.h" #include "components/ble/BleController.h" diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index 2ecab609..2894812c 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -1,12 +1,12 @@ -#include "WatchFaceDigital.h" +#include "displayapp/screens/WatchFaceDigital.h" #include #include #include -#include "BatteryIcon.h" -#include "BleIcon.h" -#include "NotificationIcon.h" -#include "Symbols.h" +#include "displayapp/screens/BatteryIcon.h" +#include "displayapp/screens/BleIcon.h" +#include "displayapp/screens/NotificationIcon.h" +#include "displayapp/screens/Symbols.h" #include "components/battery/BatteryController.h" #include "components/ble/BleController.h" #include "components/ble/NotificationManager.h" diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h index e27545f3..7134efb6 100644 --- a/src/displayapp/screens/WatchFaceDigital.h +++ b/src/displayapp/screens/WatchFaceDigital.h @@ -4,8 +4,8 @@ #include #include #include -#include "Screen.h" -#include "ScreenList.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/ScreenList.h" #include "components/datetime/DateTimeController.h" namespace Pinetime { diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp index dd626072..5d3a9834 100644 --- a/src/displayapp/screens/settings/QuickSettings.cpp +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -1,4 +1,4 @@ -#include "QuickSettings.h" +#include "displayapp/screens/settings/QuickSettings.h" #include "displayapp/DisplayApp.h" #include "displayapp/screens/Symbols.h" #include "displayapp/screens/BatteryIcon.h" diff --git a/src/displayapp/screens/settings/SettingDisplay.cpp b/src/displayapp/screens/settings/SettingDisplay.cpp index d8d6c767..666dfb80 100644 --- a/src/displayapp/screens/settings/SettingDisplay.cpp +++ b/src/displayapp/screens/settings/SettingDisplay.cpp @@ -1,4 +1,4 @@ -#include "SettingDisplay.h" +#include "displayapp/screens/settings/SettingDisplay.h" #include #include "displayapp/DisplayApp.h" #include "displayapp/Messages.h" diff --git a/src/displayapp/screens/settings/SettingPineTimeStyle.cpp b/src/displayapp/screens/settings/SettingPineTimeStyle.cpp index c9af19b6..f38ec3bd 100644 --- a/src/displayapp/screens/settings/SettingPineTimeStyle.cpp +++ b/src/displayapp/screens/settings/SettingPineTimeStyle.cpp @@ -1,4 +1,4 @@ -#include "SettingPineTimeStyle.h" +#include "displayapp/screens/settings/SettingPineTimeStyle.h" #include #include #include "displayapp/DisplayApp.h" diff --git a/src/displayapp/screens/settings/SettingSetDate.cpp b/src/displayapp/screens/settings/SettingSetDate.cpp index ba3413ef..8bfded34 100644 --- a/src/displayapp/screens/settings/SettingSetDate.cpp +++ b/src/displayapp/screens/settings/SettingSetDate.cpp @@ -1,4 +1,4 @@ -#include "SettingSetDate.h" +#include "displayapp/screens/settings/SettingSetDate.h" #include #include #include diff --git a/src/displayapp/screens/settings/SettingSetTime.cpp b/src/displayapp/screens/settings/SettingSetTime.cpp index 194bf5eb..5351adeb 100644 --- a/src/displayapp/screens/settings/SettingSetTime.cpp +++ b/src/displayapp/screens/settings/SettingSetTime.cpp @@ -1,4 +1,4 @@ -#include "SettingSetTime.h" +#include "displayapp/screens/settings/SettingSetTime.h" #include #include #include diff --git a/src/displayapp/screens/settings/SettingSteps.cpp b/src/displayapp/screens/settings/SettingSteps.cpp index bec7972b..149840df 100644 --- a/src/displayapp/screens/settings/SettingSteps.cpp +++ b/src/displayapp/screens/settings/SettingSteps.cpp @@ -1,4 +1,4 @@ -#include "SettingSteps.h" +#include "displayapp/screens/settings/SettingSteps.h" #include #include "displayapp/DisplayApp.h" #include "displayapp/screens/Symbols.h" diff --git a/src/displayapp/screens/settings/SettingTimeFormat.cpp b/src/displayapp/screens/settings/SettingTimeFormat.cpp index c99e3a0e..c6bdf401 100644 --- a/src/displayapp/screens/settings/SettingTimeFormat.cpp +++ b/src/displayapp/screens/settings/SettingTimeFormat.cpp @@ -1,4 +1,4 @@ -#include "SettingTimeFormat.h" +#include "displayapp/screens/settings/SettingTimeFormat.h" #include #include "displayapp/DisplayApp.h" #include "displayapp/screens/Screen.h" diff --git a/src/displayapp/screens/settings/SettingWakeUp.cpp b/src/displayapp/screens/settings/SettingWakeUp.cpp index d999004b..8339d9ad 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.cpp +++ b/src/displayapp/screens/settings/SettingWakeUp.cpp @@ -1,4 +1,4 @@ -#include "SettingWakeUp.h" +#include "displayapp/screens/settings/SettingWakeUp.h" #include #include "displayapp/DisplayApp.h" #include "displayapp/screens/Screen.h" diff --git a/src/displayapp/screens/settings/SettingWatchFace.cpp b/src/displayapp/screens/settings/SettingWatchFace.cpp index cdec704c..8e6e7cf4 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.cpp +++ b/src/displayapp/screens/settings/SettingWatchFace.cpp @@ -1,4 +1,4 @@ -#include "SettingWatchFace.h" +#include "displayapp/screens/settings/SettingWatchFace.h" #include #include "displayapp/DisplayApp.h" #include "displayapp/screens/Screen.h" diff --git a/src/displayapp/screens/settings/Settings.cpp b/src/displayapp/screens/settings/Settings.cpp index 1daf311e..392c12e0 100644 --- a/src/displayapp/screens/settings/Settings.cpp +++ b/src/displayapp/screens/settings/Settings.cpp @@ -1,4 +1,4 @@ -#include "Settings.h" +#include "displayapp/screens/settings/Settings.h" #include #include #include "displayapp/screens/List.h" diff --git a/src/drivers/Bma421.cpp b/src/drivers/Bma421.cpp index dd284000..8db64ad8 100644 --- a/src/drivers/Bma421.cpp +++ b/src/drivers/Bma421.cpp @@ -1,7 +1,7 @@ #include #include -#include "Bma421.h" -#include "TwiMaster.h" +#include "drivers/Bma421.h" +#include "drivers/TwiMaster.h" #include using namespace Pinetime::Drivers; diff --git a/src/drivers/Cst816s.cpp b/src/drivers/Cst816s.cpp index bf51a8ba..e9573df1 100644 --- a/src/drivers/Cst816s.cpp +++ b/src/drivers/Cst816s.cpp @@ -1,4 +1,4 @@ -#include "Cst816s.h" +#include "drivers/Cst816s.h" #include #include #include diff --git a/src/drivers/Cst816s.h b/src/drivers/Cst816s.h index 507dd4f5..4a548d45 100644 --- a/src/drivers/Cst816s.h +++ b/src/drivers/Cst816s.h @@ -1,6 +1,6 @@ #pragma once -#include "TwiMaster.h" +#include "drivers/TwiMaster.h" namespace Pinetime { namespace Drivers { diff --git a/src/drivers/DebugPins.cpp b/src/drivers/DebugPins.cpp index 56fd1458..92091280 100644 --- a/src/drivers/DebugPins.cpp +++ b/src/drivers/DebugPins.cpp @@ -1,4 +1,4 @@ -#include "DebugPins.h" +#include "drivers/DebugPins.h" #include #ifdef USE_DEBUG_PINS diff --git a/src/drivers/Hrs3300.cpp b/src/drivers/Hrs3300.cpp index edb9e81d..cecef145 100644 --- a/src/drivers/Hrs3300.cpp +++ b/src/drivers/Hrs3300.cpp @@ -6,7 +6,7 @@ #include #include -#include "Hrs3300.h" +#include "drivers/Hrs3300.h" #include #include diff --git a/src/drivers/Hrs3300.h b/src/drivers/Hrs3300.h index c4f28900..01310c62 100644 --- a/src/drivers/Hrs3300.h +++ b/src/drivers/Hrs3300.h @@ -1,6 +1,6 @@ #pragma once -#include "TwiMaster.h" +#include "drivers/TwiMaster.h" namespace Pinetime { namespace Drivers { diff --git a/src/drivers/InternalFlash.cpp b/src/drivers/InternalFlash.cpp index 0840c6e5..ec5885d5 100644 --- a/src/drivers/InternalFlash.cpp +++ b/src/drivers/InternalFlash.cpp @@ -1,4 +1,4 @@ -#include "InternalFlash.h" +#include "drivers/InternalFlash.h" #include using namespace Pinetime::Drivers; diff --git a/src/drivers/Spi.cpp b/src/drivers/Spi.cpp index a55d2888..e477622b 100644 --- a/src/drivers/Spi.cpp +++ b/src/drivers/Spi.cpp @@ -1,4 +1,4 @@ -#include "Spi.h" +#include "drivers/Spi.h" #include #include diff --git a/src/drivers/Spi.h b/src/drivers/Spi.h index 6875710d..9b6a30f4 100644 --- a/src/drivers/Spi.h +++ b/src/drivers/Spi.h @@ -1,7 +1,7 @@ #pragma once #include #include -#include "SpiMaster.h" +#include "drivers/SpiMaster.h" namespace Pinetime { namespace Drivers { diff --git a/src/drivers/SpiMaster.cpp b/src/drivers/SpiMaster.cpp index c45e1294..747dbc84 100644 --- a/src/drivers/SpiMaster.cpp +++ b/src/drivers/SpiMaster.cpp @@ -1,4 +1,4 @@ -#include "SpiMaster.h" +#include "drivers/SpiMaster.h" #include #include #include diff --git a/src/drivers/SpiNorFlash.cpp b/src/drivers/SpiNorFlash.cpp index 068d1d02..ebe3174c 100644 --- a/src/drivers/SpiNorFlash.cpp +++ b/src/drivers/SpiNorFlash.cpp @@ -1,8 +1,8 @@ -#include "SpiNorFlash.h" +#include "drivers/SpiNorFlash.h" #include #include #include -#include "Spi.h" +#include "drivers/Spi.h" using namespace Pinetime::Drivers; diff --git a/src/drivers/St7789.cpp b/src/drivers/St7789.cpp index 4d81cf27..fd1366f8 100644 --- a/src/drivers/St7789.cpp +++ b/src/drivers/St7789.cpp @@ -1,8 +1,8 @@ -#include "St7789.h" +#include "drivers/St7789.h" #include #include #include -#include "Spi.h" +#include "drivers/Spi.h" using namespace Pinetime::Drivers; diff --git a/src/drivers/TwiMaster.cpp b/src/drivers/TwiMaster.cpp index 76009278..9b456d5f 100644 --- a/src/drivers/TwiMaster.cpp +++ b/src/drivers/TwiMaster.cpp @@ -1,4 +1,4 @@ -#include "TwiMaster.h" +#include "drivers/TwiMaster.h" #include #include #include diff --git a/src/drivers/Watchdog.cpp b/src/drivers/Watchdog.cpp index a6ad263a..d0907a65 100644 --- a/src/drivers/Watchdog.cpp +++ b/src/drivers/Watchdog.cpp @@ -1,4 +1,4 @@ -#include "Watchdog.h" +#include "drivers/Watchdog.h" #include using namespace Pinetime::Drivers; diff --git a/src/heartratetask/HeartRateTask.cpp b/src/heartratetask/HeartRateTask.cpp index fddc05d7..213ab4a7 100644 --- a/src/heartratetask/HeartRateTask.cpp +++ b/src/heartratetask/HeartRateTask.cpp @@ -1,4 +1,4 @@ -#include "HeartRateTask.h" +#include "heartratetask/HeartRateTask.h" #include #include #include diff --git a/src/logging/DummyLogger.h b/src/logging/DummyLogger.h index 8732dff5..1b050b37 100644 --- a/src/logging/DummyLogger.h +++ b/src/logging/DummyLogger.h @@ -1,5 +1,5 @@ #pragma once -#include "Logger.h" +#include "logging/Logger.h" namespace Pinetime { namespace Logging { diff --git a/src/logging/NrfLogger.cpp b/src/logging/NrfLogger.cpp index 1c048f2c..ab54afe9 100644 --- a/src/logging/NrfLogger.cpp +++ b/src/logging/NrfLogger.cpp @@ -1,4 +1,4 @@ -#include "NrfLogger.h" +#include "logging/NrfLogger.h" #include #include diff --git a/src/logging/NrfLogger.h b/src/logging/NrfLogger.h index 060c4e76..21183a3d 100644 --- a/src/logging/NrfLogger.h +++ b/src/logging/NrfLogger.h @@ -1,5 +1,5 @@ #pragma once -#include "Logger.h" +#include "logging/Logger.h" #include #include diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 4b03f9ac..1120b80d 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -1,4 +1,4 @@ -#include "SystemTask.h" +#include "systemtask/SystemTask.h" #define min // workaround: nimble's min/max macros conflict with libstdc++ #define max #include diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index 412878b1..e2e6de7f 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -11,7 +11,7 @@ #include #include -#include "SystemMonitor.h" +#include "systemtask/SystemMonitor.h" #include "components/battery/BatteryController.h" #include "components/ble/NimbleController.h" #include "components/ble/NotificationManager.h" @@ -33,7 +33,7 @@ #endif #include "drivers/Watchdog.h" -#include "Messages.h" +#include "systemtask/Messages.h" extern std::chrono::time_point NoInit_BackUpTime; namespace Pinetime { diff --git a/src/touchhandler/TouchHandler.cpp b/src/touchhandler/TouchHandler.cpp index 735b311a..0be33476 100644 --- a/src/touchhandler/TouchHandler.cpp +++ b/src/touchhandler/TouchHandler.cpp @@ -1,4 +1,4 @@ -#include "TouchHandler.h" +#include "touchhandler/TouchHandler.h" using namespace Pinetime::Controllers; -- cgit v1.2.3-70-g09d2 From f2918709d92dd49e7e1fffe22be04fc2b47f928b Mon Sep 17 00:00:00 2001 From: Reinhold Gschweicher Date: Wed, 3 Nov 2021 23:02:30 +0100 Subject: Add missing standard includes --- src/BootloaderVersion.h | 3 +++ src/Version.h.in | 2 ++ src/components/ble/DeviceInformationService.h | 1 + src/displayapp/Messages.h | 1 + src/displayapp/screens/BatteryIcon.h | 1 + src/displayapp/screens/InfiniPaint.h | 1 + src/drivers/PinMap.h | 1 + 7 files changed, 10 insertions(+) (limited to 'src/components/ble') diff --git a/src/BootloaderVersion.h b/src/BootloaderVersion.h index f8127414..309c23c3 100644 --- a/src/BootloaderVersion.h +++ b/src/BootloaderVersion.h @@ -1,5 +1,8 @@ #pragma once +#include +#include + namespace Pinetime { class BootloaderVersion { public: diff --git a/src/Version.h.in b/src/Version.h.in index 8cd39c96..0d6219c0 100644 --- a/src/Version.h.in +++ b/src/Version.h.in @@ -2,6 +2,8 @@ @VERSION_EDIT_WARNING@ +#include + namespace Pinetime { class Version { public: diff --git a/src/components/ble/DeviceInformationService.h b/src/components/ble/DeviceInformationService.h index 54b3e961..a269afb4 100644 --- a/src/components/ble/DeviceInformationService.h +++ b/src/components/ble/DeviceInformationService.h @@ -1,4 +1,5 @@ #pragma once +#include #define min // workaround: nimble's min/max macros conflict with libstdc++ #define max #include diff --git a/src/displayapp/Messages.h b/src/displayapp/Messages.h index ab0a0608..29e09eb3 100644 --- a/src/displayapp/Messages.h +++ b/src/displayapp/Messages.h @@ -1,4 +1,5 @@ #pragma once +#include namespace Pinetime { namespace Applications { namespace Display { diff --git a/src/displayapp/screens/BatteryIcon.h b/src/displayapp/screens/BatteryIcon.h index b370b331..bec2e4e0 100644 --- a/src/displayapp/screens/BatteryIcon.h +++ b/src/displayapp/screens/BatteryIcon.h @@ -1,4 +1,5 @@ #pragma once +#include namespace Pinetime { namespace Applications { diff --git a/src/displayapp/screens/InfiniPaint.h b/src/displayapp/screens/InfiniPaint.h index 322ce757..bc0bca24 100644 --- a/src/displayapp/screens/InfiniPaint.h +++ b/src/displayapp/screens/InfiniPaint.h @@ -2,6 +2,7 @@ #include #include +#include // std::fill #include "displayapp/screens/Screen.h" namespace Pinetime { diff --git a/src/drivers/PinMap.h b/src/drivers/PinMap.h index 57964020..579bf38a 100644 --- a/src/drivers/PinMap.h +++ b/src/drivers/PinMap.h @@ -1,4 +1,5 @@ #pragma once +#include namespace Pinetime { namespace PinMap { -- cgit v1.2.3-70-g09d2 From 241d36471daaea03215c289f3dc2bdc2860b5053 Mon Sep 17 00:00:00 2001 From: Reinhold Gschweicher Date: Fri, 5 Nov 2021 23:55:34 +0100 Subject: Move up file header include to top --- src/components/ble/BatteryInformationService.cpp | 2 +- src/components/heartrate/Ppg.cpp | 2 +- src/components/heartrate/Ptagc.cpp | 2 +- src/displayapp/screens/BatteryIcon.cpp | 2 +- src/displayapp/screens/HeartRate.cpp | 2 +- src/displayapp/screens/Motion.cpp | 2 +- src/displayapp/screens/WatchFaceAnalog.cpp | 2 +- src/drivers/Bma421.cpp | 2 +- src/drivers/Hrs3300.cpp | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/BatteryInformationService.cpp b/src/components/ble/BatteryInformationService.cpp index b95a88d9..9a3f86f5 100644 --- a/src/components/ble/BatteryInformationService.cpp +++ b/src/components/ble/BatteryInformationService.cpp @@ -1,5 +1,5 @@ -#include #include "components/ble/BatteryInformationService.h" +#include #include "components/battery/BatteryController.h" using namespace Pinetime::Controllers; diff --git a/src/components/heartrate/Ppg.cpp b/src/components/heartrate/Ppg.cpp index c247d1f6..a5d83696 100644 --- a/src/components/heartrate/Ppg.cpp +++ b/src/components/heartrate/Ppg.cpp @@ -4,9 +4,9 @@ C++ port Copyright (C) 2021 Jean-François Milants */ +#include "components/heartrate/Ppg.h" #include #include -#include "components/heartrate/Ppg.h" using namespace Pinetime::Controllers; /** Original implementation from wasp-os : https://github.com/daniel-thompson/wasp-os/blob/master/wasp/ppg.py */ diff --git a/src/components/heartrate/Ptagc.cpp b/src/components/heartrate/Ptagc.cpp index db496a15..1c60bc23 100644 --- a/src/components/heartrate/Ptagc.cpp +++ b/src/components/heartrate/Ptagc.cpp @@ -4,8 +4,8 @@ C++ port Copyright (C) 2021 Jean-François Milants */ -#include #include "components/heartrate/Ptagc.h" +#include using namespace Pinetime::Controllers; diff --git a/src/displayapp/screens/BatteryIcon.cpp b/src/displayapp/screens/BatteryIcon.cpp index 114b08fa..08aaab70 100644 --- a/src/displayapp/screens/BatteryIcon.cpp +++ b/src/displayapp/screens/BatteryIcon.cpp @@ -1,5 +1,5 @@ -#include #include "displayapp/screens/BatteryIcon.h" +#include #include "displayapp/screens/Symbols.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/HeartRate.cpp b/src/displayapp/screens/HeartRate.cpp index 65d1aa2f..513c40bf 100644 --- a/src/displayapp/screens/HeartRate.cpp +++ b/src/displayapp/screens/HeartRate.cpp @@ -1,5 +1,5 @@ -#include #include "displayapp/screens/HeartRate.h" +#include #include #include "displayapp/DisplayApp.h" diff --git a/src/displayapp/screens/Motion.cpp b/src/displayapp/screens/Motion.cpp index 8162e02f..23eb2765 100644 --- a/src/displayapp/screens/Motion.cpp +++ b/src/displayapp/screens/Motion.cpp @@ -1,5 +1,5 @@ -#include #include "displayapp/screens/Motion.h" +#include #include "displayapp/DisplayApp.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp index 470fc8e9..4540c1a8 100644 --- a/src/displayapp/screens/WatchFaceAnalog.cpp +++ b/src/displayapp/screens/WatchFaceAnalog.cpp @@ -1,5 +1,5 @@ -#include #include "displayapp/screens/WatchFaceAnalog.h" +#include #include "displayapp/screens/BatteryIcon.h" #include "displayapp/screens/BleIcon.h" #include "displayapp/screens/Symbols.h" diff --git a/src/drivers/Bma421.cpp b/src/drivers/Bma421.cpp index 8db64ad8..2f60f42f 100644 --- a/src/drivers/Bma421.cpp +++ b/src/drivers/Bma421.cpp @@ -1,6 +1,6 @@ +#include "drivers/Bma421.h" #include #include -#include "drivers/Bma421.h" #include "drivers/TwiMaster.h" #include diff --git a/src/drivers/Hrs3300.cpp b/src/drivers/Hrs3300.cpp index cecef145..c14fe7aa 100644 --- a/src/drivers/Hrs3300.cpp +++ b/src/drivers/Hrs3300.cpp @@ -4,9 +4,9 @@ C++ port Copyright (C) 2021 Jean-François Milants */ +#include "drivers/Hrs3300.h" #include #include -#include "drivers/Hrs3300.h" #include #include -- cgit v1.2.3-70-g09d2 From bda96dc595aecb56739cc02de7e7d2d825927b7f Mon Sep 17 00:00:00 2001 From: Avamander Date: Thu, 10 Jun 2021 00:44:49 +0300 Subject: Initial Weather service skeleton --- .gitmodules | 3 + src/components/ble/NimbleController.cpp | 2 + src/components/ble/NimbleController.h | 2 + src/components/ble/weather/WeatherData.h | 338 ++++++++++++++++++++++++++ src/components/ble/weather/WeatherService.cpp | 208 ++++++++++++++++ src/components/ble/weather/WeatherService.h | 139 +++++++++++ src/displayapp/screens/Weather.cpp | 246 +++++++++++++++++++ src/displayapp/screens/Weather.h | 54 ++++ 8 files changed, 992 insertions(+) create mode 100644 src/components/ble/weather/WeatherData.h create mode 100644 src/components/ble/weather/WeatherService.cpp create mode 100644 src/components/ble/weather/WeatherService.h create mode 100644 src/displayapp/screens/Weather.cpp create mode 100644 src/displayapp/screens/Weather.h (limited to 'src/components/ble') diff --git a/.gitmodules b/.gitmodules index 815fc022..8d302ae7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "src/libs/littlefs"] path = src/libs/littlefs url = https://github.com/littlefs-project/littlefs.git +[submodule "src/libs/QCBOR"] + path = src/libs/QCBOR + url = https://github.com/laurencelundblade/QCBOR.git diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 43a8b0d6..9ef2d057 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -36,6 +36,7 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, alertNotificationClient {systemTask, notificationManager}, currentTimeService {dateTimeController}, musicService {systemTask}, + weatherService {systemTask, dateTimeController}, navService {systemTask}, batteryInformationService {batteryController}, immediateAlertService {systemTask, notificationManager}, @@ -77,6 +78,7 @@ void NimbleController::Init() { currentTimeClient.Init(); currentTimeService.Init(); musicService.Init(); + weatherService.Init(); navService.Init(); anService.Init(); dfuService.Init(); diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 895b87f2..a21cbe81 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -20,6 +20,7 @@ #include "components/ble/ServiceDiscovery.h" #include "components/ble/HeartRateService.h" #include "components/ble/MotionService.h" +#include "components/ble/weather/WeatherService.h" namespace Pinetime { namespace Drivers { @@ -93,6 +94,7 @@ namespace Pinetime { AlertNotificationClient alertNotificationClient; CurrentTimeService currentTimeService; MusicService musicService; + WeatherService weatherService; NavigationService navService; BatteryInformationService batteryInformationService; ImmediateAlertService immediateAlertService; diff --git a/src/components/ble/weather/WeatherData.h b/src/components/ble/weather/WeatherData.h new file mode 100644 index 00000000..c1d53f4e --- /dev/null +++ b/src/components/ble/weather/WeatherData.h @@ -0,0 +1,338 @@ +/* Copyright (C) 2021 Avamander + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +#pragma once + +/** + * Different weather events, weather data structures used by {@link WeatherService.h} + * + * + * Implemented based on and other material: + * https://en.wikipedia.org/wiki/METAR + * https://www.weather.gov/jetstream/obscurationtypes + * http://www.faraim.org/aim/aim-4-03-14-493.html + */ + +namespace Pinetime { + namespace Controllers { + class WeatherData { + public: + /** + * Visibility obscuration types + */ + enum class obscurationtype { + /** No obscuration */ + None = 0, + /** Water particles suspended in the air; low visibility; does not fall */ + Fog = 1, + /** Extremely small, dry particles in the air; invisible to the eye; opalescent */ + Haze = 2, + /** Small fire-created particles suspended in the air */ + Smoke = 3, + /** Fine rock powder, from for example volcanoes */ + Ash = 4, + /** Fine particles of earth suspended in the air by the wind */ + Dust = 5, + /** Fine particles of sand suspended in the air by the wind */ + Sand = 6, + /** Water particles suspended in the air; low-ish visibility; temperature is near dewpoint */ + Mist = 7, + }; + + /** + * Types of precipitation + */ + enum class precipitationtype { + /** + * No precipitation + * + * Theoretically we could just _not_ send the event, but then + * how do we differentiate between no precipitation and + * no information about precipitation + */ + None = 0, + /** Drops larger than a drizzle; also widely separated drizzle */ + Rain = 1, + /** Fairly uniform rain consisting of fine drops */ + Drizzle = 2, + /** Rain that freezes upon contact with objects and ground */ + FreezingRain = 3, + /** Rain + hail; ice pellets; small translucent frozen raindrops */ + Sleet = 4, + /** Larger ice pellets; falling separately or in irregular clumps */ + Hail = 5, + /** Hail with smaller grains of ice; mini-snowballs */ + SmallHail = 6, + /** Snow... */ + Snow = 7, + /** Frozen drizzle; very small snow crystals */ + SnowGrains = 8, + /** Needles; columns or plates of ice. Sometimes described as "diamond dust". In very cold regions */ + IceCrystals = 9 + }; + + /** + * These are special events that can "enhance" the "experience" of existing weather events + */ + enum class specialtype { + /** Strong wind with a sudden onset that lasts at least a minute */ + Squall = 0, + /** Series of waves in a water body caused by the displacement of a large volume of water */ + Tsunami = 1, + /** Violent; rotating column of air */ + Tornado = 2, + /** Unplanned; unwanted; uncontrolled fire in an area */ + Fire = 3, + /** Thunder and/or lightning */ + Thunder = 4, + }; + + /** + * These are used for weather timeline manipulation + * that isn't just adding to the stack of weather events + */ + enum class controlcodes { + /** How much is stored already */ + GetLength = 0, + /** This wipes the entire timeline */ + DelTimeline = 1, + /** There's a currently valid timeline event with the given type */ + HasValidEvent = 3 + }; + + /** + * Events have types + * then they're easier to parse after sending them over the air + */ + enum class eventtype { + /** @see obscuration */ + Obscuration = 0, + /** @see precipitation */ + Precipitation = 1, + /** @see wind */ + Wind = 2, + /** @see temperature */ + Temperature = 3, + /** @see airquality */ + AirQuality = 4, + /** @see special */ + Special = 5, + /** @see pressure */ + Pressure = 6, + /** @see location */ + Location = 7, + /** @see cloud */ + Clouds = 8, + }; + + /** + * Valid event query + */ + class valideventquery { + public: + static constexpr controlcodes code = controlcodes::HasValidEvent; + eventtype eventType; + }; + + /** The header used for further parsing */ + class timelineheader { + public: + /** UNIX timestamp */ + uint64_t timestamp; + /** + * Time in seconds until the event expires + * + * 32 bits ought to be enough for everyone + * + * If there's a newer event of the same type then it overrides this one, even if it hasn't expired + */ + uint32_t expires; + /** + * What type of weather-related event + */ + eventtype eventType; + }; + + /** Specifies how cloudiness is stored */ + class clouds : public timelineheader { + public: + /** Cloud coverage in percentage, 0-100% */ + uint8_t amount; + }; + + /** Specifies how obscuration is stored */ + class obscuration : public timelineheader { + public: + /** Type */ + obscurationtype type; + /** Visibility distance in meters */ + uint8_t amount; + }; + + /** Specifies how precipitation is stored */ + class precipitation : public timelineheader { + public: + /** Type */ + precipitationtype type; + /** How much is it going to rain? In millimeters */ + uint8_t amount; + }; + + /** + * How wind speed is stored + * + * In order to represent bursts of wind instead of constant wind, + * you have minimum and maximum speeds. + * + * As direction can fluctuate wildly and some watchfaces might wish to display it nicely, + * we're following the aerospace industry weather report option of specifying a range. + */ + class wind : public timelineheader { + public: + /** Meters per second */ + uint8_t speedMin; + /** Meters per second */ + uint8_t speedMax; + /** Unitless direction between 0-255; approximately 1 unit per 0.71 degrees */ + uint8_t directionMin; + /** Unitless direction between 0-255; approximately 1 unit per 0.71 degrees */ + uint8_t directionMax; + }; + + /** + * How temperature is stored + * + * As it's annoying to figure out the dewpoint on the watch, + * please send it from the companion + * + * We don't do floats, microdegrees are not useful. Make sure to multiply. + */ + class temperature : public timelineheader { + public: + /** Temperature °C but multiplied by 100 (e.g. -12.50°C becomes -1250) */ + int16_t temperature; + /** Dewpoint °C but multiplied by 100 (e.g. -12.50°C becomes -1250) */ + int16_t dewPoint; + }; + + /** + * How location info is stored + * + * This can be mostly static with long expiration, + * as it usually is, but it could change during a trip for ex. + * so we allow changing it dynamically. + * + * Location info can be for some kind of map watchface + * or daylight calculations, should those be required. + * + */ + class location : public timelineheader { + public: + /** Location name */ + std::string location; + /** Altitude relative to sea level in meters */ + int16_t altitude; + /** Latitude, EPSG:3857 (Google Maps, Openstreetmaps datum) */ + int32_t latitude; + /** Longitude, EPSG:3857 (Google Maps, Openstreetmaps datum) */ + int32_t longitude; + }; + + /** + * How humidity is stored + */ + class humidity : public timelineheader { + public: + /** Relative humidity, 0-100% */ + uint8_t humidity; + }; + + /** + * How air pressure is stored + */ + class pressure : public timelineheader { + public: + /** Air pressure in hectopascals (hPa) */ + int16_t pressure; + }; + + /** + * How special events are stored + */ + class special : public timelineheader { + public: + /** Special event's type */ + specialtype type; + }; + + /** + * How air quality is stored + * + * These events are a bit more complex because the topic is not simple, + * the intention is to heavy-lift the annoying preprocessing from the watch + * this allows watchface or watchapp makers to generate accurate alerts and graphics + * + * If this needs further enforced standardization, pull requests are welcome + */ + class airquality : public timelineheader { + public: + /** + * The name of the pollution + * + * for the sake of better compatibility with watchapps + * that might want to use this data for say visuals + * don't localize the name. + * + * Ideally watchapp itself localizes the name, if it's at all needed. + * + * E.g. + * For generic ones use "PM0.1", "PM5", "PM10" + * For chemical compounds use the molecular formula e.g. "NO2", "CO2", "O3" + * For pollen use the genus, e.g. "Betula" for birch or "Alternaria" for that mold's spores + */ + std::string polluter; + /** + * Amount of the pollution in SI units, + * otherwise it's going to be difficult to create UI, alerts + * and so on and for. + * + * See more: + * https://ec.europa.eu/environment/air/quality/standards.htm + * http://www.ourair.org/wp-content/uploads/2012-aaqs2.pdf + * + * Example units: + * count/m³ for pollen + * µgC/m³ for micrograms of organic carbon + * µg/m³ sulfates, PM0.1, PM1, PM2, PM10 and so on, dust + * mg/m³ CO2, CO + * ng/m³ for heavy metals + * + * List is not comprehensive, should be improved. + * The current ones are what watchapps assume. + * + * Note: ppb and ppm to concentration should be calculated on the companion, using + * the correct formula (taking into account temperature and air pressure) + * + * Note2: The amount is off by times 100, for two decimal places of precision. + * E.g. 54.32µg/m³ is 5432 + * + */ + uint32_t amount; + }; + }; + } +} \ No newline at end of file diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp new file mode 100644 index 00000000..006fc6c1 --- /dev/null +++ b/src/components/ble/weather/WeatherService.cpp @@ -0,0 +1,208 @@ +/* Copyright (C) 2021 Avamander + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +#include +#include "WeatherService.h" +#include "libs/QCBOR/inc/qcbor/qcbor.h" +#include "systemtask/SystemTask.h" + +int WeatherCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) { + return static_cast(arg)->OnCommand(conn_handle, attr_handle, ctxt); +} + +namespace Pinetime { + namespace Controllers { + WeatherService::WeatherService(System::SystemTask& system, DateTime& dateTimeController) + : system(system), dateTimeController(dateTimeController) { + } + + void WeatherService::Init() { + uint8_t res = 0; + res = ble_gatts_count_cfg(serviceDefinition); + ASSERT(res == 0) + + res = ble_gatts_add_svcs(serviceDefinition); + ASSERT(res == 0); + } + + int WeatherService::OnCommand(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt) { + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + getCurrentPressure(); + tidyTimeline(); + getTimelineLength(); + const auto packetLen = OS_MBUF_PKTLEN(ctxt->om); + if (packetLen <= 0) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + // Decode + QCBORDecodeContext decodeContext; + UsefulBufC EncodedCBOR; + // TODO: Check uninit fine + QCBORDecode_Init(&decodeContext, EncodedCBOR, QCBOR_DECODE_MODE_NORMAL); + QCBORDecode_EnterMap(&decodeContext, nullptr); + WeatherData::timelineheader timelineHeader {}; + // Always encodes to the smallest number of bytes based on the value + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Timestamp", reinterpret_cast(&(timelineHeader.timestamp))); + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Expires", reinterpret_cast(&(timelineHeader.expires))); + QCBORDecode_GetInt64InMapSZ(&decodeContext, "EventType", reinterpret_cast(&(timelineHeader.eventType))); + switch (timelineHeader.eventType) { + // TODO: Populate + case WeatherData::eventtype::AirQuality: { + break; + } + case WeatherData::eventtype::Obscuration: { + break; + } + case WeatherData::eventtype::Precipitation: { + break; + } + case WeatherData::eventtype::Wind: { + break; + } + case WeatherData::eventtype::Temperature: { + break; + } + case WeatherData::eventtype::Special: { + break; + } + case WeatherData::eventtype::Pressure: { + break; + } + case WeatherData::eventtype::Location: { + break; + } + case WeatherData::eventtype::Clouds: { + break; + } + default: { + break; + } + } + QCBORDecode_ExitMap(&decodeContext); + + auto uErr = QCBORDecode_Finish(&decodeContext); + if (uErr != 0) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + // TODO: Detect control messages + + // Encode + uint8_t buffer[64]; + QCBOREncodeContext encodeContext; + QCBOREncode_Init(&encodeContext, UsefulBuf_FROM_BYTE_ARRAY(buffer)); + QCBOREncode_OpenMap(&encodeContext); + QCBOREncode_AddTextToMap(&encodeContext, "test", UsefulBuf_FROM_SZ_LITERAL("test")); + QCBOREncode_AddInt64ToMap(&encodeContext, "test", 1ul); + QCBOREncode_CloseMap(&encodeContext); + + UsefulBufC encodedEvent; + auto uErr = QCBOREncode_Finish(&encodeContext, &encodedEvent); + if (uErr != 0) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + auto res = os_mbuf_append(ctxt->om, &buffer, sizeof(buffer)); + if (res == 0) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + return 0; + } + return 0; + } + + WeatherData::location WeatherService::getCurrentLocation() const { + return WeatherData::location(); + } + WeatherData::clouds WeatherService::getCurrentClouds() const { + return WeatherData::clouds(); + } + WeatherData::obscuration WeatherService::getCurrentObscuration() const { + return WeatherData::obscuration(); + } + WeatherData::precipitation WeatherService::getCurrentPrecipitation() const { + return WeatherData::precipitation(); + } + WeatherData::wind WeatherService::getCurrentWind() const { + return WeatherData::wind(); + } + WeatherData::temperature WeatherService::getCurrentTemperature() const { + return WeatherData::temperature(); + } + WeatherData::humidity WeatherService::getCurrentHumidity() const { + return WeatherData::humidity(); + } + WeatherData::pressure WeatherService::getCurrentPressure() const { + uint64_t currentTimestamp = getCurrentUNIXTimestamp(); + for (auto&& header : timeline) { + if (header->eventType == WeatherData::eventtype::Pressure && header->timestamp + header->expires <= currentTimestamp) { + return WeatherData::pressure(); + } + } + return WeatherData::pressure(); + } + + WeatherData::airquality WeatherService::getCurrentQuality() const { + return WeatherData::airquality(); + } + + size_t WeatherService::getTimelineLength() const { + return timeline.size(); + } + + bool WeatherService::addEventToTimeline(std::unique_ptr event) { + if (timeline.size() == timeline.max_size()) { + return false; + } + + timeline.push_back(std::move(event)); + return true; + } + + bool WeatherService::hasTimelineEventOfType(const WeatherData::eventtype type) const { + uint64_t currentTimestamp = getCurrentUNIXTimestamp(); + for (auto&& header : timeline) { + if (header->eventType == type && header->timestamp + header->expires <= currentTimestamp) { + // TODO: Check if its currently valid + return true; + } + } + return false; + } + + void WeatherService::tidyTimeline() { + uint64_t timeCurrent = 0; + timeline.erase(std::remove_if(std::begin(timeline), + std::end(timeline), + [&](std::unique_ptr const& header) { + return header->timestamp + header->expires > timeCurrent; + }), + std::end(timeline)); + + std::sort(std::begin(timeline), std::end(timeline), compareTimelineEvents); + } + + bool WeatherService::compareTimelineEvents(const std::unique_ptr& first, + const std::unique_ptr& second) { + return first->timestamp > second->timestamp; + } + + uint64_t WeatherService::getCurrentUNIXTimestamp() const { + return std::chrono::duration_cast(dateTimeController.CurrentDateTime().time_since_epoch()).count(); + } + } +} diff --git a/src/components/ble/weather/WeatherService.h b/src/components/ble/weather/WeatherService.h new file mode 100644 index 00000000..ef99db86 --- /dev/null +++ b/src/components/ble/weather/WeatherService.h @@ -0,0 +1,139 @@ +/* Copyright (C) 2021 Avamander + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +#pragma once + +#include +#include +#include +#include + +#define min // workaround: nimble's min/max macros conflict with libstdc++ +#define max +#include +#include +#undef max +#undef min + +#include "WeatherData.h" +#include + +// 00030000-78fc-48fe-8e23-433b3a1942d0 +#define WEATHER_SERVICE_UUID_BASE \ + { 0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, 0x00, 0x00, 0x03, 0x00 } +#define WEATHER_SERVICE_CHAR_UUID(y, x) \ + { 0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, (x), (y), 0x03, 0x00 } + +int WeatherCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg); + +namespace Pinetime { + namespace System { + class SystemTask; + } + namespace Controllers { + + class WeatherService { + public: + explicit WeatherService(System::SystemTask& system, DateTime& dateTimeController); + + void Init(); + + int OnCommand(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt); + + /* + * Helper functions for quick access to currently valid data + */ + WeatherData::location getCurrentLocation() const; + WeatherData::clouds getCurrentClouds() const; + WeatherData::obscuration getCurrentObscuration() const; + WeatherData::precipitation getCurrentPrecipitation() const; + WeatherData::wind getCurrentWind() const; + WeatherData::temperature getCurrentTemperature() const; + WeatherData::humidity getCurrentHumidity() const; + WeatherData::pressure getCurrentPressure() const; + WeatherData::airquality getCurrentQuality() const; + + /* + * Management functions + */ + /** + * Adds an event to the timeline + * @return + */ + bool addEventToTimeline(std::unique_ptr event); + /** + * Gets the current timeline length + */ + size_t getTimelineLength() const; + /** + * Checks if an event of a certain type exists in the timeline + * @return + */ + bool hasTimelineEventOfType(WeatherData::eventtype type) const; + + private: + ble_uuid128_t msUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = WEATHER_SERVICE_UUID_BASE}; + + /** + * Just write timeline data here + */ + ble_uuid128_t wDataCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = WEATHER_SERVICE_CHAR_UUID(0x00, 0x01)}; + /** + * This doesn't take timeline data + * but provides some control over it + */ + ble_uuid128_t wControlCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = WEATHER_SERVICE_CHAR_UUID(0x00, 0x02)}; + + const struct ble_gatt_chr_def characteristicDefinition[2] = {{.uuid = reinterpret_cast(&wDataCharUuid), + .access_cb = WeatherCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_NOTIFY, + .val_handle = &eventHandle}, + {.uuid = reinterpret_cast(&wControlCharUuid), + .access_cb = WeatherCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ}}; + const struct ble_gatt_svc_def serviceDefinition[2] = { + {.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = reinterpret_cast(&msUuid), .characteristics = characteristicDefinition}, + {0}}; + + uint16_t eventHandle {}; + + Pinetime::System::SystemTask& system; + Pinetime::Controllers::DateTime& dateTimeController; + + std::vector> timeline; + + /** + * Cleans up the timeline of expired events + * @return result code + */ + void tidyTimeline(); + + /** + * Compares two timeline events + */ + static bool compareTimelineEvents(const std::unique_ptr& first, + const std::unique_ptr& second); + + /** + * + */ + uint64_t getCurrentUNIXTimestamp() const; + }; + } +} diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp new file mode 100644 index 00000000..014761bf --- /dev/null +++ b/src/displayapp/screens/Weather.cpp @@ -0,0 +1,246 @@ +#include "Weather.h" +#include +#include "../DisplayApp.h" +#include "Label.h" +#include "Version.h" +#include "components/battery/BatteryController.h" +#include "components/ble/BleController.h" +#include "components/brightness/BrightnessController.h" +#include "components/datetime/DateTimeController.h" +#include "drivers/Watchdog.h" +#include "components/ble/weather/WeatherData.h" + +using namespace Pinetime::Applications::Screens; + +Weather::Weather(Pinetime::Applications::DisplayApp* app, + Pinetime::Controllers::DateTime& dateTimeController, + Pinetime::Controllers::Battery& batteryController, + Pinetime::Controllers::BrightnessController& brightnessController, + Pinetime::Controllers::Ble& bleController, + Pinetime::Drivers::WatchdogView& watchdog) + : Screen(app), + dateTimeController {dateTimeController}, + batteryController {batteryController}, + brightnessController {brightnessController}, + bleController {bleController}, + watchdog {watchdog}, + screens {app, + 0, + {[this]() -> std::unique_ptr { + return CreateScreen1(); + }, + [this]() -> std::unique_ptr { + return CreateScreen2(); + }, + [this]() -> std::unique_ptr { + return CreateScreen3(); + }, + [this]() -> std::unique_ptr { + return CreateScreen4(); + }, + [this]() -> std::unique_ptr { + return CreateScreen5(); + }}, + Screens::ScreenListModes::UpDown} { +} + +Weather::~Weather() { + lv_obj_clean(lv_scr_act()); +} + +bool Weather::Refresh() { + if (running) { + screens.Refresh(); + } + return running; +} + +bool Weather::OnButtonPushed() { + running = false; + return true; +} + +bool Weather::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + return screens.OnTouchEvent(event); +} + +std::unique_ptr Weather::CreateScreen1() { + lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_recolor(label, true); + lv_label_set_text_fmt(label, + "#FFFF00 InfiniTime#\n\n" + "#444444 Version# %ld.%ld.%ld\n\n" + "#444444 Build date#\n" + "%s\n" + "%s\n", + Version::Major(), + Version::Minor(), + Version::Patch(), + __DATE__, + __TIME__); + lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); + lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + return std::unique_ptr(new Screens::Label(0, 5, app, label)); +} + +std::unique_ptr Weather::CreateScreen2() { + auto batteryPercent = static_cast(batteryController.PercentRemaining()); + float batteryVoltage = batteryController.Voltage(); + + auto resetReason = [this]() { + switch (watchdog.ResetReason()) { + case Drivers::Watchdog::ResetReasons::Watchdog: + return "wtdg"; + case Drivers::Watchdog::ResetReasons::HardReset: + return "hardr"; + case Drivers::Watchdog::ResetReasons::NFC: + return "nfc"; + case Drivers::Watchdog::ResetReasons::SoftReset: + return "softr"; + case Drivers::Watchdog::ResetReasons::CpuLockup: + return "cpulock"; + case Drivers::Watchdog::ResetReasons::SystemOff: + return "off"; + case Drivers::Watchdog::ResetReasons::LpComp: + return "lpcomp"; + case Drivers::Watchdog::ResetReasons::DebugInterface: + return "dbg"; + case Drivers::Watchdog::ResetReasons::ResetPin: + return "rst"; + default: + return "?"; + } + }(); + + // uptime + static constexpr uint32_t secondsInADay = 60 * 60 * 24; + static constexpr uint32_t secondsInAnHour = 60 * 60; + static constexpr uint32_t secondsInAMinute = 60; + uint32_t uptimeSeconds = dateTimeController.Uptime().count(); + uint32_t uptimeDays = (uptimeSeconds / secondsInADay); + uptimeSeconds = uptimeSeconds % secondsInADay; + uint32_t uptimeHours = uptimeSeconds / secondsInAnHour; + uptimeSeconds = uptimeSeconds % secondsInAnHour; + uint32_t uptimeMinutes = uptimeSeconds / secondsInAMinute; + uptimeSeconds = uptimeSeconds % secondsInAMinute; + // TODO handle more than 100 days of uptime + + if (batteryPercent == -1) + batteryPercent = 0; + + // hack to not use the flot functions from printf + uint8_t batteryVoltageBytes[2]; + batteryVoltageBytes[1] = static_cast(batteryVoltage); // truncate whole numbers + batteryVoltageBytes[0] = + static_cast((batteryVoltage - batteryVoltageBytes[1]) * 100); // remove whole part of flt and shift 2 places over + // + + lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_recolor(label, true); + lv_label_set_text_fmt(label, + "#444444 Date# %02d/%02d/%04d\n" + "#444444 Time# %02d:%02d:%02d\n" + "#444444 Uptime#\n %02lud %02lu:%02lu:%02lu\n" + "#444444 Battery# %d%%/%1i.%02iv\n" + "#444444 Backlight# %s\n" + "#444444 Last reset# %s\n", + dateTimeController.Day(), + static_cast(dateTimeController.Month()), + dateTimeController.Year(), + dateTimeController.Hours(), + dateTimeController.Minutes(), + dateTimeController.Seconds(), + uptimeDays, + uptimeHours, + uptimeMinutes, + uptimeSeconds, + batteryPercent, + batteryVoltageBytes[1], + batteryVoltageBytes[0], + brightnessController.ToString(), + resetReason); + lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + return std::unique_ptr(new Screens::Label(1, 4, app, label)); +} + +std::unique_ptr Weather::CreateScreen3() { + lv_mem_monitor_t mon; + lv_mem_monitor(&mon); + + lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_recolor(label, true); + auto& bleAddr = bleController.Address(); + lv_label_set_text_fmt(label, + "#444444 BLE MAC#\n" + " %02x:%02x:%02x:%02x:%02x:%02x" + "\n" + "#444444 Memory#\n" + " #444444 used# %d (%d%%)\n" + " #444444 frag# %d%%\n" + " #444444 free# %d" + "\n" + "#444444 Steps# %li", + bleAddr[5], + bleAddr[4], + bleAddr[3], + bleAddr[2], + bleAddr[1], + bleAddr[0], + (int) mon.total_size - mon.free_size, + mon.used_pct, + mon.frag_pct, + (int) mon.free_biggest_size, + 0); + lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + return std::unique_ptr(new Screens::Label(2, 5, app, label)); +} + +bool sortById(const TaskStatus_t& lhs, const TaskStatus_t& rhs) { + return lhs.xTaskNumber < rhs.xTaskNumber; +} + +std::unique_ptr Weather::CreateScreen4() { + TaskStatus_t tasksStatus[7]; + lv_obj_t* infoTask = lv_table_create(lv_scr_act(), NULL); + lv_table_set_col_cnt(infoTask, 3); + lv_table_set_row_cnt(infoTask, 8); + lv_obj_set_pos(infoTask, 10, 10); + + lv_table_set_cell_value(infoTask, 0, 0, "#"); + lv_table_set_col_width(infoTask, 0, 50); + lv_table_set_cell_value(infoTask, 0, 1, "Task"); + lv_table_set_col_width(infoTask, 1, 80); + lv_table_set_cell_value(infoTask, 0, 2, "Free"); + lv_table_set_col_width(infoTask, 2, 90); + + auto nb = uxTaskGetSystemState(tasksStatus, 7, nullptr); + std::sort(tasksStatus, tasksStatus + nb, sortById); + for (uint8_t i = 0; i < nb; i++) { + + lv_table_set_cell_value(infoTask, i + 1, 0, std::to_string(tasksStatus[i].xTaskNumber).c_str()); + lv_table_set_cell_value(infoTask, i + 1, 1, tasksStatus[i].pcTaskName); + if (tasksStatus[i].usStackHighWaterMark < 20) { + std::string str1 = std::to_string(tasksStatus[i].usStackHighWaterMark) + " low"; + lv_table_set_cell_value(infoTask, i + 1, 2, str1.c_str()); + } else { + lv_table_set_cell_value(infoTask, i + 1, 2, std::to_string(tasksStatus[i].usStackHighWaterMark).c_str()); + } + } + return std::unique_ptr(new Screens::Label(3, 5, app, infoTask)); +} + +std::unique_ptr Weather::CreateScreen5() { + lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_recolor(label, true); + lv_label_set_text_static(label, + "Software Licensed\n" + "under the terms of\n" + "the GNU General\n" + "Public License v3\n" + "#444444 Source code#\n" + "#FFFF00 https://github.com/#\n" + "#FFFF00 JF002/InfiniTime#"); + lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); + lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + return std::unique_ptr(new Screens::Label(4, 5, app, label)); +} diff --git a/src/displayapp/screens/Weather.h b/src/displayapp/screens/Weather.h new file mode 100644 index 00000000..8b393ca1 --- /dev/null +++ b/src/displayapp/screens/Weather.h @@ -0,0 +1,54 @@ +#pragma once + +#include +#include "Screen.h" +#include "ScreenList.h" + +namespace Pinetime { + namespace Controllers { + class DateTime; + class Battery; + class BrightnessController; + class Ble; + } + + namespace Drivers { + class WatchdogView; + } + + namespace Applications { + class DisplayApp; + + namespace Screens { + class Weather : public Screen { + public: + explicit Weather(DisplayApp* app, + Pinetime::Controllers::DateTime& dateTimeController, + Pinetime::Controllers::Battery& batteryController, + Pinetime::Controllers::BrightnessController& brightnessController, + Pinetime::Controllers::Ble& bleController, + Pinetime::Drivers::WatchdogView& watchdog); + ~Weather() override; + bool Refresh() override; + bool OnButtonPushed() override; + bool OnTouchEvent(TouchEvents event) override; + + private: + bool running = true; + + Pinetime::Controllers::DateTime& dateTimeController; + Pinetime::Controllers::Battery& batteryController; + Pinetime::Controllers::BrightnessController& brightnessController; + Pinetime::Controllers::Ble& bleController; + Pinetime::Drivers::WatchdogView& watchdog; + + ScreenList<5> screens; + std::unique_ptr CreateScreen1(); + std::unique_ptr CreateScreen2(); + std::unique_ptr CreateScreen3(); + std::unique_ptr CreateScreen4(); + std::unique_ptr CreateScreen5(); + }; + } + } +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 6e165848161b72d1afa43af6807c654d3fc23d03 Mon Sep 17 00:00:00 2001 From: Avamander Date: Wed, 16 Jun 2021 23:31:17 +0300 Subject: Skeleton of the receiving logic --- src/components/ble/weather/WeatherData.h | 37 ++++--- src/components/ble/weather/WeatherService.cpp | 139 +++++++++++++++++++------- src/components/ble/weather/WeatherService.h | 45 ++++----- 3 files changed, 145 insertions(+), 76 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherData.h b/src/components/ble/weather/WeatherData.h index c1d53f4e..7cf68418 100644 --- a/src/components/ble/weather/WeatherData.h +++ b/src/components/ble/weather/WeatherData.h @@ -39,7 +39,7 @@ namespace Pinetime { None = 0, /** Water particles suspended in the air; low visibility; does not fall */ Fog = 1, - /** Extremely small, dry particles in the air; invisible to the eye; opalescent */ + /** Tiny, dry particles in the air; invisible to the eye; opalescent */ Haze = 2, /** Small fire-created particles suspended in the air */ Smoke = 3, @@ -51,6 +51,7 @@ namespace Pinetime { Sand = 6, /** Water particles suspended in the air; low-ish visibility; temperature is near dewpoint */ Mist = 7, + Length }; /** @@ -82,7 +83,8 @@ namespace Pinetime { /** Frozen drizzle; very small snow crystals */ SnowGrains = 8, /** Needles; columns or plates of ice. Sometimes described as "diamond dust". In very cold regions */ - IceCrystals = 9 + IceCrystals = 9, + Length }; /** @@ -99,6 +101,7 @@ namespace Pinetime { Fire = 3, /** Thunder and/or lightning */ Thunder = 4, + Length }; /** @@ -111,7 +114,8 @@ namespace Pinetime { /** This wipes the entire timeline */ DelTimeline = 1, /** There's a currently valid timeline event with the given type */ - HasValidEvent = 3 + HasValidEvent = 3, + Length }; /** @@ -137,19 +141,20 @@ namespace Pinetime { Location = 7, /** @see cloud */ Clouds = 8, + Length }; /** * Valid event query */ - class valideventquery { + class ValidEventQuery { public: static constexpr controlcodes code = controlcodes::HasValidEvent; eventtype eventType; }; /** The header used for further parsing */ - class timelineheader { + class TimelineHeader { public: /** UNIX timestamp */ uint64_t timestamp; @@ -168,23 +173,23 @@ namespace Pinetime { }; /** Specifies how cloudiness is stored */ - class clouds : public timelineheader { + class Clouds : public TimelineHeader { public: /** Cloud coverage in percentage, 0-100% */ uint8_t amount; }; /** Specifies how obscuration is stored */ - class obscuration : public timelineheader { + class Obscuration : public TimelineHeader { public: /** Type */ obscurationtype type; /** Visibility distance in meters */ - uint8_t amount; + uint16_t amount; }; /** Specifies how precipitation is stored */ - class precipitation : public timelineheader { + class Precipitation : public TimelineHeader { public: /** Type */ precipitationtype type; @@ -201,7 +206,7 @@ namespace Pinetime { * As direction can fluctuate wildly and some watchfaces might wish to display it nicely, * we're following the aerospace industry weather report option of specifying a range. */ - class wind : public timelineheader { + class Wind : public TimelineHeader { public: /** Meters per second */ uint8_t speedMin; @@ -221,7 +226,7 @@ namespace Pinetime { * * We don't do floats, microdegrees are not useful. Make sure to multiply. */ - class temperature : public timelineheader { + class Temperature : public TimelineHeader { public: /** Temperature °C but multiplied by 100 (e.g. -12.50°C becomes -1250) */ int16_t temperature; @@ -240,7 +245,7 @@ namespace Pinetime { * or daylight calculations, should those be required. * */ - class location : public timelineheader { + class Location : public TimelineHeader { public: /** Location name */ std::string location; @@ -255,7 +260,7 @@ namespace Pinetime { /** * How humidity is stored */ - class humidity : public timelineheader { + class Humidity : public TimelineHeader { public: /** Relative humidity, 0-100% */ uint8_t humidity; @@ -264,7 +269,7 @@ namespace Pinetime { /** * How air pressure is stored */ - class pressure : public timelineheader { + class Pressure : public TimelineHeader { public: /** Air pressure in hectopascals (hPa) */ int16_t pressure; @@ -273,7 +278,7 @@ namespace Pinetime { /** * How special events are stored */ - class special : public timelineheader { + class Special : public TimelineHeader { public: /** Special event's type */ specialtype type; @@ -288,7 +293,7 @@ namespace Pinetime { * * If this needs further enforced standardization, pull requests are welcome */ - class airquality : public timelineheader { + class AirQuality : public TimelineHeader { public: /** * The name of the pollution diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index 006fc6c1..60e608e7 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -40,58 +40,125 @@ namespace Pinetime { } int WeatherService::OnCommand(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt) { + // TODO: Detect control messages if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - getCurrentPressure(); - tidyTimeline(); - getTimelineLength(); const auto packetLen = OS_MBUF_PKTLEN(ctxt->om); if (packetLen <= 0) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } // Decode QCBORDecodeContext decodeContext; - UsefulBufC EncodedCBOR; - // TODO: Check uninit fine - QCBORDecode_Init(&decodeContext, EncodedCBOR, QCBOR_DECODE_MODE_NORMAL); + UsefulBufC encodedCbor; + // TODO: Check, uninit fine? + + QCBORDecode_Init(&decodeContext, encodedCbor, QCBOR_DECODE_MODE_NORMAL); QCBORDecode_EnterMap(&decodeContext, nullptr); - WeatherData::timelineheader timelineHeader {}; // Always encodes to the smallest number of bytes based on the value - QCBORDecode_GetInt64InMapSZ(&decodeContext, "Timestamp", reinterpret_cast(&(timelineHeader.timestamp))); - QCBORDecode_GetInt64InMapSZ(&decodeContext, "Expires", reinterpret_cast(&(timelineHeader.expires))); - QCBORDecode_GetInt64InMapSZ(&decodeContext, "EventType", reinterpret_cast(&(timelineHeader.eventType))); - switch (timelineHeader.eventType) { - // TODO: Populate + int64_t tmpVersion = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Version", &tmpVersion); + if (tmpVersion != 1) { + // TODO: Return better error? + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + int64_t tmpTimestamp = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Timestamp", &tmpTimestamp); + int64_t tmpExpires = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Expires", &tmpExpires); + if (tmpExpires > 4294967295) { + // TODO: Return better error? + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + int64_t tmpEventType = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "EventType", &tmpEventType); + if (tmpEventType > static_cast(WeatherData::eventtype::Length)) { + // TODO: Return better error? + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + + switch (static_cast(tmpEventType)) { + // TODO: Populate case WeatherData::eventtype::AirQuality: { + std::unique_ptr airquality = std::make_unique(); + airquality->timestamp = tmpTimestamp; + airquality->eventType = static_cast(tmpEventType); + airquality->expires = tmpExpires; + + timeline.push_back(std::move(airquality)); break; } case WeatherData::eventtype::Obscuration: { + std::unique_ptr obscuration = std::make_unique(); + obscuration->timestamp = tmpTimestamp; + obscuration->eventType = static_cast(tmpEventType); + obscuration->expires = tmpExpires; + + timeline.push_back(std::move(obscuration)); break; } case WeatherData::eventtype::Precipitation: { + std::unique_ptr precipitation = std::make_unique(); + precipitation->timestamp = tmpTimestamp; + precipitation->eventType = static_cast(tmpEventType); + precipitation->expires = tmpExpires; + timeline.push_back(std::move(precipitation)); break; } case WeatherData::eventtype::Wind: { + std::unique_ptr wind = std::make_unique(); + wind->timestamp = tmpTimestamp; + wind->eventType = static_cast(tmpEventType); + wind->expires = tmpExpires; + timeline.push_back(std::move(wind)); break; } case WeatherData::eventtype::Temperature: { + std::unique_ptr temperature = std::make_unique(); + temperature->timestamp = tmpTimestamp; + temperature->eventType = static_cast(tmpEventType); + temperature->expires = tmpExpires; + timeline.push_back(std::move(temperature)); break; } case WeatherData::eventtype::Special: { + std::unique_ptr special = std::make_unique(); + special->timestamp = tmpTimestamp; + special->eventType = static_cast(tmpEventType); + special->expires = tmpExpires; + timeline.push_back(std::move(special)); break; } case WeatherData::eventtype::Pressure: { + std::unique_ptr pressure = std::make_unique(); + pressure->timestamp = tmpTimestamp; + pressure->eventType = static_cast(tmpEventType); + pressure->expires = tmpExpires; + timeline.push_back(std::move(pressure)); break; } case WeatherData::eventtype::Location: { + std::unique_ptr location = std::make_unique(); + location->timestamp = tmpTimestamp; + location->eventType = static_cast(tmpEventType); + location->expires = tmpExpires; + timeline.push_back(std::move(location)); break; } case WeatherData::eventtype::Clouds: { + std::unique_ptr clouds = std::make_unique(); + clouds->timestamp = tmpTimestamp; + clouds->eventType = static_cast(tmpEventType); + clouds->expires = tmpExpires; + timeline.push_back(std::move(clouds)); break; } default: { break; } } + + getCurrentPressure(); + tidyTimeline(); + getTimelineLength(); QCBORDecode_ExitMap(&decodeContext); auto uErr = QCBORDecode_Finish(&decodeContext); @@ -99,8 +166,6 @@ namespace Pinetime { return BLE_ATT_ERR_INSUFFICIENT_RES; } } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { - // TODO: Detect control messages - // Encode uint8_t buffer[64]; QCBOREncodeContext encodeContext; @@ -125,46 +190,46 @@ namespace Pinetime { return 0; } - WeatherData::location WeatherService::getCurrentLocation() const { - return WeatherData::location(); + WeatherData::Location WeatherService::getCurrentLocation() const { + return WeatherData::Location(); } - WeatherData::clouds WeatherService::getCurrentClouds() const { - return WeatherData::clouds(); + WeatherData::Clouds WeatherService::getCurrentClouds() const { + return WeatherData::Clouds(); } - WeatherData::obscuration WeatherService::getCurrentObscuration() const { - return WeatherData::obscuration(); + WeatherData::Obscuration WeatherService::getCurrentObscuration() const { + return WeatherData::Obscuration(); } - WeatherData::precipitation WeatherService::getCurrentPrecipitation() const { - return WeatherData::precipitation(); + WeatherData::Precipitation WeatherService::getCurrentPrecipitation() const { + return WeatherData::Precipitation(); } - WeatherData::wind WeatherService::getCurrentWind() const { - return WeatherData::wind(); + WeatherData::Wind WeatherService::getCurrentWind() const { + return WeatherData::Wind(); } - WeatherData::temperature WeatherService::getCurrentTemperature() const { - return WeatherData::temperature(); + WeatherData::Temperature WeatherService::getCurrentTemperature() const { + return WeatherData::Temperature(); } - WeatherData::humidity WeatherService::getCurrentHumidity() const { - return WeatherData::humidity(); + WeatherData::Humidity WeatherService::getCurrentHumidity() const { + return WeatherData::Humidity(); } - WeatherData::pressure WeatherService::getCurrentPressure() const { + WeatherData::Pressure WeatherService::getCurrentPressure() const { uint64_t currentTimestamp = getCurrentUNIXTimestamp(); for (auto&& header : timeline) { if (header->eventType == WeatherData::eventtype::Pressure && header->timestamp + header->expires <= currentTimestamp) { - return WeatherData::pressure(); + return WeatherData::Pressure(); } } - return WeatherData::pressure(); + return WeatherData::Pressure(); } - WeatherData::airquality WeatherService::getCurrentQuality() const { - return WeatherData::airquality(); + WeatherData::AirQuality WeatherService::getCurrentQuality() const { + return WeatherData::AirQuality(); } size_t WeatherService::getTimelineLength() const { return timeline.size(); } - bool WeatherService::addEventToTimeline(std::unique_ptr event) { + bool WeatherService::addEventToTimeline(std::unique_ptr event) { if (timeline.size() == timeline.max_size()) { return false; } @@ -188,7 +253,7 @@ namespace Pinetime { uint64_t timeCurrent = 0; timeline.erase(std::remove_if(std::begin(timeline), std::end(timeline), - [&](std::unique_ptr const& header) { + [&](std::unique_ptr const& header) { return header->timestamp + header->expires > timeCurrent; }), std::end(timeline)); @@ -196,8 +261,8 @@ namespace Pinetime { std::sort(std::begin(timeline), std::end(timeline), compareTimelineEvents); } - bool WeatherService::compareTimelineEvents(const std::unique_ptr& first, - const std::unique_ptr& second) { + bool WeatherService::compareTimelineEvents(const std::unique_ptr& first, + const std::unique_ptr& second) { return first->timestamp > second->timestamp; } diff --git a/src/components/ble/weather/WeatherService.h b/src/components/ble/weather/WeatherService.h index ef99db86..64a8213a 100644 --- a/src/components/ble/weather/WeatherService.h +++ b/src/components/ble/weather/WeatherService.h @@ -57,15 +57,15 @@ namespace Pinetime { /* * Helper functions for quick access to currently valid data */ - WeatherData::location getCurrentLocation() const; - WeatherData::clouds getCurrentClouds() const; - WeatherData::obscuration getCurrentObscuration() const; - WeatherData::precipitation getCurrentPrecipitation() const; - WeatherData::wind getCurrentWind() const; - WeatherData::temperature getCurrentTemperature() const; - WeatherData::humidity getCurrentHumidity() const; - WeatherData::pressure getCurrentPressure() const; - WeatherData::airquality getCurrentQuality() const; + WeatherData::Location getCurrentLocation() const; + WeatherData::Clouds getCurrentClouds() const; + WeatherData::Obscuration getCurrentObscuration() const; + WeatherData::Precipitation getCurrentPrecipitation() const; + WeatherData::Wind getCurrentWind() const; + WeatherData::Temperature getCurrentTemperature() const; + WeatherData::Humidity getCurrentHumidity() const; + WeatherData::Pressure getCurrentPressure() const; + WeatherData::AirQuality getCurrentQuality() const; /* * Management functions @@ -74,7 +74,7 @@ namespace Pinetime { * Adds an event to the timeline * @return */ - bool addEventToTimeline(std::unique_ptr event); + bool addEventToTimeline(std::unique_ptr event); /** * Gets the current timeline length */ @@ -86,37 +86,36 @@ namespace Pinetime { bool hasTimelineEventOfType(WeatherData::eventtype type) const; private: - ble_uuid128_t msUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = WEATHER_SERVICE_UUID_BASE}; + ble_uuid128_t weatherUUID {.u = {.type = BLE_UUID_TYPE_128}, .value = WEATHER_SERVICE_UUID_BASE}; /** * Just write timeline data here */ - ble_uuid128_t wDataCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = WEATHER_SERVICE_CHAR_UUID(0x00, 0x01)}; + ble_uuid128_t weatherDataCharUUID {.u = {.type = BLE_UUID_TYPE_128}, .value = WEATHER_SERVICE_CHAR_UUID(0x00, 0x01)}; /** - * This doesn't take timeline data - * but provides some control over it + * This doesn't take timeline data, + * provides some control over it */ - ble_uuid128_t wControlCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = WEATHER_SERVICE_CHAR_UUID(0x00, 0x02)}; + ble_uuid128_t weatherControlCharUUID {.u = {.type = BLE_UUID_TYPE_128}, .value = WEATHER_SERVICE_CHAR_UUID(0x00, 0x02)}; - const struct ble_gatt_chr_def characteristicDefinition[2] = {{.uuid = reinterpret_cast(&wDataCharUuid), + const struct ble_gatt_chr_def characteristicDefinition[2] = {{.uuid = &weatherDataCharUUID.u, .access_cb = WeatherCallback, .arg = this, .flags = BLE_GATT_CHR_F_NOTIFY, .val_handle = &eventHandle}, - {.uuid = reinterpret_cast(&wControlCharUuid), + {.uuid = &weatherControlCharUUID.u, .access_cb = WeatherCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ}}; const struct ble_gatt_svc_def serviceDefinition[2] = { - {.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = reinterpret_cast(&msUuid), .characteristics = characteristicDefinition}, - {0}}; + {.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &weatherUUID.u, .characteristics = characteristicDefinition}, {0}}; uint16_t eventHandle {}; Pinetime::System::SystemTask& system; Pinetime::Controllers::DateTime& dateTimeController; - std::vector> timeline; + std::vector> timeline; /** * Cleans up the timeline of expired events @@ -127,11 +126,11 @@ namespace Pinetime { /** * Compares two timeline events */ - static bool compareTimelineEvents(const std::unique_ptr& first, - const std::unique_ptr& second); + static bool compareTimelineEvents(const std::unique_ptr& first, + const std::unique_ptr& second); /** - * + * Returns current UNIX timestamp */ uint64_t getCurrentUNIXTimestamp() const; }; -- cgit v1.2.3-70-g09d2 From 4349657f799bed04538d95c8d54653586100e82e Mon Sep 17 00:00:00 2001 From: Avamander Date: Wed, 16 Jun 2021 23:31:40 +0300 Subject: Minor style improvement --- src/components/ble/AlertNotificationService.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/components/ble') diff --git a/src/components/ble/AlertNotificationService.cpp b/src/components/ble/AlertNotificationService.cpp index f616cce8..04819122 100644 --- a/src/components/ble/AlertNotificationService.cpp +++ b/src/components/ble/AlertNotificationService.cpp @@ -53,8 +53,9 @@ int AlertNotificationService::OnAlert(uint16_t conn_handle, uint16_t attr_handle // Ignore notifications with empty message const auto packetLen = OS_MBUF_PKTLEN(ctxt->om); - if (packetLen <= headerSize) + if (packetLen <= headerSize) { return 0; + } size_t bufferSize = std::min(packetLen + stringTerminatorSize, maxBufferSize); auto messageSize = std::min(maxMessageSize, (bufferSize - headerSize)); -- cgit v1.2.3-70-g09d2 From 4b2dcbb4f053a89faab50c03083c71fabf9f288a Mon Sep 17 00:00:00 2001 From: Avamander Date: Sun, 20 Jun 2021 21:37:53 +0300 Subject: Fixed a few bugs, enabled UsefulBuf library optimizations --- src/CMakeLists.txt | 1 + src/components/ble/NimbleController.h | 3 ++ src/components/ble/weather/WeatherData.h | 4 +-- src/components/ble/weather/WeatherService.cpp | 19 +++++++++--- src/components/ble/weather/WeatherService.h | 42 +++++++++++++++------------ 5 files changed, 44 insertions(+), 25 deletions(-) (limited to 'src/components/ble') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fb5e1d1e..4273becf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -860,6 +860,7 @@ target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_EXP_AND_MANTISSA) target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS) target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS) target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_UNCOMMON_TAGS) +target_compile_definitions(QCBOR PUBLIC USEFULBUF_CONFIG_LITTLE_ENDIAN) set_target_properties(QCBOR PROPERTIES LINKER_LANGUAGE C) target_compile_options(QCBOR PRIVATE $<$,$>: ${COMMON_FLAGS} -O0 -g3> diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index a21cbe81..34f00e4e 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -71,6 +71,9 @@ namespace Pinetime { Pinetime::Controllers::AlertNotificationService& alertService() { return anService; }; + Pinetime::Controllers::WeatherService& weather() { + return weatherService; + }; uint16_t connHandle(); void NotifyBatteryLevel(uint8_t level); diff --git a/src/components/ble/weather/WeatherData.h b/src/components/ble/weather/WeatherData.h index 7cf68418..ee2a364d 100644 --- a/src/components/ble/weather/WeatherData.h +++ b/src/components/ble/weather/WeatherData.h @@ -248,7 +248,7 @@ namespace Pinetime { class Location : public TimelineHeader { public: /** Location name */ - std::string location; + std::unique_ptr location; /** Altitude relative to sea level in meters */ int16_t altitude; /** Latitude, EPSG:3857 (Google Maps, Openstreetmaps datum) */ @@ -309,7 +309,7 @@ namespace Pinetime { * For chemical compounds use the molecular formula e.g. "NO2", "CO2", "O3" * For pollen use the genus, e.g. "Betula" for birch or "Alternaria" for that mold's spores */ - std::string polluter; + std::unique_ptr polluter; /** * Amount of the pollution in SI units, * otherwise it's going to be difficult to create UI, alerts diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index 60e608e7..30d274b2 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -33,7 +33,7 @@ namespace Pinetime { void WeatherService::Init() { uint8_t res = 0; res = ble_gatts_count_cfg(serviceDefinition); - ASSERT(res == 0) + ASSERT(res == 0); res = ble_gatts_add_svcs(serviceDefinition); ASSERT(res == 0); @@ -64,13 +64,13 @@ namespace Pinetime { QCBORDecode_GetInt64InMapSZ(&decodeContext, "Timestamp", &tmpTimestamp); int64_t tmpExpires = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Expires", &tmpExpires); - if (tmpExpires > 4294967295) { + if (tmpExpires < 0 || tmpExpires > 4294967295) { // TODO: Return better error? return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } int64_t tmpEventType = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "EventType", &tmpEventType); - if (tmpEventType > static_cast(WeatherData::eventtype::Length)) { + if (tmpEventType < 0 || tmpEventType > static_cast(WeatherData::eventtype::Length)) { // TODO: Return better error? return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } @@ -82,7 +82,18 @@ namespace Pinetime { airquality->timestamp = tmpTimestamp; airquality->eventType = static_cast(tmpEventType); airquality->expires = tmpExpires; - + UsefulBufC String; + QCBORDecode_GetTextStringInMapSZ(&decodeContext, "Polluter", &String); + if (UsefulBuf_IsNULLOrEmptyC(String) != 0) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + airquality->polluter = std::make_unique(static_cast(String.ptr), String.len); + int64_t tmpAmount = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Amount", &tmpAmount); + if (tmpAmount < 0 || tmpAmount > 4294967295) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + airquality->amount = tmpAmount; timeline.push_back(std::move(airquality)); break; } diff --git a/src/components/ble/weather/WeatherService.h b/src/components/ble/weather/WeatherService.h index 64a8213a..43002dc1 100644 --- a/src/components/ble/weather/WeatherService.h +++ b/src/components/ble/weather/WeatherService.h @@ -32,12 +32,6 @@ #include "WeatherData.h" #include -// 00030000-78fc-48fe-8e23-433b3a1942d0 -#define WEATHER_SERVICE_UUID_BASE \ - { 0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, 0x00, 0x00, 0x03, 0x00 } -#define WEATHER_SERVICE_CHAR_UUID(y, x) \ - { 0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, (x), (y), 0x03, 0x00 } - int WeatherCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg); namespace Pinetime { @@ -86,27 +80,37 @@ namespace Pinetime { bool hasTimelineEventOfType(WeatherData::eventtype type) const; private: - ble_uuid128_t weatherUUID {.u = {.type = BLE_UUID_TYPE_128}, .value = WEATHER_SERVICE_UUID_BASE}; + // 00030000-78fc-48fe-8e23-433b3a1942d0 + static constexpr ble_uuid128_t BaseUUID() { + return CharUUID(0x00, 0x00); + } + + // 0003yyxx-78fc-48fe-8e23-433b3a1942d0 + static constexpr ble_uuid128_t CharUUID(uint8_t x, uint8_t y) { + return ble_uuid128_t {.u = {.type = BLE_UUID_TYPE_128}, + .value = {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, x, y, 0x03, 0x00}}; + } + + ble_uuid128_t weatherUUID {BaseUUID()}; /** * Just write timeline data here */ - ble_uuid128_t weatherDataCharUUID {.u = {.type = BLE_UUID_TYPE_128}, .value = WEATHER_SERVICE_CHAR_UUID(0x00, 0x01)}; + ble_uuid128_t weatherDataCharUUID {CharUUID(0x00, 0x01)}; /** * This doesn't take timeline data, * provides some control over it */ - ble_uuid128_t weatherControlCharUUID {.u = {.type = BLE_UUID_TYPE_128}, .value = WEATHER_SERVICE_CHAR_UUID(0x00, 0x02)}; - - const struct ble_gatt_chr_def characteristicDefinition[2] = {{.uuid = &weatherDataCharUUID.u, - .access_cb = WeatherCallback, - .arg = this, - .flags = BLE_GATT_CHR_F_NOTIFY, - .val_handle = &eventHandle}, - {.uuid = &weatherControlCharUUID.u, - .access_cb = WeatherCallback, - .arg = this, - .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ}}; + ble_uuid128_t weatherControlCharUUID {CharUUID(0x00, 0x02)}; + + const struct ble_gatt_chr_def characteristicDefinition[3] = { + {.uuid = &weatherDataCharUUID.u, + .access_cb = WeatherCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE, + .val_handle = &eventHandle}, + {.uuid = &weatherControlCharUUID.u, .access_cb = WeatherCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ}, + {nullptr}}; const struct ble_gatt_svc_def serviceDefinition[2] = { {.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &weatherUUID.u, .characteristics = characteristicDefinition}, {0}}; -- cgit v1.2.3-70-g09d2 From 3a09b3614c19fda8f90af28b596a6359064ad0fb Mon Sep 17 00:00:00 2001 From: Avamander Date: Fri, 25 Jun 2021 00:43:30 +0300 Subject: Brace style and whitespace fixes --- src/CMakeLists.txt | 2 +- src/components/ble/weather/WeatherService.cpp | 2 +- src/components/ble/weather/WeatherService.h | 2 +- src/displayapp/screens/SystemInfo.cpp | 2 +- src/displayapp/screens/Weather.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/components/ble') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4273becf..d83c467a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1153,4 +1153,4 @@ elseif (USE_OPENOCD) COMMENT "flashing ${EXECUTABLE_FILE_NAME}.hex" ) endif () -endif () +endif () \ No newline at end of file diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index 30d274b2..ae7370b5 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -281,4 +281,4 @@ namespace Pinetime { return std::chrono::duration_cast(dateTimeController.CurrentDateTime().time_since_epoch()).count(); } } -} +} \ No newline at end of file diff --git a/src/components/ble/weather/WeatherService.h b/src/components/ble/weather/WeatherService.h index 43002dc1..53dbebfb 100644 --- a/src/components/ble/weather/WeatherService.h +++ b/src/components/ble/weather/WeatherService.h @@ -139,4 +139,4 @@ namespace Pinetime { uint64_t getCurrentUNIXTimestamp() const; }; } -} +} \ No newline at end of file diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index c363e2dd..07626260 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -274,4 +274,4 @@ std::unique_ptr SystemInfo::CreateScreen5() { lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); return std::make_unique(4, 5, app, label); -} +} \ No newline at end of file diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp index 014761bf..0ba53bea 100644 --- a/src/displayapp/screens/Weather.cpp +++ b/src/displayapp/screens/Weather.cpp @@ -243,4 +243,4 @@ std::unique_ptr Weather::CreateScreen5() { lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); return std::unique_ptr(new Screens::Label(4, 5, app, label)); -} +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 19c9667a3d597167241ebcb4dfefb4e0cac068df Mon Sep 17 00:00:00 2001 From: Avamander Date: Fri, 25 Jun 2021 01:18:56 +0300 Subject: Started initial work on the UI --- src/components/ble/weather/WeatherService.cpp | 55 ++++++----- src/components/ble/weather/WeatherService.h | 34 +++---- src/displayapp/screens/Weather.cpp | 133 ++++---------------------- src/displayapp/screens/Weather.h | 35 +++---- 4 files changed, 80 insertions(+), 177 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index ae7370b5..7d20867d 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -20,8 +20,8 @@ #include "libs/QCBOR/inc/qcbor/qcbor.h" #include "systemtask/SystemTask.h" -int WeatherCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) { - return static_cast(arg)->OnCommand(conn_handle, attr_handle, ctxt); +int WeatherCallback(uint16_t connHandle, uint16_t attrHandle, struct ble_gatt_access_ctxt* ctxt, void* arg) { + return static_cast(arg)->OnCommand(connHandle, attrHandle, ctxt); } namespace Pinetime { @@ -39,7 +39,7 @@ namespace Pinetime { ASSERT(res == 0); } - int WeatherService::OnCommand(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt) { + int WeatherService::OnCommand(uint16_t connHandle, uint16_t attrHandle, struct ble_gatt_access_ctxt* ctxt) { // TODO: Detect control messages if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { const auto packetLen = OS_MBUF_PKTLEN(ctxt->om); @@ -167,9 +167,9 @@ namespace Pinetime { } } - getCurrentPressure(); - tidyTimeline(); - getTimelineLength(); + GetCurrentPressure(); + TidyTimeline(); + GetTimelineLength(); QCBORDecode_ExitMap(&decodeContext); auto uErr = QCBORDecode_Finish(&decodeContext); @@ -201,29 +201,36 @@ namespace Pinetime { return 0; } - WeatherData::Location WeatherService::getCurrentLocation() const { + WeatherData::Location WeatherService::GetCurrentLocation() const { return WeatherData::Location(); } - WeatherData::Clouds WeatherService::getCurrentClouds() const { + + WeatherData::Clouds WeatherService::GetCurrentClouds() const { return WeatherData::Clouds(); } - WeatherData::Obscuration WeatherService::getCurrentObscuration() const { + + WeatherData::Obscuration WeatherService::GetCurrentObscuration() const { return WeatherData::Obscuration(); } - WeatherData::Precipitation WeatherService::getCurrentPrecipitation() const { + + WeatherData::Precipitation WeatherService::GetCurrentPrecipitation() const { return WeatherData::Precipitation(); } - WeatherData::Wind WeatherService::getCurrentWind() const { + + WeatherData::Wind WeatherService::GetCurrentWind() const { return WeatherData::Wind(); } - WeatherData::Temperature WeatherService::getCurrentTemperature() const { + + WeatherData::Temperature WeatherService::GetCurrentTemperature() const { return WeatherData::Temperature(); } - WeatherData::Humidity WeatherService::getCurrentHumidity() const { + + WeatherData::Humidity WeatherService::GetCurrentHumidity() const { return WeatherData::Humidity(); } - WeatherData::Pressure WeatherService::getCurrentPressure() const { - uint64_t currentTimestamp = getCurrentUNIXTimestamp(); + + WeatherData::Pressure WeatherService::GetCurrentPressure() const { + uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : timeline) { if (header->eventType == WeatherData::eventtype::Pressure && header->timestamp + header->expires <= currentTimestamp) { return WeatherData::Pressure(); @@ -232,15 +239,15 @@ namespace Pinetime { return WeatherData::Pressure(); } - WeatherData::AirQuality WeatherService::getCurrentQuality() const { + WeatherData::AirQuality WeatherService::GetCurrentQuality() const { return WeatherData::AirQuality(); } - size_t WeatherService::getTimelineLength() const { + size_t WeatherService::GetTimelineLength() const { return timeline.size(); } - bool WeatherService::addEventToTimeline(std::unique_ptr event) { + bool WeatherService::AddEventToTimeline(std::unique_ptr event) { if (timeline.size() == timeline.max_size()) { return false; } @@ -249,8 +256,8 @@ namespace Pinetime { return true; } - bool WeatherService::hasTimelineEventOfType(const WeatherData::eventtype type) const { - uint64_t currentTimestamp = getCurrentUNIXTimestamp(); + bool WeatherService::HasTimelineEventOfType(const WeatherData::eventtype type) const { + uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : timeline) { if (header->eventType == type && header->timestamp + header->expires <= currentTimestamp) { // TODO: Check if its currently valid @@ -260,7 +267,7 @@ namespace Pinetime { return false; } - void WeatherService::tidyTimeline() { + void WeatherService::TidyTimeline() { uint64_t timeCurrent = 0; timeline.erase(std::remove_if(std::begin(timeline), std::end(timeline), @@ -269,15 +276,15 @@ namespace Pinetime { }), std::end(timeline)); - std::sort(std::begin(timeline), std::end(timeline), compareTimelineEvents); + std::sort(std::begin(timeline), std::end(timeline), CompareTimelineEvents); } - bool WeatherService::compareTimelineEvents(const std::unique_ptr& first, + bool WeatherService::CompareTimelineEvents(const std::unique_ptr& first, const std::unique_ptr& second) { return first->timestamp > second->timestamp; } - uint64_t WeatherService::getCurrentUNIXTimestamp() const { + uint64_t WeatherService::GetCurrentUnixTimestamp() const { return std::chrono::duration_cast(dateTimeController.CurrentDateTime().time_since_epoch()).count(); } } diff --git a/src/components/ble/weather/WeatherService.h b/src/components/ble/weather/WeatherService.h index 53dbebfb..786d4715 100644 --- a/src/components/ble/weather/WeatherService.h +++ b/src/components/ble/weather/WeatherService.h @@ -32,7 +32,7 @@ #include "WeatherData.h" #include -int WeatherCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg); +int WeatherCallback(uint16_t connHandle, uint16_t attrHandle, struct ble_gatt_access_ctxt* ctxt, void* arg); namespace Pinetime { namespace System { @@ -46,20 +46,20 @@ namespace Pinetime { void Init(); - int OnCommand(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt); + int OnCommand(uint16_t connHandle, uint16_t attrHandle, struct ble_gatt_access_ctxt* ctxt); /* * Helper functions for quick access to currently valid data */ - WeatherData::Location getCurrentLocation() const; - WeatherData::Clouds getCurrentClouds() const; - WeatherData::Obscuration getCurrentObscuration() const; - WeatherData::Precipitation getCurrentPrecipitation() const; - WeatherData::Wind getCurrentWind() const; - WeatherData::Temperature getCurrentTemperature() const; - WeatherData::Humidity getCurrentHumidity() const; - WeatherData::Pressure getCurrentPressure() const; - WeatherData::AirQuality getCurrentQuality() const; + WeatherData::Location GetCurrentLocation() const; + WeatherData::Clouds GetCurrentClouds() const; + WeatherData::Obscuration GetCurrentObscuration() const; + WeatherData::Precipitation GetCurrentPrecipitation() const; + WeatherData::Wind GetCurrentWind() const; + WeatherData::Temperature GetCurrentTemperature() const; + WeatherData::Humidity GetCurrentHumidity() const; + WeatherData::Pressure GetCurrentPressure() const; + WeatherData::AirQuality GetCurrentQuality() const; /* * Management functions @@ -68,16 +68,16 @@ namespace Pinetime { * Adds an event to the timeline * @return */ - bool addEventToTimeline(std::unique_ptr event); + bool AddEventToTimeline(std::unique_ptr event); /** * Gets the current timeline length */ - size_t getTimelineLength() const; + size_t GetTimelineLength() const; /** * Checks if an event of a certain type exists in the timeline * @return */ - bool hasTimelineEventOfType(WeatherData::eventtype type) const; + bool HasTimelineEventOfType(const WeatherData::eventtype type) const; private: // 00030000-78fc-48fe-8e23-433b3a1942d0 @@ -125,18 +125,18 @@ namespace Pinetime { * Cleans up the timeline of expired events * @return result code */ - void tidyTimeline(); + void TidyTimeline(); /** * Compares two timeline events */ - static bool compareTimelineEvents(const std::unique_ptr& first, + static bool CompareTimelineEvents(const std::unique_ptr& first, const std::unique_ptr& second); /** * Returns current UNIX timestamp */ - uint64_t getCurrentUNIXTimestamp() const; + uint64_t GetCurrentUnixTimestamp() const; }; } } \ No newline at end of file diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp index 0ba53bea..a1278649 100644 --- a/src/displayapp/screens/Weather.cpp +++ b/src/displayapp/screens/Weather.cpp @@ -1,5 +1,6 @@ #include "Weather.h" #include +#include #include "../DisplayApp.h" #include "Label.h" #include "Version.h" @@ -12,22 +13,14 @@ using namespace Pinetime::Applications::Screens; -Weather::Weather(Pinetime::Applications::DisplayApp* app, - Pinetime::Controllers::DateTime& dateTimeController, - Pinetime::Controllers::Battery& batteryController, - Pinetime::Controllers::BrightnessController& brightnessController, - Pinetime::Controllers::Ble& bleController, - Pinetime::Drivers::WatchdogView& watchdog) +Weather::Weather(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::WeatherService& weather) : Screen(app), dateTimeController {dateTimeController}, - batteryController {batteryController}, - brightnessController {brightnessController}, - bleController {bleController}, - watchdog {watchdog}, + weatherService(weather), screens {app, 0, {[this]() -> std::unique_ptr { - return CreateScreen1(); + return CreateScreenTemperature(); }, [this]() -> std::unique_ptr { return CreateScreen2(); @@ -64,101 +57,30 @@ bool Weather::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return screens.OnTouchEvent(event); } -std::unique_ptr Weather::CreateScreen1() { +std::unique_ptr Weather::CreateScreenTemperature() { lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); lv_label_set_recolor(label, true); + Controllers::WeatherData::Temperature current = weatherService.GetCurrentTemperature(); lv_label_set_text_fmt(label, - "#FFFF00 InfiniTime#\n\n" - "#444444 Version# %ld.%ld.%ld\n\n" - "#444444 Build date#\n" - "%s\n" - "%s\n", - Version::Major(), - Version::Minor(), - Version::Patch(), - __DATE__, - __TIME__); + "#FFFF00 Temperature#\n\n" + "#444444 %hd%%#°C \n\n" + "#444444 %hd#\n" + "%llu\n" + "%lu\n", + current.temperature, + current.dewPoint, + current.timestamp, + current.expires); lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); return std::unique_ptr(new Screens::Label(0, 5, app, label)); } std::unique_ptr Weather::CreateScreen2() { - auto batteryPercent = static_cast(batteryController.PercentRemaining()); - float batteryVoltage = batteryController.Voltage(); - - auto resetReason = [this]() { - switch (watchdog.ResetReason()) { - case Drivers::Watchdog::ResetReasons::Watchdog: - return "wtdg"; - case Drivers::Watchdog::ResetReasons::HardReset: - return "hardr"; - case Drivers::Watchdog::ResetReasons::NFC: - return "nfc"; - case Drivers::Watchdog::ResetReasons::SoftReset: - return "softr"; - case Drivers::Watchdog::ResetReasons::CpuLockup: - return "cpulock"; - case Drivers::Watchdog::ResetReasons::SystemOff: - return "off"; - case Drivers::Watchdog::ResetReasons::LpComp: - return "lpcomp"; - case Drivers::Watchdog::ResetReasons::DebugInterface: - return "dbg"; - case Drivers::Watchdog::ResetReasons::ResetPin: - return "rst"; - default: - return "?"; - } - }(); - // uptime - static constexpr uint32_t secondsInADay = 60 * 60 * 24; - static constexpr uint32_t secondsInAnHour = 60 * 60; - static constexpr uint32_t secondsInAMinute = 60; - uint32_t uptimeSeconds = dateTimeController.Uptime().count(); - uint32_t uptimeDays = (uptimeSeconds / secondsInADay); - uptimeSeconds = uptimeSeconds % secondsInADay; - uint32_t uptimeHours = uptimeSeconds / secondsInAnHour; - uptimeSeconds = uptimeSeconds % secondsInAnHour; - uint32_t uptimeMinutes = uptimeSeconds / secondsInAMinute; - uptimeSeconds = uptimeSeconds % secondsInAMinute; - // TODO handle more than 100 days of uptime - - if (batteryPercent == -1) - batteryPercent = 0; - - // hack to not use the flot functions from printf - uint8_t batteryVoltageBytes[2]; - batteryVoltageBytes[1] = static_cast(batteryVoltage); // truncate whole numbers - batteryVoltageBytes[0] = - static_cast((batteryVoltage - batteryVoltageBytes[1]) * 100); // remove whole part of flt and shift 2 places over - // - lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); lv_label_set_recolor(label, true); - lv_label_set_text_fmt(label, - "#444444 Date# %02d/%02d/%04d\n" - "#444444 Time# %02d:%02d:%02d\n" - "#444444 Uptime#\n %02lud %02lu:%02lu:%02lu\n" - "#444444 Battery# %d%%/%1i.%02iv\n" - "#444444 Backlight# %s\n" - "#444444 Last reset# %s\n", - dateTimeController.Day(), - static_cast(dateTimeController.Month()), - dateTimeController.Year(), - dateTimeController.Hours(), - dateTimeController.Minutes(), - dateTimeController.Seconds(), - uptimeDays, - uptimeHours, - uptimeMinutes, - uptimeSeconds, - batteryPercent, - batteryVoltageBytes[1], - batteryVoltageBytes[0], - brightnessController.ToString(), - resetReason); + lv_label_set_text_fmt(label, "#444444 Date# %02d\n", dateTimeController.Day()); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); return std::unique_ptr(new Screens::Label(1, 4, app, label)); } @@ -169,28 +91,11 @@ std::unique_ptr Weather::CreateScreen3() { lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); lv_label_set_recolor(label, true); - auto& bleAddr = bleController.Address(); lv_label_set_text_fmt(label, - "#444444 BLE MAC#\n" - " %02x:%02x:%02x:%02x:%02x:%02x" - "\n" - "#444444 Memory#\n" - " #444444 used# %d (%d%%)\n" " #444444 frag# %d%%\n" - " #444444 free# %d" - "\n" - "#444444 Steps# %li", - bleAddr[5], - bleAddr[4], - bleAddr[3], - bleAddr[2], - bleAddr[1], - bleAddr[0], - (int) mon.total_size - mon.free_size, + " #444444 free# %d", mon.used_pct, - mon.frag_pct, - (int) mon.free_biggest_size, - 0); + mon.frag_pct); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); return std::unique_ptr(new Screens::Label(2, 5, app, label)); } @@ -201,7 +106,7 @@ bool sortById(const TaskStatus_t& lhs, const TaskStatus_t& rhs) { std::unique_ptr Weather::CreateScreen4() { TaskStatus_t tasksStatus[7]; - lv_obj_t* infoTask = lv_table_create(lv_scr_act(), NULL); + lv_obj_t* infoTask = lv_table_create(lv_scr_act(), nullptr); lv_table_set_col_cnt(infoTask, 3); lv_table_set_row_cnt(infoTask, 8); lv_obj_set_pos(infoTask, 10, 10); diff --git a/src/displayapp/screens/Weather.h b/src/displayapp/screens/Weather.h index 8b393ca1..469bf592 100644 --- a/src/displayapp/screens/Weather.h +++ b/src/displayapp/screens/Weather.h @@ -1,52 +1,43 @@ #pragma once #include +#include #include "Screen.h" #include "ScreenList.h" namespace Pinetime { - namespace Controllers { - class DateTime; - class Battery; - class BrightnessController; - class Ble; - } - - namespace Drivers { - class WatchdogView; - } - namespace Applications { class DisplayApp; namespace Screens { class Weather : public Screen { public: - explicit Weather(DisplayApp* app, - Pinetime::Controllers::DateTime& dateTimeController, - Pinetime::Controllers::Battery& batteryController, - Pinetime::Controllers::BrightnessController& brightnessController, - Pinetime::Controllers::Ble& bleController, - Pinetime::Drivers::WatchdogView& watchdog); + explicit Weather(DisplayApp* app, Pinetime::Controllers::WeatherService& weather); + ~Weather() override; + bool Refresh() override; + bool OnButtonPushed() override; + bool OnTouchEvent(TouchEvents event) override; private: bool running = true; Pinetime::Controllers::DateTime& dateTimeController; - Pinetime::Controllers::Battery& batteryController; - Pinetime::Controllers::BrightnessController& brightnessController; - Pinetime::Controllers::Ble& bleController; - Pinetime::Drivers::WatchdogView& watchdog; + Controllers::WeatherService& weatherService; ScreenList<5> screens; - std::unique_ptr CreateScreen1(); + + std::unique_ptr CreateScreenTemperature(); + std::unique_ptr CreateScreen2(); + std::unique_ptr CreateScreen3(); + std::unique_ptr CreateScreen4(); + std::unique_ptr CreateScreen5(); }; } -- cgit v1.2.3-70-g09d2 From 0ed256ba15ceace2949f21ecbc1407b8553dd75d Mon Sep 17 00:00:00 2001 From: Avamander Date: Fri, 25 Jun 2021 02:52:59 +0300 Subject: Few formatting fixes --- src/CMakeLists.txt | 12 ++++++------ src/components/ble/weather/WeatherService.cpp | 2 +- src/components/ble/weather/WeatherService.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/components/ble') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d83c467a..f1149ce5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -796,7 +796,7 @@ link_directories( ) -set(COMMON_FLAGS -MP -MD -mthumb -mabi=aapcs -Wall -Wno-unknown-pragmas -g3 -ffunction-sections -fdata-sections -fno-strict-aliasing -fno-builtin --short-enums -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wreturn-type -Werror=return-type -fstack-usage -fno-exceptions -fno-non-call-exceptions) +set(COMMON_FLAGS -MP -MD -mthumb -mabi=aapcs -Wall -Wextra -Warray-bounds=2 -Wformat=2 -Wformat-overflow=2 -Wformat-truncation=2 -Wformat-nonliteral -ftree-vrp -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unknown-pragmas -Wno-expansion-to-defined -g3 -ffunction-sections -fdata-sections -fno-strict-aliasing -fno-builtin --short-enums -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wreturn-type -Werror=return-type -fstack-usage -fno-exceptions -fno-non-call-exceptions) add_definitions(-DCONFIG_GPIO_AS_PINRESET) add_definitions(-DNIMBLE_CFG_CONTROLLER) add_definitions(-DOS_CPUTIME_FREQ) @@ -818,10 +818,10 @@ add_library(nrf-sdk STATIC ${SDK_SOURCE_FILES}) target_include_directories(nrf-sdk SYSTEM PUBLIC . ../) target_include_directories(nrf-sdk SYSTEM PUBLIC ${INCLUDES_FROM_LIBS}) target_compile_options(nrf-sdk PRIVATE - $<$,$>: ${COMMON_FLAGS} -Og -g3> - $<$,$>: ${COMMON_FLAGS} -Os> - $<$,$>: ${COMMON_FLAGS} -Og -fno-rtti> - $<$,$>: ${COMMON_FLAGS} -Os -fno-rtti> + $<$,$>: ${COMMON_FLAGS} -Wno-expansion-to-defined -Og -g3> + $<$,$>: ${COMMON_FLAGS} -Wno-expansion-to-defined -O3> + $<$,$>: ${COMMON_FLAGS} -Wno-expansion-to-defined -Og -fno-rtti> + $<$,$>: ${COMMON_FLAGS} -Wno-expansion-to-defined -O3 -fno-rtti> $<$: -MP -MD -x assembler-with-cpp> ) @@ -1153,4 +1153,4 @@ elseif (USE_OPENOCD) COMMENT "flashing ${EXECUTABLE_FILE_NAME}.hex" ) endif () -endif () \ No newline at end of file +endif () diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index 7d20867d..a9c9f114 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -288,4 +288,4 @@ namespace Pinetime { return std::chrono::duration_cast(dateTimeController.CurrentDateTime().time_since_epoch()).count(); } } -} \ No newline at end of file +} diff --git a/src/components/ble/weather/WeatherService.h b/src/components/ble/weather/WeatherService.h index 786d4715..995f856e 100644 --- a/src/components/ble/weather/WeatherService.h +++ b/src/components/ble/weather/WeatherService.h @@ -139,4 +139,4 @@ namespace Pinetime { uint64_t GetCurrentUnixTimestamp() const; }; } -} \ No newline at end of file +} -- cgit v1.2.3-70-g09d2 From ed6f0aade4db811b5013441c57944baff4528938 Mon Sep 17 00:00:00 2001 From: Avamander Date: Sat, 21 Aug 2021 21:58:03 +0300 Subject: Implemented a few functions. --- src/components/ble/weather/WeatherData.h | 6 +- src/components/ble/weather/WeatherService.cpp | 84 ++++++++++++++++++++++----- src/components/ble/weather/WeatherService.h | 20 +++---- src/displayapp/screens/Weather.cpp | 16 +---- 4 files changed, 85 insertions(+), 41 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherData.h b/src/components/ble/weather/WeatherData.h index ee2a364d..9b424004 100644 --- a/src/components/ble/weather/WeatherData.h +++ b/src/components/ble/weather/WeatherData.h @@ -122,7 +122,7 @@ namespace Pinetime { * Events have types * then they're easier to parse after sending them over the air */ - enum class eventtype { + enum class eventtype : uint8_t { /** @see obscuration */ Obscuration = 0, /** @see precipitation */ @@ -141,6 +141,8 @@ namespace Pinetime { Location = 7, /** @see cloud */ Clouds = 8, + /** @see humidity */ + Humidity = 9, Length }; @@ -340,4 +342,4 @@ namespace Pinetime { }; }; } -} \ No newline at end of file +} diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index a9c9f114..22c80837 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -90,7 +90,7 @@ namespace Pinetime { airquality->polluter = std::make_unique(static_cast(String.ptr), String.len); int64_t tmpAmount = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Amount", &tmpAmount); - if (tmpAmount < 0 || tmpAmount > 4294967295) { + if (tmpAmount < 0) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } airquality->amount = tmpAmount; @@ -162,6 +162,14 @@ namespace Pinetime { timeline.push_back(std::move(clouds)); break; } + case WeatherData::eventtype::Humidity: { + std::unique_ptr humidity = std::make_unique(); + humidity->timestamp = tmpTimestamp; + humidity->eventType = static_cast(tmpEventType); + humidity->expires = tmpExpires; + timeline.push_back(std::move(humidity)); + break; + } default: { break; } @@ -201,46 +209,94 @@ namespace Pinetime { return 0; } - WeatherData::Location WeatherService::GetCurrentLocation() const { - return WeatherData::Location(); - } - WeatherData::Clouds WeatherService::GetCurrentClouds() const { - return WeatherData::Clouds(); + uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + for (auto&& header : timeline) { + if (header->eventType == WeatherData::eventtype::Clouds && header->timestamp + header->expires <= currentTimestamp) { + return reinterpret_cast(header); + } + } + return {}; } WeatherData::Obscuration WeatherService::GetCurrentObscuration() const { - return WeatherData::Obscuration(); + uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + for (auto&& header : timeline) { + if (header->eventType == WeatherData::eventtype::Obscuration && header->timestamp + header->expires <= currentTimestamp) { + return reinterpret_cast(header); + } + } + return {}; } WeatherData::Precipitation WeatherService::GetCurrentPrecipitation() const { - return WeatherData::Precipitation(); + uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + for (auto&& header : timeline) { + if (header->eventType == WeatherData::eventtype::Precipitation && header->timestamp + header->expires <= currentTimestamp) { + return reinterpret_cast(header); + } + } + return {}; } WeatherData::Wind WeatherService::GetCurrentWind() const { - return WeatherData::Wind(); + uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + for (auto&& header : timeline) { + if (header->eventType == WeatherData::eventtype::Wind && header->timestamp + header->expires <= currentTimestamp) { + return reinterpret_cast(header); + } + } + return {}; } WeatherData::Temperature WeatherService::GetCurrentTemperature() const { - return WeatherData::Temperature(); + uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + for (auto&& header : timeline) { + if (header->eventType == WeatherData::eventtype::Temperature && header->timestamp + header->expires <= currentTimestamp) { + return reinterpret_cast(header); + } + } + return {}; } WeatherData::Humidity WeatherService::GetCurrentHumidity() const { - return WeatherData::Humidity(); + uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + for (auto&& header : timeline) { + if (header->eventType == WeatherData::eventtype::Humidity && header->timestamp + header->expires <= currentTimestamp) { + return reinterpret_cast(header); + } + } + return {}; } WeatherData::Pressure WeatherService::GetCurrentPressure() const { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : timeline) { if (header->eventType == WeatherData::eventtype::Pressure && header->timestamp + header->expires <= currentTimestamp) { - return WeatherData::Pressure(); + return reinterpret_cast(header); + } + } + return {}; + } + + WeatherData::Location WeatherService::GetCurrentLocation() const { + uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + for (auto&& header : timeline) { + if (header->eventType == WeatherData::eventtype::Location && header->timestamp + header->expires <= currentTimestamp) { + return reinterpret_cast(header); } } - return WeatherData::Pressure(); + return {}; } WeatherData::AirQuality WeatherService::GetCurrentQuality() const { - return WeatherData::AirQuality(); + uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + for (auto&& header : timeline) { + if (header->eventType == WeatherData::eventtype::AirQuality && header->timestamp + header->expires <= currentTimestamp) { + return reinterpret_cast(header); + } + } + return {}; } size_t WeatherService::GetTimelineLength() const { diff --git a/src/components/ble/weather/WeatherService.h b/src/components/ble/weather/WeatherService.h index 995f856e..5504ea49 100644 --- a/src/components/ble/weather/WeatherService.h +++ b/src/components/ble/weather/WeatherService.h @@ -77,42 +77,42 @@ namespace Pinetime { * Checks if an event of a certain type exists in the timeline * @return */ - bool HasTimelineEventOfType(const WeatherData::eventtype type) const; + bool HasTimelineEventOfType(WeatherData::eventtype type) const; private: // 00030000-78fc-48fe-8e23-433b3a1942d0 - static constexpr ble_uuid128_t BaseUUID() { - return CharUUID(0x00, 0x00); + static constexpr ble_uuid128_t BaseUuid() { + return CharUuid(0x00, 0x00); } // 0003yyxx-78fc-48fe-8e23-433b3a1942d0 - static constexpr ble_uuid128_t CharUUID(uint8_t x, uint8_t y) { + static constexpr ble_uuid128_t CharUuid(uint8_t x, uint8_t y) { return ble_uuid128_t {.u = {.type = BLE_UUID_TYPE_128}, .value = {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, x, y, 0x03, 0x00}}; } - ble_uuid128_t weatherUUID {BaseUUID()}; + ble_uuid128_t weatherUuid {BaseUuid()}; /** * Just write timeline data here */ - ble_uuid128_t weatherDataCharUUID {CharUUID(0x00, 0x01)}; + ble_uuid128_t weatherDataCharUuid {CharUuid(0x00, 0x01)}; /** * This doesn't take timeline data, * provides some control over it */ - ble_uuid128_t weatherControlCharUUID {CharUUID(0x00, 0x02)}; + ble_uuid128_t weatherControlCharUuid {CharUuid(0x00, 0x02)}; const struct ble_gatt_chr_def characteristicDefinition[3] = { - {.uuid = &weatherDataCharUUID.u, + {.uuid = &weatherDataCharUuid.u, .access_cb = WeatherCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE, .val_handle = &eventHandle}, - {.uuid = &weatherControlCharUUID.u, .access_cb = WeatherCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ}, + {.uuid = &weatherControlCharUuid.u, .access_cb = WeatherCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ}, {nullptr}}; const struct ble_gatt_svc_def serviceDefinition[2] = { - {.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &weatherUUID.u, .characteristics = characteristicDefinition}, {0}}; + {.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &weatherUuid.u, .characteristics = characteristicDefinition}, {0}}; uint16_t eventHandle {}; diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp index a1278649..ea96c9f2 100644 --- a/src/displayapp/screens/Weather.cpp +++ b/src/displayapp/screens/Weather.cpp @@ -105,7 +105,6 @@ bool sortById(const TaskStatus_t& lhs, const TaskStatus_t& rhs) { } std::unique_ptr Weather::CreateScreen4() { - TaskStatus_t tasksStatus[7]; lv_obj_t* infoTask = lv_table_create(lv_scr_act(), nullptr); lv_table_set_col_cnt(infoTask, 3); lv_table_set_row_cnt(infoTask, 8); @@ -118,19 +117,6 @@ std::unique_ptr Weather::CreateScreen4() { lv_table_set_cell_value(infoTask, 0, 2, "Free"); lv_table_set_col_width(infoTask, 2, 90); - auto nb = uxTaskGetSystemState(tasksStatus, 7, nullptr); - std::sort(tasksStatus, tasksStatus + nb, sortById); - for (uint8_t i = 0; i < nb; i++) { - - lv_table_set_cell_value(infoTask, i + 1, 0, std::to_string(tasksStatus[i].xTaskNumber).c_str()); - lv_table_set_cell_value(infoTask, i + 1, 1, tasksStatus[i].pcTaskName); - if (tasksStatus[i].usStackHighWaterMark < 20) { - std::string str1 = std::to_string(tasksStatus[i].usStackHighWaterMark) + " low"; - lv_table_set_cell_value(infoTask, i + 1, 2, str1.c_str()); - } else { - lv_table_set_cell_value(infoTask, i + 1, 2, std::to_string(tasksStatus[i].usStackHighWaterMark).c_str()); - } - } return std::unique_ptr(new Screens::Label(3, 5, app, infoTask)); } @@ -148,4 +134,4 @@ std::unique_ptr Weather::CreateScreen5() { lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); return std::unique_ptr(new Screens::Label(4, 5, app, label)); -} \ No newline at end of file +} -- cgit v1.2.3-70-g09d2 From ffb17357e74fd80a0381361a5cbc6bc481d28000 Mon Sep 17 00:00:00 2001 From: Avamander Date: Sun, 28 Nov 2021 15:33:06 +0200 Subject: Fixed a few compilation errors, fixed UUID. --- src/components/ble/weather/WeatherData.h | 4 ++-- src/components/ble/weather/WeatherService.cpp | 2 +- src/components/ble/weather/WeatherService.h | 2 +- src/displayapp/screens/Weather.cpp | 27 +++++++++++++++++++-------- src/displayapp/screens/Weather.h | 4 ++-- 5 files changed, 25 insertions(+), 14 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherData.h b/src/components/ble/weather/WeatherData.h index 9b424004..19b9709d 100644 --- a/src/components/ble/weather/WeatherData.h +++ b/src/components/ble/weather/WeatherData.h @@ -250,7 +250,7 @@ namespace Pinetime { class Location : public TimelineHeader { public: /** Location name */ - std::unique_ptr location; + std::string location; /** Altitude relative to sea level in meters */ int16_t altitude; /** Latitude, EPSG:3857 (Google Maps, Openstreetmaps datum) */ @@ -311,7 +311,7 @@ namespace Pinetime { * For chemical compounds use the molecular formula e.g. "NO2", "CO2", "O3" * For pollen use the genus, e.g. "Betula" for birch or "Alternaria" for that mold's spores */ - std::unique_ptr polluter; + std::string polluter; /** * Amount of the pollution in SI units, * otherwise it's going to be difficult to create UI, alerts diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index 22c80837..bbaa21f0 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -87,7 +87,7 @@ namespace Pinetime { if (UsefulBuf_IsNULLOrEmptyC(String) != 0) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } - airquality->polluter = std::make_unique(static_cast(String.ptr), String.len); + airquality->polluter = std::string(static_cast(String.ptr), String.len); int64_t tmpAmount = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Amount", &tmpAmount); if (tmpAmount < 0) { diff --git a/src/components/ble/weather/WeatherService.h b/src/components/ble/weather/WeatherService.h index 5504ea49..7bf60ee1 100644 --- a/src/components/ble/weather/WeatherService.h +++ b/src/components/ble/weather/WeatherService.h @@ -88,7 +88,7 @@ namespace Pinetime { // 0003yyxx-78fc-48fe-8e23-433b3a1942d0 static constexpr ble_uuid128_t CharUuid(uint8_t x, uint8_t y) { return ble_uuid128_t {.u = {.type = BLE_UUID_TYPE_128}, - .value = {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, x, y, 0x03, 0x00}}; + .value = {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, y, x, 0x03, 0x00}}; } ble_uuid128_t weatherUuid {BaseUuid()}; diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp index ea96c9f2..025a3bd8 100644 --- a/src/displayapp/screens/Weather.cpp +++ b/src/displayapp/screens/Weather.cpp @@ -1,14 +1,26 @@ +/* Copyright (C) 2021 Avamander + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ #include "Weather.h" #include #include -#include "../DisplayApp.h" #include "Label.h" -#include "Version.h" #include "components/battery/BatteryController.h" #include "components/ble/BleController.h" -#include "components/brightness/BrightnessController.h" -#include "components/datetime/DateTimeController.h" -#include "drivers/Watchdog.h" #include "components/ble/weather/WeatherData.h" using namespace Pinetime::Applications::Screens; @@ -41,11 +53,10 @@ Weather::~Weather() { lv_obj_clean(lv_scr_act()); } -bool Weather::Refresh() { +void Weather::Refresh() { if (running) { - screens.Refresh(); + // screens.Refresh(); } - return running; } bool Weather::OnButtonPushed() { diff --git a/src/displayapp/screens/Weather.h b/src/displayapp/screens/Weather.h index 469bf592..99cf15ba 100644 --- a/src/displayapp/screens/Weather.h +++ b/src/displayapp/screens/Weather.h @@ -16,7 +16,7 @@ namespace Pinetime { ~Weather() override; - bool Refresh() override; + void Refresh() override; bool OnButtonPushed() override; @@ -42,4 +42,4 @@ namespace Pinetime { }; } } -} \ No newline at end of file +} -- cgit v1.2.3-70-g09d2 From 657dc3a9ba21039cc9abd3c40c68aa3e810bd074 Mon Sep 17 00:00:00 2001 From: Avamander Date: Sun, 28 Nov 2021 19:12:16 +0200 Subject: Changed UUID so it wouldn't conflict with Motion --- src/components/ble/weather/WeatherService.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherService.h b/src/components/ble/weather/WeatherService.h index 7bf60ee1..43b2ee28 100644 --- a/src/components/ble/weather/WeatherService.h +++ b/src/components/ble/weather/WeatherService.h @@ -80,15 +80,15 @@ namespace Pinetime { bool HasTimelineEventOfType(WeatherData::eventtype type) const; private: - // 00030000-78fc-48fe-8e23-433b3a1942d0 + // 00040000-78fc-48fe-8e23-433b3a1942d0 static constexpr ble_uuid128_t BaseUuid() { return CharUuid(0x00, 0x00); } - // 0003yyxx-78fc-48fe-8e23-433b3a1942d0 + // 0004yyxx-78fc-48fe-8e23-433b3a1942d0 static constexpr ble_uuid128_t CharUuid(uint8_t x, uint8_t y) { return ble_uuid128_t {.u = {.type = BLE_UUID_TYPE_128}, - .value = {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, y, x, 0x03, 0x00}}; + .value = {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, y, x, 0x04, 0x00}}; } ble_uuid128_t weatherUuid {BaseUuid()}; -- cgit v1.2.3-70-g09d2 From 900598a7eeff1a84ccf7d0d7c94ac28a780299d4 Mon Sep 17 00:00:00 2001 From: Avamander Date: Sun, 28 Nov 2021 19:13:03 +0200 Subject: Removed versioning because it's not necessary --- src/components/ble/weather/WeatherService.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index bbaa21f0..135f64dd 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -48,18 +48,11 @@ namespace Pinetime { } // Decode QCBORDecodeContext decodeContext; - UsefulBufC encodedCbor; - // TODO: Check, uninit fine? + UsefulBufC encodedCbor = {ctxt->om, OS_MBUF_PKTLEN(ctxt->om)}; QCBORDecode_Init(&decodeContext, encodedCbor, QCBOR_DECODE_MODE_NORMAL); QCBORDecode_EnterMap(&decodeContext, nullptr); // Always encodes to the smallest number of bytes based on the value - int64_t tmpVersion = 0; - QCBORDecode_GetInt64InMapSZ(&decodeContext, "Version", &tmpVersion); - if (tmpVersion != 1) { - // TODO: Return better error? - return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; - } int64_t tmpTimestamp = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Timestamp", &tmpTimestamp); int64_t tmpExpires = 0; -- cgit v1.2.3-70-g09d2 From 48beb7c3b18bcfdc369a63be5923a35a2113aa36 Mon Sep 17 00:00:00 2001 From: Avamander Date: Sun, 28 Nov 2021 20:58:28 +0200 Subject: Improved error handling and fixed incompatibility with co.nstant.in:cbor library --- src/CMakeLists.txt | 10 +++++----- src/components/ble/weather/WeatherService.cpp | 9 ++++++--- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src/components/ble') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cbccb714..9f3b6d4e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -859,7 +859,7 @@ target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_FLOAT_HW_USE) target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_PREFERRED_FLOAT) target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_EXP_AND_MANTISSA) target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS) -target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS) +#target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS) target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_UNCOMMON_TAGS) target_compile_definitions(QCBOR PUBLIC USEFULBUF_CONFIG_LITTLE_ENDIAN) set_target_properties(QCBOR PROPERTIES LINKER_LANGUAGE C) @@ -889,10 +889,10 @@ add_executable(${EXECUTABLE_NAME} ${SOURCE_FILES}) set_target_properties(${EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_FILE_NAME}) target_link_libraries(${EXECUTABLE_NAME} nimble nrf-sdk lvgl littlefs QCBOR) target_compile_options(${EXECUTABLE_NAME} PUBLIC - $<$,$>: ${COMMON_FLAGS} -Og -g3> - $<$,$>: ${COMMON_FLAGS} -Os> - $<$,$>: ${COMMON_FLAGS} -Og -g3 -fno-rtti> - $<$,$>: ${COMMON_FLAGS} -Os -fno-rtti> + $<$,$>: ${COMMON_FLAGS} -Wextra -Wformat -Wno-missing-field-initializers -Wno-unused-parameter -Og -g3> + $<$,$>: ${COMMON_FLAGS} -Wextra -Wformat -Wno-missing-field-initializers -Wno-unused-parameter -Os> + $<$,$>: ${COMMON_FLAGS} -Wextra -Wformat -Wno-missing-field-initializers -Wno-unused-parameter -Og -g3 -fno-rtti> + $<$,$>: ${COMMON_FLAGS} -Wextra -Wformat -Wno-missing-field-initializers -Wno-unused-parameter -Os -fno-rtti> $<$: -MP -MD -x assembler-with-cpp> ) diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index 135f64dd..42302610 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -48,13 +48,17 @@ namespace Pinetime { } // Decode QCBORDecodeContext decodeContext; - UsefulBufC encodedCbor = {ctxt->om, OS_MBUF_PKTLEN(ctxt->om)}; + UsefulBufC encodedCbor = {ctxt->om->om_data, OS_MBUF_PKTLEN(ctxt->om)}; QCBORDecode_Init(&decodeContext, encodedCbor, QCBOR_DECODE_MODE_NORMAL); + // KINDLY provide us a fixed-length map QCBORDecode_EnterMap(&decodeContext, nullptr); // Always encodes to the smallest number of bytes based on the value int64_t tmpTimestamp = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Timestamp", &tmpTimestamp); + if (QCBORDecode_GetError(&decodeContext) != QCBOR_SUCCESS) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } int64_t tmpExpires = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Expires", &tmpExpires); if (tmpExpires < 0 || tmpExpires > 4294967295) { @@ -173,8 +177,7 @@ namespace Pinetime { GetTimelineLength(); QCBORDecode_ExitMap(&decodeContext); - auto uErr = QCBORDecode_Finish(&decodeContext); - if (uErr != 0) { + if (QCBORDecode_Finish(&decodeContext) != QCBOR_SUCCESS) { return BLE_ATT_ERR_INSUFFICIENT_RES; } } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { -- cgit v1.2.3-70-g09d2 From c870f8ed302823e12018aa196d87937c92966d06 Mon Sep 17 00:00:00 2001 From: Avamander Date: Wed, 1 Dec 2021 00:45:28 +0200 Subject: Bunch of bugs fixed, improved error handling, debug UI addition --- src/components/ble/weather/WeatherService.cpp | 127 ++++++++++++----------- src/components/ble/weather/WeatherService.h | 31 ++++-- src/displayapp/Apps.h | 1 + src/displayapp/screens/Weather.cpp | 144 ++++++++++++++++---------- src/displayapp/screens/Weather.h | 8 +- 5 files changed, 182 insertions(+), 129 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index 42302610..4ec57d00 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -28,6 +28,7 @@ namespace Pinetime { namespace Controllers { WeatherService::WeatherService(System::SystemTask& system, DateTime& dateTimeController) : system(system), dateTimeController(dateTimeController) { + nullHeader = &nullTimelineheader; } void WeatherService::Init() { @@ -42,7 +43,7 @@ namespace Pinetime { int WeatherService::OnCommand(uint16_t connHandle, uint16_t attrHandle, struct ble_gatt_access_ctxt* ctxt) { // TODO: Detect control messages if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - const auto packetLen = OS_MBUF_PKTLEN(ctxt->om); + const uint8_t packetLen = OS_MBUF_PKTLEN(ctxt->om); if (packetLen <= 0) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } @@ -56,30 +57,28 @@ namespace Pinetime { // Always encodes to the smallest number of bytes based on the value int64_t tmpTimestamp = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Timestamp", &tmpTimestamp); - if (QCBORDecode_GetError(&decodeContext) != QCBOR_SUCCESS) { + uint8_t err = QCBORDecode_GetError(&decodeContext); + if (err != QCBOR_SUCCESS) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } int64_t tmpExpires = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Expires", &tmpExpires); if (tmpExpires < 0 || tmpExpires > 4294967295) { - // TODO: Return better error? return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } int64_t tmpEventType = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "EventType", &tmpEventType); if (tmpEventType < 0 || tmpEventType > static_cast(WeatherData::eventtype::Length)) { - // TODO: Return better error? return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } switch (static_cast(tmpEventType)) { - // TODO: Populate case WeatherData::eventtype::AirQuality: { std::unique_ptr airquality = std::make_unique(); airquality->timestamp = tmpTimestamp; airquality->eventType = static_cast(tmpEventType); airquality->expires = tmpExpires; - UsefulBufC String; + UsefulBufC String; // TODO: Everything ok with lifecycle here? QCBORDecode_GetTextStringInMapSZ(&decodeContext, "Polluter", &String); if (UsefulBuf_IsNULLOrEmptyC(String) != 0) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; @@ -172,10 +171,9 @@ namespace Pinetime { } } - GetCurrentPressure(); - TidyTimeline(); - GetTimelineLength(); QCBORDecode_ExitMap(&decodeContext); + GetTimelineLength(); + TidyTimeline(); if (QCBORDecode_Finish(&decodeContext) != QCBOR_SUCCESS) { return BLE_ATT_ERR_INSUFFICIENT_RES; @@ -205,94 +203,103 @@ namespace Pinetime { return 0; } - WeatherData::Clouds WeatherService::GetCurrentClouds() const { + std::unique_ptr& WeatherService::GetCurrentClouds() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); - for (auto&& header : timeline) { - if (header->eventType == WeatherData::eventtype::Clouds && header->timestamp + header->expires <= currentTimestamp) { - return reinterpret_cast(header); + for (auto&& header : this->timeline) { + if (header->eventType == WeatherData::eventtype::Clouds && isEventStillValid(header, currentTimestamp)) { + return reinterpret_cast&>(header); } } - return {}; + + return reinterpret_cast&>(this->nullHeader); } - WeatherData::Obscuration WeatherService::GetCurrentObscuration() const { + std::unique_ptr& WeatherService::GetCurrentObscuration() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); - for (auto&& header : timeline) { - if (header->eventType == WeatherData::eventtype::Obscuration && header->timestamp + header->expires <= currentTimestamp) { - return reinterpret_cast(header); + for (auto&& header : this->timeline) { + if (header->eventType == WeatherData::eventtype::Obscuration && isEventStillValid(header, currentTimestamp)) { + return reinterpret_cast&>(header); } } - return {}; + + return reinterpret_cast&>(this->nullHeader); } - WeatherData::Precipitation WeatherService::GetCurrentPrecipitation() const { + std::unique_ptr& WeatherService::GetCurrentPrecipitation() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); - for (auto&& header : timeline) { - if (header->eventType == WeatherData::eventtype::Precipitation && header->timestamp + header->expires <= currentTimestamp) { - return reinterpret_cast(header); + for (auto&& header : this->timeline) { + if (header->eventType == WeatherData::eventtype::Precipitation && isEventStillValid(header, currentTimestamp)) { + return reinterpret_cast&>(header); } } - return {}; + + return reinterpret_cast&>(this->nullHeader); } - WeatherData::Wind WeatherService::GetCurrentWind() const { + std::unique_ptr& WeatherService::GetCurrentWind() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); - for (auto&& header : timeline) { - if (header->eventType == WeatherData::eventtype::Wind && header->timestamp + header->expires <= currentTimestamp) { - return reinterpret_cast(header); + for (auto&& header : this->timeline) { + if (header->eventType == WeatherData::eventtype::Wind && isEventStillValid(header, currentTimestamp)) { + return reinterpret_cast&>(header); } } - return {}; + + return reinterpret_cast&>(this->nullHeader); } - WeatherData::Temperature WeatherService::GetCurrentTemperature() const { + std::unique_ptr& WeatherService::GetCurrentTemperature() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); - for (auto&& header : timeline) { - if (header->eventType == WeatherData::eventtype::Temperature && header->timestamp + header->expires <= currentTimestamp) { - return reinterpret_cast(header); + for (auto&& header : this->timeline) { + if (header->eventType == WeatherData::eventtype::Temperature && isEventStillValid(header, currentTimestamp)) { + return reinterpret_cast&>(header); } } - return {}; + + return reinterpret_cast&>(this->nullHeader); } - WeatherData::Humidity WeatherService::GetCurrentHumidity() const { + std::unique_ptr& WeatherService::GetCurrentHumidity() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); - for (auto&& header : timeline) { - if (header->eventType == WeatherData::eventtype::Humidity && header->timestamp + header->expires <= currentTimestamp) { - return reinterpret_cast(header); + for (auto&& header : this->timeline) { + if (header->eventType == WeatherData::eventtype::Humidity && isEventStillValid(header, currentTimestamp)) { + return reinterpret_cast&>(header); } } - return {}; + + return reinterpret_cast&>(this->nullHeader); } - WeatherData::Pressure WeatherService::GetCurrentPressure() const { + std::unique_ptr& WeatherService::GetCurrentPressure() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); - for (auto&& header : timeline) { - if (header->eventType == WeatherData::eventtype::Pressure && header->timestamp + header->expires <= currentTimestamp) { - return reinterpret_cast(header); + for (auto&& header : this->timeline) { + if (header->eventType == WeatherData::eventtype::Pressure && isEventStillValid(header, currentTimestamp)) { + return reinterpret_cast&>(header); } } - return {}; + + return reinterpret_cast&>(this->nullHeader); } - WeatherData::Location WeatherService::GetCurrentLocation() const { + std::unique_ptr& WeatherService::GetCurrentLocation() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); - for (auto&& header : timeline) { - if (header->eventType == WeatherData::eventtype::Location && header->timestamp + header->expires <= currentTimestamp) { - return reinterpret_cast(header); + for (auto&& header : this->timeline) { + if (header->eventType == WeatherData::eventtype::Location && isEventStillValid(header, currentTimestamp)) { + return reinterpret_cast&>(header); } } - return {}; + + return reinterpret_cast&>(this->nullHeader); } - WeatherData::AirQuality WeatherService::GetCurrentQuality() const { + std::unique_ptr& WeatherService::GetCurrentQuality() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); - for (auto&& header : timeline) { - if (header->eventType == WeatherData::eventtype::AirQuality && header->timestamp + header->expires <= currentTimestamp) { - return reinterpret_cast(header); + for (auto&& header : this->timeline) { + if (header->eventType == WeatherData::eventtype::AirQuality && isEventStillValid(header, currentTimestamp)) { + return reinterpret_cast&>(header); } } - return {}; + + return reinterpret_cast&>(this->nullHeader); } size_t WeatherService::GetTimelineLength() const { @@ -311,8 +318,7 @@ namespace Pinetime { bool WeatherService::HasTimelineEventOfType(const WeatherData::eventtype type) const { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : timeline) { - if (header->eventType == type && header->timestamp + header->expires <= currentTimestamp) { - // TODO: Check if its currently valid + if (header->eventType == type && isEventStillValid(header, currentTimestamp)) { return true; } } @@ -320,11 +326,11 @@ namespace Pinetime { } void WeatherService::TidyTimeline() { - uint64_t timeCurrent = 0; + uint64_t timeCurrent = GetCurrentUnixTimestamp(); timeline.erase(std::remove_if(std::begin(timeline), std::end(timeline), [&](std::unique_ptr const& header) { - return header->timestamp + header->expires > timeCurrent; + return isEventStillValid(header, timeCurrent); }), std::end(timeline)); @@ -336,6 +342,11 @@ namespace Pinetime { return first->timestamp > second->timestamp; } + bool WeatherService::isEventStillValid(const std::unique_ptr& header, const uint64_t currentTimestamp) { + // Not getting timestamp in isEventStillValid for more speed + return header->timestamp + header->expires <= currentTimestamp; + } + uint64_t WeatherService::GetCurrentUnixTimestamp() const { return std::chrono::duration_cast(dateTimeController.CurrentDateTime().time_since_epoch()).count(); } diff --git a/src/components/ble/weather/WeatherService.h b/src/components/ble/weather/WeatherService.h index 43b2ee28..7accc49e 100644 --- a/src/components/ble/weather/WeatherService.h +++ b/src/components/ble/weather/WeatherService.h @@ -51,15 +51,15 @@ namespace Pinetime { /* * Helper functions for quick access to currently valid data */ - WeatherData::Location GetCurrentLocation() const; - WeatherData::Clouds GetCurrentClouds() const; - WeatherData::Obscuration GetCurrentObscuration() const; - WeatherData::Precipitation GetCurrentPrecipitation() const; - WeatherData::Wind GetCurrentWind() const; - WeatherData::Temperature GetCurrentTemperature() const; - WeatherData::Humidity GetCurrentHumidity() const; - WeatherData::Pressure GetCurrentPressure() const; - WeatherData::AirQuality GetCurrentQuality() const; + std::unique_ptr& GetCurrentLocation(); + std::unique_ptr& GetCurrentClouds(); + std::unique_ptr& GetCurrentObscuration(); + std::unique_ptr& GetCurrentPrecipitation(); + std::unique_ptr& GetCurrentWind(); + std::unique_ptr& GetCurrentTemperature(); + std::unique_ptr& GetCurrentHumidity(); + std::unique_ptr& GetCurrentPressure(); + std::unique_ptr& GetCurrentQuality(); /* * Management functions @@ -123,7 +123,6 @@ namespace Pinetime { /** * Cleans up the timeline of expired events - * @return result code */ void TidyTimeline(); @@ -137,6 +136,18 @@ namespace Pinetime { * Returns current UNIX timestamp */ uint64_t GetCurrentUnixTimestamp() const; + + /** + * Checks if the event hasn't gone past and expired + * + * @param header timeline event to check + * @param currentTimestamp what's the time right now + * @return if the event is valid + */ + static bool isEventStillValid(const std::unique_ptr& uniquePtr, const uint64_t timestamp); + + std::unique_ptr nullTimelineheader = std::make_unique(); + std::unique_ptr* nullHeader; }; } } diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h index d340efee..1cf7e2a8 100644 --- a/src/displayapp/Apps.h +++ b/src/displayapp/Apps.h @@ -25,6 +25,7 @@ namespace Pinetime { Metronome, Motion, Steps, + Weather, QuickSettings, Settings, SettingWatchFace, diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp index 025a3bd8..132bee71 100644 --- a/src/displayapp/screens/Weather.cpp +++ b/src/displayapp/screens/Weather.cpp @@ -35,16 +35,16 @@ Weather::Weather(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers: return CreateScreenTemperature(); }, [this]() -> std::unique_ptr { - return CreateScreen2(); + return CreateScreenAir(); }, [this]() -> std::unique_ptr { - return CreateScreen3(); + return CreateScreenClouds(); }, [this]() -> std::unique_ptr { - return CreateScreen4(); + return CreateScreenPrecipitation(); }, [this]() -> std::unique_ptr { - return CreateScreen5(); + return CreateScreenHumidity(); }}, Screens::ScreenListModes::UpDown} { } @@ -71,78 +71,108 @@ bool Weather::OnTouchEvent(Pinetime::Applications::TouchEvents event) { std::unique_ptr Weather::CreateScreenTemperature() { lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); lv_label_set_recolor(label, true); - Controllers::WeatherData::Temperature current = weatherService.GetCurrentTemperature(); - lv_label_set_text_fmt(label, - "#FFFF00 Temperature#\n\n" - "#444444 %hd%%#°C \n\n" - "#444444 %hd#\n" - "%llu\n" - "%lu\n", - current.temperature, - current.dewPoint, - current.timestamp, - current.expires); + std::unique_ptr& current = weatherService.GetCurrentTemperature(); + if (current->timestamp == 0) { + // Do not use the data, it's invalid + } else { + lv_label_set_text_fmt(label, + "#FFFF00 Temperature#\n\n" + "#444444 %hd%%#°C \n\n" + "#444444 %hd#\n\n" + "%llu\n" + "%lu\n", + current->temperature, + current->dewPoint, + current->timestamp, + current->expires); + } lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); return std::unique_ptr(new Screens::Label(0, 5, app, label)); } -std::unique_ptr Weather::CreateScreen2() { - // uptime +std::unique_ptr Weather::CreateScreenAir() { lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); lv_label_set_recolor(label, true); - lv_label_set_text_fmt(label, "#444444 Date# %02d\n", dateTimeController.Day()); + std::unique_ptr& current = weatherService.GetCurrentQuality(); + if (current->timestamp == 0) { + // Do not use the data, it's invalid + } else { + lv_label_set_text_fmt(label, + "#FFFF00 Air quality#\n\n" + "#444444 %s#\n" + "#444444 %lu#\n\n" + "%llu\n" + "%lu\n", + current->polluter.c_str(), + current->amount, + current->timestamp, + current->expires); + } + lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); - return std::unique_ptr(new Screens::Label(1, 4, app, label)); + return std::unique_ptr(new Screens::Label(0, 5, app, label)); } -std::unique_ptr Weather::CreateScreen3() { - lv_mem_monitor_t mon; - lv_mem_monitor(&mon); - +std::unique_ptr Weather::CreateScreenClouds() { lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); lv_label_set_recolor(label, true); - lv_label_set_text_fmt(label, - " #444444 frag# %d%%\n" - " #444444 free# %d", - mon.used_pct, - mon.frag_pct); + std::unique_ptr& current = weatherService.GetCurrentClouds(); + if (current->timestamp == 0) { + // Do not use the data, it's invalid + } else { + lv_label_set_text_fmt(label, + "#FFFF00 Clouds#\n\n" + "#444444 %hhu%%#\n\n" + "%llu\n" + "%lu\n", + current->amount, + current->timestamp, + current->expires); + } + lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); - return std::unique_ptr(new Screens::Label(2, 5, app, label)); -} - -bool sortById(const TaskStatus_t& lhs, const TaskStatus_t& rhs) { - return lhs.xTaskNumber < rhs.xTaskNumber; + return std::unique_ptr(new Screens::Label(0, 5, app, label)); } -std::unique_ptr Weather::CreateScreen4() { - lv_obj_t* infoTask = lv_table_create(lv_scr_act(), nullptr); - lv_table_set_col_cnt(infoTask, 3); - lv_table_set_row_cnt(infoTask, 8); - lv_obj_set_pos(infoTask, 10, 10); - - lv_table_set_cell_value(infoTask, 0, 0, "#"); - lv_table_set_col_width(infoTask, 0, 50); - lv_table_set_cell_value(infoTask, 0, 1, "Task"); - lv_table_set_col_width(infoTask, 1, 80); - lv_table_set_cell_value(infoTask, 0, 2, "Free"); - lv_table_set_col_width(infoTask, 2, 90); - - return std::unique_ptr(new Screens::Label(3, 5, app, infoTask)); +std::unique_ptr Weather::CreateScreenPrecipitation() { + lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_recolor(label, true); + std::unique_ptr& current = weatherService.GetCurrentPrecipitation(); + if (current->timestamp == 0) { + // Do not use the data, it's invalid + } else { + lv_label_set_text_fmt(label, + "#FFFF00 Precipitation#\n\n" + "#444444 %hhu%%#\n\n" + "%llu\n" + "%lu\n", + current->amount, + current->timestamp, + current->expires); + } + lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); + lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + return std::unique_ptr(new Screens::Label(0, 5, app, label)); } -std::unique_ptr Weather::CreateScreen5() { +std::unique_ptr Weather::CreateScreenHumidity() { lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); lv_label_set_recolor(label, true); - lv_label_set_text_static(label, - "Software Licensed\n" - "under the terms of\n" - "the GNU General\n" - "Public License v3\n" - "#444444 Source code#\n" - "#FFFF00 https://github.com/#\n" - "#FFFF00 JF002/InfiniTime#"); + std::unique_ptr& current = weatherService.GetCurrentHumidity(); + if (current->timestamp == 0) { + // Do not use the data, it's invalid + } else { + lv_label_set_text_fmt(label, + "#FFFF00 Humidity#\n\n" + "#444444 %hhu%%#\n\n" + "%llu\n" + "%lu\n", + current->humidity, + current->timestamp, + current->expires); + } lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); - return std::unique_ptr(new Screens::Label(4, 5, app, label)); + return std::unique_ptr(new Screens::Label(0, 5, app, label)); } diff --git a/src/displayapp/screens/Weather.h b/src/displayapp/screens/Weather.h index 99cf15ba..34f95fce 100644 --- a/src/displayapp/screens/Weather.h +++ b/src/displayapp/screens/Weather.h @@ -32,13 +32,13 @@ namespace Pinetime { std::unique_ptr CreateScreenTemperature(); - std::unique_ptr CreateScreen2(); + std::unique_ptr CreateScreenAir(); - std::unique_ptr CreateScreen3(); + std::unique_ptr CreateScreenClouds(); - std::unique_ptr CreateScreen4(); + std::unique_ptr CreateScreenPrecipitation(); - std::unique_ptr CreateScreen5(); + std::unique_ptr CreateScreenHumidity(); }; } } -- cgit v1.2.3-70-g09d2 From 06b022fc4dd6c2b1e5145e111f5c1f32e4729eab Mon Sep 17 00:00:00 2001 From: Avamander Date: Wed, 1 Dec 2021 01:15:11 +0200 Subject: Improved UI and fixed a bug --- src/components/ble/weather/WeatherService.cpp | 21 +++++++++++---------- src/displayapp/screens/Weather.cpp | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 10 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index 4ec57d00..250b36ab 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -29,6 +29,7 @@ namespace Pinetime { WeatherService::WeatherService(System::SystemTask& system, DateTime& dateTimeController) : system(system), dateTimeController(dateTimeController) { nullHeader = &nullTimelineheader; + nullTimelineheader->timestamp = 0; } void WeatherService::Init() { @@ -211,7 +212,7 @@ namespace Pinetime { } } - return reinterpret_cast&>(this->nullHeader); + return reinterpret_cast&>(*this->nullHeader); } std::unique_ptr& WeatherService::GetCurrentObscuration() { @@ -222,7 +223,7 @@ namespace Pinetime { } } - return reinterpret_cast&>(this->nullHeader); + return reinterpret_cast&>(*this->nullHeader); } std::unique_ptr& WeatherService::GetCurrentPrecipitation() { @@ -233,7 +234,7 @@ namespace Pinetime { } } - return reinterpret_cast&>(this->nullHeader); + return reinterpret_cast&>(*this->nullHeader); } std::unique_ptr& WeatherService::GetCurrentWind() { @@ -244,7 +245,7 @@ namespace Pinetime { } } - return reinterpret_cast&>(this->nullHeader); + return reinterpret_cast&>(*this->nullHeader); } std::unique_ptr& WeatherService::GetCurrentTemperature() { @@ -255,7 +256,7 @@ namespace Pinetime { } } - return reinterpret_cast&>(this->nullHeader); + return reinterpret_cast&>(*this->nullHeader); } std::unique_ptr& WeatherService::GetCurrentHumidity() { @@ -266,7 +267,7 @@ namespace Pinetime { } } - return reinterpret_cast&>(this->nullHeader); + return reinterpret_cast&>(*this->nullHeader); } std::unique_ptr& WeatherService::GetCurrentPressure() { @@ -277,7 +278,7 @@ namespace Pinetime { } } - return reinterpret_cast&>(this->nullHeader); + return reinterpret_cast&>(*this->nullHeader); } std::unique_ptr& WeatherService::GetCurrentLocation() { @@ -288,7 +289,7 @@ namespace Pinetime { } } - return reinterpret_cast&>(this->nullHeader); + return reinterpret_cast&>(*this->nullHeader); } std::unique_ptr& WeatherService::GetCurrentQuality() { @@ -299,7 +300,7 @@ namespace Pinetime { } } - return reinterpret_cast&>(this->nullHeader); + return reinterpret_cast&>(*this->nullHeader); } size_t WeatherService::GetTimelineLength() const { @@ -330,7 +331,7 @@ namespace Pinetime { timeline.erase(std::remove_if(std::begin(timeline), std::end(timeline), [&](std::unique_ptr const& header) { - return isEventStillValid(header, timeCurrent); + return !isEventStillValid(header, timeCurrent); }), std::end(timeline)); diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp index 132bee71..0854c74a 100644 --- a/src/displayapp/screens/Weather.cpp +++ b/src/displayapp/screens/Weather.cpp @@ -74,6 +74,16 @@ std::unique_ptr Weather::CreateScreenTemperature() { std::unique_ptr& current = weatherService.GetCurrentTemperature(); if (current->timestamp == 0) { // Do not use the data, it's invalid + lv_label_set_text_fmt(label, + "#FFFF00 Temperature#\n\n" + "#444444 %d#\n\n" + "#444444 %d#\n\n" + "%d\n" + "%d\n", + 0, + 0, + 0, + 0); } else { lv_label_set_text_fmt(label, "#FFFF00 Temperature#\n\n" @@ -97,6 +107,16 @@ std::unique_ptr Weather::CreateScreenAir() { std::unique_ptr& current = weatherService.GetCurrentQuality(); if (current->timestamp == 0) { // Do not use the data, it's invalid + lv_label_set_text_fmt(label, + "#FFFF00 Air quality#\n\n" + "#444444 %s#\n" + "#444444 %d#\n\n" + "%d\n" + "%d\n", + "", + 0, + 0, + 0); } else { lv_label_set_text_fmt(label, "#FFFF00 Air quality#\n\n" -- cgit v1.2.3-70-g09d2 From 9108952e6ba96f94bbd1530036318c9b21ec0cf9 Mon Sep 17 00:00:00 2001 From: Avamander Date: Wed, 1 Dec 2021 15:18:34 +0200 Subject: Implemented parsing of all defined weather data types --- src/components/ble/weather/WeatherService.cpp | 200 +++++++++++++++++++++++--- 1 file changed, 181 insertions(+), 19 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index 250b36ab..c60e0f09 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -42,15 +42,14 @@ namespace Pinetime { } int WeatherService::OnCommand(uint16_t connHandle, uint16_t attrHandle, struct ble_gatt_access_ctxt* ctxt) { - // TODO: Detect control messages if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - const uint8_t packetLen = OS_MBUF_PKTLEN(ctxt->om); + const uint8_t packetLen = OS_MBUF_PKTLEN(ctxt->om); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) if (packetLen <= 0) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } // Decode QCBORDecodeContext decodeContext; - UsefulBufC encodedCbor = {ctxt->om->om_data, OS_MBUF_PKTLEN(ctxt->om)}; + UsefulBufC encodedCbor = {ctxt->om->om_data, OS_MBUF_PKTLEN(ctxt->om)}; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) QCBORDecode_Init(&decodeContext, encodedCbor, QCBOR_DECODE_MODE_NORMAL); // KINDLY provide us a fixed-length map @@ -58,18 +57,18 @@ namespace Pinetime { // Always encodes to the smallest number of bytes based on the value int64_t tmpTimestamp = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Timestamp", &tmpTimestamp); - uint8_t err = QCBORDecode_GetError(&decodeContext); - if (err != QCBOR_SUCCESS) { + if (QCBORDecode_GetError(&decodeContext) != QCBOR_SUCCESS) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } int64_t tmpExpires = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Expires", &tmpExpires); - if (tmpExpires < 0 || tmpExpires > 4294967295) { + if (QCBORDecode_GetError(&decodeContext) != QCBOR_SUCCESS || tmpExpires < 0 || tmpExpires > 4294967295) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } int64_t tmpEventType = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "EventType", &tmpEventType); - if (tmpEventType < 0 || tmpEventType > static_cast(WeatherData::eventtype::Length)) { + if (QCBORDecode_GetError(&decodeContext) != QCBOR_SUCCESS || tmpEventType < 0 || + tmpEventType >= static_cast(WeatherData::eventtype::Length)) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } @@ -79,19 +78,24 @@ namespace Pinetime { airquality->timestamp = tmpTimestamp; airquality->eventType = static_cast(tmpEventType); airquality->expires = tmpExpires; + UsefulBufC String; // TODO: Everything ok with lifecycle here? QCBORDecode_GetTextStringInMapSZ(&decodeContext, "Polluter", &String); if (UsefulBuf_IsNULLOrEmptyC(String) != 0) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } airquality->polluter = std::string(static_cast(String.ptr), String.len); + int64_t tmpAmount = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Amount", &tmpAmount); - if (tmpAmount < 0) { + if (tmpAmount < 0 || tmpAmount > 4294967295) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + airquality->amount = tmpAmount; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) + + if (AddEventToTimeline(std::move(airquality))) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } - airquality->amount = tmpAmount; - timeline.push_back(std::move(airquality)); break; } case WeatherData::eventtype::Obscuration: { @@ -100,7 +104,23 @@ namespace Pinetime { obscuration->eventType = static_cast(tmpEventType); obscuration->expires = tmpExpires; - timeline.push_back(std::move(obscuration)); + int64_t tmpType = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Type", &tmpType); + if (tmpType < 0 || tmpType >= static_cast(WeatherData::obscurationtype::Length)) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + obscuration->type = static_cast(tmpType); + + int64_t tmpAmount = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Amount", &tmpAmount); + if (tmpAmount < 0 || tmpAmount > 65535) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + obscuration->amount = tmpAmount; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) + + if (AddEventToTimeline(std::move(obscuration))) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } break; } case WeatherData::eventtype::Precipitation: { @@ -108,7 +128,24 @@ namespace Pinetime { precipitation->timestamp = tmpTimestamp; precipitation->eventType = static_cast(tmpEventType); precipitation->expires = tmpExpires; - timeline.push_back(std::move(precipitation)); + + int64_t tmpType = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Type", &tmpType); + if (tmpType < 0 || tmpType >= static_cast(WeatherData::precipitationtype::Length)) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + precipitation->type = static_cast(tmpType); + + int64_t tmpAmount = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Amount", &tmpAmount); + if (tmpAmount < 0 || tmpAmount > 255) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + precipitation->amount = tmpAmount; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) + + if (AddEventToTimeline(std::move(precipitation))) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } break; } case WeatherData::eventtype::Wind: { @@ -116,7 +153,38 @@ namespace Pinetime { wind->timestamp = tmpTimestamp; wind->eventType = static_cast(tmpEventType); wind->expires = tmpExpires; - timeline.push_back(std::move(wind)); + + int64_t tmpMin = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "SpeedMin", &tmpMin); + if (tmpMin < 0 || tmpMin > 255) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + wind->speedMin = tmpMin; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) + + int64_t tmpMax = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "SpeedMin", &tmpMax); + if (tmpMax < 0 || tmpMax > 255) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + wind->speedMax = tmpMax; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) + + int64_t tmpDMin = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "DirectionMin", &tmpDMin); + if (tmpDMin < 0 || tmpDMin > 255) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + wind->directionMin = tmpDMin; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) + + int64_t tmpDMax = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "DirectionMax", &tmpDMax); + if (tmpDMax < 0 || tmpDMax > 255) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + wind->directionMax = tmpDMax; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) + + if (AddEventToTimeline(std::move(wind))) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } break; } case WeatherData::eventtype::Temperature: { @@ -124,7 +192,24 @@ namespace Pinetime { temperature->timestamp = tmpTimestamp; temperature->eventType = static_cast(tmpEventType); temperature->expires = tmpExpires; - timeline.push_back(std::move(temperature)); + + int64_t tmpTemperature = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Temperature", &tmpTemperature); + if (tmpTemperature < 0 || tmpTemperature > 65535) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + temperature->temperature = tmpTemperature; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) + + int64_t tmpDewPoint = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "DewPoint", &tmpDewPoint); + if (tmpDewPoint < 0 || tmpDewPoint > 65535) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + temperature->dewPoint = tmpDewPoint; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) + + if (AddEventToTimeline(std::move(temperature))) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } break; } case WeatherData::eventtype::Special: { @@ -132,7 +217,17 @@ namespace Pinetime { special->timestamp = tmpTimestamp; special->eventType = static_cast(tmpEventType); special->expires = tmpExpires; - timeline.push_back(std::move(special)); + + int64_t tmpType = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "DewPoint", &tmpType); + if (tmpType < 0 || tmpType >= static_cast(WeatherData::specialtype::Length)) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + special->type = static_cast(tmpType); + + if (AddEventToTimeline(std::move(special))) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } break; } case WeatherData::eventtype::Pressure: { @@ -140,7 +235,17 @@ namespace Pinetime { pressure->timestamp = tmpTimestamp; pressure->eventType = static_cast(tmpEventType); pressure->expires = tmpExpires; - timeline.push_back(std::move(pressure)); + + int64_t tmpDewPoint = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "DewPoint", &tmpDewPoint); + if (tmpDewPoint < 0 || tmpDewPoint >= 65535) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + pressure->pressure = tmpDewPoint; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) + + if (AddEventToTimeline(std::move(pressure))) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } break; } case WeatherData::eventtype::Location: { @@ -148,7 +253,38 @@ namespace Pinetime { location->timestamp = tmpTimestamp; location->eventType = static_cast(tmpEventType); location->expires = tmpExpires; - timeline.push_back(std::move(location)); + + UsefulBufC stringBuf; // TODO: Everything ok with lifecycle here? + QCBORDecode_GetTextStringInMapSZ(&decodeContext, "Location", &stringBuf); + if (UsefulBuf_IsNULLOrEmptyC(stringBuf) != 0) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + location->location = std::string(static_cast(stringBuf.ptr), stringBuf.len); + + int64_t tmpAltitude = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Altitude", &tmpAltitude); + if (tmpAltitude < -32768 || tmpAltitude >= 32767) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + location->altitude = static_cast(tmpAltitude); + + int64_t tmpLatitude = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Latitude", &tmpLatitude); + if (tmpLatitude < -2147483648 || tmpLatitude >= 2147483647) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + location->latitude = static_cast(tmpLatitude); + + int64_t tmpLongitude = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Longitude", &tmpLongitude); + if (tmpLongitude < -2147483648 || tmpLongitude >= 2147483647) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + location->latitude = static_cast(tmpLongitude); + + if (AddEventToTimeline(std::move(location))) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } break; } case WeatherData::eventtype::Clouds: { @@ -156,7 +292,17 @@ namespace Pinetime { clouds->timestamp = tmpTimestamp; clouds->eventType = static_cast(tmpEventType); clouds->expires = tmpExpires; - timeline.push_back(std::move(clouds)); + + int64_t tmpAmount = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Amount", &tmpAmount); + if (tmpAmount < 0 || tmpAmount > 255) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + clouds->amount = static_cast(tmpAmount); + + if (AddEventToTimeline(std::move(clouds))) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } break; } case WeatherData::eventtype::Humidity: { @@ -164,7 +310,17 @@ namespace Pinetime { humidity->timestamp = tmpTimestamp; humidity->eventType = static_cast(tmpEventType); humidity->expires = tmpExpires; - timeline.push_back(std::move(humidity)); + + int64_t tmpType = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "DewPoint", &tmpType); + if (tmpType < 0 || tmpType >= 255) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + humidity->humidity = static_cast(tmpType); + + if (AddEventToTimeline(std::move(humidity))) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } break; } default: { @@ -183,6 +339,12 @@ namespace Pinetime { // Encode uint8_t buffer[64]; QCBOREncodeContext encodeContext; + /* TODO: This is very much still a test endpoint + * it needs a characteristic UUID check + * and actual implementations that show + * what actually has to be read. + * WARN: Consider commands not part of the API for now! + */ QCBOREncode_Init(&encodeContext, UsefulBuf_FROM_BYTE_ARRAY(buffer)); QCBOREncode_OpenMap(&encodeContext); QCBOREncode_AddTextToMap(&encodeContext, "test", UsefulBuf_FROM_SZ_LITERAL("test")); -- cgit v1.2.3-70-g09d2 From 75cf5324baf760b3f463ba84126c317471266b32 Mon Sep 17 00:00:00 2001 From: Avamander Date: Wed, 1 Dec 2021 18:41:01 +0200 Subject: Fixed an incorrect decode in Humidity --- src/components/ble/weather/WeatherService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index c60e0f09..c2a1cec0 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -312,7 +312,7 @@ namespace Pinetime { humidity->expires = tmpExpires; int64_t tmpType = 0; - QCBORDecode_GetInt64InMapSZ(&decodeContext, "DewPoint", &tmpType); + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Humidity", &tmpType); if (tmpType < 0 || tmpType >= 255) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } -- cgit v1.2.3-70-g09d2 From abbfb92fa2039754c45ae10e222ffd6d5bcbd778 Mon Sep 17 00:00:00 2001 From: Avamander Date: Wed, 1 Dec 2021 18:41:26 +0200 Subject: Added new precipitation and obscuration types --- src/components/ble/weather/WeatherData.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherData.h b/src/components/ble/weather/WeatherData.h index 19b9709d..8f5ef8ea 100644 --- a/src/components/ble/weather/WeatherData.h +++ b/src/components/ble/weather/WeatherData.h @@ -51,6 +51,8 @@ namespace Pinetime { Sand = 6, /** Water particles suspended in the air; low-ish visibility; temperature is near dewpoint */ Mist = 7, + /** This is SPECIAL in the sense that the thing raining down is doing the obscuration */ + Precipitation = 8, Length }; @@ -84,6 +86,8 @@ namespace Pinetime { SnowGrains = 8, /** Needles; columns or plates of ice. Sometimes described as "diamond dust". In very cold regions */ IceCrystals = 9, + /** It's raining down ash, e.g. from a volcano */ + Ash = 10, Length }; @@ -230,9 +234,15 @@ namespace Pinetime { */ class Temperature : public TimelineHeader { public: - /** Temperature °C but multiplied by 100 (e.g. -12.50°C becomes -1250) */ + /** + * Temperature °C but multiplied by 100 (e.g. -12.50°C becomes -1250) + * -32768 is reserved for "no data" + */ int16_t temperature; - /** Dewpoint °C but multiplied by 100 (e.g. -12.50°C becomes -1250) */ + /** + * Dewpoint °C but multiplied by 100 (e.g. -12.50°C becomes -1250) + * -32768 is reserved for "no data" + */ int16_t dewPoint; }; -- cgit v1.2.3-70-g09d2 From 9525fc427321ad209de657e837c47db5237912b9 Mon Sep 17 00:00:00 2001 From: Avamander Date: Wed, 1 Dec 2021 20:54:13 +0200 Subject: Specified how values should be interpreted better --- src/components/ble/weather/WeatherData.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherData.h b/src/components/ble/weather/WeatherData.h index 8f5ef8ea..195e5021 100644 --- a/src/components/ble/weather/WeatherData.h +++ b/src/components/ble/weather/WeatherData.h @@ -190,7 +190,10 @@ namespace Pinetime { public: /** Type */ obscurationtype type; - /** Visibility distance in meters */ + /** + * Visibility distance in meters + * 65535 is reserved for unspecified + */ uint16_t amount; }; @@ -199,7 +202,9 @@ namespace Pinetime { public: /** Type */ precipitationtype type; - /** How much is it going to rain? In millimeters */ + /** How much is it going to rain? In millimeters + * 255 is reserved for unspecified + **/ uint8_t amount; }; -- cgit v1.2.3-70-g09d2 From b72c6a5bc97c786a295136742d89e6c14e1ccd72 Mon Sep 17 00:00:00 2001 From: Avamander Date: Wed, 1 Dec 2021 21:08:57 +0200 Subject: Clarified a few comments --- src/components/ble/weather/WeatherData.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherData.h b/src/components/ble/weather/WeatherData.h index 195e5021..73b15ca9 100644 --- a/src/components/ble/weather/WeatherData.h +++ b/src/components/ble/weather/WeatherData.h @@ -188,7 +188,7 @@ namespace Pinetime { /** Specifies how obscuration is stored */ class Obscuration : public TimelineHeader { public: - /** Type */ + /** Type of precipitation */ obscurationtype type; /** * Visibility distance in meters @@ -200,9 +200,10 @@ namespace Pinetime { /** Specifies how precipitation is stored */ class Precipitation : public TimelineHeader { public: - /** Type */ + /** Type of precipitation */ precipitationtype type; - /** How much is it going to rain? In millimeters + /** + * How much is it going to rain? In millimeters * 255 is reserved for unspecified **/ uint8_t amount; @@ -235,7 +236,7 @@ namespace Pinetime { * As it's annoying to figure out the dewpoint on the watch, * please send it from the companion * - * We don't do floats, microdegrees are not useful. Make sure to multiply. + * We don't do floats, picodegrees are not useful. Make sure to multiply. */ class Temperature : public TimelineHeader { public: @@ -344,7 +345,7 @@ namespace Pinetime { * ng/m³ for heavy metals * * List is not comprehensive, should be improved. - * The current ones are what watchapps assume. + * The current ones are what watchapps assume! * * Note: ppb and ppm to concentration should be calculated on the companion, using * the correct formula (taking into account temperature and air pressure) -- cgit v1.2.3-70-g09d2 From ffd6c3f0953c753b0caf151be1eb824bdd777264 Mon Sep 17 00:00:00 2001 From: Avamander Date: Wed, 1 Dec 2021 21:11:31 +0200 Subject: Removed an instance of shadowing --- src/components/ble/weather/WeatherService.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index c2a1cec0..e6d22d71 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -79,12 +79,12 @@ namespace Pinetime { airquality->eventType = static_cast(tmpEventType); airquality->expires = tmpExpires; - UsefulBufC String; // TODO: Everything ok with lifecycle here? - QCBORDecode_GetTextStringInMapSZ(&decodeContext, "Polluter", &String); - if (UsefulBuf_IsNULLOrEmptyC(String) != 0) { + UsefulBufC stringBuf; // TODO: Everything ok with lifecycle here? + QCBORDecode_GetTextStringInMapSZ(&decodeContext, "Polluter", &stringBuf); + if (UsefulBuf_IsNULLOrEmptyC(stringBuf) != 0) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } - airquality->polluter = std::string(static_cast(String.ptr), String.len); + airquality->polluter = std::string(static_cast(stringBuf.ptr), stringBuf.len); int64_t tmpAmount = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Amount", &tmpAmount); -- cgit v1.2.3-70-g09d2 From e0133cec36db56f71a2d9078c927e450ae361817 Mon Sep 17 00:00:00 2001 From: Avamander Date: Wed, 1 Dec 2021 21:20:51 +0200 Subject: Improved documentation --- src/components/ble/weather/WeatherData.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherData.h b/src/components/ble/weather/WeatherData.h index 73b15ca9..d56f481c 100644 --- a/src/components/ble/weather/WeatherData.h +++ b/src/components/ble/weather/WeatherData.h @@ -20,6 +20,24 @@ /** * Different weather events, weather data structures used by {@link WeatherService.h} * + * How to upload events to the timeline? + * + * All timeline write payloads are simply CBOR-encoded payloads of the structs described below. + * + * All payloads have a mandatory header part and the dynamic part that + * depends on the event type specified in the header. If you don't, + * you'll get an error returned. Data is relatively well-validated, + * so keep in the bounds of the data types given. + * + * Write all struct members into a single finite-sized map, and write it to the characteristic. + * Mind the MTU. + * + * How to debug? + * + * There's a Screen that you can compile into your firmware that shows currently valid events. + * You can adapt that to display something else. That part right now is very much work in progress + * because the exact requirements are not yet known. + * * * Implemented based on and other material: * https://en.wikipedia.org/wiki/METAR @@ -152,6 +170,8 @@ namespace Pinetime { /** * Valid event query + * + * NOTE: Not currently available, until needs are better known */ class ValidEventQuery { public: -- cgit v1.2.3-70-g09d2 From 797b60397c630ac93dcff1bf7cef268c20747fb3 Mon Sep 17 00:00:00 2001 From: Avamander Date: Wed, 1 Dec 2021 21:24:53 +0200 Subject: Improved documentation --- src/components/ble/weather/WeatherService.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherService.h b/src/components/ble/weather/WeatherService.h index 7accc49e..cc1a4b0d 100644 --- a/src/components/ble/weather/WeatherService.h +++ b/src/components/ble/weather/WeatherService.h @@ -94,12 +94,16 @@ namespace Pinetime { ble_uuid128_t weatherUuid {BaseUuid()}; /** - * Just write timeline data here + * Just write timeline data here. + * + * See {@link WeatherData.h} for more information. */ ble_uuid128_t weatherDataCharUuid {CharUuid(0x00, 0x01)}; /** - * This doesn't take timeline data, - * provides some control over it + * This doesn't take timeline data, provides some control over it. + * + * NOTE: Currently not supported. Companion app implementer feedback required. + * There's very little point in solidifying an API before we know the needs. */ ble_uuid128_t weatherControlCharUuid {CharUuid(0x00, 0x02)}; -- cgit v1.2.3-70-g09d2 From 154e3d27ad0053edf09db6437264028cbca8afd1 Mon Sep 17 00:00:00 2001 From: Avamander Date: Wed, 1 Dec 2021 23:45:01 +0200 Subject: Added a few helper functions --- src/components/ble/weather/WeatherService.cpp | 46 +++++++++++++++++++++++++++ src/components/ble/weather/WeatherService.h | 17 +++++++--- 2 files changed, 59 insertions(+), 4 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index e6d22d71..c8eb3c20 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -513,5 +513,51 @@ namespace Pinetime { uint64_t WeatherService::GetCurrentUnixTimestamp() const { return std::chrono::duration_cast(dateTimeController.CurrentDateTime().time_since_epoch()).count(); } + + int16_t WeatherService::getTodayMinTemp() const { + uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + uint64_t currentDayEnd = currentTimestamp - ((24 - dateTimeController.Hours()) * 60 * 60) - + ((60 - dateTimeController.Minutes()) * 60) - (60 - dateTimeController.Seconds()); + int16_t result = -32768; + for (auto&& header : this->timeline) { + if (header->eventType == WeatherData::eventtype::AirQuality && isEventStillValid(header, currentTimestamp) && + header->timestamp < currentDayEnd && + reinterpret_cast&>(header)->temperature != -32768) { + int16_t temperature = reinterpret_cast&>(header)->temperature; + if (result == -32768) { + result = temperature; + } else if (result > temperature) { + result = temperature; + } else { + // The temperature in this item is higher than the lowest we've found + } + } + } + + return result; + } + + int16_t WeatherService::getTodayMaxTemp() const { + uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + uint64_t currentDayEnd = currentTimestamp - ((24 - dateTimeController.Hours()) * 60 * 60) - + ((60 - dateTimeController.Minutes()) * 60) - (60 - dateTimeController.Seconds()); + int16_t result = -32768; + for (auto&& header : this->timeline) { + if (header->eventType == WeatherData::eventtype::AirQuality && isEventStillValid(header, currentTimestamp) && + header->timestamp < currentDayEnd && + reinterpret_cast&>(header)->temperature != -32768) { + int16_t temperature = reinterpret_cast&>(header)->temperature; + if (result == -32768) { + result = temperature; + } else if (result < temperature) { + result = temperature; + } else { + // The temperature in this item is lower than the highest we've found + } + } + } + + return result; + } } } diff --git a/src/components/ble/weather/WeatherService.h b/src/components/ble/weather/WeatherService.h index cc1a4b0d..52b0356a 100644 --- a/src/components/ble/weather/WeatherService.h +++ b/src/components/ble/weather/WeatherService.h @@ -61,6 +61,17 @@ namespace Pinetime { std::unique_ptr& GetCurrentPressure(); std::unique_ptr& GetCurrentQuality(); + /** + * Searches for the current day's maximum temperature + * @return -32768 if there's no data, degrees celcius times 100 otherwise + */ + int16_t getTodayMaxTemp() const; + /** + * Searches for the current day's minimum temperature + * @return -32768 if there's no data, degrees celcius times 100 otherwise + */ + int16_t getTodayMinTemp() const; + /* * Management functions */ @@ -75,7 +86,6 @@ namespace Pinetime { size_t GetTimelineLength() const; /** * Checks if an event of a certain type exists in the timeline - * @return */ bool HasTimelineEventOfType(WeatherData::eventtype type) const; @@ -124,6 +134,8 @@ namespace Pinetime { Pinetime::Controllers::DateTime& dateTimeController; std::vector> timeline; + std::unique_ptr nullTimelineheader = std::make_unique(); + std::unique_ptr* nullHeader; /** * Cleans up the timeline of expired events @@ -149,9 +161,6 @@ namespace Pinetime { * @return if the event is valid */ static bool isEventStillValid(const std::unique_ptr& uniquePtr, const uint64_t timestamp); - - std::unique_ptr nullTimelineheader = std::make_unique(); - std::unique_ptr* nullHeader; }; } } -- cgit v1.2.3-70-g09d2 From be7931c4fb304df077f8a795d1e6e94c522556f7 Mon Sep 17 00:00:00 2001 From: Avamander Date: Wed, 1 Dec 2021 23:47:54 +0200 Subject: Whoops, fixed a wrong type --- src/components/ble/weather/WeatherService.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index c8eb3c20..c342602e 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -520,7 +520,7 @@ namespace Pinetime { ((60 - dateTimeController.Minutes()) * 60) - (60 - dateTimeController.Seconds()); int16_t result = -32768; for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::AirQuality && isEventStillValid(header, currentTimestamp) && + if (header->eventType == WeatherData::eventtype::Temperature && isEventStillValid(header, currentTimestamp) && header->timestamp < currentDayEnd && reinterpret_cast&>(header)->temperature != -32768) { int16_t temperature = reinterpret_cast&>(header)->temperature; @@ -543,7 +543,7 @@ namespace Pinetime { ((60 - dateTimeController.Minutes()) * 60) - (60 - dateTimeController.Seconds()); int16_t result = -32768; for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::AirQuality && isEventStillValid(header, currentTimestamp) && + if (header->eventType == WeatherData::eventtype::Temperature && isEventStillValid(header, currentTimestamp) && header->timestamp < currentDayEnd && reinterpret_cast&>(header)->temperature != -32768) { int16_t temperature = reinterpret_cast&>(header)->temperature; -- cgit v1.2.3-70-g09d2 From 4a8f72bd1e77a387b1fe97d316c0f75d8c94c936 Mon Sep 17 00:00:00 2001 From: Avamander Date: Thu, 2 Dec 2021 21:12:33 +0200 Subject: Fixed a bug in DewPoint decoding --- src/components/ble/weather/WeatherService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index c342602e..e5d8053a 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -202,7 +202,7 @@ namespace Pinetime { int64_t tmpDewPoint = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "DewPoint", &tmpDewPoint); - if (tmpDewPoint < 0 || tmpDewPoint > 65535) { + if (tmpDewPoint < -32768 || tmpDewPoint > 32767) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } temperature->dewPoint = tmpDewPoint; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) -- cgit v1.2.3-70-g09d2 From 58d454b11fe3c143b37aea90772c122321a5b902 Mon Sep 17 00:00:00 2001 From: Avamander Date: Thu, 2 Dec 2021 23:49:51 +0200 Subject: Improved Temperature parsing --- src/components/ble/weather/WeatherService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index e5d8053a..a30b2270 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -195,7 +195,7 @@ namespace Pinetime { int64_t tmpTemperature = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Temperature", &tmpTemperature); - if (tmpTemperature < 0 || tmpTemperature > 65535) { + if (tmpTemperature < -32768 || tmpTemperature > 32767) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } temperature->temperature = tmpTemperature; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) -- cgit v1.2.3-70-g09d2 From 62bb6b51634b22410a96f1ca9cbe183d1e9c504c Mon Sep 17 00:00:00 2001 From: Avamander Date: Fri, 3 Dec 2021 16:28:17 +0200 Subject: Better cleanup, bugfixes and improvements in weather parsing. UI improvements --- src/components/ble/weather/WeatherService.cpp | 107 ++++++++++++++++++-------- src/components/ble/weather/WeatherService.h | 7 +- src/displayapp/DisplayApp.cpp | 7 +- src/displayapp/screens/Weather.cpp | 8 +- 4 files changed, 89 insertions(+), 40 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index a30b2270..f3be35f2 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -58,17 +58,20 @@ namespace Pinetime { int64_t tmpTimestamp = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Timestamp", &tmpTimestamp); if (QCBORDecode_GetError(&decodeContext) != QCBOR_SUCCESS) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } int64_t tmpExpires = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Expires", &tmpExpires); if (QCBORDecode_GetError(&decodeContext) != QCBOR_SUCCESS || tmpExpires < 0 || tmpExpires > 4294967295) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } int64_t tmpEventType = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "EventType", &tmpEventType); if (QCBORDecode_GetError(&decodeContext) != QCBOR_SUCCESS || tmpEventType < 0 || tmpEventType >= static_cast(WeatherData::eventtype::Length)) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } @@ -82,6 +85,7 @@ namespace Pinetime { UsefulBufC stringBuf; // TODO: Everything ok with lifecycle here? QCBORDecode_GetTextStringInMapSZ(&decodeContext, "Polluter", &stringBuf); if (UsefulBuf_IsNULLOrEmptyC(stringBuf) != 0) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } airquality->polluter = std::string(static_cast(stringBuf.ptr), stringBuf.len); @@ -89,11 +93,13 @@ namespace Pinetime { int64_t tmpAmount = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Amount", &tmpAmount); if (tmpAmount < 0 || tmpAmount > 4294967295) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } airquality->amount = tmpAmount; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) - if (AddEventToTimeline(std::move(airquality))) { + if (!AddEventToTimeline(std::move(airquality))) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } break; @@ -107,6 +113,7 @@ namespace Pinetime { int64_t tmpType = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Type", &tmpType); if (tmpType < 0 || tmpType >= static_cast(WeatherData::obscurationtype::Length)) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } obscuration->type = static_cast(tmpType); @@ -114,11 +121,13 @@ namespace Pinetime { int64_t tmpAmount = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Amount", &tmpAmount); if (tmpAmount < 0 || tmpAmount > 65535) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } obscuration->amount = tmpAmount; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) - if (AddEventToTimeline(std::move(obscuration))) { + if (!AddEventToTimeline(std::move(obscuration))) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } break; @@ -132,6 +141,7 @@ namespace Pinetime { int64_t tmpType = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Type", &tmpType); if (tmpType < 0 || tmpType >= static_cast(WeatherData::precipitationtype::Length)) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } precipitation->type = static_cast(tmpType); @@ -139,11 +149,13 @@ namespace Pinetime { int64_t tmpAmount = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Amount", &tmpAmount); if (tmpAmount < 0 || tmpAmount > 255) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } precipitation->amount = tmpAmount; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) - if (AddEventToTimeline(std::move(precipitation))) { + if (!AddEventToTimeline(std::move(precipitation))) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } break; @@ -157,6 +169,7 @@ namespace Pinetime { int64_t tmpMin = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "SpeedMin", &tmpMin); if (tmpMin < 0 || tmpMin > 255) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } wind->speedMin = tmpMin; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) @@ -164,6 +177,7 @@ namespace Pinetime { int64_t tmpMax = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "SpeedMin", &tmpMax); if (tmpMax < 0 || tmpMax > 255) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } wind->speedMax = tmpMax; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) @@ -171,6 +185,7 @@ namespace Pinetime { int64_t tmpDMin = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "DirectionMin", &tmpDMin); if (tmpDMin < 0 || tmpDMin > 255) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } wind->directionMin = tmpDMin; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) @@ -178,11 +193,13 @@ namespace Pinetime { int64_t tmpDMax = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "DirectionMax", &tmpDMax); if (tmpDMax < 0 || tmpDMax > 255) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } wind->directionMax = tmpDMax; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) - if (AddEventToTimeline(std::move(wind))) { + if (!AddEventToTimeline(std::move(wind))) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } break; @@ -196,18 +213,23 @@ namespace Pinetime { int64_t tmpTemperature = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Temperature", &tmpTemperature); if (tmpTemperature < -32768 || tmpTemperature > 32767) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } - temperature->temperature = tmpTemperature; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) + temperature->temperature = + static_cast(tmpTemperature); // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) int64_t tmpDewPoint = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "DewPoint", &tmpDewPoint); if (tmpDewPoint < -32768 || tmpDewPoint > 32767) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } - temperature->dewPoint = tmpDewPoint; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) + temperature->dewPoint = + static_cast(tmpDewPoint); // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) - if (AddEventToTimeline(std::move(temperature))) { + if (!AddEventToTimeline(std::move(temperature))) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } break; @@ -219,13 +241,15 @@ namespace Pinetime { special->expires = tmpExpires; int64_t tmpType = 0; - QCBORDecode_GetInt64InMapSZ(&decodeContext, "DewPoint", &tmpType); + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Type", &tmpType); if (tmpType < 0 || tmpType >= static_cast(WeatherData::specialtype::Length)) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } special->type = static_cast(tmpType); - if (AddEventToTimeline(std::move(special))) { + if (!AddEventToTimeline(std::move(special))) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } break; @@ -236,14 +260,16 @@ namespace Pinetime { pressure->eventType = static_cast(tmpEventType); pressure->expires = tmpExpires; - int64_t tmpDewPoint = 0; - QCBORDecode_GetInt64InMapSZ(&decodeContext, "DewPoint", &tmpDewPoint); - if (tmpDewPoint < 0 || tmpDewPoint >= 65535) { + int64_t tmpPressure = 0; + QCBORDecode_GetInt64InMapSZ(&decodeContext, "Pressure", &tmpPressure); + if (tmpPressure < 0 || tmpPressure >= 65535) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } - pressure->pressure = tmpDewPoint; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) + pressure->pressure = tmpPressure; // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) - if (AddEventToTimeline(std::move(pressure))) { + if (!AddEventToTimeline(std::move(pressure))) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } break; @@ -257,6 +283,7 @@ namespace Pinetime { UsefulBufC stringBuf; // TODO: Everything ok with lifecycle here? QCBORDecode_GetTextStringInMapSZ(&decodeContext, "Location", &stringBuf); if (UsefulBuf_IsNULLOrEmptyC(stringBuf) != 0) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } location->location = std::string(static_cast(stringBuf.ptr), stringBuf.len); @@ -264,6 +291,7 @@ namespace Pinetime { int64_t tmpAltitude = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Altitude", &tmpAltitude); if (tmpAltitude < -32768 || tmpAltitude >= 32767) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } location->altitude = static_cast(tmpAltitude); @@ -271,6 +299,7 @@ namespace Pinetime { int64_t tmpLatitude = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Latitude", &tmpLatitude); if (tmpLatitude < -2147483648 || tmpLatitude >= 2147483647) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } location->latitude = static_cast(tmpLatitude); @@ -278,11 +307,13 @@ namespace Pinetime { int64_t tmpLongitude = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Longitude", &tmpLongitude); if (tmpLongitude < -2147483648 || tmpLongitude >= 2147483647) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } location->latitude = static_cast(tmpLongitude); - if (AddEventToTimeline(std::move(location))) { + if (!AddEventToTimeline(std::move(location))) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } break; @@ -296,11 +327,13 @@ namespace Pinetime { int64_t tmpAmount = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Amount", &tmpAmount); if (tmpAmount < 0 || tmpAmount > 255) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } clouds->amount = static_cast(tmpAmount); - if (AddEventToTimeline(std::move(clouds))) { + if (!AddEventToTimeline(std::move(clouds))) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } break; @@ -314,17 +347,20 @@ namespace Pinetime { int64_t tmpType = 0; QCBORDecode_GetInt64InMapSZ(&decodeContext, "Humidity", &tmpType); if (tmpType < 0 || tmpType >= 255) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } humidity->humidity = static_cast(tmpType); - if (AddEventToTimeline(std::move(humidity))) { + if (!AddEventToTimeline(std::move(humidity))) { + CleanUpQcbor(&decodeContext); return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } break; } default: { - break; + CleanUpQcbor(&decodeContext); + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } } @@ -369,7 +405,7 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentClouds() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Clouds && isEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::Clouds && IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -380,7 +416,7 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentObscuration() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Obscuration && isEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::Obscuration && IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -391,7 +427,7 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentPrecipitation() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Precipitation && isEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::Precipitation && IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -402,7 +438,7 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentWind() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Wind && isEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::Wind && IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -413,7 +449,7 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentTemperature() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Temperature && isEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::Temperature && IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -424,7 +460,7 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentHumidity() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Humidity && isEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::Humidity && IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -435,7 +471,7 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentPressure() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Pressure && isEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::Pressure && IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -446,7 +482,7 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentLocation() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Location && isEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::Location && IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -457,7 +493,7 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentQuality() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::AirQuality && isEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::AirQuality && IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -481,7 +517,7 @@ namespace Pinetime { bool WeatherService::HasTimelineEventOfType(const WeatherData::eventtype type) const { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : timeline) { - if (header->eventType == type && isEventStillValid(header, currentTimestamp)) { + if (header->eventType == type && IsEventStillValid(header, currentTimestamp)) { return true; } } @@ -493,7 +529,7 @@ namespace Pinetime { timeline.erase(std::remove_if(std::begin(timeline), std::end(timeline), [&](std::unique_ptr const& header) { - return !isEventStillValid(header, timeCurrent); + return !IsEventStillValid(header, timeCurrent); }), std::end(timeline)); @@ -505,9 +541,9 @@ namespace Pinetime { return first->timestamp > second->timestamp; } - bool WeatherService::isEventStillValid(const std::unique_ptr& header, const uint64_t currentTimestamp) { + bool WeatherService::IsEventStillValid(const std::unique_ptr& uniquePtr, const uint64_t timestamp) { // Not getting timestamp in isEventStillValid for more speed - return header->timestamp + header->expires <= currentTimestamp; + return uniquePtr->timestamp + uniquePtr->expires >= timestamp; } uint64_t WeatherService::GetCurrentUnixTimestamp() const { @@ -520,7 +556,7 @@ namespace Pinetime { ((60 - dateTimeController.Minutes()) * 60) - (60 - dateTimeController.Seconds()); int16_t result = -32768; for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Temperature && isEventStillValid(header, currentTimestamp) && + if (header->eventType == WeatherData::eventtype::Temperature && IsEventStillValid(header, currentTimestamp) && header->timestamp < currentDayEnd && reinterpret_cast&>(header)->temperature != -32768) { int16_t temperature = reinterpret_cast&>(header)->temperature; @@ -543,7 +579,7 @@ namespace Pinetime { ((60 - dateTimeController.Minutes()) * 60) - (60 - dateTimeController.Seconds()); int16_t result = -32768; for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Temperature && isEventStillValid(header, currentTimestamp) && + if (header->eventType == WeatherData::eventtype::Temperature && IsEventStillValid(header, currentTimestamp) && header->timestamp < currentDayEnd && reinterpret_cast&>(header)->temperature != -32768) { int16_t temperature = reinterpret_cast&>(header)->temperature; @@ -559,5 +595,10 @@ namespace Pinetime { return result; } + + void WeatherService::CleanUpQcbor(QCBORDecodeContext* decodeContext) { + QCBORDecode_ExitMap(decodeContext); + QCBORDecode_Finish(decodeContext); + } } } diff --git a/src/components/ble/weather/WeatherService.h b/src/components/ble/weather/WeatherService.h index 52b0356a..a9f02b16 100644 --- a/src/components/ble/weather/WeatherService.h +++ b/src/components/ble/weather/WeatherService.h @@ -30,7 +30,8 @@ #undef min #include "WeatherData.h" -#include +#include "libs/QCBOR/inc/qcbor/qcbor.h" +#include "components/datetime/DateTimeController.h" int WeatherCallback(uint16_t connHandle, uint16_t attrHandle, struct ble_gatt_access_ctxt* ctxt, void* arg); @@ -160,7 +161,9 @@ namespace Pinetime { * @param currentTimestamp what's the time right now * @return if the event is valid */ - static bool isEventStillValid(const std::unique_ptr& uniquePtr, const uint64_t timestamp); + static bool IsEventStillValid(const std::unique_ptr& uniquePtr, const uint64_t timestamp); + + void CleanUpQcbor(QCBORDecodeContext* decodeContext); }; } } diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 80155187..d45251b9 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -1,5 +1,6 @@ #include "displayapp/DisplayApp.h" #include +#include #include "displayapp/screens/HeartRate.h" #include "displayapp/screens/Motion.h" #include "displayapp/screens/Timer.h" @@ -439,7 +440,8 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) currentScreen = std::make_unique(this, systemTask->nimble().music()); break; case Apps::Navigation: - currentScreen = std::make_unique(this, systemTask->nimble().navigation()); + currentScreen = std::make_unique(this, systemTask->nimble().weather()); + // currentScreen = std::make_unique(this, systemTask->nimble().navigation()); break; case Apps::HeartRate: currentScreen = std::make_unique(this, heartRateController, *systemTask); @@ -451,6 +453,9 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) case Apps::Motion: currentScreen = std::make_unique(this, motionController); break; + case Apps::Weather: + currentScreen = std::make_unique(this, systemTask->nimble().weather()); + break; case Apps::Steps: currentScreen = std::make_unique(this, motionController, settingsController); break; diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp index c9852ee1..d4241194 100644 --- a/src/displayapp/screens/Weather.cpp +++ b/src/displayapp/screens/Weather.cpp @@ -76,22 +76,22 @@ std::unique_ptr Weather::CreateScreenTemperature() { // Do not use the data, it's invalid lv_label_set_text_fmt(label, "#FFFF00 Temperature#\n\n" - "#444444 %d#\n\n" + "#444444 %.2f#°C \n\n" "#444444 %d#\n\n" "%d\n" "%d\n", - 0, + 0.0f, 0, 0, 0); } else { lv_label_set_text_fmt(label, "#FFFF00 Temperature#\n\n" - "#444444 %hd%%#°C \n\n" + "#444444 %.2f#°C \n\n" "#444444 %hd#\n\n" "%llu\n" "%lu\n", - current->temperature, + current->temperature / 100.0f, current->dewPoint, current->timestamp, current->expires); -- cgit v1.2.3-70-g09d2 From 7b04ce5ebaf1d73feac529bd16828415e5a046c7 Mon Sep 17 00:00:00 2001 From: Avamander Date: Fri, 3 Dec 2021 17:38:23 +0200 Subject: Added a note about the timestamp having a timezone offset --- src/components/ble/weather/WeatherData.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherData.h b/src/components/ble/weather/WeatherData.h index d56f481c..42572ec0 100644 --- a/src/components/ble/weather/WeatherData.h +++ b/src/components/ble/weather/WeatherData.h @@ -182,7 +182,11 @@ namespace Pinetime { /** The header used for further parsing */ class TimelineHeader { public: - /** UNIX timestamp */ + /** + * UNIX timestamp + * TODO: This is currently WITH A TIMEZONE OFFSET! + * Please send events with the timestamp offset by the timezone. + **/ uint64_t timestamp; /** * Time in seconds until the event expires -- cgit v1.2.3-70-g09d2 From f1f2bc119a7c855613616ecaf5c8aa72390cde14 Mon Sep 17 00:00:00 2001 From: Avamander Date: Sat, 4 Dec 2021 13:58:40 +0200 Subject: Added a note about map key capitalization --- src/components/ble/weather/WeatherData.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/components/ble') diff --git a/src/components/ble/weather/WeatherData.h b/src/components/ble/weather/WeatherData.h index 42572ec0..613d5acb 100644 --- a/src/components/ble/weather/WeatherData.h +++ b/src/components/ble/weather/WeatherData.h @@ -29,7 +29,7 @@ * you'll get an error returned. Data is relatively well-validated, * so keep in the bounds of the data types given. * - * Write all struct members into a single finite-sized map, and write it to the characteristic. + * Write all struct members (CamelCase keys) into a single finite-sized map, and write it to the characteristic. * Mind the MTU. * * How to debug? -- cgit v1.2.3-70-g09d2 From 3eebe66d659c9c8e72a7c355973c74c2b8899174 Mon Sep 17 00:00:00 2001 From: Avamander Date: Sat, 4 Dec 2021 17:12:34 +0200 Subject: Updated docs and renamed functions for consistency --- doc/ble.md | 18 +++++++++++------- src/components/ble/weather/WeatherService.cpp | 4 ++-- src/components/ble/weather/WeatherService.h | 11 +++++++---- 3 files changed, 20 insertions(+), 13 deletions(-) (limited to 'src/components/ble') diff --git a/doc/ble.md b/doc/ble.md index 8573166f..2b86243e 100644 --- a/doc/ble.md +++ b/doc/ble.md @@ -2,7 +2,7 @@ ## Introduction This page describes the BLE implementation and API built in this firmware. -**Note** : I'm a beginner in BLE related technologies and the information in this document reflects my current knowledge and understanding of the BLE stack. This information might be erroneous or incomplete. Feel free to submit a PR if you think you can improve it. +**Note**: I'm a beginner in BLE related technologies and the information in this document reflects my current knowledge and understanding of the BLE stack. This information might be erroneous or incomplete. Feel free to submit a PR if you think you can improve it. --- @@ -72,12 +72,16 @@ The following custom services are implemented in InfiniTime: * [Navigation Service](NavigationService.md) : 00010000-78fc-48fe-8e23-433b3a1942d0 - - Since InfiniTime 0.13 - * Call characteristic (extension to the Alert Notification Service): 00020001-78fc-48fe-8e23-433b3a1942d0 - - - - Since InfiniTime 1.7: - * [Motion Service](MotionService.md) : 00030000-78fc-48fe-8e23-433b3a1942d0 +- Since InfiniTime 0.13 + * Call characteristic (extension to the Alert Notification Service): 00020001-78fc-48fe-8e23-433b3a1942d0 + + +- Since InfiniTime 1.7: + * [Motion Service](MotionService.md): 00030000-78fc-48fe-8e23-433b3a1942d0 + + +- Since InfiniTime 1.8: + * [Weather Service](/src/components/ble/weather/WeatherService.h): 00040000-78fc-48fe-8e23-433b3a1942d0 --- diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index f3be35f2..23f53b74 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -550,7 +550,7 @@ namespace Pinetime { return std::chrono::duration_cast(dateTimeController.CurrentDateTime().time_since_epoch()).count(); } - int16_t WeatherService::getTodayMinTemp() const { + int16_t WeatherService::GetTodayMinTemp() const { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); uint64_t currentDayEnd = currentTimestamp - ((24 - dateTimeController.Hours()) * 60 * 60) - ((60 - dateTimeController.Minutes()) * 60) - (60 - dateTimeController.Seconds()); @@ -573,7 +573,7 @@ namespace Pinetime { return result; } - int16_t WeatherService::getTodayMaxTemp() const { + int16_t WeatherService::GetTodayMaxTemp() const { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); uint64_t currentDayEnd = currentTimestamp - ((24 - dateTimeController.Hours()) * 60 * 60) - ((60 - dateTimeController.Minutes()) * 60) - (60 - dateTimeController.Seconds()); diff --git a/src/components/ble/weather/WeatherService.h b/src/components/ble/weather/WeatherService.h index a9f02b16..eca70cbd 100644 --- a/src/components/ble/weather/WeatherService.h +++ b/src/components/ble/weather/WeatherService.h @@ -64,14 +64,14 @@ namespace Pinetime { /** * Searches for the current day's maximum temperature - * @return -32768 if there's no data, degrees celcius times 100 otherwise + * @return -32768 if there's no data, degrees Celsius times 100 otherwise */ - int16_t getTodayMaxTemp() const; + int16_t GetTodayMaxTemp() const; /** * Searches for the current day's minimum temperature - * @return -32768 if there's no data, degrees celcius times 100 otherwise + * @return -32768 if there's no data, degrees Celsius times 100 otherwise */ - int16_t getTodayMinTemp() const; + int16_t GetTodayMinTemp() const; /* * Management functions @@ -163,6 +163,9 @@ namespace Pinetime { */ static bool IsEventStillValid(const std::unique_ptr& uniquePtr, const uint64_t timestamp); + /** + * This is a helper function that closes a QCBOR map and decoding context cleanly + */ void CleanUpQcbor(QCBORDecodeContext* decodeContext); }; } -- cgit v1.2.3-70-g09d2 From 62dbcbfc953a36202d96466563a8e71b8bd4ff65 Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Sat, 30 Oct 2021 13:02:39 -0500 Subject: Connect and bond with a passkey This commit adds the following: Passkey pairing - passkey is displayed on watch Swipe down to clear passkey screen Connection encryption Connection bonding Automatic reconnects to a bonded peripheral Trusted device on Android Note that persisting the bond between reboots is NOT included in this commit. Therefore, rebooting the watch will cause reconnect failures. You must delete the bond from the phone to reconnect/pair. --- src/CMakeLists.txt | 2 + src/components/ble/BatteryInformationService.cpp | 2 +- src/components/ble/BleController.h | 11 ++- src/components/ble/NimbleController.cpp | 106 +++++++++++++++------ src/displayapp/Apps.h | 1 + src/displayapp/DisplayApp.cpp | 9 ++ src/displayapp/Messages.h | 1 + src/displayapp/screens/PassKey.cpp | 17 ++++ src/displayapp/screens/PassKey.h | 20 ++++ .../porting/nimble/include/syscfg/syscfg.h | 16 ++-- src/sdk_config.h | 2 +- src/systemtask/Messages.h | 1 + src/systemtask/SystemTask.cpp | 7 ++ 13 files changed, 154 insertions(+), 41 deletions(-) create mode 100644 src/displayapp/screens/PassKey.cpp create mode 100644 src/displayapp/screens/PassKey.h (limited to 'src/components/ble') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e727b2b0..fecd09dd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -154,6 +154,7 @@ set(NIMBLE_SRC libs/mynewt-nimble/nimble/controller/src/ble_ll_supp_cmd.c libs/mynewt-nimble/nimble/controller/src/ble_ll_hci_ev.c libs/mynewt-nimble/nimble/controller/src/ble_ll_rfmgmt.c + libs/mynewt-nimble/nimble/controller/src/ble_ll_resolv.c libs/mynewt-nimble/porting/nimble/src/os_cputime.c libs/mynewt-nimble/porting/nimble/src/os_cputime_pwr2.c libs/mynewt-nimble/porting/nimble/src/os_mbuf.c @@ -421,6 +422,7 @@ list(APPEND SOURCE_FILES displayapp/screens/BatteryInfo.cpp displayapp/screens/Steps.cpp displayapp/screens/Timer.cpp + displayapp/screens/PassKey.cpp displayapp/screens/Error.cpp displayapp/screens/Alarm.cpp displayapp/Colors.cpp diff --git a/src/components/ble/BatteryInformationService.cpp b/src/components/ble/BatteryInformationService.cpp index 9a3f86f5..82df7b15 100644 --- a/src/components/ble/BatteryInformationService.cpp +++ b/src/components/ble/BatteryInformationService.cpp @@ -17,7 +17,7 @@ BatteryInformationService::BatteryInformationService(Controllers::Battery& batte characteristicDefinition {{.uuid = &batteryLevelUuid.u, .access_cb = BatteryInformationServiceCallback, .arg = this, - .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_READ_AUTHEN | BLE_GATT_CHR_F_NOTIFY, .val_handle = &batteryLevelHandle}, {0}}, serviceDefinition { diff --git a/src/components/ble/BleController.h b/src/components/ble/BleController.h index 2cba26a9..72b87663 100644 --- a/src/components/ble/BleController.h +++ b/src/components/ble/BleController.h @@ -9,7 +9,7 @@ namespace Pinetime { public: using BleAddress = std::array; enum class FirmwareUpdateStates { Idle, Running, Validated, Error }; - enum class AddressTypes { Public, Random }; + enum class AddressTypes { Public, Random, RPA_Public, RPA_Random }; Ble() = default; bool IsConnected() const { @@ -48,6 +48,12 @@ namespace Pinetime { void AddressType(AddressTypes t) { addressType = t; } + void SetPairingKey(uint32_t k) { + pairingKey = k; + } + uint32_t GetPairingKey() const { + return pairingKey; + } private: bool isConnected = false; @@ -57,6 +63,7 @@ namespace Pinetime { FirmwareUpdateStates firmwareUpdateState = FirmwareUpdateStates::Idle; BleAddress address; AddressTypes addressType; + uint32_t pairingKey = 0; }; } -} \ No newline at end of file +} diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 43a8b0d6..01901e0a 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -1,4 +1,6 @@ #include "components/ble/NimbleController.h" +#include + #include #define min // workaround: nimble's min/max macros conflict with libstdc++ #define max @@ -6,6 +8,7 @@ #include #include #include +#include #undef max #undef min #include @@ -45,16 +48,18 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, } void nimble_on_reset(int reason) { - NRF_LOG_INFO("Resetting state; reason=%d\n", reason); + NRF_LOG_INFO("Nimble lost sync, resetting state; reason=%d", reason); } void nimble_on_sync(void) { - int rc; + int rc; - rc = ble_hs_util_ensure_addr(0); - ASSERT(rc == 0); + NRF_LOG_INFO("Nimble is synced"); + + rc = ble_hs_util_ensure_addr(0); + ASSERT(rc == 0); - nptr->StartAdvertising(); + nptr->StartAdvertising(); } int GAPEventCallback(struct ble_gap_event* event, void* arg) { @@ -69,6 +74,7 @@ void NimbleController::Init() { nptr = this; ble_hs_cfg.reset_cb = nimble_on_reset; ble_hs_cfg.sync_cb = nimble_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; ble_svc_gap_init(); ble_svc_gatt_init(); @@ -97,8 +103,22 @@ void NimbleController::Init() { Pinetime::Controllers::Ble::BleAddress address; rc = ble_hs_id_copy_addr(addrType, address.data(), nullptr); ASSERT(rc == 0); - bleController.AddressType((addrType == 0) ? Ble::AddressTypes::Public : Ble::AddressTypes::Random); + bleController.Address(std::move(address)); + switch (addrType) { + case BLE_OWN_ADDR_PUBLIC: + bleController.AddressType(Ble::AddressTypes::Public); + break; + case BLE_OWN_ADDR_RANDOM: + bleController.AddressType(Ble::AddressTypes::Random); + break; + case BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT: + bleController.AddressType(Ble::AddressTypes::RPA_Public); + break; + case BLE_OWN_ADDR_RPA_RANDOM_DEFAULT: + bleController.AddressType(Ble::AddressTypes::RPA_Random); + break; + } rc = ble_gatts_start(); ASSERT(rc == 0); @@ -108,17 +128,10 @@ void NimbleController::Init() { } void NimbleController::StartAdvertising() { - int rc; - - /* set adv parameters */ struct ble_gap_adv_params adv_params; struct ble_hs_adv_fields fields; - /* advertising payload is split into advertising data and advertising - response, because all data cannot fit into single packet; name of device - is sent as response to scan request */ struct ble_hs_adv_fields rsp_fields; - /* fill all fields and parameters with zeros */ memset(&adv_params, 0, sizeof(adv_params)); memset(&fields, 0, sizeof(fields)); memset(&rsp_fields, 0, sizeof(rsp_fields)); @@ -141,10 +154,11 @@ void NimbleController::StartAdvertising() { fields.uuids128_is_complete = 1; fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; - rsp_fields.name = (uint8_t*) deviceName; + rsp_fields.name = reinterpret_cast(deviceName); rsp_fields.name_len = strlen(deviceName); rsp_fields.name_is_complete = 1; + int rc; rc = ble_gap_adv_set_fields(&fields); ASSERT(rc == 0); @@ -159,15 +173,14 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { switch (event->type) { case BLE_GAP_EVENT_ADV_COMPLETE: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_ADV_COMPLETE"); - NRF_LOG_INFO("reason=%d; status=%d", event->adv_complete.reason, event->connect.status); + NRF_LOG_INFO("reason=%d; status=%0X", event->adv_complete.reason, event->connect.status); StartAdvertising(); break; case BLE_GAP_EVENT_CONNECT: - NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_CONNECT"); - /* A new connection was established or a connection attempt failed. */ - NRF_LOG_INFO("connection %s; status=%d ", event->connect.status == 0 ? "established" : "failed", event->connect.status); + NRF_LOG_INFO("Connect event : BLE_GAP_EVENT_CONNECT"); + NRF_LOG_INFO("connection %s; status=%0X ", event->connect.status == 0 ? "established" : "failed", event->connect.status); if (event->connect.status != 0) { /* Connection failed; resume advertising. */ @@ -186,10 +199,9 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { break; case BLE_GAP_EVENT_DISCONNECT: - NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_DISCONNECT"); - NRF_LOG_INFO("disconnect reason=%d", event->disconnect.reason); - /* Connection terminated; resume advertising. */ + NRF_LOG_INFO("Disconnect event : BLE_GAP_EVENT_DISCONNECT"); + NRF_LOG_INFO("disconnect reason=%d", event->disconnect.reason); currentTimeClient.Reset(); alertNotificationClient.Reset(); connectionHandle = BLE_HS_CONN_HANDLE_NONE; @@ -199,18 +211,45 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { break; case BLE_GAP_EVENT_CONN_UPDATE: - NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_CONN_UPDATE"); /* The central has updated the connection parameters. */ - NRF_LOG_INFO("update status=%d ", event->conn_update.status); + NRF_LOG_INFO("Update event : BLE_GAP_EVENT_CONN_UPDATE"); + NRF_LOG_INFO("update status=%0X ", event->conn_update.status); + break; + + case BLE_GAP_EVENT_CONN_UPDATE_REQ: + /* The central has requested updated connection parameters */ + NRF_LOG_INFO("Update event : BLE_GAP_EVENT_CONN_UPDATE_REQ"); + NRF_LOG_INFO("update request : itvl_min=%d itvl_max=%d latency=%d supervision=%d", + event->conn_update_req.peer_params->itvl_min, + event->conn_update_req.peer_params->itvl_max, + event->conn_update_req.peer_params->latency, + event->conn_update_req.peer_params->supervision_timeout); break; case BLE_GAP_EVENT_ENC_CHANGE: /* Encryption has been enabled or disabled for this connection. */ - NRF_LOG_INFO("encryption change event; status=%d ", event->enc_change.status); + NRF_LOG_INFO("Security event : BLE_GAP_EVENT_ENC_CHANGE"); + NRF_LOG_INFO("encryption change event; status=%0X ", event->enc_change.status); + break; + + case BLE_GAP_EVENT_PASSKEY_ACTION: + /* Authentication has been requested for this connection. + * Standards insist that the rand() PRNG be deterministic. + * Use the nimble TRNG since rand() is predictable. + */ + NRF_LOG_INFO("Security event : BLE_GAP_EVENT_PASSKEY_ACTION"); + if (event->passkey.params.action == BLE_SM_IOACT_DISP) { + struct ble_sm_io pkey = {0}; + pkey.action = event->passkey.params.action; + pkey.passkey = ble_ll_rand() % 1000000; + bleController.SetPairingKey(pkey.passkey); + systemTask.PushMessage(Pinetime::System::Messages::OnPairing); + ble_sm_inject_io(event->passkey.conn_handle, &pkey); + } break; case BLE_GAP_EVENT_SUBSCRIBE: - NRF_LOG_INFO("subscribe event; conn_handle=%d attr_handle=%d " + NRF_LOG_INFO("Subscribe event; conn_handle=%d attr_handle=%d " "reason=%d prevn=%d curn=%d previ=%d curi=???\n", event->subscribe.conn_handle, event->subscribe.attr_handle, @@ -234,11 +273,11 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { break; case BLE_GAP_EVENT_MTU: - NRF_LOG_INFO("mtu update event; conn_handle=%d cid=%d mtu=%d\n", - event->mtu.conn_handle, event->mtu.channel_id, event->mtu.value); + NRF_LOG_INFO("MTU Update event; conn_handle=%d cid=%d mtu=%d", event->mtu.conn_handle, event->mtu.channel_id, event->mtu.value); break; case BLE_GAP_EVENT_REPEAT_PAIRING: { + NRF_LOG_INFO("Pairing event : BLE_GAP_EVENT_REPEAT_PAIRING"); /* We already have a bond with the peer, but it is attempting to * establish a new secure link. This app sacrifices security for * convenience: just throw away the old bond and accept the new link. @@ -257,6 +296,8 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { case BLE_GAP_EVENT_NOTIFY_RX: { /* Peer sent us a notification or indication. */ + /* Attribute data is contained in event->notify_rx.attr_data. */ + NRF_LOG_INFO("Notify event : BLE_GAP_EVENT_NOTIFY_RX"); size_t notifSize = OS_MBUF_PKTLEN(event->notify_rx.om); NRF_LOG_INFO("received %s; conn_handle=%d attr_handle=%d " @@ -268,10 +309,17 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { alertNotificationClient.OnNotification(event); } break; - /* Attribute data is contained in event->notify_rx.attr_data. */ + + case BLE_GAP_EVENT_NOTIFY_TX: + NRF_LOG_INFO("Notify event : BLE_GAP_EVENT_NOTIFY_TX"); + break; + + case BLE_GAP_EVENT_IDENTITY_RESOLVED: + NRF_LOG_INFO("Identity event : BLE_GAP_EVENT_IDENTITY_RESOLVED"); + break; default: - // NRF_LOG_INFO("Advertising event : %d", event->type); + NRF_LOG_INFO("UNHANDLED GAP event : %d", event->type); break; } return 0; diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h index d340efee..935a61a1 100644 --- a/src/displayapp/Apps.h +++ b/src/displayapp/Apps.h @@ -25,6 +25,7 @@ namespace Pinetime { Metronome, Motion, Steps, + PassKey, QuickSettings, Settings, SettingWatchFace, diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 80155187..08a76467 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -29,6 +29,7 @@ #include "displayapp/screens/FlashLight.h" #include "displayapp/screens/BatteryInfo.h" #include "displayapp/screens/Steps.h" +#include "displayapp/screens/PassKey.h" #include "displayapp/screens/Error.h" #include "drivers/Cst816s.h" @@ -288,6 +289,9 @@ void DisplayApp::Refresh() { // Added to remove warning // What should happen here? break; + case Messages::ShowPairingKey: + LoadApp(Apps::PassKey, DisplayApp::FullRefreshDirections::Up); + break; } } @@ -351,6 +355,11 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::None); break; + case Apps::PassKey: + currentScreen = std::make_unique(this, bleController.GetPairingKey()); + ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::SwipeDown); + break; + case Apps::Notifications: currentScreen = std::make_unique( this, notificationManager, systemTask->nimble().alertService(), motorController, Screens::Notifications::Modes::Normal); diff --git a/src/displayapp/Messages.h b/src/displayapp/Messages.h index 29e09eb3..b22d6c3c 100644 --- a/src/displayapp/Messages.h +++ b/src/displayapp/Messages.h @@ -19,6 +19,7 @@ namespace Pinetime { UpdateTimeOut, DimScreen, RestoreBrightness, + ShowPairingKey, AlarmTriggered }; } diff --git a/src/displayapp/screens/PassKey.cpp b/src/displayapp/screens/PassKey.cpp new file mode 100644 index 00000000..66bf0c24 --- /dev/null +++ b/src/displayapp/screens/PassKey.cpp @@ -0,0 +1,17 @@ +#include "PassKey.h" +#include "displayapp/DisplayApp.h" + +using namespace Pinetime::Applications::Screens; + +PassKey::PassKey(Pinetime::Applications::DisplayApp* app, uint32_t key) : Screen(app) { + lpasskey = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(lpasskey, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xFFFF00)); + lv_obj_set_style_local_text_font(lpasskey, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); + lv_label_set_text_fmt(lpasskey, "%06u", key); + lv_obj_align(lpasskey, nullptr, LV_ALIGN_CENTER, 0, -20); +} + +PassKey::~PassKey() { + lv_obj_clean(lv_scr_act()); +} + diff --git a/src/displayapp/screens/PassKey.h b/src/displayapp/screens/PassKey.h new file mode 100644 index 00000000..34e0d593 --- /dev/null +++ b/src/displayapp/screens/PassKey.h @@ -0,0 +1,20 @@ +#pragma once + +#include "Screen.h" +#include + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class PassKey : public Screen { + public: + PassKey(DisplayApp* app, uint32_t key); + ~PassKey() override; + + private: + lv_obj_t* lpasskey; + }; + } + } +} diff --git a/src/libs/mynewt-nimble/porting/nimble/include/syscfg/syscfg.h b/src/libs/mynewt-nimble/porting/nimble/include/syscfg/syscfg.h index 94b72cb6..b3f23411 100644 --- a/src/libs/mynewt-nimble/porting/nimble/include/syscfg/syscfg.h +++ b/src/libs/mynewt-nimble/porting/nimble/include/syscfg/syscfg.h @@ -699,11 +699,11 @@ #endif #ifndef MYNEWT_VAL_BLE_SM_BONDING -#define MYNEWT_VAL_BLE_SM_BONDING (0) +#define MYNEWT_VAL_BLE_SM_BONDING (1) #endif #ifndef MYNEWT_VAL_BLE_SM_IO_CAP -#define MYNEWT_VAL_BLE_SM_IO_CAP (BLE_HS_IO_NO_INPUT_OUTPUT) +#define MYNEWT_VAL_BLE_SM_IO_CAP (BLE_HS_IO_DISPLAY_ONLY) #endif #ifndef MYNEWT_VAL_BLE_SM_KEYPRESS @@ -711,7 +711,7 @@ #endif #ifndef MYNEWT_VAL_BLE_SM_LEGACY -#define MYNEWT_VAL_BLE_SM_LEGACY (1) +#define MYNEWT_VAL_BLE_SM_LEGACY (0) #endif #ifndef MYNEWT_VAL_BLE_SM_MAX_PROCS @@ -719,7 +719,7 @@ #endif #ifndef MYNEWT_VAL_BLE_SM_MITM -#define MYNEWT_VAL_BLE_SM_MITM (0) +#define MYNEWT_VAL_BLE_SM_MITM (1) #endif #ifndef MYNEWT_VAL_BLE_SM_OOB_DATA_FLAG @@ -727,11 +727,11 @@ #endif #ifndef MYNEWT_VAL_BLE_SM_OUR_KEY_DIST -#define MYNEWT_VAL_BLE_SM_OUR_KEY_DIST (0) +#define MYNEWT_VAL_BLE_SM_OUR_KEY_DIST (7) #endif #ifndef MYNEWT_VAL_BLE_SM_SC -#define MYNEWT_VAL_BLE_SM_SC (0) +#define MYNEWT_VAL_BLE_SM_SC (1) #endif #ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS @@ -739,7 +739,7 @@ #endif #ifndef MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST -#define MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST (0) +#define MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST (3) #endif #ifndef MYNEWT_VAL_BLE_STORE_MAX_BONDS @@ -1089,7 +1089,7 @@ /* Overridden by @apache-mynewt-nimble/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PRIVACY -#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PRIVACY (0) +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PRIVACY (1) #endif #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG diff --git a/src/sdk_config.h b/src/sdk_config.h index 38d47a7f..7634dca1 100644 --- a/src/sdk_config.h +++ b/src/sdk_config.h @@ -12580,4 +12580,4 @@ #endif // <<< end of configuration section >>> -#endif // SDK_CONFIG_H \ No newline at end of file +#endif // SDK_CONFIG_H diff --git a/src/systemtask/Messages.h b/src/systemtask/Messages.h index b7142704..516f6462 100644 --- a/src/systemtask/Messages.h +++ b/src/systemtask/Messages.h @@ -22,6 +22,7 @@ namespace Pinetime { DisableSleeping, OnNewDay, OnChargingEvent, + OnPairing, SetOffAlarm, StopRinging, MeasureBatteryTimerExpired, diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 1120b80d..2fb4de51 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -396,6 +396,13 @@ void SystemTask::Work() { case Messages::BatteryPercentageUpdated: nimbleController.NotifyBatteryLevel(batteryController.PercentRemaining()); break; + case Messages::OnPairing: + if (isSleeping && !isWakingUp) { + GoToRunning(); + } + motorController.RunForDuration(35); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::ShowPairingKey); + break; default: break; -- cgit v1.2.3-70-g09d2 From 150fa3b6615e524a072a1af6d6728519381fa737 Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Sat, 4 Dec 2021 14:49:49 -0600 Subject: Persist bond between reboots Save bond information in the FS after a disconnect or encryption change if the bond is not already stored. The bond is restored on boot enabling automatic reconnection to a previously bonded central. Two consecutive watch reboots with the central out of range (or BLE off) will remove the stored bond from the watch. --- src/components/ble/NimbleController.cpp | 113 ++++++++++++++++++++++++++++++-- src/components/ble/NimbleController.h | 11 +++- src/systemtask/SystemTask.cpp | 3 +- 3 files changed, 117 insertions(+), 10 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 01901e0a..ec411989 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #undef max #undef min #include @@ -16,6 +17,7 @@ #include "components/ble/BleController.h" #include "components/ble/NotificationManager.h" #include "components/datetime/DateTimeController.h" +#include "components/fs/FS.h" #include "systemtask/SystemTask.h" using namespace Pinetime::Controllers; @@ -27,7 +29,8 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, Controllers::Battery& batteryController, Pinetime::Drivers::SpiNorFlash& spiNorFlash, Controllers::HeartRateController& heartRateController, - Controllers::MotionController& motionController) + Controllers::MotionController& motionController, + Pinetime::Controllers::FS& fs) : systemTask {systemTask}, bleController {bleController}, dateTimeController {dateTimeController}, @@ -43,7 +46,8 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, batteryInformationService {batteryController}, immediateAlertService {systemTask, notificationManager}, heartRateService {systemTask, heartRateController}, - motionService{systemTask, motionController}, + fs {fs}, + motionService {systemTask, motionController}, serviceDiscovery({¤tTimeClient, &alertNotificationClient}) { } @@ -123,6 +127,8 @@ void NimbleController::Init() { rc = ble_gatts_start(); ASSERT(rc == 0); + RestoreBond(); + if (!ble_gap_adv_active() && !bleController.IsConnected()) StartAdvertising(); } @@ -202,6 +208,10 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { /* Connection terminated; resume advertising. */ NRF_LOG_INFO("Disconnect event : BLE_GAP_EVENT_DISCONNECT"); NRF_LOG_INFO("disconnect reason=%d", event->disconnect.reason); + + if (event->disconnect.conn.sec_state.bonded) + PersistBond(event->disconnect.conn); + currentTimeClient.Reset(); alertNotificationClient.Reset(); connectionHandle = BLE_HS_CONN_HANDLE_NONE; @@ -230,6 +240,19 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { /* Encryption has been enabled or disabled for this connection. */ NRF_LOG_INFO("Security event : BLE_GAP_EVENT_ENC_CHANGE"); NRF_LOG_INFO("encryption change event; status=%0X ", event->enc_change.status); + + if (event->enc_change.status == 0) { + struct ble_gap_conn_desc desc; + ble_gap_conn_find(event->enc_change.conn_handle, &desc); + if (desc.sec_state.bonded) + PersistBond(desc); + + NRF_LOG_INFO("new state: encrypted=%d authenticated=%d bonded=%d key_size=%d", + desc.sec_state.encrypted, + desc.sec_state.authenticated, + desc.sec_state.bonded, + desc.sec_state.key_size); + } break; case BLE_GAP_EVENT_PASSKEY_ACTION: @@ -258,15 +281,13 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { event->subscribe.cur_notify, event->subscribe.prev_indicate); - if(event->subscribe.reason == BLE_GAP_SUBSCRIBE_REASON_TERM) { + if (event->subscribe.reason == BLE_GAP_SUBSCRIBE_REASON_TERM) { heartRateService.UnsubscribeNotification(event->subscribe.conn_handle, event->subscribe.attr_handle); motionService.UnsubscribeNotification(event->subscribe.conn_handle, event->subscribe.attr_handle); - } - else if(event->subscribe.prev_notify == 0 && event->subscribe.cur_notify == 1) { + } else if (event->subscribe.prev_notify == 0 && event->subscribe.cur_notify == 1) { heartRateService.SubscribeNotification(event->subscribe.conn_handle, event->subscribe.attr_handle); motionService.SubscribeNotification(event->subscribe.conn_handle, event->subscribe.attr_handle); - } - else if(event->subscribe.prev_notify == 1 && event->subscribe.cur_notify == 0) { + } else if (event->subscribe.prev_notify == 1 && event->subscribe.cur_notify == 0) { heartRateService.UnsubscribeNotification(event->subscribe.conn_handle, event->subscribe.attr_handle); motionService.UnsubscribeNotification(event->subscribe.conn_handle, event->subscribe.attr_handle); } @@ -340,3 +361,81 @@ void NimbleController::NotifyBatteryLevel(uint8_t level) { batteryInformationService.NotifyBatteryLevel(connectionHandle, level); } } + +void NimbleController::PersistBond(struct ble_gap_conn_desc& desc) { + union ble_store_key key; + union ble_store_value our_sec, peer_sec, peer_cccd_set[MYNEWT_VAL(BLE_STORE_MAX_CCCDS)] = {0}; + int rc; + + memset(&key, 0, sizeof key); + memset(&our_sec, 0, sizeof our_sec); + key.sec.peer_addr = desc.peer_id_addr; + rc = ble_store_read_our_sec(&key.sec, &our_sec.sec); + + if (memcmp(&our_sec.sec, &bondId, sizeof bondId) == 0) + return; + + memcpy(&bondId, &our_sec.sec, sizeof bondId); + + memset(&key, 0, sizeof key); + memset(&peer_sec, 0, sizeof peer_sec); + key.sec.peer_addr = desc.peer_id_addr; + rc += ble_store_read_peer_sec(&key.sec, &peer_sec.sec); + + if (rc == 0) { + memset(&key, 0, sizeof key); + key.cccd.peer_addr = desc.peer_id_addr; + int peer_count = 0; + ble_store_util_count(BLE_STORE_OBJ_TYPE_CCCD, &peer_count); + for (int i = 0; i < peer_count; i++) { + key.cccd.idx = peer_count; + ble_store_read_cccd(&key.cccd, &peer_cccd_set[i].cccd); + } + + /* Wakeup Spi and SpiNorFlash before accessing the file system + * This should be fixed in the FS driver + */ + systemTask.PushMessage(Pinetime::System::Messages::GoToRunning); + systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping); + vTaskDelay(10); + + lfs_file_t file_p; + + rc = fs.FileOpen(&file_p, "/bond.dat", LFS_O_WRONLY | LFS_O_CREAT); + if (rc == 0) { + fs.FileWrite(&file_p, reinterpret_cast(&our_sec.sec), sizeof our_sec); + fs.FileWrite(&file_p, reinterpret_cast(&peer_sec.sec), sizeof peer_sec); + fs.FileWrite(&file_p, reinterpret_cast(&peer_count), 1); + for (int i = 0; i < peer_count; i++) { + fs.FileWrite(&file_p, reinterpret_cast(&peer_cccd_set[i].cccd), sizeof(struct ble_store_value_cccd)); + } + fs.FileClose(&file_p); + } + systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping); + } +} + +void NimbleController::RestoreBond() { + lfs_file_t file_p; + union ble_store_value sec, cccd; + uint8_t peer_count = 0; + + if (fs.FileOpen(&file_p, "/bond.dat", LFS_O_RDONLY) == 0) { + memset(&sec, 0, sizeof sec); + fs.FileRead(&file_p, reinterpret_cast(&sec.sec), sizeof sec); + ble_store_write_our_sec(&sec.sec); + + memset(&sec, 0, sizeof sec); + fs.FileRead(&file_p, reinterpret_cast(&sec.sec), sizeof sec); + ble_store_write_peer_sec(&sec.sec); + + fs.FileRead(&file_p, &peer_count, 1); + for (int i = 0; i < peer_count; i++) { + fs.FileRead(&file_p, reinterpret_cast(&cccd.cccd), sizeof(struct ble_store_value_cccd)); + ble_store_write_cccd(&cccd.cccd); + } + + fs.FileClose(&file_p); + fs.FileDelete("/bond.dat"); + } +} diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 895b87f2..944e8cad 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -20,6 +20,7 @@ #include "components/ble/ServiceDiscovery.h" #include "components/ble/HeartRateService.h" #include "components/ble/MotionService.h" +#include "components/fs/FS.h" namespace Pinetime { namespace Drivers { @@ -45,7 +46,8 @@ namespace Pinetime { Controllers::Battery& batteryController, Pinetime::Drivers::SpiNorFlash& spiNorFlash, Controllers::HeartRateController& heartRateController, - Controllers::MotionController& motionController); + Controllers::MotionController& motionController, + Pinetime::Controllers::FS& fs); void Init(); void StartAdvertising(); int OnGAPEvent(ble_gap_event* event); @@ -78,6 +80,9 @@ namespace Pinetime { fastAdvCount = 0; } + void PersistBond(struct ble_gap_conn_desc &desc); + void RestoreBond(); + private: static constexpr const char* deviceName = "InfiniTime"; Pinetime::System::SystemTask& systemTask; @@ -98,10 +103,12 @@ namespace Pinetime { ImmediateAlertService immediateAlertService; HeartRateService heartRateService; MotionService motionService; + Pinetime::Controllers::FS& fs; uint8_t addrType; // 1 = Random, 0 = PUBLIC uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE; uint8_t fastAdvCount = 0; + uint8_t bondId[16] = {0}; ble_uuid128_t dfuServiceUuid { .u {.type = BLE_UUID_TYPE_128}, @@ -110,6 +117,6 @@ namespace Pinetime { ServiceDiscovery serviceDiscovery; }; - static NimbleController* nptr; + static NimbleController* nptr; } } diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 2fb4de51..215c78a5 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -109,7 +109,8 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, batteryController, spiNorFlash, heartRateController, - motionController) { + motionController, + fs) { } void SystemTask::Start() { -- cgit v1.2.3-70-g09d2 From 048ecd41e414a9abc8c3d09423b8f5cb99304309 Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Wed, 8 Dec 2021 00:10:54 -0600 Subject: Adjust BLE/LL stacks, style, comments, refactoring Increase BLE task stack +200 and decrease LL task stack -200 more braces! --- src/components/ble/NimbleController.cpp | 29 ++++++++++++++++------ src/components/ble/NimbleController.h | 13 +++++----- .../npl/freertos/src/nimble_port_freertos.c | 4 +-- src/systemtask/SystemTask.cpp | 3 ++- 4 files changed, 31 insertions(+), 18 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index ec411989..0f20aefe 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -10,10 +10,10 @@ #include #include #include -#undef max -#undef min #include #include +#undef max +#undef min #include "components/ble/BleController.h" #include "components/ble/NotificationManager.h" #include "components/datetime/DateTimeController.h" @@ -36,7 +36,9 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, dateTimeController {dateTimeController}, notificationManager {notificationManager}, spiNorFlash {spiNorFlash}, + fs {fs}, dfuService {systemTask, bleController, spiNorFlash}, + currentTimeClient {dateTimeController}, anService {systemTask, notificationManager}, alertNotificationClient {systemTask, notificationManager}, @@ -46,7 +48,6 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, batteryInformationService {batteryController}, immediateAlertService {systemTask, notificationManager}, heartRateService {systemTask, heartRateController}, - fs {fs}, motionService {systemTask, motionController}, serviceDiscovery({¤tTimeClient, &alertNotificationClient}) { } @@ -129,8 +130,9 @@ void NimbleController::Init() { RestoreBond(); - if (!ble_gap_adv_active() && !bleController.IsConnected()) + if (!ble_gap_adv_active() && !bleController.IsConnected()) { StartAdvertising(); + } } void NimbleController::StartAdvertising() { @@ -209,8 +211,9 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { NRF_LOG_INFO("Disconnect event : BLE_GAP_EVENT_DISCONNECT"); NRF_LOG_INFO("disconnect reason=%d", event->disconnect.reason); - if (event->disconnect.conn.sec_state.bonded) + if (event->disconnect.conn.sec_state.bonded) { PersistBond(event->disconnect.conn); + } currentTimeClient.Reset(); alertNotificationClient.Reset(); @@ -244,8 +247,9 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { if (event->enc_change.status == 0) { struct ble_gap_conn_desc desc; ble_gap_conn_find(event->enc_change.conn_handle, &desc); - if (desc.sec_state.bonded) + if (desc.sec_state.bonded) { PersistBond(desc); + } NRF_LOG_INFO("new state: encrypted=%d authenticated=%d bonded=%d key_size=%d", desc.sec_state.encrypted, @@ -257,8 +261,16 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { case BLE_GAP_EVENT_PASSKEY_ACTION: /* Authentication has been requested for this connection. + * + * BLE authentication is determined by the combination of I/O capabilities + * on the central and peripheral. When the peripheral is display only and + * the central has a keyboard and display then passkey auth is selected. + * When both the central and peripheral have displays and support yes/no + * buttons then numeric comparison is selected. We currently advertise + * display capability only so we only handle the "display" action here. + * * Standards insist that the rand() PRNG be deterministic. - * Use the nimble TRNG since rand() is predictable. + * Use the nimble TRNG here since rand() is predictable. */ NRF_LOG_INFO("Security event : BLE_GAP_EVENT_PASSKEY_ACTION"); if (event->passkey.params.action == BLE_SM_IOACT_DISP) { @@ -372,8 +384,9 @@ void NimbleController::PersistBond(struct ble_gap_conn_desc& desc) { key.sec.peer_addr = desc.peer_id_addr; rc = ble_store_read_our_sec(&key.sec, &our_sec.sec); - if (memcmp(&our_sec.sec, &bondId, sizeof bondId) == 0) + if (memcmp(&our_sec.sec, &bondId, sizeof bondId) == 0) { return; + } memcpy(&bondId, &our_sec.sec, sizeof bondId); diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 944e8cad..7569ce2a 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -14,11 +14,11 @@ #include "components/ble/CurrentTimeService.h" #include "components/ble/DeviceInformationService.h" #include "components/ble/DfuService.h" +#include "components/ble/HeartRateService.h" #include "components/ble/ImmediateAlertService.h" #include "components/ble/MusicService.h" #include "components/ble/NavigationService.h" #include "components/ble/ServiceDiscovery.h" -#include "components/ble/HeartRateService.h" #include "components/ble/MotionService.h" #include "components/fs/FS.h" @@ -80,16 +80,17 @@ namespace Pinetime { fastAdvCount = 0; } - void PersistBond(struct ble_gap_conn_desc &desc); + private: + void PersistBond(struct ble_gap_conn_desc& desc); void RestoreBond(); - private: static constexpr const char* deviceName = "InfiniTime"; Pinetime::System::SystemTask& systemTask; Pinetime::Controllers::Ble& bleController; DateTime& dateTimeController; Pinetime::Controllers::NotificationManager& notificationManager; Pinetime::Drivers::SpiNorFlash& spiNorFlash; + Pinetime::Controllers::FS& fs; Pinetime::Controllers::DfuService dfuService; DeviceInformationService deviceInformationService; @@ -103,9 +104,9 @@ namespace Pinetime { ImmediateAlertService immediateAlertService; HeartRateService heartRateService; MotionService motionService; - Pinetime::Controllers::FS& fs; + ServiceDiscovery serviceDiscovery; - uint8_t addrType; // 1 = Random, 0 = PUBLIC + uint8_t addrType; uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE; uint8_t fastAdvCount = 0; uint8_t bondId[16] = {0}; @@ -113,8 +114,6 @@ namespace Pinetime { ble_uuid128_t dfuServiceUuid { .u {.type = BLE_UUID_TYPE_128}, .value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, 0xDE, 0xEF, 0x12, 0x12, 0x30, 0x15, 0x00, 0x00}}; - - ServiceDiscovery serviceDiscovery; }; static NimbleController* nptr; diff --git a/src/libs/mynewt-nimble/porting/npl/freertos/src/nimble_port_freertos.c b/src/libs/mynewt-nimble/porting/npl/freertos/src/nimble_port_freertos.c index 8ee3475a..b9902781 100644 --- a/src/libs/mynewt-nimble/porting/npl/freertos/src/nimble_port_freertos.c +++ b/src/libs/mynewt-nimble/porting/npl/freertos/src/nimble_port_freertos.c @@ -37,7 +37,7 @@ nimble_port_freertos_init(TaskFunction_t host_task_fn) * provided by NimBLE and in case of FreeRTOS it does not need to be wrapped * since it has compatible prototype. */ - xTaskCreate(nimble_port_ll_task_func, "ll", configMINIMAL_STACK_SIZE + 400, + xTaskCreate(nimble_port_ll_task_func, "ll", configMINIMAL_STACK_SIZE + 200, NULL, configMAX_PRIORITIES - 1, &ll_task_h); #endif @@ -46,6 +46,6 @@ nimble_port_freertos_init(TaskFunction_t host_task_fn) * have separate task for NimBLE host, but since something needs to handle * default queue it is just easier to make separate task which does this. */ - xTaskCreate(host_task_fn, "ble", configMINIMAL_STACK_SIZE + 400, + xTaskCreate(host_task_fn, "ble", configMINIMAL_STACK_SIZE + 600, NULL, tskIDLE_PRIORITY + 1, &host_task_h); } diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 215c78a5..79384a5b 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -259,8 +259,9 @@ void SystemTask::Work() { displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToRunning); heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp); - if (!bleController.IsConnected()) + if (!bleController.IsConnected()) { nimbleController.RestartFastAdv(); + } isSleeping = false; isWakingUp = false; -- cgit v1.2.3-70-g09d2 From f57f797ff54d9ee8864d3fc62f0c8662df13aad8 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Sun, 17 Oct 2021 01:09:26 +0000 Subject: Added Blank FSService that exposes only version info --- src/CMakeLists.txt | 3 ++ src/components/ble/FSService.cpp | 55 ++++++++++++++++++++++++++++ src/components/ble/FSService.h | 65 +++++++++++++++++++++++++++++++++ src/components/ble/NimbleController.cpp | 9 +++-- src/components/ble/NimbleController.h | 3 ++ 5 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 src/components/ble/FSService.cpp create mode 100644 src/components/ble/FSService.h (limited to 'src/components/ble') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bb9f76fe..809544c9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -487,6 +487,7 @@ list(APPEND SOURCE_FILES components/ble/NavigationService.cpp displayapp/fonts/lv_font_navi_80.c components/ble/BatteryInformationService.cpp + components/ble/FSService.cpp components/ble/ImmediateAlertService.cpp components/ble/ServiceDiscovery.cpp components/ble/HeartRateService.cpp @@ -557,6 +558,7 @@ list(APPEND RECOVERY_SOURCE_FILES components/ble/MusicService.cpp components/ble/weather/WeatherService.cpp components/ble/BatteryInformationService.cpp + components/ble/FSService.cpp components/ble/ImmediateAlertService.cpp components/ble/ServiceDiscovery.cpp components/ble/NavigationService.cpp @@ -669,6 +671,7 @@ set(INCLUDE_FILES components/ble/DfuService.h components/firmwarevalidator/FirmwareValidator.h components/ble/BatteryInformationService.h + components/ble/FSService.h components/ble/ImmediateAlertService.h components/ble/ServiceDiscovery.h components/ble/BleClient.h diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp new file mode 100644 index 00000000..6551c20c --- /dev/null +++ b/src/components/ble/FSService.cpp @@ -0,0 +1,55 @@ +#include +#include "FSService.h" + +using namespace Pinetime::Controllers; + +constexpr ble_uuid128_t FSService::fsServiceUuid; +constexpr ble_uuid128_t FSService::fsVersionUuid; +constexpr ble_uuid128_t FSService::fsTransferUuid; + +int FSServiceCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) { + auto* fsService = static_cast(arg); + return fsService->OnFSServiceRequested(conn_handle, attr_handle, ctxt); +} + +FSService::FSService(Pinetime::Controllers::FS& fs) + : fs {fs}, + characteristicDefinition {{.uuid = &fsVersionUuid.u, + .access_cb = FSServiceCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_READ, + .val_handle = &versionCharacteristicHandle}, + { + .uuid = &fsTransferUuid.u, + .access_cb = FSServiceCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY, + .val_handle = nullptr, + }, + {0}}, + serviceDefinition { + {/* Device Information Service */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &fsServiceUuid.u, + .characteristics = characteristicDefinition}, + {0}, + } { +} + +void FSService::Init() { + int res = 0; + res = ble_gatts_count_cfg(serviceDefinition); + ASSERT(res == 0); + + res = ble_gatts_add_svcs(serviceDefinition); + ASSERT(res == 0); +} + +int FSService::OnFSServiceRequested(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt* context) { + if (attributeHandle == versionCharacteristicHandle) { + NRF_LOG_INFO("FS_S : handle = %d", versionCharacteristicHandle); + int res = os_mbuf_append(context->om, &fsVersion, sizeof(fsVersion)); + return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + return 0; +} diff --git a/src/components/ble/FSService.h b/src/components/ble/FSService.h new file mode 100644 index 00000000..85b484a3 --- /dev/null +++ b/src/components/ble/FSService.h @@ -0,0 +1,65 @@ +#pragma once +#define min // workaround: nimble's min/max macros conflict with libstdc++ +#define max +#include +#undef max +#undef min +#include "components/fs/FS.h" + +namespace Pinetime { + namespace System { + class SystemTask; + } + namespace Controllers { + class Ble; + class FSService { + public: + FSService(Pinetime::Controllers::FS& fs); + void Init(); + + int OnFSServiceRequested(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt* context); + void NotifyFSRaw(uint16_t connectionHandle); + + private: + Pinetime::Controllers::FS& fs; + static constexpr uint16_t FSServiceId {0xFEBB}; + static constexpr uint16_t fsVersionId {0x0100}; + static constexpr uint16_t fsTransferId {0x0200}; + uint16_t fsVersion = {0x0004}; + + static constexpr ble_uuid128_t fsServiceUuid { + .u {.type = BLE_UUID_TYPE_128}, + .value = {0x72, 0x65, 0x66, 0x73, 0x6e, 0x61, 0x72, 0x54, 0x65, 0x6c, 0x69, 0x46, 0xBB, 0xFE, 0xAF, 0xAD}}; + + static constexpr ble_uuid128_t fsVersionUuid { + .u {.type = BLE_UUID_TYPE_128}, + .value = {0x72, 0x65, 0x66, 0x73, 0x6e, 0x61, 0x72, 0x54, 0x65, 0x6c, 0x69, 0x46, 0x00, 0x01, 0xAF, 0xAD}}; + + static constexpr ble_uuid128_t fsTransferUuid { + .u {.type = BLE_UUID_TYPE_128}, + .value = {0x72, 0x65, 0x66, 0x73, 0x6e, 0x61, 0x72, 0x54, 0x65, 0x6c, 0x69, 0x46, 0x00, 0x02, 0xAF, 0xAD}}; + + struct ble_gatt_chr_def characteristicDefinition[3]; + struct ble_gatt_svc_def serviceDefinition[2]; + uint16_t versionCharacteristicHandle; + + enum class commands { + INVALID = 0x00, + READ = 0x10, + READ_DATA = 0x11, + READ_PACING = 0x12, + WRITE = 0x20, + WRITE_PACING = 0x21, + WRITE_DATA = 0x22, + DELETE = 0x30, + DELETE_STATUS = 0x31, + MKDIR = 0x40, + MKDIR_STATUS = 0x41, + LISTDIR = 0x50, + LISTDIR_ENTRY = 0x51, + MOVE = 0x60, + MOVE_STATUS = 0x61, + } + }; + } +} diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index acf4f94b..b5eb46b8 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -30,7 +30,7 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, Pinetime::Drivers::SpiNorFlash& spiNorFlash, Controllers::HeartRateController& heartRateController, Controllers::MotionController& motionController, - Pinetime::Controllers::FS& fs) + Controllers::FS& fs) : systemTask {systemTask}, bleController {bleController}, dateTimeController {dateTimeController}, @@ -49,7 +49,9 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, batteryInformationService {batteryController}, immediateAlertService {systemTask, notificationManager}, heartRateService {systemTask, heartRateController}, - motionService {systemTask, motionController}, + motionService{systemTask, motionController}, + fs {fs}, + fsService {fs}, serviceDiscovery({¤tTimeClient, &alertNotificationClient}) { } @@ -97,7 +99,8 @@ void NimbleController::Init() { immediateAlertService.Init(); heartRateService.Init(); motionService.Init(); - + fsService.Init(); + int rc; rc = ble_hs_util_ensure_addr(0); ASSERT(rc == 0); diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 12bd6924..14749b8d 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -22,6 +22,7 @@ #include "components/ble/MotionService.h" #include "components/ble/weather/WeatherService.h" #include "components/fs/FS.h" +#include "components/ble/FSService.h" namespace Pinetime { namespace Drivers { @@ -110,6 +111,8 @@ namespace Pinetime { HeartRateService heartRateService; MotionService motionService; ServiceDiscovery serviceDiscovery; + FS fs; + FSService fsService; uint8_t addrType; uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE; -- cgit v1.2.3-70-g09d2 From 91c644b43c250b0a03047349182828df31ddcbd2 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Sun, 17 Oct 2021 16:04:23 +0000 Subject: direcetory listings maybe? Added LISTDIR command and notify responses. --- src/components/ble/FSService.cpp | 73 ++++++++++++++++++++++++++++++++++++++-- src/components/ble/FSService.h | 27 +++++++++++++-- src/components/fs/FS.cpp | 63 +++++++++++++++++++--------------- src/components/fs/FS.h | 3 ++ 4 files changed, 132 insertions(+), 34 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index 6551c20c..2cfd5ccd 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -1,5 +1,6 @@ #include #include "FSService.h" +#include "components/ble/BleController.h" using namespace Pinetime::Controllers; @@ -13,8 +14,8 @@ int FSServiceCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gat } FSService::FSService(Pinetime::Controllers::FS& fs) - : fs {fs}, - characteristicDefinition {{.uuid = &fsVersionUuid.u, + : fs {fs}, + characteristicDefinition {{.uuid = &fsVersionUuid.u, .access_cb = FSServiceCallback, .arg = this, .flags = BLE_GATT_CHR_F_READ, @@ -24,7 +25,7 @@ FSService::FSService(Pinetime::Controllers::FS& fs) .access_cb = FSServiceCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY, - .val_handle = nullptr, + .val_handle = &transferCharacteristicHandle, }, {0}}, serviceDefinition { @@ -51,5 +52,71 @@ int FSService::OnFSServiceRequested(uint16_t connectionHandle, uint16_t attribut int res = os_mbuf_append(context->om, &fsVersion, sizeof(fsVersion)); return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } + if (attributeHandle == transferCharacteristicHandle) { + return FSCommandHandler(connectionHandle, context->om); + } + return 0; +} + +int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { + auto command = static_cast(om->om_data[0]); + NRF_LOG_INFO("[FS_S] -> FSCommandHandler"); + + switch (command) { + case commands::LISTDIR: { + NRF_LOG_INFO("[FS_S] -> ListDir"); + ListDirHeader *header = (ListDirHeader *)&om->om_data[0]; + uint16_t plen = header->pathlen; + char path[plen+1] = {0}; + memcpy(path, header->pathstr, plen); + NRF_LOG_INFO("[FS_S] -> DIR %.10s", path); + lfs_dir_t dir; + struct lfs_info info; + + ListDirResponse resp; + resp.command = 0x51; // LISTDIR_ENTRY; + resp.status = 1; // TODO actually use res above! + resp.totalentries = 0; + resp.entry = 0; + int res = fs.DirOpen(path, &dir); + while (fs.DirRead(&dir, &info)) { + resp.totalentries++; + } + NRF_LOG_INFO("[FS_S] -> %d ", resp.totalentries); + fs.DirClose(&dir); + fs.DirOpen(path, &dir); + while (fs.DirRead(&dir, &info)) { + switch(info.type){ + case LFS_TYPE_REG: + { + resp.flags = 0; + resp.file_size = info.size; + break; + } + case LFS_TYPE_DIR: + { + resp.flags = 1; + resp.file_size = 0; + break; + } + } + resp.modification_time = 0; // TODO Does LFS actually support TS? + strcpy(resp.path,info.name); + resp.path_length = strlen(info.name); + NRF_LOG_INFO("[FS_S] ->Path %s ,", info.name); + auto* om = ble_hs_mbuf_from_flat(&resp,sizeof(ListDirResponse)); + ble_gattc_notify_custom(connectionHandle,transferCharacteristicHandle,om); + resp.entry++; + } + resp.entry++; + resp.file_size = 0; + resp.path_length = 0; + resp.flags = 0; + //Todo this better + auto* om = ble_hs_mbuf_from_flat(&resp,sizeof(ListDirResponse)-70+resp.path_length); + ble_gattc_notify_custom(connectionHandle,transferCharacteristicHandle,om); + NRF_LOG_INFO("[FS_S] -> done "); + } + } return 0; } diff --git a/src/components/ble/FSService.h b/src/components/ble/FSService.h index 85b484a3..eb4b34d7 100644 --- a/src/components/ble/FSService.h +++ b/src/components/ble/FSService.h @@ -4,6 +4,7 @@ #include #undef max #undef min + #include "components/fs/FS.h" namespace Pinetime { @@ -42,8 +43,26 @@ namespace Pinetime { struct ble_gatt_chr_def characteristicDefinition[3]; struct ble_gatt_svc_def serviceDefinition[2]; uint16_t versionCharacteristicHandle; + uint16_t transferCharacteristicHandle; + typedef struct __attribute__((packed)) { + uint8_t command; + uint8_t padding; + uint16_t pathlen; + char pathstr[70]; + } ListDirHeader; + typedef struct __attribute__((packed)) { + uint8_t command; + uint8_t status; + uint16_t path_length; + uint32_t entry; + uint32_t totalentries; + uint32_t flags; + uint32_t modification_time; + uint32_t file_size; + char path[70]; + } ListDirResponse; - enum class commands { + enum class commands : uint8_t { INVALID = 0x00, READ = 0x10, READ_DATA = 0x11, @@ -58,8 +77,10 @@ namespace Pinetime { LISTDIR = 0x50, LISTDIR_ENTRY = 0x51, MOVE = 0x60, - MOVE_STATUS = 0x61, - } + MOVE_STATUS = 0x61 + }; + + int FSCommandHandler(uint16_t connectionHandle, os_mbuf* om); }; } } diff --git a/src/components/fs/FS.cpp b/src/components/fs/FS.cpp index 1cad4f02..f287c28e 100644 --- a/src/components/fs/FS.cpp +++ b/src/components/fs/FS.cpp @@ -5,29 +5,28 @@ using namespace Pinetime::Controllers; -FS::FS(Pinetime::Drivers::SpiNorFlash& driver) : - flashDriver{ driver }, - lfsConfig{ - .context = this, - .read = SectorRead, - .prog = SectorProg, - .erase = SectorErase, - .sync = SectorSync, - - .read_size = 16, - .prog_size = 8, - .block_size = blockSize, - .block_count = size / blockSize, - .block_cycles = 1000u, - - .cache_size = 16, - .lookahead_size = 16, - - .name_max = 50, - .attr_max = 50, - } -{ } - +FS::FS(Pinetime::Drivers::SpiNorFlash& driver) + : flashDriver {driver}, + lfsConfig { + .context = this, + .read = SectorRead, + .prog = SectorProg, + .erase = SectorErase, + .sync = SectorSync, + + .read_size = 16, + .prog_size = 8, + .block_size = blockSize, + .block_count = size / blockSize, + .block_cycles = 1000u, + + .cache_size = 16, + .lookahead_size = 16, + + .name_max = 50, + .attr_max = 50, + } { +} void FS::Init() { @@ -48,7 +47,6 @@ void FS::Init() { VerifyResource(); LVGLFileSystemInit(); #endif - } void FS::VerifyResource() { @@ -56,7 +54,7 @@ void FS::VerifyResource() { resourcesValid = true; } -int FS::FileOpen(lfs_file_t* file_p, const char* fileName, const int flags) { +int FS::FileOpen(lfs_file_t* file_p, const char* fileName, const int flags) { return lfs_file_open(&lfs, file_p, fileName, flags); } @@ -80,6 +78,17 @@ int FS::FileDelete(const char* fileName) { return lfs_remove(&lfs, fileName); } +int FS::DirOpen(const char* path, lfs_dir_t* lfs_dir) { + return lfs_dir_open(&lfs, lfs_dir, path); +} + +int FS::DirClose(lfs_dir_t* lfs_dir) { + return lfs_dir_close(&lfs, lfs_dir); +} + +int FS::DirRead(lfs_dir_t* dir, lfs_info* info) { + return lfs_dir_read(&lfs, dir, info); +} int FS::DirCreate(const char* path) { return lfs_mkdir(&lfs, path); @@ -148,8 +157,7 @@ namespace { if (file->type == 0) { return LV_FS_RES_FS_ERR; - } - else { + } else { return LV_FS_RES_OK; } } @@ -193,5 +201,4 @@ void FS::LVGLFileSystemInit() { fs_drv.user_data = this; lv_fs_drv_register(&fs_drv); - } \ No newline at end of file diff --git a/src/components/fs/FS.h b/src/components/fs/FS.h index 75ba16c8..28d28d3c 100644 --- a/src/components/fs/FS.h +++ b/src/components/fs/FS.h @@ -21,6 +21,9 @@ namespace Pinetime { int FileDelete(const char* fileName); + int DirOpen(const char* path, lfs_dir_t* lfs_dir); + int DirClose(lfs_dir_t* lfs_dir); + int DirRead(lfs_dir_t* dir, lfs_info* info); int DirCreate(const char* path); int DirDelete(const char* path); -- cgit v1.2.3-70-g09d2 From 1dd71744802b4ae80c8952f73bbf0051fbe12cf3 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Sun, 17 Oct 2021 20:48:34 +0000 Subject: More reliable FS listing --- src/components/ble/FSService.cpp | 17 ++++++++++++----- src/components/fs/FS.cpp | 4 +++- src/components/fs/FS.h | 1 + 3 files changed, 16 insertions(+), 6 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index 2cfd5ccd..2f02cd96 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -70,21 +70,26 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { char path[plen+1] = {0}; memcpy(path, header->pathstr, plen); NRF_LOG_INFO("[FS_S] -> DIR %.10s", path); - lfs_dir_t dir; - struct lfs_info info; + lfs_dir_t dir = {}; + struct lfs_info info = {}; - ListDirResponse resp; + ListDirResponse resp = {}; resp.command = 0x51; // LISTDIR_ENTRY; resp.status = 1; // TODO actually use res above! resp.totalentries = 0; resp.entry = 0; + int sr; int res = fs.DirOpen(path, &dir); + + NRF_LOG_INFO("[FS_S] ->diropen %d ", res); while (fs.DirRead(&dir, &info)) { resp.totalentries++; + } NRF_LOG_INFO("[FS_S] -> %d ", resp.totalentries); - fs.DirClose(&dir); - fs.DirOpen(path, &dir); + + fs.DirRewind(&dir); + while (fs.DirRead(&dir, &info)) { switch(info.type){ case LFS_TYPE_REG: @@ -106,8 +111,10 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { NRF_LOG_INFO("[FS_S] ->Path %s ,", info.name); auto* om = ble_hs_mbuf_from_flat(&resp,sizeof(ListDirResponse)); ble_gattc_notify_custom(connectionHandle,transferCharacteristicHandle,om); + vTaskDelay(1); //Allow stuff to actually go out over the BLE conn resp.entry++; } + fs.DirClose(&dir); resp.entry++; resp.file_size = 0; resp.path_length = 0; diff --git a/src/components/fs/FS.cpp b/src/components/fs/FS.cpp index f287c28e..353193dc 100644 --- a/src/components/fs/FS.cpp +++ b/src/components/fs/FS.cpp @@ -89,7 +89,9 @@ int FS::DirClose(lfs_dir_t* lfs_dir) { int FS::DirRead(lfs_dir_t* dir, lfs_info* info) { return lfs_dir_read(&lfs, dir, info); } - +int FS::DirRewind(lfs_dir_t* dir) { + return lfs_dir_rewind(&lfs, dir); +} int FS::DirCreate(const char* path) { return lfs_mkdir(&lfs, path); } diff --git a/src/components/fs/FS.h b/src/components/fs/FS.h index 28d28d3c..ccff2409 100644 --- a/src/components/fs/FS.h +++ b/src/components/fs/FS.h @@ -24,6 +24,7 @@ namespace Pinetime { int DirOpen(const char* path, lfs_dir_t* lfs_dir); int DirClose(lfs_dir_t* lfs_dir); int DirRead(lfs_dir_t* dir, lfs_info* info); + int DirRewind(lfs_dir_t* dir); int DirCreate(const char* path); int DirDelete(const char* path); -- cgit v1.2.3-70-g09d2 From eabbbfa373de04d1dc694618d5a9d475f0918592 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Sun, 17 Oct 2021 22:07:43 +0000 Subject: Fix folder count in output --- src/components/ble/FSService.cpp | 4 +-- src/components/ble/FSService.h | 56 +++++++++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 20 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index 2f02cd96..40679e5c 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -78,7 +78,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { resp.status = 1; // TODO actually use res above! resp.totalentries = 0; resp.entry = 0; - int sr; + int res = fs.DirOpen(path, &dir); NRF_LOG_INFO("[FS_S] ->diropen %d ", res); @@ -115,7 +115,6 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { resp.entry++; } fs.DirClose(&dir); - resp.entry++; resp.file_size = 0; resp.path_length = 0; resp.flags = 0; @@ -123,6 +122,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { auto* om = ble_hs_mbuf_from_flat(&resp,sizeof(ListDirResponse)-70+resp.path_length); ble_gattc_notify_custom(connectionHandle,transferCharacteristicHandle,om); NRF_LOG_INFO("[FS_S] -> done "); + break; } } return 0; diff --git a/src/components/ble/FSService.h b/src/components/ble/FSService.h index eb4b34d7..a1c42aa7 100644 --- a/src/components/ble/FSService.h +++ b/src/components/ble/FSService.h @@ -44,23 +44,8 @@ namespace Pinetime { struct ble_gatt_svc_def serviceDefinition[2]; uint16_t versionCharacteristicHandle; uint16_t transferCharacteristicHandle; - typedef struct __attribute__((packed)) { - uint8_t command; - uint8_t padding; - uint16_t pathlen; - char pathstr[70]; - } ListDirHeader; - typedef struct __attribute__((packed)) { - uint8_t command; - uint8_t status; - uint16_t path_length; - uint32_t entry; - uint32_t totalentries; - uint32_t flags; - uint32_t modification_time; - uint32_t file_size; - char path[70]; - } ListDirResponse; + + int FSCommandHandler(uint16_t connectionHandle, os_mbuf* om); enum class commands : uint8_t { INVALID = 0x00, @@ -80,7 +65,42 @@ namespace Pinetime { MOVE_STATUS = 0x61 }; - int FSCommandHandler(uint16_t connectionHandle, os_mbuf* om); + using ListDirHeader = struct __attribute__((packed)) { + uint8_t command; + uint8_t padding; + uint16_t pathlen; + char pathstr[70]; + }; + + using ListDirResponse = struct __attribute__((packed)) { + uint8_t command; + uint8_t status; + uint16_t path_length; + uint32_t entry; + uint32_t totalentries; + uint32_t flags; + uint32_t modification_time; + uint32_t file_size; + char path[70]; + }; + + using MKDirHeader = struct __attribute__((packed)) { + uint8_t command; + uint8_t padding; + uint16_t pathlen; + uint32_t padding2; + uint64_t time; + char pathstr[70]; + }; + + using MKDirResponse = struct __attribute__((packed)) { + uint8_t command; + uint8_t status; + uint32_t padding1; + uint16_t padding2; + uint64_t modification_time; + }; + }; } } -- cgit v1.2.3-70-g09d2 From 3a8e66a52fcc6317a7dffa15cb161f37a645d36c Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Sun, 17 Oct 2021 23:07:43 +0000 Subject: Added Delete file Added FS Stat. --- src/components/ble/FSService.cpp | 96 ++++++++++++++++++++++++++++++---------- src/components/ble/FSService.h | 20 +++++++-- src/components/fs/FS.cpp | 4 ++ src/components/fs/FS.h | 1 + 4 files changed, 93 insertions(+), 28 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index 40679e5c..0cf2b937 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -63,64 +63,112 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { NRF_LOG_INFO("[FS_S] -> FSCommandHandler"); switch (command) { + case commands::DELETE: { + NRF_LOG_INFO("[FS_S] -> Delete"); + auto* header = (DelHeader*)om->om_data; + uint16_t plen = header->pathlen; + char path[plen + 1] = {0}; + struct lfs_info info = {}; + DelResponse resp = {}; + resp.command = commands::DELETE_STATUS; + int res = fs.Stat(path, &info); + // Get Info about path + // branch for DirDel of FileDelete + if (info.type == LFS_TYPE_DIR) { + res = fs.DirDelete(path); + } else { + res = fs.FileDelete(path); + } + switch (res) { + case LFS_ERR_OK: + resp.status = 0x01; + break; + default: + resp.status = 0x02; + break; + } + auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(DelResponse)); + ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); + break; + } + case commands::MKDIR: { + NRF_LOG_INFO("[FS_S] -> MKDir"); + auto* header = (MKDirHeader*) om->om_data; + uint16_t plen = header->pathlen; + char path[plen + 1] = {0}; + memcpy(path, header->pathstr, plen); + NRF_LOG_INFO("[FS_S] -> MKDIR %.10s", path); + MKDirResponse resp = {}; + resp.command = commands::MKDIR_STATUS; + int res = fs.DirCreate(path); + switch (res) { + case LFS_ERR_OK: + resp.status = 0x01; + break; + default: + resp.status = 0x02; + break; + } + resp.modification_time = 0; // We should timestamp..but no + auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(MKDirResponse)); + ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); + break; + } case commands::LISTDIR: { NRF_LOG_INFO("[FS_S] -> ListDir"); - ListDirHeader *header = (ListDirHeader *)&om->om_data[0]; + ListDirHeader* header = (ListDirHeader*)om->om_data; uint16_t plen = header->pathlen; - char path[plen+1] = {0}; + char path[plen + 1] = {0}; memcpy(path, header->pathstr, plen); NRF_LOG_INFO("[FS_S] -> DIR %.10s", path); lfs_dir_t dir = {}; struct lfs_info info = {}; ListDirResponse resp = {}; - resp.command = 0x51; // LISTDIR_ENTRY; - resp.status = 1; // TODO actually use res above! + resp.command = commands::LISTDIR_ENTRY; + resp.status = 1; // TODO actually use res above! resp.totalentries = 0; resp.entry = 0; int res = fs.DirOpen(path, &dir); - + NRF_LOG_INFO("[FS_S] ->diropen %d ", res); while (fs.DirRead(&dir, &info)) { resp.totalentries++; - } NRF_LOG_INFO("[FS_S] -> %d ", resp.totalentries); - + fs.DirRewind(&dir); - + while (fs.DirRead(&dir, &info)) { - switch(info.type){ - case LFS_TYPE_REG: - { + switch (info.type) { + case LFS_TYPE_REG: { resp.flags = 0; resp.file_size = info.size; break; - } - case LFS_TYPE_DIR: - { - resp.flags = 1; - resp.file_size = 0; - break; + } + case LFS_TYPE_DIR: { + resp.flags = 1; + resp.file_size = 0; + break; } } resp.modification_time = 0; // TODO Does LFS actually support TS? - strcpy(resp.path,info.name); + strcpy(resp.path, info.name); resp.path_length = strlen(info.name); NRF_LOG_INFO("[FS_S] ->Path %s ,", info.name); - auto* om = ble_hs_mbuf_from_flat(&resp,sizeof(ListDirResponse)); - ble_gattc_notify_custom(connectionHandle,transferCharacteristicHandle,om); - vTaskDelay(1); //Allow stuff to actually go out over the BLE conn + auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse)); + ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); + vTaskDelay(1); // Allow stuff to actually go out over the BLE conn resp.entry++; } fs.DirClose(&dir); resp.file_size = 0; resp.path_length = 0; resp.flags = 0; - //Todo this better - auto* om = ble_hs_mbuf_from_flat(&resp,sizeof(ListDirResponse)-70+resp.path_length); - ble_gattc_notify_custom(connectionHandle,transferCharacteristicHandle,om); + // TODO Handle Size of response better. + auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse) - 70 + resp.path_length); + ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); NRF_LOG_INFO("[FS_S] -> done "); break; } diff --git a/src/components/ble/FSService.h b/src/components/ble/FSService.h index a1c42aa7..3ca6d934 100644 --- a/src/components/ble/FSService.h +++ b/src/components/ble/FSService.h @@ -66,14 +66,14 @@ namespace Pinetime { }; using ListDirHeader = struct __attribute__((packed)) { - uint8_t command; + commands command; uint8_t padding; uint16_t pathlen; char pathstr[70]; }; using ListDirResponse = struct __attribute__((packed)) { - uint8_t command; + commands command; uint8_t status; uint16_t path_length; uint32_t entry; @@ -85,7 +85,7 @@ namespace Pinetime { }; using MKDirHeader = struct __attribute__((packed)) { - uint8_t command; + commands command; uint8_t padding; uint16_t pathlen; uint32_t padding2; @@ -94,13 +94,25 @@ namespace Pinetime { }; using MKDirResponse = struct __attribute__((packed)) { - uint8_t command; + commands command; uint8_t status; uint32_t padding1; uint16_t padding2; uint64_t modification_time; }; + using DelHeader = struct __attribute__((packed)) { + commands command; + uint8_t padding; + uint16_t pathlen; + char pathstr[70]; + }; + + using DelResponse = struct __attribute__((packed)) { + commands command; + uint8_t status; + }; + }; } } diff --git a/src/components/fs/FS.cpp b/src/components/fs/FS.cpp index 353193dc..d30b7373 100644 --- a/src/components/fs/FS.cpp +++ b/src/components/fs/FS.cpp @@ -96,6 +96,10 @@ int FS::DirCreate(const char* path) { return lfs_mkdir(&lfs, path); } +int FS::Stat(const char* path, lfs_info* info){ + return lfs_stat(&lfs,path,info); +} + // Delete directory and all files inside int FS::DirDelete(const char* path) { diff --git a/src/components/fs/FS.h b/src/components/fs/FS.h index ccff2409..e50ff10a 100644 --- a/src/components/fs/FS.h +++ b/src/components/fs/FS.h @@ -28,6 +28,7 @@ namespace Pinetime { int DirCreate(const char* path); int DirDelete(const char* path); + int Stat(const char* path, lfs_info* info); void VerifyResource(); private: -- cgit v1.2.3-70-g09d2 From 8f6a390c36007eecb875bca6d8be860dbec6bd9c Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Mon, 18 Oct 2021 04:20:26 +0000 Subject: Start of read command --- src/components/ble/FSService.cpp | 121 ++++++++++++++++++++++++++++++++++++--- src/components/ble/FSService.h | 56 ++++++++++++++---- 2 files changed, 158 insertions(+), 19 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index 0cf2b937..52cfafb8 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -4,7 +4,7 @@ using namespace Pinetime::Controllers; -constexpr ble_uuid128_t FSService::fsServiceUuid; +constexpr ble_uuid16_t FSService::fsServiceUuid; constexpr ble_uuid128_t FSService::fsVersionUuid; constexpr ble_uuid128_t FSService::fsTransferUuid; @@ -63,9 +63,90 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { NRF_LOG_INFO("[FS_S] -> FSCommandHandler"); switch (command) { + case commands::READ: { + NRF_LOG_INFO("[FS_S] -> Read"); + if (state != FSState::IDLE) { + return -1; + } + state = FSState::READ; + auto* header = (ReadHeader*) om->om_data; + uint16_t plen = header->pathlen; + if (plen > maxpathlen - 1) { + return -1; + } + memcpy(filepath, header->pathstr, plen); + filepath[plen + 1] = 0; // Copy and null teminate string + ReadResponse resp; + resp.command = commands::READ_DATA; + resp.chunkoff = header->chunkoff; + resp.status = 0x01; + struct lfs_info info = {}; + int res = fs.Stat(filepath, &info); + if (res == LFS_ERR_NOENT && info.type != LFS_TYPE_DIR) { + resp.status = 0x03; + resp.chunklen = 0; + resp.totallen = 0; + } else { + lfs_file f; + resp.chunklen = std::min(header->chunksize, info.size); + resp.totallen = info.size; + fs.FileOpen(&f, filepath, LFS_O_RDONLY); + fs.FileSeek(&f, header->chunkoff); + resp.chunklen = fs.FileRead(&f, resp.chunk, resp.chunklen); + fs.FileClose(&f); + } + auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ReadResponse)); + ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); + if (header->chunksize >= resp.totallen) { // probably removeable...but then usafe + state = FSState::IDLE; + } + } + case commands::READ_PACING: { + NRF_LOG_INFO("[FS_S] -> ReadPacing"); + if (state != FSState::READ) { + return -1; + } + auto* header = (ReadPacing*) om->om_data; + ReadResponse resp = {}; + + resp.command = commands::READ_DATA; + resp.chunkoff = header->chunkoff; + resp.status = 0x01; + struct lfs_info info = {}; + int res = fs.Stat(filepath, &info); + if (res == LFS_ERR_NOENT && info.type != LFS_TYPE_DIR) { + resp.status = 0x03; + resp.chunklen = 0; + resp.totallen = 0; + } else { + lfs_file f; + resp.chunklen = std::min(header->chunksize, info.size); + resp.totallen = info.size; + fs.FileOpen(&f, filepath, LFS_O_RDONLY); + fs.FileSeek(&f, header->chunkoff); + resp.chunklen = fs.FileRead(&f, resp.chunk, resp.chunklen); + fs.FileClose(&f); + } + auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ReadResponse)); + ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); + if (resp.chunklen >= header->chunksize) { // is this right? + state = FSState::IDLE; + } + } + case commands::WRITE: { + if (state != FSState::IDLE) { + return -1; + } + } + case commands::WRITE_PACING: { + if (state != FSState::WRITE) { + return -1; + } + } + case commands::DELETE: { NRF_LOG_INFO("[FS_S] -> Delete"); - auto* header = (DelHeader*)om->om_data; + auto* header = (DelHeader*) om->om_data; uint16_t plen = header->pathlen; char path[plen + 1] = {0}; struct lfs_info info = {}; @@ -116,7 +197,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { } case commands::LISTDIR: { NRF_LOG_INFO("[FS_S] -> ListDir"); - ListDirHeader* header = (ListDirHeader*)om->om_data; + ListDirHeader* header = (ListDirHeader*) om->om_data; uint16_t plen = header->pathlen; char path[plen + 1] = {0}; memcpy(path, header->pathstr, plen); @@ -140,7 +221,11 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { fs.DirRewind(&dir); - while (fs.DirRead(&dir, &info)) { + while (true) { + int res = fs.DirRead(&dir, &info); + if(res <= 0){ + break; + } switch (info.type) { case LFS_TYPE_REG: { resp.flags = 0; @@ -157,9 +242,9 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { strcpy(resp.path, info.name); resp.path_length = strlen(info.name); NRF_LOG_INFO("[FS_S] ->Path %s ,", info.name); - auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse)); + auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse)+resp.path_length); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); - vTaskDelay(1); // Allow stuff to actually go out over the BLE conn + vTaskDelay(5); // Allow stuff to actually go out over the BLE conn resp.entry++; } fs.DirClose(&dir); @@ -167,7 +252,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { resp.path_length = 0; resp.flags = 0; // TODO Handle Size of response better. - auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse) - 70 + resp.path_length); + auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse)+resp.path_length); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); NRF_LOG_INFO("[FS_S] -> done "); break; @@ -175,3 +260,25 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { } return 0; } +// Loads resp with file data given a valid filepath header and resp +void FSService::prepareReadDataResp(ReadHeader* header, ReadResponse* resp) { + uint16_t plen = header->pathlen; + resp->command = commands::READ_DATA; + resp->chunkoff = header->chunkoff; + resp->status = 0x01; + struct lfs_info info = {}; + int res = fs.Stat(filepath, &info); + if (res == LFS_ERR_NOENT && info.type != LFS_TYPE_DIR) { + resp->status = 0x03; + resp->chunklen = 0; + resp->totallen = 0; + } else { + lfs_file f; + resp->chunklen = std::min(header->chunksize, info.size); + resp->totallen = info.size; + fs.FileOpen(&f, filepath, LFS_O_RDONLY); + fs.FileSeek(&f, header->chunkoff); + resp->chunklen = fs.FileRead(&f, resp->chunk, resp->chunklen); + fs.FileClose(&f); + } +} diff --git a/src/components/ble/FSService.h b/src/components/ble/FSService.h index 3ca6d934..93205e54 100644 --- a/src/components/ble/FSService.h +++ b/src/components/ble/FSService.h @@ -27,10 +27,10 @@ namespace Pinetime { static constexpr uint16_t fsVersionId {0x0100}; static constexpr uint16_t fsTransferId {0x0200}; uint16_t fsVersion = {0x0004}; - - static constexpr ble_uuid128_t fsServiceUuid { - .u {.type = BLE_UUID_TYPE_128}, - .value = {0x72, 0x65, 0x66, 0x73, 0x6e, 0x61, 0x72, 0x54, 0x65, 0x6c, 0x69, 0x46, 0xBB, 0xFE, 0xAF, 0xAD}}; + static constexpr uint8_t maxpathlen = 100; + static constexpr ble_uuid16_t fsServiceUuid { + .u {.type = BLE_UUID_TYPE_16}, + .value = {0xFEBB}};// {0x72, 0x65, 0x66, 0x73, 0x6e, 0x61, 0x72, 0x54, 0x65, 0x6c, 0x69, 0x46, 0xBB, 0xFE, 0xAF, 0xAD}}; static constexpr ble_uuid128_t fsVersionUuid { .u {.type = BLE_UUID_TYPE_128}, @@ -45,8 +45,6 @@ namespace Pinetime { uint16_t versionCharacteristicHandle; uint16_t transferCharacteristicHandle; - int FSCommandHandler(uint16_t connectionHandle, os_mbuf* om); - enum class commands : uint8_t { INVALID = 0x00, READ = 0x10, @@ -64,12 +62,44 @@ namespace Pinetime { MOVE = 0x60, MOVE_STATUS = 0x61 }; + enum class FSState : uint8_t { + IDLE = 0x00, + READ = 0x01, + WRITE = 0x02, + }; + FSState state; + char filepath[maxpathlen]; // TODO ..ugh fixed filepath len + using ReadHeader = struct __attribute__((packed)) { + commands command; + uint8_t padding; + uint16_t pathlen; + uint32_t chunkoff; + uint32_t chunksize; + char pathstr[]; + }; + + using ReadResponse = struct __attribute__((packed)) { + commands command; + uint8_t status; + uint16_t padding; + uint32_t chunkoff; + uint32_t totallen; + uint32_t chunklen; + uint8_t chunk[]; + }; + using ReadPacing = struct __attribute__((packed)) { + commands command; + uint8_t status; + uint16_t padding; + uint32_t chunkoff; + uint32_t chunksize; + }; using ListDirHeader = struct __attribute__((packed)) { commands command; uint8_t padding; uint16_t pathlen; - char pathstr[70]; + char pathstr[]; }; using ListDirResponse = struct __attribute__((packed)) { @@ -81,7 +111,7 @@ namespace Pinetime { uint32_t flags; uint32_t modification_time; uint32_t file_size; - char path[70]; + char path[]; }; using MKDirHeader = struct __attribute__((packed)) { @@ -90,7 +120,7 @@ namespace Pinetime { uint16_t pathlen; uint32_t padding2; uint64_t time; - char pathstr[70]; + char pathstr[]; }; using MKDirResponse = struct __attribute__((packed)) { @@ -100,19 +130,21 @@ namespace Pinetime { uint16_t padding2; uint64_t modification_time; }; - + using DelHeader = struct __attribute__((packed)) { commands command; uint8_t padding; uint16_t pathlen; - char pathstr[70]; + char pathstr[]; }; using DelResponse = struct __attribute__((packed)) { commands command; uint8_t status; }; - + + int FSCommandHandler(uint16_t connectionHandle, os_mbuf* om); + void prepareReadDataResp(ReadHeader *header, ReadResponse *resp); }; } } -- cgit v1.2.3-70-g09d2 From d89e38d3bf9e84e69635f0cb10cc42f0071fa038 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Tue, 19 Oct 2021 19:03:00 +0000 Subject: Focus on getting flash access working properly --- src/components/ble/FSService.cpp | 10 +++++---- src/components/ble/FSService.h | 2 +- src/components/fs/FS.cpp | 12 ++++++++-- src/components/fs/FS.h | 47 ++++++++++++++++++++-------------------- 4 files changed, 41 insertions(+), 30 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index 52cfafb8..0a1fabb7 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -60,9 +60,10 @@ int FSService::OnFSServiceRequested(uint16_t connectionHandle, uint16_t attribut int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { auto command = static_cast(om->om_data[0]); - NRF_LOG_INFO("[FS_S] -> FSCommandHandler"); - + NRF_LOG_INFO("[FS_S] -> FSCommandHandler %d",command); + fs.Mount(); switch (command) { + /* case commands::READ: { NRF_LOG_INFO("[FS_S] -> Read"); if (state != FSState::IDLE) { @@ -194,7 +195,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(MKDirResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); break; - } + }*/ case commands::LISTDIR: { NRF_LOG_INFO("[FS_S] -> ListDir"); ListDirHeader* header = (ListDirHeader*) om->om_data; @@ -244,7 +245,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { NRF_LOG_INFO("[FS_S] ->Path %s ,", info.name); auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse)+resp.path_length); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); - vTaskDelay(5); // Allow stuff to actually go out over the BLE conn + vTaskDelay(10); // Allow stuff to actually go out over the BLE conn resp.entry++; } fs.DirClose(&dir); @@ -258,6 +259,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { break; } } + fs.UnMount(); return 0; } // Loads resp with file data given a valid filepath header and resp diff --git a/src/components/ble/FSService.h b/src/components/ble/FSService.h index 93205e54..114c1e0d 100644 --- a/src/components/ble/FSService.h +++ b/src/components/ble/FSService.h @@ -109,7 +109,7 @@ namespace Pinetime { uint32_t entry; uint32_t totalentries; uint32_t flags; - uint32_t modification_time; + uint64_t modification_time; uint32_t file_size; char path[]; }; diff --git a/src/components/fs/FS.cpp b/src/components/fs/FS.cpp index d30b7373..c8a5a2eb 100644 --- a/src/components/fs/FS.cpp +++ b/src/components/fs/FS.cpp @@ -54,6 +54,14 @@ void FS::VerifyResource() { resourcesValid = true; } +void FS::Mount() { + flashDriver.Wakeup(); +} + +void FS::UnMount() { + flashDriver.Sleep(); +} + int FS::FileOpen(lfs_file_t* file_p, const char* fileName, const int flags) { return lfs_file_open(&lfs, file_p, fileName, flags); } @@ -96,8 +104,8 @@ int FS::DirCreate(const char* path) { return lfs_mkdir(&lfs, path); } -int FS::Stat(const char* path, lfs_info* info){ - return lfs_stat(&lfs,path,info); +int FS::Stat(const char* path, lfs_info* info) { + return lfs_stat(&lfs, path, info); } // Delete directory and all files inside diff --git a/src/components/fs/FS.h b/src/components/fs/FS.h index e50ff10a..1aa8d5f1 100644 --- a/src/components/fs/FS.h +++ b/src/components/fs/FS.h @@ -13,6 +13,9 @@ namespace Pinetime { void Init(); void LVGLFileSystemInit(); + void Mount(); + void UnMount(); + int FileOpen(lfs_file_t* file_p, const char* fileName, const int flags); int FileClose(lfs_file_t* file_p); int FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size); @@ -32,31 +35,30 @@ namespace Pinetime { void VerifyResource(); private: - Pinetime::Drivers::SpiNorFlash& flashDriver; /* - * External Flash MAP (4 MBytes) - * - * 0x000000 +---------------------------------------+ - * | Bootloader Assets | - * | 256 KBytes | - * | | - * 0x040000 +---------------------------------------+ - * | OTA | - * | 464 KBytes | - * | | - * | | - * | | - * 0x0B4000 +---------------------------------------+ - * | File System | - * | | - * | | - * | | - * | | - * 0x400000 +---------------------------------------+ - * - */ + * External Flash MAP (4 MBytes) + * + * 0x000000 +---------------------------------------+ + * | Bootloader Assets | + * | 256 KBytes | + * | | + * 0x040000 +---------------------------------------+ + * | OTA | + * | 464 KBytes | + * | | + * | | + * | | + * 0x0B4000 +---------------------------------------+ + * | File System | + * | | + * | | + * | | + * | | + * 0x400000 +---------------------------------------+ + * + */ static constexpr size_t startAddress = 0x0B4000; static constexpr size_t size = 0x34C000; static constexpr size_t blockSize = 4096; @@ -70,7 +72,6 @@ namespace Pinetime { static int SectorErase(const struct lfs_config* c, lfs_block_t block); static int SectorProg(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, const void* buffer, lfs_size_t size); static int SectorRead(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, void* buffer, lfs_size_t size); - }; } } -- cgit v1.2.3-70-g09d2 From 6393a17d7402b92e00cd748bc7e901ba053135de Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Wed, 20 Oct 2021 01:30:04 +0000 Subject: List Dir works? --- src/components/ble/FSService.cpp | 41 ++++++++++++++++++++++----------- src/components/ble/FSService.h | 8 ++++--- src/components/ble/NimbleController.cpp | 2 +- src/systemtask/Messages.h | 2 ++ src/systemtask/SystemTask.cpp | 13 +++++++++++ 5 files changed, 49 insertions(+), 17 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index 0a1fabb7..cd2cc07a 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -1,6 +1,7 @@ #include #include "FSService.h" #include "components/ble/BleController.h" +#include "systemtask/SystemTask.h" using namespace Pinetime::Controllers; @@ -13,8 +14,9 @@ int FSServiceCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gat return fsService->OnFSServiceRequested(conn_handle, attr_handle, ctxt); } -FSService::FSService(Pinetime::Controllers::FS& fs) - : fs {fs}, +FSService::FSService(Pinetime::System::SystemTask& systemTask, Pinetime::Controllers::FS& fs) + : systemTask {systemTask}, + fs {fs}, characteristicDefinition {{.uuid = &fsVersionUuid.u, .access_cb = FSServiceCallback, .arg = this, @@ -60,8 +62,13 @@ int FSService::OnFSServiceRequested(uint16_t connectionHandle, uint16_t attribut int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { auto command = static_cast(om->om_data[0]); - NRF_LOG_INFO("[FS_S] -> FSCommandHandler %d",command); - fs.Mount(); + NRF_LOG_INFO("[FS_S] -> FSCommandHandler Command %d", command); + // Just always make sure we are awake... + systemTask.PushMessage(Pinetime::System::Messages::StartFileTransfer); + vTaskDelay(10); + while (systemTask.IsSleeping()) { + vTaskDelay(100); // 50ms + } switch (command) { /* case commands::READ: { @@ -203,6 +210,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { char path[plen + 1] = {0}; memcpy(path, header->pathstr, plen); NRF_LOG_INFO("[FS_S] -> DIR %.10s", path); + lfs_dir_t dir = {}; struct lfs_info info = {}; @@ -212,9 +220,11 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { resp.totalentries = 0; resp.entry = 0; - int res = fs.DirOpen(path, &dir); + if (fs.DirOpen(path, &dir)) { + return 0; + } - NRF_LOG_INFO("[FS_S] ->diropen %d ", res); + // NRF_LOG_INFO("[FS_S] ->diropen %d ", res); while (fs.DirRead(&dir, &info)) { resp.totalentries++; } @@ -222,9 +232,11 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { fs.DirRewind(&dir); - while (true) { + // NRF_LOG_INFO("[FS_S] ->diropen %d ", res); + + while (resp.entry < resp.totalentries) { int res = fs.DirRead(&dir, &info); - if(res <= 0){ + if (res <= 0) { break; } switch (info.type) { @@ -243,23 +255,26 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { strcpy(resp.path, info.name); resp.path_length = strlen(info.name); NRF_LOG_INFO("[FS_S] ->Path %s ,", info.name); - auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse)+resp.path_length); + auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse) + resp.path_length); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); - vTaskDelay(10); // Allow stuff to actually go out over the BLE conn + vTaskDelay(100); // Allow stuff to actually go out over the BLE conn resp.entry++; } - fs.DirClose(&dir); + + if (fs.DirClose(&dir)) { + return 0; + } resp.file_size = 0; resp.path_length = 0; resp.flags = 0; // TODO Handle Size of response better. - auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse)+resp.path_length); + auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse) + resp.path_length); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); NRF_LOG_INFO("[FS_S] -> done "); break; } } - fs.UnMount(); + systemTask.PushMessage(Pinetime::System::Messages::StopFileTransfer); return 0; } // Loads resp with file data given a valid filepath header and resp diff --git a/src/components/ble/FSService.h b/src/components/ble/FSService.h index 114c1e0d..69ed094b 100644 --- a/src/components/ble/FSService.h +++ b/src/components/ble/FSService.h @@ -15,13 +15,15 @@ namespace Pinetime { class Ble; class FSService { public: - FSService(Pinetime::Controllers::FS& fs); + FSService(Pinetime::System::SystemTask& systemTask, + Pinetime::Controllers::FS& fs); void Init(); int OnFSServiceRequested(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt* context); void NotifyFSRaw(uint16_t connectionHandle); private: + Pinetime::System::SystemTask& systemTask; Pinetime::Controllers::FS& fs; static constexpr uint16_t FSServiceId {0xFEBB}; static constexpr uint16_t fsVersionId {0x0100}; @@ -30,7 +32,7 @@ namespace Pinetime { static constexpr uint8_t maxpathlen = 100; static constexpr ble_uuid16_t fsServiceUuid { .u {.type = BLE_UUID_TYPE_16}, - .value = {0xFEBB}};// {0x72, 0x65, 0x66, 0x73, 0x6e, 0x61, 0x72, 0x54, 0x65, 0x6c, 0x69, 0x46, 0xBB, 0xFE, 0xAF, 0xAD}}; + .value = {0xFEBB}}; // {0x72, 0x65, 0x66, 0x73, 0x6e, 0x61, 0x72, 0x54, 0x65, 0x6c, 0x69, 0x46, 0xBB, 0xFE, 0xAF, 0xAD}}; static constexpr ble_uuid128_t fsVersionUuid { .u {.type = BLE_UUID_TYPE_128}, @@ -144,7 +146,7 @@ namespace Pinetime { }; int FSCommandHandler(uint16_t connectionHandle, os_mbuf* om); - void prepareReadDataResp(ReadHeader *header, ReadResponse *resp); + void prepareReadDataResp(ReadHeader* header, ReadResponse* resp); }; } } diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index b5eb46b8..01230661 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -51,7 +51,7 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, heartRateService {systemTask, heartRateController}, motionService{systemTask, motionController}, fs {fs}, - fsService {fs}, + fsService {systemTask,fs}, serviceDiscovery({¤tTimeClient, &alertNotificationClient}) { } diff --git a/src/systemtask/Messages.h b/src/systemtask/Messages.h index 516f6462..cc30fdc6 100644 --- a/src/systemtask/Messages.h +++ b/src/systemtask/Messages.h @@ -27,6 +27,8 @@ namespace Pinetime { StopRinging, MeasureBatteryTimerExpired, BatteryPercentageUpdated, + StartFileTransfer, + StopFileTransfer, }; } } diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 28f81243..a95d479d 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -342,6 +342,19 @@ void SystemTask::Work() { doNotGoToSleep = false; xTimerStart(dimTimer, 0); break; + case Messages::StartFileTransfer: + NRF_LOG_INFO("[systemtask] FS Started"); + doNotGoToSleep = true; + if (isSleeping && !isWakingUp) + GoToRunning(); + //TODO add intent of fs access icon or something + break; + case Messages::StopFileTransfer: + NRF_LOG_INFO("[systemtask] FS Stopped"); + doNotGoToSleep = false; + xTimerStart(dimTimer, 0); + //TODO add intent of fs access icon or something + break; case Messages::OnTouchEvent: if (touchHandler.GetNewTouchInfo()) { touchHandler.UpdateLvglTouchPoint(); -- cgit v1.2.3-70-g09d2 From faa05eb57b7d6214e53d0b147a796793496a89ae Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Thu, 21 Oct 2021 04:02:50 +0000 Subject: Actually fix memory corruption, seems stable now ListDir MKDIR delete all seem to work Co-authored-by: Iambian --- src/components/ble/FSService.cpp | 103 +++++++++++++++------------------------ src/components/ble/FSService.h | 5 +- 2 files changed, 43 insertions(+), 65 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index cd2cc07a..0ba3e102 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -69,8 +69,9 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { while (systemTask.IsSleeping()) { vTaskDelay(100); // 50ms } + lfs_dir_t dir; + lfs_info info; switch (command) { - /* case commands::READ: { NRF_LOG_INFO("[FS_S] -> Read"); if (state != FSState::IDLE) { @@ -151,31 +152,15 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { return -1; } } - case commands::DELETE: { NRF_LOG_INFO("[FS_S] -> Delete"); auto* header = (DelHeader*) om->om_data; uint16_t plen = header->pathlen; - char path[plen + 1] = {0}; - struct lfs_info info = {}; - DelResponse resp = {}; + char path[plen + 1] {0}; + memcpy(path, header->pathstr, plen); + DelResponse resp {}; resp.command = commands::DELETE_STATUS; - int res = fs.Stat(path, &info); - // Get Info about path - // branch for DirDel of FileDelete - if (info.type == LFS_TYPE_DIR) { - res = fs.DirDelete(path); - } else { - res = fs.FileDelete(path); - } - switch (res) { - case LFS_ERR_OK: - resp.status = 0x01; - break; - default: - resp.status = 0x02; - break; - } + resp.status = fs.FileDelete(path) ? 0x02 : 0x01; auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(DelResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); break; @@ -184,57 +169,43 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { NRF_LOG_INFO("[FS_S] -> MKDir"); auto* header = (MKDirHeader*) om->om_data; uint16_t plen = header->pathlen; - char path[plen + 1] = {0}; + char path[plen + 1] {0}; memcpy(path, header->pathstr, plen); - NRF_LOG_INFO("[FS_S] -> MKDIR %.10s", path); - MKDirResponse resp = {}; + MKDirResponse resp {}; resp.command = commands::MKDIR_STATUS; - int res = fs.DirCreate(path); - switch (res) { - case LFS_ERR_OK: - resp.status = 0x01; - break; - default: - resp.status = 0x02; - break; - } - resp.modification_time = 0; // We should timestamp..but no + resp.modification_time = 0; + resp.status = fs.DirCreate(path) ? 0x02 : 0x01; auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(MKDirResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); break; - }*/ + } case commands::LISTDIR: { NRF_LOG_INFO("[FS_S] -> ListDir"); ListDirHeader* header = (ListDirHeader*) om->om_data; uint16_t plen = header->pathlen; - char path[plen + 1] = {0}; + char path[plen + 1] {0}; memcpy(path, header->pathstr, plen); NRF_LOG_INFO("[FS_S] -> DIR %.10s", path); - lfs_dir_t dir = {}; - struct lfs_info info = {}; + ListDirResponse resp {}; - ListDirResponse resp = {}; resp.command = commands::LISTDIR_ENTRY; - resp.status = 1; // TODO actually use res above! + resp.status = 1; resp.totalentries = 0; resp.entry = 0; - - if (fs.DirOpen(path, &dir)) { - return 0; - } - - // NRF_LOG_INFO("[FS_S] ->diropen %d ", res); + resp.modification_time = 0; // TODO Does LFS actually support TS? + if (fs.DirOpen(path, &dir) != 0) { + resp.status = 0x02; + auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse)); + ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); + break; + }; + // Count Total files in directory. while (fs.DirRead(&dir, &info)) { resp.totalentries++; } - NRF_LOG_INFO("[FS_S] -> %d ", resp.totalentries); - fs.DirRewind(&dir); - - // NRF_LOG_INFO("[FS_S] ->diropen %d ", res); - - while (resp.entry < resp.totalentries) { + while (true) { int res = fs.DirRead(&dir, &info); if (res <= 0) { break; @@ -251,35 +222,39 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { break; } } - resp.modification_time = 0; // TODO Does LFS actually support TS? - strcpy(resp.path, info.name); + + //strcpy(resp.path, info.name); resp.path_length = strlen(info.name); - NRF_LOG_INFO("[FS_S] ->Path %s ,", info.name); - auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse) + resp.path_length); + NRF_LOG_INFO("[FS_S] -> DIR %.10s", path); + auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse)); + os_mbuf_append(om,info.name,resp.path_length); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); + /* + * Todo Figure out how to know when the previous Notify was TX'd + * For now just delay 100ms to make sure that the data went out... + */ vTaskDelay(100); // Allow stuff to actually go out over the BLE conn resp.entry++; } - - if (fs.DirClose(&dir)) { - return 0; - } + assert(fs.DirClose(&dir) == 0); resp.file_size = 0; resp.path_length = 0; resp.flags = 0; - // TODO Handle Size of response better. - auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse) + resp.path_length); + auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); - NRF_LOG_INFO("[FS_S] -> done "); break; } + default: + break; } + NRF_LOG_INFO("[FS_S] -> done "); systemTask.PushMessage(Pinetime::System::Messages::StopFileTransfer); return 0; } + // Loads resp with file data given a valid filepath header and resp void FSService::prepareReadDataResp(ReadHeader* header, ReadResponse* resp) { - uint16_t plen = header->pathlen; + // uint16_t plen = header->pathlen; resp->command = commands::READ_DATA; resp->chunkoff = header->chunkoff; resp->status = 0x01; diff --git a/src/components/ble/FSService.h b/src/components/ble/FSService.h index 69ed094b..e9c98fb4 100644 --- a/src/components/ble/FSService.h +++ b/src/components/ble/FSService.h @@ -29,7 +29,7 @@ namespace Pinetime { static constexpr uint16_t fsVersionId {0x0100}; static constexpr uint16_t fsTransferId {0x0200}; uint16_t fsVersion = {0x0004}; - static constexpr uint8_t maxpathlen = 100; + static constexpr uint16_t maxpathlen = 256; static constexpr ble_uuid16_t fsServiceUuid { .u {.type = BLE_UUID_TYPE_16}, .value = {0xFEBB}}; // {0x72, 0x65, 0x66, 0x73, 0x6e, 0x61, 0x72, 0x54, 0x65, 0x6c, 0x69, 0x46, 0xBB, 0xFE, 0xAF, 0xAD}}; @@ -47,6 +47,9 @@ namespace Pinetime { uint16_t versionCharacteristicHandle; uint16_t transferCharacteristicHandle; + // lfs_dir_t dir; + // lfs_info info; + enum class commands : uint8_t { INVALID = 0x00, READ = 0x10, -- cgit v1.2.3-70-g09d2 From 8fb99471c38c2efd7af88d4888c5792bdd8deafb Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Fri, 22 Oct 2021 03:34:23 +0000 Subject: Reading Seems to work? --- src/components/ble/FSService.cpp | 78 ++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 39 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index 0ba3e102..68fd5ea6 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -73,74 +73,76 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { lfs_info info; switch (command) { case commands::READ: { + lfs_file f; NRF_LOG_INFO("[FS_S] -> Read"); - if (state != FSState::IDLE) { - return -1; - } - state = FSState::READ; auto* header = (ReadHeader*) om->om_data; uint16_t plen = header->pathlen; - if (plen > maxpathlen - 1) { + if (plen > maxpathlen) { //> counts for null term return -1; } memcpy(filepath, header->pathstr, plen); filepath[plen + 1] = 0; // Copy and null teminate string ReadResponse resp; resp.command = commands::READ_DATA; - resp.chunkoff = header->chunkoff; resp.status = 0x01; - struct lfs_info info = {}; + resp.chunkoff = header->chunkoff; int res = fs.Stat(filepath, &info); if (res == LFS_ERR_NOENT && info.type != LFS_TYPE_DIR) { resp.status = 0x03; resp.chunklen = 0; resp.totallen = 0; } else { - lfs_file f; - resp.chunklen = std::min(header->chunksize, info.size); + resp.chunklen = std::min(header->chunksize, info.size); // TODO add mtu somehow resp.totallen = info.size; fs.FileOpen(&f, filepath, LFS_O_RDONLY); fs.FileSeek(&f, header->chunkoff); - resp.chunklen = fs.FileRead(&f, resp.chunk, resp.chunklen); - fs.FileClose(&f); } - auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ReadResponse)); - ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); - if (header->chunksize >= resp.totallen) { // probably removeable...but then usafe - state = FSState::IDLE; + os_mbuf* om; + if (resp.chunklen > 0) { + uint8_t fileData[resp.chunklen] {0}; + resp.chunklen = fs.FileRead(&f, fileData, resp.chunklen); + om = ble_hs_mbuf_from_flat(&resp, sizeof(ReadResponse)); + os_mbuf_append(om, fileData, resp.chunklen); + } else { + resp.chunklen = 0; + om = ble_hs_mbuf_from_flat(&resp, sizeof(ReadResponse)); } + fs.FileClose(&f); + ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); + break; } case commands::READ_PACING: { - NRF_LOG_INFO("[FS_S] -> ReadPacing"); - if (state != FSState::READ) { - return -1; - } - auto* header = (ReadPacing*) om->om_data; - ReadResponse resp = {}; - + lfs_file f; + NRF_LOG_INFO("[FS_S] -> Readpacing"); + auto* header = (ReadHeader*) om->om_data; + ReadResponse resp; resp.command = commands::READ_DATA; - resp.chunkoff = header->chunkoff; resp.status = 0x01; - struct lfs_info info = {}; + resp.chunkoff = header->chunkoff; int res = fs.Stat(filepath, &info); if (res == LFS_ERR_NOENT && info.type != LFS_TYPE_DIR) { resp.status = 0x03; resp.chunklen = 0; resp.totallen = 0; } else { - lfs_file f; - resp.chunklen = std::min(header->chunksize, info.size); + resp.chunklen = std::min(header->chunksize, info.size); // TODO add mtu somehow resp.totallen = info.size; fs.FileOpen(&f, filepath, LFS_O_RDONLY); fs.FileSeek(&f, header->chunkoff); - resp.chunklen = fs.FileRead(&f, resp.chunk, resp.chunklen); - fs.FileClose(&f); } - auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ReadResponse)); - ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); - if (resp.chunklen >= header->chunksize) { // is this right? - state = FSState::IDLE; + os_mbuf* om; + if (resp.chunklen > 0) { + uint8_t fileData[resp.chunklen] {0}; + resp.chunklen = fs.FileRead(&f, fileData, resp.chunklen); + om = ble_hs_mbuf_from_flat(&resp, sizeof(ReadResponse)); + os_mbuf_append(om, fileData, resp.chunklen); + } else { + resp.chunklen = 0; + om = ble_hs_mbuf_from_flat(&resp, sizeof(ReadResponse)); } + fs.FileClose(&f); + ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); + break; } case commands::WRITE: { if (state != FSState::IDLE) { @@ -185,7 +187,6 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { uint16_t plen = header->pathlen; char path[plen + 1] {0}; memcpy(path, header->pathstr, plen); - NRF_LOG_INFO("[FS_S] -> DIR %.10s", path); ListDirResponse resp {}; @@ -223,16 +224,15 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { } } - //strcpy(resp.path, info.name); + // strcpy(resp.path, info.name); resp.path_length = strlen(info.name); - NRF_LOG_INFO("[FS_S] -> DIR %.10s", path); auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse)); - os_mbuf_append(om,info.name,resp.path_length); + os_mbuf_append(om, info.name, resp.path_length); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); /* - * Todo Figure out how to know when the previous Notify was TX'd - * For now just delay 100ms to make sure that the data went out... - */ + * Todo Figure out how to know when the previous Notify was TX'd + * For now just delay 100ms to make sure that the data went out... + */ vTaskDelay(100); // Allow stuff to actually go out over the BLE conn resp.entry++; } -- cgit v1.2.3-70-g09d2 From c1aa5a5ea7d5ecde63a786827a866312c04507f9 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Mon, 25 Oct 2021 03:02:02 +0000 Subject: Write works --- src/components/ble/FSService.cpp | 52 ++++++++++++++++++++++++++++++---------- src/components/ble/FSService.h | 31 +++++++++++++++++++++--- src/components/fs/FS.cpp | 4 +++- src/components/fs/FS.h | 8 +++++-- 4 files changed, 77 insertions(+), 18 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index 68fd5ea6..c784a8c4 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -83,6 +83,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { memcpy(filepath, header->pathstr, plen); filepath[plen + 1] = 0; // Copy and null teminate string ReadResponse resp; + os_mbuf* om; resp.command = commands::READ_DATA; resp.status = 0x01; resp.chunkoff = header->chunkoff; @@ -91,23 +92,19 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { resp.status = 0x03; resp.chunklen = 0; resp.totallen = 0; + om = ble_hs_mbuf_from_flat(&resp, sizeof(ReadResponse)); } else { resp.chunklen = std::min(header->chunksize, info.size); // TODO add mtu somehow resp.totallen = info.size; fs.FileOpen(&f, filepath, LFS_O_RDONLY); fs.FileSeek(&f, header->chunkoff); - } - os_mbuf* om; - if (resp.chunklen > 0) { uint8_t fileData[resp.chunklen] {0}; resp.chunklen = fs.FileRead(&f, fileData, resp.chunklen); om = ble_hs_mbuf_from_flat(&resp, sizeof(ReadResponse)); os_mbuf_append(om, fileData, resp.chunklen); - } else { - resp.chunklen = 0; - om = ble_hs_mbuf_from_flat(&resp, sizeof(ReadResponse)); + fs.FileClose(&f); } - fs.FileClose(&f); + ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); break; } @@ -145,14 +142,45 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { break; } case commands::WRITE: { - if (state != FSState::IDLE) { + lfs_file f; + NRF_LOG_INFO("[FS_S] -> Write"); + auto* header = (WriteHeader*) om->om_data; + uint16_t plen = header->pathlen; + if (plen > maxpathlen) { //> counts for null term return -1; } + memcpy(filepath, header->pathstr, plen); + filepath[plen + 1] = 0; // Copy and null teminate string + fileSize = header->totalSize; + WriteResponse resp; + resp.command = commands::WRITE_PACING; + resp.offset = header->offset; + resp.modTime = 0; + int res = fs.FileOpen(&f, filepath, LFS_O_RDWR | LFS_O_CREAT); + resp.status = res ? 0x02 : 0x01; + fs.FileClose(&f); + resp.freespace = std::min(fs.getSize() - (fs.GetFSSize() * fs.getBlockSize()), fileSize - header->offset); + auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(WriteResponse)); + ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); + break; } - case commands::WRITE_PACING: { - if (state != FSState::WRITE) { - return -1; - } + case commands::WRITE_DATA: { + lfs_file f; + NRF_LOG_INFO("[FS_S] -> WriteData"); + auto* header = (WritePacing*) om->om_data; + WriteResponse resp; + resp.command = commands::WRITE_PACING; + resp.offset = header->offset; + int res = fs.FileOpen(&f, filepath, LFS_O_RDWR | LFS_O_CREAT); + resp.status = res ? 0x02 : 0x01; + fs.FileSeek(&f, header->offset); + fs.FileWrite(&f, header->data, header->dataSize); + fs.FileClose(&f); + resp.freespace = std::min(fs.getSize() - (fs.GetFSSize() * fs.getBlockSize()), fileSize - header->offset); + // NRF_LOG_INFO('[FS_S] Used Blocks -> %u',resp.freespace); + auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(WriteResponse)); + ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); + break; } case commands::DELETE: { NRF_LOG_INFO("[FS_S] -> Delete"); diff --git a/src/components/ble/FSService.h b/src/components/ble/FSService.h index e9c98fb4..17f52eb0 100644 --- a/src/components/ble/FSService.h +++ b/src/components/ble/FSService.h @@ -47,9 +47,6 @@ namespace Pinetime { uint16_t versionCharacteristicHandle; uint16_t transferCharacteristicHandle; - // lfs_dir_t dir; - // lfs_info info; - enum class commands : uint8_t { INVALID = 0x00, READ = 0x10, @@ -74,6 +71,7 @@ namespace Pinetime { }; FSState state; char filepath[maxpathlen]; // TODO ..ugh fixed filepath len + int fileSize; using ReadHeader = struct __attribute__((packed)) { commands command; uint8_t padding; @@ -100,6 +98,33 @@ namespace Pinetime { uint32_t chunksize; }; + using WriteHeader = struct __attribute__((packed)) { + commands command; + uint8_t padding; + uint16_t pathlen; + uint32_t offset; + uint64_t modTime; + uint32_t totalSize; + char pathstr[]; + }; + + using WriteResponse = struct __attribute__((packed)) { + commands command; + uint8_t status; + uint16_t padding; + uint32_t offset; + uint64_t modTime; + uint32_t freespace; + }; + + using WritePacing = struct __attribute__((packed)) { + commands command; + uint8_t status; + uint16_t padding; + uint32_t offset; + uint32_t dataSize; + uint8_t data[]; + }; using ListDirHeader = struct __attribute__((packed)) { commands command; uint8_t padding; diff --git a/src/components/fs/FS.cpp b/src/components/fs/FS.cpp index c8a5a2eb..297706fe 100644 --- a/src/components/fs/FS.cpp +++ b/src/components/fs/FS.cpp @@ -107,7 +107,9 @@ int FS::DirCreate(const char* path) { int FS::Stat(const char* path, lfs_info* info) { return lfs_stat(&lfs, path, info); } - +lfs_ssize_t FS::GetFSSize(){ + return lfs_fs_size(&lfs); +} // Delete directory and all files inside int FS::DirDelete(const char* path) { diff --git a/src/components/fs/FS.h b/src/components/fs/FS.h index 1aa8d5f1..e4df9566 100644 --- a/src/components/fs/FS.h +++ b/src/components/fs/FS.h @@ -10,6 +10,8 @@ namespace Pinetime { public: FS(Pinetime::Drivers::SpiNorFlash&); + + void Init(); void LVGLFileSystemInit(); @@ -30,10 +32,11 @@ namespace Pinetime { int DirRewind(lfs_dir_t* dir); int DirCreate(const char* path); int DirDelete(const char* path); - + lfs_ssize_t GetFSSize(); int Stat(const char* path, lfs_info* info); void VerifyResource(); - + static size_t getSize(){return size;} + static size_t getBlockSize(){return blockSize;} private: Pinetime::Drivers::SpiNorFlash& flashDriver; @@ -62,6 +65,7 @@ namespace Pinetime { static constexpr size_t startAddress = 0x0B4000; static constexpr size_t size = 0x34C000; static constexpr size_t blockSize = 4096; + bool resourcesValid = false; const struct lfs_config lfsConfig; -- cgit v1.2.3-70-g09d2 From 8f46908d387cc4fe3f911bc0ca517719238418ed Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Tue, 26 Oct 2021 03:42:34 +0000 Subject: Fix lvgl_open to respect littlefs open errors --- src/components/ble/FSService.cpp | 6 ++---- src/components/fs/FS.cpp | 15 ++++++++------- 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index c784a8c4..0230ea15 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -156,7 +156,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { resp.command = commands::WRITE_PACING; resp.offset = header->offset; resp.modTime = 0; - int res = fs.FileOpen(&f, filepath, LFS_O_RDWR | LFS_O_CREAT); + int res = fs.FileOpen(&f, filepath, LFS_O_WRONLY | LFS_O_CREAT); resp.status = res ? 0x02 : 0x01; fs.FileClose(&f); resp.freespace = std::min(fs.getSize() - (fs.GetFSSize() * fs.getBlockSize()), fileSize - header->offset); @@ -177,7 +177,6 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { fs.FileWrite(&f, header->data, header->dataSize); fs.FileClose(&f); resp.freespace = std::min(fs.getSize() - (fs.GetFSSize() * fs.getBlockSize()), fileSize - header->offset); - // NRF_LOG_INFO('[FS_S] Used Blocks -> %u',resp.freespace); auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(WriteResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); break; @@ -222,14 +221,13 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { resp.status = 1; resp.totalentries = 0; resp.entry = 0; - resp.modification_time = 0; // TODO Does LFS actually support TS? + resp.modification_time = 0; if (fs.DirOpen(path, &dir) != 0) { resp.status = 0x02; auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); break; }; - // Count Total files in directory. while (fs.DirRead(&dir, &info)) { resp.totalentries++; } diff --git a/src/components/fs/FS.cpp b/src/components/fs/FS.cpp index 79fb2222..78b0f5cb 100644 --- a/src/components/fs/FS.cpp +++ b/src/components/fs/FS.cpp @@ -141,16 +141,17 @@ int FS::SectorRead(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, namespace { lv_fs_res_t lvglOpen(lv_fs_drv_t* drv, void* file_p, const char* path, lv_fs_mode_t mode) { - lfs_file_t* file = static_cast(file_p); FS* filesys = static_cast(drv->user_data); - filesys->FileOpen(file, path, LFS_O_RDONLY); - - if (file->type == 0) { - return LV_FS_RES_FS_ERR; - } else { - return LV_FS_RES_OK; + int res = filesys->FileOpen(file, path, LFS_O_RDONLY); + if (res == 0) { + if (file->type == 0) { + return LV_FS_RES_FS_ERR; + } else { + return LV_FS_RES_OK; + } } + return LV_FS_RES_NOT_EX; } lv_fs_res_t lvglClose(lv_fs_drv_t* drv, void* file_p) { -- cgit v1.2.3-70-g09d2 From 362a5ef1136399c178cf881f7569e3d291432ec1 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Tue, 16 Nov 2021 04:32:53 +0000 Subject: Added move function --- src/components/ble/FSService.cpp | 15 +++++++++++++++ src/components/ble/FSService.h | 17 ++++++++++++++--- src/components/fs/FS.cpp | 4 +++- src/components/fs/FS.h | 1 + 4 files changed, 33 insertions(+), 4 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index 0230ea15..1082d24c 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -270,6 +270,21 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); break; } + case commands::MOVE: { + NRF_LOG_INFO("[FS_S] -> Move"); + MoveHeader* header = (MoveHeader*) om->om_data; + uint16_t plen = header->OldPathLength; + // Null Terminate string + header->pathstr[plen] = 0; + char path[header->NewPathLength + 1] {0}; + memcpy(path, &header->pathstr[plen + 1], header->NewPathLength); + MoveResponse resp {}; + resp.command = commands::MOVE_STATUS; + int res = fs.Rename(header->pathstr, path); + resp.status = (res == 0) ? 1 : 2; + auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(MoveResponse)); + ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); + } default: break; } diff --git a/src/components/ble/FSService.h b/src/components/ble/FSService.h index 17f52eb0..828925a8 100644 --- a/src/components/ble/FSService.h +++ b/src/components/ble/FSService.h @@ -15,8 +15,7 @@ namespace Pinetime { class Ble; class FSService { public: - FSService(Pinetime::System::SystemTask& systemTask, - Pinetime::Controllers::FS& fs); + FSService(Pinetime::System::SystemTask& systemTask, Pinetime::Controllers::FS& fs); void Init(); int OnFSServiceRequested(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt* context); @@ -116,7 +115,7 @@ namespace Pinetime { uint64_t modTime; uint32_t freespace; }; - + using WritePacing = struct __attribute__((packed)) { commands command; uint8_t status; @@ -172,6 +171,18 @@ namespace Pinetime { commands command; uint8_t status; }; + using MoveHeader = struct __attribute__((packed)) { + commands command; + uint8_t padding; + uint16_t OldPathLength; + uint16_t NewPathLength; + char pathstr[]; + }; + + using MoveResponse = struct __attribute__((packed)) { + commands command; + uint8_t status; + }; int FSCommandHandler(uint16_t connectionHandle, os_mbuf* om); void prepareReadDataResp(ReadHeader* header, ReadResponse* resp); diff --git a/src/components/fs/FS.cpp b/src/components/fs/FS.cpp index 78b0f5cb..8c98ae34 100644 --- a/src/components/fs/FS.cpp +++ b/src/components/fs/FS.cpp @@ -95,7 +95,9 @@ int FS::DirRewind(lfs_dir_t* dir) { int FS::DirCreate(const char* path) { return lfs_mkdir(&lfs, path); } - +int FS::Rename(const char* oldPath, const char* newPath){ + return lfs_rename(&lfs,oldPath,newPath); +} int FS::Stat(const char* path, lfs_info* info) { return lfs_stat(&lfs, path, info); } diff --git a/src/components/fs/FS.h b/src/components/fs/FS.h index da3bd273..2b27ae5d 100644 --- a/src/components/fs/FS.h +++ b/src/components/fs/FS.h @@ -28,6 +28,7 @@ namespace Pinetime { int DirCreate(const char* path); lfs_ssize_t GetFSSize(); + int Rename(const char* oldPath, const char* newPath); int Stat(const char* path, lfs_info* info); void VerifyResource(); -- cgit v1.2.3-70-g09d2 From 09b9130244a7d5e448612d4a9a70988c2610d686 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Sat, 20 Nov 2021 04:57:02 +0000 Subject: Fix string nullterminations, Expand error codes. --- src/components/ble/FSService.cpp | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index 1082d24c..e1d5bae0 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -81,7 +81,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { return -1; } memcpy(filepath, header->pathstr, plen); - filepath[plen + 1] = 0; // Copy and null teminate string + filepath[plen] = 0; // Copy and null teminate string ReadResponse resp; os_mbuf* om; resp.command = commands::READ_DATA; @@ -150,14 +150,14 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { return -1; } memcpy(filepath, header->pathstr, plen); - filepath[plen + 1] = 0; // Copy and null teminate string + filepath[plen] = 0; // Copy and null teminate string fileSize = header->totalSize; WriteResponse resp; resp.command = commands::WRITE_PACING; resp.offset = header->offset; resp.modTime = 0; int res = fs.FileOpen(&f, filepath, LFS_O_WRONLY | LFS_O_CREAT); - resp.status = res ? 0x02 : 0x01; + resp.status = (res==0) ? 0x01: (int8_t)res; fs.FileClose(&f); resp.freespace = std::min(fs.getSize() - (fs.GetFSSize() * fs.getBlockSize()), fileSize - header->offset); auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(WriteResponse)); @@ -171,11 +171,14 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { WriteResponse resp; resp.command = commands::WRITE_PACING; resp.offset = header->offset; - int res = fs.FileOpen(&f, filepath, LFS_O_RDWR | LFS_O_CREAT); - resp.status = res ? 0x02 : 0x01; + resp.status = 1; + fs.FileOpen(&f, filepath, LFS_O_RDWR | LFS_O_CREAT); fs.FileSeek(&f, header->offset); - fs.FileWrite(&f, header->data, header->dataSize); + int res = fs.FileWrite(&f, header->data, header->dataSize); fs.FileClose(&f); + if(res < 0 ){ + resp.status = (int8_t)res; + } resp.freespace = std::min(fs.getSize() - (fs.GetFSSize() * fs.getBlockSize()), fileSize - header->offset); auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(WriteResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); @@ -187,9 +190,11 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { uint16_t plen = header->pathlen; char path[plen + 1] {0}; memcpy(path, header->pathstr, plen); + path[plen] = 0; // Copy and null teminate string DelResponse resp {}; resp.command = commands::DELETE_STATUS; - resp.status = fs.FileDelete(path) ? 0x02 : 0x01; + int res = fs.FileDelete(path); + resp.status = (res==0) ? 0x01 : (int8_t)res; auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(DelResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); break; @@ -200,10 +205,12 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { uint16_t plen = header->pathlen; char path[plen + 1] {0}; memcpy(path, header->pathstr, plen); + path[plen] = 0; // Copy and null teminate string MKDirResponse resp {}; resp.command = commands::MKDIR_STATUS; resp.modification_time = 0; - resp.status = fs.DirCreate(path) ? 0x02 : 0x01; + int res = fs.DirCreate(path); + resp.status = (res==0) ? 0x01 : (int8_t)res; auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(MKDirResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); break; @@ -213,6 +220,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { ListDirHeader* header = (ListDirHeader*) om->om_data; uint16_t plen = header->pathlen; char path[plen + 1] {0}; + path[plen] = 0; // Copy and null teminate string memcpy(path, header->pathstr, plen); ListDirResponse resp {}; @@ -222,8 +230,9 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { resp.totalentries = 0; resp.entry = 0; resp.modification_time = 0; - if (fs.DirOpen(path, &dir) != 0) { - resp.status = 0x02; + int res = fs.DirOpen(path, &dir); + if (res != 0) { + resp.status = (int8_t)res; auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); break; @@ -233,7 +242,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { } fs.DirRewind(&dir); while (true) { - int res = fs.DirRead(&dir, &info); + res = fs.DirRead(&dir, &info); if (res <= 0) { break; } @@ -278,10 +287,11 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { header->pathstr[plen] = 0; char path[header->NewPathLength + 1] {0}; memcpy(path, &header->pathstr[plen + 1], header->NewPathLength); + path[header->NewPathLength] = 0; // Copy and null teminate string MoveResponse resp {}; resp.command = commands::MOVE_STATUS; - int res = fs.Rename(header->pathstr, path); - resp.status = (res == 0) ? 1 : 2; + int8_t res = (int8_t)fs.Rename(header->pathstr, path); + resp.status = (res == 0) ? 1 : res; auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(MoveResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); } -- cgit v1.2.3-70-g09d2 From b62c62ee1f62d3371bfa29855bf2fd59b4dcecf8 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Sat, 20 Nov 2021 20:18:14 +0000 Subject: Change read to return LFS return values when reading a directory or nonexistant file --- src/components/ble/FSService.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index e1d5bae0..4cefcdcf 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -89,7 +89,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { resp.chunkoff = header->chunkoff; int res = fs.Stat(filepath, &info); if (res == LFS_ERR_NOENT && info.type != LFS_TYPE_DIR) { - resp.status = 0x03; + resp.status = (int8_t) res; resp.chunklen = 0; resp.totallen = 0; om = ble_hs_mbuf_from_flat(&resp, sizeof(ReadResponse)); @@ -118,7 +118,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { resp.chunkoff = header->chunkoff; int res = fs.Stat(filepath, &info); if (res == LFS_ERR_NOENT && info.type != LFS_TYPE_DIR) { - resp.status = 0x03; + resp.status = (int8_t) res; resp.chunklen = 0; resp.totallen = 0; } else { @@ -157,7 +157,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { resp.offset = header->offset; resp.modTime = 0; int res = fs.FileOpen(&f, filepath, LFS_O_WRONLY | LFS_O_CREAT); - resp.status = (res==0) ? 0x01: (int8_t)res; + resp.status = (res == 0) ? 0x01 : (int8_t) res; fs.FileClose(&f); resp.freespace = std::min(fs.getSize() - (fs.GetFSSize() * fs.getBlockSize()), fileSize - header->offset); auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(WriteResponse)); @@ -171,13 +171,13 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { WriteResponse resp; resp.command = commands::WRITE_PACING; resp.offset = header->offset; - resp.status = 1; + resp.status = 0x01; fs.FileOpen(&f, filepath, LFS_O_RDWR | LFS_O_CREAT); fs.FileSeek(&f, header->offset); - int res = fs.FileWrite(&f, header->data, header->dataSize); + int res = fs.FileWrite(&f, header->data, header->dataSize); fs.FileClose(&f); - if(res < 0 ){ - resp.status = (int8_t)res; + if (res < 0) { + resp.status = (int8_t) res; } resp.freespace = std::min(fs.getSize() - (fs.GetFSSize() * fs.getBlockSize()), fileSize - header->offset); auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(WriteResponse)); @@ -194,7 +194,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { DelResponse resp {}; resp.command = commands::DELETE_STATUS; int res = fs.FileDelete(path); - resp.status = (res==0) ? 0x01 : (int8_t)res; + resp.status = (res == 0) ? 0x01 : (int8_t) res; auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(DelResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); break; @@ -210,7 +210,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { resp.command = commands::MKDIR_STATUS; resp.modification_time = 0; int res = fs.DirCreate(path); - resp.status = (res==0) ? 0x01 : (int8_t)res; + resp.status = (res == 0) ? 0x01 : (int8_t) res; auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(MKDirResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); break; @@ -226,13 +226,13 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { ListDirResponse resp {}; resp.command = commands::LISTDIR_ENTRY; - resp.status = 1; + resp.status = 0x01; resp.totalentries = 0; resp.entry = 0; resp.modification_time = 0; int res = fs.DirOpen(path, &dir); if (res != 0) { - resp.status = (int8_t)res; + resp.status = (int8_t) res; auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(ListDirResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); break; @@ -290,7 +290,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { path[header->NewPathLength] = 0; // Copy and null teminate string MoveResponse resp {}; resp.command = commands::MOVE_STATUS; - int8_t res = (int8_t)fs.Rename(header->pathstr, path); + int8_t res = (int8_t) fs.Rename(header->pathstr, path); resp.status = (res == 0) ? 1 : res; auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(MoveResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); -- cgit v1.2.3-70-g09d2 From fdb5e27aea99c3a5117661948de75e7853165ff5 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Sun, 21 Nov 2021 03:33:00 +0000 Subject: Attempt at a more robust File handler --- src/components/ble/FSService.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index 4cefcdcf..2222ae9a 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -147,7 +147,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { auto* header = (WriteHeader*) om->om_data; uint16_t plen = header->pathlen; if (plen > maxpathlen) { //> counts for null term - return -1; + return -1; // TODO make this actually return a BLE notif } memcpy(filepath, header->pathstr, plen); filepath[plen] = 0; // Copy and null teminate string @@ -156,9 +156,12 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { resp.command = commands::WRITE_PACING; resp.offset = header->offset; resp.modTime = 0; + int res = fs.FileOpen(&f, filepath, LFS_O_WRONLY | LFS_O_CREAT); - resp.status = (res == 0) ? 0x01 : (int8_t) res; - fs.FileClose(&f); + if(res == 0){ + fs.FileClose(&f); + resp.status = (res == 0) ? 0x01 : (int8_t) res; + } resp.freespace = std::min(fs.getSize() - (fs.GetFSSize() * fs.getBlockSize()), fileSize - header->offset); auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(WriteResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); @@ -171,14 +174,18 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { WriteResponse resp; resp.command = commands::WRITE_PACING; resp.offset = header->offset; - resp.status = 0x01; - fs.FileOpen(&f, filepath, LFS_O_RDWR | LFS_O_CREAT); - fs.FileSeek(&f, header->offset); - int res = fs.FileWrite(&f, header->data, header->dataSize); - fs.FileClose(&f); + int res = 0; + + if (!(res = fs.FileOpen(&f, filepath, LFS_O_RDWR | LFS_O_CREAT))) { + if (!(res = fs.FileSeek(&f, header->offset))) { + res = fs.FileWrite(&f, header->data, header->dataSize); + } + fs.FileClose(&f); + } if (res < 0) { resp.status = (int8_t) res; } + resp.freespace = std::min(fs.getSize() - (fs.GetFSSize() * fs.getBlockSize()), fileSize - header->offset); auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(WriteResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); -- cgit v1.2.3-70-g09d2 From d1e9aa107617565b456f05e20e9468ab270d323e Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Sun, 21 Nov 2021 06:17:07 +0000 Subject: Force variable cleanup because LFS makes assumptions about variable initialization state --- src/components/ble/FSService.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index 2222ae9a..03d4673d 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -71,9 +71,11 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { } lfs_dir_t dir; lfs_info info; + lfs_file f; + memset(&f, 0, sizeof(lfs_file_t)); + memset(&dir, 0, sizeof(lfs_dir_t)); switch (command) { case commands::READ: { - lfs_file f; NRF_LOG_INFO("[FS_S] -> Read"); auto* header = (ReadHeader*) om->om_data; uint16_t plen = header->pathlen; @@ -109,7 +111,6 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { break; } case commands::READ_PACING: { - lfs_file f; NRF_LOG_INFO("[FS_S] -> Readpacing"); auto* header = (ReadHeader*) om->om_data; ReadResponse resp; @@ -142,7 +143,6 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { break; } case commands::WRITE: { - lfs_file f; NRF_LOG_INFO("[FS_S] -> Write"); auto* header = (WriteHeader*) om->om_data; uint16_t plen = header->pathlen; @@ -157,8 +157,8 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { resp.offset = header->offset; resp.modTime = 0; - int res = fs.FileOpen(&f, filepath, LFS_O_WRONLY | LFS_O_CREAT); - if(res == 0){ + int res = fs.FileOpen(&f, filepath, LFS_O_RDWR | LFS_O_CREAT); + if (res == 0) { fs.FileClose(&f); resp.status = (res == 0) ? 0x01 : (int8_t) res; } @@ -168,7 +168,6 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { break; } case commands::WRITE_DATA: { - lfs_file f; NRF_LOG_INFO("[FS_S] -> WriteData"); auto* header = (WritePacing*) om->om_data; WriteResponse resp; @@ -185,7 +184,6 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { if (res < 0) { resp.status = (int8_t) res; } - resp.freespace = std::min(fs.getSize() - (fs.GetFSSize() * fs.getBlockSize()), fileSize - header->offset); auto* om = ble_hs_mbuf_from_flat(&resp, sizeof(WriteResponse)); ble_gattc_notify_custom(connectionHandle, transferCharacteristicHandle, om); -- cgit v1.2.3-70-g09d2 From b9a2db1a49976cbfe92a9941bce17ffdbae7d0b3 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Sun, 21 Nov 2021 06:33:24 +0000 Subject: Fix large file support that broke due to a refactor. --- src/components/ble/FSService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index 03d4673d..d82596cb 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -176,7 +176,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { int res = 0; if (!(res = fs.FileOpen(&f, filepath, LFS_O_RDWR | LFS_O_CREAT))) { - if (!(res = fs.FileSeek(&f, header->offset))) { + if ((res = fs.FileSeek(&f, header->offset) ) >= 0) { res = fs.FileWrite(&f, header->data, header->dataSize); } fs.FileClose(&f); -- cgit v1.2.3-70-g09d2 From 0a0d1f270328001e1e80a2ac6c26feb111bfa27a Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Sun, 21 Nov 2021 21:35:41 +0000 Subject: Fix more initializers --- src/components/ble/FSService.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/FSService.cpp b/src/components/ble/FSService.cpp index d82596cb..8dc9ed67 100644 --- a/src/components/ble/FSService.cpp +++ b/src/components/ble/FSService.cpp @@ -69,11 +69,9 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { while (systemTask.IsSleeping()) { vTaskDelay(100); // 50ms } - lfs_dir_t dir; - lfs_info info; - lfs_file f; - memset(&f, 0, sizeof(lfs_file_t)); - memset(&dir, 0, sizeof(lfs_dir_t)); + lfs_dir_t dir = {0}; + lfs_info info = {0}; + lfs_file f = {0}; switch (command) { case commands::READ: { NRF_LOG_INFO("[FS_S] -> Read"); @@ -100,7 +98,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { resp.totallen = info.size; fs.FileOpen(&f, filepath, LFS_O_RDONLY); fs.FileSeek(&f, header->chunkoff); - uint8_t fileData[resp.chunklen] {0}; + uint8_t fileData[resp.chunklen] = {0}; resp.chunklen = fs.FileRead(&f, fileData, resp.chunklen); om = ble_hs_mbuf_from_flat(&resp, sizeof(ReadResponse)); os_mbuf_append(om, fileData, resp.chunklen); @@ -130,7 +128,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { } os_mbuf* om; if (resp.chunklen > 0) { - uint8_t fileData[resp.chunklen] {0}; + uint8_t fileData[resp.chunklen] = {0}; resp.chunklen = fs.FileRead(&f, fileData, resp.chunklen); om = ble_hs_mbuf_from_flat(&resp, sizeof(ReadResponse)); os_mbuf_append(om, fileData, resp.chunklen); @@ -176,7 +174,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { int res = 0; if (!(res = fs.FileOpen(&f, filepath, LFS_O_RDWR | LFS_O_CREAT))) { - if ((res = fs.FileSeek(&f, header->offset) ) >= 0) { + if ((res = fs.FileSeek(&f, header->offset)) >= 0) { res = fs.FileWrite(&f, header->data, header->dataSize); } fs.FileClose(&f); @@ -193,7 +191,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { NRF_LOG_INFO("[FS_S] -> Delete"); auto* header = (DelHeader*) om->om_data; uint16_t plen = header->pathlen; - char path[plen + 1] {0}; + char path[plen + 1] = {0}; memcpy(path, header->pathstr, plen); path[plen] = 0; // Copy and null teminate string DelResponse resp {}; @@ -208,7 +206,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { NRF_LOG_INFO("[FS_S] -> MKDir"); auto* header = (MKDirHeader*) om->om_data; uint16_t plen = header->pathlen; - char path[plen + 1] {0}; + char path[plen + 1] = {0}; memcpy(path, header->pathstr, plen); path[plen] = 0; // Copy and null teminate string MKDirResponse resp {}; @@ -224,7 +222,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { NRF_LOG_INFO("[FS_S] -> ListDir"); ListDirHeader* header = (ListDirHeader*) om->om_data; uint16_t plen = header->pathlen; - char path[plen + 1] {0}; + char path[plen + 1] = {0}; path[plen] = 0; // Copy and null teminate string memcpy(path, header->pathstr, plen); @@ -290,7 +288,7 @@ int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) { uint16_t plen = header->OldPathLength; // Null Terminate string header->pathstr[plen] = 0; - char path[header->NewPathLength + 1] {0}; + char path[header->NewPathLength + 1] = {0}; memcpy(path, &header->pathstr[plen + 1], header->NewPathLength); path[header->NewPathLength] = 0; // Copy and null teminate string MoveResponse resp {}; -- cgit v1.2.3-70-g09d2 From 1470489e7b14fdfe4871cdc714c4a3c98917c4bb Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Fri, 10 Dec 2021 01:49:03 +0000 Subject: Fix Failed rebase. --- src/components/ble/NimbleController.cpp | 7 +++---- src/components/ble/NimbleController.h | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 01230661..3bf1ec80 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -49,9 +49,8 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, batteryInformationService {batteryController}, immediateAlertService {systemTask, notificationManager}, heartRateService {systemTask, heartRateController}, - motionService{systemTask, motionController}, - fs {fs}, - fsService {systemTask,fs}, + motionService {systemTask, motionController}, + fsService {systemTask, fs}, serviceDiscovery({¤tTimeClient, &alertNotificationClient}) { } @@ -100,7 +99,7 @@ void NimbleController::Init() { heartRateService.Init(); motionService.Init(); fsService.Init(); - + int rc; rc = ble_hs_util_ensure_addr(0); ASSERT(rc == 0); diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 14749b8d..7a387037 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -111,7 +111,6 @@ namespace Pinetime { HeartRateService heartRateService; MotionService motionService; ServiceDiscovery serviceDiscovery; - FS fs; FSService fsService; uint8_t addrType; -- cgit v1.2.3-70-g09d2 From eca0588c2328a72aee3c6132c7c4221277cb8b28 Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Tue, 21 Dec 2021 16:02:01 -0600 Subject: Optional secure pairing with a passkey Support passkey pairing when requested by the central Fix a comment and reorder warning --- src/components/ble/BatteryInformationService.cpp | 2 +- src/components/ble/NimbleController.cpp | 6 ++---- src/components/ble/NimbleController.h | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) (limited to 'src/components/ble') diff --git a/src/components/ble/BatteryInformationService.cpp b/src/components/ble/BatteryInformationService.cpp index 82df7b15..9a3f86f5 100644 --- a/src/components/ble/BatteryInformationService.cpp +++ b/src/components/ble/BatteryInformationService.cpp @@ -17,7 +17,7 @@ BatteryInformationService::BatteryInformationService(Controllers::Battery& batte characteristicDefinition {{.uuid = &batteryLevelUuid.u, .access_cb = BatteryInformationServiceCallback, .arg = this, - .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_READ_AUTHEN | BLE_GATT_CHR_F_NOTIFY, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY, .val_handle = &batteryLevelHandle}, {0}}, serviceDefinition { diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 3bf1ec80..d8510bd3 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -134,9 +134,7 @@ void NimbleController::Init() { RestoreBond(); - if (!ble_gap_adv_active() && !bleController.IsConnected()) { - StartAdvertising(); - } + StartAdvertising(); } void NimbleController::StartAdvertising() { @@ -274,7 +272,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { * display capability only so we only handle the "display" action here. * * Standards insist that the rand() PRNG be deterministic. - * Use the nimble TRNG here since rand() is predictable. + * Use the tinycrypt prng here since rand() is predictable. */ NRF_LOG_INFO("Security event : BLE_GAP_EVENT_PASSKEY_ACTION"); if (event->passkey.params.action == BLE_SM_IOACT_DISP) { diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 7a387037..2b300e63 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -110,8 +110,8 @@ namespace Pinetime { ImmediateAlertService immediateAlertService; HeartRateService heartRateService; MotionService motionService; - ServiceDiscovery serviceDiscovery; FSService fsService; + ServiceDiscovery serviceDiscovery; uint8_t addrType; uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE; -- cgit v1.2.3-70-g09d2