From b9382c912ebf153c82d7c7af1f1f7a934b5c8ff6 Mon Sep 17 00:00:00 2001 From: HTotoo Date: Wed, 20 Sep 2023 13:47:33 +0200 Subject: [PATCH] WIP integrate weather, tpms and pocsag to SubGhz app --- .../external/pocsag_pager/application.fam | 14 - .../pocsag_pager/helpers/pocsag_pager_event.h | 14 - .../pocsag_pager/helpers/pocsag_pager_types.h | 49 -- .../helpers/radio_device_loader.c | 66 --- .../helpers/radio_device_loader.h | 17 - .../pocsag_pager/images/Message_8x7.png | Bin 130 -> 0 bytes .../pocsag_pager/pocsag_pager_10px.png | Bin 134 -> 0 bytes .../external/pocsag_pager/pocsag_pager_app.c | 206 -------- .../pocsag_pager/pocsag_pager_app_i.c | 146 ------ .../pocsag_pager/pocsag_pager_app_i.h | 76 --- .../pocsag_pager/pocsag_pager_history.c | 223 -------- .../pocsag_pager/pocsag_pager_history.h | 112 ---- .../pocsag_pager/protocols/protocol_items.c | 9 - .../pocsag_pager/protocols/protocol_items.h | 6 - .../scenes/pocsag_pager_receiver.c | 214 -------- .../pocsag_pager/scenes/pocsag_pager_scene.c | 30 -- .../pocsag_pager/scenes/pocsag_pager_scene.h | 29 -- .../scenes/pocsag_pager_scene_about.c | 74 --- .../scenes/pocsag_pager_scene_config.h | 5 - .../pocsag_pager_scene_receiver_config.c | 221 -------- .../scenes/pocsag_pager_scene_receiver_info.c | 50 -- .../scenes/pocsag_pager_scene_start.c | 58 --- .../views/pocsag_pager_receiver.c | 479 ------------------ .../views/pocsag_pager_receiver.h | 43 -- .../views/pocsag_pager_receiver_info.c | 138 ----- .../views/pocsag_pager_receiver_info.h | 16 - .../external/weather_station/application.fam | 14 - .../helpers/radio_device_loader.c | 69 --- .../helpers/radio_device_loader.h | 17 - .../helpers/weather_station_event.h | 14 - .../helpers/weather_station_types.h | 49 -- .../weather_station/images/Humid_10x15.png | Bin 3624 -> 0 bytes .../weather_station/images/Humid_8x13.png | Bin 3618 -> 0 bytes .../weather_station/images/Therm_7x16.png | Bin 3611 -> 0 bytes .../weather_station/images/Timer_11x11.png | Bin 3616 -> 0 bytes .../weather_station/images/station_icon.png | Bin 3607 -> 0 bytes .../protocols/protocol_items.c | 26 - .../protocols/protocol_items.h | 23 - .../scenes/weather_station_receiver.c | 216 -------- .../scenes/weather_station_scene.c | 30 -- .../scenes/weather_station_scene.h | 29 -- .../scenes/weather_station_scene_about.c | 78 --- .../scenes/weather_station_scene_config.h | 5 - .../weather_station_scene_receiver_config.c | 223 -------- .../weather_station_scene_receiver_info.c | 50 -- .../scenes/weather_station_scene_start.c | 58 --- .../views/weather_station_receiver.c | 473 ----------------- .../views/weather_station_receiver.h | 39 -- .../views/weather_station_receiver_info.c | 246 --------- .../views/weather_station_receiver_info.h | 16 - .../weather_station/weather_station_10px.png | Bin 175 -> 0 bytes .../weather_station/weather_station_app.c | 188 ------- .../weather_station/weather_station_app_i.c | 155 ------ .../weather_station/weather_station_app_i.h | 76 --- .../weather_station/weather_station_history.c | 245 --------- .../weather_station/weather_station_history.h | 112 ---- .../scenes/subghz_scene_receiver_config.c | 33 ++ .../subghz}/protocols/acurite_592txr.c | 4 +- .../subghz}/protocols/acurite_592txr.h | 0 .../subghz}/protocols/acurite_606tx.c | 4 +- .../subghz}/protocols/acurite_606tx.h | 0 .../subghz}/protocols/acurite_609txc.c | 4 +- .../subghz}/protocols/acurite_609txc.h | 0 .../subghz}/protocols/ambient_weather.c | 4 +- .../subghz}/protocols/ambient_weather.h | 0 .../subghz}/protocols/auriol_ahfl.c | 4 +- .../subghz}/protocols/auriol_ahfl.h | 0 .../subghz}/protocols/auriol_hg0601a.c | 4 +- .../subghz}/protocols/auriol_hg0601a.h | 0 .../subghz}/protocols/gt_wt_02.c | 8 +- .../subghz}/protocols/gt_wt_02.h | 0 .../subghz}/protocols/gt_wt_03.c | 4 +- .../subghz}/protocols/gt_wt_03.h | 0 .../subghz}/protocols/infactory.c | 4 +- .../subghz}/protocols/infactory.h | 0 .../subghz}/protocols/lacrosse_tx.c | 4 +- .../subghz}/protocols/lacrosse_tx.h | 0 .../subghz}/protocols/lacrosse_tx141thbv2.c | 4 +- .../subghz}/protocols/lacrosse_tx141thbv2.h | 0 .../subghz}/protocols/nexus_th.c | 4 +- .../subghz}/protocols/nexus_th.h | 0 .../subghz}/protocols/oregon2.c | 3 +- .../subghz}/protocols/oregon2.h | 0 .../subghz}/protocols/oregon3.c | 3 +- .../subghz}/protocols/oregon3.h | 0 .../subghz}/protocols/oregon_v1.c | 10 +- .../subghz}/protocols/oregon_v1.h | 0 .../subghz}/protocols/pcsg_generic.c | 1 - .../subghz}/protocols/pcsg_generic.h | 3 + .../subghz}/protocols/pocsag.c | 0 .../subghz}/protocols/pocsag.h | 0 lib/subghz/protocols/protocol_items.c | 20 + lib/subghz/protocols/protocol_items.h | 20 + lib/subghz/protocols/schrader_gg4.c | 295 +++++++++++ lib/subghz/protocols/schrader_gg4.h | 80 +++ .../subghz}/protocols/thermopro_tx4.c | 4 +- .../subghz}/protocols/thermopro_tx4.h | 0 lib/subghz/protocols/tpms_generic.c | 227 +++++++++ lib/subghz/protocols/tpms_generic.h | 80 +++ .../subghz}/protocols/tx_8300.c | 4 +- .../subghz}/protocols/tx_8300.h | 0 .../subghz}/protocols/wendox_w6726.c | 4 +- .../subghz}/protocols/wendox_w6726.h | 0 .../subghz}/protocols/ws_generic.c | 2 +- .../subghz}/protocols/ws_generic.h | 3 + lib/subghz/types.h | 2 + 106 files changed, 805 insertions(+), 4787 deletions(-) delete mode 100644 applications/external/pocsag_pager/application.fam delete mode 100644 applications/external/pocsag_pager/helpers/pocsag_pager_event.h delete mode 100644 applications/external/pocsag_pager/helpers/pocsag_pager_types.h delete mode 100644 applications/external/pocsag_pager/helpers/radio_device_loader.c delete mode 100644 applications/external/pocsag_pager/helpers/radio_device_loader.h delete mode 100644 applications/external/pocsag_pager/images/Message_8x7.png delete mode 100644 applications/external/pocsag_pager/pocsag_pager_10px.png delete mode 100644 applications/external/pocsag_pager/pocsag_pager_app.c delete mode 100644 applications/external/pocsag_pager/pocsag_pager_app_i.c delete mode 100644 applications/external/pocsag_pager/pocsag_pager_app_i.h delete mode 100644 applications/external/pocsag_pager/pocsag_pager_history.c delete mode 100644 applications/external/pocsag_pager/pocsag_pager_history.h delete mode 100644 applications/external/pocsag_pager/protocols/protocol_items.c delete mode 100644 applications/external/pocsag_pager/protocols/protocol_items.h delete mode 100644 applications/external/pocsag_pager/scenes/pocsag_pager_receiver.c delete mode 100644 applications/external/pocsag_pager/scenes/pocsag_pager_scene.c delete mode 100644 applications/external/pocsag_pager/scenes/pocsag_pager_scene.h delete mode 100644 applications/external/pocsag_pager/scenes/pocsag_pager_scene_about.c delete mode 100644 applications/external/pocsag_pager/scenes/pocsag_pager_scene_config.h delete mode 100644 applications/external/pocsag_pager/scenes/pocsag_pager_scene_receiver_config.c delete mode 100644 applications/external/pocsag_pager/scenes/pocsag_pager_scene_receiver_info.c delete mode 100644 applications/external/pocsag_pager/scenes/pocsag_pager_scene_start.c delete mode 100644 applications/external/pocsag_pager/views/pocsag_pager_receiver.c delete mode 100644 applications/external/pocsag_pager/views/pocsag_pager_receiver.h delete mode 100644 applications/external/pocsag_pager/views/pocsag_pager_receiver_info.c delete mode 100644 applications/external/pocsag_pager/views/pocsag_pager_receiver_info.h delete mode 100644 applications/external/weather_station/application.fam delete mode 100644 applications/external/weather_station/helpers/radio_device_loader.c delete mode 100644 applications/external/weather_station/helpers/radio_device_loader.h delete mode 100644 applications/external/weather_station/helpers/weather_station_event.h delete mode 100644 applications/external/weather_station/helpers/weather_station_types.h delete mode 100644 applications/external/weather_station/images/Humid_10x15.png delete mode 100644 applications/external/weather_station/images/Humid_8x13.png delete mode 100644 applications/external/weather_station/images/Therm_7x16.png delete mode 100644 applications/external/weather_station/images/Timer_11x11.png delete mode 100644 applications/external/weather_station/images/station_icon.png delete mode 100644 applications/external/weather_station/protocols/protocol_items.c delete mode 100644 applications/external/weather_station/protocols/protocol_items.h delete mode 100644 applications/external/weather_station/scenes/weather_station_receiver.c delete mode 100644 applications/external/weather_station/scenes/weather_station_scene.c delete mode 100644 applications/external/weather_station/scenes/weather_station_scene.h delete mode 100644 applications/external/weather_station/scenes/weather_station_scene_about.c delete mode 100644 applications/external/weather_station/scenes/weather_station_scene_config.h delete mode 100644 applications/external/weather_station/scenes/weather_station_scene_receiver_config.c delete mode 100644 applications/external/weather_station/scenes/weather_station_scene_receiver_info.c delete mode 100644 applications/external/weather_station/scenes/weather_station_scene_start.c delete mode 100644 applications/external/weather_station/views/weather_station_receiver.c delete mode 100644 applications/external/weather_station/views/weather_station_receiver.h delete mode 100644 applications/external/weather_station/views/weather_station_receiver_info.c delete mode 100644 applications/external/weather_station/views/weather_station_receiver_info.h delete mode 100644 applications/external/weather_station/weather_station_10px.png delete mode 100644 applications/external/weather_station/weather_station_app.c delete mode 100644 applications/external/weather_station/weather_station_app_i.c delete mode 100644 applications/external/weather_station/weather_station_app_i.h delete mode 100644 applications/external/weather_station/weather_station_history.c delete mode 100644 applications/external/weather_station/weather_station_history.h rename {applications/external/weather_station => lib/subghz}/protocols/acurite_592txr.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/acurite_592txr.h (100%) rename {applications/external/weather_station => lib/subghz}/protocols/acurite_606tx.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/acurite_606tx.h (100%) rename {applications/external/weather_station => lib/subghz}/protocols/acurite_609txc.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/acurite_609txc.h (100%) rename {applications/external/weather_station => lib/subghz}/protocols/ambient_weather.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/ambient_weather.h (100%) rename {applications/external/weather_station => lib/subghz}/protocols/auriol_ahfl.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/auriol_ahfl.h (100%) rename {applications/external/weather_station => lib/subghz}/protocols/auriol_hg0601a.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/auriol_hg0601a.h (100%) rename {applications/external/weather_station => lib/subghz}/protocols/gt_wt_02.c (98%) rename {applications/external/weather_station => lib/subghz}/protocols/gt_wt_02.h (100%) rename {applications/external/weather_station => lib/subghz}/protocols/gt_wt_03.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/gt_wt_03.h (100%) rename {applications/external/weather_station => lib/subghz}/protocols/infactory.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/infactory.h (100%) rename {applications/external/weather_station => lib/subghz}/protocols/lacrosse_tx.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/lacrosse_tx.h (100%) rename {applications/external/weather_station => lib/subghz}/protocols/lacrosse_tx141thbv2.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/lacrosse_tx141thbv2.h (100%) rename {applications/external/weather_station => lib/subghz}/protocols/nexus_th.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/nexus_th.h (100%) rename {applications/external/weather_station => lib/subghz}/protocols/oregon2.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/oregon2.h (100%) rename {applications/external/weather_station => lib/subghz}/protocols/oregon3.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/oregon3.h (100%) rename {applications/external/weather_station => lib/subghz}/protocols/oregon_v1.c (98%) rename {applications/external/weather_station => lib/subghz}/protocols/oregon_v1.h (100%) rename {applications/external/pocsag_pager => lib/subghz}/protocols/pcsg_generic.c (99%) rename {applications/external/pocsag_pager => lib/subghz}/protocols/pcsg_generic.h (93%) rename {applications/external/pocsag_pager => lib/subghz}/protocols/pocsag.c (100%) rename {applications/external/pocsag_pager => lib/subghz}/protocols/pocsag.h (100%) create mode 100644 lib/subghz/protocols/schrader_gg4.c create mode 100644 lib/subghz/protocols/schrader_gg4.h rename {applications/external/weather_station => lib/subghz}/protocols/thermopro_tx4.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/thermopro_tx4.h (100%) create mode 100644 lib/subghz/protocols/tpms_generic.c create mode 100644 lib/subghz/protocols/tpms_generic.h rename {applications/external/weather_station => lib/subghz}/protocols/tx_8300.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/tx_8300.h (100%) rename {applications/external/weather_station => lib/subghz}/protocols/wendox_w6726.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/wendox_w6726.h (100%) rename {applications/external/weather_station => lib/subghz}/protocols/ws_generic.c (99%) rename {applications/external/weather_station => lib/subghz}/protocols/ws_generic.h (95%) diff --git a/applications/external/pocsag_pager/application.fam b/applications/external/pocsag_pager/application.fam deleted file mode 100644 index 04634c81f..000000000 --- a/applications/external/pocsag_pager/application.fam +++ /dev/null @@ -1,14 +0,0 @@ -App( - appid="pocsag_pager", - name="POCSAG Pager", - apptype=FlipperAppType.EXTERNAL, - entry_point="pocsag_pager_app", - requires=["gui"], - stack_size=4 * 1024, - fap_icon="pocsag_pager_10px.png", - fap_category="Sub-GHz", - fap_icon_assets="images", - fap_author="@xMasterX & @Shmuma", - fap_version="1.0", - fap_description="App can capture POCSAG 1200 messages on CC1101 supported frequencies.", -) diff --git a/applications/external/pocsag_pager/helpers/pocsag_pager_event.h b/applications/external/pocsag_pager/helpers/pocsag_pager_event.h deleted file mode 100644 index 8bcf64a30..000000000 --- a/applications/external/pocsag_pager/helpers/pocsag_pager_event.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -typedef enum { - //PCSGCustomEvent - PCSGCustomEventStartId = 100, - - PCSGCustomEventSceneSettingLock, - - PCSGCustomEventViewReceiverOK, - PCSGCustomEventViewReceiverConfig, - PCSGCustomEventViewReceiverBack, - PCSGCustomEventViewReceiverOffDisplay, - PCSGCustomEventViewReceiverUnlock, -} PCSGCustomEvent; diff --git a/applications/external/pocsag_pager/helpers/pocsag_pager_types.h b/applications/external/pocsag_pager/helpers/pocsag_pager_types.h deleted file mode 100644 index fabd7f321..000000000 --- a/applications/external/pocsag_pager/helpers/pocsag_pager_types.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include -#include - -#define PCSG_VERSION_APP "0.1" -#define PCSG_DEVELOPED "@xMasterX & @Shmuma" -#define PCSG_GITHUB "https://github.com/xMasterX/flipper-pager" - -#define PCSG_KEY_FILE_VERSION 1 -#define PCSG_KEY_FILE_TYPE "Flipper POCSAG Pager Key File" - -/** PCSGRxKeyState state */ -typedef enum { - PCSGRxKeyStateIDLE, - PCSGRxKeyStateBack, - PCSGRxKeyStateStart, - PCSGRxKeyStateAddKey, -} PCSGRxKeyState; - -/** PCSGHopperState state */ -typedef enum { - PCSGHopperStateOFF, - PCSGHopperStateRunnig, - PCSGHopperStatePause, - PCSGHopperStateRSSITimeOut, -} PCSGHopperState; - -/** PCSGLock */ -typedef enum { - PCSGLockOff, - PCSGLockOn, -} PCSGLock; - -typedef enum { - POCSAGPagerViewVariableItemList, - POCSAGPagerViewSubmenu, - POCSAGPagerViewReceiver, - POCSAGPagerViewReceiverInfo, - POCSAGPagerViewWidget, -} POCSAGPagerView; - -/** POCSAGPagerTxRx state */ -typedef enum { - PCSGTxRxStateIDLE, - PCSGTxRxStateRx, - PCSGTxRxStateTx, - PCSGTxRxStateSleep, -} PCSGTxRxState; diff --git a/applications/external/pocsag_pager/helpers/radio_device_loader.c b/applications/external/pocsag_pager/helpers/radio_device_loader.c deleted file mode 100644 index ce0920755..000000000 --- a/applications/external/pocsag_pager/helpers/radio_device_loader.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "radio_device_loader.h" - -#include -#include - -static void radio_device_loader_power_on() { - uint8_t attempts = 0; - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - //CC1101 power-up time - furi_delay_ms(10); - } -} - -static void radio_device_loader_power_off() { - if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg(); -} - -bool radio_device_loader_is_connect_external(const char* name) { - bool is_connect = false; - bool is_otg_enabled = furi_hal_power_is_otg_enabled(); - - if(!is_otg_enabled) { - radio_device_loader_power_on(); - } - - is_connect = subghz_devices_is_connect(subghz_devices_get_by_name(name)); - - if(!is_otg_enabled) { - radio_device_loader_power_off(); - } - return is_connect; -} - -const SubGhzDevice* radio_device_loader_set( - const SubGhzDevice* current_radio_device, - SubGhzRadioDeviceType radio_device_type) { - const SubGhzDevice* radio_device; - - if(radio_device_type == SubGhzRadioDeviceTypeExternalCC1101 && - radio_device_loader_is_connect_external(SUBGHZ_DEVICE_CC1101_EXT_NAME)) { - radio_device_loader_power_on(); - radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_EXT_NAME); - subghz_devices_begin(radio_device); - } else if(current_radio_device == NULL) { - radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME); - } else { - radio_device_loader_end(current_radio_device); - radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME); - } - - return radio_device; -} - -bool radio_device_loader_is_external(const SubGhzDevice* radio_device) { - furi_assert(radio_device); - return (radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME)); -} - -void radio_device_loader_end(const SubGhzDevice* radio_device) { - furi_assert(radio_device); - radio_device_loader_power_off(); - if(radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME)) { - subghz_devices_end(radio_device); - } -} \ No newline at end of file diff --git a/applications/external/pocsag_pager/helpers/radio_device_loader.h b/applications/external/pocsag_pager/helpers/radio_device_loader.h deleted file mode 100644 index bae4bacf2..000000000 --- a/applications/external/pocsag_pager/helpers/radio_device_loader.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include - -/** SubGhzRadioDeviceType */ -typedef enum { - SubGhzRadioDeviceTypeInternal, - SubGhzRadioDeviceTypeExternalCC1101, -} SubGhzRadioDeviceType; - -const SubGhzDevice* radio_device_loader_set( - const SubGhzDevice* current_radio_device, - SubGhzRadioDeviceType radio_device_type); - -bool radio_device_loader_is_external(const SubGhzDevice* radio_device); - -void radio_device_loader_end(const SubGhzDevice* radio_device); \ No newline at end of file diff --git a/applications/external/pocsag_pager/images/Message_8x7.png b/applications/external/pocsag_pager/images/Message_8x7.png deleted file mode 100644 index 642688cd5af3f8bf3e2f12c822edce2c1d9246fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 130 zcmeAS@N?(olHy`uVBq!ia0vp^96-#@!3HEvBYEP06k~CayA#8@b22Z192-v;#}J9| z)_zAW1_O@6Z~n{A4RjPVpP|0da0P?P(bWwFNzXVd3>lY8Yh_E@Xsq~Ub|&GLUV{9j c1Mj<;Pq%3Oeo&)42WSq1r>mdKI;Vst0QP_;f4F%}28J29*~C-V}>aqx6;4ABTq z{`3F;|9Unh24xRLWo6~Kr3#xJv^b==j5yW_OkbIB`9x61`H2#0ht@P+R5&XUCTueC g#REkNvw+nM!Ra<%Cov0d1DeI)>FVdQ&MBb@045|TWdHyG diff --git a/applications/external/pocsag_pager/pocsag_pager_app.c b/applications/external/pocsag_pager/pocsag_pager_app.c deleted file mode 100644 index 70ff49f1a..000000000 --- a/applications/external/pocsag_pager/pocsag_pager_app.c +++ /dev/null @@ -1,206 +0,0 @@ -#include "pocsag_pager_app_i.h" - -#include -#include -#include -#include "protocols/protocol_items.h" - -static bool pocsag_pager_app_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - POCSAGPagerApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool pocsag_pager_app_back_event_callback(void* context) { - furi_assert(context); - POCSAGPagerApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -static void pocsag_pager_app_tick_event_callback(void* context) { - furi_assert(context); - POCSAGPagerApp* app = context; - scene_manager_handle_tick_event(app->scene_manager); -} - -POCSAGPagerApp* pocsag_pager_app_alloc() { - POCSAGPagerApp* app = malloc(sizeof(POCSAGPagerApp)); - - // GUI - app->gui = furi_record_open(RECORD_GUI); - - // View Dispatcher - app->view_dispatcher = view_dispatcher_alloc(); - app->scene_manager = scene_manager_alloc(&pocsag_pager_scene_handlers, app); - view_dispatcher_enable_queue(app->view_dispatcher); - - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - view_dispatcher_set_custom_event_callback( - app->view_dispatcher, pocsag_pager_app_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, pocsag_pager_app_back_event_callback); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, pocsag_pager_app_tick_event_callback, 100); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - // Open Notification record - app->notifications = furi_record_open(RECORD_NOTIFICATION); - - // Variable Item List - app->variable_item_list = variable_item_list_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - POCSAGPagerViewVariableItemList, - variable_item_list_get_view(app->variable_item_list)); - - // SubMenu - app->submenu = submenu_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, POCSAGPagerViewSubmenu, submenu_get_view(app->submenu)); - - // Widget - app->widget = widget_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, POCSAGPagerViewWidget, widget_get_view(app->widget)); - - // Receiver - app->pcsg_receiver = pcsg_view_receiver_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - POCSAGPagerViewReceiver, - pcsg_view_receiver_get_view(app->pcsg_receiver)); - - // Receiver Info - app->pcsg_receiver_info = pcsg_view_receiver_info_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - POCSAGPagerViewReceiverInfo, - pcsg_view_receiver_info_get_view(app->pcsg_receiver_info)); - - //init setting - app->setting = subghz_setting_alloc(); - - //ToDo FIX file name setting - - subghz_setting_load(app->setting, EXT_PATH("pocsag/settings.txt")); - - //init Worker & Protocol & History - app->lock = PCSGLockOff; - app->txrx = malloc(sizeof(POCSAGPagerTxRx)); - app->txrx->preset = malloc(sizeof(SubGhzRadioPreset)); - app->txrx->preset->name = furi_string_alloc(); - - furi_hal_power_suppress_charge_enter(); - - // Radio Devices init & load - subghz_devices_init(); - app->txrx->radio_device = - radio_device_loader_set(app->txrx->radio_device, SubGhzRadioDeviceTypeExternalCC1101); - - subghz_devices_reset(app->txrx->radio_device); - subghz_devices_idle(app->txrx->radio_device); - - // Custom Presets load without using config file - - FlipperFormat* temp_fm_preset = flipper_format_string_alloc(); - flipper_format_write_string_cstr( - temp_fm_preset, - (const char*)"Custom_preset_data", - (const char*)"02 0D 0B 06 08 32 07 04 14 00 13 02 12 04 11 83 10 67 15 24 18 18 19 16 1D 91 1C 00 1B 07 20 FB 22 10 21 56 00 00 C0 00 00 00 00 00 00 00"); - flipper_format_rewind(temp_fm_preset); - subghz_setting_load_custom_preset(app->setting, (const char*)"FM95", temp_fm_preset); - - flipper_format_free(temp_fm_preset); - - // custom presets loading - end - - pcsg_preset_init(app, "FM95", 439987500, NULL, 0); - - app->txrx->hopper_state = PCSGHopperStateOFF; - app->txrx->history = pcsg_history_alloc(); - app->txrx->worker = subghz_worker_alloc(); - app->txrx->environment = subghz_environment_alloc(); - subghz_environment_set_protocol_registry( - app->txrx->environment, (void*)&pocsag_pager_protocol_registry); - app->txrx->receiver = subghz_receiver_alloc_init(app->txrx->environment); - - subghz_receiver_set_filter(app->txrx->receiver, SubGhzProtocolFlag_Decodable); - subghz_worker_set_overrun_callback( - app->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset); - subghz_worker_set_pair_callback( - app->txrx->worker, (SubGhzWorkerPairCallback)subghz_receiver_decode); - subghz_worker_set_context(app->txrx->worker, app->txrx->receiver); - - scene_manager_next_scene(app->scene_manager, POCSAGPagerSceneStart); - - return app; -} - -void pocsag_pager_app_free(POCSAGPagerApp* app) { - furi_assert(app); - - // Radio Devices sleep & off - pcsg_sleep(app); - radio_device_loader_end(app->txrx->radio_device); - - subghz_devices_deinit(); - - // Submenu - view_dispatcher_remove_view(app->view_dispatcher, POCSAGPagerViewSubmenu); - submenu_free(app->submenu); - - // Variable Item List - view_dispatcher_remove_view(app->view_dispatcher, POCSAGPagerViewVariableItemList); - variable_item_list_free(app->variable_item_list); - - // Widget - view_dispatcher_remove_view(app->view_dispatcher, POCSAGPagerViewWidget); - widget_free(app->widget); - - // Receiver - view_dispatcher_remove_view(app->view_dispatcher, POCSAGPagerViewReceiver); - pcsg_view_receiver_free(app->pcsg_receiver); - - // Receiver Info - view_dispatcher_remove_view(app->view_dispatcher, POCSAGPagerViewReceiverInfo); - pcsg_view_receiver_info_free(app->pcsg_receiver_info); - - //setting - subghz_setting_free(app->setting); - - //Worker & Protocol & History - subghz_receiver_free(app->txrx->receiver); - subghz_environment_free(app->txrx->environment); - pcsg_history_free(app->txrx->history); - subghz_worker_free(app->txrx->worker); - furi_string_free(app->txrx->preset->name); - free(app->txrx->preset); - free(app->txrx); - - // View dispatcher - view_dispatcher_free(app->view_dispatcher); - scene_manager_free(app->scene_manager); - - // Notifications - furi_record_close(RECORD_NOTIFICATION); - app->notifications = NULL; - - // Close records - furi_record_close(RECORD_GUI); - - furi_hal_power_suppress_charge_exit(); - - free(app); -} - -int32_t pocsag_pager_app(void* p) { - UNUSED(p); - POCSAGPagerApp* pocsag_pager_app = pocsag_pager_app_alloc(); - - view_dispatcher_run(pocsag_pager_app->view_dispatcher); - - pocsag_pager_app_free(pocsag_pager_app); - - return 0; -} diff --git a/applications/external/pocsag_pager/pocsag_pager_app_i.c b/applications/external/pocsag_pager/pocsag_pager_app_i.c deleted file mode 100644 index 8dda1d8b6..000000000 --- a/applications/external/pocsag_pager/pocsag_pager_app_i.c +++ /dev/null @@ -1,146 +0,0 @@ -#include "pocsag_pager_app_i.h" - -#define TAG "POCSAGPager" -#include - -void pcsg_preset_init( - void* context, - const char* preset_name, - uint32_t frequency, - uint8_t* preset_data, - size_t preset_data_size) { - furi_assert(context); - POCSAGPagerApp* app = context; - furi_string_set(app->txrx->preset->name, preset_name); - app->txrx->preset->frequency = frequency; - app->txrx->preset->data = preset_data; - app->txrx->preset->data_size = preset_data_size; -} - -void pcsg_get_frequency_modulation( - POCSAGPagerApp* app, - FuriString* frequency, - FuriString* modulation) { - furi_assert(app); - if(frequency != NULL) { - furi_string_printf( - frequency, - "%03ld.%02ld", - app->txrx->preset->frequency / 1000000 % 1000, - app->txrx->preset->frequency / 10000 % 100); - } - if(modulation != NULL) { - furi_string_printf(modulation, "%.2s", furi_string_get_cstr(app->txrx->preset->name)); - } -} - -void pcsg_begin(POCSAGPagerApp* app, uint8_t* preset_data) { - furi_assert(app); - - subghz_devices_reset(app->txrx->radio_device); - subghz_devices_idle(app->txrx->radio_device); - subghz_devices_load_preset(app->txrx->radio_device, FuriHalSubGhzPresetCustom, preset_data); - - // furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow); - app->txrx->txrx_state = PCSGTxRxStateIDLE; -} - -uint32_t pcsg_rx(POCSAGPagerApp* app, uint32_t frequency) { - furi_assert(app); - if(!subghz_devices_is_frequency_valid(app->txrx->radio_device, frequency)) { - furi_crash("POCSAGPager: Incorrect RX frequency."); - } - furi_assert( - app->txrx->txrx_state != PCSGTxRxStateRx && app->txrx->txrx_state != PCSGTxRxStateSleep); - - subghz_devices_idle(app->txrx->radio_device); - uint32_t value = subghz_devices_set_frequency(app->txrx->radio_device, frequency); - - // Not need. init in subghz_devices_start_async_tx - // furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow); - - subghz_devices_flush_rx(app->txrx->radio_device); - subghz_devices_set_rx(app->txrx->radio_device); - - subghz_devices_start_async_rx( - app->txrx->radio_device, subghz_worker_rx_callback, app->txrx->worker); - subghz_worker_start(app->txrx->worker); - app->txrx->txrx_state = PCSGTxRxStateRx; - return value; -} - -void pcsg_idle(POCSAGPagerApp* app) { - furi_assert(app); - furi_assert(app->txrx->txrx_state != PCSGTxRxStateSleep); - subghz_devices_idle(app->txrx->radio_device); - app->txrx->txrx_state = PCSGTxRxStateIDLE; -} - -void pcsg_rx_end(POCSAGPagerApp* app) { - furi_assert(app); - furi_assert(app->txrx->txrx_state == PCSGTxRxStateRx); - if(subghz_worker_is_running(app->txrx->worker)) { - subghz_worker_stop(app->txrx->worker); - subghz_devices_stop_async_rx(app->txrx->radio_device); - } - subghz_devices_idle(app->txrx->radio_device); - app->txrx->txrx_state = PCSGTxRxStateIDLE; -} - -void pcsg_sleep(POCSAGPagerApp* app) { - furi_assert(app); - subghz_devices_sleep(app->txrx->radio_device); - app->txrx->txrx_state = PCSGTxRxStateSleep; -} - -void pcsg_hopper_update(POCSAGPagerApp* app) { - furi_assert(app); - - switch(app->txrx->hopper_state) { - case PCSGHopperStateOFF: - return; - break; - case PCSGHopperStatePause: - return; - break; - case PCSGHopperStateRSSITimeOut: - if(app->txrx->hopper_timeout != 0) { - app->txrx->hopper_timeout--; - return; - } - break; - default: - break; - } - float rssi = -127.0f; - if(app->txrx->hopper_state != PCSGHopperStateRSSITimeOut) { - // See RSSI Calculation timings in CC1101 17.3 RSSI - rssi = subghz_devices_get_rssi(app->txrx->radio_device); - - // Stay if RSSI is high enough - if(rssi > -90.0f) { - app->txrx->hopper_timeout = 10; - app->txrx->hopper_state = PCSGHopperStateRSSITimeOut; - return; - } - } else { - app->txrx->hopper_state = PCSGHopperStateRunnig; - } - // Select next frequency - if(app->txrx->hopper_idx_frequency < - subghz_setting_get_hopper_frequency_count(app->setting) - 1) { - app->txrx->hopper_idx_frequency++; - } else { - app->txrx->hopper_idx_frequency = 0; - } - - if(app->txrx->txrx_state == PCSGTxRxStateRx) { - pcsg_rx_end(app); - }; - if(app->txrx->txrx_state == PCSGTxRxStateIDLE) { - subghz_receiver_reset(app->txrx->receiver); - app->txrx->preset->frequency = - subghz_setting_get_hopper_frequency(app->setting, app->txrx->hopper_idx_frequency); - pcsg_rx(app, app->txrx->preset->frequency); - } -} diff --git a/applications/external/pocsag_pager/pocsag_pager_app_i.h b/applications/external/pocsag_pager/pocsag_pager_app_i.h deleted file mode 100644 index c31e5ae1a..000000000 --- a/applications/external/pocsag_pager/pocsag_pager_app_i.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include "helpers/pocsag_pager_types.h" -#include "helpers/radio_device_loader.h" - -#include "scenes/pocsag_pager_scene.h" -#include -#include -#include -#include -#include -#include -#include -#include "views/pocsag_pager_receiver.h" -#include "views/pocsag_pager_receiver_info.h" -#include "pocsag_pager_history.h" - -#include -#include -#include -#include -#include -#include - -typedef struct POCSAGPagerApp POCSAGPagerApp; - -struct POCSAGPagerTxRx { - SubGhzWorker* worker; - - SubGhzEnvironment* environment; - SubGhzReceiver* receiver; - SubGhzRadioPreset* preset; - PCSGHistory* history; - uint16_t idx_menu_chosen; - PCSGTxRxState txrx_state; - PCSGHopperState hopper_state; - uint8_t hopper_timeout; - uint8_t hopper_idx_frequency; - PCSGRxKeyState rx_key_state; - - const SubGhzDevice* radio_device; -}; - -typedef struct POCSAGPagerTxRx POCSAGPagerTxRx; - -struct POCSAGPagerApp { - Gui* gui; - ViewDispatcher* view_dispatcher; - POCSAGPagerTxRx* txrx; - SceneManager* scene_manager; - NotificationApp* notifications; - VariableItemList* variable_item_list; - Submenu* submenu; - Widget* widget; - PCSGReceiver* pcsg_receiver; - PCSGReceiverInfo* pcsg_receiver_info; - PCSGLock lock; - SubGhzSetting* setting; -}; - -void pcsg_preset_init( - void* context, - const char* preset_name, - uint32_t frequency, - uint8_t* preset_data, - size_t preset_data_size); -void pcsg_get_frequency_modulation( - POCSAGPagerApp* app, - FuriString* frequency, - FuriString* modulation); -void pcsg_begin(POCSAGPagerApp* app, uint8_t* preset_data); -uint32_t pcsg_rx(POCSAGPagerApp* app, uint32_t frequency); -void pcsg_idle(POCSAGPagerApp* app); -void pcsg_rx_end(POCSAGPagerApp* app); -void pcsg_sleep(POCSAGPagerApp* app); -void pcsg_hopper_update(POCSAGPagerApp* app); diff --git a/applications/external/pocsag_pager/pocsag_pager_history.c b/applications/external/pocsag_pager/pocsag_pager_history.c deleted file mode 100644 index d5f97b571..000000000 --- a/applications/external/pocsag_pager/pocsag_pager_history.c +++ /dev/null @@ -1,223 +0,0 @@ -#include "pocsag_pager_history.h" -#include -#include -#include -#include "protocols/pcsg_generic.h" - -#include - -#define PCSG_HISTORY_MAX 50 -#define TAG "PCSGHistory" - -typedef struct { - FuriString* item_str; - FlipperFormat* flipper_string; - uint8_t type; - SubGhzRadioPreset* preset; -} PCSGHistoryItem; - -ARRAY_DEF(PCSGHistoryItemArray, PCSGHistoryItem, M_POD_OPLIST) - -#define M_OPL_PCSGHistoryItemArray_t() ARRAY_OPLIST(PCSGHistoryItemArray, M_POD_OPLIST) - -typedef struct { - PCSGHistoryItemArray_t data; -} PCSGHistoryStruct; - -struct PCSGHistory { - uint32_t last_update_timestamp; - uint16_t last_index_write; - uint8_t code_last_hash_data; - FuriString* tmp_string; - PCSGHistoryStruct* history; -}; - -PCSGHistory* pcsg_history_alloc(void) { - PCSGHistory* instance = malloc(sizeof(PCSGHistory)); - instance->tmp_string = furi_string_alloc(); - instance->history = malloc(sizeof(PCSGHistoryStruct)); - PCSGHistoryItemArray_init(instance->history->data); - return instance; -} - -void pcsg_history_free(PCSGHistory* instance) { - furi_assert(instance); - furi_string_free(instance->tmp_string); - for - M_EACH(item, instance->history->data, PCSGHistoryItemArray_t) { - furi_string_free(item->item_str); - furi_string_free(item->preset->name); - free(item->preset); - flipper_format_free(item->flipper_string); - item->type = 0; - } - PCSGHistoryItemArray_clear(instance->history->data); - free(instance->history); - free(instance); -} - -uint32_t pcsg_history_get_frequency(PCSGHistory* instance, uint16_t idx) { - furi_assert(instance); - PCSGHistoryItem* item = PCSGHistoryItemArray_get(instance->history->data, idx); - return item->preset->frequency; -} - -SubGhzRadioPreset* pcsg_history_get_radio_preset(PCSGHistory* instance, uint16_t idx) { - furi_assert(instance); - PCSGHistoryItem* item = PCSGHistoryItemArray_get(instance->history->data, idx); - return item->preset; -} - -const char* pcsg_history_get_preset(PCSGHistory* instance, uint16_t idx) { - furi_assert(instance); - PCSGHistoryItem* item = PCSGHistoryItemArray_get(instance->history->data, idx); - return furi_string_get_cstr(item->preset->name); -} - -void pcsg_history_reset(PCSGHistory* instance) { - furi_assert(instance); - furi_string_reset(instance->tmp_string); - for - M_EACH(item, instance->history->data, PCSGHistoryItemArray_t) { - furi_string_free(item->item_str); - furi_string_free(item->preset->name); - free(item->preset); - flipper_format_free(item->flipper_string); - item->type = 0; - } - PCSGHistoryItemArray_reset(instance->history->data); - instance->last_index_write = 0; - instance->code_last_hash_data = 0; -} - -uint16_t pcsg_history_get_item(PCSGHistory* instance) { - furi_assert(instance); - return instance->last_index_write; -} - -uint8_t pcsg_history_get_type_protocol(PCSGHistory* instance, uint16_t idx) { - furi_assert(instance); - PCSGHistoryItem* item = PCSGHistoryItemArray_get(instance->history->data, idx); - return item->type; -} - -const char* pcsg_history_get_protocol_name(PCSGHistory* instance, uint16_t idx) { - furi_assert(instance); - PCSGHistoryItem* item = PCSGHistoryItemArray_get(instance->history->data, idx); - flipper_format_rewind(item->flipper_string); - if(!flipper_format_read_string(item->flipper_string, "Protocol", instance->tmp_string)) { - FURI_LOG_E(TAG, "Missing Protocol"); - furi_string_reset(instance->tmp_string); - } - return furi_string_get_cstr(instance->tmp_string); -} - -FlipperFormat* pcsg_history_get_raw_data(PCSGHistory* instance, uint16_t idx) { - furi_assert(instance); - PCSGHistoryItem* item = PCSGHistoryItemArray_get(instance->history->data, idx); - if(item->flipper_string) { - return item->flipper_string; - } else { - return NULL; - } -} -bool pcsg_history_get_text_space_left(PCSGHistory* instance, FuriString* output) { - furi_assert(instance); - if(instance->last_index_write == PCSG_HISTORY_MAX) { - if(output != NULL) furi_string_printf(output, "Memory is FULL"); - return true; - } - if(output != NULL) - furi_string_printf(output, "%02u/%02u", instance->last_index_write, PCSG_HISTORY_MAX); - return false; -} - -void pcsg_history_get_text_item_menu(PCSGHistory* instance, FuriString* output, uint16_t idx) { - PCSGHistoryItem* item = PCSGHistoryItemArray_get(instance->history->data, idx); - furi_string_set(output, item->item_str); -} - -PCSGHistoryStateAddKey - pcsg_history_add_to_history(PCSGHistory* instance, void* context, SubGhzRadioPreset* preset) { - furi_assert(instance); - furi_assert(context); - - if(instance->last_index_write >= PCSG_HISTORY_MAX) return PCSGHistoryStateAddKeyOverflow; - - SubGhzProtocolDecoderBase* decoder_base = context; - if((instance->code_last_hash_data == - subghz_protocol_decoder_base_get_hash_data(decoder_base)) && - ((furi_get_tick() - instance->last_update_timestamp) < 500)) { - instance->last_update_timestamp = furi_get_tick(); - return PCSGHistoryStateAddKeyTimeOut; - } - - instance->code_last_hash_data = subghz_protocol_decoder_base_get_hash_data(decoder_base); - instance->last_update_timestamp = furi_get_tick(); - - FlipperFormat* fff = flipper_format_string_alloc(); - subghz_protocol_decoder_base_serialize(decoder_base, fff, preset); - - do { - if(!flipper_format_rewind(fff)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - - } while(false); - flipper_format_free(fff); - - PCSGHistoryItem* item = PCSGHistoryItemArray_push_raw(instance->history->data); - item->preset = malloc(sizeof(SubGhzRadioPreset)); - item->type = decoder_base->protocol->type; - item->preset->frequency = preset->frequency; - item->preset->name = furi_string_alloc(); - furi_string_set(item->preset->name, preset->name); - item->preset->data = preset->data; - item->preset->data_size = preset->data_size; - - item->item_str = furi_string_alloc(); - item->flipper_string = flipper_format_string_alloc(); - subghz_protocol_decoder_base_serialize(decoder_base, item->flipper_string, preset); - - do { - if(!flipper_format_rewind(item->flipper_string)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_string(item->flipper_string, "Protocol", instance->tmp_string)) { - FURI_LOG_E(TAG, "Missing Protocol"); - break; - } - - if(!flipper_format_rewind(item->flipper_string)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - FuriString* temp_ric = furi_string_alloc(); - if(!flipper_format_read_string(item->flipper_string, "Ric", temp_ric)) { - FURI_LOG_E(TAG, "Missing Ric"); - break; - } - - FuriString* temp_message = furi_string_alloc(); - if(!flipper_format_read_string(item->flipper_string, "Message", temp_message)) { - FURI_LOG_E(TAG, "Missing Message"); - break; - } - - furi_string_printf( - item->item_str, - "%s%s", - furi_string_get_cstr(temp_ric), - furi_string_get_cstr(temp_message)); - - furi_string_free(temp_message); - furi_string_free(temp_ric); - - } while(false); - instance->last_index_write++; - return PCSGHistoryStateAddKeyNewDada; - - return PCSGHistoryStateAddKeyUnknown; -} diff --git a/applications/external/pocsag_pager/pocsag_pager_history.h b/applications/external/pocsag_pager/pocsag_pager_history.h deleted file mode 100644 index 7528fcc29..000000000 --- a/applications/external/pocsag_pager/pocsag_pager_history.h +++ /dev/null @@ -1,112 +0,0 @@ - -#pragma once - -#include -#include -#include -#include -#include - -typedef struct PCSGHistory PCSGHistory; - -/** History state add key */ -typedef enum { - PCSGHistoryStateAddKeyUnknown, - PCSGHistoryStateAddKeyTimeOut, - PCSGHistoryStateAddKeyNewDada, - PCSGHistoryStateAddKeyUpdateData, - PCSGHistoryStateAddKeyOverflow, -} PCSGHistoryStateAddKey; - -/** Allocate PCSGHistory - * - * @return PCSGHistory* - */ -PCSGHistory* pcsg_history_alloc(void); - -/** Free PCSGHistory - * - * @param instance - PCSGHistory instance - */ -void pcsg_history_free(PCSGHistory* instance); - -/** Clear history - * - * @param instance - PCSGHistory instance - */ -void pcsg_history_reset(PCSGHistory* instance); - -/** Get frequency to history[idx] - * - * @param instance - PCSGHistory instance - * @param idx - record index - * @return frequency - frequency Hz - */ -uint32_t pcsg_history_get_frequency(PCSGHistory* instance, uint16_t idx); - -SubGhzRadioPreset* pcsg_history_get_radio_preset(PCSGHistory* instance, uint16_t idx); - -/** Get preset to history[idx] - * - * @param instance - PCSGHistory instance - * @param idx - record index - * @return preset - preset name - */ -const char* pcsg_history_get_preset(PCSGHistory* instance, uint16_t idx); - -/** Get history index write - * - * @param instance - PCSGHistory instance - * @return idx - current record index - */ -uint16_t pcsg_history_get_item(PCSGHistory* instance); - -/** Get type protocol to history[idx] - * - * @param instance - PCSGHistory instance - * @param idx - record index - * @return type - type protocol - */ -uint8_t pcsg_history_get_type_protocol(PCSGHistory* instance, uint16_t idx); - -/** Get name protocol to history[idx] - * - * @param instance - PCSGHistory instance - * @param idx - record index - * @return name - const char* name protocol - */ -const char* pcsg_history_get_protocol_name(PCSGHistory* instance, uint16_t idx); - -/** Get string item menu to history[idx] - * - * @param instance - PCSGHistory instance - * @param output - FuriString* output - * @param idx - record index - */ -void pcsg_history_get_text_item_menu(PCSGHistory* instance, FuriString* output, uint16_t idx); - -/** Get string the remaining number of records to history - * - * @param instance - PCSGHistory instance - * @param output - FuriString* output - * @return bool - is FUUL - */ -bool pcsg_history_get_text_space_left(PCSGHistory* instance, FuriString* output); - -/** Add protocol to history - * - * @param instance - PCSGHistory instance - * @param context - SubGhzProtocolCommon context - * @param preset - SubGhzRadioPreset preset - * @return PCSGHistoryStateAddKey; - */ -PCSGHistoryStateAddKey - pcsg_history_add_to_history(PCSGHistory* instance, void* context, SubGhzRadioPreset* preset); - -/** Get SubGhzProtocolCommonLoad to load into the protocol decoder bin data - * - * @param instance - PCSGHistory instance - * @param idx - record index - * @return SubGhzProtocolCommonLoad* - */ -FlipperFormat* pcsg_history_get_raw_data(PCSGHistory* instance, uint16_t idx); diff --git a/applications/external/pocsag_pager/protocols/protocol_items.c b/applications/external/pocsag_pager/protocols/protocol_items.c deleted file mode 100644 index 7e6ebebbd..000000000 --- a/applications/external/pocsag_pager/protocols/protocol_items.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "protocol_items.h" - -const SubGhzProtocol* pocsag_pager_protocol_registry_items[] = { - &subghz_protocol_pocsag, -}; - -const SubGhzProtocolRegistry pocsag_pager_protocol_registry = { - .items = pocsag_pager_protocol_registry_items, - .size = COUNT_OF(pocsag_pager_protocol_registry_items)}; \ No newline at end of file diff --git a/applications/external/pocsag_pager/protocols/protocol_items.h b/applications/external/pocsag_pager/protocols/protocol_items.h deleted file mode 100644 index 3981cd2e3..000000000 --- a/applications/external/pocsag_pager/protocols/protocol_items.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include "../pocsag_pager_app_i.h" - -#include "pocsag.h" - -extern const SubGhzProtocolRegistry pocsag_pager_protocol_registry; diff --git a/applications/external/pocsag_pager/scenes/pocsag_pager_receiver.c b/applications/external/pocsag_pager/scenes/pocsag_pager_receiver.c deleted file mode 100644 index cc2abd7e0..000000000 --- a/applications/external/pocsag_pager/scenes/pocsag_pager_receiver.c +++ /dev/null @@ -1,214 +0,0 @@ -#include "../pocsag_pager_app_i.h" -#include "../views/pocsag_pager_receiver.h" - -static const NotificationSequence subghs_sequence_rx = { - &message_green_255, - - &message_vibro_on, - &message_note_c6, - &message_delay_50, - &message_sound_off, - &message_vibro_off, - - &message_delay_50, - NULL, -}; - -static const NotificationSequence subghs_sequence_rx_locked = { - &message_green_255, - - &message_display_backlight_on, - - &message_vibro_on, - &message_note_c6, - &message_delay_50, - &message_sound_off, - &message_vibro_off, - - &message_delay_500, - - &message_display_backlight_off, - NULL, -}; - -static void pocsag_pager_scene_receiver_update_statusbar(void* context) { - POCSAGPagerApp* app = context; - FuriString* history_stat_str; - history_stat_str = furi_string_alloc(); - if(!pcsg_history_get_text_space_left(app->txrx->history, history_stat_str)) { - FuriString* frequency_str; - FuriString* modulation_str; - - frequency_str = furi_string_alloc(); - modulation_str = furi_string_alloc(); - - pcsg_get_frequency_modulation(app, frequency_str, modulation_str); - - pcsg_view_receiver_add_data_statusbar( - app->pcsg_receiver, - furi_string_get_cstr(frequency_str), - furi_string_get_cstr(modulation_str), - furi_string_get_cstr(history_stat_str)); - - furi_string_free(frequency_str); - furi_string_free(modulation_str); - } else { - pcsg_view_receiver_add_data_statusbar( - app->pcsg_receiver, furi_string_get_cstr(history_stat_str), "", ""); - } - furi_string_free(history_stat_str); -} - -void pocsag_pager_scene_receiver_callback(PCSGCustomEvent event, void* context) { - furi_assert(context); - POCSAGPagerApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -static void pocsag_pager_scene_receiver_add_to_history_callback( - SubGhzReceiver* receiver, - SubGhzProtocolDecoderBase* decoder_base, - void* context) { - furi_assert(context); - POCSAGPagerApp* app = context; - FuriString* str_buff; - str_buff = furi_string_alloc(); - - if(pcsg_history_add_to_history(app->txrx->history, decoder_base, app->txrx->preset) == - PCSGHistoryStateAddKeyNewDada) { - furi_string_reset(str_buff); - - pcsg_history_get_text_item_menu( - app->txrx->history, str_buff, pcsg_history_get_item(app->txrx->history) - 1); - pcsg_view_receiver_add_item_to_menu( - app->pcsg_receiver, - furi_string_get_cstr(str_buff), - pcsg_history_get_type_protocol( - app->txrx->history, pcsg_history_get_item(app->txrx->history) - 1)); - - pocsag_pager_scene_receiver_update_statusbar(app); - notification_message(app->notifications, &sequence_blink_green_10); - if(app->lock != PCSGLockOn) { - notification_message(app->notifications, &subghs_sequence_rx); - } else { - notification_message(app->notifications, &subghs_sequence_rx_locked); - } - } - subghz_receiver_reset(receiver); - furi_string_free(str_buff); - app->txrx->rx_key_state = PCSGRxKeyStateAddKey; -} - -void pocsag_pager_scene_receiver_on_enter(void* context) { - POCSAGPagerApp* app = context; - - FuriString* str_buff; - str_buff = furi_string_alloc(); - - if(app->txrx->rx_key_state == PCSGRxKeyStateIDLE) { - pcsg_preset_init(app, "FM95", 439987500, NULL, 0); - pcsg_history_reset(app->txrx->history); - app->txrx->rx_key_state = PCSGRxKeyStateStart; - } - - pcsg_view_receiver_set_lock(app->pcsg_receiver, app->lock); - pcsg_view_receiver_set_ext_module_state( - app->pcsg_receiver, radio_device_loader_is_external(app->txrx->radio_device)); - - //Load history to receiver - pcsg_view_receiver_exit(app->pcsg_receiver); - for(uint8_t i = 0; i < pcsg_history_get_item(app->txrx->history); i++) { - furi_string_reset(str_buff); - pcsg_history_get_text_item_menu(app->txrx->history, str_buff, i); - pcsg_view_receiver_add_item_to_menu( - app->pcsg_receiver, - furi_string_get_cstr(str_buff), - pcsg_history_get_type_protocol(app->txrx->history, i)); - app->txrx->rx_key_state = PCSGRxKeyStateAddKey; - } - furi_string_free(str_buff); - pocsag_pager_scene_receiver_update_statusbar(app); - - pcsg_view_receiver_set_callback(app->pcsg_receiver, pocsag_pager_scene_receiver_callback, app); - subghz_receiver_set_rx_callback( - app->txrx->receiver, pocsag_pager_scene_receiver_add_to_history_callback, app); - - if(app->txrx->txrx_state == PCSGTxRxStateRx) { - pcsg_rx_end(app); - }; - if((app->txrx->txrx_state == PCSGTxRxStateIDLE) || - (app->txrx->txrx_state == PCSGTxRxStateSleep)) { - // Start RX - pcsg_begin( - app, - subghz_setting_get_preset_data_by_name( - app->setting, furi_string_get_cstr(app->txrx->preset->name))); - - pcsg_rx(app, app->txrx->preset->frequency); - } - - pcsg_view_receiver_set_idx_menu(app->pcsg_receiver, app->txrx->idx_menu_chosen); - view_dispatcher_switch_to_view(app->view_dispatcher, POCSAGPagerViewReceiver); -} - -bool pocsag_pager_scene_receiver_on_event(void* context, SceneManagerEvent event) { - POCSAGPagerApp* app = context; - bool consumed = false; - if(event.type == SceneManagerEventTypeCustom) { - switch(event.event) { - case PCSGCustomEventViewReceiverBack: - // Stop CC1101 Rx - if(app->txrx->txrx_state == PCSGTxRxStateRx) { - pcsg_rx_end(app); - pcsg_idle(app); - }; - app->txrx->hopper_state = PCSGHopperStateOFF; - app->txrx->idx_menu_chosen = 0; - subghz_receiver_set_rx_callback(app->txrx->receiver, NULL, app); - - app->txrx->rx_key_state = PCSGRxKeyStateIDLE; - pcsg_preset_init(app, "FM95", 439987500, NULL, 0); - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, POCSAGPagerSceneStart); - consumed = true; - break; - case PCSGCustomEventViewReceiverOK: - app->txrx->idx_menu_chosen = pcsg_view_receiver_get_idx_menu(app->pcsg_receiver); - scene_manager_next_scene(app->scene_manager, POCSAGPagerSceneReceiverInfo); - consumed = true; - break; - case PCSGCustomEventViewReceiverConfig: - app->txrx->idx_menu_chosen = pcsg_view_receiver_get_idx_menu(app->pcsg_receiver); - scene_manager_next_scene(app->scene_manager, POCSAGPagerSceneReceiverConfig); - consumed = true; - break; - case PCSGCustomEventViewReceiverOffDisplay: - notification_message(app->notifications, &sequence_display_backlight_off); - consumed = true; - break; - case PCSGCustomEventViewReceiverUnlock: - app->lock = PCSGLockOff; - consumed = true; - break; - default: - break; - } - } else if(event.type == SceneManagerEventTypeTick) { - if(app->txrx->hopper_state != PCSGHopperStateOFF) { - pcsg_hopper_update(app); - pocsag_pager_scene_receiver_update_statusbar(app); - } - // Get current RSSI - float rssi = subghz_devices_get_rssi(app->txrx->radio_device); - pcsg_receiver_rssi(app->pcsg_receiver, rssi); - - if(app->txrx->txrx_state == PCSGTxRxStateRx) { - notification_message(app->notifications, &sequence_blink_cyan_10); - } - } - return consumed; -} - -void pocsag_pager_scene_receiver_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/pocsag_pager/scenes/pocsag_pager_scene.c b/applications/external/pocsag_pager/scenes/pocsag_pager_scene.c deleted file mode 100644 index 4644d99c0..000000000 --- a/applications/external/pocsag_pager/scenes/pocsag_pager_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "../pocsag_pager_app_i.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const pocsag_pager_scene_on_enter_handlers[])(void*) = { -#include "pocsag_pager_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_event handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, -bool (*const pocsag_pager_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "pocsag_pager_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_exit handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, -void (*const pocsag_pager_scene_on_exit_handlers[])(void* context) = { -#include "pocsag_pager_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers pocsag_pager_scene_handlers = { - .on_enter_handlers = pocsag_pager_scene_on_enter_handlers, - .on_event_handlers = pocsag_pager_scene_on_event_handlers, - .on_exit_handlers = pocsag_pager_scene_on_exit_handlers, - .scene_num = POCSAGPagerSceneNum, -}; diff --git a/applications/external/pocsag_pager/scenes/pocsag_pager_scene.h b/applications/external/pocsag_pager/scenes/pocsag_pager_scene.h deleted file mode 100644 index d5c64f9d9..000000000 --- a/applications/external/pocsag_pager/scenes/pocsag_pager_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) POCSAGPagerScene##id, -typedef enum { -#include "pocsag_pager_scene_config.h" - POCSAGPagerSceneNum, -} POCSAGPagerScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers pocsag_pager_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "pocsag_pager_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_event handlers declaration -#define ADD_SCENE(prefix, name, id) \ - bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); -#include "pocsag_pager_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_exit handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); -#include "pocsag_pager_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/pocsag_pager/scenes/pocsag_pager_scene_about.c b/applications/external/pocsag_pager/scenes/pocsag_pager_scene_about.c deleted file mode 100644 index 2af33c8bf..000000000 --- a/applications/external/pocsag_pager/scenes/pocsag_pager_scene_about.c +++ /dev/null @@ -1,74 +0,0 @@ -#include "../pocsag_pager_app_i.h" -#include "../helpers/pocsag_pager_types.h" - -void pocsag_pager_scene_about_widget_callback(GuiButtonType result, InputType type, void* context) { - POCSAGPagerApp* app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(app->view_dispatcher, result); - } -} - -void pocsag_pager_scene_about_on_enter(void* context) { - POCSAGPagerApp* app = context; - - FuriString* temp_str; - temp_str = furi_string_alloc(); - furi_string_printf(temp_str, "\e#%s\n", "Information"); - - furi_string_cat_printf(temp_str, "Version: %s\n", PCSG_VERSION_APP); - furi_string_cat_printf(temp_str, "Developed by:\n%s\n\n", PCSG_DEVELOPED); - furi_string_cat_printf(temp_str, "Github: %s\n\n", PCSG_GITHUB); - - furi_string_cat_printf(temp_str, "\e#%s\n", "Description"); - furi_string_cat_printf(temp_str, "Receiving POCSAG Pager \nmessages\n\n"); - - furi_string_cat_printf(temp_str, "Supported protocols:\n"); - size_t i = 0; - const char* protocol_name = - subghz_environment_get_protocol_name_registry(app->txrx->environment, i++); - do { - furi_string_cat_printf(temp_str, "%s\n", protocol_name); - protocol_name = subghz_environment_get_protocol_name_registry(app->txrx->environment, i++); - } while(protocol_name != NULL); - - widget_add_text_box_element( - app->widget, - 0, - 0, - 128, - 14, - AlignCenter, - AlignBottom, - "\e#\e! \e!\n", - false); - widget_add_text_box_element( - app->widget, - 0, - 2, - 128, - 14, - AlignCenter, - AlignBottom, - "\e#\e! POCSAG Pager \e!\n", - false); - widget_add_text_scroll_element(app->widget, 0, 16, 128, 50, furi_string_get_cstr(temp_str)); - furi_string_free(temp_str); - - view_dispatcher_switch_to_view(app->view_dispatcher, POCSAGPagerViewWidget); -} - -bool pocsag_pager_scene_about_on_event(void* context, SceneManagerEvent event) { - POCSAGPagerApp* app = context; - bool consumed = false; - UNUSED(app); - UNUSED(event); - - return consumed; -} - -void pocsag_pager_scene_about_on_exit(void* context) { - POCSAGPagerApp* app = context; - - // Clear views - widget_reset(app->widget); -} diff --git a/applications/external/pocsag_pager/scenes/pocsag_pager_scene_config.h b/applications/external/pocsag_pager/scenes/pocsag_pager_scene_config.h deleted file mode 100644 index 8136af14f..000000000 --- a/applications/external/pocsag_pager/scenes/pocsag_pager_scene_config.h +++ /dev/null @@ -1,5 +0,0 @@ -ADD_SCENE(pocsag_pager, start, Start) -ADD_SCENE(pocsag_pager, about, About) -ADD_SCENE(pocsag_pager, receiver, Receiver) -ADD_SCENE(pocsag_pager, receiver_config, ReceiverConfig) -ADD_SCENE(pocsag_pager, receiver_info, ReceiverInfo) diff --git a/applications/external/pocsag_pager/scenes/pocsag_pager_scene_receiver_config.c b/applications/external/pocsag_pager/scenes/pocsag_pager_scene_receiver_config.c deleted file mode 100644 index 154e7d270..000000000 --- a/applications/external/pocsag_pager/scenes/pocsag_pager_scene_receiver_config.c +++ /dev/null @@ -1,221 +0,0 @@ -#include "../pocsag_pager_app_i.h" - -enum PCSGSettingIndex { - PCSGSettingIndexFrequency, - PCSGSettingIndexHopping, - PCSGSettingIndexModulation, - PCSGSettingIndexLock, -}; - -#define HOPPING_COUNT 2 -const char* const hopping_text[HOPPING_COUNT] = { - "OFF", - "ON", -}; -const uint32_t hopping_value[HOPPING_COUNT] = { - PCSGHopperStateOFF, - PCSGHopperStateRunnig, -}; - -uint8_t pocsag_pager_scene_receiver_config_next_frequency(const uint32_t value, void* context) { - furi_assert(context); - POCSAGPagerApp* app = context; - uint8_t index = 0; - for(uint8_t i = 0; i < subghz_setting_get_frequency_count(app->setting); i++) { - if(value == subghz_setting_get_frequency(app->setting, i)) { - index = i; - break; - } else { - index = subghz_setting_get_frequency_default_index(app->setting); - } - } - return index; -} - -uint8_t pocsag_pager_scene_receiver_config_next_preset(const char* preset_name, void* context) { - furi_assert(context); - POCSAGPagerApp* app = context; - uint8_t index = 0; - for(uint8_t i = 0; i < subghz_setting_get_preset_count(app->setting); i++) { - if(!strcmp(subghz_setting_get_preset_name(app->setting, i), preset_name)) { - index = i; - break; - } else { - // index = subghz_setting_get_frequency_default_index(app ->setting); - } - } - return index; -} - -uint8_t pocsag_pager_scene_receiver_config_hopper_value_index( - const uint32_t value, - const uint32_t values[], - uint8_t values_count, - void* context) { - furi_assert(context); - UNUSED(values_count); - POCSAGPagerApp* app = context; - - if(value == values[0]) { - return 0; - } else { - variable_item_set_current_value_text( - (VariableItem*)scene_manager_get_scene_state( - app->scene_manager, POCSAGPagerSceneReceiverConfig), - " -----"); - return 1; - } -} - -static void pocsag_pager_scene_receiver_config_set_frequency(VariableItem* item) { - POCSAGPagerApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - - if(app->txrx->hopper_state == PCSGHopperStateOFF) { - char text_buf[10] = {0}; - snprintf( - text_buf, - sizeof(text_buf), - "%lu.%02lu", - subghz_setting_get_frequency(app->setting, index) / 1000000, - (subghz_setting_get_frequency(app->setting, index) % 1000000) / 10000); - variable_item_set_current_value_text(item, text_buf); - app->txrx->preset->frequency = subghz_setting_get_frequency(app->setting, index); - } else { - variable_item_set_current_value_index( - item, subghz_setting_get_frequency_default_index(app->setting)); - } -} - -static void pocsag_pager_scene_receiver_config_set_preset(VariableItem* item) { - POCSAGPagerApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text( - item, subghz_setting_get_preset_name(app->setting, index)); - pcsg_preset_init( - app, - subghz_setting_get_preset_name(app->setting, index), - app->txrx->preset->frequency, - subghz_setting_get_preset_data(app->setting, index), - subghz_setting_get_preset_data_size(app->setting, index)); -} - -static void pocsag_pager_scene_receiver_config_set_hopping_running(VariableItem* item) { - POCSAGPagerApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - - variable_item_set_current_value_text(item, hopping_text[index]); - if(hopping_value[index] == PCSGHopperStateOFF) { - char text_buf[10] = {0}; - snprintf( - text_buf, - sizeof(text_buf), - "%lu.%02lu", - subghz_setting_get_default_frequency(app->setting) / 1000000, - (subghz_setting_get_default_frequency(app->setting) % 1000000) / 10000); - variable_item_set_current_value_text( - (VariableItem*)scene_manager_get_scene_state( - app->scene_manager, POCSAGPagerSceneReceiverConfig), - text_buf); - app->txrx->preset->frequency = subghz_setting_get_default_frequency(app->setting); - variable_item_set_current_value_index( - (VariableItem*)scene_manager_get_scene_state( - app->scene_manager, POCSAGPagerSceneReceiverConfig), - subghz_setting_get_frequency_default_index(app->setting)); - } else { - variable_item_set_current_value_text( - (VariableItem*)scene_manager_get_scene_state( - app->scene_manager, POCSAGPagerSceneReceiverConfig), - " -----"); - variable_item_set_current_value_index( - (VariableItem*)scene_manager_get_scene_state( - app->scene_manager, POCSAGPagerSceneReceiverConfig), - subghz_setting_get_frequency_default_index(app->setting)); - } - - app->txrx->hopper_state = hopping_value[index]; -} - -static void - pocsag_pager_scene_receiver_config_var_list_enter_callback(void* context, uint32_t index) { - furi_assert(context); - POCSAGPagerApp* app = context; - if(index == PCSGSettingIndexLock) { - view_dispatcher_send_custom_event(app->view_dispatcher, PCSGCustomEventSceneSettingLock); - } -} - -void pocsag_pager_scene_receiver_config_on_enter(void* context) { - POCSAGPagerApp* app = context; - VariableItem* item; - uint8_t value_index; - - item = variable_item_list_add( - app->variable_item_list, - "Frequency:", - subghz_setting_get_frequency_count(app->setting), - pocsag_pager_scene_receiver_config_set_frequency, - app); - value_index = - pocsag_pager_scene_receiver_config_next_frequency(app->txrx->preset->frequency, app); - scene_manager_set_scene_state( - app->scene_manager, POCSAGPagerSceneReceiverConfig, (uint32_t)item); - variable_item_set_current_value_index(item, value_index); - char text_buf[10] = {0}; - snprintf( - text_buf, - sizeof(text_buf), - "%lu.%02lu", - subghz_setting_get_frequency(app->setting, value_index) / 1000000, - (subghz_setting_get_frequency(app->setting, value_index) % 1000000) / 10000); - variable_item_set_current_value_text(item, text_buf); - - item = variable_item_list_add( - app->variable_item_list, - "Hopping:", - HOPPING_COUNT, - pocsag_pager_scene_receiver_config_set_hopping_running, - app); - value_index = pocsag_pager_scene_receiver_config_hopper_value_index( - app->txrx->hopper_state, hopping_value, HOPPING_COUNT, app); - variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, hopping_text[value_index]); - - item = variable_item_list_add( - app->variable_item_list, - "Modulation:", - subghz_setting_get_preset_count(app->setting), - pocsag_pager_scene_receiver_config_set_preset, - app); - value_index = pocsag_pager_scene_receiver_config_next_preset( - furi_string_get_cstr(app->txrx->preset->name), app); - variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text( - item, subghz_setting_get_preset_name(app->setting, value_index)); - - variable_item_list_add(app->variable_item_list, "Lock Keyboard", 1, NULL, NULL); - variable_item_list_set_enter_callback( - app->variable_item_list, pocsag_pager_scene_receiver_config_var_list_enter_callback, app); - - view_dispatcher_switch_to_view(app->view_dispatcher, POCSAGPagerViewVariableItemList); -} - -bool pocsag_pager_scene_receiver_config_on_event(void* context, SceneManagerEvent event) { - POCSAGPagerApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == PCSGCustomEventSceneSettingLock) { - app->lock = PCSGLockOn; - scene_manager_previous_scene(app->scene_manager); - consumed = true; - } - } - return consumed; -} - -void pocsag_pager_scene_receiver_config_on_exit(void* context) { - POCSAGPagerApp* app = context; - variable_item_list_set_selected_item(app->variable_item_list, 0); - variable_item_list_reset(app->variable_item_list); -} diff --git a/applications/external/pocsag_pager/scenes/pocsag_pager_scene_receiver_info.c b/applications/external/pocsag_pager/scenes/pocsag_pager_scene_receiver_info.c deleted file mode 100644 index 5f17d9fb7..000000000 --- a/applications/external/pocsag_pager/scenes/pocsag_pager_scene_receiver_info.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "../pocsag_pager_app_i.h" -#include "../views/pocsag_pager_receiver.h" - -void pocsag_pager_scene_receiver_info_callback(PCSGCustomEvent event, void* context) { - furi_assert(context); - POCSAGPagerApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -static void pocsag_pager_scene_receiver_info_add_to_history_callback( - SubGhzReceiver* receiver, - SubGhzProtocolDecoderBase* decoder_base, - void* context) { - furi_assert(context); - POCSAGPagerApp* app = context; - - if(pcsg_history_add_to_history(app->txrx->history, decoder_base, app->txrx->preset) == - PCSGHistoryStateAddKeyUpdateData) { - pcsg_view_receiver_info_update( - app->pcsg_receiver_info, - pcsg_history_get_raw_data(app->txrx->history, app->txrx->idx_menu_chosen)); - subghz_receiver_reset(receiver); - - notification_message(app->notifications, &sequence_blink_green_10); - app->txrx->rx_key_state = PCSGRxKeyStateAddKey; - } -} - -void pocsag_pager_scene_receiver_info_on_enter(void* context) { - POCSAGPagerApp* app = context; - - subghz_receiver_set_rx_callback( - app->txrx->receiver, pocsag_pager_scene_receiver_info_add_to_history_callback, app); - pcsg_view_receiver_info_update( - app->pcsg_receiver_info, - pcsg_history_get_raw_data(app->txrx->history, app->txrx->idx_menu_chosen)); - view_dispatcher_switch_to_view(app->view_dispatcher, POCSAGPagerViewReceiverInfo); -} - -bool pocsag_pager_scene_receiver_info_on_event(void* context, SceneManagerEvent event) { - POCSAGPagerApp* app = context; - bool consumed = false; - UNUSED(app); - UNUSED(event); - return consumed; -} - -void pocsag_pager_scene_receiver_info_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/pocsag_pager/scenes/pocsag_pager_scene_start.c b/applications/external/pocsag_pager/scenes/pocsag_pager_scene_start.c deleted file mode 100644 index d2a94facb..000000000 --- a/applications/external/pocsag_pager/scenes/pocsag_pager_scene_start.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "../pocsag_pager_app_i.h" - -typedef enum { - SubmenuIndexPOCSAGPagerReceiver, - SubmenuIndexPOCSAGPagerAbout, -} SubmenuIndex; - -void pocsag_pager_scene_start_submenu_callback(void* context, uint32_t index) { - POCSAGPagerApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void pocsag_pager_scene_start_on_enter(void* context) { - UNUSED(context); - POCSAGPagerApp* app = context; - Submenu* submenu = app->submenu; - - submenu_add_item( - submenu, - "Receive messages", - SubmenuIndexPOCSAGPagerReceiver, - pocsag_pager_scene_start_submenu_callback, - app); - submenu_add_item( - submenu, - "About", - SubmenuIndexPOCSAGPagerAbout, - pocsag_pager_scene_start_submenu_callback, - app); - - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(app->scene_manager, POCSAGPagerSceneStart)); - - view_dispatcher_switch_to_view(app->view_dispatcher, POCSAGPagerViewSubmenu); -} - -bool pocsag_pager_scene_start_on_event(void* context, SceneManagerEvent event) { - POCSAGPagerApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexPOCSAGPagerAbout) { - scene_manager_next_scene(app->scene_manager, POCSAGPagerSceneAbout); - consumed = true; - } else if(event.event == SubmenuIndexPOCSAGPagerReceiver) { - scene_manager_next_scene(app->scene_manager, POCSAGPagerSceneReceiver); - consumed = true; - } - scene_manager_set_scene_state(app->scene_manager, POCSAGPagerSceneStart, event.event); - } - - return consumed; -} - -void pocsag_pager_scene_start_on_exit(void* context) { - POCSAGPagerApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/external/pocsag_pager/views/pocsag_pager_receiver.c b/applications/external/pocsag_pager/views/pocsag_pager_receiver.c deleted file mode 100644 index 629c3894e..000000000 --- a/applications/external/pocsag_pager/views/pocsag_pager_receiver.c +++ /dev/null @@ -1,479 +0,0 @@ -#include "pocsag_pager_receiver.h" -#include "../pocsag_pager_app_i.h" -#include "pocsag_pager_icons.h" -#include -#include - -#include -#include -#include - -#define FRAME_HEIGHT 12 -#define MAX_LEN_PX 112 -#define MENU_ITEMS 4u -#define UNLOCK_CNT 3 - -#define SUBGHZ_RAW_THRESHOLD_MIN -90.0f - -typedef struct { - FuriString* item_str; - uint8_t type; -} PCSGReceiverMenuItem; - -ARRAY_DEF(PCSGReceiverMenuItemArray, PCSGReceiverMenuItem, M_POD_OPLIST) - -#define M_OPL_PCSGReceiverMenuItemArray_t() ARRAY_OPLIST(PCSGReceiverMenuItemArray, M_POD_OPLIST) - -struct PCSGReceiverHistory { - PCSGReceiverMenuItemArray_t data; -}; - -typedef struct PCSGReceiverHistory PCSGReceiverHistory; - -static const Icon* ReceiverItemIcons[] = { - [SubGhzProtocolTypeUnknown] = &I_Quest_7x8, - [SubGhzProtocolTypeStatic] = &I_Message_8x7, - [SubGhzProtocolTypeDynamic] = &I_Lock_7x8, -}; - -typedef enum { - PCSGReceiverBarShowDefault, - PCSGReceiverBarShowLock, - PCSGReceiverBarShowToUnlockPress, - PCSGReceiverBarShowUnlock, -} PCSGReceiverBarShow; - -struct PCSGReceiver { - PCSGLock lock; - uint8_t lock_count; - FuriTimer* timer; - View* view; - PCSGReceiverCallback callback; - void* context; -}; - -typedef struct { - FuriString* frequency_str; - FuriString* preset_str; - FuriString* history_stat_str; - PCSGReceiverHistory* history; - uint16_t idx; - uint16_t list_offset; - uint16_t history_item; - PCSGReceiverBarShow bar_show; - uint8_t u_rssi; - bool ext_module; -} PCSGReceiverModel; - -void pcsg_receiver_rssi(PCSGReceiver* instance, float rssi) { - furi_assert(instance); - with_view_model( - instance->view, - PCSGReceiverModel * model, - { - if(rssi < SUBGHZ_RAW_THRESHOLD_MIN) { - model->u_rssi = 0; - } else { - model->u_rssi = (uint8_t)(rssi - SUBGHZ_RAW_THRESHOLD_MIN); - } - }, - true); -} - -void pcsg_view_receiver_set_lock(PCSGReceiver* pcsg_receiver, PCSGLock lock) { - furi_assert(pcsg_receiver); - pcsg_receiver->lock_count = 0; - if(lock == PCSGLockOn) { - pcsg_receiver->lock = lock; - with_view_model( - pcsg_receiver->view, - PCSGReceiverModel * model, - { model->bar_show = PCSGReceiverBarShowLock; }, - true); - furi_timer_start(pcsg_receiver->timer, pdMS_TO_TICKS(1000)); - } else { - with_view_model( - pcsg_receiver->view, - PCSGReceiverModel * model, - { model->bar_show = PCSGReceiverBarShowDefault; }, - true); - } -} - -void pcsg_view_receiver_set_ext_module_state(PCSGReceiver* pcsg_receiver, bool is_external) { - furi_assert(pcsg_receiver); - with_view_model( - pcsg_receiver->view, PCSGReceiverModel * model, { model->ext_module = is_external; }, true); -} - -void pcsg_view_receiver_set_callback( - PCSGReceiver* pcsg_receiver, - PCSGReceiverCallback callback, - void* context) { - furi_assert(pcsg_receiver); - furi_assert(callback); - pcsg_receiver->callback = callback; - pcsg_receiver->context = context; -} - -static void pcsg_view_receiver_update_offset(PCSGReceiver* pcsg_receiver) { - furi_assert(pcsg_receiver); - - with_view_model( - pcsg_receiver->view, - PCSGReceiverModel * model, - { - size_t history_item = model->history_item; - uint16_t bounds = history_item > 3 ? 2 : history_item; - - if(history_item > 3 && model->idx >= (int16_t)(history_item - 1)) { - model->list_offset = model->idx - 3; - } else if(model->list_offset < model->idx - bounds) { - model->list_offset = - CLAMP(model->list_offset + 1, (int16_t)(history_item - bounds), 0); - } else if(model->list_offset > model->idx - bounds) { - model->list_offset = CLAMP(model->idx - 1, (int16_t)(history_item - bounds), 0); - } - }, - true); -} - -void pcsg_view_receiver_add_item_to_menu( - PCSGReceiver* pcsg_receiver, - const char* name, - uint8_t type) { - furi_assert(pcsg_receiver); - with_view_model( - pcsg_receiver->view, - PCSGReceiverModel * model, - { - PCSGReceiverMenuItem* item_menu = - PCSGReceiverMenuItemArray_push_raw(model->history->data); - item_menu->item_str = furi_string_alloc_set(name); - item_menu->type = type; - if((model->idx == model->history_item - 1)) { - model->history_item++; - model->idx++; - } else { - model->history_item++; - } - }, - true); - pcsg_view_receiver_update_offset(pcsg_receiver); -} - -void pcsg_view_receiver_add_data_statusbar( - PCSGReceiver* pcsg_receiver, - const char* frequency_str, - const char* preset_str, - const char* history_stat_str) { - furi_assert(pcsg_receiver); - with_view_model( - pcsg_receiver->view, - PCSGReceiverModel * model, - { - furi_string_set_str(model->frequency_str, frequency_str); - furi_string_set_str(model->preset_str, preset_str); - furi_string_set_str(model->history_stat_str, history_stat_str); - }, - true); -} - -static void pcsg_view_receiver_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar) { - canvas_set_color(canvas, ColorBlack); - canvas_draw_box(canvas, 0, 0 + idx * FRAME_HEIGHT, scrollbar ? 122 : 127, FRAME_HEIGHT); - - canvas_set_color(canvas, ColorWhite); - canvas_draw_dot(canvas, 0, 0 + idx * FRAME_HEIGHT); - canvas_draw_dot(canvas, 1, 0 + idx * FRAME_HEIGHT); - canvas_draw_dot(canvas, 0, (0 + idx * FRAME_HEIGHT) + 1); - - canvas_draw_dot(canvas, 0, (0 + idx * FRAME_HEIGHT) + 11); - canvas_draw_dot(canvas, scrollbar ? 121 : 126, 0 + idx * FRAME_HEIGHT); - canvas_draw_dot(canvas, scrollbar ? 121 : 126, (0 + idx * FRAME_HEIGHT) + 11); -} - -static void pcsg_view_rssi_draw(Canvas* canvas, PCSGReceiverModel* model) { - for(uint8_t i = 1; i < model->u_rssi; i++) { - if(i % 5) { - canvas_draw_dot(canvas, 46 + i, 50); - canvas_draw_dot(canvas, 47 + i, 51); - canvas_draw_dot(canvas, 46 + i, 52); - } - } -} - -void pcsg_view_receiver_draw(Canvas* canvas, PCSGReceiverModel* model) { - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontSecondary); - - elements_button_left(canvas, "Config"); - //canvas_draw_line(canvas, 46, 51, 125, 51); - - bool scrollbar = model->history_item > 4; - FuriString* str_buff; - str_buff = furi_string_alloc(); - - PCSGReceiverMenuItem* item_menu; - - for(size_t i = 0; i < MIN(model->history_item, MENU_ITEMS); ++i) { - size_t idx = CLAMP((uint16_t)(i + model->list_offset), model->history_item, 0); - item_menu = PCSGReceiverMenuItemArray_get(model->history->data, idx); - furi_string_set(str_buff, item_menu->item_str); - furi_string_replace_all(str_buff, "#", ""); - elements_string_fit_width(canvas, str_buff, scrollbar ? MAX_LEN_PX - 7 : MAX_LEN_PX); - if(model->idx == idx) { - pcsg_view_receiver_draw_frame(canvas, i, scrollbar); - } else { - canvas_set_color(canvas, ColorBlack); - } - canvas_draw_icon(canvas, 4, 2 + i * FRAME_HEIGHT, ReceiverItemIcons[item_menu->type]); - canvas_draw_str(canvas, 15, 9 + i * FRAME_HEIGHT, furi_string_get_cstr(str_buff)); - furi_string_reset(str_buff); - } - if(scrollbar) { - elements_scrollbar_pos(canvas, 128, 0, 49, model->idx, model->history_item); - } - furi_string_free(str_buff); - - canvas_set_color(canvas, ColorBlack); - - if(model->history_item == 0) { - canvas_draw_icon(canvas, 0, 0, model->ext_module ? &I_Fishing_123x52 : &I_Scanning_123x52); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 63, 46, "Scanning..."); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 44, 10, model->ext_module ? "Ext" : "Int"); - } - - // Draw RSSI - pcsg_view_rssi_draw(canvas, model); - - switch(model->bar_show) { - case PCSGReceiverBarShowLock: - canvas_draw_icon(canvas, 64, 55, &I_Lock_7x8); - canvas_draw_str(canvas, 74, 62, "Locked"); - break; - case PCSGReceiverBarShowToUnlockPress: - canvas_draw_str(canvas, 44, 62, furi_string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 79, 62, furi_string_get_cstr(model->preset_str)); - canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str)); - canvas_set_font(canvas, FontSecondary); - elements_bold_rounded_frame(canvas, 14, 8, 99, 48); - elements_multiline_text(canvas, 65, 26, "To unlock\npress:"); - canvas_draw_icon(canvas, 65, 42, &I_Pin_back_arrow_10x8); - canvas_draw_icon(canvas, 80, 42, &I_Pin_back_arrow_10x8); - canvas_draw_icon(canvas, 95, 42, &I_Pin_back_arrow_10x8); - canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42); - canvas_draw_dot(canvas, 17, 61); - break; - case PCSGReceiverBarShowUnlock: - canvas_draw_icon(canvas, 64, 55, &I_Unlock_7x8); - canvas_draw_str(canvas, 74, 62, "Unlocked"); - break; - default: - canvas_draw_str(canvas, 44, 62, furi_string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 79, 62, furi_string_get_cstr(model->preset_str)); - canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str)); - break; - } -} - -static void pcsg_view_receiver_timer_callback(void* context) { - furi_assert(context); - PCSGReceiver* pcsg_receiver = context; - with_view_model( - pcsg_receiver->view, - PCSGReceiverModel * model, - { model->bar_show = PCSGReceiverBarShowDefault; }, - true); - if(pcsg_receiver->lock_count < UNLOCK_CNT) { - pcsg_receiver->callback(PCSGCustomEventViewReceiverOffDisplay, pcsg_receiver->context); - } else { - pcsg_receiver->lock = PCSGLockOff; - pcsg_receiver->callback(PCSGCustomEventViewReceiverUnlock, pcsg_receiver->context); - } - pcsg_receiver->lock_count = 0; -} - -bool pcsg_view_receiver_input(InputEvent* event, void* context) { - furi_assert(context); - PCSGReceiver* pcsg_receiver = context; - - if(pcsg_receiver->lock == PCSGLockOn) { - with_view_model( - pcsg_receiver->view, - PCSGReceiverModel * model, - { model->bar_show = PCSGReceiverBarShowToUnlockPress; }, - true); - if(pcsg_receiver->lock_count == 0) { - furi_timer_start(pcsg_receiver->timer, pdMS_TO_TICKS(1000)); - } - if(event->key == InputKeyBack && event->type == InputTypeShort) { - pcsg_receiver->lock_count++; - } - if(pcsg_receiver->lock_count >= UNLOCK_CNT) { - pcsg_receiver->callback(PCSGCustomEventViewReceiverUnlock, pcsg_receiver->context); - with_view_model( - pcsg_receiver->view, - PCSGReceiverModel * model, - { model->bar_show = PCSGReceiverBarShowUnlock; }, - true); - pcsg_receiver->lock = PCSGLockOff; - furi_timer_start(pcsg_receiver->timer, pdMS_TO_TICKS(650)); - } - - return true; - } - - if(event->key == InputKeyBack && event->type == InputTypeShort) { - pcsg_receiver->callback(PCSGCustomEventViewReceiverBack, pcsg_receiver->context); - } else if( - event->key == InputKeyUp && - (event->type == InputTypeShort || event->type == InputTypeRepeat)) { - with_view_model( - pcsg_receiver->view, - PCSGReceiverModel * model, - { - if(model->idx != 0) model->idx--; - }, - true); - } else if( - event->key == InputKeyDown && - (event->type == InputTypeShort || event->type == InputTypeRepeat)) { - with_view_model( - pcsg_receiver->view, - PCSGReceiverModel * model, - { - if(model->history_item && model->idx != model->history_item - 1) model->idx++; - }, - true); - } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { - pcsg_receiver->callback(PCSGCustomEventViewReceiverConfig, pcsg_receiver->context); - } else if(event->key == InputKeyOk && event->type == InputTypeShort) { - with_view_model( - pcsg_receiver->view, - PCSGReceiverModel * model, - { - if(model->history_item != 0) { - pcsg_receiver->callback(PCSGCustomEventViewReceiverOK, pcsg_receiver->context); - } - }, - false); - } - - pcsg_view_receiver_update_offset(pcsg_receiver); - - return true; -} - -void pcsg_view_receiver_enter(void* context) { - furi_assert(context); -} - -void pcsg_view_receiver_exit(void* context) { - furi_assert(context); - PCSGReceiver* pcsg_receiver = context; - with_view_model( - pcsg_receiver->view, - PCSGReceiverModel * model, - { - furi_string_reset(model->frequency_str); - furi_string_reset(model->preset_str); - furi_string_reset(model->history_stat_str); - for - M_EACH(item_menu, model->history->data, PCSGReceiverMenuItemArray_t) { - furi_string_free(item_menu->item_str); - item_menu->type = 0; - } - PCSGReceiverMenuItemArray_reset(model->history->data); - model->idx = 0; - model->list_offset = 0; - model->history_item = 0; - }, - false); - furi_timer_stop(pcsg_receiver->timer); -} - -PCSGReceiver* pcsg_view_receiver_alloc() { - PCSGReceiver* pcsg_receiver = malloc(sizeof(PCSGReceiver)); - - // View allocation and configuration - pcsg_receiver->view = view_alloc(); - - pcsg_receiver->lock = PCSGLockOff; - pcsg_receiver->lock_count = 0; - view_allocate_model(pcsg_receiver->view, ViewModelTypeLocking, sizeof(PCSGReceiverModel)); - view_set_context(pcsg_receiver->view, pcsg_receiver); - view_set_draw_callback(pcsg_receiver->view, (ViewDrawCallback)pcsg_view_receiver_draw); - view_set_input_callback(pcsg_receiver->view, pcsg_view_receiver_input); - view_set_enter_callback(pcsg_receiver->view, pcsg_view_receiver_enter); - view_set_exit_callback(pcsg_receiver->view, pcsg_view_receiver_exit); - - with_view_model( - pcsg_receiver->view, - PCSGReceiverModel * model, - { - model->frequency_str = furi_string_alloc(); - model->preset_str = furi_string_alloc(); - model->history_stat_str = furi_string_alloc(); - model->bar_show = PCSGReceiverBarShowDefault; - model->history = malloc(sizeof(PCSGReceiverHistory)); - PCSGReceiverMenuItemArray_init(model->history->data); - }, - true); - pcsg_receiver->timer = - furi_timer_alloc(pcsg_view_receiver_timer_callback, FuriTimerTypeOnce, pcsg_receiver); - return pcsg_receiver; -} - -void pcsg_view_receiver_free(PCSGReceiver* pcsg_receiver) { - furi_assert(pcsg_receiver); - - with_view_model( - pcsg_receiver->view, - PCSGReceiverModel * model, - { - furi_string_free(model->frequency_str); - furi_string_free(model->preset_str); - furi_string_free(model->history_stat_str); - for - M_EACH(item_menu, model->history->data, PCSGReceiverMenuItemArray_t) { - furi_string_free(item_menu->item_str); - item_menu->type = 0; - } - PCSGReceiverMenuItemArray_clear(model->history->data); - free(model->history); - }, - false); - furi_timer_free(pcsg_receiver->timer); - view_free(pcsg_receiver->view); - free(pcsg_receiver); -} - -View* pcsg_view_receiver_get_view(PCSGReceiver* pcsg_receiver) { - furi_assert(pcsg_receiver); - return pcsg_receiver->view; -} - -uint16_t pcsg_view_receiver_get_idx_menu(PCSGReceiver* pcsg_receiver) { - furi_assert(pcsg_receiver); - uint32_t idx = 0; - with_view_model( - pcsg_receiver->view, PCSGReceiverModel * model, { idx = model->idx; }, false); - return idx; -} - -void pcsg_view_receiver_set_idx_menu(PCSGReceiver* pcsg_receiver, uint16_t idx) { - furi_assert(pcsg_receiver); - with_view_model( - pcsg_receiver->view, - PCSGReceiverModel * model, - { - model->idx = idx; - if(model->idx > 2) model->list_offset = idx - 2; - }, - true); - pcsg_view_receiver_update_offset(pcsg_receiver); -} diff --git a/applications/external/pocsag_pager/views/pocsag_pager_receiver.h b/applications/external/pocsag_pager/views/pocsag_pager_receiver.h deleted file mode 100644 index 87900748f..000000000 --- a/applications/external/pocsag_pager/views/pocsag_pager_receiver.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include -#include "../helpers/pocsag_pager_types.h" -#include "../helpers/pocsag_pager_event.h" - -typedef struct PCSGReceiver PCSGReceiver; - -typedef void (*PCSGReceiverCallback)(PCSGCustomEvent event, void* context); - -void pcsg_receiver_rssi(PCSGReceiver* instance, float rssi); - -void pcsg_view_receiver_set_lock(PCSGReceiver* pcsg_receiver, PCSGLock keyboard); - -void pcsg_view_receiver_set_ext_module_state(PCSGReceiver* pcsg_receiver, bool is_external); - -void pcsg_view_receiver_set_callback( - PCSGReceiver* pcsg_receiver, - PCSGReceiverCallback callback, - void* context); - -PCSGReceiver* pcsg_view_receiver_alloc(); - -void pcsg_view_receiver_free(PCSGReceiver* pcsg_receiver); - -View* pcsg_view_receiver_get_view(PCSGReceiver* pcsg_receiver); - -void pcsg_view_receiver_add_data_statusbar( - PCSGReceiver* pcsg_receiver, - const char* frequency_str, - const char* preset_str, - const char* history_stat_str); - -void pcsg_view_receiver_add_item_to_menu( - PCSGReceiver* pcsg_receiver, - const char* name, - uint8_t type); - -uint16_t pcsg_view_receiver_get_idx_menu(PCSGReceiver* pcsg_receiver); - -void pcsg_view_receiver_set_idx_menu(PCSGReceiver* pcsg_receiver, uint16_t idx); - -void pcsg_view_receiver_exit(void* context); diff --git a/applications/external/pocsag_pager/views/pocsag_pager_receiver_info.c b/applications/external/pocsag_pager/views/pocsag_pager_receiver_info.c deleted file mode 100644 index 91ee69ab5..000000000 --- a/applications/external/pocsag_pager/views/pocsag_pager_receiver_info.c +++ /dev/null @@ -1,138 +0,0 @@ -#include "pocsag_pager_receiver.h" -#include "../pocsag_pager_app_i.h" -#include "pocsag_pager_icons.h" -#include -#include "../protocols/pcsg_generic.h" -#include -#include - -#define abs(x) ((x) > 0 ? (x) : -(x)) - -struct PCSGReceiverInfo { - View* view; -}; - -typedef struct { - FuriString* protocol_name; - PCSGBlockGeneric* generic; -} PCSGReceiverInfoModel; - -void pcsg_view_receiver_info_update(PCSGReceiverInfo* pcsg_receiver_info, FlipperFormat* fff) { - furi_assert(pcsg_receiver_info); - furi_assert(fff); - - with_view_model( - pcsg_receiver_info->view, - PCSGReceiverInfoModel * model, - { - flipper_format_rewind(fff); - flipper_format_read_string(fff, "Protocol", model->protocol_name); - - pcsg_block_generic_deserialize(model->generic, fff); - }, - true); -} - -void pcsg_view_receiver_info_draw(Canvas* canvas, PCSGReceiverInfoModel* model) { - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontSecondary); - if(model->generic->result_ric != NULL) { - elements_text_box( - canvas, - 0, - 0, - 128, - 64, - AlignLeft, - AlignTop, - furi_string_get_cstr(model->generic->result_ric), - false); - } - if(model->generic->result_msg != NULL) { - elements_text_box( - canvas, - 0, - 12, - 128, - 64, - AlignLeft, - AlignTop, - furi_string_get_cstr(model->generic->result_msg), - false); - } -} - -bool pcsg_view_receiver_info_input(InputEvent* event, void* context) { - furi_assert(context); - //PCSGReceiverInfo* pcsg_receiver_info = context; - - if(event->key == InputKeyBack) { - return false; - } - - return true; -} - -void pcsg_view_receiver_info_enter(void* context) { - furi_assert(context); -} - -void pcsg_view_receiver_info_exit(void* context) { - furi_assert(context); - PCSGReceiverInfo* pcsg_receiver_info = context; - - with_view_model( - pcsg_receiver_info->view, - PCSGReceiverInfoModel * model, - { furi_string_reset(model->protocol_name); }, - false); -} - -PCSGReceiverInfo* pcsg_view_receiver_info_alloc() { - PCSGReceiverInfo* pcsg_receiver_info = malloc(sizeof(PCSGReceiverInfo)); - - // View allocation and configuration - pcsg_receiver_info->view = view_alloc(); - - view_allocate_model( - pcsg_receiver_info->view, ViewModelTypeLocking, sizeof(PCSGReceiverInfoModel)); - view_set_context(pcsg_receiver_info->view, pcsg_receiver_info); - view_set_draw_callback( - pcsg_receiver_info->view, (ViewDrawCallback)pcsg_view_receiver_info_draw); - view_set_input_callback(pcsg_receiver_info->view, pcsg_view_receiver_info_input); - view_set_enter_callback(pcsg_receiver_info->view, pcsg_view_receiver_info_enter); - view_set_exit_callback(pcsg_receiver_info->view, pcsg_view_receiver_info_exit); - - with_view_model( - pcsg_receiver_info->view, - PCSGReceiverInfoModel * model, - { - model->generic = malloc(sizeof(PCSGBlockGeneric)); - model->protocol_name = furi_string_alloc(); - }, - true); - - return pcsg_receiver_info; -} - -void pcsg_view_receiver_info_free(PCSGReceiverInfo* pcsg_receiver_info) { - furi_assert(pcsg_receiver_info); - - with_view_model( - pcsg_receiver_info->view, - PCSGReceiverInfoModel * model, - { - furi_string_free(model->protocol_name); - free(model->generic); - }, - false); - - view_free(pcsg_receiver_info->view); - free(pcsg_receiver_info); -} - -View* pcsg_view_receiver_info_get_view(PCSGReceiverInfo* pcsg_receiver_info) { - furi_assert(pcsg_receiver_info); - return pcsg_receiver_info->view; -} diff --git a/applications/external/pocsag_pager/views/pocsag_pager_receiver_info.h b/applications/external/pocsag_pager/views/pocsag_pager_receiver_info.h deleted file mode 100644 index dfc85ec88..000000000 --- a/applications/external/pocsag_pager/views/pocsag_pager_receiver_info.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include -#include "../helpers/pocsag_pager_types.h" -#include "../helpers/pocsag_pager_event.h" -#include - -typedef struct PCSGReceiverInfo PCSGReceiverInfo; - -void pcsg_view_receiver_info_update(PCSGReceiverInfo* pcsg_receiver_info, FlipperFormat* fff); - -PCSGReceiverInfo* pcsg_view_receiver_info_alloc(); - -void pcsg_view_receiver_info_free(PCSGReceiverInfo* pcsg_receiver_info); - -View* pcsg_view_receiver_info_get_view(PCSGReceiverInfo* pcsg_receiver_info); diff --git a/applications/external/weather_station/application.fam b/applications/external/weather_station/application.fam deleted file mode 100644 index 0221130a3..000000000 --- a/applications/external/weather_station/application.fam +++ /dev/null @@ -1,14 +0,0 @@ -App( - appid="weather_station", - name="Weather Station", - apptype=FlipperAppType.EXTERNAL, - targets=["f7"], - entry_point="weather_station_app", - requires=["gui"], - stack_size=4 * 1024, - fap_description="Receive weather data from a wide range of supported Sub-1GHz remote sensor", - fap_version="1.1", - fap_icon="weather_station_10px.png", - fap_category="Sub-GHz", - fap_icon_assets="images", -) diff --git a/applications/external/weather_station/helpers/radio_device_loader.c b/applications/external/weather_station/helpers/radio_device_loader.c deleted file mode 100644 index 0d99549eb..000000000 --- a/applications/external/weather_station/helpers/radio_device_loader.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "radio_device_loader.h" - -#include -#include - -static void radio_device_loader_power_on() { - uint8_t attempts = 0; - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - //CC1101 power-up time - furi_delay_ms(10); - } -} - -static void radio_device_loader_power_off() { - if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg(); -} - -bool radio_device_loader_is_connect_external(const char* name) { - bool is_connect = false; - bool is_otg_enabled = furi_hal_power_is_otg_enabled(); - - if(!is_otg_enabled) { - radio_device_loader_power_on(); - } - - const SubGhzDevice* device = subghz_devices_get_by_name(name); - if(device) { - is_connect = subghz_devices_is_connect(device); - } - - if(!is_otg_enabled) { - radio_device_loader_power_off(); - } - return is_connect; -} - -const SubGhzDevice* radio_device_loader_set( - const SubGhzDevice* current_radio_device, - SubGhzRadioDeviceType radio_device_type) { - const SubGhzDevice* radio_device; - - if(radio_device_type == SubGhzRadioDeviceTypeExternalCC1101 && - radio_device_loader_is_connect_external(SUBGHZ_DEVICE_CC1101_EXT_NAME)) { - radio_device_loader_power_on(); - radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_EXT_NAME); - subghz_devices_begin(radio_device); - } else if(current_radio_device == NULL) { - radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME); - } else { - radio_device_loader_end(current_radio_device); - radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME); - } - - return radio_device; -} - -bool radio_device_loader_is_external(const SubGhzDevice* radio_device) { - furi_assert(radio_device); - return (radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME)); -} - -void radio_device_loader_end(const SubGhzDevice* radio_device) { - furi_assert(radio_device); - radio_device_loader_power_off(); - if(radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME)) { - subghz_devices_end(radio_device); - } -} \ No newline at end of file diff --git a/applications/external/weather_station/helpers/radio_device_loader.h b/applications/external/weather_station/helpers/radio_device_loader.h deleted file mode 100644 index bae4bacf2..000000000 --- a/applications/external/weather_station/helpers/radio_device_loader.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include - -/** SubGhzRadioDeviceType */ -typedef enum { - SubGhzRadioDeviceTypeInternal, - SubGhzRadioDeviceTypeExternalCC1101, -} SubGhzRadioDeviceType; - -const SubGhzDevice* radio_device_loader_set( - const SubGhzDevice* current_radio_device, - SubGhzRadioDeviceType radio_device_type); - -bool radio_device_loader_is_external(const SubGhzDevice* radio_device); - -void radio_device_loader_end(const SubGhzDevice* radio_device); \ No newline at end of file diff --git a/applications/external/weather_station/helpers/weather_station_event.h b/applications/external/weather_station/helpers/weather_station_event.h deleted file mode 100644 index b0486183d..000000000 --- a/applications/external/weather_station/helpers/weather_station_event.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -typedef enum { - //WSCustomEvent - WSCustomEventStartId = 100, - - WSCustomEventSceneSettingLock, - - WSCustomEventViewReceiverOK, - WSCustomEventViewReceiverConfig, - WSCustomEventViewReceiverBack, - WSCustomEventViewReceiverOffDisplay, - WSCustomEventViewReceiverUnlock, -} WSCustomEvent; diff --git a/applications/external/weather_station/helpers/weather_station_types.h b/applications/external/weather_station/helpers/weather_station_types.h deleted file mode 100644 index e6c696bf8..000000000 --- a/applications/external/weather_station/helpers/weather_station_types.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include -#include - -#define WS_VERSION_APP "1.1" -#define WS_DEVELOPED "SkorP" -#define WS_GITHUB "https://github.com/flipperdevices/flipperzero-firmware" - -#define WS_KEY_FILE_VERSION 1 -#define WS_KEY_FILE_TYPE "Flipper Weather Station Key File" - -/** WSRxKeyState state */ -typedef enum { - WSRxKeyStateIDLE, - WSRxKeyStateBack, - WSRxKeyStateStart, - WSRxKeyStateAddKey, -} WSRxKeyState; - -/** WSHopperState state */ -typedef enum { - WSHopperStateOFF, - WSHopperStateRunnig, - WSHopperStatePause, - WSHopperStateRSSITimeOut, -} WSHopperState; - -/** WSLock */ -typedef enum { - WSLockOff, - WSLockOn, -} WSLock; - -typedef enum { - WeatherStationViewVariableItemList, - WeatherStationViewSubmenu, - WeatherStationViewReceiver, - WeatherStationViewReceiverInfo, - WeatherStationViewWidget, -} WeatherStationView; - -/** WeatherStationTxRx state */ -typedef enum { - WSTxRxStateIDLE, - WSTxRxStateRx, - WSTxRxStateTx, - WSTxRxStateSleep, -} WSTxRxState; diff --git a/applications/external/weather_station/images/Humid_10x15.png b/applications/external/weather_station/images/Humid_10x15.png deleted file mode 100644 index 34b074e5f75150853ec976d7521e1663f0f30f1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3624 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 diff --git a/applications/external/weather_station/images/Humid_8x13.png b/applications/external/weather_station/images/Humid_8x13.png deleted file mode 100644 index 6d8c71b000699e148e9480f7ddf9795b33e2fe7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3618 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 diff --git a/applications/external/weather_station/images/Therm_7x16.png b/applications/external/weather_station/images/Therm_7x16.png deleted file mode 100644 index 7c55500b7e7ea9112c92ba966643e3684887eb92..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3611 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 diff --git a/applications/external/weather_station/images/Timer_11x11.png b/applications/external/weather_station/images/Timer_11x11.png deleted file mode 100644 index 21ad47f4b2bf69d81929187ca63d7a3d1b111ea4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3616 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 Y4M;=-T9{t95l zwopRIzGX{t@mx#XY`<~ut>5#<({oM616_IinfXlyJJOj zkl+P5pku?t6BJeC_(UzE<#Glk?CTGhm~hFoW=C_z#f9CJuvZnl!9Tz=Eq6ce+JopD z?=~lbANcgutbcCbdERd@TfCB4-pNzPE0}DqVXqY?Sb#oy;M291rsj!hh*3Dd0v!4N$jm_A&>aR04G!q5@?AuOOgqA02TV;0gxZTjk{gfa__1 zxaqR9{+}mGMQ2sml}anquTnsmguC&o`SCbALyjtUSV)}^*Cy;Eq#HpR0@I}7;hG|! zR^9_Zc7g;u+m-Er4&l;{4(+%K;d5$VUvuw*Jv^p%W;%=LMgTCu4DH%cg_a)<)8h`K z?%Y4N$mM-jAp7EatXG+c(Q_bsZpe9szE>NQoLg0cgEQ091C~u_H^MvTkR5WvxjN_V z3x9>`Z>_I=dNrvK4nGra#lXFNH-St*I)nRS!v0I*z5 ztN*CX%NgcEv00KjI4t2{B5S*<^$TE~5) ze*Z|lz?QrAb+kfL16mZ#PYgT4a6evr6|EfE{zO*A9s1EoRqVw9H`+H*g>) zbJ=ASV;>^wwCT$Py;cBzbt|&Q40b2H%pUbo@HwU`U+3_3)B6G+h)h^|ykvI92gb9* zsGHh3vmc7QMTX)HFfHnJUk>qTG+j`KG&iE3>ZfLUi-iUejvAZet?{-4=J}u_3YrIo_;mO&9e zZ>}oeCl-GYDjFP(Y0^;;i^0H^s&4JGc={06E!J(??du>vr&^GqX?|Ef@$C@Nr;G=2 zM-_CUHDWq*x^Y@#T4q{q*^NKb!^rR9hU28N!@KjA(leqnnls#_RJgIzgLH?{{2bf? zt$0^-Nlt~sWBaK5gPIr95$)F`Ev#}&?kDve_LlNqr#$|`e0g9r>8NeW2j}j#IkPV* zUpQA;fqa}wL;LKf=ca0!K?0uAj#6^wM+r!YAs z8DC^xWM5=9U#nfZkeB(W)}-2HGhEoX#Zu|Ck{LO^V}ItXCCB=zORDn@P%^7}T5M<{AgxJcGjHq`$aLmYVuIhNjWchNB9&1&)-l#K5b?HtgU zsyNtoyor+On9*ZKmLgaAUt5Wejj_7g21zl1WXLp+w$@HtGS~dhOayhWWoDFTG%Vx~ zKVH;cq%1~_+s-V*=8F6-aW`nU3&;yQ#zE$c z2{#UR+qbz9bXo3ooFQ_U^sQ`g!T4r&m9d0z{MC}HGxa5M-mQP!Dv?{CP3=hNpa@5t z4E@sgfrs#!5Zf3ks1y+u;T&lgM~}uI?t-OgvARYu{^Qv1*ktTj1{r3Dc&uirrD9MB zIj=vY^HTGrVKcIed&QmXBH;nn!o!b;R+=A^(>uv99v^$a~Qr=wvt zB2TgaBBqK=HnNVk)xGmS#-b|uk~fbnA7mYi;}2|*Z6Jf8UD{pI1DMk)M{SqQRcwN8 z|B+Cm6{zq=BUg2%>bg?Ftr}|~>(LBkmSp-R5EYI>*21pcPPpZVE|jxLtRR0SfA+f6 zR!oX0+j-*~TM0dy#Pimt{8sUP7d8G0^rJ60SLJ>co-#7Y+3R(C%sWJKQPzp}h4N5VE@I5k9#y}$GMydF)REorv z0p*c^8JQ^ByVq$Wcb*j#HB}Kiy}G^TK98woxd|s1rhHBj_7xf&dL}e}>e<5DH)}tGMqt?ZxiV=Y;+Z->yZO;F@omfAkK!)vRwD zynQw7#NlMq>(xuzwAd_PH!O`QoZCp=q@F3UrTQ(jaCUQU^T-QV^jCfCmF-619OC;< z%$o_f{Pt=mbBU!Uq%Gw1``zYAc{(<5dTyO>eEp~pa_G{{;Nl6Mp5HFXl4YUi(dorJF>ae#V6XK#nJk@-(bd|(KP7kjdb1Fy(b|7f2^T9Z3GPiwsY8@4V#qT+xvj28qC=F>o~6g&&1H=}lwO{Jm*(5L^QS11Z}O zJSo0=mg9d@Y;2GgzWz*tuP4a@ivqJnAQTD_iO@0Cgz4&fn>%=Kl)VF6V2yDBLmuu#BGDc20P%5&ib>ZsNy~+CaLb9y8-;NI`}zRsF?bn; PjRq`CY_X+i_pAQ_NTe=6 diff --git a/applications/external/weather_station/protocols/protocol_items.c b/applications/external/weather_station/protocols/protocol_items.c deleted file mode 100644 index e0ec86068..000000000 --- a/applications/external/weather_station/protocols/protocol_items.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "protocol_items.h" - -const SubGhzProtocol* weather_station_protocol_registry_items[] = { - &ws_protocol_infactory, - &ws_protocol_thermopro_tx4, - &ws_protocol_nexus_th, - &ws_protocol_gt_wt_02, - &ws_protocol_gt_wt_03, - &ws_protocol_acurite_606tx, - &ws_protocol_acurite_609txc, - &ws_protocol_lacrosse_tx, - &ws_protocol_lacrosse_tx141thbv2, - &ws_protocol_oregon2, - &ws_protocol_oregon3, - &ws_protocol_acurite_592txr, - &ws_protocol_ambient_weather, - &ws_protocol_auriol_th, - &ws_protocol_oregon_v1, - &ws_protocol_tx_8300, - &ws_protocol_wendox_w6726, - &ws_protocol_auriol_ahfl, -}; - -const SubGhzProtocolRegistry weather_station_protocol_registry = { - .items = weather_station_protocol_registry_items, - .size = COUNT_OF(weather_station_protocol_registry_items)}; diff --git a/applications/external/weather_station/protocols/protocol_items.h b/applications/external/weather_station/protocols/protocol_items.h deleted file mode 100644 index 7d9bda243..000000000 --- a/applications/external/weather_station/protocols/protocol_items.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once -#include "../weather_station_app_i.h" - -#include "infactory.h" -#include "thermopro_tx4.h" -#include "nexus_th.h" -#include "gt_wt_02.h" -#include "gt_wt_03.h" -#include "acurite_606tx.h" -#include "acurite_609txc.h" -#include "lacrosse_tx.h" -#include "lacrosse_tx141thbv2.h" -#include "oregon2.h" -#include "oregon3.h" -#include "acurite_592txr.h" -#include "ambient_weather.h" -#include "auriol_hg0601a.h" -#include "oregon_v1.h" -#include "tx_8300.h" -#include "wendox_w6726.h" -#include "auriol_ahfl.h" - -extern const SubGhzProtocolRegistry weather_station_protocol_registry; diff --git a/applications/external/weather_station/scenes/weather_station_receiver.c b/applications/external/weather_station/scenes/weather_station_receiver.c deleted file mode 100644 index 76d808e7e..000000000 --- a/applications/external/weather_station/scenes/weather_station_receiver.c +++ /dev/null @@ -1,216 +0,0 @@ -#include "../weather_station_app_i.h" -#include "../views/weather_station_receiver.h" - -static const NotificationSequence subghs_sequence_rx = { - &message_green_255, - - &message_vibro_on, - &message_note_c6, - &message_delay_50, - &message_sound_off, - &message_vibro_off, - - &message_delay_50, - NULL, -}; - -static const NotificationSequence subghs_sequence_rx_locked = { - &message_green_255, - - &message_display_backlight_on, - - &message_vibro_on, - &message_note_c6, - &message_delay_50, - &message_sound_off, - &message_vibro_off, - - &message_delay_500, - - &message_display_backlight_off, - NULL, -}; - -static void weather_station_scene_receiver_update_statusbar(void* context) { - WeatherStationApp* app = context; - FuriString* history_stat_str; - history_stat_str = furi_string_alloc(); - if(!ws_history_get_text_space_left(app->txrx->history, history_stat_str)) { - FuriString* frequency_str; - FuriString* modulation_str; - - frequency_str = furi_string_alloc(); - modulation_str = furi_string_alloc(); - - ws_get_frequency_modulation(app, frequency_str, modulation_str); - - ws_view_receiver_add_data_statusbar( - app->ws_receiver, - furi_string_get_cstr(frequency_str), - furi_string_get_cstr(modulation_str), - furi_string_get_cstr(history_stat_str), - radio_device_loader_is_external(app->txrx->radio_device)); - - furi_string_free(frequency_str); - furi_string_free(modulation_str); - } else { - ws_view_receiver_add_data_statusbar( - app->ws_receiver, - furi_string_get_cstr(history_stat_str), - "", - "", - radio_device_loader_is_external(app->txrx->radio_device)); - } - furi_string_free(history_stat_str); -} - -void weather_station_scene_receiver_callback(WSCustomEvent event, void* context) { - furi_assert(context); - WeatherStationApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -static void weather_station_scene_receiver_add_to_history_callback( - SubGhzReceiver* receiver, - SubGhzProtocolDecoderBase* decoder_base, - void* context) { - furi_assert(context); - WeatherStationApp* app = context; - FuriString* str_buff; - str_buff = furi_string_alloc(); - - if(ws_history_add_to_history(app->txrx->history, decoder_base, app->txrx->preset) == - WSHistoryStateAddKeyNewDada) { - furi_string_reset(str_buff); - - ws_history_get_text_item_menu( - app->txrx->history, str_buff, ws_history_get_item(app->txrx->history) - 1); - ws_view_receiver_add_item_to_menu( - app->ws_receiver, - furi_string_get_cstr(str_buff), - ws_history_get_type_protocol( - app->txrx->history, ws_history_get_item(app->txrx->history) - 1)); - - weather_station_scene_receiver_update_statusbar(app); - notification_message(app->notifications, &sequence_blink_green_10); - if(app->lock != WSLockOn) { - notification_message(app->notifications, &subghs_sequence_rx); - } else { - notification_message(app->notifications, &subghs_sequence_rx_locked); - } - } - subghz_receiver_reset(receiver); - furi_string_free(str_buff); - app->txrx->rx_key_state = WSRxKeyStateAddKey; -} - -void weather_station_scene_receiver_on_enter(void* context) { - WeatherStationApp* app = context; - - FuriString* str_buff; - str_buff = furi_string_alloc(); - - if(app->txrx->rx_key_state == WSRxKeyStateIDLE) { - ws_preset_init(app, "AM650", subghz_setting_get_default_frequency(app->setting), NULL, 0); - ws_history_reset(app->txrx->history); - app->txrx->rx_key_state = WSRxKeyStateStart; - } - - ws_view_receiver_set_lock(app->ws_receiver, app->lock); - - //Load history to receiver - ws_view_receiver_exit(app->ws_receiver); - for(uint8_t i = 0; i < ws_history_get_item(app->txrx->history); i++) { - furi_string_reset(str_buff); - ws_history_get_text_item_menu(app->txrx->history, str_buff, i); - ws_view_receiver_add_item_to_menu( - app->ws_receiver, - furi_string_get_cstr(str_buff), - ws_history_get_type_protocol(app->txrx->history, i)); - app->txrx->rx_key_state = WSRxKeyStateAddKey; - } - furi_string_free(str_buff); - weather_station_scene_receiver_update_statusbar(app); - - ws_view_receiver_set_callback(app->ws_receiver, weather_station_scene_receiver_callback, app); - subghz_receiver_set_rx_callback( - app->txrx->receiver, weather_station_scene_receiver_add_to_history_callback, app); - - if(app->txrx->txrx_state == WSTxRxStateRx) { - ws_rx_end(app); - }; - if((app->txrx->txrx_state == WSTxRxStateIDLE) || (app->txrx->txrx_state == WSTxRxStateSleep)) { - ws_begin( - app, - subghz_setting_get_preset_data_by_name( - app->setting, furi_string_get_cstr(app->txrx->preset->name))); - - ws_rx(app, app->txrx->preset->frequency); - } - - ws_view_receiver_set_idx_menu(app->ws_receiver, app->txrx->idx_menu_chosen); - view_dispatcher_switch_to_view(app->view_dispatcher, WeatherStationViewReceiver); -} - -bool weather_station_scene_receiver_on_event(void* context, SceneManagerEvent event) { - WeatherStationApp* app = context; - bool consumed = false; - if(event.type == SceneManagerEventTypeCustom) { - switch(event.event) { - case WSCustomEventViewReceiverBack: - // Stop CC1101 Rx - if(app->txrx->txrx_state == WSTxRxStateRx) { - ws_rx_end(app); - ws_sleep(app); - }; - app->txrx->hopper_state = WSHopperStateOFF; - app->txrx->idx_menu_chosen = 0; - subghz_receiver_set_rx_callback(app->txrx->receiver, NULL, app); - - app->txrx->rx_key_state = WSRxKeyStateIDLE; - ws_preset_init( - app, "AM650", subghz_setting_get_default_frequency(app->setting), NULL, 0); - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, WeatherStationSceneStart); - consumed = true; - break; - case WSCustomEventViewReceiverOK: - app->txrx->idx_menu_chosen = ws_view_receiver_get_idx_menu(app->ws_receiver); - scene_manager_next_scene(app->scene_manager, WeatherStationSceneReceiverInfo); - consumed = true; - break; - case WSCustomEventViewReceiverConfig: - app->txrx->idx_menu_chosen = ws_view_receiver_get_idx_menu(app->ws_receiver); - scene_manager_next_scene(app->scene_manager, WeatherStationSceneReceiverConfig); - consumed = true; - break; - case WSCustomEventViewReceiverOffDisplay: - notification_message(app->notifications, &sequence_display_backlight_off); - consumed = true; - break; - case WSCustomEventViewReceiverUnlock: - app->lock = WSLockOff; - consumed = true; - break; - default: - break; - } - } else if(event.type == SceneManagerEventTypeTick) { - if(app->txrx->hopper_state != WSHopperStateOFF) { - ws_hopper_update(app); - weather_station_scene_receiver_update_statusbar(app); - } - // Get current RSSI - float rssi = subghz_devices_get_rssi(app->txrx->radio_device); - ws_view_receiver_set_rssi(app->ws_receiver, rssi); - - if(app->txrx->txrx_state == WSTxRxStateRx) { - notification_message(app->notifications, &sequence_blink_cyan_10); - } - } - return consumed; -} - -void weather_station_scene_receiver_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/weather_station/scenes/weather_station_scene.c b/applications/external/weather_station/scenes/weather_station_scene.c deleted file mode 100644 index f9306e5f4..000000000 --- a/applications/external/weather_station/scenes/weather_station_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "../weather_station_app_i.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const weather_station_scene_on_enter_handlers[])(void*) = { -#include "weather_station_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_event handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, -bool (*const weather_station_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "weather_station_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_exit handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, -void (*const weather_station_scene_on_exit_handlers[])(void* context) = { -#include "weather_station_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers weather_station_scene_handlers = { - .on_enter_handlers = weather_station_scene_on_enter_handlers, - .on_event_handlers = weather_station_scene_on_event_handlers, - .on_exit_handlers = weather_station_scene_on_exit_handlers, - .scene_num = WeatherStationSceneNum, -}; diff --git a/applications/external/weather_station/scenes/weather_station_scene.h b/applications/external/weather_station/scenes/weather_station_scene.h deleted file mode 100644 index 8cee4ee60..000000000 --- a/applications/external/weather_station/scenes/weather_station_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) WeatherStationScene##id, -typedef enum { -#include "weather_station_scene_config.h" - WeatherStationSceneNum, -} WeatherStationScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers weather_station_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "weather_station_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_event handlers declaration -#define ADD_SCENE(prefix, name, id) \ - bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); -#include "weather_station_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_exit handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); -#include "weather_station_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/weather_station/scenes/weather_station_scene_about.c b/applications/external/weather_station/scenes/weather_station_scene_about.c deleted file mode 100644 index d916dc76f..000000000 --- a/applications/external/weather_station/scenes/weather_station_scene_about.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "../weather_station_app_i.h" -#include "../helpers/weather_station_types.h" - -void weather_station_scene_about_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - WeatherStationApp* app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(app->view_dispatcher, result); - } -} - -void weather_station_scene_about_on_enter(void* context) { - WeatherStationApp* app = context; - - FuriString* temp_str; - temp_str = furi_string_alloc(); - furi_string_printf(temp_str, "\e#%s\n", "Information"); - - furi_string_cat_printf(temp_str, "Version: %s\n", WS_VERSION_APP); - furi_string_cat_printf(temp_str, "Developed by: %s\n", WS_DEVELOPED); - furi_string_cat_printf(temp_str, "Github: %s\n\n", WS_GITHUB); - - furi_string_cat_printf(temp_str, "\e#%s\n", "Description"); - furi_string_cat_printf( - temp_str, "Reading messages from\nweather stations that work\nwith SubGhz sensors\n\n"); - - furi_string_cat_printf(temp_str, "Supported protocols:\n"); - size_t i = 0; - const char* protocol_name = - subghz_environment_get_protocol_name_registry(app->txrx->environment, i++); - do { - furi_string_cat_printf(temp_str, "%s\n", protocol_name); - protocol_name = subghz_environment_get_protocol_name_registry(app->txrx->environment, i++); - } while(protocol_name != NULL); - - widget_add_text_box_element( - app->widget, - 0, - 0, - 128, - 14, - AlignCenter, - AlignBottom, - "\e#\e! \e!\n", - false); - widget_add_text_box_element( - app->widget, - 0, - 2, - 128, - 14, - AlignCenter, - AlignBottom, - "\e#\e! Weather station \e!\n", - false); - widget_add_text_scroll_element(app->widget, 0, 16, 128, 50, furi_string_get_cstr(temp_str)); - furi_string_free(temp_str); - - view_dispatcher_switch_to_view(app->view_dispatcher, WeatherStationViewWidget); -} - -bool weather_station_scene_about_on_event(void* context, SceneManagerEvent event) { - WeatherStationApp* app = context; - bool consumed = false; - UNUSED(app); - UNUSED(event); - - return consumed; -} - -void weather_station_scene_about_on_exit(void* context) { - WeatherStationApp* app = context; - - // Clear views - widget_reset(app->widget); -} diff --git a/applications/external/weather_station/scenes/weather_station_scene_config.h b/applications/external/weather_station/scenes/weather_station_scene_config.h deleted file mode 100644 index 0ba8ec013..000000000 --- a/applications/external/weather_station/scenes/weather_station_scene_config.h +++ /dev/null @@ -1,5 +0,0 @@ -ADD_SCENE(weather_station, start, Start) -ADD_SCENE(weather_station, about, About) -ADD_SCENE(weather_station, receiver, Receiver) -ADD_SCENE(weather_station, receiver_config, ReceiverConfig) -ADD_SCENE(weather_station, receiver_info, ReceiverInfo) diff --git a/applications/external/weather_station/scenes/weather_station_scene_receiver_config.c b/applications/external/weather_station/scenes/weather_station_scene_receiver_config.c deleted file mode 100644 index fcd8f6d3e..000000000 --- a/applications/external/weather_station/scenes/weather_station_scene_receiver_config.c +++ /dev/null @@ -1,223 +0,0 @@ -#include "../weather_station_app_i.h" - -enum WSSettingIndex { - WSSettingIndexFrequency, - WSSettingIndexHopping, - WSSettingIndexModulation, - WSSettingIndexLock, -}; - -#define HOPPING_COUNT 2 -const char* const hopping_text[HOPPING_COUNT] = { - "OFF", - "ON", -}; -const uint32_t hopping_value[HOPPING_COUNT] = { - WSHopperStateOFF, - WSHopperStateRunnig, -}; - -uint8_t weather_station_scene_receiver_config_next_frequency(const uint32_t value, void* context) { - furi_assert(context); - WeatherStationApp* app = context; - uint8_t index = 0; - for(uint8_t i = 0; i < subghz_setting_get_frequency_count(app->setting); i++) { - if(value == subghz_setting_get_frequency(app->setting, i)) { - index = i; - break; - } else { - index = subghz_setting_get_frequency_default_index(app->setting); - } - } - return index; -} - -uint8_t weather_station_scene_receiver_config_next_preset(const char* preset_name, void* context) { - furi_assert(context); - WeatherStationApp* app = context; - uint8_t index = 0; - for(uint8_t i = 0; i < subghz_setting_get_preset_count(app->setting); i++) { - if(!strcmp(subghz_setting_get_preset_name(app->setting, i), preset_name)) { - index = i; - break; - } else { - // index = subghz_setting_get_frequency_default_index(app ->setting); - } - } - return index; -} - -uint8_t weather_station_scene_receiver_config_hopper_value_index( - const uint32_t value, - const uint32_t values[], - uint8_t values_count, - void* context) { - furi_assert(context); - UNUSED(values_count); - WeatherStationApp* app = context; - - if(value == values[0]) { - return 0; - } else { - variable_item_set_current_value_text( - (VariableItem*)scene_manager_get_scene_state( - app->scene_manager, WeatherStationSceneReceiverConfig), - " -----"); - return 1; - } -} - -static void weather_station_scene_receiver_config_set_frequency(VariableItem* item) { - WeatherStationApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - - if(app->txrx->hopper_state == WSHopperStateOFF) { - char text_buf[10] = {0}; - snprintf( - text_buf, - sizeof(text_buf), - "%lu.%02lu", - subghz_setting_get_frequency(app->setting, index) / 1000000, - (subghz_setting_get_frequency(app->setting, index) % 1000000) / 10000); - variable_item_set_current_value_text(item, text_buf); - app->txrx->preset->frequency = subghz_setting_get_frequency(app->setting, index); - } else { - variable_item_set_current_value_index( - item, subghz_setting_get_frequency_default_index(app->setting)); - } -} - -static void weather_station_scene_receiver_config_set_preset(VariableItem* item) { - WeatherStationApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text( - item, subghz_setting_get_preset_name(app->setting, index)); - ws_preset_init( - app, - subghz_setting_get_preset_name(app->setting, index), - app->txrx->preset->frequency, - subghz_setting_get_preset_data(app->setting, index), - subghz_setting_get_preset_data_size(app->setting, index)); -} - -static void weather_station_scene_receiver_config_set_hopping_running(VariableItem* item) { - WeatherStationApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - - variable_item_set_current_value_text(item, hopping_text[index]); - if(hopping_value[index] == WSHopperStateOFF) { - char text_buf[10] = {0}; - snprintf( - text_buf, - sizeof(text_buf), - "%lu.%02lu", - subghz_setting_get_default_frequency(app->setting) / 1000000, - (subghz_setting_get_default_frequency(app->setting) % 1000000) / 10000); - variable_item_set_current_value_text( - (VariableItem*)scene_manager_get_scene_state( - app->scene_manager, WeatherStationSceneReceiverConfig), - text_buf); - app->txrx->preset->frequency = subghz_setting_get_default_frequency(app->setting); - variable_item_set_current_value_index( - (VariableItem*)scene_manager_get_scene_state( - app->scene_manager, WeatherStationSceneReceiverConfig), - subghz_setting_get_frequency_default_index(app->setting)); - } else { - variable_item_set_current_value_text( - (VariableItem*)scene_manager_get_scene_state( - app->scene_manager, WeatherStationSceneReceiverConfig), - " -----"); - variable_item_set_current_value_index( - (VariableItem*)scene_manager_get_scene_state( - app->scene_manager, WeatherStationSceneReceiverConfig), - subghz_setting_get_frequency_default_index(app->setting)); - } - - app->txrx->hopper_state = hopping_value[index]; -} - -static void - weather_station_scene_receiver_config_var_list_enter_callback(void* context, uint32_t index) { - furi_assert(context); - WeatherStationApp* app = context; - if(index == WSSettingIndexLock) { - view_dispatcher_send_custom_event(app->view_dispatcher, WSCustomEventSceneSettingLock); - } -} - -void weather_station_scene_receiver_config_on_enter(void* context) { - WeatherStationApp* app = context; - VariableItem* item; - uint8_t value_index; - - item = variable_item_list_add( - app->variable_item_list, - "Frequency:", - subghz_setting_get_frequency_count(app->setting), - weather_station_scene_receiver_config_set_frequency, - app); - value_index = - weather_station_scene_receiver_config_next_frequency(app->txrx->preset->frequency, app); - scene_manager_set_scene_state( - app->scene_manager, WeatherStationSceneReceiverConfig, (uint32_t)item); - variable_item_set_current_value_index(item, value_index); - char text_buf[10] = {0}; - snprintf( - text_buf, - sizeof(text_buf), - "%lu.%02lu", - subghz_setting_get_frequency(app->setting, value_index) / 1000000, - (subghz_setting_get_frequency(app->setting, value_index) % 1000000) / 10000); - variable_item_set_current_value_text(item, text_buf); - - item = variable_item_list_add( - app->variable_item_list, - "Hopping:", - HOPPING_COUNT, - weather_station_scene_receiver_config_set_hopping_running, - app); - value_index = weather_station_scene_receiver_config_hopper_value_index( - app->txrx->hopper_state, hopping_value, HOPPING_COUNT, app); - variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, hopping_text[value_index]); - - item = variable_item_list_add( - app->variable_item_list, - "Modulation:", - subghz_setting_get_preset_count(app->setting), - weather_station_scene_receiver_config_set_preset, - app); - value_index = weather_station_scene_receiver_config_next_preset( - furi_string_get_cstr(app->txrx->preset->name), app); - variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text( - item, subghz_setting_get_preset_name(app->setting, value_index)); - - variable_item_list_add(app->variable_item_list, "Lock Keyboard", 1, NULL, NULL); - variable_item_list_set_enter_callback( - app->variable_item_list, - weather_station_scene_receiver_config_var_list_enter_callback, - app); - - view_dispatcher_switch_to_view(app->view_dispatcher, WeatherStationViewVariableItemList); -} - -bool weather_station_scene_receiver_config_on_event(void* context, SceneManagerEvent event) { - WeatherStationApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == WSCustomEventSceneSettingLock) { - app->lock = WSLockOn; - scene_manager_previous_scene(app->scene_manager); - consumed = true; - } - } - return consumed; -} - -void weather_station_scene_receiver_config_on_exit(void* context) { - WeatherStationApp* app = context; - variable_item_list_set_selected_item(app->variable_item_list, 0); - variable_item_list_reset(app->variable_item_list); -} diff --git a/applications/external/weather_station/scenes/weather_station_scene_receiver_info.c b/applications/external/weather_station/scenes/weather_station_scene_receiver_info.c deleted file mode 100644 index b26661be3..000000000 --- a/applications/external/weather_station/scenes/weather_station_scene_receiver_info.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "../weather_station_app_i.h" -#include "../views/weather_station_receiver.h" - -void weather_station_scene_receiver_info_callback(WSCustomEvent event, void* context) { - furi_assert(context); - WeatherStationApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -static void weather_station_scene_receiver_info_add_to_history_callback( - SubGhzReceiver* receiver, - SubGhzProtocolDecoderBase* decoder_base, - void* context) { - furi_assert(context); - WeatherStationApp* app = context; - - if(ws_history_add_to_history(app->txrx->history, decoder_base, app->txrx->preset) == - WSHistoryStateAddKeyUpdateData) { - ws_view_receiver_info_update( - app->ws_receiver_info, - ws_history_get_raw_data(app->txrx->history, app->txrx->idx_menu_chosen)); - subghz_receiver_reset(receiver); - - notification_message(app->notifications, &sequence_blink_green_10); - app->txrx->rx_key_state = WSRxKeyStateAddKey; - } -} - -void weather_station_scene_receiver_info_on_enter(void* context) { - WeatherStationApp* app = context; - - subghz_receiver_set_rx_callback( - app->txrx->receiver, weather_station_scene_receiver_info_add_to_history_callback, app); - ws_view_receiver_info_update( - app->ws_receiver_info, - ws_history_get_raw_data(app->txrx->history, app->txrx->idx_menu_chosen)); - view_dispatcher_switch_to_view(app->view_dispatcher, WeatherStationViewReceiverInfo); -} - -bool weather_station_scene_receiver_info_on_event(void* context, SceneManagerEvent event) { - WeatherStationApp* app = context; - bool consumed = false; - UNUSED(app); - UNUSED(event); - return consumed; -} - -void weather_station_scene_receiver_info_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/weather_station/scenes/weather_station_scene_start.c b/applications/external/weather_station/scenes/weather_station_scene_start.c deleted file mode 100644 index 56dd6fa86..000000000 --- a/applications/external/weather_station/scenes/weather_station_scene_start.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "../weather_station_app_i.h" - -typedef enum { - SubmenuIndexWeatherStationReceiver, - SubmenuIndexWeatherStationAbout, -} SubmenuIndex; - -void weather_station_scene_start_submenu_callback(void* context, uint32_t index) { - WeatherStationApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void weather_station_scene_start_on_enter(void* context) { - UNUSED(context); - WeatherStationApp* app = context; - Submenu* submenu = app->submenu; - - submenu_add_item( - submenu, - "Read Weather Station", - SubmenuIndexWeatherStationReceiver, - weather_station_scene_start_submenu_callback, - app); - submenu_add_item( - submenu, - "About", - SubmenuIndexWeatherStationAbout, - weather_station_scene_start_submenu_callback, - app); - - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(app->scene_manager, WeatherStationSceneStart)); - - view_dispatcher_switch_to_view(app->view_dispatcher, WeatherStationViewSubmenu); -} - -bool weather_station_scene_start_on_event(void* context, SceneManagerEvent event) { - WeatherStationApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexWeatherStationAbout) { - scene_manager_next_scene(app->scene_manager, WeatherStationSceneAbout); - consumed = true; - } else if(event.event == SubmenuIndexWeatherStationReceiver) { - scene_manager_next_scene(app->scene_manager, WeatherStationSceneReceiver); - consumed = true; - } - scene_manager_set_scene_state(app->scene_manager, WeatherStationSceneStart, event.event); - } - - return consumed; -} - -void weather_station_scene_start_on_exit(void* context) { - WeatherStationApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/external/weather_station/views/weather_station_receiver.c b/applications/external/weather_station/views/weather_station_receiver.c deleted file mode 100644 index 488ef022f..000000000 --- a/applications/external/weather_station/views/weather_station_receiver.c +++ /dev/null @@ -1,473 +0,0 @@ -#include "weather_station_receiver.h" -#include "../weather_station_app_i.h" -#include "weather_station_icons.h" -#include -#include - -#include -#include -#include - -#define FRAME_HEIGHT 12 -#define MAX_LEN_PX 112 -#define MENU_ITEMS 4u -#define UNLOCK_CNT 3 - -#define SUBGHZ_RAW_THRESHOLD_MIN -90.0f -typedef struct { - FuriString* item_str; - uint8_t type; -} WSReceiverMenuItem; - -ARRAY_DEF(WSReceiverMenuItemArray, WSReceiverMenuItem, M_POD_OPLIST) - -#define M_OPL_WSReceiverMenuItemArray_t() ARRAY_OPLIST(WSReceiverMenuItemArray, M_POD_OPLIST) - -struct WSReceiverHistory { - WSReceiverMenuItemArray_t data; -}; - -typedef struct WSReceiverHistory WSReceiverHistory; - -static const Icon* ReceiverItemIcons[] = { - [SubGhzProtocolTypeUnknown] = &I_Quest_7x8, - [SubGhzProtocolTypeStatic] = &I_Unlock_7x8, - [SubGhzProtocolTypeDynamic] = &I_Lock_7x8, - [SubGhzProtocolWeatherStation] = &I_station_icon, -}; - -typedef enum { - WSReceiverBarShowDefault, - WSReceiverBarShowLock, - WSReceiverBarShowToUnlockPress, - WSReceiverBarShowUnlock, -} WSReceiverBarShow; - -struct WSReceiver { - WSLock lock; - uint8_t lock_count; - FuriTimer* timer; - View* view; - WSReceiverCallback callback; - void* context; -}; - -typedef struct { - FuriString* frequency_str; - FuriString* preset_str; - FuriString* history_stat_str; - WSReceiverHistory* history; - uint16_t idx; - uint16_t list_offset; - uint16_t history_item; - WSReceiverBarShow bar_show; - uint8_t u_rssi; - bool external_redio; -} WSReceiverModel; - -void ws_view_receiver_set_rssi(WSReceiver* instance, float rssi) { - furi_assert(instance); - with_view_model( - instance->view, - WSReceiverModel * model, - { - if(rssi < SUBGHZ_RAW_THRESHOLD_MIN) { - model->u_rssi = 0; - } else { - model->u_rssi = (uint8_t)(rssi - SUBGHZ_RAW_THRESHOLD_MIN); - } - }, - true); -} - -void ws_view_receiver_set_lock(WSReceiver* ws_receiver, WSLock lock) { - furi_assert(ws_receiver); - ws_receiver->lock_count = 0; - if(lock == WSLockOn) { - ws_receiver->lock = lock; - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { model->bar_show = WSReceiverBarShowLock; }, - true); - furi_timer_start(ws_receiver->timer, pdMS_TO_TICKS(1000)); - } else { - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { model->bar_show = WSReceiverBarShowDefault; }, - true); - } -} - -void ws_view_receiver_set_callback( - WSReceiver* ws_receiver, - WSReceiverCallback callback, - void* context) { - furi_assert(ws_receiver); - furi_assert(callback); - ws_receiver->callback = callback; - ws_receiver->context = context; -} - -static void ws_view_receiver_update_offset(WSReceiver* ws_receiver) { - furi_assert(ws_receiver); - - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - size_t history_item = model->history_item; - uint16_t bounds = history_item > 3 ? 2 : history_item; - - if(history_item > 3 && model->idx >= (int16_t)(history_item - 1)) { - model->list_offset = model->idx - 3; - } else if(model->list_offset < model->idx - bounds) { - model->list_offset = - CLAMP(model->list_offset + 1, (int16_t)(history_item - bounds), 0); - } else if(model->list_offset > model->idx - bounds) { - model->list_offset = CLAMP(model->idx - 1, (int16_t)(history_item - bounds), 0); - } - }, - true); -} - -void ws_view_receiver_add_item_to_menu(WSReceiver* ws_receiver, const char* name, uint8_t type) { - furi_assert(ws_receiver); - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - WSReceiverMenuItem* item_menu = WSReceiverMenuItemArray_push_raw(model->history->data); - item_menu->item_str = furi_string_alloc_set(name); - item_menu->type = type; - if((model->idx == model->history_item - 1)) { - model->history_item++; - model->idx++; - } else { - model->history_item++; - } - }, - true); - ws_view_receiver_update_offset(ws_receiver); -} - -void ws_view_receiver_add_data_statusbar( - WSReceiver* ws_receiver, - const char* frequency_str, - const char* preset_str, - const char* history_stat_str, - bool external) { - furi_assert(ws_receiver); - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - furi_string_set_str(model->frequency_str, frequency_str); - furi_string_set_str(model->preset_str, preset_str); - furi_string_set_str(model->history_stat_str, history_stat_str); - model->external_redio = external; - }, - true); -} - -static void ws_view_receiver_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar) { - canvas_set_color(canvas, ColorBlack); - canvas_draw_box(canvas, 0, 0 + idx * FRAME_HEIGHT, scrollbar ? 122 : 127, FRAME_HEIGHT); - - canvas_set_color(canvas, ColorWhite); - canvas_draw_dot(canvas, 0, 0 + idx * FRAME_HEIGHT); - canvas_draw_dot(canvas, 1, 0 + idx * FRAME_HEIGHT); - canvas_draw_dot(canvas, 0, (0 + idx * FRAME_HEIGHT) + 1); - - canvas_draw_dot(canvas, 0, (0 + idx * FRAME_HEIGHT) + 11); - canvas_draw_dot(canvas, scrollbar ? 121 : 126, 0 + idx * FRAME_HEIGHT); - canvas_draw_dot(canvas, scrollbar ? 121 : 126, (0 + idx * FRAME_HEIGHT) + 11); -} - -static void ws_view_rssi_draw(Canvas* canvas, WSReceiverModel* model) { - for(uint8_t i = 1; i < model->u_rssi; i++) { - if(i % 5) { - canvas_draw_dot(canvas, 46 + i, 50); - canvas_draw_dot(canvas, 47 + i, 51); - canvas_draw_dot(canvas, 46 + i, 52); - } - } -} - -void ws_view_receiver_draw(Canvas* canvas, WSReceiverModel* model) { - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontSecondary); - - elements_button_left(canvas, "Config"); - - bool scrollbar = model->history_item > 4; - FuriString* str_buff; - str_buff = furi_string_alloc(); - - // bool ext_module = furi_hal_subghz_get_radio_type(); - - WSReceiverMenuItem* item_menu; - - for(size_t i = 0; i < MIN(model->history_item, MENU_ITEMS); ++i) { - size_t idx = CLAMP((uint16_t)(i + model->list_offset), model->history_item, 0); - item_menu = WSReceiverMenuItemArray_get(model->history->data, idx); - furi_string_set(str_buff, item_menu->item_str); - elements_string_fit_width(canvas, str_buff, scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX); - if(model->idx == idx) { - ws_view_receiver_draw_frame(canvas, i, scrollbar); - } else { - canvas_set_color(canvas, ColorBlack); - } - canvas_draw_icon(canvas, 4, 2 + i * FRAME_HEIGHT, ReceiverItemIcons[item_menu->type]); - canvas_draw_str(canvas, 14, 9 + i * FRAME_HEIGHT, furi_string_get_cstr(str_buff)); - furi_string_reset(str_buff); - } - if(scrollbar) { - elements_scrollbar_pos(canvas, 128, 0, 49, model->idx, model->history_item); - } - furi_string_free(str_buff); - - canvas_set_color(canvas, ColorBlack); - - if(model->history_item == 0) { - canvas_draw_icon( - canvas, 0, 0, model->external_redio ? &I_Fishing_123x52 : &I_Scanning_123x52); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 63, 46, "Scanning..."); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 44, 10, model->external_redio ? "Ext" : "Int"); - } - - // Draw RSSI - ws_view_rssi_draw(canvas, model); - - switch(model->bar_show) { - case WSReceiverBarShowLock: - canvas_draw_icon(canvas, 64, 55, &I_Lock_7x8); - canvas_draw_str(canvas, 74, 62, "Locked"); - break; - case WSReceiverBarShowToUnlockPress: - canvas_draw_str(canvas, 44, 62, furi_string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 79, 62, furi_string_get_cstr(model->preset_str)); - canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str)); - canvas_set_font(canvas, FontSecondary); - elements_bold_rounded_frame(canvas, 14, 8, 99, 48); - elements_multiline_text(canvas, 65, 26, "To unlock\npress:"); - canvas_draw_icon(canvas, 65, 42, &I_Pin_back_arrow_10x8); - canvas_draw_icon(canvas, 80, 42, &I_Pin_back_arrow_10x8); - canvas_draw_icon(canvas, 95, 42, &I_Pin_back_arrow_10x8); - canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42); - canvas_draw_dot(canvas, 17, 61); - break; - case WSReceiverBarShowUnlock: - canvas_draw_icon(canvas, 64, 55, &I_Unlock_7x8); - canvas_draw_str(canvas, 74, 62, "Unlocked"); - break; - default: - canvas_draw_str(canvas, 44, 62, furi_string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 79, 62, furi_string_get_cstr(model->preset_str)); - canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str)); - break; - } -} - -static void ws_view_receiver_timer_callback(void* context) { - furi_assert(context); - WSReceiver* ws_receiver = context; - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { model->bar_show = WSReceiverBarShowDefault; }, - true); - if(ws_receiver->lock_count < UNLOCK_CNT) { - ws_receiver->callback(WSCustomEventViewReceiverOffDisplay, ws_receiver->context); - } else { - ws_receiver->lock = WSLockOff; - ws_receiver->callback(WSCustomEventViewReceiverUnlock, ws_receiver->context); - } - ws_receiver->lock_count = 0; -} - -bool ws_view_receiver_input(InputEvent* event, void* context) { - furi_assert(context); - WSReceiver* ws_receiver = context; - - if(ws_receiver->lock == WSLockOn) { - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { model->bar_show = WSReceiverBarShowToUnlockPress; }, - true); - if(ws_receiver->lock_count == 0) { - furi_timer_start(ws_receiver->timer, pdMS_TO_TICKS(1000)); - } - if(event->key == InputKeyBack && event->type == InputTypeShort) { - ws_receiver->lock_count++; - } - if(ws_receiver->lock_count >= UNLOCK_CNT) { - ws_receiver->callback(WSCustomEventViewReceiverUnlock, ws_receiver->context); - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { model->bar_show = WSReceiverBarShowUnlock; }, - true); - ws_receiver->lock = WSLockOff; - furi_timer_start(ws_receiver->timer, pdMS_TO_TICKS(650)); - } - - return true; - } - - if(event->key == InputKeyBack && event->type == InputTypeShort) { - ws_receiver->callback(WSCustomEventViewReceiverBack, ws_receiver->context); - } else if( - event->key == InputKeyUp && - (event->type == InputTypeShort || event->type == InputTypeRepeat)) { - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - if(model->idx != 0) model->idx--; - }, - true); - } else if( - event->key == InputKeyDown && - (event->type == InputTypeShort || event->type == InputTypeRepeat)) { - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - if(model->history_item && model->idx != model->history_item - 1) model->idx++; - }, - true); - } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { - ws_receiver->callback(WSCustomEventViewReceiverConfig, ws_receiver->context); - } else if(event->key == InputKeyOk && event->type == InputTypeShort) { - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - if(model->history_item != 0) { - ws_receiver->callback(WSCustomEventViewReceiverOK, ws_receiver->context); - } - }, - false); - } - - ws_view_receiver_update_offset(ws_receiver); - - return true; -} - -void ws_view_receiver_enter(void* context) { - furi_assert(context); -} - -void ws_view_receiver_exit(void* context) { - furi_assert(context); - WSReceiver* ws_receiver = context; - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - furi_string_reset(model->frequency_str); - furi_string_reset(model->preset_str); - furi_string_reset(model->history_stat_str); - for - M_EACH(item_menu, model->history->data, WSReceiverMenuItemArray_t) { - furi_string_free(item_menu->item_str); - item_menu->type = 0; - } - WSReceiverMenuItemArray_reset(model->history->data); - model->idx = 0; - model->list_offset = 0; - model->history_item = 0; - }, - false); - furi_timer_stop(ws_receiver->timer); -} - -WSReceiver* ws_view_receiver_alloc() { - WSReceiver* ws_receiver = malloc(sizeof(WSReceiver)); - - // View allocation and configuration - ws_receiver->view = view_alloc(); - - ws_receiver->lock = WSLockOff; - ws_receiver->lock_count = 0; - view_allocate_model(ws_receiver->view, ViewModelTypeLocking, sizeof(WSReceiverModel)); - view_set_context(ws_receiver->view, ws_receiver); - view_set_draw_callback(ws_receiver->view, (ViewDrawCallback)ws_view_receiver_draw); - view_set_input_callback(ws_receiver->view, ws_view_receiver_input); - view_set_enter_callback(ws_receiver->view, ws_view_receiver_enter); - view_set_exit_callback(ws_receiver->view, ws_view_receiver_exit); - - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - model->frequency_str = furi_string_alloc(); - model->preset_str = furi_string_alloc(); - model->history_stat_str = furi_string_alloc(); - model->bar_show = WSReceiverBarShowDefault; - model->history = malloc(sizeof(WSReceiverHistory)); - model->external_redio = false; - WSReceiverMenuItemArray_init(model->history->data); - }, - true); - ws_receiver->timer = - furi_timer_alloc(ws_view_receiver_timer_callback, FuriTimerTypeOnce, ws_receiver); - return ws_receiver; -} - -void ws_view_receiver_free(WSReceiver* ws_receiver) { - furi_assert(ws_receiver); - - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - furi_string_free(model->frequency_str); - furi_string_free(model->preset_str); - furi_string_free(model->history_stat_str); - for - M_EACH(item_menu, model->history->data, WSReceiverMenuItemArray_t) { - furi_string_free(item_menu->item_str); - item_menu->type = 0; - } - WSReceiverMenuItemArray_clear(model->history->data); - free(model->history); - }, - false); - furi_timer_free(ws_receiver->timer); - view_free(ws_receiver->view); - free(ws_receiver); -} - -View* ws_view_receiver_get_view(WSReceiver* ws_receiver) { - furi_assert(ws_receiver); - return ws_receiver->view; -} - -uint16_t ws_view_receiver_get_idx_menu(WSReceiver* ws_receiver) { - furi_assert(ws_receiver); - uint32_t idx = 0; - with_view_model( - ws_receiver->view, WSReceiverModel * model, { idx = model->idx; }, false); - return idx; -} - -void ws_view_receiver_set_idx_menu(WSReceiver* ws_receiver, uint16_t idx) { - furi_assert(ws_receiver); - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - model->idx = idx; - if(model->idx > 2) model->list_offset = idx - 2; - }, - true); - ws_view_receiver_update_offset(ws_receiver); -} diff --git a/applications/external/weather_station/views/weather_station_receiver.h b/applications/external/weather_station/views/weather_station_receiver.h deleted file mode 100644 index ade61e2dc..000000000 --- a/applications/external/weather_station/views/weather_station_receiver.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include -#include "../helpers/weather_station_types.h" -#include "../helpers/weather_station_event.h" - -typedef struct WSReceiver WSReceiver; - -typedef void (*WSReceiverCallback)(WSCustomEvent event, void* context); - -void ws_view_receiver_set_rssi(WSReceiver* instance, float rssi); - -void ws_view_receiver_set_lock(WSReceiver* ws_receiver, WSLock keyboard); - -void ws_view_receiver_set_callback( - WSReceiver* ws_receiver, - WSReceiverCallback callback, - void* context); - -WSReceiver* ws_view_receiver_alloc(); - -void ws_view_receiver_free(WSReceiver* ws_receiver); - -View* ws_view_receiver_get_view(WSReceiver* ws_receiver); - -void ws_view_receiver_add_data_statusbar( - WSReceiver* ws_receiver, - const char* frequency_str, - const char* preset_str, - const char* history_stat_str, - bool external); - -void ws_view_receiver_add_item_to_menu(WSReceiver* ws_receiver, const char* name, uint8_t type); - -uint16_t ws_view_receiver_get_idx_menu(WSReceiver* ws_receiver); - -void ws_view_receiver_set_idx_menu(WSReceiver* ws_receiver, uint16_t idx); - -void ws_view_receiver_exit(void* context); diff --git a/applications/external/weather_station/views/weather_station_receiver_info.c b/applications/external/weather_station/views/weather_station_receiver_info.c deleted file mode 100644 index c58993a98..000000000 --- a/applications/external/weather_station/views/weather_station_receiver_info.c +++ /dev/null @@ -1,246 +0,0 @@ -#include "weather_station_receiver.h" -#include "../weather_station_app_i.h" -#include "weather_station_icons.h" -#include -#include "../protocols/ws_generic.h" -#include -#include -#include - -struct WSReceiverInfo { - View* view; - FuriTimer* timer; -}; - -typedef struct { - uint32_t curr_ts; - FuriString* protocol_name; - WSBlockGeneric* generic; -} WSReceiverInfoModel; - -void ws_view_receiver_info_update(WSReceiverInfo* ws_receiver_info, FlipperFormat* fff) { - furi_assert(ws_receiver_info); - furi_assert(fff); - - with_view_model( - ws_receiver_info->view, - WSReceiverInfoModel * model, - { - flipper_format_rewind(fff); - flipper_format_read_string(fff, "Protocol", model->protocol_name); - - ws_block_generic_deserialize(model->generic, fff); - - FuriHalRtcDateTime curr_dt; - furi_hal_rtc_get_datetime(&curr_dt); - model->curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt); - }, - true); -} - -void ws_view_receiver_info_draw(Canvas* canvas, WSReceiverInfoModel* model) { - char buffer[64]; - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontSecondary); - - snprintf( - buffer, - sizeof(buffer), - "%s %db", - furi_string_get_cstr(model->protocol_name), - model->generic->data_count_bit); - canvas_draw_str(canvas, 0, 8, buffer); - - if(model->generic->channel != WS_NO_CHANNEL) { - snprintf(buffer, sizeof(buffer), "Ch: %01d", model->generic->channel); - canvas_draw_str(canvas, 106, 8, buffer); - } - - if(model->generic->id != WS_NO_ID) { - snprintf(buffer, sizeof(buffer), "Sn: 0x%02lX", model->generic->id); - canvas_draw_str(canvas, 0, 20, buffer); - } - - if(model->generic->btn != WS_NO_BTN) { - snprintf(buffer, sizeof(buffer), "Btn: %01d", model->generic->btn); - canvas_draw_str(canvas, 57, 20, buffer); - } - - if(model->generic->battery_low != WS_NO_BATT) { - snprintf( - buffer, sizeof(buffer), "Batt: %s", (!model->generic->battery_low ? "ok" : "low")); - canvas_draw_str_aligned(canvas, 126, 17, AlignRight, AlignCenter, buffer); - } - - snprintf(buffer, sizeof(buffer), "Data: 0x%llX", model->generic->data); - canvas_draw_str(canvas, 0, 32, buffer); - - elements_bold_rounded_frame(canvas, 0, 38, 127, 25); - canvas_set_font(canvas, FontPrimary); - - if(!float_is_equal(model->generic->temp, WS_NO_TEMPERATURE)) { - canvas_draw_icon(canvas, 6, 43, &I_Therm_7x16); - - uint8_t temp_x1 = 0; - uint8_t temp_x2 = 0; - if(furi_hal_rtc_get_locale_units() == FuriHalRtcLocaleUnitsMetric) { - snprintf(buffer, sizeof(buffer), "%3.1f C", (double)model->generic->temp); - if(model->generic->temp < -9.0f) { - temp_x1 = 49; - temp_x2 = 40; - } else { - temp_x1 = 47; - temp_x2 = 38; - } - } else { - snprintf( - buffer, - sizeof(buffer), - "%3.1f F", - (double)locale_celsius_to_fahrenheit(model->generic->temp)); - if((model->generic->temp < -27.77f) || (model->generic->temp > 37.77f)) { - temp_x1 = 50; - temp_x2 = 42; - } else { - temp_x1 = 48; - temp_x2 = 40; - } - } - - canvas_draw_str_aligned(canvas, temp_x1, 47, AlignRight, AlignTop, buffer); - canvas_draw_circle(canvas, temp_x2, 46, 1); - } - - if(model->generic->humidity != WS_NO_HUMIDITY) { - canvas_draw_icon(canvas, 53, 44, &I_Humid_8x13); - snprintf(buffer, sizeof(buffer), "%d%%", model->generic->humidity); - canvas_draw_str(canvas, 64, 55, buffer); - } - - if((int)model->generic->timestamp > 0 && model->curr_ts) { - int ts_diff = (int)model->curr_ts - (int)model->generic->timestamp; - - canvas_draw_icon(canvas, 91, 46, &I_Timer_11x11); - - if(ts_diff > 60) { - int tmp_sec = ts_diff; - int cnt_min = 1; - for(int i = 1; tmp_sec > 60; i++) { - tmp_sec = tmp_sec - 60; - cnt_min = i; - } - - if(model->curr_ts % 2 == 0) { - canvas_draw_str_aligned(canvas, 105, 51, AlignLeft, AlignCenter, "Old"); - } else { - if(cnt_min >= 59) { - canvas_draw_str_aligned(canvas, 105, 51, AlignLeft, AlignCenter, "Old"); - } else { - snprintf(buffer, sizeof(buffer), "%dm", cnt_min); - canvas_draw_str_aligned(canvas, 114, 51, AlignCenter, AlignCenter, buffer); - } - } - - } else { - snprintf(buffer, sizeof(buffer), "%d", ts_diff); - canvas_draw_str_aligned(canvas, 112, 51, AlignCenter, AlignCenter, buffer); - } - } -} - -bool ws_view_receiver_info_input(InputEvent* event, void* context) { - furi_assert(context); - //WSReceiverInfo* ws_receiver_info = context; - - if(event->key == InputKeyBack) { - return false; - } - - return true; -} - -static void ws_view_receiver_info_enter(void* context) { - furi_assert(context); - WSReceiverInfo* ws_receiver_info = context; - - furi_timer_start(ws_receiver_info->timer, 1000); -} - -static void ws_view_receiver_info_exit(void* context) { - furi_assert(context); - WSReceiverInfo* ws_receiver_info = context; - - furi_timer_stop(ws_receiver_info->timer); - - with_view_model( - ws_receiver_info->view, - WSReceiverInfoModel * model, - { furi_string_reset(model->protocol_name); }, - false); -} - -static void ws_view_receiver_info_timer(void* context) { - WSReceiverInfo* ws_receiver_info = context; - // Force redraw - with_view_model( - ws_receiver_info->view, - WSReceiverInfoModel * model, - { - FuriHalRtcDateTime curr_dt; - furi_hal_rtc_get_datetime(&curr_dt); - model->curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt); - }, - true); -} - -WSReceiverInfo* ws_view_receiver_info_alloc() { - WSReceiverInfo* ws_receiver_info = malloc(sizeof(WSReceiverInfo)); - - // View allocation and configuration - ws_receiver_info->view = view_alloc(); - - view_allocate_model(ws_receiver_info->view, ViewModelTypeLocking, sizeof(WSReceiverInfoModel)); - view_set_context(ws_receiver_info->view, ws_receiver_info); - view_set_draw_callback(ws_receiver_info->view, (ViewDrawCallback)ws_view_receiver_info_draw); - view_set_input_callback(ws_receiver_info->view, ws_view_receiver_info_input); - view_set_enter_callback(ws_receiver_info->view, ws_view_receiver_info_enter); - view_set_exit_callback(ws_receiver_info->view, ws_view_receiver_info_exit); - - with_view_model( - ws_receiver_info->view, - WSReceiverInfoModel * model, - { - model->generic = malloc(sizeof(WSBlockGeneric)); - model->protocol_name = furi_string_alloc(); - }, - true); - - ws_receiver_info->timer = - furi_timer_alloc(ws_view_receiver_info_timer, FuriTimerTypePeriodic, ws_receiver_info); - - return ws_receiver_info; -} - -void ws_view_receiver_info_free(WSReceiverInfo* ws_receiver_info) { - furi_assert(ws_receiver_info); - - furi_timer_free(ws_receiver_info->timer); - - with_view_model( - ws_receiver_info->view, - WSReceiverInfoModel * model, - { - furi_string_free(model->protocol_name); - free(model->generic); - }, - false); - - view_free(ws_receiver_info->view); - free(ws_receiver_info); -} - -View* ws_view_receiver_info_get_view(WSReceiverInfo* ws_receiver_info) { - furi_assert(ws_receiver_info); - return ws_receiver_info->view; -} diff --git a/applications/external/weather_station/views/weather_station_receiver_info.h b/applications/external/weather_station/views/weather_station_receiver_info.h deleted file mode 100644 index 705434a23..000000000 --- a/applications/external/weather_station/views/weather_station_receiver_info.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include -#include "../helpers/weather_station_types.h" -#include "../helpers/weather_station_event.h" -#include - -typedef struct WSReceiverInfo WSReceiverInfo; - -void ws_view_receiver_info_update(WSReceiverInfo* ws_receiver_info, FlipperFormat* fff); - -WSReceiverInfo* ws_view_receiver_info_alloc(); - -void ws_view_receiver_info_free(WSReceiverInfo* ws_receiver_info); - -View* ws_view_receiver_info_get_view(WSReceiverInfo* ws_receiver_info); diff --git a/applications/external/weather_station/weather_station_10px.png b/applications/external/weather_station/weather_station_10px.png deleted file mode 100644 index 7d5cc318c369f583c531ca5e8846a9a498ec44b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V6Od#Ihk44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`0h7I;J!GcfQS24TkI`72U@f-asejv*Ssy?udP3<@01TYulb=@zZ(cJX(> z9E<0IiRH6?9buO;SoeAj)2m&2)(%T&iEpuE4*KbLE`4W{EU(#4ulkv@OZPmG6Pd23 R{2OQ -#include -#include "protocols/protocol_items.h" - -static bool weather_station_app_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - WeatherStationApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool weather_station_app_back_event_callback(void* context) { - furi_assert(context); - WeatherStationApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -static void weather_station_app_tick_event_callback(void* context) { - furi_assert(context); - WeatherStationApp* app = context; - scene_manager_handle_tick_event(app->scene_manager); -} - -WeatherStationApp* weather_station_app_alloc() { - WeatherStationApp* app = malloc(sizeof(WeatherStationApp)); - - // GUI - app->gui = furi_record_open(RECORD_GUI); - - // View Dispatcher - app->view_dispatcher = view_dispatcher_alloc(); - app->scene_manager = scene_manager_alloc(&weather_station_scene_handlers, app); - view_dispatcher_enable_queue(app->view_dispatcher); - - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - view_dispatcher_set_custom_event_callback( - app->view_dispatcher, weather_station_app_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, weather_station_app_back_event_callback); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, weather_station_app_tick_event_callback, 100); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - // Open Notification record - app->notifications = furi_record_open(RECORD_NOTIFICATION); - - // Variable Item List - app->variable_item_list = variable_item_list_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - WeatherStationViewVariableItemList, - variable_item_list_get_view(app->variable_item_list)); - - // SubMenu - app->submenu = submenu_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, WeatherStationViewSubmenu, submenu_get_view(app->submenu)); - - // Widget - app->widget = widget_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, WeatherStationViewWidget, widget_get_view(app->widget)); - - // Receiver - app->ws_receiver = ws_view_receiver_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - WeatherStationViewReceiver, - ws_view_receiver_get_view(app->ws_receiver)); - - // Receiver Info - app->ws_receiver_info = ws_view_receiver_info_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - WeatherStationViewReceiverInfo, - ws_view_receiver_info_get_view(app->ws_receiver_info)); - - //init setting - app->setting = subghz_setting_alloc(); - - //ToDo FIX file name setting - subghz_setting_load(app->setting, EXT_PATH("subghz/assets/setting_user")); - - //init Worker & Protocol & History - app->lock = WSLockOff; - app->txrx = malloc(sizeof(WeatherStationTxRx)); - app->txrx->preset = malloc(sizeof(SubGhzRadioPreset)); - app->txrx->preset->name = furi_string_alloc(); - ws_preset_init(app, "AM650", subghz_setting_get_default_frequency(app->setting), NULL, 0); - - app->txrx->hopper_state = WSHopperStateOFF; - app->txrx->history = ws_history_alloc(); - app->txrx->worker = subghz_worker_alloc(); - app->txrx->environment = subghz_environment_alloc(); - subghz_environment_set_protocol_registry( - app->txrx->environment, (void*)&weather_station_protocol_registry); - app->txrx->receiver = subghz_receiver_alloc_init(app->txrx->environment); - - subghz_devices_init(); - - app->txrx->radio_device = - radio_device_loader_set(app->txrx->radio_device, SubGhzRadioDeviceTypeExternalCC1101); - - subghz_devices_reset(app->txrx->radio_device); - subghz_devices_idle(app->txrx->radio_device); - - subghz_receiver_set_filter(app->txrx->receiver, SubGhzProtocolFlag_Decodable); - subghz_worker_set_overrun_callback( - app->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset); - subghz_worker_set_pair_callback( - app->txrx->worker, (SubGhzWorkerPairCallback)subghz_receiver_decode); - subghz_worker_set_context(app->txrx->worker, app->txrx->receiver); - - furi_hal_power_suppress_charge_enter(); - - scene_manager_next_scene(app->scene_manager, WeatherStationSceneStart); - - return app; -} - -void weather_station_app_free(WeatherStationApp* app) { - furi_assert(app); - - subghz_devices_sleep(app->txrx->radio_device); - radio_device_loader_end(app->txrx->radio_device); - - subghz_devices_deinit(); - - // Submenu - view_dispatcher_remove_view(app->view_dispatcher, WeatherStationViewSubmenu); - submenu_free(app->submenu); - - // Variable Item List - view_dispatcher_remove_view(app->view_dispatcher, WeatherStationViewVariableItemList); - variable_item_list_free(app->variable_item_list); - - // Widget - view_dispatcher_remove_view(app->view_dispatcher, WeatherStationViewWidget); - widget_free(app->widget); - - // Receiver - view_dispatcher_remove_view(app->view_dispatcher, WeatherStationViewReceiver); - ws_view_receiver_free(app->ws_receiver); - - // Receiver Info - view_dispatcher_remove_view(app->view_dispatcher, WeatherStationViewReceiverInfo); - ws_view_receiver_info_free(app->ws_receiver_info); - - //setting - subghz_setting_free(app->setting); - - //Worker & Protocol & History - subghz_receiver_free(app->txrx->receiver); - subghz_environment_free(app->txrx->environment); - ws_history_free(app->txrx->history); - subghz_worker_free(app->txrx->worker); - furi_string_free(app->txrx->preset->name); - free(app->txrx->preset); - free(app->txrx); - - // View dispatcher - view_dispatcher_free(app->view_dispatcher); - scene_manager_free(app->scene_manager); - - // Notifications - furi_record_close(RECORD_NOTIFICATION); - app->notifications = NULL; - - // Close records - furi_record_close(RECORD_GUI); - - furi_hal_power_suppress_charge_exit(); - - free(app); -} - -int32_t weather_station_app(void* p) { - UNUSED(p); - WeatherStationApp* weather_station_app = weather_station_app_alloc(); - - view_dispatcher_run(weather_station_app->view_dispatcher); - - weather_station_app_free(weather_station_app); - - return 0; -} diff --git a/applications/external/weather_station/weather_station_app_i.c b/applications/external/weather_station/weather_station_app_i.c deleted file mode 100644 index e98c61ee5..000000000 --- a/applications/external/weather_station/weather_station_app_i.c +++ /dev/null @@ -1,155 +0,0 @@ -#include "weather_station_app_i.h" - -#define TAG "WeatherStation" -#include - -void ws_preset_init( - void* context, - const char* preset_name, - uint32_t frequency, - uint8_t* preset_data, - size_t preset_data_size) { - furi_assert(context); - WeatherStationApp* app = context; - furi_string_set(app->txrx->preset->name, preset_name); - app->txrx->preset->frequency = frequency; - app->txrx->preset->data = preset_data; - app->txrx->preset->data_size = preset_data_size; -} - -bool ws_set_preset(WeatherStationApp* app, const char* preset) { - if(!strcmp(preset, "FuriHalSubGhzPresetOok270Async")) { - furi_string_set(app->txrx->preset->name, "AM270"); - } else if(!strcmp(preset, "FuriHalSubGhzPresetOok650Async")) { - furi_string_set(app->txrx->preset->name, "AM650"); - } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev238Async")) { - furi_string_set(app->txrx->preset->name, "FM238"); - } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev476Async")) { - furi_string_set(app->txrx->preset->name, "FM476"); - } else if(!strcmp(preset, "FuriHalSubGhzPresetCustom")) { - furi_string_set(app->txrx->preset->name, "CUSTOM"); - } else { - FURI_LOG_E(TAG, "Unknown preset"); - return false; - } - return true; -} - -void ws_get_frequency_modulation( - WeatherStationApp* app, - FuriString* frequency, - FuriString* modulation) { - furi_assert(app); - if(frequency != NULL) { - furi_string_printf( - frequency, - "%03ld.%02ld", - app->txrx->preset->frequency / 1000000 % 1000, - app->txrx->preset->frequency / 10000 % 100); - } - if(modulation != NULL) { - furi_string_printf(modulation, "%.2s", furi_string_get_cstr(app->txrx->preset->name)); - } -} - -void ws_begin(WeatherStationApp* app, uint8_t* preset_data) { - furi_assert(app); - subghz_devices_reset(app->txrx->radio_device); - subghz_devices_idle(app->txrx->radio_device); - subghz_devices_load_preset(app->txrx->radio_device, FuriHalSubGhzPresetCustom, preset_data); - app->txrx->txrx_state = WSTxRxStateIDLE; -} - -uint32_t ws_rx(WeatherStationApp* app, uint32_t frequency) { - furi_assert(app); - if(!subghz_devices_is_frequency_valid(app->txrx->radio_device, frequency)) { - furi_crash("WeatherStation: Incorrect RX frequency."); - } - furi_assert( - app->txrx->txrx_state != WSTxRxStateRx && app->txrx->txrx_state != WSTxRxStateSleep); - - subghz_devices_idle(app->txrx->radio_device); - uint32_t value = subghz_devices_set_frequency(app->txrx->radio_device, frequency); - subghz_devices_flush_rx(app->txrx->radio_device); - subghz_devices_set_rx(app->txrx->radio_device); - - subghz_devices_start_async_rx( - app->txrx->radio_device, subghz_worker_rx_callback, app->txrx->worker); - - subghz_worker_start(app->txrx->worker); - app->txrx->txrx_state = WSTxRxStateRx; - return value; -} - -void ws_idle(WeatherStationApp* app) { - furi_assert(app); - furi_assert(app->txrx->txrx_state != WSTxRxStateSleep); - subghz_devices_idle(app->txrx->radio_device); - app->txrx->txrx_state = WSTxRxStateIDLE; -} - -void ws_rx_end(WeatherStationApp* app) { - furi_assert(app); - furi_assert(app->txrx->txrx_state == WSTxRxStateRx); - if(subghz_worker_is_running(app->txrx->worker)) { - subghz_worker_stop(app->txrx->worker); - subghz_devices_stop_async_rx(app->txrx->radio_device); - } - subghz_devices_idle(app->txrx->radio_device); - app->txrx->txrx_state = WSTxRxStateIDLE; -} - -void ws_sleep(WeatherStationApp* app) { - furi_assert(app); - subghz_devices_sleep(app->txrx->radio_device); - app->txrx->txrx_state = WSTxRxStateSleep; -} - -void ws_hopper_update(WeatherStationApp* app) { - furi_assert(app); - - switch(app->txrx->hopper_state) { - case WSHopperStateOFF: - case WSHopperStatePause: - return; - case WSHopperStateRSSITimeOut: - if(app->txrx->hopper_timeout != 0) { - app->txrx->hopper_timeout--; - return; - } - break; - default: - break; - } - float rssi = -127.0f; - if(app->txrx->hopper_state != WSHopperStateRSSITimeOut) { - // See RSSI Calculation timings in CC1101 17.3 RSSI - rssi = subghz_devices_get_rssi(app->txrx->radio_device); - - // Stay if RSSI is high enough - if(rssi > -90.0f) { - app->txrx->hopper_timeout = 10; - app->txrx->hopper_state = WSHopperStateRSSITimeOut; - return; - } - } else { - app->txrx->hopper_state = WSHopperStateRunnig; - } - // Select next frequency - if(app->txrx->hopper_idx_frequency < - subghz_setting_get_hopper_frequency_count(app->setting) - 1) { - app->txrx->hopper_idx_frequency++; - } else { - app->txrx->hopper_idx_frequency = 0; - } - - if(app->txrx->txrx_state == WSTxRxStateRx) { - ws_rx_end(app); - }; - if(app->txrx->txrx_state == WSTxRxStateIDLE) { - subghz_receiver_reset(app->txrx->receiver); - app->txrx->preset->frequency = - subghz_setting_get_hopper_frequency(app->setting, app->txrx->hopper_idx_frequency); - ws_rx(app, app->txrx->preset->frequency); - } -} diff --git a/applications/external/weather_station/weather_station_app_i.h b/applications/external/weather_station/weather_station_app_i.h deleted file mode 100644 index 0950f5975..000000000 --- a/applications/external/weather_station/weather_station_app_i.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include "helpers/weather_station_types.h" - -#include "scenes/weather_station_scene.h" -#include -#include -#include -#include -#include -#include -#include -#include "views/weather_station_receiver.h" -#include "views/weather_station_receiver_info.h" -#include "weather_station_history.h" - -#include -#include -#include -#include -#include - -#include "helpers/radio_device_loader.h" - -typedef struct WeatherStationApp WeatherStationApp; - -struct WeatherStationTxRx { - SubGhzWorker* worker; - - const SubGhzDevice* radio_device; - SubGhzEnvironment* environment; - SubGhzReceiver* receiver; - SubGhzRadioPreset* preset; - WSHistory* history; - uint16_t idx_menu_chosen; - WSTxRxState txrx_state; - WSHopperState hopper_state; - uint8_t hopper_timeout; - uint8_t hopper_idx_frequency; - WSRxKeyState rx_key_state; -}; - -typedef struct WeatherStationTxRx WeatherStationTxRx; - -struct WeatherStationApp { - Gui* gui; - ViewDispatcher* view_dispatcher; - WeatherStationTxRx* txrx; - SceneManager* scene_manager; - NotificationApp* notifications; - VariableItemList* variable_item_list; - Submenu* submenu; - Widget* widget; - WSReceiver* ws_receiver; - WSReceiverInfo* ws_receiver_info; - WSLock lock; - SubGhzSetting* setting; -}; - -void ws_preset_init( - void* context, - const char* preset_name, - uint32_t frequency, - uint8_t* preset_data, - size_t preset_data_size); -bool ws_set_preset(WeatherStationApp* app, const char* preset); -void ws_get_frequency_modulation( - WeatherStationApp* app, - FuriString* frequency, - FuriString* modulation); -void ws_begin(WeatherStationApp* app, uint8_t* preset_data); -uint32_t ws_rx(WeatherStationApp* app, uint32_t frequency); -void ws_idle(WeatherStationApp* app); -void ws_rx_end(WeatherStationApp* app); -void ws_sleep(WeatherStationApp* app); -void ws_hopper_update(WeatherStationApp* app); diff --git a/applications/external/weather_station/weather_station_history.c b/applications/external/weather_station/weather_station_history.c deleted file mode 100644 index 9adff39c6..000000000 --- a/applications/external/weather_station/weather_station_history.c +++ /dev/null @@ -1,245 +0,0 @@ -#include "weather_station_history.h" -#include -#include -#include -#include "protocols/ws_generic.h" - -#include - -#define WS_HISTORY_MAX 50 -#define TAG "WSHistory" - -typedef struct { - FuriString* item_str; - FlipperFormat* flipper_string; - uint8_t type; - uint32_t id; - SubGhzRadioPreset* preset; -} WSHistoryItem; - -ARRAY_DEF(WSHistoryItemArray, WSHistoryItem, M_POD_OPLIST) - -#define M_OPL_WSHistoryItemArray_t() ARRAY_OPLIST(WSHistoryItemArray, M_POD_OPLIST) - -typedef struct { - WSHistoryItemArray_t data; -} WSHistoryStruct; - -struct WSHistory { - uint32_t last_update_timestamp; - uint16_t last_index_write; - uint8_t code_last_hash_data; - FuriString* tmp_string; - WSHistoryStruct* history; -}; - -WSHistory* ws_history_alloc(void) { - WSHistory* instance = malloc(sizeof(WSHistory)); - instance->tmp_string = furi_string_alloc(); - instance->history = malloc(sizeof(WSHistoryStruct)); - WSHistoryItemArray_init(instance->history->data); - return instance; -} - -void ws_history_free(WSHistory* instance) { - furi_assert(instance); - furi_string_free(instance->tmp_string); - for - M_EACH(item, instance->history->data, WSHistoryItemArray_t) { - furi_string_free(item->item_str); - furi_string_free(item->preset->name); - free(item->preset); - flipper_format_free(item->flipper_string); - item->type = 0; - } - WSHistoryItemArray_clear(instance->history->data); - free(instance->history); - free(instance); -} - -uint32_t ws_history_get_frequency(WSHistory* instance, uint16_t idx) { - furi_assert(instance); - WSHistoryItem* item = WSHistoryItemArray_get(instance->history->data, idx); - return item->preset->frequency; -} - -SubGhzRadioPreset* ws_history_get_radio_preset(WSHistory* instance, uint16_t idx) { - furi_assert(instance); - WSHistoryItem* item = WSHistoryItemArray_get(instance->history->data, idx); - return item->preset; -} - -const char* ws_history_get_preset(WSHistory* instance, uint16_t idx) { - furi_assert(instance); - WSHistoryItem* item = WSHistoryItemArray_get(instance->history->data, idx); - return furi_string_get_cstr(item->preset->name); -} - -void ws_history_reset(WSHistory* instance) { - furi_assert(instance); - furi_string_reset(instance->tmp_string); - for - M_EACH(item, instance->history->data, WSHistoryItemArray_t) { - furi_string_free(item->item_str); - furi_string_free(item->preset->name); - free(item->preset); - flipper_format_free(item->flipper_string); - item->type = 0; - } - WSHistoryItemArray_reset(instance->history->data); - instance->last_index_write = 0; - instance->code_last_hash_data = 0; -} - -uint16_t ws_history_get_item(WSHistory* instance) { - furi_assert(instance); - return instance->last_index_write; -} - -uint8_t ws_history_get_type_protocol(WSHistory* instance, uint16_t idx) { - furi_assert(instance); - WSHistoryItem* item = WSHistoryItemArray_get(instance->history->data, idx); - return item->type; -} - -const char* ws_history_get_protocol_name(WSHistory* instance, uint16_t idx) { - furi_assert(instance); - WSHistoryItem* item = WSHistoryItemArray_get(instance->history->data, idx); - flipper_format_rewind(item->flipper_string); - if(!flipper_format_read_string(item->flipper_string, "Protocol", instance->tmp_string)) { - FURI_LOG_E(TAG, "Missing Protocol"); - furi_string_reset(instance->tmp_string); - } - return furi_string_get_cstr(instance->tmp_string); -} - -FlipperFormat* ws_history_get_raw_data(WSHistory* instance, uint16_t idx) { - furi_assert(instance); - WSHistoryItem* item = WSHistoryItemArray_get(instance->history->data, idx); - if(item->flipper_string) { - return item->flipper_string; - } else { - return NULL; - } -} -bool ws_history_get_text_space_left(WSHistory* instance, FuriString* output) { - furi_assert(instance); - if(instance->last_index_write == WS_HISTORY_MAX) { - if(output != NULL) furi_string_printf(output, "Memory is FULL"); - return true; - } - if(output != NULL) - furi_string_printf(output, "%02u/%02u", instance->last_index_write, WS_HISTORY_MAX); - return false; -} - -void ws_history_get_text_item_menu(WSHistory* instance, FuriString* output, uint16_t idx) { - WSHistoryItem* item = WSHistoryItemArray_get(instance->history->data, idx); - furi_string_set(output, item->item_str); -} - -WSHistoryStateAddKey - ws_history_add_to_history(WSHistory* instance, void* context, SubGhzRadioPreset* preset) { - furi_assert(instance); - furi_assert(context); - - if(instance->last_index_write >= WS_HISTORY_MAX) return WSHistoryStateAddKeyOverflow; - - SubGhzProtocolDecoderBase* decoder_base = context; - if((instance->code_last_hash_data == - subghz_protocol_decoder_base_get_hash_data(decoder_base)) && - ((furi_get_tick() - instance->last_update_timestamp) < 500)) { - instance->last_update_timestamp = furi_get_tick(); - return WSHistoryStateAddKeyTimeOut; - } - - instance->code_last_hash_data = subghz_protocol_decoder_base_get_hash_data(decoder_base); - instance->last_update_timestamp = furi_get_tick(); - - FlipperFormat* fff = flipper_format_string_alloc(); - uint32_t id = 0; - subghz_protocol_decoder_base_serialize(decoder_base, fff, preset); - - do { - if(!flipper_format_rewind(fff)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_uint32(fff, "Id", (uint32_t*)&id, 1)) { - FURI_LOG_E(TAG, "Missing Id"); - break; - } - } while(false); - flipper_format_free(fff); - - //Update record if found - bool sensor_found = false; - for(size_t i = 0; i < WSHistoryItemArray_size(instance->history->data); i++) { - WSHistoryItem* item = WSHistoryItemArray_get(instance->history->data, i); - if(item->id == id) { - sensor_found = true; - Stream* flipper_string_stream = flipper_format_get_raw_stream(item->flipper_string); - stream_clean(flipper_string_stream); - subghz_protocol_decoder_base_serialize(decoder_base, item->flipper_string, preset); - return WSHistoryStateAddKeyUpdateData; - } - } - - // or add new record - if(!sensor_found) { //-V547 - WSHistoryItem* item = WSHistoryItemArray_push_raw(instance->history->data); - item->preset = malloc(sizeof(SubGhzRadioPreset)); - item->type = decoder_base->protocol->type; - item->preset->frequency = preset->frequency; - item->preset->name = furi_string_alloc(); - furi_string_set(item->preset->name, preset->name); - item->preset->data = preset->data; - item->preset->data_size = preset->data_size; - item->id = id; - - item->item_str = furi_string_alloc(); - item->flipper_string = flipper_format_string_alloc(); - subghz_protocol_decoder_base_serialize(decoder_base, item->flipper_string, preset); - - do { - if(!flipper_format_rewind(item->flipper_string)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_string( - item->flipper_string, "Protocol", instance->tmp_string)) { - FURI_LOG_E(TAG, "Missing Protocol"); - break; - } - - if(!flipper_format_rewind(item->flipper_string)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - uint8_t key_data[sizeof(uint64_t)] = {0}; - if(!flipper_format_read_hex(item->flipper_string, "Data", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Missing Data"); - break; - } - uint64_t data = 0; - for(uint8_t i = 0; i < sizeof(uint64_t); i++) { - data = (data << 8) | key_data[i]; - } - uint32_t temp_data = 0; - if(!flipper_format_read_uint32(item->flipper_string, "Ch", (uint32_t*)&temp_data, 1)) { - FURI_LOG_E(TAG, "Missing Channel"); - break; - } - if(temp_data != WS_NO_CHANNEL) { - furi_string_cat_printf(instance->tmp_string, " Ch:%X", (uint8_t)temp_data); - } - - furi_string_printf( - item->item_str, "%s %llX", furi_string_get_cstr(instance->tmp_string), data); - - } while(false); - instance->last_index_write++; - return WSHistoryStateAddKeyNewDada; - } - return WSHistoryStateAddKeyUnknown; -} diff --git a/applications/external/weather_station/weather_station_history.h b/applications/external/weather_station/weather_station_history.h deleted file mode 100644 index 11601fe79..000000000 --- a/applications/external/weather_station/weather_station_history.h +++ /dev/null @@ -1,112 +0,0 @@ - -#pragma once - -#include -#include -#include -#include -#include - -typedef struct WSHistory WSHistory; - -/** History state add key */ -typedef enum { - WSHistoryStateAddKeyUnknown, - WSHistoryStateAddKeyTimeOut, - WSHistoryStateAddKeyNewDada, - WSHistoryStateAddKeyUpdateData, - WSHistoryStateAddKeyOverflow, -} WSHistoryStateAddKey; - -/** Allocate WSHistory - * - * @return WSHistory* - */ -WSHistory* ws_history_alloc(void); - -/** Free WSHistory - * - * @param instance - WSHistory instance - */ -void ws_history_free(WSHistory* instance); - -/** Clear history - * - * @param instance - WSHistory instance - */ -void ws_history_reset(WSHistory* instance); - -/** Get frequency to history[idx] - * - * @param instance - WSHistory instance - * @param idx - record index - * @return frequency - frequency Hz - */ -uint32_t ws_history_get_frequency(WSHistory* instance, uint16_t idx); - -SubGhzRadioPreset* ws_history_get_radio_preset(WSHistory* instance, uint16_t idx); - -/** Get preset to history[idx] - * - * @param instance - WSHistory instance - * @param idx - record index - * @return preset - preset name - */ -const char* ws_history_get_preset(WSHistory* instance, uint16_t idx); - -/** Get history index write - * - * @param instance - WSHistory instance - * @return idx - current record index - */ -uint16_t ws_history_get_item(WSHistory* instance); - -/** Get type protocol to history[idx] - * - * @param instance - WSHistory instance - * @param idx - record index - * @return type - type protocol - */ -uint8_t ws_history_get_type_protocol(WSHistory* instance, uint16_t idx); - -/** Get name protocol to history[idx] - * - * @param instance - WSHistory instance - * @param idx - record index - * @return name - const char* name protocol - */ -const char* ws_history_get_protocol_name(WSHistory* instance, uint16_t idx); - -/** Get string item menu to history[idx] - * - * @param instance - WSHistory instance - * @param output - FuriString* output - * @param idx - record index - */ -void ws_history_get_text_item_menu(WSHistory* instance, FuriString* output, uint16_t idx); - -/** Get string the remaining number of records to history - * - * @param instance - WSHistory instance - * @param output - FuriString* output - * @return bool - is FUUL - */ -bool ws_history_get_text_space_left(WSHistory* instance, FuriString* output); - -/** Add protocol to history - * - * @param instance - WSHistory instance - * @param context - SubGhzProtocolCommon context - * @param preset - SubGhzRadioPreset preset - * @return WSHistoryStateAddKey; - */ -WSHistoryStateAddKey - ws_history_add_to_history(WSHistory* instance, void* context, SubGhzRadioPreset* preset); - -/** Get SubGhzProtocolCommonLoad to load into the protocol decoder bin data - * - * @param instance - WSHistory instance - * @param idx - record index - * @return SubGhzProtocolCommonLoad* - */ -FlipperFormat* ws_history_get_raw_data(WSHistory* instance, uint16_t idx); diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_config.c b/applications/main/subghz/scenes/subghz_scene_receiver_config.c index d09b63c4e..a5d9b1449 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_config.c @@ -11,6 +11,8 @@ enum SubGhzSettingIndex { SubGhzSettingIndexIgnoreStarline, SubGhzSettingIndexIgnoreCars, SubGhzSettingIndexIgnoreMagellan, + SubGhzSettingIndexIgnoreWeather, + SubGhzSettingIndexIgnoreTPMS, SubGhzSettingIndexIgnorePrinceton, SubGhzSettingIndexSound, SubGhzSettingIndexResetToDefault, @@ -274,6 +276,13 @@ static void subghz_scene_receiver_config_set_magellan(VariableItem* item) { subghz_scene_receiver_config_set_ignore_filter(item, SubGhzProtocolFlag_Magellan); } +static void subghz_scene_receiver_config_set_weather(VariableItem* item) { + subghz_scene_receiver_config_set_ignore_filter(item, SubGhzProtocolFlag_Weather); +} +static void subghz_scene_receiver_config_set_tpms(VariableItem* item) { + subghz_scene_receiver_config_set_ignore_filter(item, SubGhzProtocolFlag_TPMS); +} + static void subghz_scene_receiver_config_set_princeton(VariableItem* item) { subghz_scene_receiver_config_set_ignore_filter(item, SubGhzProtocolFlag_Princeton); } @@ -433,6 +442,30 @@ void subghz_scene_receiver_config_on_enter(void* context) { variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, combobox_text[value_index]); + item = variable_item_list_add( + subghz->variable_item_list, + "Ignore Weather:", + COMBO_BOX_COUNT, + subghz_scene_receiver_config_set_weather, + subghz); + + value_index = subghz_scene_receiver_config_ignore_filter_get_index( + subghz->ignore_filter, SubGhzProtocolFlag_Weather); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, combobox_text[value_index]); + + item = variable_item_list_add( + subghz->variable_item_list, + "Ignore TPMS:", + COMBO_BOX_COUNT, + subghz_scene_receiver_config_set_tpms, + subghz); + + value_index = subghz_scene_receiver_config_ignore_filter_get_index( + subghz->ignore_filter, SubGhzProtocolFlag_TPMS); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, combobox_text[value_index]); + item = variable_item_list_add( subghz->variable_item_list, "Ignore Princeton:", diff --git a/applications/external/weather_station/protocols/acurite_592txr.c b/lib/subghz/protocols/acurite_592txr.c similarity index 99% rename from applications/external/weather_station/protocols/acurite_592txr.c rename to lib/subghz/protocols/acurite_592txr.c index 874f6dd33..ec385fe9b 100644 --- a/applications/external/weather_station/protocols/acurite_592txr.c +++ b/lib/subghz/protocols/acurite_592txr.c @@ -84,7 +84,7 @@ const SubGhzProtocol ws_protocol_acurite_592txr = { .name = WS_PROTOCOL_ACURITE_592TXR_NAME, .type = SubGhzProtocolWeatherStation, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_acurite_592txr_decoder, .encoder = &ws_protocol_acurite_592txr_encoder, @@ -280,7 +280,7 @@ SubGhzProtocolStatus void ws_protocol_decoder_acurite_592txr_get_string(void* context, FuriString* output) { furi_assert(context); WSProtocolDecoderAcurite_592TXR* instance = context; - furi_string_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/applications/external/weather_station/protocols/acurite_592txr.h b/lib/subghz/protocols/acurite_592txr.h similarity index 100% rename from applications/external/weather_station/protocols/acurite_592txr.h rename to lib/subghz/protocols/acurite_592txr.h diff --git a/applications/external/weather_station/protocols/acurite_606tx.c b/lib/subghz/protocols/acurite_606tx.c similarity index 99% rename from applications/external/weather_station/protocols/acurite_606tx.c rename to lib/subghz/protocols/acurite_606tx.c index e0d405c66..12962683f 100644 --- a/applications/external/weather_station/protocols/acurite_606tx.c +++ b/lib/subghz/protocols/acurite_606tx.c @@ -69,7 +69,7 @@ const SubGhzProtocol ws_protocol_acurite_606tx = { .name = WS_PROTOCOL_ACURITE_606TX_NAME, .type = SubGhzProtocolWeatherStation, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_acurite_606tx_decoder, .encoder = &ws_protocol_acurite_606tx_encoder, @@ -221,7 +221,7 @@ SubGhzProtocolStatus void ws_protocol_decoder_acurite_606tx_get_string(void* context, FuriString* output) { furi_assert(context); WSProtocolDecoderAcurite_606TX* instance = context; - furi_string_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/applications/external/weather_station/protocols/acurite_606tx.h b/lib/subghz/protocols/acurite_606tx.h similarity index 100% rename from applications/external/weather_station/protocols/acurite_606tx.h rename to lib/subghz/protocols/acurite_606tx.h diff --git a/applications/external/weather_station/protocols/acurite_609txc.c b/lib/subghz/protocols/acurite_609txc.c similarity index 99% rename from applications/external/weather_station/protocols/acurite_609txc.c rename to lib/subghz/protocols/acurite_609txc.c index 853b78446..96bdaf7c2 100644 --- a/applications/external/weather_station/protocols/acurite_609txc.c +++ b/lib/subghz/protocols/acurite_609txc.c @@ -70,7 +70,7 @@ const SubGhzProtocol ws_protocol_acurite_609txc = { .name = WS_PROTOCOL_ACURITE_609TXC_NAME, .type = SubGhzProtocolWeatherStation, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_acurite_609txc_decoder, .encoder = &ws_protocol_acurite_609txc_encoder, @@ -221,7 +221,7 @@ SubGhzProtocolStatus void ws_protocol_decoder_acurite_609txc_get_string(void* context, FuriString* output) { furi_assert(context); WSProtocolDecoderAcurite_609TXC* instance = context; - furi_string_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/applications/external/weather_station/protocols/acurite_609txc.h b/lib/subghz/protocols/acurite_609txc.h similarity index 100% rename from applications/external/weather_station/protocols/acurite_609txc.h rename to lib/subghz/protocols/acurite_609txc.h diff --git a/applications/external/weather_station/protocols/ambient_weather.c b/lib/subghz/protocols/ambient_weather.c similarity index 99% rename from applications/external/weather_station/protocols/ambient_weather.c rename to lib/subghz/protocols/ambient_weather.c index 588a7f82a..23b528b17 100644 --- a/applications/external/weather_station/protocols/ambient_weather.c +++ b/lib/subghz/protocols/ambient_weather.c @@ -84,7 +84,7 @@ const SubGhzProtocol ws_protocol_ambient_weather = { .name = WS_PROTOCOL_AMBIENT_WEATHER_NAME, .type = SubGhzProtocolWeatherStation, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_ambient_weather_decoder, .encoder = &ws_protocol_ambient_weather_encoder, @@ -250,7 +250,7 @@ SubGhzProtocolStatus void ws_protocol_decoder_ambient_weather_get_string(void* context, FuriString* output) { furi_assert(context); WSProtocolDecoderAmbient_Weather* instance = context; - furi_string_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/applications/external/weather_station/protocols/ambient_weather.h b/lib/subghz/protocols/ambient_weather.h similarity index 100% rename from applications/external/weather_station/protocols/ambient_weather.h rename to lib/subghz/protocols/ambient_weather.h diff --git a/applications/external/weather_station/protocols/auriol_ahfl.c b/lib/subghz/protocols/auriol_ahfl.c similarity index 99% rename from applications/external/weather_station/protocols/auriol_ahfl.c rename to lib/subghz/protocols/auriol_ahfl.c index 80b89e380..6ae1c4e93 100644 --- a/applications/external/weather_station/protocols/auriol_ahfl.c +++ b/lib/subghz/protocols/auriol_ahfl.c @@ -81,7 +81,7 @@ const SubGhzProtocol ws_protocol_auriol_ahfl = { .name = WS_PROTOCOL_AURIOL_AHFL_NAME, .type = SubGhzProtocolWeatherStation, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_auriol_ahfl_decoder, .encoder = &ws_protocol_auriol_ahfl_encoder, @@ -236,7 +236,7 @@ SubGhzProtocolStatus void ws_protocol_decoder_auriol_ahfl_get_string(void* context, FuriString* output) { furi_assert(context); WSProtocolDecoderAuriol_AHFL* instance = context; - furi_string_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/applications/external/weather_station/protocols/auriol_ahfl.h b/lib/subghz/protocols/auriol_ahfl.h similarity index 100% rename from applications/external/weather_station/protocols/auriol_ahfl.h rename to lib/subghz/protocols/auriol_ahfl.h diff --git a/applications/external/weather_station/protocols/auriol_hg0601a.c b/lib/subghz/protocols/auriol_hg0601a.c similarity index 99% rename from applications/external/weather_station/protocols/auriol_hg0601a.c rename to lib/subghz/protocols/auriol_hg0601a.c index 813fe1526..3d3aacc0f 100644 --- a/applications/external/weather_station/protocols/auriol_hg0601a.c +++ b/lib/subghz/protocols/auriol_hg0601a.c @@ -80,7 +80,7 @@ const SubGhzProtocol ws_protocol_auriol_th = { .name = WS_PROTOCOL_AURIOL_TH_NAME, .type = SubGhzProtocolWeatherStation, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_auriol_th_decoder, .encoder = &ws_protocol_auriol_th_encoder, @@ -230,7 +230,7 @@ SubGhzProtocolStatus void ws_protocol_decoder_auriol_th_get_string(void* context, FuriString* output) { furi_assert(context); WSProtocolDecoderAuriol_TH* instance = context; - furi_string_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/applications/external/weather_station/protocols/auriol_hg0601a.h b/lib/subghz/protocols/auriol_hg0601a.h similarity index 100% rename from applications/external/weather_station/protocols/auriol_hg0601a.h rename to lib/subghz/protocols/auriol_hg0601a.h diff --git a/applications/external/weather_station/protocols/gt_wt_02.c b/lib/subghz/protocols/gt_wt_02.c similarity index 98% rename from applications/external/weather_station/protocols/gt_wt_02.c rename to lib/subghz/protocols/gt_wt_02.c index d333164b4..8e59e6219 100644 --- a/applications/external/weather_station/protocols/gt_wt_02.c +++ b/lib/subghz/protocols/gt_wt_02.c @@ -9,9 +9,9 @@ * GT-WT-02 sensor on 433.92MHz. * Example and frame description provided by https://github.com/ludwich66 * [01] {37} 34 00 ed 47 60 : 00110100 00000000 11101101 01000111 01100000 - * code, BatOK,not-man-send, Channel1, +23,7°C, 35% + * code, BatOK,not-man-send, Channel1, +23,7�C, 35% * [01] {37} 34 8f 87 15 90 : 00110100 10001111 10000111 00010101 10010000 - * code, BatOK,not-man-send, Channel1,-12,1°C, 10% + * code, BatOK,not-man-send, Channel1,-12,1�C, 10% * Humidity: * - the working range is 20-90 % * - if "LL" in display view it sends 10 % @@ -83,7 +83,7 @@ const SubGhzProtocol ws_protocol_gt_wt_02 = { .name = WS_PROTOCOL_GT_WT_02_NAME, .type = SubGhzProtocolWeatherStation, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_gt_wt_02_decoder, .encoder = &ws_protocol_gt_wt_02_encoder, @@ -237,7 +237,7 @@ SubGhzProtocolStatus void ws_protocol_decoder_gt_wt_02_get_string(void* context, FuriString* output) { furi_assert(context); WSProtocolDecoderGT_WT02* instance = context; - furi_string_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/applications/external/weather_station/protocols/gt_wt_02.h b/lib/subghz/protocols/gt_wt_02.h similarity index 100% rename from applications/external/weather_station/protocols/gt_wt_02.h rename to lib/subghz/protocols/gt_wt_02.h diff --git a/applications/external/weather_station/protocols/gt_wt_03.c b/lib/subghz/protocols/gt_wt_03.c similarity index 99% rename from applications/external/weather_station/protocols/gt_wt_03.c rename to lib/subghz/protocols/gt_wt_03.c index 30430b839..834df926c 100644 --- a/applications/external/weather_station/protocols/gt_wt_03.c +++ b/lib/subghz/protocols/gt_wt_03.c @@ -109,7 +109,7 @@ const SubGhzProtocol ws_protocol_gt_wt_03 = { .name = WS_PROTOCOL_GT_WT_03_NAME, .type = SubGhzProtocolWeatherStation, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_gt_wt_03_decoder, .encoder = &ws_protocol_gt_wt_03_encoder, @@ -312,7 +312,7 @@ SubGhzProtocolStatus void ws_protocol_decoder_gt_wt_03_get_string(void* context, FuriString* output) { furi_assert(context); WSProtocolDecoderGT_WT03* instance = context; - furi_string_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/applications/external/weather_station/protocols/gt_wt_03.h b/lib/subghz/protocols/gt_wt_03.h similarity index 100% rename from applications/external/weather_station/protocols/gt_wt_03.h rename to lib/subghz/protocols/gt_wt_03.h diff --git a/applications/external/weather_station/protocols/infactory.c b/lib/subghz/protocols/infactory.c similarity index 99% rename from applications/external/weather_station/protocols/infactory.c rename to lib/subghz/protocols/infactory.c index 4b0e6602a..32f93c067 100644 --- a/applications/external/weather_station/protocols/infactory.c +++ b/lib/subghz/protocols/infactory.c @@ -94,7 +94,7 @@ const SubGhzProtocol ws_protocol_infactory = { .name = WS_PROTOCOL_INFACTORY_NAME, .type = SubGhzProtocolWeatherStation, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_infactory_decoder, .encoder = &ws_protocol_infactory_encoder, @@ -268,7 +268,7 @@ SubGhzProtocolStatus void ws_protocol_decoder_infactory_get_string(void* context, FuriString* output) { furi_assert(context); WSProtocolDecoderInfactory* instance = context; - furi_string_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/applications/external/weather_station/protocols/infactory.h b/lib/subghz/protocols/infactory.h similarity index 100% rename from applications/external/weather_station/protocols/infactory.h rename to lib/subghz/protocols/infactory.h diff --git a/applications/external/weather_station/protocols/lacrosse_tx.c b/lib/subghz/protocols/lacrosse_tx.c similarity index 99% rename from applications/external/weather_station/protocols/lacrosse_tx.c rename to lib/subghz/protocols/lacrosse_tx.c index f4b850d76..fa1d7ebe4 100644 --- a/applications/external/weather_station/protocols/lacrosse_tx.c +++ b/lib/subghz/protocols/lacrosse_tx.c @@ -98,7 +98,7 @@ const SubGhzProtocol ws_protocol_lacrosse_tx = { .name = WS_PROTOCOL_LACROSSE_TX_NAME, .type = SubGhzProtocolWeatherStation, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_lacrosse_tx_decoder, .encoder = &ws_protocol_lacrosse_tx_encoder, @@ -301,7 +301,7 @@ SubGhzProtocolStatus void ws_protocol_decoder_lacrosse_tx_get_string(void* context, FuriString* output) { furi_assert(context); WSProtocolDecoderLaCrosse_TX* instance = context; - furi_string_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/applications/external/weather_station/protocols/lacrosse_tx.h b/lib/subghz/protocols/lacrosse_tx.h similarity index 100% rename from applications/external/weather_station/protocols/lacrosse_tx.h rename to lib/subghz/protocols/lacrosse_tx.h diff --git a/applications/external/weather_station/protocols/lacrosse_tx141thbv2.c b/lib/subghz/protocols/lacrosse_tx141thbv2.c similarity index 99% rename from applications/external/weather_station/protocols/lacrosse_tx141thbv2.c rename to lib/subghz/protocols/lacrosse_tx141thbv2.c index f2fddd40c..7b97289d6 100644 --- a/applications/external/weather_station/protocols/lacrosse_tx141thbv2.c +++ b/lib/subghz/protocols/lacrosse_tx141thbv2.c @@ -76,7 +76,7 @@ const SubGhzProtocol ws_protocol_lacrosse_tx141thbv2 = { .name = WS_PROTOCOL_LACROSSE_TX141THBV2_NAME, .type = SubGhzProtocolWeatherStation, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_lacrosse_tx141thbv2_decoder, .encoder = &ws_protocol_lacrosse_tx141thbv2_encoder, @@ -276,7 +276,7 @@ SubGhzProtocolStatus ws_protocol_decoder_lacrosse_tx141thbv2_deserialize( void ws_protocol_decoder_lacrosse_tx141thbv2_get_string(void* context, FuriString* output) { furi_assert(context); WSProtocolDecoderLaCrosse_TX141THBv2* instance = context; - furi_string_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/applications/external/weather_station/protocols/lacrosse_tx141thbv2.h b/lib/subghz/protocols/lacrosse_tx141thbv2.h similarity index 100% rename from applications/external/weather_station/protocols/lacrosse_tx141thbv2.h rename to lib/subghz/protocols/lacrosse_tx141thbv2.h diff --git a/applications/external/weather_station/protocols/nexus_th.c b/lib/subghz/protocols/nexus_th.c similarity index 99% rename from applications/external/weather_station/protocols/nexus_th.c rename to lib/subghz/protocols/nexus_th.c index 14ba8b273..2eacecead 100644 --- a/applications/external/weather_station/protocols/nexus_th.c +++ b/lib/subghz/protocols/nexus_th.c @@ -82,7 +82,7 @@ const SubGhzProtocol ws_protocol_nexus_th = { .name = WS_PROTOCOL_NEXUS_TH_NAME, .type = SubGhzProtocolWeatherStation, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_nexus_th_decoder, .encoder = &ws_protocol_nexus_th_encoder, @@ -236,7 +236,7 @@ SubGhzProtocolStatus void ws_protocol_decoder_nexus_th_get_string(void* context, FuriString* output) { furi_assert(context); WSProtocolDecoderNexus_TH* instance = context; - furi_string_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/applications/external/weather_station/protocols/nexus_th.h b/lib/subghz/protocols/nexus_th.h similarity index 100% rename from applications/external/weather_station/protocols/nexus_th.h rename to lib/subghz/protocols/nexus_th.h diff --git a/applications/external/weather_station/protocols/oregon2.c b/lib/subghz/protocols/oregon2.c similarity index 99% rename from applications/external/weather_station/protocols/oregon2.c rename to lib/subghz/protocols/oregon2.c index 313748ccf..c900fb8d0 100644 --- a/applications/external/weather_station/protocols/oregon2.c +++ b/lib/subghz/protocols/oregon2.c @@ -423,7 +423,8 @@ const SubGhzProtocolDecoder ws_protocol_oregon2_decoder = { const SubGhzProtocol ws_protocol_oregon2 = { .name = WS_PROTOCOL_OREGON2_NAME, .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | + SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_oregon2_decoder, }; diff --git a/applications/external/weather_station/protocols/oregon2.h b/lib/subghz/protocols/oregon2.h similarity index 100% rename from applications/external/weather_station/protocols/oregon2.h rename to lib/subghz/protocols/oregon2.h diff --git a/applications/external/weather_station/protocols/oregon3.c b/lib/subghz/protocols/oregon3.c similarity index 99% rename from applications/external/weather_station/protocols/oregon3.c rename to lib/subghz/protocols/oregon3.c index bd35c2fd5..94b1d4e3e 100644 --- a/applications/external/weather_station/protocols/oregon3.c +++ b/lib/subghz/protocols/oregon3.c @@ -359,7 +359,8 @@ const SubGhzProtocolDecoder ws_protocol_oregon3_decoder = { const SubGhzProtocol ws_protocol_oregon3 = { .name = WS_PROTOCOL_OREGON3_NAME, .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | + SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_oregon3_decoder, }; diff --git a/applications/external/weather_station/protocols/oregon3.h b/lib/subghz/protocols/oregon3.h similarity index 100% rename from applications/external/weather_station/protocols/oregon3.h rename to lib/subghz/protocols/oregon3.h diff --git a/applications/external/weather_station/protocols/oregon_v1.c b/lib/subghz/protocols/oregon_v1.c similarity index 98% rename from applications/external/weather_station/protocols/oregon_v1.c rename to lib/subghz/protocols/oregon_v1.c index 03215bbf5..7c3410d6e 100644 --- a/applications/external/weather_station/protocols/oregon_v1.c +++ b/lib/subghz/protocols/oregon_v1.c @@ -30,9 +30,9 @@ * - u: unknown; * - b: battery low; flag to indicate low battery voltage * - s: temperature sign - * - T: BCD, Temperature; in °C * 10 - * - t: BCD, Temperature; in °C * 1 - * - z: BCD, Temperature; in °C * 0.1 + * - T: BCD, Temperature; in �C * 10 + * - t: BCD, Temperature; in �C * 1 + * - z: BCD, Temperature; in �C * 0.1 * - c: Channel 00=CH1, 01=CH2, 10=CH3 * */ @@ -95,7 +95,7 @@ const SubGhzProtocol ws_protocol_oregon_v1 = { .name = WS_PROTOCOL_OREGON_V1_NAME, .type = SubGhzProtocolWeatherStation, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_oregon_v1_decoder, .encoder = &ws_protocol_oregon_v1_encoder, @@ -303,7 +303,7 @@ SubGhzProtocolStatus void ws_protocol_decoder_oregon_v1_get_string(void* context, FuriString* output) { furi_assert(context); WSProtocolDecoderOregon_V1* instance = context; - furi_string_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/applications/external/weather_station/protocols/oregon_v1.h b/lib/subghz/protocols/oregon_v1.h similarity index 100% rename from applications/external/weather_station/protocols/oregon_v1.h rename to lib/subghz/protocols/oregon_v1.h diff --git a/applications/external/pocsag_pager/protocols/pcsg_generic.c b/lib/subghz/protocols/pcsg_generic.c similarity index 99% rename from applications/external/pocsag_pager/protocols/pcsg_generic.c rename to lib/subghz/protocols/pcsg_generic.c index 5425fd512..99ff1f665 100644 --- a/applications/external/pocsag_pager/protocols/pcsg_generic.c +++ b/lib/subghz/protocols/pcsg_generic.c @@ -1,7 +1,6 @@ #include "pcsg_generic.h" #include #include -#include "../helpers/pocsag_pager_types.h" #define TAG "PCSGBlockGeneric" diff --git a/applications/external/pocsag_pager/protocols/pcsg_generic.h b/lib/subghz/protocols/pcsg_generic.h similarity index 93% rename from applications/external/pocsag_pager/protocols/pcsg_generic.h rename to lib/subghz/protocols/pcsg_generic.h index 126b54ffe..7db3100b5 100644 --- a/applications/external/pocsag_pager/protocols/pcsg_generic.h +++ b/lib/subghz/protocols/pcsg_generic.h @@ -13,6 +13,9 @@ extern "C" { #endif +#define PCSG_KEY_FILE_VERSION 1 +#define PCSG_KEY_FILE_TYPE "Flipper POCSAG Pager Key File" + typedef struct PCSGBlockGeneric PCSGBlockGeneric; struct PCSGBlockGeneric { diff --git a/applications/external/pocsag_pager/protocols/pocsag.c b/lib/subghz/protocols/pocsag.c similarity index 100% rename from applications/external/pocsag_pager/protocols/pocsag.c rename to lib/subghz/protocols/pocsag.c diff --git a/applications/external/pocsag_pager/protocols/pocsag.h b/lib/subghz/protocols/pocsag.h similarity index 100% rename from applications/external/pocsag_pager/protocols/pocsag.h rename to lib/subghz/protocols/pocsag.h diff --git a/lib/subghz/protocols/protocol_items.c b/lib/subghz/protocols/protocol_items.c index 74244c5ff..644f5f68e 100644 --- a/lib/subghz/protocols/protocol_items.c +++ b/lib/subghz/protocols/protocol_items.c @@ -42,6 +42,26 @@ const SubGhzProtocol* subghz_protocol_registry_items[] = { &subghz_protocol_dooya, &subghz_protocol_alutech_at_4n, &subghz_protocol_kinggates_stylo_4k, + &ws_protocol_infactory, + &ws_protocol_thermopro_tx4, + &ws_protocol_nexus_th, + &ws_protocol_gt_wt_02, + &ws_protocol_gt_wt_03, + &ws_protocol_acurite_606tx, + &ws_protocol_acurite_609txc, + &ws_protocol_lacrosse_tx, + &ws_protocol_lacrosse_tx141thbv2, + &ws_protocol_oregon2, + &ws_protocol_oregon3, + &ws_protocol_acurite_592txr, + &ws_protocol_ambient_weather, + &ws_protocol_auriol_th, + &ws_protocol_oregon_v1, + &ws_protocol_tx_8300, + &ws_protocol_wendox_w6726, + &ws_protocol_auriol_ahfl, + &subghz_protocol_pocsag, + &tpms_protocol_schrader_gg4, &subghz_protocol_bin_raw, }; diff --git a/lib/subghz/protocols/protocol_items.h b/lib/subghz/protocols/protocol_items.h index f1a28ac9b..74a4e4d6e 100644 --- a/lib/subghz/protocols/protocol_items.h +++ b/lib/subghz/protocols/protocol_items.h @@ -43,4 +43,24 @@ #include "dooya.h" #include "alutech_at_4n.h" #include "kinggates_stylo_4k.h" +#include "infactory.h" +#include "thermopro_tx4.h" +#include "nexus_th.h" +#include "gt_wt_02.h" +#include "gt_wt_03.h" +#include "acurite_606tx.h" +#include "acurite_609txc.h" +#include "lacrosse_tx.h" +#include "lacrosse_tx141thbv2.h" +#include "oregon2.h" +#include "oregon3.h" +#include "acurite_592txr.h" +#include "ambient_weather.h" +#include "auriol_hg0601a.h" +#include "oregon_v1.h" +#include "tx_8300.h" +#include "wendox_w6726.h" +#include "auriol_ahfl.h" +#include "pocsag.h" +#include "schrader_gg4.h" #include "bin_raw.h" diff --git a/lib/subghz/protocols/schrader_gg4.c b/lib/subghz/protocols/schrader_gg4.c new file mode 100644 index 000000000..627236aaa --- /dev/null +++ b/lib/subghz/protocols/schrader_gg4.c @@ -0,0 +1,295 @@ +#include "schrader_gg4.h" +#include + +#define TAG "Schrader" + +// https://github.com/merbanan/rtl_433/blob/master/src/devices/schraeder.c +// https://elib.dlr.de/81155/1/TPMS_for_Trafffic_Management_purposes.pdf +// https://github.com/furrtek/portapack-havoc/issues/349 +// https://fccid.io/MRXGG4 +// https://fccid.io/MRXGG4T + +/** + * Schrader 3013/3015 MRX-GG4 + +OEM: +KIA Sportage CGA 11-SPT1504-RA +Mercedes-Benz A0009054100 + +* Frequency: 433.92MHz+-38KHz +* Modulation: ASK +* Working Temperature: -50°C to 125°C +* Tire monitoring range value: 0kPa-350kPa+-7kPa + +Examples in normal environmental conditions: +3000878456094cd0 +3000878456084ecb +3000878456074d01 + +Data layout: + * | Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | Byte 7 | + * | --------- | --------- | --------- | --------- | --------- | --------- | --------- | --------- | + * | SSSS SSSS | IIII IIII | IIII IIII | IIII IIII | IIII IIII | PPPP PPPP | TTTT TTTT | CCCC CCCC | + * + +- The preamble is 0b000 +- S: always 0x30 in relearn state +- I: 32 bit ID +- P: 8 bit Pressure (multiplyed by 2.5 = PSI) +- T: 8 bit Temperature (deg. C offset by 50) +- C: 8 bit Checksum (CRC8, Poly 0x7, Init 0x0) +*/ + +#define PREAMBLE 0b000 +#define PREAMBLE_BITS_LEN 3 + +static const SubGhzBlockConst tpms_protocol_schrader_gg4_const = { + .te_short = 120, + .te_long = 240, + .te_delta = 55, // 50% of te_short due to poor sensitivity + .min_count_bit_for_found = 64, +}; + +struct TPMSProtocolDecoderSchraderGG4 { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + TPMSBlockGeneric generic; + + ManchesterState manchester_saved_state; + uint16_t header_count; +}; + +struct TPMSProtocolEncoderSchraderGG4 { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + TPMSBlockGeneric generic; +}; + +typedef enum { + SchraderGG4DecoderStepReset = 0, + SchraderGG4DecoderStepCheckPreamble, + SchraderGG4DecoderStepDecoderData, + SchraderGG4DecoderStepSaveDuration, + SchraderGG4DecoderStepCheckDuration, +} SchraderGG4DecoderStep; + +const SubGhzProtocolDecoder tpms_protocol_schrader_gg4_decoder = { + .alloc = tpms_protocol_decoder_schrader_gg4_alloc, + .free = tpms_protocol_decoder_schrader_gg4_free, + + .feed = tpms_protocol_decoder_schrader_gg4_feed, + .reset = tpms_protocol_decoder_schrader_gg4_reset, + + .get_hash_data = tpms_protocol_decoder_schrader_gg4_get_hash_data, + .serialize = tpms_protocol_decoder_schrader_gg4_serialize, + .deserialize = tpms_protocol_decoder_schrader_gg4_deserialize, + .get_string = tpms_protocol_decoder_schrader_gg4_get_string, +}; + +const SubGhzProtocolEncoder tpms_protocol_schrader_gg4_encoder = { + .alloc = NULL, + .free = NULL, + + .deserialize = NULL, + .stop = NULL, + .yield = NULL, +}; + +const SubGhzProtocol tpms_protocol_schrader_gg4 = { + .name = TPMS_PROTOCOL_SCHRADER_GG4_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_AM | + SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_TPMS, + + .decoder = &tpms_protocol_schrader_gg4_decoder, + .encoder = &tpms_protocol_schrader_gg4_encoder, +}; + +void* tpms_protocol_decoder_schrader_gg4_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + TPMSProtocolDecoderSchraderGG4* instance = malloc(sizeof(TPMSProtocolDecoderSchraderGG4)); + instance->base.protocol = &tpms_protocol_schrader_gg4; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void tpms_protocol_decoder_schrader_gg4_free(void* context) { + furi_assert(context); + TPMSProtocolDecoderSchraderGG4* instance = context; + free(instance); +} + +void tpms_protocol_decoder_schrader_gg4_reset(void* context) { + furi_assert(context); + TPMSProtocolDecoderSchraderGG4* instance = context; + instance->decoder.parser_step = SchraderGG4DecoderStepReset; +} + +static bool tpms_protocol_schrader_gg4_check_crc(TPMSProtocolDecoderSchraderGG4* instance) { + uint8_t msg[] = { + instance->decoder.decode_data >> 48, + instance->decoder.decode_data >> 40, + instance->decoder.decode_data >> 32, + instance->decoder.decode_data >> 24, + instance->decoder.decode_data >> 16, + instance->decoder.decode_data >> 8}; + + uint8_t crc = subghz_protocol_blocks_crc8(msg, 6, 0x7, 0); + return (crc == (instance->decoder.decode_data & 0xFF)); +} + +/** + * Analysis of received data + * @param instance Pointer to a TPMSBlockGeneric* instance + */ +static void tpms_protocol_schrader_gg4_analyze(TPMSBlockGeneric* instance) { + instance->id = instance->data >> 24; + + // TODO locate and fix + instance->battery_low = TPMS_NO_BATT; + + instance->temperature = ((instance->data >> 8) & 0xFF) - 50; + instance->pressure = ((instance->data >> 16) & 0xFF) * 2.5 * 0.069; +} + +static ManchesterEvent level_and_duration_to_event(bool level, uint32_t duration) { + bool is_long = false; + + if(DURATION_DIFF(duration, tpms_protocol_schrader_gg4_const.te_long) < + tpms_protocol_schrader_gg4_const.te_delta) { + is_long = true; + } else if( + DURATION_DIFF(duration, tpms_protocol_schrader_gg4_const.te_short) < + tpms_protocol_schrader_gg4_const.te_delta) { + is_long = false; + } else { + return ManchesterEventReset; + } + + if(level) + return is_long ? ManchesterEventLongHigh : ManchesterEventShortHigh; + else + return is_long ? ManchesterEventLongLow : ManchesterEventShortLow; +} + +void tpms_protocol_decoder_schrader_gg4_feed(void* context, bool level, uint32_t duration) { + furi_assert(context); + bool bit = false; + bool have_bit = false; + TPMSProtocolDecoderSchraderGG4* instance = context; + + // low-level bit sequence decoding + if(instance->decoder.parser_step != SchraderGG4DecoderStepReset) { + ManchesterEvent event = level_and_duration_to_event(level, duration); + + if(event == ManchesterEventReset) { + if((instance->decoder.parser_step == SchraderGG4DecoderStepDecoderData) && + instance->decoder.decode_count_bit) { + // FURI_LOG_D(TAG, "%d-%ld", level, duration); + FURI_LOG_D( + TAG, + "reset accumulated %d bits: %llx", + instance->decoder.decode_count_bit, + instance->decoder.decode_data); + } + + instance->decoder.parser_step = SchraderGG4DecoderStepReset; + } else { + have_bit = manchester_advance( + instance->manchester_saved_state, event, &instance->manchester_saved_state, &bit); + if(!have_bit) return; + + // Invert value, due to signal is Manchester II and decoder is Manchester I + bit = !bit; + } + } + + switch(instance->decoder.parser_step) { + case SchraderGG4DecoderStepReset: + // wait for start ~480us pulse + if((level) && (DURATION_DIFF(duration, tpms_protocol_schrader_gg4_const.te_long * 2) < + tpms_protocol_schrader_gg4_const.te_delta)) { + instance->decoder.parser_step = SchraderGG4DecoderStepCheckPreamble; + instance->header_count = 0; + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + + // First will be short space, so set correct initial state for machine + // https://clearwater.com.au/images/rc5/rc5-state-machine.gif + instance->manchester_saved_state = ManchesterStateStart1; + } + break; + case SchraderGG4DecoderStepCheckPreamble: + if(bit != 0) { + instance->decoder.parser_step = SchraderGG4DecoderStepReset; + break; + } + + instance->header_count++; + if(instance->header_count == PREAMBLE_BITS_LEN) + instance->decoder.parser_step = SchraderGG4DecoderStepDecoderData; + break; + + case SchraderGG4DecoderStepDecoderData: + subghz_protocol_blocks_add_bit(&instance->decoder, bit); + if(instance->decoder.decode_count_bit == + tpms_protocol_schrader_gg4_const.min_count_bit_for_found) { + FURI_LOG_D(TAG, "%016llx", instance->decoder.decode_data); + if(!tpms_protocol_schrader_gg4_check_crc(instance)) { + FURI_LOG_D(TAG, "CRC mismatch drop"); + } else { + instance->generic.data = instance->decoder.decode_data; + instance->generic.data_count_bit = instance->decoder.decode_count_bit; + tpms_protocol_schrader_gg4_analyze(&instance->generic); + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + } + instance->decoder.parser_step = SchraderGG4DecoderStepReset; + } + break; + } +} + +uint8_t tpms_protocol_decoder_schrader_gg4_get_hash_data(void* context) { + furi_assert(context); + TPMSProtocolDecoderSchraderGG4* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus tpms_protocol_decoder_schrader_gg4_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + TPMSProtocolDecoderSchraderGG4* instance = context; + return tpms_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + tpms_protocol_decoder_schrader_gg4_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + TPMSProtocolDecoderSchraderGG4* instance = context; + return tpms_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + tpms_protocol_schrader_gg4_const.min_count_bit_for_found); +} + +void tpms_protocol_decoder_schrader_gg4_get_string(void* context, FuriString* output) { + furi_assert(context); + TPMSProtocolDecoderSchraderGG4* instance = context; + furi_string_cat_printf( + output, + "%s\r\n" + "Id:0x%08lX\r\n" + "Bat:%d\r\n" + "Temp:%2.0f C Bar:%2.1f", + instance->generic.protocol_name, + instance->generic.id, + instance->generic.battery_low, + (double)instance->generic.temperature, + (double)instance->generic.pressure); +} diff --git a/lib/subghz/protocols/schrader_gg4.h b/lib/subghz/protocols/schrader_gg4.h new file mode 100644 index 000000000..29c2c7d00 --- /dev/null +++ b/lib/subghz/protocols/schrader_gg4.h @@ -0,0 +1,80 @@ +#pragma once + +#include + +#include +#include +#include +#include "tpms_generic.h" +#include + +#define TPMS_PROTOCOL_SCHRADER_GG4_NAME "Schrader GG4" + +typedef struct TPMSProtocolDecoderSchraderGG4 TPMSProtocolDecoderSchraderGG4; +typedef struct TPMSProtocolEncoderSchraderGG4 TPMSProtocolEncoderSchraderGG4; + +extern const SubGhzProtocolDecoder tpms_protocol_schrader_gg4_decoder; +extern const SubGhzProtocolEncoder tpms_protocol_schrader_gg4_encoder; +extern const SubGhzProtocol tpms_protocol_schrader_gg4; + +/** + * Allocate TPMSProtocolDecoderSchraderGG4. + * @param environment Pointer to a SubGhzEnvironment instance + * @return TPMSProtocolDecoderSchraderGG4* pointer to a TPMSProtocolDecoderSchraderGG4 instance + */ +void* tpms_protocol_decoder_schrader_gg4_alloc(SubGhzEnvironment* environment); + +/** + * Free TPMSProtocolDecoderSchraderGG4. + * @param context Pointer to a TPMSProtocolDecoderSchraderGG4 instance + */ +void tpms_protocol_decoder_schrader_gg4_free(void* context); + +/** + * Reset decoder TPMSProtocolDecoderSchraderGG4. + * @param context Pointer to a TPMSProtocolDecoderSchraderGG4 instance + */ +void tpms_protocol_decoder_schrader_gg4_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a TPMSProtocolDecoderSchraderGG4 instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void tpms_protocol_decoder_schrader_gg4_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a TPMSProtocolDecoderSchraderGG4 instance + * @return hash Hash sum + */ +uint8_t tpms_protocol_decoder_schrader_gg4_get_hash_data(void* context); + +/** + * Serialize data TPMSProtocolDecoderSchraderGG4. + * @param context Pointer to a TPMSProtocolDecoderSchraderGG4 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param preset The modulation on which the signal was received, SubGhzRadioPreset + * @return status + */ +SubGhzProtocolStatus tpms_protocol_decoder_schrader_gg4_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data TPMSProtocolDecoderSchraderGG4. + * @param context Pointer to a TPMSProtocolDecoderSchraderGG4 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + tpms_protocol_decoder_schrader_gg4_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a TPMSProtocolDecoderSchraderGG4 instance + * @param output Resulting text + */ +void tpms_protocol_decoder_schrader_gg4_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/thermopro_tx4.c b/lib/subghz/protocols/thermopro_tx4.c similarity index 99% rename from applications/external/weather_station/protocols/thermopro_tx4.c rename to lib/subghz/protocols/thermopro_tx4.c index 24e883e60..afcfbed51 100644 --- a/applications/external/weather_station/protocols/thermopro_tx4.c +++ b/lib/subghz/protocols/thermopro_tx4.c @@ -79,7 +79,7 @@ const SubGhzProtocol ws_protocol_thermopro_tx4 = { .name = WS_PROTOCOL_THERMOPRO_TX4_NAME, .type = SubGhzProtocolWeatherStation, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_thermopro_tx4_decoder, .encoder = &ws_protocol_thermopro_tx4_encoder, @@ -233,7 +233,7 @@ SubGhzProtocolStatus void ws_protocol_decoder_thermopro_tx4_get_string(void* context, FuriString* output) { furi_assert(context); WSProtocolDecoderThermoPRO_TX4* instance = context; - furi_string_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/applications/external/weather_station/protocols/thermopro_tx4.h b/lib/subghz/protocols/thermopro_tx4.h similarity index 100% rename from applications/external/weather_station/protocols/thermopro_tx4.h rename to lib/subghz/protocols/thermopro_tx4.h diff --git a/lib/subghz/protocols/tpms_generic.c b/lib/subghz/protocols/tpms_generic.c new file mode 100644 index 000000000..b6776c5a3 --- /dev/null +++ b/lib/subghz/protocols/tpms_generic.c @@ -0,0 +1,227 @@ +#include "tpms_generic.h" +#include +#include + +#define TAG "TPMSBlockGeneric" + +void tpms_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str) { + const char* preset_name_temp; + if(!strcmp(preset_name, "AM270")) { + preset_name_temp = "FuriHalSubGhzPresetOok270Async"; + } else if(!strcmp(preset_name, "AM650")) { + preset_name_temp = "FuriHalSubGhzPresetOok650Async"; + } else if(!strcmp(preset_name, "FM238")) { + preset_name_temp = "FuriHalSubGhzPreset2FSKDev238Async"; + } else if(!strcmp(preset_name, "FM476")) { + preset_name_temp = "FuriHalSubGhzPreset2FSKDev476Async"; + } else { + preset_name_temp = "FuriHalSubGhzPresetCustom"; + } + furi_string_set(preset_str, preset_name_temp); +} + +SubGhzProtocolStatus tpms_block_generic_serialize( + TPMSBlockGeneric* instance, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(instance); + SubGhzProtocolStatus res = SubGhzProtocolStatusError; + FuriString* temp_str; + temp_str = furi_string_alloc(); + do { + stream_clean(flipper_format_get_raw_stream(flipper_format)); + if(!flipper_format_write_header_cstr( + flipper_format, TPMS_KEY_FILE_TYPE, TPMS_KEY_FILE_VERSION)) { + FURI_LOG_E(TAG, "Unable to add header"); + res = SubGhzProtocolStatusErrorParserHeader; + break; + } + + if(!flipper_format_write_uint32(flipper_format, "Frequency", &preset->frequency, 1)) { + FURI_LOG_E(TAG, "Unable to add Frequency"); + res = SubGhzProtocolStatusErrorParserFrequency; + break; + } + + tpms_block_generic_get_preset_name(furi_string_get_cstr(preset->name), temp_str); + if(!flipper_format_write_string_cstr( + flipper_format, "Preset", furi_string_get_cstr(temp_str))) { + FURI_LOG_E(TAG, "Unable to add Preset"); + res = SubGhzProtocolStatusErrorParserPreset; + break; + } + if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { + if(!flipper_format_write_string_cstr( + flipper_format, "Custom_preset_module", "CC1101")) { + FURI_LOG_E(TAG, "Unable to add Custom_preset_module"); + res = SubGhzProtocolStatusErrorParserCustomPreset; + break; + } + if(!flipper_format_write_hex( + flipper_format, "Custom_preset_data", preset->data, preset->data_size)) { + FURI_LOG_E(TAG, "Unable to add Custom_preset_data"); + res = SubGhzProtocolStatusErrorParserCustomPreset; + break; + } + } + if(!flipper_format_write_string_cstr(flipper_format, "Protocol", instance->protocol_name)) { + FURI_LOG_E(TAG, "Unable to add Protocol"); + res = SubGhzProtocolStatusErrorParserProtocolName; + break; + } + + uint32_t temp_data = instance->id; + if(!flipper_format_write_uint32(flipper_format, "Id", &temp_data, 1)) { + FURI_LOG_E(TAG, "Unable to add Id"); + res = SubGhzProtocolStatusErrorParserOthers; + break; + } + + temp_data = instance->data_count_bit; + if(!flipper_format_write_uint32(flipper_format, "Bit", &temp_data, 1)) { + FURI_LOG_E(TAG, "Unable to add Bit"); + res = SubGhzProtocolStatusErrorParserBitCount; + break; + } + + uint8_t key_data[sizeof(uint64_t)] = {0}; + for(size_t i = 0; i < sizeof(uint64_t); i++) { + key_data[sizeof(uint64_t) - i - 1] = (instance->data >> (i * 8)) & 0xFF; + } + + if(!flipper_format_write_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) { + FURI_LOG_E(TAG, "Unable to add Data"); + res = SubGhzProtocolStatusErrorParserOthers; + break; + } + + temp_data = instance->battery_low; + if(!flipper_format_write_uint32(flipper_format, "Batt", &temp_data, 1)) { + FURI_LOG_E(TAG, "Unable to add Battery_low"); + res = SubGhzProtocolStatusErrorParserOthers; + break; + } + + float temp = instance->pressure; + if(!flipper_format_write_float(flipper_format, "Pressure", &temp, 1)) { + FURI_LOG_E(TAG, "Unable to add Pressure"); + res = SubGhzProtocolStatusErrorParserOthers; + break; + } + + //DATE AGE set + FuriHalRtcDateTime curr_dt; + furi_hal_rtc_get_datetime(&curr_dt); + uint32_t curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt); + + temp_data = curr_ts; + if(!flipper_format_write_uint32(flipper_format, "Ts", &temp_data, 1)) { + FURI_LOG_E(TAG, "Unable to add timestamp"); + res = SubGhzProtocolStatusErrorParserOthers; + break; + } + + temp = instance->temperature; + if(!flipper_format_write_float(flipper_format, "Temp", &temp, 1)) { + FURI_LOG_E(TAG, "Unable to add Temperature"); + res = SubGhzProtocolStatusErrorParserOthers; + break; + } + + res = SubGhzProtocolStatusOk; + } while(false); + furi_string_free(temp_str); + return res; +} + +SubGhzProtocolStatus + tpms_block_generic_deserialize(TPMSBlockGeneric* instance, FlipperFormat* flipper_format) { + furi_assert(instance); + SubGhzProtocolStatus res = SubGhzProtocolStatusError; + uint32_t temp_data = 0; + + do { + if(!flipper_format_rewind(flipper_format)) { + FURI_LOG_E(TAG, "Rewind error"); + res = SubGhzProtocolStatusErrorParserOthers; + break; + } + + if(!flipper_format_read_uint32(flipper_format, "Id", &temp_data, 1)) { + FURI_LOG_E(TAG, "Missing Id"); + res = SubGhzProtocolStatusErrorParserOthers; + break; + } + instance->id = temp_data; + + if(!flipper_format_read_uint32(flipper_format, "Bit", &temp_data, 1)) { + FURI_LOG_E(TAG, "Missing Bit"); + res = SubGhzProtocolStatusErrorParserBitCount; + break; + } + instance->data_count_bit = (uint8_t)temp_data; + + uint8_t key_data[sizeof(uint64_t)] = {0}; + if(!flipper_format_read_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) { + FURI_LOG_E(TAG, "Missing Data"); + res = SubGhzProtocolStatusErrorParserOthers; + break; + } + + for(uint8_t i = 0; i < sizeof(uint64_t); i++) { + instance->data = instance->data << 8 | key_data[i]; + } + + if(!flipper_format_read_uint32(flipper_format, "Batt", &temp_data, 1)) { + FURI_LOG_E(TAG, "Missing Battery_low"); + res = SubGhzProtocolStatusErrorParserOthers; + break; + } + instance->battery_low = (uint8_t)temp_data; + + float temp; + if(!flipper_format_read_float(flipper_format, "Pressure", &temp, 1)) { + FURI_LOG_E(TAG, "Missing Pressure"); + res = SubGhzProtocolStatusErrorParserOthers; + break; + } + instance->pressure = temp; + + if(!flipper_format_read_uint32(flipper_format, "Ts", &temp_data, 1)) { + FURI_LOG_E(TAG, "Missing timestamp"); + res = SubGhzProtocolStatusErrorParserOthers; + break; + } + instance->timestamp = temp_data; + + if(!flipper_format_read_float(flipper_format, "Temp", &temp, 1)) { + FURI_LOG_E(TAG, "Missing Temperature"); + res = SubGhzProtocolStatusErrorParserOthers; + break; + } + instance->temperature = temp; + + res = SubGhzProtocolStatusOk; + } while(0); + + return res; +} + +SubGhzProtocolStatus tpms_block_generic_deserialize_check_count_bit( + TPMSBlockGeneric* instance, + FlipperFormat* flipper_format, + uint16_t count_bit) { + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = tpms_block_generic_deserialize(instance, flipper_format); + if(ret != SubGhzProtocolStatusOk) { + break; + } + if(instance->data_count_bit != count_bit) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + ret = SubGhzProtocolStatusErrorValueBitCount; + break; + } + } while(false); + return ret; +} \ No newline at end of file diff --git a/lib/subghz/protocols/tpms_generic.h b/lib/subghz/protocols/tpms_generic.h new file mode 100644 index 000000000..3d52ee061 --- /dev/null +++ b/lib/subghz/protocols/tpms_generic.h @@ -0,0 +1,80 @@ +#pragma once + +#include +#include +#include + +#include +#include "furi.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define TPMS_KEY_FILE_VERSION 1 +#define TPMS_KEY_FILE_TYPE "Flipper Tire Pressure Monitoring System Key File" + +#define TPMS_NO_BATT 0xFF + +typedef struct TPMSBlockGeneric TPMSBlockGeneric; + +struct TPMSBlockGeneric { + const char* protocol_name; + uint64_t data; + uint8_t data_count_bit; + + uint32_t timestamp; + + uint32_t id; + uint8_t battery_low; + // bool storage; + float pressure; // bar + float temperature; // celsius +}; + +/** + * Get name preset. + * @param preset_name name preset + * @param preset_str Output name preset + */ +void tpms_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str); + +/** + * Serialize data TPMSBlockGeneric. + * @param instance Pointer to a TPMSBlockGeneric instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param preset The modulation on which the signal was received, SubGhzRadioPreset + * @return status + */ +SubGhzProtocolStatus tpms_block_generic_serialize( + TPMSBlockGeneric* instance, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data TPMSBlockGeneric. + * @param instance Pointer to a TPMSBlockGeneric instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + tpms_block_generic_deserialize(TPMSBlockGeneric* instance, FlipperFormat* flipper_format); + +/** + * Deserialize data TPMSBlockGeneric. + * @param instance Pointer to a TPMSBlockGeneric instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param count_bit Count bit protocol + * @return status + */ +SubGhzProtocolStatus tpms_block_generic_deserialize_check_count_bit( + TPMSBlockGeneric* instance, + FlipperFormat* flipper_format, + uint16_t count_bit); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/external/weather_station/protocols/tx_8300.c b/lib/subghz/protocols/tx_8300.c similarity index 99% rename from applications/external/weather_station/protocols/tx_8300.c rename to lib/subghz/protocols/tx_8300.c index 3a06ce49d..fbad1e291 100644 --- a/applications/external/weather_station/protocols/tx_8300.c +++ b/lib/subghz/protocols/tx_8300.c @@ -90,7 +90,7 @@ const SubGhzProtocol ws_protocol_tx_8300 = { .name = WS_PROTOCOL_TX_8300_NAME, .type = SubGhzProtocolWeatherStation, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_tx_8300_decoder, .encoder = &ws_protocol_tx_8300_encoder, @@ -266,7 +266,7 @@ SubGhzProtocolStatus void ws_protocol_decoder_tx_8300_get_string(void* context, FuriString* output) { furi_assert(context); WSProtocolDecoderTX_8300* instance = context; - furi_string_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/applications/external/weather_station/protocols/tx_8300.h b/lib/subghz/protocols/tx_8300.h similarity index 100% rename from applications/external/weather_station/protocols/tx_8300.h rename to lib/subghz/protocols/tx_8300.h diff --git a/applications/external/weather_station/protocols/wendox_w6726.c b/lib/subghz/protocols/wendox_w6726.c similarity index 99% rename from applications/external/weather_station/protocols/wendox_w6726.c rename to lib/subghz/protocols/wendox_w6726.c index 2fbe961f7..77c010000 100644 --- a/applications/external/weather_station/protocols/wendox_w6726.c +++ b/lib/subghz/protocols/wendox_w6726.c @@ -84,7 +84,7 @@ const SubGhzProtocol ws_protocol_wendox_w6726 = { .name = WS_PROTOCOL_WENDOX_W6726_NAME, .type = SubGhzProtocolWeatherStation, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Weather, .decoder = &ws_protocol_wendox_w6726_decoder, .encoder = &ws_protocol_wendox_w6726_encoder, @@ -281,7 +281,7 @@ SubGhzProtocolStatus void ws_protocol_decoder_wendox_w6726_get_string(void* context, FuriString* output) { furi_assert(context); WSProtocolDecoderWendoxW6726* instance = context; - furi_string_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/applications/external/weather_station/protocols/wendox_w6726.h b/lib/subghz/protocols/wendox_w6726.h similarity index 100% rename from applications/external/weather_station/protocols/wendox_w6726.h rename to lib/subghz/protocols/wendox_w6726.h diff --git a/applications/external/weather_station/protocols/ws_generic.c b/lib/subghz/protocols/ws_generic.c similarity index 99% rename from applications/external/weather_station/protocols/ws_generic.c rename to lib/subghz/protocols/ws_generic.c index 026856a9e..c3483dadd 100644 --- a/applications/external/weather_station/protocols/ws_generic.c +++ b/lib/subghz/protocols/ws_generic.c @@ -1,7 +1,7 @@ #include "ws_generic.h" #include #include -#include "../helpers/weather_station_types.h" +//#include "../helpers/weather_station_types.h" #define TAG "WSBlockGeneric" diff --git a/applications/external/weather_station/protocols/ws_generic.h b/lib/subghz/protocols/ws_generic.h similarity index 95% rename from applications/external/weather_station/protocols/ws_generic.h rename to lib/subghz/protocols/ws_generic.h index ff047fae6..e31d614ae 100644 --- a/applications/external/weather_station/protocols/ws_generic.h +++ b/lib/subghz/protocols/ws_generic.h @@ -21,6 +21,9 @@ extern "C" { #define WS_NO_BTN 0xFF #define WS_NO_TEMPERATURE -273.0f +#define WS_KEY_FILE_VERSION 1 +#define WS_KEY_FILE_TYPE "Flipper Weather Station Key File" + typedef struct WSBlockGeneric WSBlockGeneric; struct WSBlockGeneric { diff --git a/lib/subghz/types.h b/lib/subghz/types.h index 8999e1d54..8d3c403fd 100644 --- a/lib/subghz/types.h +++ b/lib/subghz/types.h @@ -129,6 +129,8 @@ typedef enum { SubGhzProtocolFlag_AutoAlarms = (1 << 12), SubGhzProtocolFlag_Magellan = (1 << 13), SubGhzProtocolFlag_Princeton = (1 << 14), + SubGhzProtocolFlag_Weather = (1 << 15), + SubGhzProtocolFlag_TPMS = (1 << 16), } SubGhzProtocolFlag; struct SubGhzProtocol {