mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-14 09:58:36 -07:00
FindMy: Add import from nRF Connect .txt file
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
#include "findmy_icons.h"
|
#include "findmy_icons.h"
|
||||||
#include <toolbox/stream/file_stream.h>
|
#include <toolbox/stream/file_stream.h>
|
||||||
#include <toolbox/hex.h>
|
#include <toolbox/hex.h>
|
||||||
|
#include <toolbox/path.h>
|
||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
#include <storage/storage.h>
|
#include <storage/storage.h>
|
||||||
#include <dialogs/dialogs.h>
|
#include <dialogs/dialogs.h>
|
||||||
|
|||||||
@@ -1,9 +1,76 @@
|
|||||||
#include "../findmy_i.h"
|
#include "../findmy_i.h"
|
||||||
|
|
||||||
enum VarItemListIndex {
|
enum VarItemListIndex {
|
||||||
|
VarItemListIndexNrfConnect,
|
||||||
VarItemListIndexOpenHaystack,
|
VarItemListIndexOpenHaystack,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char* parse_nrf_connect(FindMy* app, const char* path) {
|
||||||
|
const char* error = NULL;
|
||||||
|
|
||||||
|
Stream* stream = file_stream_alloc(app->storage);
|
||||||
|
FuriString* line = furi_string_alloc();
|
||||||
|
do {
|
||||||
|
// XX-XX-XX-XX-XX-XX_YYYY-MM-DD HH_MM_SS.txt
|
||||||
|
error = "Filename must\nhave MAC\naddress";
|
||||||
|
uint8_t mac[EXTRA_BEACON_MAC_ADDR_SIZE];
|
||||||
|
path_extract_filename_no_ext(path, line);
|
||||||
|
if(furi_string_size(line) < sizeof(mac) * 3 - 1) break;
|
||||||
|
error = NULL;
|
||||||
|
for(size_t i = 0; i < sizeof(mac); i++) {
|
||||||
|
char a = furi_string_get_char(line, i * 3);
|
||||||
|
char b = furi_string_get_char(line, i * 3 + 1);
|
||||||
|
if((a < 'A' && a > 'F') || (a < '0' && a > '9') || (b < 'A' && b > 'F') ||
|
||||||
|
(b < '0' && b > '9') || !hex_char_to_uint8(a, b, &mac[i])) {
|
||||||
|
error = "Filename must\nhave MAC\naddress";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(error) break;
|
||||||
|
furi_hal_bt_reverse_mac_addr(mac);
|
||||||
|
|
||||||
|
error = "Can't open file";
|
||||||
|
if(!file_stream_open(stream, path, FSAM_READ, FSOM_OPEN_EXISTING)) break;
|
||||||
|
|
||||||
|
// YYYY-MM-DD HH:MM:SS.ms, XX dBm, 0xXXXXX
|
||||||
|
error = "Wrong file format";
|
||||||
|
if(!stream_read_line(stream, line)) break;
|
||||||
|
const char* marker = " dBm, 0x";
|
||||||
|
size_t pos = furi_string_search(line, marker);
|
||||||
|
if(pos == FURI_STRING_FAILURE) break;
|
||||||
|
furi_string_right(line, pos + strlen(marker));
|
||||||
|
furi_string_trim(line);
|
||||||
|
|
||||||
|
error = "Wrong payload size";
|
||||||
|
uint8_t data[EXTRA_BEACON_MAX_DATA_SIZE];
|
||||||
|
if(furi_string_size(line) != sizeof(data) * 2) break;
|
||||||
|
error = NULL;
|
||||||
|
for(size_t i = 0; i < sizeof(data); i++) {
|
||||||
|
char a = furi_string_get_char(line, i * 2);
|
||||||
|
char b = furi_string_get_char(line, i * 2 + 1);
|
||||||
|
if((a < 'A' && a > 'F') || (a < '0' && a > '9') || (b < 'A' && b > 'F') ||
|
||||||
|
(b < '0' && b > '9') || !hex_char_to_uint8(a, b, &data[i])) {
|
||||||
|
error = "Invalid payload";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(error) break;
|
||||||
|
|
||||||
|
memcpy(app->state.mac, mac, sizeof(app->state.mac));
|
||||||
|
memcpy(app->state.data, data, sizeof(app->state.data));
|
||||||
|
findmy_state_sync_config(&app->state);
|
||||||
|
findmy_state_save(&app->state);
|
||||||
|
|
||||||
|
error = NULL;
|
||||||
|
|
||||||
|
} while(false);
|
||||||
|
furi_string_free(line);
|
||||||
|
file_stream_close(stream);
|
||||||
|
stream_free(stream);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
static const char* parse_open_haystack(FindMy* app, const char* path) {
|
static const char* parse_open_haystack(FindMy* app, const char* path) {
|
||||||
const char* error = NULL;
|
const char* error = NULL;
|
||||||
|
|
||||||
@@ -78,6 +145,8 @@ void findmy_scene_config_import_on_enter(void* context) {
|
|||||||
VariableItemList* var_item_list = app->var_item_list;
|
VariableItemList* var_item_list = app->var_item_list;
|
||||||
VariableItem* item;
|
VariableItem* item;
|
||||||
|
|
||||||
|
item = variable_item_list_add(var_item_list, "nRF Connect .txt", 0, NULL, NULL);
|
||||||
|
|
||||||
item = variable_item_list_add(var_item_list, "OpenHaystack .keys", 0, NULL, NULL);
|
item = variable_item_list_add(var_item_list, "OpenHaystack .keys", 0, NULL, NULL);
|
||||||
|
|
||||||
// This scene acts more like a submenu than a var item list tbh
|
// This scene acts more like a submenu than a var item list tbh
|
||||||
@@ -101,6 +170,9 @@ bool findmy_scene_config_import_on_event(void* context, SceneManagerEvent event)
|
|||||||
|
|
||||||
const char* extension = NULL;
|
const char* extension = NULL;
|
||||||
switch(event.event) {
|
switch(event.event) {
|
||||||
|
case VarItemListIndexNrfConnect:
|
||||||
|
extension = ".txt";
|
||||||
|
break;
|
||||||
case VarItemListIndexOpenHaystack:
|
case VarItemListIndexOpenHaystack:
|
||||||
extension = ".keys";
|
extension = ".keys";
|
||||||
break;
|
break;
|
||||||
@@ -123,6 +195,9 @@ bool findmy_scene_config_import_on_event(void* context, SceneManagerEvent event)
|
|||||||
// Used in result to show success or error message
|
// Used in result to show success or error message
|
||||||
const char* error = NULL;
|
const char* error = NULL;
|
||||||
switch(event.event) {
|
switch(event.event) {
|
||||||
|
case VarItemListIndexNrfConnect:
|
||||||
|
error = parse_nrf_connect(app, furi_string_get_cstr(path));
|
||||||
|
break;
|
||||||
case VarItemListIndexOpenHaystack:
|
case VarItemListIndexOpenHaystack:
|
||||||
error = parse_open_haystack(app, furi_string_get_cstr(path));
|
error = parse_open_haystack(app, furi_string_get_cstr(path));
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user