Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FindMyFlipper - Add Tile Support, Save Tag Type, Dynamic Data Length #41

Merged
merged 2 commits into from
Mar 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 7 additions & 13 deletions applications/system/findmy/findmy.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ static FindMy* findmy_app_alloc() {

findmy_main_update_active(app->findmy_main, furi_hal_bt_extra_beacon_is_active());
findmy_main_update_interval(app->findmy_main, app->state.broadcast_interval);
findmy_main_update_type(app->findmy_main, findmy_data_get_type(app->state.data));
findmy_main_update_type(app->findmy_main, app->state.tag_type);

return app;
}
Expand Down Expand Up @@ -141,18 +141,12 @@ void findmy_toggle_beacon(FindMy* app) {
findmy_main_update_active(app->findmy_main, furi_hal_bt_extra_beacon_is_active());
}

FindMyType findmy_data_get_type(uint8_t data[EXTRA_BEACON_MAX_DATA_SIZE]) {
if(data[0] == 0x1E && // Length
data[1] == 0xFF && // Manufacturer Specific Data
data[2] == 0x4C && // Company ID (Apple, Inc.)
data[3] == 0x00 && // ...
data[4] == 0x12 && // Type (FindMy)
data[5] == 0x19 // Length
) {
return FindMyTypeApple;
} else {
return FindMyTypeSamsung;
}
void findmy_set_tag_type(FindMy* app, FindMyType type) {
app->state.tag_type = type;
findmy_state_sync_config(&app->state);
findmy_state_save(&app->state);
findmy_main_update_type(app->findmy_main, type);
FURI_LOG_I("TagType2", "Tag Type: %d", type);
}

void furi_hal_bt_reverse_mac_addr(uint8_t mac_addr[GAP_MAC_ADDR_SIZE]) {
Expand Down
2 changes: 0 additions & 2 deletions applications/system/findmy/findmy.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#pragma once

typedef struct FindMy FindMy;

typedef enum FindMyType FindMyType;
7 changes: 1 addition & 6 deletions applications/system/findmy/findmy_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,7 @@ typedef enum {
FindMyViewPopup,
} FindMyView;

enum FindMyType {
FindMyTypeApple,
FindMyTypeSamsung,
};

void findmy_change_broadcast_interval(FindMy* app, uint8_t value);
void findmy_change_transmit_power(FindMy* app, uint8_t value);
void findmy_set_tag_type(FindMy* app, FindMyType type);
void findmy_toggle_beacon(FindMy* app);
FindMyType findmy_data_get_type(uint8_t data[EXTRA_BEACON_MAX_DATA_SIZE]);
35 changes: 32 additions & 3 deletions applications/system/findmy/findmy_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,18 @@ bool findmy_state_load(FindMyState* out_state) {
if(!flipper_format_read_uint32(file, "transmit_power", &tmp, 1)) break;
state.transmit_power = tmp;

if(!flipper_format_read_uint32(file, "tag_type", &tmp, 1)) {
// Support migrating from old config
tmp = FindMyTypeApple;
flipper_format_rewind(file);
}
state.tag_type = tmp;

if(!flipper_format_read_hex(file, "mac", state.mac, sizeof(state.mac))) break;

if(!flipper_format_read_hex(file, "data", state.data, sizeof(state.data))) break;
if(!flipper_format_read_hex(
file, "data", state.data, findmy_state_data_size(state.tag_type)))
break;

loaded_from_file = true;
} while(0);
Expand All @@ -45,6 +54,8 @@ bool findmy_state_load(FindMyState* out_state) {
state.broadcast_interval = 5;
state.transmit_power = 6;

state.tag_type = FindMyTypeApple;

// Set default mac
uint8_t default_mac[EXTRA_BEACON_MAC_ADDR_SIZE] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
memcpy(state.mac, default_mac, sizeof(state.mac));
Expand Down Expand Up @@ -88,7 +99,8 @@ void findmy_state_apply(FindMyState* state) {

furi_check(furi_hal_bt_extra_beacon_set_config(&state->config));

furi_check(furi_hal_bt_extra_beacon_set_data(state->data, sizeof(state->data)));
furi_check(
furi_hal_bt_extra_beacon_set_data(state->data, findmy_state_data_size(state->tag_type)));

if(state->beacon_active) {
furi_check(furi_hal_bt_extra_beacon_start());
Expand Down Expand Up @@ -120,11 +132,28 @@ void findmy_state_save(FindMyState* state) {
tmp = state->transmit_power;
if(!flipper_format_write_uint32(file, "transmit_power", &tmp, 1)) break;

tmp = state->tag_type;
if(!flipper_format_write_uint32(file, "tag_type", &tmp, 1)) break;

if(!flipper_format_write_hex(file, "mac", state->mac, sizeof(state->mac))) break;

if(!flipper_format_write_hex(file, "data", state->data, sizeof(state->data))) break;
if(!flipper_format_write_hex(
file, "data", state->data, findmy_state_data_size(state->tag_type)))
break;
} while(0);

flipper_format_free(file);
furi_record_close(RECORD_STORAGE);
}

uint8_t findmy_state_data_size(FindMyType type) {
switch(type) {
case FindMyTypeApple:
case FindMyTypeSamsung:
return 31;
case FindMyTypeTile:
return 21;
default:
return 0;
}
}
9 changes: 9 additions & 0 deletions applications/system/findmy/findmy_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,20 @@
#define FINDMY_STATE_DIR EXT_PATH("apps_data/findmy")
#define FINDMY_STATE_PATH FINDMY_STATE_DIR "/findmy_state.txt"

typedef enum {
FindMyTypeApple,
FindMyTypeSamsung,
FindMyTypeTile,
} FindMyType;

typedef struct {
bool beacon_active;
uint8_t broadcast_interval;
uint8_t transmit_power;

uint8_t mac[EXTRA_BEACON_MAC_ADDR_SIZE];
uint8_t data[EXTRA_BEACON_MAX_DATA_SIZE];
FindMyType tag_type;

// Generated from the other state values
GapExtraBeaconConfig config;
Expand All @@ -26,3 +33,5 @@ void findmy_state_apply(FindMyState* state);
void findmy_state_sync_config(FindMyState* state);

void findmy_state_save(FindMyState* state);

uint8_t findmy_state_data_size(FindMyType type);
11 changes: 5 additions & 6 deletions applications/system/findmy/generate_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,7 @@ def main():
s256_b64 = base64.b64encode(public_key_hash.finalize()).decode("ascii")

if "/" not in s256_b64[:7]:
fname = (
f"{prefix}_{s256_b64[:7]}.keys"
if prefix
else f"{s256_b64[:7]}.keys"
)
fname = f"{prefix}_{mac}.keys" if prefix else f"{mac}.keys"

print(f"{i + 1})")
print("Private key (Base64):", private_key_b64)
Expand All @@ -95,8 +91,9 @@ def main():
print("Payload:", payload)
print()
print(
"Place the .keys file onto your Flipper or input the MAC and Payload manually."
"Place the .keys file onto your Flipper in the Apps_Data->FindMyFlipper folder or input the MAC and Payload manually."
)
print()

with open(f"keys/{fname}", "w") as f:
f.write(f"Private key: {private_key_b64}\n")
Expand All @@ -106,6 +103,8 @@ def main():
f.write(f"Public key (Hex): {public_key_hex}\n")
f.write(f"MAC: {mac}\n")
f.write(f"Payload: {payload}\n")
print("Keys file saved to:", os.path.abspath(f"keys/{fname}"))
print()
break


Expand Down
14 changes: 4 additions & 10 deletions applications/system/findmy/scenes/findmy_scene_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
enum VarItemListIndex {
VarItemListIndexBroadcastInterval,
VarItemListIndexTransmitPower,
VarItemListIndexImportTagFromFile,
VarItemListIndexRegisterTagManually,
VarItemListIndexRegisterTag,
VarItemListIndexAbout,
};

Expand Down Expand Up @@ -58,9 +57,7 @@ void findmy_scene_config_on_enter(void* context) {
snprintf(power_str, sizeof(power_str), "%ddBm", app->state.transmit_power);
variable_item_set_current_value_text(item, power_str);

item = variable_item_list_add(var_item_list, "Import Tag From File", 0, NULL, NULL);

item = variable_item_list_add(var_item_list, "Register Tag Manually", 0, NULL, NULL);
item = variable_item_list_add(var_item_list, "Register Tag", 0, NULL, NULL);

item = variable_item_list_add(
var_item_list,
Expand All @@ -86,11 +83,8 @@ bool findmy_scene_config_on_event(void* context, SceneManagerEvent event) {
scene_manager_set_scene_state(app->scene_manager, FindMySceneConfig, event.event);
consumed = true;
switch(event.event) {
case VarItemListIndexImportTagFromFile:
scene_manager_next_scene(app->scene_manager, FindMySceneConfigImport);
break;
case VarItemListIndexRegisterTagManually:
scene_manager_next_scene(app->scene_manager, FindMySceneConfigMac);
case VarItemListIndexRegisterTag:
scene_manager_next_scene(app->scene_manager, FindMySceneConfigTagtype);
break;
case VarItemListIndexAbout:
break;
Expand Down
17 changes: 14 additions & 3 deletions applications/system/findmy/scenes/findmy_scene_config_import.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
enum VarItemListIndex {
VarItemListIndexNrfConnect,
VarItemListIndexOpenHaystack,
VarItemListIndexRegisterTagManually,
};

static const char* parse_nrf_connect(FindMy* app, const char* path) {
Expand Down Expand Up @@ -42,10 +43,15 @@ static const char* parse_nrf_connect(FindMy* app, const char* path) {
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;
size_t line_size = furi_string_size(line);
uint8_t data_size = findmy_state_data_size(app->state.tag_type);
FURI_LOG_I("ImportPayload", "Line Size: %d", line_size);
FURI_LOG_I("ImportPayload", "Data Size: %d", data_size * 2);
if(line_size != data_size * 2) break;
// Initialize full data to 0's, then fill only first data_size bytes
uint8_t data[EXTRA_BEACON_MAX_DATA_SIZE] = {0};
error = NULL;
for(size_t i = 0; i < sizeof(data); i++) {
for(size_t i = 0; i < data_size; 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') ||
Expand Down Expand Up @@ -151,6 +157,8 @@ void findmy_scene_config_import_on_enter(void* context) {

item = variable_item_list_add(var_item_list, "OpenHaystack (.keys)", 0, NULL, NULL);

item = variable_item_list_add(var_item_list, "Register Tag Manually", 0, NULL, NULL);

// This scene acts more like a submenu than a var item list tbh
UNUSED(item);

Expand Down Expand Up @@ -178,6 +186,9 @@ bool findmy_scene_config_import_on_event(void* context, SceneManagerEvent event)
case VarItemListIndexOpenHaystack:
extension = ".keys";
break;
case VarItemListIndexRegisterTagManually:
scene_manager_next_scene(app->scene_manager, FindMySceneConfigMac);
break;
default:
break;
}
Expand Down
11 changes: 5 additions & 6 deletions applications/system/findmy/scenes/findmy_scene_config_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ void findmy_scene_config_packet_on_enter(void* context) {

byte_input_set_header_text(byte_input, "Enter Bluetooth Payload:");

memcpy(app->packet_buf, app->state.data, sizeof(app->packet_buf));
memcpy(app->packet_buf, app->state.data, findmy_state_data_size(app->state.tag_type));

byte_input_set_result_callback(
byte_input,
findmy_scene_config_packet_callback,
NULL,
app,
app->packet_buf,
sizeof(app->packet_buf));
findmy_state_data_size(app->state.tag_type));

view_dispatcher_switch_to_view(app->view_dispatcher, FindMyViewByteInput);
}
Expand All @@ -39,11 +39,10 @@ bool findmy_scene_config_packet_on_event(void* context, SceneManagerEvent event)
case ByteInputResultOk:
scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, FindMySceneConfig);
memcpy(app->state.data, app->packet_buf, sizeof(app->state.data));
memcpy(app->state.data, app->packet_buf, findmy_state_data_size(app->state.tag_type));
findmy_state_save(&app->state);
furi_check(
furi_hal_bt_extra_beacon_set_data(app->state.data, sizeof(app->state.data)));
findmy_main_update_type(app->findmy_main, findmy_data_get_type(app->state.data));
furi_check(furi_hal_bt_extra_beacon_set_data(
app->state.data, findmy_state_data_size(app->state.tag_type)));
break;
default:
break;
Expand Down
70 changes: 70 additions & 0 deletions applications/system/findmy/scenes/findmy_scene_config_tagtype.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include "../findmy_i.h"

enum VarItemListIndex {
VarItemListIndexApple,
VarItemListIndexSamsung,
VarItemListIndexTile,
};

void findmy_scene_config_tagtype_callback(void* context, uint32_t index) {
furi_assert(context);
FindMy* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, index);
}

void findmy_scene_config_tagtype_on_enter(void* context) {
FindMy* app = context;
VariableItemList* var_item_list = app->var_item_list;
VariableItem* item;

variable_item_list_set_header(var_item_list, "Choose tag type");

item = variable_item_list_add(var_item_list, "Apple AirTag", 0, NULL, NULL);

item = variable_item_list_add(var_item_list, "Samsung SmartTag", 0, NULL, NULL);

item = variable_item_list_add(var_item_list, "Tile SmartTag", 0, NULL, NULL);

UNUSED(item);

variable_item_list_set_enter_callback(
var_item_list, findmy_scene_config_tagtype_callback, app);

variable_item_list_set_selected_item(
var_item_list, scene_manager_get_scene_state(app->scene_manager, FindMySceneConfigImport));
view_dispatcher_switch_to_view(app->view_dispatcher, FindMyViewVarItemList);
}

bool findmy_scene_config_tagtype_on_event(void* context, SceneManagerEvent event) {
FindMy* app = context;
bool consumed = false;

if(event.type == SceneManagerEventTypeCustom) {
scene_manager_set_scene_state(app->scene_manager, FindMySceneConfigTagtype, event.event);
consumed = true;

switch(event.event) {
case VarItemListIndexApple:
findmy_set_tag_type(app, FindMyTypeApple);
break;
case VarItemListIndexSamsung:
findmy_set_tag_type(app, FindMyTypeSamsung);
break;
case VarItemListIndexTile:
findmy_set_tag_type(app, FindMyTypeTile);
break;
default:
break;
}
scene_manager_next_scene(app->scene_manager, FindMySceneConfigImport);
}

return consumed;
}

void findmy_scene_config_tagtype_on_exit(void* context) {
FindMy* app = context;
VariableItemList* var_item_list = app->var_item_list;

variable_item_list_reset(var_item_list);
}
1 change: 1 addition & 0 deletions applications/system/findmy/scenes/findmy_scenes.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
ADD_SCENE(findmy, main, Main)
ADD_SCENE(findmy, config, Config)
ADD_SCENE(findmy, config_import, ConfigImport)
ADD_SCENE(findmy, config_tagtype, ConfigTagtype)
ADD_SCENE(findmy, config_import_result, ConfigImportResult)
ADD_SCENE(findmy, config_mac, ConfigMac)
ADD_SCENE(findmy, config_packet, ConfigPacket)
Loading
Loading