SubGHz Remote: submodule

This commit is contained in:
gid9798 2023-08-29 13:37:15 +03:00
parent 5bd868665e
commit cb5c5c08f6
32 changed files with 280 additions and 20 deletions

4
.gitmodules vendored
View file

@ -38,3 +38,7 @@
[submodule "lib/stm32wb_copro"] [submodule "lib/stm32wb_copro"]
path = lib/stm32wb_copro path = lib/stm32wb_copro
url = https://github.com/flipperdevices/stm32wb_copro.git url = https://github.com/flipperdevices/stm32wb_copro.git
[submodule "subghz_remote"]
path = applications/main/subghz_remote
url = https://github.com/DarkFlippers/SubGHz_Remote
branch = ufw_main_app

View file

@ -0,0 +1,4 @@
dist/*
.vscode
.clang-format
.editorconfig

View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 DarkFlippers @gid9798 @xMasterX
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,17 +1,43 @@
# App(
# appid="subghz_remote_ofw",
# name="Sub-GHz Remote",
# apptype=FlipperAppType.EXTERNAL,
# entry_point="subghz_remote_app",
# requires=[
# "gui",
# "dialogs",
# ],
# stack_size=2 * 1024,
# targets=["f7"],
# fap_icon="icon.png",
# fap_author="gid9798 xMasterX",
# fap_description="SubGhz Remote, uses up to 5 .sub files",
# fap_category="Sub-GHz",
# fap_icon_assets="icons",
# fap_icon_assets_symbol="subghz_remote",
# fap_version="1.2",
# fap_weburl="https://github.com/DarkFlippers/SubGHz_Remote",
# )
App( App(
appid="subghz_remote", appid="subghz_remote",
name="Sub-GHz Remote", name="Sub-GHz Remote",
apptype=FlipperAppType.MENUEXTERNAL, apptype=FlipperAppType.MENUEXTERNAL,
entry_point="subghz_remote_app", entry_point="subghz_remote_app",
icon="A_SubGHzRemote_14", icon="A_SubGHzRemote_14",
order=11,
requires=[ requires=[
"gui", "gui",
"dialogs", "dialogs",
], ],
stack_size=2 * 1024, stack_size=2 * 1024,
order=11, targets=["f7"],
fap_libs=["assets",],
fap_icon="icon.png", fap_icon="icon.png",
fap_author="gid9798 xMasterX",
fap_description="SubGhz Remote, uses up to 5 .sub files", fap_description="SubGhz Remote, uses up to 5 .sub files",
fap_category="Sub-GHz", fap_category="Sub-GHz",
) fap_icon_assets="icons",
fap_icon_assets_symbol="subghz_remote",
fap_version="1.2",
fap_weburl="https://github.com/DarkFlippers/SubGHz_Remote",
)

View file

@ -0,0 +1,25 @@
## v1.2
- **Official FirmWare Support**
- Add warning screen on CustomFW
- The .sub file format may differ from the official one and may be broken
## v1.1
- **Was combined with a configuration plugin**
- Editing/Creating map file
- Support for starting arguments
## v1.0
**Initial implementation:**
- Transmission
- GUI
- All .sub files for which transfer is available are supported
- Signal types:
- Static
- Dynamic
- RAW
- BinRAW
*Custom modulations are not supported yet*
**Map File Format** - FlipperFormat .txt file

View file

@ -0,0 +1,24 @@
With this application, you can combine up to 5 .sub files into one remote, and use flipper as a remote with multiple buttons.
## What is "Map" Files?
"Map" is short for mapping
A Map Files is a .txt files that the application uses to store information about remotes
# How to use
## First screen
After launching the application, you will see the MAP file selection screen (file browser).
- Select map file or press "back" to go Main menu
## Main menu
- Open map file - switching to remote
- Select map file
- On remote screen, use the navigation buttons(D-pad) to send a signal
- Edit Map File - map file editor
- Select map file
- Up/Down - slot nafigation
- Ok - edit menu
- Left - preview/save
- New Map File - Creating a new map file
- Enter a name
- The rest is similar to map file editor
# About map file
Map file - FlipperFormat .txt file.
Stores custom names, and paths to used .sub files.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -48,4 +48,11 @@ typedef enum {
SubRemCustomEventSceneEditPreviewSaved, SubRemCustomEventSceneEditPreviewSaved,
SubRemCustomEventSceneNewName, SubRemCustomEventSceneNewName,
#ifdef FW_ORIGIN_Official
SubRemCustomEventSceneFwWarningExit,
SubRemCustomEventSceneFwWarningNext,
SubRemCustomEventSceneFwWarningContinue,
#endif
} SubRemCustomEvent; } SubRemCustomEvent;

View file

@ -149,7 +149,9 @@ SubRemLoadSubState subrem_sub_preset_load(
if(protocol->flag & SubGhzProtocolFlag_Send) { if(protocol->flag & SubGhzProtocolFlag_Send) {
if((protocol->type == SubGhzProtocolTypeStatic) || if((protocol->type == SubGhzProtocolTypeStatic) ||
(protocol->type == SubGhzProtocolTypeDynamic) || (protocol->type == SubGhzProtocolTypeDynamic) ||
#ifndef FW_ORIGIN_Official
(protocol->type == SubGhzProtocolTypeBinRAW) || (protocol->type == SubGhzProtocolTypeBinRAW) ||
#endif
(protocol->type == SubGhzProtocolTypeRAW)) { (protocol->type == SubGhzProtocolTypeRAW)) {
sub_preset->type = protocol->type; sub_preset->type = protocol->type;
} else { } else {

View file

@ -1,10 +1,12 @@
#include "subghz_txrx_i.h" #include "subghz_txrx_i.h"
#include <lib/subghz/protocols/protocol_items.h> #include <lib/subghz/subghz_protocol_registry.h>
#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h> #include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h> #include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
#ifndef FW_ORIGIN_Official
#include <lib/subghz/blocks/custom_btn.h> #include <lib/subghz/blocks/custom_btn.h>
#endif
#define TAG "SubGhz" #define TAG "SubGhz"
@ -657,12 +659,14 @@ bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance) {
return instance->debug_pin_state; return instance->debug_pin_state;
} }
#ifndef FW_ORIGIN_Official
void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance) { void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance) {
furi_assert(instance); furi_assert(instance);
subghz_environment_reset_keeloq(instance->environment); subghz_environment_reset_keeloq(instance->environment);
subghz_custom_btns_reset(); subghz_custom_btns_reset();
} }
#endif
SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance) { SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance) {
furi_assert(instance); furi_assert(instance);

View file

@ -369,7 +369,7 @@ bool subghz_txrx_radio_device_is_tx_allowed(SubGhzTxRx* instance, uint32_t frequ
void subghz_txrx_set_debug_pin_state(SubGhzTxRx* instance, bool state); void subghz_txrx_set_debug_pin_state(SubGhzTxRx* instance, bool state);
bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance); bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance);
#ifndef FW_ORIGIN_Official
void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance); void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance);
#endif
SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance); // TODO use only in DecodeRaw SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance); // TODO use only in DecodeRaw

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -6,4 +6,7 @@ ADD_SCENE(subrem, edit_submenu, EditSubMenu)
ADD_SCENE(subrem, edit_label, EditLabel) ADD_SCENE(subrem, edit_label, EditLabel)
ADD_SCENE(subrem, open_sub_file, OpenSubFile) ADD_SCENE(subrem, open_sub_file, OpenSubFile)
ADD_SCENE(subrem, edit_preview, EditPreview) ADD_SCENE(subrem, edit_preview, EditPreview)
ADD_SCENE(subrem, enter_new_name, EnterNewName) ADD_SCENE(subrem, enter_new_name, EnterNewName)
#ifdef FW_ORIGIN_Official
ADD_SCENE(subrem, fw_warning, FwWarning)
#endif

View file

@ -53,9 +53,9 @@ void subrem_scene_edit_label_on_enter(void* context) {
app->file_name_tmp, app->file_name_tmp,
25, 25,
false); false);
#ifndef FW_ORIGIN_Official
text_input_set_minimum_length(app->text_input, 0); text_input_set_minimum_length(app->text_input, 0);
#endif
widget_add_string_element( widget_add_string_element(
app->widget, 63, 12, AlignCenter, AlignCenter, FontPrimary, "Empty Label Name"); app->widget, 63, 12, AlignCenter, AlignCenter, FontPrimary, "Empty Label Name");
widget_add_string_element( widget_add_string_element(

View file

@ -0,0 +1,129 @@
#include "../subghz_remote_app_i.h"
#include "../helpers/subrem_custom_event.h"
#ifdef FW_ORIGIN_Official
typedef enum {
SceneFwWarningStateAttention,
SceneFwWarningStateAccept,
} SceneFwWarningState;
static void subrem_scene_fw_warning_widget_render(SubGhzRemoteApp* app, SceneFwWarningState state);
static void
subrem_scene_fw_warning_widget_callback(GuiButtonType result, InputType type, void* context) {
furi_assert(context);
SubGhzRemoteApp* app = context;
if(type == InputTypeShort) {
SubRemCustomEvent event = SubRemCustomEventSceneFwWarningExit;
switch(scene_manager_get_scene_state(app->scene_manager, SubRemSceneFwWarning)) {
case SceneFwWarningStateAttention:
if(result == GuiButtonTypeRight) {
event = SubRemCustomEventSceneFwWarningNext;
}
break;
case SceneFwWarningStateAccept:
if(result == GuiButtonTypeRight) {
event = SubRemCustomEventSceneFwWarningContinue;
}
break;
}
view_dispatcher_send_custom_event(app->view_dispatcher, event);
}
}
static void
subrem_scene_fw_warning_widget_render(SubGhzRemoteApp* app, SceneFwWarningState state) {
furi_assert(app);
Widget* widget = app->widget;
widget_reset(widget);
switch(state) {
case SceneFwWarningStateAttention:
widget_add_button_element(
widget, GuiButtonTypeLeft, "Exit", subrem_scene_fw_warning_widget_callback, app);
widget_add_button_element(
widget, GuiButtonTypeRight, "Continue", subrem_scene_fw_warning_widget_callback, app);
widget_add_string_element(
widget, 64, 12, AlignCenter, AlignBottom, FontPrimary, "Not official FW");
widget_add_string_multiline_element(
widget,
64,
32,
AlignCenter,
AlignCenter,
FontSecondary,
"You are using custom firmware\nPlease download a compatible\nversion of the application");
break;
case SceneFwWarningStateAccept:
widget_add_button_element(
widget, GuiButtonTypeLeft, "Exit", subrem_scene_fw_warning_widget_callback, app);
widget_add_button_element(
widget, GuiButtonTypeRight, "Accept", subrem_scene_fw_warning_widget_callback, app);
widget_add_string_element(
widget, 64, 12, AlignCenter, AlignBottom, FontPrimary, "Not official FW");
widget_add_string_multiline_element(
widget,
64,
32,
AlignCenter,
AlignCenter,
FontSecondary,
"Yes, I understand that\nthe application can\nbreak my subghz key file");
break;
}
}
void subrem_scene_fw_warning_on_enter(void* context) {
furi_assert(context);
SubGhzRemoteApp* app = context;
scene_manager_set_scene_state(
app->scene_manager, SubRemSceneFwWarning, SceneFwWarningStateAttention);
subrem_scene_fw_warning_widget_render(app, SceneFwWarningStateAttention);
view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDWidget);
}
bool subrem_scene_fw_warning_on_event(void* context, SceneManagerEvent event) {
furi_assert(context);
SubGhzRemoteApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeBack) {
consumed = true;
} else if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubRemCustomEventSceneFwWarningExit) {
scene_manager_stop(app->scene_manager);
view_dispatcher_stop(app->view_dispatcher);
consumed = true;
} else if(event.event == SubRemCustomEventSceneFwWarningNext) {
scene_manager_set_scene_state(
app->scene_manager, SubRemSceneFwWarning, SceneFwWarningStateAccept);
subrem_scene_fw_warning_widget_render(app, SceneFwWarningStateAccept);
view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDWidget);
consumed = true;
} else if(event.event == SubRemCustomEventSceneFwWarningContinue) {
scene_manager_previous_scene(app->scene_manager);
consumed = true;
}
}
return consumed;
}
void subrem_scene_fw_warning_on_exit(void* context) {
furi_assert(context);
SubGhzRemoteApp* app = context;
widget_reset(app->widget);
}
#endif

View file

@ -1,4 +1,5 @@
#include "subghz_remote_app_i.h" #include "subghz_remote_app_i.h"
#include <lib/toolbox/version.h>
static bool subghz_remote_app_custom_event_callback(void* context, uint32_t event) { static bool subghz_remote_app_custom_event_callback(void* context, uint32_t event) {
furi_assert(context); furi_assert(context);
@ -174,7 +175,9 @@ int32_t subghz_remote_app(void* arg) {
subghz_remote_make_app_folder(subghz_remote_app); subghz_remote_make_app_folder(subghz_remote_app);
bool map_loaded = false; bool map_loaded = false;
#ifdef FW_ORIGIN_Official
const bool fw_ofw = strcmp(version_get_firmware_origin(version_get()), "Official") == 0;
#endif
if((arg != NULL) && (strlen(arg) != 0)) { if((arg != NULL) && (strlen(arg) != 0)) {
furi_string_set(subghz_remote_app->file_path, (const char*)arg); furi_string_set(subghz_remote_app->file_path, (const char*)arg);
SubRemLoadMapState load_state = subrem_map_file_load( SubRemLoadMapState load_state = subrem_map_file_load(
@ -193,8 +196,19 @@ int32_t subghz_remote_app(void* arg) {
} else { } else {
furi_string_set(subghz_remote_app->file_path, SUBREM_APP_FOLDER); furi_string_set(subghz_remote_app->file_path, SUBREM_APP_FOLDER);
scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneStart); scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneStart);
#ifdef FW_ORIGIN_Official
if(fw_ofw) {
scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneOpenMapFile);
}
}
if(!fw_ofw) {
scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneFwWarning);
}
#else
scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneOpenMapFile); scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneOpenMapFile);
} }
#endif
view_dispatcher_run(subghz_remote_app->view_dispatcher); view_dispatcher_run(subghz_remote_app->view_dispatcher);

View file

@ -3,12 +3,9 @@
#include <flipper_format/flipper_format_i.h> #include <flipper_format/flipper_format_i.h>
#include "helpers/txrx/subghz_txrx.h" #include "helpers/txrx/subghz_txrx.h"
#ifndef FW_ORIGIN_Official
// #include <lib/subghz/protocols/keeloq.h>
// #include <lib/subghz/protocols/star_line.h>
#include <lib/subghz/protocols/protocol_items.h>
#include <lib/subghz/blocks/custom_btn.h> #include <lib/subghz/blocks/custom_btn.h>
#endif
#define TAG "SubGhzRemote" #define TAG "SubGhzRemote"
@ -225,9 +222,9 @@ bool subrem_tx_start_sub(SubGhzRemoteApp* app, SubRemSubFilePreset* sub_preset)
sub_preset->freq_preset.frequency, sub_preset->freq_preset.frequency,
NULL, NULL,
0); 0);
#ifndef FW_ORIGIN_Official
subghz_custom_btns_reset(); subghz_custom_btns_reset();
#endif
if(subghz_txrx_tx_start(app->txrx, sub_preset->fff_data) == SubGhzTxRxStartTxStateOk) { if(subghz_txrx_tx_start(app->txrx, sub_preset->fff_data) == SubGhzTxRxStartTxStateOk) {
ret = true; ret = true;
} }
@ -242,12 +239,12 @@ bool subrem_tx_stop_sub(SubGhzRemoteApp* app, bool forced) {
if(forced || (sub_preset->type != SubGhzProtocolTypeRAW)) { if(forced || (sub_preset->type != SubGhzProtocolTypeRAW)) {
subghz_txrx_stop(app->txrx); subghz_txrx_stop(app->txrx);
#ifndef FW_ORIGIN_Official
if(sub_preset->type == SubGhzProtocolTypeDynamic) { if(sub_preset->type == SubGhzProtocolTypeDynamic) {
subghz_txrx_reset_dynamic_and_custom_btns(app->txrx); subghz_txrx_reset_dynamic_and_custom_btns(app->txrx);
} }
subghz_custom_btns_reset(); subghz_custom_btns_reset();
#endif
return true; return true;
} }

View file

@ -6,7 +6,7 @@
#include "helpers/txrx/subghz_txrx.h" #include "helpers/txrx/subghz_txrx.h"
#include <assets_icons.h> #include "subghz_remote_icons.h"
#include "views/remote.h" #include "views/remote.h"
#include "views/edit_menu.h" #include "views/edit_menu.h"