mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 04:34:43 +04:00
Merge branch 'dev' into release
This commit is contained in:
21
CHANGELOG.md
21
CHANGELOG.md
@@ -1,18 +1,11 @@
|
||||
### New changes
|
||||
* If you have copied apps into `apps` folder - remove `apps` folder on your microSD before installing this release to avoid issues!
|
||||
* Dev Builds: Add extra pack dev branch to avoid "bug" reports with `API mismatch`
|
||||
* App Loader: Add option to ignore api mismatch (warning! some apps WILL not work, please update them to avoid any issues) -> (by @Willy-JL | PR #395)
|
||||
* SubGHz: Add manually -> GSN protocol support
|
||||
* SubGHz: Add 318 and 418 MHz back to hopping list
|
||||
* SubGHz: Fix hopper stuck at 433.42 due to wide range signals -
|
||||
When we using 433.92 remote flipper in hopping mode will stuck at 433.42 and may loose signal because of that, need to avoid using close freqs in hopping, only freqs with bigger difference like 310 -> 315
|
||||
* Plugins: Update **TOTP (Authenticator)** [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator) -> BadBT Support
|
||||
* OFW: Screen streaming improvements
|
||||
* OFW: 1-Wire Overdrive Mode -> **Breaking API change, api was changed from 19.x to 20.x**
|
||||
* OFW: Disable UART IRQs by default
|
||||
* OFW: BadUSB: implement boot protocol
|
||||
* OFW: Remove hmac_sha256 from public API -> **Breaking API change, api was changed from 18.x to 19.x**
|
||||
**(this will make your manually copied plugins not work, update them in same way you installed them, or delete `apps` folder and then install firmware, if you using extra pack builds (with `e` in version) all apps in _Extra will be updated automatically)**
|
||||
* SubGHz: AN-Motors AT4 + Alutech AT4N - Add Manually support
|
||||
* SubGHz: Aprimatic keeloq emulation support + Add Manually
|
||||
* NFC: MF Classic User Dict -> Fix deleting of the key in extra actions menu
|
||||
* Plugins: Update WiFi Marauder [(by 0xchocolate)](https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion)
|
||||
* Plugins: Fix POCSAG pager `RIC:` text repetition and overlap (by @Willy-JL | PR #398)
|
||||
* OFW: NFC: MF Classic - Additional checks before invalidating the key (Fixes issues with not using MF keys from user dict)
|
||||
* OFW: Fix crash when emulating a DSGeneric key
|
||||
|
||||
#### [🎲 Download latest extra apps pack](https://github.com/xMasterX/all-the-plugins/archive/refs/heads/main.zip)
|
||||
|
||||
|
||||
11
ReadMe.md
11
ReadMe.md
@@ -52,9 +52,9 @@ Our Discord Community:
|
||||
- Sub-GHz -> Press OK in frequency analyzer to use detected frequency in Read modes [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/77)
|
||||
- Sub-GHz -> Long press OK button in Sub-GHz Frequency analyzer to switch to Read menu [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/79)
|
||||
- Lock device with pin(or regular lock if pin not set) by holding UP button on main screen [(by an4tur0r)](https://github.com/DarkFlippers/unleashed-firmware/pull/107)
|
||||
* Sub-GHz -> Press OK in frequency analyzer to use detected frequency in Read modes
|
||||
* Sub-GHz -> Long press OK button in Sub-GHz Frequency analyzer to switch to Read menu
|
||||
* Sub-GHz -> External CC1101 module support
|
||||
* Sub-GHz -> Short press OK in frequency analyzer to save detected frequency for usage in Read modes
|
||||
* Sub-GHz -> Long press OK button in Sub-GHz Frequency analyzer to switch to Read menu and automatically use selected frequency
|
||||
* Sub-GHz -> External CC1101 module support (Hardware SPI used)
|
||||
* SubGHz -> **Hold right in received signal list to delete selected signal**
|
||||
* SubGHz -> **Custom buttons for Keeloq / Alutech AT4N / Nice Flor S / Somfy Telis / Security+ 2.0** - now you can use arrow buttons to send signal with different button code
|
||||
* SubGHz -> BFT Mitto / Somfy Telis / Nice Flor S manual creation with programming new remote into receiver (use button 0xF for BFT Mitto, 0x8 (Prog) on Somfy Telis)
|
||||
@@ -84,10 +84,11 @@ Encoders/sending made by Eng1n33r & @xMasterX:
|
||||
- Keeloq: Beninca
|
||||
- Keeloq: Stilmatic / Schellenberg
|
||||
- Keeloq: CAME Space
|
||||
- Keeloq: Aprimatic (model TR and similar)
|
||||
- CAME Atomo
|
||||
- Nice Flor S
|
||||
- FAAC SLH (Spa) [External seed calculation required (For info contact me in Discord: Nano#8998)]
|
||||
- Keeloq: BFT Mitto [External seed calculation required (For info contact me in Discord: Nano#8998)]
|
||||
- Keeloq: BFT Mitto [External seed calculation required (For info contact me in Discord: Nano#8998)] -> Update! check out new [instructions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md)
|
||||
- Security+ v1 & v2
|
||||
- Star Line
|
||||
|
||||
@@ -189,7 +190,7 @@ Games:
|
||||
|
||||
## [- How to add extra Sub-GHz frequencies](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzSettings.md)
|
||||
|
||||
## [- How to use Flipper as new remote (Nice FlorS, BFT Mitto, Somfy Telis)](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md)
|
||||
## [- How to use Flipper as new remote (Nice FlorS, BFT Mitto, Somfy Telis, Aprimatic, AN-Motors, etc..)](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md)
|
||||
|
||||
## [- Configure Sub-GHz Remote App](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemotePlugin.md)
|
||||
|
||||
|
||||
@@ -157,8 +157,7 @@ static bool pocsag_decode_message_word(SubGhzProtocolDecoderPocsag* instance, ui
|
||||
// Function called when current message got decoded, but other messages might follow
|
||||
static void pocsag_message_done(SubGhzProtocolDecoderPocsag* instance) {
|
||||
// append the message to the long-term storage string
|
||||
furi_string_cat_printf(
|
||||
instance->generic.result_ric, "\e#RIC: %" PRIu32 "\e# | ", instance->ric);
|
||||
furi_string_printf(instance->generic.result_ric, "\e#RIC: %" PRIu32 "\e# | ", instance->ric);
|
||||
furi_string_cat_str(instance->generic.result_ric, func_msg[instance->func]);
|
||||
if(instance->func != POCSAG_FUNC_ALERT1) {
|
||||
furi_string_cat(instance->done_msg, instance->msg);
|
||||
|
||||
@@ -373,7 +373,8 @@ bool totp_scene_generate_token_handle_event(
|
||||
|
||||
SceneState* scene_state;
|
||||
if(event->input.type == InputTypeLong) {
|
||||
if(event->input.key == InputKeyDown && plugin_state->automation_method & AutomationMethodBadUsb) {
|
||||
if(event->input.key == InputKeyDown &&
|
||||
plugin_state->automation_method & AutomationMethodBadUsb) {
|
||||
scene_state = (SceneState*)plugin_state->current_scene_state;
|
||||
totp_usb_type_code_worker_notify(
|
||||
scene_state->usb_type_code_worker_context, TotpUsbTypeCodeWorkerEventType);
|
||||
@@ -383,7 +384,9 @@ bool totp_scene_generate_token_handle_event(
|
||||
return true;
|
||||
}
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
else if(event->input.key == InputKeyUp && plugin_state->automation_method & AutomationMethodBadBt) {
|
||||
else if(
|
||||
event->input.key == InputKeyUp &&
|
||||
plugin_state->automation_method & AutomationMethodBadBt) {
|
||||
scene_state = (SceneState*)plugin_state->current_scene_state;
|
||||
totp_bt_type_code_worker_notify(
|
||||
plugin_state->bt_type_code_worker_context, TotpBtTypeCodeWorkerEventType);
|
||||
|
||||
@@ -4,7 +4,7 @@ App(
|
||||
apptype=FlipperAppType.EXTERNAL,
|
||||
entry_point="wifi_marauder_app",
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
stack_size=4 * 1024,
|
||||
order=90,
|
||||
fap_icon="wifi_10px.png",
|
||||
fap_category="GPIO",
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
ADD_SCENE(wifi_marauder, start, Start)
|
||||
ADD_SCENE(wifi_marauder, console_output, ConsoleOutput)
|
||||
ADD_SCENE(wifi_marauder, text_input, TextInput)
|
||||
ADD_SCENE(wifi_marauder, settings_init, SettingsInit)
|
||||
ADD_SCENE(wifi_marauder, log_viewer, LogViewer)
|
||||
|
||||
@@ -4,6 +4,11 @@ void wifi_marauder_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, vo
|
||||
furi_assert(context);
|
||||
WifiMarauderApp* app = context;
|
||||
|
||||
if(app->is_writing_log) {
|
||||
app->has_saved_logs_this_session = true;
|
||||
storage_file_write(app->log_file, buf, len);
|
||||
}
|
||||
|
||||
// If text box store gets too big, then truncate it
|
||||
app->text_box_store_strlen += len;
|
||||
if(app->text_box_store_strlen >= WIFI_MARAUDER_TEXT_BOX_STORE_SIZE - 1) {
|
||||
@@ -21,15 +26,7 @@ void wifi_marauder_console_output_handle_rx_packets_cb(uint8_t* buf, size_t len,
|
||||
furi_assert(context);
|
||||
WifiMarauderApp* app = context;
|
||||
|
||||
// If it is a sniff function, open the pcap file for recording
|
||||
if(strncmp("sniff", app->selected_tx_string, strlen("sniff")) == 0 && !app->is_writing) {
|
||||
app->is_writing = true;
|
||||
if(!app->capture_file || !storage_file_is_open(app->capture_file)) {
|
||||
wifi_marauder_create_pcap_file(app);
|
||||
}
|
||||
}
|
||||
|
||||
if(app->is_writing) {
|
||||
if(app->is_writing_pcap) {
|
||||
storage_file_write(app->capture_file, buf, len);
|
||||
}
|
||||
}
|
||||
@@ -49,8 +46,7 @@ void wifi_marauder_scene_console_output_on_enter(void* context) {
|
||||
furi_string_reset(app->text_box_store);
|
||||
app->text_box_store_strlen = 0;
|
||||
if(0 == strncmp("help", app->selected_tx_string, strlen("help"))) {
|
||||
const char* help_msg = "Marauder companion " WIFI_MARAUDER_APP_VERSION
|
||||
"\nby @0xchocolate\nmodified by @tcpassos\n";
|
||||
const char* help_msg = "Marauder companion " WIFI_MARAUDER_APP_VERSION "\n";
|
||||
furi_string_cat_str(app->text_box_store, help_msg);
|
||||
app->text_box_store_strlen += strlen(help_msg);
|
||||
}
|
||||
@@ -62,7 +58,7 @@ void wifi_marauder_scene_console_output_on_enter(void* context) {
|
||||
}
|
||||
}
|
||||
|
||||
// Set starting text - for "View Log", this will just be what was already in the text box store
|
||||
// Set starting text - for "View Log from end", this will just be what was already in the text box store
|
||||
text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store));
|
||||
|
||||
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneConsoleOutput, 0);
|
||||
@@ -76,8 +72,23 @@ void wifi_marauder_scene_console_output_on_enter(void* context) {
|
||||
app->lp_uart,
|
||||
wifi_marauder_console_output_handle_rx_packets_cb); // setup callback for packets rx thread
|
||||
|
||||
// Send command with newline '\n'
|
||||
// Get ready to send command
|
||||
if(app->is_command && app->selected_tx_string) {
|
||||
// Create files *before* sending command
|
||||
// (it takes time to iterate through the directory)
|
||||
if(app->ok_to_save_logs) {
|
||||
app->is_writing_log = true;
|
||||
wifi_marauder_create_log_file(app);
|
||||
}
|
||||
|
||||
// If it is a sniff function, open the pcap file for recording
|
||||
if(app->ok_to_save_pcaps &&
|
||||
strncmp("sniff", app->selected_tx_string, strlen("sniff")) == 0) {
|
||||
app->is_writing_pcap = true;
|
||||
wifi_marauder_create_pcap_file(app);
|
||||
}
|
||||
|
||||
// Send command with newline '\n'
|
||||
wifi_marauder_uart_tx(
|
||||
(uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string));
|
||||
wifi_marauder_uart_tx((uint8_t*)("\n"), 1);
|
||||
@@ -111,8 +122,13 @@ void wifi_marauder_scene_console_output_on_exit(void* context) {
|
||||
wifi_marauder_uart_tx((uint8_t*)("stopscan\n"), strlen("stopscan\n"));
|
||||
}
|
||||
|
||||
app->is_writing = false;
|
||||
app->is_writing_pcap = false;
|
||||
if(app->capture_file && storage_file_is_open(app->capture_file)) {
|
||||
storage_file_close(app->capture_file);
|
||||
}
|
||||
|
||||
app->is_writing_log = false;
|
||||
if(app->log_file && storage_file_is_open(app->log_file)) {
|
||||
storage_file_close(app->log_file);
|
||||
}
|
||||
}
|
||||
|
||||
185
applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_log_viewer.c
vendored
Normal file
185
applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_log_viewer.c
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
#include "../wifi_marauder_app_i.h"
|
||||
|
||||
void wifi_marauder_scene_log_viewer_widget_callback(
|
||||
GuiButtonType result,
|
||||
InputType type,
|
||||
void* context) {
|
||||
WifiMarauderApp* app = context;
|
||||
if(type == InputTypeShort) {
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, result);
|
||||
}
|
||||
}
|
||||
|
||||
static void _read_log_page_into_text_store(WifiMarauderApp* app) {
|
||||
char temp[64 + 1];
|
||||
storage_file_seek(
|
||||
app->log_file, WIFI_MARAUDER_TEXT_BOX_STORE_SIZE * (app->open_log_file_page - 1), true);
|
||||
furi_string_reset(app->text_box_store);
|
||||
for(uint16_t i = 0; i < (WIFI_MARAUDER_TEXT_BOX_STORE_SIZE / (sizeof(temp) - 1)); i++) {
|
||||
uint16_t num_bytes = storage_file_read(app->log_file, temp, sizeof(temp) - 1);
|
||||
if(num_bytes == 0) {
|
||||
break;
|
||||
}
|
||||
temp[num_bytes] = '\0';
|
||||
furi_string_cat_str(app->text_box_store, temp);
|
||||
}
|
||||
}
|
||||
|
||||
void wifi_marauder_scene_log_viewer_setup_widget(WifiMarauderApp* app, bool called_from_browse) {
|
||||
Widget* widget = app->widget;
|
||||
bool is_open = storage_file_is_open(app->log_file);
|
||||
bool should_open_log = (app->has_saved_logs_this_session || called_from_browse);
|
||||
if(is_open) {
|
||||
_read_log_page_into_text_store(app);
|
||||
} else if(
|
||||
should_open_log &&
|
||||
storage_file_open(app->log_file, app->log_file_path, FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||
uint64_t filesize = storage_file_size(app->log_file);
|
||||
app->open_log_file_num_pages = filesize / WIFI_MARAUDER_TEXT_BOX_STORE_SIZE;
|
||||
int extra_page = (filesize % WIFI_MARAUDER_TEXT_BOX_STORE_SIZE != 0) ? 1 : 0;
|
||||
app->open_log_file_num_pages = (filesize / WIFI_MARAUDER_TEXT_BOX_STORE_SIZE) + extra_page;
|
||||
app->open_log_file_page = 1;
|
||||
_read_log_page_into_text_store(app);
|
||||
} else {
|
||||
app->open_log_file_page = 0;
|
||||
app->open_log_file_num_pages = 0;
|
||||
}
|
||||
|
||||
widget_reset(widget);
|
||||
|
||||
if(furi_string_empty(app->text_box_store)) {
|
||||
char help_msg[256];
|
||||
snprintf(
|
||||
help_msg,
|
||||
sizeof(help_msg),
|
||||
"The log is empty! :(\nTry sending a command?\n\nSaving pcaps to flipper sdcard: %s\nSaving logs to flipper sdcard: %s",
|
||||
app->ok_to_save_pcaps ? "ON" : "OFF",
|
||||
app->ok_to_save_logs ? "ON" : "OFF");
|
||||
furi_string_set_str(app->text_box_store, help_msg);
|
||||
}
|
||||
|
||||
widget_add_text_scroll_element(
|
||||
widget, 0, 0, 128, 53, furi_string_get_cstr(app->text_box_store));
|
||||
|
||||
if(1 < app->open_log_file_page && app->open_log_file_page < app->open_log_file_num_pages) {
|
||||
// hide "Browse" text for middle pages
|
||||
widget_add_button_element(
|
||||
widget, GuiButtonTypeCenter, "", wifi_marauder_scene_log_viewer_widget_callback, app);
|
||||
} else {
|
||||
// only show "Browse" text on first and last page
|
||||
widget_add_button_element(
|
||||
widget,
|
||||
GuiButtonTypeCenter,
|
||||
"Browse",
|
||||
wifi_marauder_scene_log_viewer_widget_callback,
|
||||
app);
|
||||
}
|
||||
|
||||
char pagecounter[100];
|
||||
snprintf(
|
||||
pagecounter,
|
||||
sizeof(pagecounter),
|
||||
"%d/%d",
|
||||
app->open_log_file_page,
|
||||
app->open_log_file_num_pages);
|
||||
if(app->open_log_file_page > 1) {
|
||||
if(app->open_log_file_page == app->open_log_file_num_pages) {
|
||||
// only show left side page-count on last page
|
||||
widget_add_button_element(
|
||||
widget,
|
||||
GuiButtonTypeLeft,
|
||||
pagecounter,
|
||||
wifi_marauder_scene_log_viewer_widget_callback,
|
||||
app);
|
||||
} else {
|
||||
widget_add_button_element(
|
||||
widget, GuiButtonTypeLeft, "", wifi_marauder_scene_log_viewer_widget_callback, app);
|
||||
}
|
||||
}
|
||||
if(app->open_log_file_page < app->open_log_file_num_pages) {
|
||||
widget_add_button_element(
|
||||
widget,
|
||||
GuiButtonTypeRight,
|
||||
pagecounter,
|
||||
wifi_marauder_scene_log_viewer_widget_callback,
|
||||
app);
|
||||
}
|
||||
}
|
||||
|
||||
void wifi_marauder_scene_log_viewer_on_enter(void* context) {
|
||||
WifiMarauderApp* app = context;
|
||||
|
||||
app->open_log_file_page = 0;
|
||||
app->open_log_file_num_pages = 0;
|
||||
bool saved_logs_exist = false;
|
||||
if(!app->has_saved_logs_this_session && furi_string_empty(app->text_box_store)) {
|
||||
// no commands sent yet this session, find last saved log
|
||||
if(storage_dir_open(app->log_file, MARAUDER_APP_FOLDER_LOGS)) {
|
||||
char name[70];
|
||||
char lastname[70];
|
||||
while(storage_dir_read(app->log_file, NULL, name, sizeof(name))) {
|
||||
// keep reading directory until last file is reached
|
||||
strlcpy(lastname, name, sizeof(lastname));
|
||||
saved_logs_exist = true;
|
||||
}
|
||||
if(saved_logs_exist) {
|
||||
snprintf(
|
||||
app->log_file_path,
|
||||
sizeof(app->log_file_path),
|
||||
"%s/%s",
|
||||
MARAUDER_APP_FOLDER_LOGS,
|
||||
lastname);
|
||||
}
|
||||
}
|
||||
storage_dir_close(app->log_file);
|
||||
}
|
||||
|
||||
wifi_marauder_scene_log_viewer_setup_widget(app, saved_logs_exist);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewWidget);
|
||||
}
|
||||
|
||||
bool wifi_marauder_scene_log_viewer_on_event(void* context, SceneManagerEvent event) {
|
||||
WifiMarauderApp* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == GuiButtonTypeCenter) {
|
||||
// Browse
|
||||
FuriString* predefined_filepath = furi_string_alloc_set_str(MARAUDER_APP_FOLDER_LOGS);
|
||||
FuriString* selected_filepath = furi_string_alloc();
|
||||
if(dialog_file_browser_show(
|
||||
app->dialogs, selected_filepath, predefined_filepath, NULL)) {
|
||||
strncpy(
|
||||
app->log_file_path,
|
||||
furi_string_get_cstr(selected_filepath),
|
||||
sizeof(app->log_file_path));
|
||||
if(storage_file_is_open(app->log_file)) {
|
||||
storage_file_close(app->log_file);
|
||||
}
|
||||
wifi_marauder_scene_log_viewer_setup_widget(app, true);
|
||||
}
|
||||
furi_string_free(selected_filepath);
|
||||
furi_string_free(predefined_filepath);
|
||||
consumed = true;
|
||||
} else if(event.event == GuiButtonTypeRight) {
|
||||
// Advance page
|
||||
++app->open_log_file_page;
|
||||
wifi_marauder_scene_log_viewer_setup_widget(app, false);
|
||||
} else if(event.event == GuiButtonTypeLeft) {
|
||||
// Previous page
|
||||
--app->open_log_file_page;
|
||||
wifi_marauder_scene_log_viewer_setup_widget(app, false);
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void wifi_marauder_scene_log_viewer_on_exit(void* context) {
|
||||
WifiMarauderApp* app = context;
|
||||
widget_reset(app->widget);
|
||||
if(storage_file_is_open(app->log_file)) {
|
||||
storage_file_close(app->log_file);
|
||||
}
|
||||
}
|
||||
130
applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_settings_init.c
vendored
Normal file
130
applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_settings_init.c
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
#include "../wifi_marauder_app_i.h"
|
||||
|
||||
const char* Y = "Y";
|
||||
const char* N = "N";
|
||||
|
||||
#define PROMPT_PCAPS 0
|
||||
#define PROMPT_LOGS 1
|
||||
|
||||
void wifi_marauder_scene_settings_init_widget_callback(
|
||||
GuiButtonType result,
|
||||
InputType type,
|
||||
void* context) {
|
||||
WifiMarauderApp* app = context;
|
||||
if(type == InputTypeShort) {
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, result);
|
||||
}
|
||||
}
|
||||
|
||||
void wifi_marauder_scene_settings_init_setup_widget(WifiMarauderApp* app) {
|
||||
Widget* widget = app->widget;
|
||||
|
||||
widget_reset(widget);
|
||||
|
||||
widget_add_button_element(
|
||||
widget, GuiButtonTypeLeft, "No", wifi_marauder_scene_settings_init_widget_callback, app);
|
||||
widget_add_button_element(
|
||||
widget, GuiButtonTypeRight, "Yes", wifi_marauder_scene_settings_init_widget_callback, app);
|
||||
|
||||
if(app->which_prompt == PROMPT_PCAPS) {
|
||||
widget_add_string_element(widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Save pcaps?");
|
||||
widget_add_text_scroll_element(
|
||||
widget,
|
||||
0,
|
||||
12,
|
||||
128,
|
||||
38,
|
||||
"With compatible marauder\nfirmware, you can choose to\nsave captures (pcaps) to the\nflipper sd card here:\n" MARAUDER_APP_FOLDER_USER_PCAPS
|
||||
"\n\nYou can change this setting in the app at any time. Would\nyou like to enable this feature now?");
|
||||
} else {
|
||||
widget_add_string_element(widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Save logs?");
|
||||
widget_add_text_scroll_element(
|
||||
widget,
|
||||
0,
|
||||
12,
|
||||
128,
|
||||
38,
|
||||
"This app supports saving text\nlogs of console output to the\nflipper sd card here:\n" MARAUDER_APP_FOLDER_USER_LOGS
|
||||
"\n\nYou can change this setting in the app at any time. Would\nyou like to enable this feature now?");
|
||||
}
|
||||
}
|
||||
|
||||
void wifi_marauder_scene_settings_init_on_enter(void* context) {
|
||||
WifiMarauderApp* app = context;
|
||||
|
||||
app->which_prompt = PROMPT_PCAPS;
|
||||
wifi_marauder_scene_settings_init_setup_widget(app);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewWidget);
|
||||
}
|
||||
|
||||
bool wifi_marauder_scene_settings_init_on_event(void* context, SceneManagerEvent event) {
|
||||
WifiMarauderApp* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
// get which button press: "Yes" or "No"
|
||||
if(event.event == GuiButtonTypeRight) {
|
||||
// Yes
|
||||
if(app->which_prompt == PROMPT_PCAPS) {
|
||||
app->ok_to_save_pcaps = true;
|
||||
} else {
|
||||
app->ok_to_save_logs = true;
|
||||
}
|
||||
} else if(event.event == GuiButtonTypeLeft) {
|
||||
// No
|
||||
if(app->which_prompt == PROMPT_PCAPS) {
|
||||
app->ok_to_save_pcaps = false;
|
||||
} else {
|
||||
app->ok_to_save_logs = false;
|
||||
}
|
||||
}
|
||||
|
||||
// save setting to file, load next widget or scene
|
||||
if(app->which_prompt == PROMPT_PCAPS) {
|
||||
if(storage_file_open(
|
||||
app->save_pcap_setting_file,
|
||||
SAVE_PCAP_SETTING_FILEPATH,
|
||||
FSAM_WRITE,
|
||||
FSOM_CREATE_ALWAYS)) {
|
||||
const char* ok = app->ok_to_save_pcaps ? Y : N;
|
||||
storage_file_write(app->save_pcap_setting_file, ok, sizeof(ok));
|
||||
} else {
|
||||
dialog_message_show_storage_error(app->dialogs, "Cannot save settings");
|
||||
}
|
||||
storage_file_close(app->save_pcap_setting_file);
|
||||
// same scene, different-looking widget
|
||||
app->which_prompt = PROMPT_LOGS;
|
||||
wifi_marauder_scene_settings_init_setup_widget(app);
|
||||
} else {
|
||||
if(storage_file_open(
|
||||
app->save_logs_setting_file,
|
||||
SAVE_LOGS_SETTING_FILEPATH,
|
||||
FSAM_WRITE,
|
||||
FSOM_CREATE_ALWAYS)) {
|
||||
const char* ok = app->ok_to_save_logs ? Y : N;
|
||||
storage_file_write(app->save_logs_setting_file, ok, sizeof(ok));
|
||||
} else {
|
||||
dialog_message_show_storage_error(app->dialogs, "Cannot save settings");
|
||||
}
|
||||
storage_file_close(app->save_logs_setting_file);
|
||||
// go back to start scene (main menu)
|
||||
app->need_to_prompt_settings_init = false;
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void wifi_marauder_scene_settings_init_on_exit(void* context) {
|
||||
WifiMarauderApp* app = context;
|
||||
widget_reset(app->widget);
|
||||
if(storage_file_is_open(app->save_pcap_setting_file)) {
|
||||
storage_file_close(app->save_pcap_setting_file);
|
||||
}
|
||||
if(storage_file_is_open(app->save_logs_setting_file)) {
|
||||
storage_file_close(app->save_logs_setting_file);
|
||||
}
|
||||
}
|
||||
@@ -127,6 +127,13 @@ const WifiMarauderItem items[NUM_MENU_ITEMS] = {
|
||||
{"Update", {"ota", "sd"}, 2, {"update -w", "update -s"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP},
|
||||
{"Reboot", {""}, 1, {"reboot"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP},
|
||||
{"Help", {""}, 1, {"help"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
|
||||
{"Save to flipper sdcard", // keep as last entry or change logic in callback below
|
||||
{""},
|
||||
1,
|
||||
{""},
|
||||
NO_ARGS,
|
||||
FOCUS_CONSOLE_START,
|
||||
NO_TIP},
|
||||
};
|
||||
|
||||
static void wifi_marauder_scene_start_var_list_enter_callback(void* context, uint32_t index) {
|
||||
@@ -136,6 +143,13 @@ static void wifi_marauder_scene_start_var_list_enter_callback(void* context, uin
|
||||
furi_assert(index < NUM_MENU_ITEMS);
|
||||
const WifiMarauderItem* item = &items[index];
|
||||
|
||||
if(index == NUM_MENU_ITEMS - 1) {
|
||||
// "Save to flipper sdcard" special case - start SettingsInit widget
|
||||
view_dispatcher_send_custom_event(
|
||||
app->view_dispatcher, WifiMarauderEventStartSettingsInit);
|
||||
return;
|
||||
}
|
||||
|
||||
const int selected_option_index = app->selected_option_index[index];
|
||||
furi_assert(selected_option_index < item->num_options_menu);
|
||||
app->selected_tx_string = item->actual_commands[selected_option_index];
|
||||
@@ -147,6 +161,12 @@ static void wifi_marauder_scene_start_var_list_enter_callback(void* context, uin
|
||||
item->focus_console;
|
||||
app->show_stopscan_tip = item->show_stopscan_tip;
|
||||
|
||||
if(!app->is_command && selected_option_index == 0) {
|
||||
// View Log from start
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventStartLogViewer);
|
||||
return;
|
||||
}
|
||||
|
||||
bool needs_keyboard = (item->needs_keyboard == TOGGLE_ARGS) ? (selected_option_index != 0) :
|
||||
item->needs_keyboard;
|
||||
if(needs_keyboard) {
|
||||
@@ -193,6 +213,11 @@ void wifi_marauder_scene_start_on_enter(void* context) {
|
||||
var_item_list, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneStart));
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewVarItemList);
|
||||
|
||||
// Wait, if the user hasn't initialized sdcard settings, let's prompt them once (then come back here)
|
||||
if(app->need_to_prompt_settings_init) {
|
||||
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneSettingsInit);
|
||||
}
|
||||
}
|
||||
|
||||
bool wifi_marauder_scene_start_on_event(void* context, SceneManagerEvent event) {
|
||||
@@ -204,16 +229,28 @@ bool wifi_marauder_scene_start_on_event(void* context, SceneManagerEvent event)
|
||||
if(event.event == WifiMarauderEventStartKeyboard) {
|
||||
scene_manager_set_scene_state(
|
||||
app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index);
|
||||
scene_manager_next_scene(app->scene_manager, WifiMarauderAppViewTextInput);
|
||||
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneTextInput);
|
||||
} else if(event.event == WifiMarauderEventStartConsole) {
|
||||
scene_manager_set_scene_state(
|
||||
app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index);
|
||||
scene_manager_next_scene(app->scene_manager, WifiMarauderAppViewConsoleOutput);
|
||||
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
|
||||
} else if(event.event == WifiMarauderEventStartSettingsInit) {
|
||||
scene_manager_set_scene_state(
|
||||
app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index);
|
||||
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneSettingsInit);
|
||||
} else if(event.event == WifiMarauderEventStartLogViewer) {
|
||||
scene_manager_set_scene_state(
|
||||
app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index);
|
||||
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneLogViewer);
|
||||
}
|
||||
consumed = true;
|
||||
} else if(event.type == SceneManagerEventTypeTick) {
|
||||
app->selected_menu_index = variable_item_list_get_selected_item_index(app->var_item_list);
|
||||
consumed = true;
|
||||
} else if(event.type == SceneManagerEventTypeBack) {
|
||||
scene_manager_stop(app->scene_manager);
|
||||
view_dispatcher_stop(app->view_dispatcher);
|
||||
consumed = true;
|
||||
}
|
||||
|
||||
return consumed;
|
||||
|
||||
@@ -80,7 +80,7 @@ bool wifi_marauder_scene_text_input_on_event(void* context, SceneManagerEvent ev
|
||||
if(event.event == WifiMarauderEventStartConsole) {
|
||||
// Point to custom string to send
|
||||
app->selected_tx_string = app->text_input_store;
|
||||
scene_manager_next_scene(app->scene_manager, WifiMarauderAppViewConsoleOutput);
|
||||
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
|
||||
consumed = true;
|
||||
} else if(event.event == WifiMarauderEventSaveSourceMac) {
|
||||
if(12 != strlen(app->text_input_store)) {
|
||||
@@ -138,7 +138,7 @@ bool wifi_marauder_scene_text_input_on_event(void* context, SceneManagerEvent ev
|
||||
app->special_case_input_src_addr,
|
||||
app->special_case_input_dst_addr);
|
||||
app->selected_tx_string = app->text_input_store;
|
||||
scene_manager_next_scene(app->scene_manager, WifiMarauderAppViewConsoleOutput);
|
||||
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@ WifiMarauderApp* wifi_marauder_app_alloc() {
|
||||
app->dialogs = furi_record_open(RECORD_DIALOGS);
|
||||
app->storage = furi_record_open(RECORD_STORAGE);
|
||||
app->capture_file = storage_file_alloc(app->storage);
|
||||
app->log_file = storage_file_alloc(app->storage);
|
||||
app->save_pcap_setting_file = storage_file_alloc(app->storage);
|
||||
app->save_logs_setting_file = storage_file_alloc(app->storage);
|
||||
|
||||
app->view_dispatcher = view_dispatcher_alloc();
|
||||
app->scene_manager = scene_manager_alloc(&wifi_marauder_scene_handlers, app);
|
||||
@@ -65,6 +68,17 @@ WifiMarauderApp* wifi_marauder_app_alloc() {
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher, WifiMarauderAppViewTextInput, text_input_get_view(app->text_input));
|
||||
|
||||
app->widget = widget_alloc();
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher, WifiMarauderAppViewWidget, widget_get_view(app->widget));
|
||||
|
||||
app->has_saved_logs_this_session = false;
|
||||
|
||||
// if user hasn't confirmed whether to save pcaps and logs to sdcard, then prompt when scene starts
|
||||
app->need_to_prompt_settings_init =
|
||||
(!storage_file_exists(app->storage, SAVE_PCAP_SETTING_FILEPATH) ||
|
||||
!storage_file_exists(app->storage, SAVE_LOGS_SETTING_FILEPATH));
|
||||
|
||||
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneStart);
|
||||
|
||||
return app;
|
||||
@@ -76,6 +90,38 @@ void wifi_marauder_make_app_folder(WifiMarauderApp* app) {
|
||||
if(!storage_simply_mkdir(app->storage, MARAUDER_APP_FOLDER)) {
|
||||
dialog_message_show_storage_error(app->dialogs, "Cannot create\napp folder");
|
||||
}
|
||||
|
||||
if(!storage_simply_mkdir(app->storage, MARAUDER_APP_FOLDER_PCAPS)) {
|
||||
dialog_message_show_storage_error(app->dialogs, "Cannot create\npcaps folder");
|
||||
}
|
||||
|
||||
if(!storage_simply_mkdir(app->storage, MARAUDER_APP_FOLDER_LOGS)) {
|
||||
dialog_message_show_storage_error(app->dialogs, "Cannot create\npcaps folder");
|
||||
}
|
||||
}
|
||||
|
||||
void wifi_marauder_load_settings(WifiMarauderApp* app) {
|
||||
if(storage_file_open(
|
||||
app->save_pcap_setting_file,
|
||||
SAVE_PCAP_SETTING_FILEPATH,
|
||||
FSAM_READ,
|
||||
FSOM_OPEN_EXISTING)) {
|
||||
char ok[1];
|
||||
storage_file_read(app->save_pcap_setting_file, ok, sizeof(ok));
|
||||
app->ok_to_save_pcaps = ok[0] == 'Y';
|
||||
}
|
||||
storage_file_close(app->save_pcap_setting_file);
|
||||
|
||||
if(storage_file_open(
|
||||
app->save_logs_setting_file,
|
||||
SAVE_LOGS_SETTING_FILEPATH,
|
||||
FSAM_READ,
|
||||
FSOM_OPEN_EXISTING)) {
|
||||
char ok[1];
|
||||
storage_file_read(app->save_logs_setting_file, ok, sizeof(ok));
|
||||
app->ok_to_save_logs = ok[0] == 'Y';
|
||||
}
|
||||
storage_file_close(app->save_logs_setting_file);
|
||||
}
|
||||
|
||||
void wifi_marauder_app_free(WifiMarauderApp* app) {
|
||||
@@ -85,10 +131,15 @@ void wifi_marauder_app_free(WifiMarauderApp* app) {
|
||||
view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewVarItemList);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewConsoleOutput);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewTextInput);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewWidget);
|
||||
widget_free(app->widget);
|
||||
text_box_free(app->text_box);
|
||||
furi_string_free(app->text_box_store);
|
||||
text_input_free(app->text_input);
|
||||
storage_file_free(app->capture_file);
|
||||
storage_file_free(app->log_file);
|
||||
storage_file_free(app->save_pcap_setting_file);
|
||||
storage_file_free(app->save_logs_setting_file);
|
||||
|
||||
// View dispatcher
|
||||
view_dispatcher_free(app->view_dispatcher);
|
||||
@@ -118,6 +169,7 @@ int32_t wifi_marauder_app(void* p) {
|
||||
WifiMarauderApp* wifi_marauder_app = wifi_marauder_app_alloc();
|
||||
|
||||
wifi_marauder_make_app_folder(wifi_marauder_app);
|
||||
wifi_marauder_load_settings(wifi_marauder_app);
|
||||
|
||||
wifi_marauder_app->uart = wifi_marauder_usart_init(wifi_marauder_app);
|
||||
wifi_marauder_app->lp_uart = wifi_marauder_lp_uart_init(wifi_marauder_app);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WIFI_MARAUDER_APP_VERSION "v0.3.1"
|
||||
#define WIFI_MARAUDER_APP_VERSION "v0.3.3"
|
||||
|
||||
typedef struct WifiMarauderApp WifiMarauderApp;
|
||||
|
||||
|
||||
@@ -14,16 +14,24 @@
|
||||
#include <gui/modules/text_box.h>
|
||||
#include <gui/modules/text_input.h>
|
||||
#include <gui/modules/variable_item_list.h>
|
||||
#include <gui/modules/widget.h>
|
||||
|
||||
#include <storage/storage.h>
|
||||
#include <dialogs/dialogs.h>
|
||||
|
||||
#define NUM_MENU_ITEMS (16)
|
||||
#define NUM_MENU_ITEMS (17)
|
||||
|
||||
#define WIFI_MARAUDER_TEXT_BOX_STORE_SIZE (4096)
|
||||
#define WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE (512)
|
||||
|
||||
#define MARAUDER_APP_FOLDER EXT_PATH("apps_data/marauder")
|
||||
#define MARAUDER_APP_FOLDER_USER "apps_data/marauder"
|
||||
#define MARAUDER_APP_FOLDER EXT_PATH(MARAUDER_APP_FOLDER_USER)
|
||||
#define MARAUDER_APP_FOLDER_PCAPS MARAUDER_APP_FOLDER "/pcaps"
|
||||
#define MARAUDER_APP_FOLDER_LOGS MARAUDER_APP_FOLDER "/logs"
|
||||
#define MARAUDER_APP_FOLDER_USER_PCAPS MARAUDER_APP_FOLDER_USER "/pcaps"
|
||||
#define MARAUDER_APP_FOLDER_USER_LOGS MARAUDER_APP_FOLDER_USER "/logs"
|
||||
#define SAVE_PCAP_SETTING_FILEPATH MARAUDER_APP_FOLDER "/save_pcaps_here.setting"
|
||||
#define SAVE_LOGS_SETTING_FILEPATH MARAUDER_APP_FOLDER "/save_logs_here.setting"
|
||||
|
||||
struct WifiMarauderApp {
|
||||
Gui* gui;
|
||||
@@ -37,9 +45,21 @@ struct WifiMarauderApp {
|
||||
TextInput* text_input;
|
||||
Storage* storage;
|
||||
File* capture_file;
|
||||
File* log_file;
|
||||
char log_file_path[100];
|
||||
File* save_pcap_setting_file;
|
||||
File* save_logs_setting_file;
|
||||
bool need_to_prompt_settings_init;
|
||||
int which_prompt;
|
||||
bool ok_to_save_pcaps;
|
||||
bool ok_to_save_logs;
|
||||
bool has_saved_logs_this_session;
|
||||
DialogsApp* dialogs;
|
||||
|
||||
VariableItemList* var_item_list;
|
||||
Widget* widget;
|
||||
int open_log_file_page;
|
||||
int open_log_file_num_pages;
|
||||
|
||||
WifiMarauderUart* uart;
|
||||
WifiMarauderUart* lp_uart;
|
||||
@@ -50,7 +70,8 @@ struct WifiMarauderApp {
|
||||
bool is_custom_tx_string;
|
||||
bool focus_console_start;
|
||||
bool show_stopscan_tip;
|
||||
bool is_writing;
|
||||
bool is_writing_pcap;
|
||||
bool is_writing_log;
|
||||
|
||||
// For input source and destination MAC in targeted deauth attack
|
||||
int special_case_input_step;
|
||||
@@ -83,4 +104,5 @@ typedef enum {
|
||||
WifiMarauderAppViewVarItemList,
|
||||
WifiMarauderAppViewConsoleOutput,
|
||||
WifiMarauderAppViewTextInput,
|
||||
WifiMarauderAppViewWidget,
|
||||
} WifiMarauderAppView;
|
||||
|
||||
@@ -5,5 +5,7 @@ typedef enum {
|
||||
WifiMarauderEventStartConsole,
|
||||
WifiMarauderEventStartKeyboard,
|
||||
WifiMarauderEventSaveSourceMac,
|
||||
WifiMarauderEventSaveDestinationMac
|
||||
WifiMarauderEventSaveDestinationMac,
|
||||
WifiMarauderEventStartSettingsInit,
|
||||
WifiMarauderEventStartLogViewer
|
||||
} WifiMarauderCustomEvent;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "wifi_marauder_app_i.h"
|
||||
#include "wifi_marauder_pcap.h"
|
||||
|
||||
void wifi_marauder_get_prefix_from_cmd(char* dest, const char* command) {
|
||||
void wifi_marauder_get_prefix_from_sniff_cmd(char* dest, const char* command) {
|
||||
int start, end, delta;
|
||||
start = strlen("sniff");
|
||||
end = strcspn(command, " ");
|
||||
@@ -10,10 +10,17 @@ void wifi_marauder_get_prefix_from_cmd(char* dest, const char* command) {
|
||||
dest[delta] = '\0';
|
||||
}
|
||||
|
||||
void wifi_marauder_get_prefix_from_cmd(char* dest, const char* command) {
|
||||
int end;
|
||||
end = strcspn(command, " ");
|
||||
strncpy(dest, command, end);
|
||||
dest[end] = '\0';
|
||||
}
|
||||
|
||||
void wifi_marauder_create_pcap_file(WifiMarauderApp* app) {
|
||||
char prefix[10];
|
||||
char capture_file_path[100];
|
||||
wifi_marauder_get_prefix_from_cmd(prefix, app->selected_tx_string);
|
||||
wifi_marauder_get_prefix_from_sniff_cmd(prefix, app->selected_tx_string);
|
||||
|
||||
int i = 0;
|
||||
do {
|
||||
@@ -21,7 +28,7 @@ void wifi_marauder_create_pcap_file(WifiMarauderApp* app) {
|
||||
capture_file_path,
|
||||
sizeof(capture_file_path),
|
||||
"%s/%s_%d.pcap",
|
||||
MARAUDER_APP_FOLDER,
|
||||
MARAUDER_APP_FOLDER_PCAPS,
|
||||
prefix,
|
||||
i);
|
||||
i++;
|
||||
@@ -30,4 +37,28 @@ void wifi_marauder_create_pcap_file(WifiMarauderApp* app) {
|
||||
if(!storage_file_open(app->capture_file, capture_file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
|
||||
dialog_message_show_storage_error(app->dialogs, "Cannot open pcap file");
|
||||
}
|
||||
}
|
||||
|
||||
void wifi_marauder_create_log_file(WifiMarauderApp* app) {
|
||||
char prefix[10];
|
||||
char log_file_path[100];
|
||||
wifi_marauder_get_prefix_from_cmd(prefix, app->selected_tx_string);
|
||||
|
||||
int i = 0;
|
||||
do {
|
||||
snprintf(
|
||||
log_file_path,
|
||||
sizeof(log_file_path),
|
||||
"%s/%s_%d.log",
|
||||
MARAUDER_APP_FOLDER_LOGS,
|
||||
prefix,
|
||||
i);
|
||||
i++;
|
||||
} while(storage_file_exists(app->storage, log_file_path));
|
||||
|
||||
if(!storage_file_open(app->log_file, log_file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
|
||||
dialog_message_show_storage_error(app->dialogs, "Cannot open log file");
|
||||
} else {
|
||||
strcpy(app->log_file_path, log_file_path);
|
||||
}
|
||||
}
|
||||
@@ -8,4 +8,13 @@
|
||||
*
|
||||
* @param app Application context
|
||||
*/
|
||||
void wifi_marauder_create_pcap_file(WifiMarauderApp* app);
|
||||
void wifi_marauder_create_pcap_file(WifiMarauderApp* app);
|
||||
|
||||
/**
|
||||
* Creates a log file to store text from console output.
|
||||
* The file name will have a prefix according to the command being performed by the application (Eg: scanap_0.log)
|
||||
*
|
||||
* @param app Application context
|
||||
*/
|
||||
// same as wifi_marauder_create_pcap_file, but for log files (to save console text output)
|
||||
void wifi_marauder_create_log_file(WifiMarauderApp* app);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "furi_hal.h"
|
||||
|
||||
#define RX_BUF_SIZE (320)
|
||||
#define RX_BUF_SIZE (2048)
|
||||
|
||||
typedef struct WifiMarauderUart WifiMarauderUart;
|
||||
|
||||
|
||||
@@ -86,9 +86,16 @@ static bool fap_loader_run_selected_app(FapLoader* loader, bool ignore_mismatch)
|
||||
if(preload_res == FlipperApplicationPreloadStatusApiMismatch) {
|
||||
if(!ignore_mismatch) {
|
||||
DialogMessage* message = dialog_message_alloc();
|
||||
dialog_message_set_header(message, "API Mismatch", 64, 0, AlignCenter, AlignTop);
|
||||
dialog_message_set_header(
|
||||
message, "API Mismatch", 64, 0, AlignCenter, AlignTop);
|
||||
dialog_message_set_buttons(message, "Cancel", NULL, "Continue");
|
||||
dialog_message_set_text(message, "This app might not\nwork correctly\nContinue anyways?", 64, 32, AlignCenter, AlignCenter);
|
||||
dialog_message_set_text(
|
||||
message,
|
||||
"This app might not\nwork correctly\nContinue anyways?",
|
||||
64,
|
||||
32,
|
||||
AlignCenter,
|
||||
AlignCenter);
|
||||
if(dialog_message_show(loader->dialogs, message) == DialogMessageButtonRight) {
|
||||
retry = true;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@ typedef enum {
|
||||
SubmenuIndexDTMNeo433,
|
||||
SubmenuIndexGibidi433,
|
||||
SubmenuIndexGSN,
|
||||
SubmenuIndexAprimatic,
|
||||
SubmenuIndexANMotorsAT4,
|
||||
SubmenuIndexAlutechAT4N,
|
||||
SubmenuIndexNiceFlo12bit,
|
||||
SubmenuIndexNiceFlo24bit,
|
||||
SubmenuIndexNiceFlorS_433_92,
|
||||
|
||||
@@ -98,6 +98,18 @@ void subghz_scene_set_type_on_enter(void* context) {
|
||||
SubmenuIndexSomfyTelis,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"AN-Motors AT4 433MHz",
|
||||
SubmenuIndexANMotorsAT4,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"Alutech AT4N 433MHz",
|
||||
SubmenuIndexAlutechAT4N,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"KL: DoorHan 315MHz",
|
||||
@@ -158,6 +170,12 @@ void subghz_scene_set_type_on_enter(void* context) {
|
||||
SubmenuIndexGSN,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"KL: Aprimatic 433MHz",
|
||||
SubmenuIndexAprimatic,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"KL: Elmes (PL) 433MHz",
|
||||
@@ -502,6 +520,58 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
|
||||
}
|
||||
break;
|
||||
case SubmenuIndexANMotorsAT4:
|
||||
subghz->txrx->transmitter = subghz_transmitter_alloc_init(
|
||||
subghz->txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME);
|
||||
subghz_preset_init(subghz, "AM650", 433920000, NULL, 0);
|
||||
if(subghz->txrx->transmitter) {
|
||||
subghz_protocol_keeloq_create_data(
|
||||
subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter),
|
||||
subghz->txrx->fff_data,
|
||||
(key & 0x00FFFFFF) | 0x04000000,
|
||||
0x2,
|
||||
0x0021,
|
||||
"AN-Motors",
|
||||
subghz->txrx->preset);
|
||||
flipper_format_write_string_cstr(
|
||||
subghz->txrx->fff_data, "Manufacture", "AN-Motors");
|
||||
generated_protocol = true;
|
||||
} else {
|
||||
generated_protocol = false;
|
||||
}
|
||||
subghz_transmitter_free(subghz->txrx->transmitter);
|
||||
if(!generated_protocol) {
|
||||
furi_string_set(
|
||||
subghz->error_str, "Function requires\nan SD card with\nfresh databases.");
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
|
||||
}
|
||||
break;
|
||||
case SubmenuIndexAprimatic:
|
||||
subghz->txrx->transmitter = subghz_transmitter_alloc_init(
|
||||
subghz->txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME);
|
||||
subghz_preset_init(subghz, "AM650", 433920000, NULL, 0);
|
||||
if(subghz->txrx->transmitter) {
|
||||
subghz_protocol_keeloq_create_data(
|
||||
subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter),
|
||||
subghz->txrx->fff_data,
|
||||
(key & 0x000FFFFF) | 0x00600000,
|
||||
0x4,
|
||||
0x0003,
|
||||
"Aprimatic",
|
||||
subghz->txrx->preset);
|
||||
flipper_format_write_string_cstr(
|
||||
subghz->txrx->fff_data, "Manufacture", "Aprimatic");
|
||||
generated_protocol = true;
|
||||
} else {
|
||||
generated_protocol = false;
|
||||
}
|
||||
subghz_transmitter_free(subghz->txrx->transmitter);
|
||||
if(!generated_protocol) {
|
||||
furi_string_set(
|
||||
subghz->error_str, "Function requires\nan SD card with\nfresh databases.");
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
|
||||
}
|
||||
break;
|
||||
case SubmenuIndexGibidi433:
|
||||
subghz->txrx->transmitter = subghz_transmitter_alloc_init(
|
||||
subghz->txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME);
|
||||
@@ -717,6 +787,29 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
|
||||
}
|
||||
break;
|
||||
case SubmenuIndexAlutechAT4N:
|
||||
subghz->txrx->transmitter = subghz_transmitter_alloc_init(
|
||||
subghz->txrx->environment, SUBGHZ_PROTOCOL_ALUTECH_AT_4N_NAME);
|
||||
subghz_preset_init(subghz, "AM650", 433920000, NULL, 0);
|
||||
if(subghz->txrx->transmitter) {
|
||||
subghz_protocol_alutech_at_4n_create_data(
|
||||
subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter),
|
||||
subghz->txrx->fff_data,
|
||||
(key & 0x000FFFFF) | 0x00100000,
|
||||
0x44,
|
||||
0x0003,
|
||||
subghz->txrx->preset);
|
||||
generated_protocol = true;
|
||||
} else {
|
||||
generated_protocol = false;
|
||||
}
|
||||
subghz_transmitter_free(subghz->txrx->transmitter);
|
||||
if(!generated_protocol) {
|
||||
furi_string_set(
|
||||
subghz->error_str, "Function requires\nan SD card with\nfresh databases.");
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
|
||||
}
|
||||
break;
|
||||
case SubmenuIndexSomfyTelis:
|
||||
subghz->txrx->transmitter = subghz_transmitter_alloc_init(
|
||||
subghz->txrx->environment, SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME);
|
||||
|
||||
@@ -1,58 +1,58 @@
|
||||
Filetype: Flipper SubGhz Keystore File
|
||||
Version: 0
|
||||
Encryption: 1
|
||||
IV: AB 0B A1 23 45 FE E7 06 66 73 21 67 97 12 3D 61
|
||||
CA9DC3E30069ED9C257FCA6747136F617F4E390F2B8BDDFDEBEC8A398A6A0C1E
|
||||
78F18401572E33117850EA83D00C2F92376E88D7CAC0BF7CBA7037BF6755F43C
|
||||
909055FF43224057BCE5F965174AF46586EB7CA4CAE1B3EB8B66EA569047948A
|
||||
AB9B7D338457774713147BF666A5996926B90146CB698AC2F4DE63ADE89D84BB
|
||||
ED796AED9BB3185ACD94779F7CC42665D4A3B04419E4272B77DA8D94B5CF84921889CEB110AB55D7267720A7C5B290EF
|
||||
88E0CECA92549C73981F95999FA8F03B1B2EB98774134752556D7D7EFA802757
|
||||
C42CABAD74010E35726659C8E4AF4888282FBEA9703616B3403DA7C3DCA8A8ED
|
||||
6F44BC56AC2E9883A2469C1909D171A8C58A0CFE4B506CC562EB2F08A484AE1B
|
||||
65DEBEBC629FA3CE72B5028E1E385DFFEE0A9FE227FC5F6DD4368C0CB1886A7D
|
||||
EA9BDC762FCBAAA11A4BE677AE344993990153C9E7A4A89F8271F49765FC72EF
|
||||
8FAE9AC3033E637703626956F91791DAE4B3BEA9C82C065C91A314DDB647F8FE661750526E58C613000260675C2B520C
|
||||
3D853DEC62375B3201B1C2269E31794A3C29958B191953A331D39675CCB53C002EF1491B63C49E629AF5D747CC52BD11
|
||||
61A02BB85B08AA8047EAD9FB80D489AB15CBE0302C660891C4B29D2621C80DBB
|
||||
5230A9651D1A0910695593E1A5F6EA6EB21990D6465E52B325CF141C9E0C9172
|
||||
C9348D18DC019C3E364F7AD9CD5B6D77EE2D6486CFBDFAFE7042AB917E8FFE7C
|
||||
DED385BBAC8FAB5918DBDBDC8622850048A540963AF35C3DD772926927B148C2
|
||||
E1EC13990BDA8E22F2848F97069462FB46840FEA688C52EDE930CD22C4E6F445BF317A96C4A6C2DC4295B2E3E86053B9
|
||||
D5453884C337587A13117F35219C7B4356E8E63EBC4C197CC1633D444D0A6AD0
|
||||
72C3E291DA11AD3D195C6A1B65849B0C91B7D18762B515A5728389356C42B62C
|
||||
0E9EA0D97053752977D83A019A2F0393D326407AE507F5EE6E650082DBC683F81BDD71B79BE81EEB3139815377577346
|
||||
A32FF38450B3121CB01CE06AA369DC7B883CD9B1695CBADBC9609F009D6BFF7B7518D9DD690D214A1DB0D1A0C6F9FC3F
|
||||
98848EFBB09D2A3EA59EE91B1B510BA3775E36B14500DE1238317AFC9872358F
|
||||
E8B2785366399F84EADF07B0E299603BB885780E6ECA883508FFB7664C6473FE
|
||||
1F6CEA6696B2E07FEB256506609D7E11D9F09F18B9EE43DE9BC42014ABF5213F
|
||||
F2FF5045A5E90AAF92C2ECCB9FEFFBDE400A7E3E6B09CF43608896F7BC91736F
|
||||
73CC30A78808BB2B3F7F398D88C79470AF86B825DE0C2FF31442D351C2826D9C
|
||||
B68FD5017BA4809AD22DF64805DCE329A81C2CE3F7BE87FADFBD02211AB02321
|
||||
57BC2E14A724D6E2F4B0FD9401C3E6E5117D338077958648A558E40C553C787F
|
||||
882A41BC36393F06C57ED71E66D003E24B5DAE86F90D8AEDD89A2DFED6719BF1
|
||||
95EDC3C3EB639AC66656B58D8F71A5B1B329002C4CCF7666C41C717A939C0979
|
||||
494A32528A68F5B4DF45385CC7FB470224F25D8AC9C81AB0DBD291AA4764BB17
|
||||
9A6D21675317433CE6EE860C9A2713265E1DA5E8F4024690252971EA5C2A566A
|
||||
2B8379BCDDD0E6F73B1AD2D5A4D69D34D0013E98C87AD2BCE7AEED80F3BF4F69
|
||||
6E5D67B8B825943F9B9979D5E1EA9348B1DD40A5DA39B20FA96B78CAD3E03747
|
||||
27559A18DD6D52FFED8427376113C1A35840D64A53466071E1B769A28F161A99
|
||||
A2F38E38C253947816B5E629AAC02BC77EF7B56CC95FBF291C05466C56E01E47FE92053C900C0F6F98B11D7873BB9AFC
|
||||
8A7E57E1228F75F78D51C13FE79C269E43F007E55F5B87741BCADDAAA6402DF7
|
||||
E088817700DBC7D778427464368D7771E3C20194CE60D08668578CAA527258B8
|
||||
3E5AD04DE23578A3BBC5FB91608435EBA1FF1465EDCE3E064F60A2EED35C9015
|
||||
647C9BFB61C0509D152A7B6B5C548DC558052F862314B42F4D1D8B98F6BF2412
|
||||
3D659FF6999401CAB590681036C3FDABAF157C774928E0D7D76FAC08AA6CFE93
|
||||
342362E28923E64DC5047E25E5A2F3FC8A6EB63554793CB8A1C99FFE632A370508CA208CA912470DB343A1636C751B9E
|
||||
3B71D04AB09DFB44015F5553B4B76C9419C4D615F60184BA0B6A5687E47D66BA
|
||||
14CF7621A4943DE2156AB8FDE8A9E74D26776D8362D9364387626488CB3DA5DC
|
||||
2F9205BF8B310C33E38F571FFBDF6FC4BA5135457A2CF6CA9CD319F3EDF4BF6E
|
||||
785EDF05A2111B8E4A126BE274C9BD8D6C0482F4A2B716FFAE93EDB8D1634F41
|
||||
4B26880D1AE8EC1D285296F473EB5A805CF1C1EA47B899A6A3F8E9EFDB2CBCA3
|
||||
A002B3ED0D1FCBC02298BFE7F18207CD58AB21D358F20855D067939EF50DCC08
|
||||
BE82806DE526A6453C6FA309DAE0B52D67A98A194753DD4CC2C8C196A47B253F60149FAF49D0396E1F24CB1EDF1430DA
|
||||
031686817FB37936FD0313B9358FD35BAF5DEB924F7A939C4B843DD095F11806
|
||||
3A7B7A7AE8723C2A060FF368AB048A48737D4EEAD3C97BF98BC9E8CAE552431B
|
||||
357C4A1A41F43100208863F2E607AE14CC55235D757CDE5C491BE405BB72BDB4
|
||||
0C46E442B9AC3C479C18D4D94AB3E5124D4033AFD05AE00AC6881DD62F11E07F
|
||||
8705CF1D9B202056CEBD98FF25CB0B6BF40175DBDC2FE86FE2A7D2AC796F818EA71A8C1312E9C7FCE6CC3D11FBBA98E4
|
||||
IV: AF 0B A3 13 56 FA F7 46 76 78 25 28 34 16 3D 62
|
||||
77995F096640A6CA8735DE839975FA3573145DDB995E45F58AECCD6A6F2D6FCB
|
||||
A062DD58F9957EC098075344DFF69FB3B2A3C9893D4240C74BE32299F330290B
|
||||
2AD2CCC4FB760D772001A903A995435260F442152BDCD5B075FBC61015BEC7E1
|
||||
34AE78CF87A10211C8E6F6E2EE18C4F0BBE3B677094B7118E03AD9E89AF70E28
|
||||
41943E7507D37A344F56EDF4BBDCDA75FAA10A6E97DF801ACF2A0E97E41782053CA74E31E3488EA1AFE29369E7A542C7
|
||||
9FA67B118BC1FE289F38A78DA4E1FFBAEB4498404B49CBD9690B9421FC05564D
|
||||
3A872E97A668C644D3827273ADDA6B1BC689A3AD09F5980EC7461E40624653BE
|
||||
5E1F4D865E5F4176DBF7832992B60947812E05701E647CF36427C2EE04F97FE2
|
||||
7FCF6E437D0DA231A2937C46622C4939F0045AEF5CF7FCF5D97E24B67995F0D3
|
||||
D09F230FEDB9CB690B5AC7C6BCE86B0779D9C233D2823562EABE340FF06C819D
|
||||
84F0A81ABB7857438BF52BE8988C1A471EFEDFE16EC11851BFC39F34EB26236F318CFAAEC9A53AD5500D48CAE21E777A
|
||||
F3FDDDD5DB6038D0E2FC02750530325976ADA2600DE19BF736AF6CB7E810D7627B4F396963F0288F486182228B9AAE22
|
||||
87E07B23B3B2740D93C82696C020057CC7F3864ABD6E6967656F44427C529DD1
|
||||
20C35809F7F5161C21E643A606DC48A5CC85BCEB546A03023DF778C4499426E3
|
||||
81CCF1CA68E2B6663DA9D12FEE241307A2E449440901793A955CB5D5915819DD
|
||||
1B66D0664451153D0124364834E1543960A756351330523C3FFE83DA4EE7F0E6
|
||||
7025D550A40466B472BA71F3248C37E6DE1FD59ED5C11CBB26238795DD44F4B21BD447F3CA72AED6A25B977982100A1E
|
||||
99F38C3F7C89D2805FB36F931AC5D1B248A56838AC29E13B1255CAE706B68216
|
||||
D138C616E4E1F6053177118C94F65C0BA6B155286CE63E0728E3F2D2BF6C6A98
|
||||
276E646DBF54B341F93AB4E1C36525AF983879F7251D84BB02DD54F4A5E0FA85A3278891F7ADA9ADE2F8AAD010F6F6D4
|
||||
3F3598143FE40E04FE25EADE1EC2B4CDAE339AF7730AE9DC45C97C0E44B299DBCC0E9DA6F4B0EE00F25D2FDD9E1C6BF5
|
||||
20FA8F62628FEA51A584CE298F22E60FF85BFE193AF1C5DE57605FF02E90739C
|
||||
B14B4896088EF58E0CE659511C93782FB5F94BC69B64E5011EBD10DF18FFB3B1
|
||||
90BBE045FFEA06A77B55B0B6D0CFA8F12C4E1B35FB0111DD0C2CF1637AE8924A
|
||||
04B87BC1D09E8EE3C8A91CE75169546D37868B2D87BF2D712623F84937ACE974
|
||||
B8C5B04070FFB27B4686057C57F762FA3CAF2BBD3E5BEBE462C1C2FC283AE118
|
||||
A40B154CEC2F5F989CA6F30703A0133217530D41F12739B25E2C1BEF54E6AC7C
|
||||
4F5B9A68E8DEDB00410F5AD7FB7F7CA8F43B75F0457DA2AFAA8279A8C4AF34AB
|
||||
9A7B185F6A157B1886DC6AA98B1F3D6899331D8BDDBAAC9620321E16BB4CC7E8
|
||||
4A710E11F1C7A7138065801BDB4E72B07608220BBCF7455111FDD41DC0290B94
|
||||
3A5B715089F926049077172755B0C48B4A4420031787D7DB113CF402C7D3D0AE
|
||||
EE0B90EC27EC0F4A8DCD3C747E17594E0A27A92E05F2DE7B0457873C7154E075
|
||||
0B9B201C209072676A47225BE4E43B4631B080A85F9FCFAA5683A4F9A727187A
|
||||
13A15C606AA2EA40F2DCDE7F44217F02D2D9796CAC9164100B211D7A22CF333B
|
||||
DF5292BBF35AB1408956D439A81EF12F53573F985489727A10FB652B7BD8B10D
|
||||
50E59C9DD3A08EA8752656B753B8D9D2BFD674EB4C5F0DCAE9870E81D7F00F6AAC133FA7C7307FA197D551EE877F8CD7
|
||||
E173C1798596A31F697D63E0CCDDFAB14B1B1E299DD642102A7858ECC795CF1B
|
||||
92D3326A93AA6B37041F219C8035F37A057C1B69BECA7881098BED2A49C58751
|
||||
27D17F007115734FA0F55F2BDF016ECE8DFA703FA6D61729456E95B78FC8AC29
|
||||
4FF7306A426B7DE021D59968FAEF3453F555A9A952D81C4008D5000513799DEA
|
||||
660CB0D4634EABC6CAA9E321CB08FC0C8C8F6BAE0FAF0C10C1FCCBA93B68D9B4
|
||||
86D84C91BFBF0DE22088C0F5A8598A2C2807033E60BC11333E8D1A6188F043D5
|
||||
F3E0E8566E12ADBA44974A3CA1D6D60456649031DCAD4365D0AE80FEDBC80AAA106A9BAB39448CD62EF916A59ECA9579
|
||||
F4D6EB6D241B17CA0A9E73E93DA3B58B6B257CC0484FC92E285984A09FD4CEA9
|
||||
094265CB574E0C9B8954B3130A2017492B1149C3FB9239A6B690A9C7B6635E5A
|
||||
BE67B61B2F99BAA4AF94B71CB5F2386417D5F3B187899222D2671B1147BA9932
|
||||
74840B34C9F27A76FCB593629C8114BCABD1B1CE96E22CC378DC9E7BEEF263FB
|
||||
2511F44F0A13D94B55D7FF3297194E47D6987890F9170BCBC14A7607C5A38E01
|
||||
FD0CF9314CB9B949CEFE1DA3FA05A18FBEEF751B4DC900DBAE068EE211C4492C
|
||||
22ECD6934472760CF806E7C9E86885D0C0AAE501EDBF9DCB7ADC7AE53F3B73C38F2B6FB3FD0F867C5B5BFD00440CB43A
|
||||
325CA78241AE4EE784CC867815403E342F77BB428EB1FE189AD569F10170CB98
|
||||
BF065D29EC8E2BB411F0131DF3A06BDF07B1436A14004D0E11E1261F0E232CB8
|
||||
CE015802FCE9AFD9807F855D813FD06D5446A8953057A79BC4A452BDAB8E9DD7
|
||||
C6B569EB172EC4609966E2C9426BE99A86529073A57824B1752392658C4E87F08ED8675A32F44E413CD6037CA4A0DE71
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# to use manual settings and prevent them from being deleted on upgrade, rename *_user.example files to *_user
|
||||
Filetype: Flipper SubGhz Setting File
|
||||
Version: 1
|
||||
# Add Standard frequencies for your region
|
||||
# Add Standard frequencies included with firmware and place user frequencies after them
|
||||
#Add_standard_frequencies: true
|
||||
|
||||
# Default Frequency: used as default for "Read" and "Read Raw"
|
||||
|
||||
@@ -1,5 +1,55 @@
|
||||
# How to use Flipper as a new SubGHz remote (not clone of original remote)
|
||||
|
||||
### If your system is not added here that doesn't mean flipper don't support it! Look into add manually menu, and search for your manufacturers inscturctions!
|
||||
### Also many supported systems can be used only from `Read` mode, `Add Manually` is used only to make new remotes that can be binded with receiver
|
||||
|
||||
## AN-Motors AT4
|
||||
|
||||
**This instruction for older boards, if your has no** `Learn` **button but has buttons** `F`, `CL`, `+`, `-` **read instruction from Alutech AT4N**
|
||||
1. Create new remote with randomly generated serial: Go to SubGHz -> Add Manually -> AN-Motors AT4 433Mhz
|
||||
2. Open your new remote file
|
||||
3. Open your receiver box, find button `Learn` click it one time, led will turn on.
|
||||
4. Press `Send` on your flipper one time, led on receiver board will turn off.
|
||||
5. Press `Send` on your flipper again, led on receiver will start flashing, wait couple seconds until led turns off.
|
||||
6. Done
|
||||
|
||||
Watch this video to learn more (video in Russian language): https://www.youtube.com/watch?v=URVMtTELcnU
|
||||
|
||||
## Alutech AT4N (AN-Motors)
|
||||
|
||||
1. Create new remote with randomly generated serial: Go to SubGHz -> Add Manually -> Alutech AT4N 433Mhz
|
||||
2. Open your new remote file
|
||||
3. Open your receiver box, find button `F` press it for ~3sec, display will show `Pr`.
|
||||
4. Click `F` button couple times until you see `Lr` on screen
|
||||
5. Using buttons `+` / `-` select free number that has no remotes in it (if it has remote programmed on that number, it will show a red dot on the down right corner)
|
||||
6. Press `Send` on your flipper one time, display on receiver board will flash and red dot will appear next to remote number.
|
||||
7. Press button `F` on receiver board for ~3sec to exit programming mode
|
||||
8. Done
|
||||
|
||||
Watch this video to learn more and see how different boards can be programmed (video in Russian language): https://www.youtube.com/watch?v=XrOVVYhFXDg
|
||||
|
||||
## Aprimatic TR
|
||||
|
||||
1. Create new remote with randomly generated serial: Go to SubGHz -> Add Manually -> KL: Aprimatic 433Mhz
|
||||
2. Open your new remote file
|
||||
3. Push all 4 buttons at same time on your existing remote thats already works with receiver
|
||||
4. Receiver makes a continuous beep
|
||||
5. Press `Send` on your flipper for ~2 seconds
|
||||
6. Wait until receiver stops beeping
|
||||
7. Done?
|
||||
|
||||
## Doorhan
|
||||
|
||||
1. Create new remote with randomly generated serial: Go to SubGHz -> Add Manually -> KL: Doorhan 433Mhz or 315Mhz depends on your receiver (find out by reading your existing remote)
|
||||
2. Open your new remote file
|
||||
3. Push `P` button for ~2 sec, led will start flashing
|
||||
4. Press `Send` on your flipper for ~2 seconds
|
||||
5. Led on the receiver board will flash and turn off
|
||||
6. Done!
|
||||
|
||||
Also you can program new remote using old remote on newer boards! See first video below:
|
||||
Watch this videos to learn more (videos in Russian language): https://www.youtube.com/watch?v=wZ5121HYv50 / https://www.youtube.com/watch?v=1ucrDKF3vWc
|
||||
|
||||
## Somfy Telis
|
||||
|
||||
1. Create new remote with randomly generated serial: Go to SubGHz -> Add Manually -> Somfy Telis 433Mhz
|
||||
|
||||
@@ -119,7 +119,7 @@ bool furi_hal_subghz_check_radio(void) {
|
||||
if((ver != 0) && (ver != 255)) {
|
||||
FURI_LOG_D(TAG, "Radio check ok");
|
||||
} else {
|
||||
FURI_LOG_D(TAG, "Radio check failed");
|
||||
FURI_LOG_D(TAG, "Radio check failed, revert to default");
|
||||
|
||||
result = false;
|
||||
}
|
||||
@@ -182,7 +182,7 @@ bool furi_hal_subghz_init_check(void) {
|
||||
if(result) {
|
||||
FURI_LOG_I(TAG, "Init OK");
|
||||
} else {
|
||||
FURI_LOG_E(TAG, "Failed to initialization");
|
||||
FURI_LOG_E(TAG, "Selected CC1101 module init failed, revert to default");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ bool ds_generic_write_blank(OneWireHost* host, iButtonProtocolData* protocol_dat
|
||||
}
|
||||
|
||||
static bool ds_generic_reset_callback(bool is_short, void* context) {
|
||||
furi_assert(context);
|
||||
DallasGenericProtocolData* data = context;
|
||||
if(!is_short) {
|
||||
onewire_slave_set_overdrive(data->state.bus, is_short);
|
||||
@@ -93,7 +94,7 @@ void ds_generic_emulate(OneWireSlave* bus, iButtonProtocolData* protocol_data) {
|
||||
DallasGenericProtocolData* data = protocol_data;
|
||||
data->state.bus = bus;
|
||||
|
||||
onewire_slave_set_reset_callback(bus, ds_generic_reset_callback, NULL);
|
||||
onewire_slave_set_reset_callback(bus, ds_generic_reset_callback, protocol_data);
|
||||
onewire_slave_set_command_callback(bus, ds_generic_command_callback, protocol_data);
|
||||
}
|
||||
|
||||
|
||||
@@ -330,17 +330,20 @@ bool mf_classic_dict_delete_index(MfClassicDict* dict, uint32_t target) {
|
||||
uint32_t index = 0;
|
||||
|
||||
bool key_removed = false;
|
||||
stream_rewind(dict->stream);
|
||||
while(!key_removed) {
|
||||
if(!stream_read_line(dict->stream, next_line)) break;
|
||||
if(furi_string_get_char(next_line, 0) == '#') continue;
|
||||
if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue;
|
||||
if(index++ != target) continue;
|
||||
stream_seek(dict->stream, -NFC_MF_CLASSIC_KEY_LEN, StreamOffsetFromCurrent);
|
||||
if(!stream_delete(dict->stream, NFC_MF_CLASSIC_KEY_LEN)) break;
|
||||
stream_seek(dict->stream, -(NFC_MF_CLASSIC_KEY_LEN + 1), StreamOffsetFromCurrent);
|
||||
if(!stream_delete(dict->stream, (NFC_MF_CLASSIC_KEY_LEN + 1))) break;
|
||||
dict->total_keys--;
|
||||
key_removed = true;
|
||||
}
|
||||
|
||||
stream_rewind(dict->stream);
|
||||
|
||||
furi_string_free(next_line);
|
||||
return key_removed;
|
||||
}
|
||||
|
||||
@@ -638,7 +638,8 @@ static void nfc_worker_mf_classic_key_attack(
|
||||
(uint32_t)key);
|
||||
if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyA)) {
|
||||
mf_classic_set_key_found(data, i, MfClassicKeyA, key);
|
||||
FURI_LOG_D(TAG, "Key found");
|
||||
FURI_LOG_D(
|
||||
TAG, "Key A found: %04lx%08lx", (uint32_t)(key >> 32), (uint32_t)key);
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
|
||||
|
||||
uint64_t found_key;
|
||||
@@ -661,7 +662,8 @@ static void nfc_worker_mf_classic_key_attack(
|
||||
(uint32_t)key);
|
||||
if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyB)) {
|
||||
mf_classic_set_key_found(data, i, MfClassicKeyB, key);
|
||||
FURI_LOG_D(TAG, "Key found");
|
||||
FURI_LOG_D(
|
||||
TAG, "Key B found: %04lx%08lx", (uint32_t)(key >> 32), (uint32_t)key);
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
|
||||
}
|
||||
}
|
||||
@@ -760,9 +762,13 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
||||
furi_hal_nfc_sleep();
|
||||
deactivated = true;
|
||||
} else {
|
||||
mf_classic_set_key_not_found(data, i, MfClassicKeyA);
|
||||
is_key_a_found = false;
|
||||
FURI_LOG_D(TAG, "Key %dA not found in attack", i);
|
||||
// If the key A is marked as found and matches the searching key, invalidate it
|
||||
if(mf_classic_is_key_found(data, i, MfClassicKeyA) &&
|
||||
data->block[i].value[0] == key) {
|
||||
mf_classic_set_key_not_found(data, i, MfClassicKeyA);
|
||||
is_key_a_found = false;
|
||||
FURI_LOG_D(TAG, "Key %dA not found in attack", i);
|
||||
}
|
||||
}
|
||||
if(!is_key_b_found) {
|
||||
is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB);
|
||||
@@ -775,9 +781,13 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
||||
}
|
||||
deactivated = true;
|
||||
} else {
|
||||
mf_classic_set_key_not_found(data, i, MfClassicKeyB);
|
||||
is_key_b_found = false;
|
||||
FURI_LOG_D(TAG, "Key %dB not found in attack", i);
|
||||
// If the key B is marked as found and matches the searching key, invalidate it
|
||||
if(mf_classic_is_key_found(data, i, MfClassicKeyB) &&
|
||||
data->block[i].value[10] == key) {
|
||||
mf_classic_set_key_not_found(data, i, MfClassicKeyB);
|
||||
is_key_b_found = false;
|
||||
FURI_LOG_D(TAG, "Key %dB not found in attack", i);
|
||||
}
|
||||
}
|
||||
if(is_key_a_found && is_key_b_found) break;
|
||||
if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break;
|
||||
|
||||
@@ -320,8 +320,12 @@ bool subghz_protocol_alutech_at_4n_create_data(
|
||||
instance->generic.data_count_bit = 72;
|
||||
bool res = subghz_protocol_alutech_at_4n_gen_data(instance, btn);
|
||||
if(res) {
|
||||
return SubGhzProtocolStatusOk ==
|
||||
subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
|
||||
res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
|
||||
if((res == SubGhzProtocolStatusOk) &&
|
||||
!flipper_format_write_uint32(flipper_format, "CRC", &instance->crc, 1)) {
|
||||
FURI_LOG_E(TAG, "Unable to add CRC");
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ static const char* mfname;
|
||||
static uint8_t kl_type;
|
||||
static uint8_t btn_temp_id;
|
||||
static uint8_t btn_temp_id_original;
|
||||
static bool bft_prog_mode;
|
||||
static uint8_t klq_prog_mode;
|
||||
static uint16_t temp_counter;
|
||||
|
||||
void keeloq_set_btn(uint8_t b) {
|
||||
@@ -106,7 +106,7 @@ uint8_t keeloq_get_custom_btn() {
|
||||
void keeloq_reset_original_btn() {
|
||||
btn_temp_id_original = 0;
|
||||
temp_counter = 0;
|
||||
bft_prog_mode = false;
|
||||
klq_prog_mode = 0;
|
||||
}
|
||||
|
||||
void keeloq_reset_mfname() {
|
||||
@@ -173,16 +173,27 @@ static bool subghz_protocol_keeloq_gen_data(
|
||||
|
||||
// BFT programming mode on / off conditions
|
||||
if((strcmp(instance->manufacture_name, "BFT") == 0) && (btn == 0xF)) {
|
||||
bft_prog_mode = true;
|
||||
klq_prog_mode = 1;
|
||||
}
|
||||
if((strcmp(instance->manufacture_name, "BFT") == 0) && (btn != 0xF) && bft_prog_mode) {
|
||||
bft_prog_mode = false;
|
||||
if((strcmp(instance->manufacture_name, "BFT") == 0) && (btn != 0xF) && (klq_prog_mode == 1)) {
|
||||
klq_prog_mode = 0;
|
||||
}
|
||||
// Aprimatic programming mode on / off conditions
|
||||
if((strcmp(instance->manufacture_name, "Aprimatic") == 0) && (btn == 0xF)) {
|
||||
klq_prog_mode = 2;
|
||||
}
|
||||
if((strcmp(instance->manufacture_name, "Aprimatic") == 0) && (btn != 0xF) &&
|
||||
(klq_prog_mode == 2)) {
|
||||
klq_prog_mode = 0;
|
||||
}
|
||||
// If we using BFT programming mode we will trasmit its seed in hop part like original remote
|
||||
if(bft_prog_mode) {
|
||||
if(klq_prog_mode == 1) {
|
||||
hop = instance->generic.seed;
|
||||
} else if(klq_prog_mode == 2) {
|
||||
// If we using Aprimatic programming mode we will trasmit some strange looking hop value, why? cuz manufacturer did it this way :)
|
||||
hop = 0x1A2B3C4D;
|
||||
}
|
||||
if(counter_up && !bft_prog_mode) {
|
||||
if(counter_up && klq_prog_mode == 0) {
|
||||
if(instance->generic.cnt < 0xFFFF) {
|
||||
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) {
|
||||
instance->generic.cnt = 0;
|
||||
@@ -193,11 +204,28 @@ static bool subghz_protocol_keeloq_gen_data(
|
||||
instance->generic.cnt = 0;
|
||||
}
|
||||
}
|
||||
if(!bft_prog_mode) {
|
||||
if(klq_prog_mode == 0) {
|
||||
uint32_t decrypt = (uint32_t)btn << 28 |
|
||||
(instance->generic.serial & 0x3FF)
|
||||
<< 16 | //ToDo in some protocols the discriminator is 0
|
||||
instance->generic.cnt;
|
||||
|
||||
if(strcmp(instance->manufacture_name, "Aprimatic") == 0) {
|
||||
// Aprimatic uses 12bit serial number + 2bit APR1 "parity" bit in front of it replacing first 2 bits of serial
|
||||
// Thats in theory! We need to check if this is true for all Aprimatic remotes but we got only 3 recordings to test
|
||||
// For now lets assume that this is true for all Aprimatic remotes, if not we will need to add some more code here
|
||||
uint32_t apri_serial = instance->generic.serial;
|
||||
uint8_t apr1 = 0;
|
||||
for(uint16_t i = 1; i != 0b10000000000; i <<= 1) {
|
||||
if(apri_serial & i) apr1++;
|
||||
}
|
||||
apri_serial &= 0b00001111111111;
|
||||
if(apr1 % 2 == 0) {
|
||||
apri_serial |= 0b110000000000;
|
||||
}
|
||||
decrypt = btn << 28 | (apri_serial & 0xFFF) << 16 | instance->generic.cnt;
|
||||
}
|
||||
|
||||
// DTM Neo, Came_Space uses 12bit -> simple learning -- FAAC_RC,XT , Mutanco_Mutancode, Stilmatic(Schellenberg) -> 12bit normal learning
|
||||
if((strcmp(instance->manufacture_name, "DTM_Neo") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "FAAC_RC,XT") == 0) ||
|
||||
@@ -363,11 +391,14 @@ static bool
|
||||
if(instance->manufacture_name == 0x0) {
|
||||
instance->manufacture_name = "";
|
||||
}
|
||||
if(bft_prog_mode) {
|
||||
if(klq_prog_mode == 1) {
|
||||
instance->manufacture_name = "BFT";
|
||||
} else if(klq_prog_mode == 2) {
|
||||
instance->manufacture_name = "Aprimatic";
|
||||
}
|
||||
uint8_t klq_last_custom_btn = 0xA;
|
||||
if(strcmp(instance->manufacture_name, "BFT") == 0) {
|
||||
if((strcmp(instance->manufacture_name, "BFT") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "Aprimatic") == 0)) {
|
||||
klq_last_custom_btn = 0xF;
|
||||
}
|
||||
|
||||
@@ -649,7 +680,7 @@ void* subghz_protocol_decoder_keeloq_alloc(SubGhzEnvironment* environment) {
|
||||
instance->keystore = subghz_environment_get_keystore(environment);
|
||||
instance->manufacture_from_file = furi_string_alloc();
|
||||
|
||||
bft_prog_mode = false;
|
||||
klq_prog_mode = 0;
|
||||
|
||||
return instance;
|
||||
}
|
||||
@@ -1151,7 +1182,7 @@ static void subghz_protocol_keeloq_check_remote_controller(
|
||||
uint32_t key_hop = key & 0x00000000ffffffff;
|
||||
|
||||
// If we are in BFT programming mode we will set previous remembered counter and skip mf keys check
|
||||
if(!bft_prog_mode) {
|
||||
if(klq_prog_mode == 0) {
|
||||
// Check key AN-Motors
|
||||
if((key_hop >> 24) == ((key_hop >> 16) & 0x00ff) &&
|
||||
(key_fix >> 28) == ((key_hop >> 12) & 0x0f) && (key_hop & 0xFFF) == 0x404) {
|
||||
@@ -1168,10 +1199,14 @@ static void subghz_protocol_keeloq_check_remote_controller(
|
||||
}
|
||||
temp_counter = instance->cnt;
|
||||
|
||||
} else {
|
||||
} else if(klq_prog_mode == 1) {
|
||||
*manufacture_name = "BFT";
|
||||
mfname = *manufacture_name;
|
||||
instance->cnt = temp_counter;
|
||||
} else if(klq_prog_mode == 2) {
|
||||
*manufacture_name = "Aprimatic";
|
||||
mfname = *manufacture_name;
|
||||
instance->cnt = temp_counter;
|
||||
}
|
||||
|
||||
instance->serial = key_fix & 0x0FFFFFFF;
|
||||
|
||||
Reference in New Issue
Block a user